⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sslserversocket.cpp

📁 基本实现了数字证书的制作、SSL安全通讯、加解密操作等功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
							break;
						}
					default:
						{	
							m_pList->AddMsg("未知命令",M_ERROR);
							break;
						}
					}
					if(SSlSend((char *)&RA,sizeof(RA))<=0)//发送
						break;
				}
			}
			catch (_com_error &e)
			{
				DisplayError(e);
				SSlSend((char *)&RA,sizeof(RA));//发送
			}
			break;
		}
		case Audit://审核
			{
				try
				{
					if (m_pConnection == NULL)
					{
						return;
					}				
					m_pRecordset->Open((_bstr_t)CA.SQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); 
					if(!m_pRecordset->adoEOF)//记录
					{ 
						char out[100]="";
						char cert[4096]={0};
						char key[4096]={0};
						int certl=0,keyl=0;
						stuCERT sCERT;
						///////////////////////////////////////////////////////////////////////////////////
						_variant_t	varBLOB;
						varBLOB = m_pRecordset->Fields->GetItem("USERINFO")->GetChunk(sizeof(stuCERT));
						if(varBLOB.vt == (VT_ARRAY | VT_UI1))
						{
							char *pBuf = NULL;
							SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
							memcpy(&sCERT,pBuf,sizeof(stuCERT));//个体信息
							SafeArrayUnaccessData(varBLOB.parray);
						}
						///////////////////////////////////////////////////////////////////////////////////
						
						SYSTEMTIME tm;
						GetLocalTime(&tm);
						CString time;
						time.Format("%d-%d-%d", tm.wYear,tm.wMonth,tm.wDay);
						
						_variant_t UserID=m_pRecordset->Fields->GetItem("ID")->Value;
						
						HRSRC hRsrc=FindResource(NULL,MAKEINTRESOURCE(IDR_ROOT_CERT),"CERT");
						DWORD lenCert = SizeofResource(NULL, hRsrc); 
						HGLOBAL hgCert=LoadResource(NULL,hRsrc);
						LPSTR lpCert=(LPSTR)LockResource(hgCert);
	
						/*私钥*/
						hRsrc=FindResource(NULL,MAKEINTRESOURCE(IDR_ROOT_KEY),"CERT");
						DWORD lenKey = SizeofResource(NULL, hRsrc); 
						HGLOBAL hgKey=LoadResource(NULL,hRsrc);
						LPSTR lpKey=(LPSTR)LockResource(hgKey);

			
						if(DirectCert(lpCert,lenCert,lpKey,lenKey,UserID.lVal,0,atoi("365"),&sCERT,1024,
							cert,&certl,key,&keyl,out/*,m_CertFormat*/))//固定有效期和密钥长度
						{
							m_pRecordset->Fields->GetItem("CERTSTATE")->PutValue(_variant_t((long)1));
							m_pRecordset->Fields->GetItem("AUDITIME")->PutValue(_variant_t(time));
							m_pRecordset->Fields->GetItem("USERCERT")->PutValue(_variant_t(cert));
							m_pRecordset->Fields->GetItem("USERKEY")->PutValue(_variant_t(key));
							m_pRecordset->Update();
							
							RA.ID=UserID.lVal;//ID
							RA.Type=Audit;//操作类型
							RA.State=TRUE;//操作状态
						}
						else
						{
							m_pList->AddMsg(out,M_ERROR);
							RA.Type=Audit;//操作类型
							RA.State=FALSE;//操作状态
						}
					}				
				}
				catch (_com_error &e)
				{
					DisplayError(e);
					RA.Type=Made;//操作类型
					RA.State=FALSE;//操作状态
				}
				if(SSlSend((char *)&RA,sizeof(RA))<=0)
					return;
				break;
			}
		case Made://制作证书
			{
				try
				{
					if (m_pConnection == NULL)
					{
						return;
					}
					m_pRecordset->Open((_bstr_t)CA.SQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); 
					if(!m_pRecordset->adoEOF)//记录
					{ 
						_bstr_t UserCert=m_pRecordset->Fields->GetItem("USERCERT")->Value;
						CString Cert=UserCert.copy();
						_bstr_t UserKey=m_pRecordset->Fields->GetItem("USERKEY")->Value;
						CString Key=UserKey.copy();
						_variant_t UserID=m_pRecordset->Fields->GetItem("ID")->Value;
						
						RA.ID=UserID.lVal;//ID
						RA.Type=Made;//操作类型
						RA.State=TRUE;//操作状态
						RA.CertL=Cert.GetLength();//公钥长度
						RA.KeyL=Key.GetLength();//私钥长度
						SSlSend((char *)&RA,sizeof(RA));//发送证书ID、公钥证书长度,私钥长度
						
						CString CertKey;
						CertKey=Cert+Key;
						SSlSend(CertKey.GetBuffer(0),strlen(CertKey));//发送证书内容
					}
				}
				catch (_com_error &e)
				{
					DisplayError(e);
					RA.Type=Made;//操作类型
					RA.State=FALSE;//操作状态
					SSlSend((char *)&RA,sizeof(RA));
				}
				break;
			}
		case MadeOK://制作成功,用于更新数据库,不发送消息
			{
				try
				{
					if (m_pConnection == NULL)
					{
						return;
					}				
					m_pRecordset->Open((_bstr_t)CA.SQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); 
					if(!m_pRecordset->adoEOF)//记录
					{ 
						
						SYSTEMTIME tm;
						GetLocalTime(&tm);
						CString time;
						time.Format("%d-%d-%d", tm.wYear,tm.wMonth,tm.wDay);
						m_pRecordset->Fields->GetItem("CERTSTATE")->PutValue(_variant_t((long)2));
						m_pRecordset->Fields->GetItem("MADETIME")->PutValue(_variant_t(time));
						m_pRecordset->Update();
					}
				}
				catch (_com_error &e)
				{
					DisplayError(e);
					m_pList->AddMsg("更新数据库失败",M_ERROR);
				}	 								 
				break;
			}
		case Revoke://作废证书
			{
				try
				{
					if (m_pConnection == NULL)
					{
						return;
					}				
					m_pRecordset->Open((_bstr_t)CA.SQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); 
					time_t ttime;//当前时间
					time(&ttime);
					if(!m_pRecordset->adoEOF)//记录
					{ 
						m_pRecordset->Fields->GetItem("CERTSTATE")->PutValue(_variant_t((long)-1));
						m_pRecordset->Fields->GetItem("REVOKETIME")->PutValue(_variant_t(ttime));
						m_pRecordset->Update();
						_variant_t UserID=m_pRecordset->Fields->GetItem("ID")->Value;
						
						RA.ID=UserID.lVal;//ID
						RA.Type=Revoke;//操作类型
						RA.State=TRUE;//操作状态
					}
				}
				catch (_com_error &e)
				{
					DisplayError(e);
					RA.Type=Revoke;//操作类型
					RA.State=FALSE;//操作状态
				}
				SSlSend((char *)&RA,sizeof(RA));
				break;
			}
		case MadeCrl://制作CRL
			{
				try
				{
					if (m_pConnection == NULL)
					{
						return;
					}				
					time_t timet;//作废时间
					int id;//索引
					time_t t;
					time(&t);
					char out[100]={0};
					stuREVOKE * Head=NULL;
					m_pRecordset->Open((_bstr_t)CA.SQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); 
					while(!m_pRecordset->adoEOF)//记录
					{ 
						_variant_t UserID=m_pRecordset->Fields->GetItem("ID")->Value;
						id=UserID.lVal;//ID
						_variant_t RevokeTime=m_pRecordset->Fields->GetItem("REVOKETIME")->Value;
						timet=RevokeTime.lVal;//time
						AddRevoke(Head,id,timet);
						m_pRecordset->MoveNext();//转到下一条纪录
					}
					HRSRC hRsrc=FindResource(NULL,MAKEINTRESOURCE(IDR_ROOT_CERT),"CERT");
					DWORD lenCert = SizeofResource(NULL, hRsrc); 
					HGLOBAL hgCert=LoadResource(NULL,hRsrc);
					LPSTR lpCert=(LPSTR)LockResource(hgCert);
					/*私钥*/
					hRsrc=FindResource(NULL,MAKEINTRESOURCE(IDR_ROOT_KEY),"CERT");
					DWORD lenKey = SizeofResource(NULL, hRsrc); 
					HGLOBAL hgKey=LoadResource(NULL,hRsrc);
					LPSTR lpKey=(LPSTR)LockResource(hgKey);
					char * Crl=NULL;
					int CrlLen=0;
					if(MakeCrl(lpCert,lenCert,lpKey,lenKey,Head,NewCrlMem,Crl,&CrlLen,NULL,out))
					{
						RA.Type=MadeCrl;//操作类型
						RA.State=TRUE;//操作状态
						RA.CertL=CrlLen;//crl长度
						if(SSlSend((char *)&RA,sizeof(RA))>0)//发送crl、crl长度
							int i=SSlSend(Crl,CrlLen);//发送证书内容
						delete Crl;
					}
					else
					{
						RA.Type=MadeCrl;//操作类型
						RA.State=FALSE;//操作状态
						m_pList->AddMsg(out,M_ERROR);
						SSlSend((char *)&RA,sizeof(RA));
					}
				}
				catch (_com_error &e)
				{
					DisplayError(e);
					RA.Type=Revoke;//操作类型
					RA.State=FALSE;//操作状态
					SSlSend((char *)&RA,sizeof(RA));
				}
				break;
			}
		}
		m_pRecordset->Close();
		m_pRecordset = NULL;
		AsyncSelect(FD_READ|FD_CLOSE);
	}
	CAsyncSocket::OnReceive(nErrorCode);
}

char * CSslServerSocket::NewCrlMem(UINT len) //分配内存
{
	return new char [len];
}

void CSslServerSocket::OnSend(int nErrorCode)
{
	// TODO: Add your specialized code here and/or call the base class
	char out[100]={0};
	if(m_type==0)//www
	{
		/*得到html*/
		HRSRC hRsrc=FindResource(NULL,MAKEINTRESOURCE(IDR_HTML),RT_HTML);
		DWORD lenHtml = SizeofResource(NULL, hRsrc); 
		HGLOBAL hgHtml=LoadResource(NULL,hRsrc);
		LPSTR lpHtml=(LPSTR)LockResource(hgHtml);
		SSlWww(lpHtml,lenHtml,out);
	}
	CAsyncSocket::OnSend(nErrorCode);
}

void CSslServerSocket::SSlWww(char * file,int len, char *out)
{
	int i=0,k=0;
	POSITION pos;
	if(len==0)//磁盘文件
	{
		FILE *fp;
		char buf[1024]={0};
		if((fp=fopen(file,"r+b"))==NULL)
		{
			sprintf(out,"Error opening %s",file);
			return;
		}
		for (;;)
		{
			i=fread(buf,sizeof(char), 1024,fp);
			if (i <= 0) break;
			k=SSlSend(buf,i);
			memset(buf,0,1024);
			if (k <= 0)
			{
				break;
			}
		}
		fclose(fp);
	}
	else
	{
//		for(i=0;;i++)
		{
	//		k=SSlSend(file+i*1024,(len>1024)?1024:len);
			k=SSlSend(file,len);
//			if (k <= 0) break;
//			len-=1024;
//			if(len<=0)
//				break;
		}
	}
	CString clientIp,str;
	unsigned int port;
	GetPeerName(clientIp,port);//得到用户ip,port
	str.Format("断开客户连接%s",clientIp);
	SSL_set_shutdown(m_Ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
	ShutDown(2);
	pos=m_pObSock->Find(this);
	if(pos) m_pObSock->RemoveAt(pos);//主动关闭
	Close();
	m_pList->AddMsg(str,M_WARING);
	delete this;

}

void CSslServerSocket::SSlShouDown()
{
	if(m_Ctx!=NULL)
	{
		SSL_CTX_free(m_Ctx);
		m_Ctx=NULL;
	}
	if(m_Ssl!=NULL)
	{
		SSL_shutdown(m_Ssl);
		SSL_free(m_Ssl);
		m_Ssl=NULL;
	}
	if(m_hSocket != INVALID_SOCKET)
	{
		ShutDown(2);
		Close();
	}
}

int CSslServerSocket::Verify(int ok, X509_STORE_CTX *ctx)
{
	char buf[256];
	X509 *err_cert;
	int err,depth;
	char out[100]={0};
	int	verify_depth=1;
	long verify_error;
	err_cert=X509_STORE_CTX_get_current_cert(ctx);
	err=	X509_STORE_CTX_get_error(ctx);
	depth=	X509_STORE_CTX_get_error_depth(ctx);

	X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
	sprintf(out,"depth=%d %s\n",depth,buf);
	if (!ok)
		{
		sprintf(out,"verify error:num=%d:%s\n",err,
			X509_verify_cert_error_string(err));
		if (verify_depth >= depth)
			{
			ok=1;
			verify_error=X509_V_OK;
			}
		else
			{
			ok=0;
			verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
			}
		}
	switch (ctx->error)
		{
	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
		X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
		sprintf(out,"issuer= %s\n",buf);
		break;
	case X509_V_ERR_CERT_NOT_YET_VALID:
	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
		sprintf(out,"notBefore=");
		break;
	case X509_V_ERR_CERT_HAS_EXPIRED:
	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
		sprintf(out,"notAfter=");
		break;
		}
	return(ok);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -