欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

asyncsslsocketlayer.cpp

AsynSocketDemo.rar网络代码,可以设置代理,ssl加密. AsynSocketDemo.rar网络代码,可以设置代理,ssl加密. AsynSocketDemo.rar网络代码,
CPP
第 1 页 / 共 3 页
字号:
			{
				return pBIO_read(m_sslbio, lpBuf,nBufLen);
			}
			WSASetLastError(m_nNetworkError);
			return SOCKET_ERROR;
		}
		if (m_nShutDown)
		{
			SetLastError(WSAESHUTDOWN);
			return SOCKET_ERROR;
		}
		CAsyncSslSocketLayer::OnReceive(1);
		if (!nBufLen)
			return 0;
		if (!pBIO_ctrl(m_sslbio, BIO_CTRL_PENDING, 0, NULL))
		{
			SetLastError(WSAEWOULDBLOCK);
			return SOCKET_ERROR;
		}
		int numread=pBIO_read(m_sslbio, lpBuf, nBufLen);
		if (pBIO_ctrl(m_nbio, BIO_CTRL_PENDING, 0, NULL))
			CAsyncSslSocketLayer::OnSend(0);
		if (numread<0)
			if (!BIO_should_retry(m_sslbio))
			{
				m_nNetworkError=WSAECONNABORTED;
				WSASetLastError(WSAECONNABORTED);
				TriggerEvent(FD_CLOSE, 0);
				return SOCKET_ERROR;
			}
			else
			{
				SetLastError(WSAEWOULDBLOCK);
				return SOCKET_ERROR;
			}
			if (pBIO_ctrl(m_sslbio, BIO_CTRL_PENDING, 0, NULL))
			{
				TriggerEvent(FD_FORCEREAD, 0);
				TriggerEvent(FD_WRITE, 0);
			}
		return numread;
	}
	else
		return ReceiveNext(lpBuf, nBufLen, nFlags);
}

void CAsyncSslSocketLayer::Close()
{
	m_nShutDown = 0;
	ResetSslSession();
	CloseNext();
}

BOOL CAsyncSslSocketLayer::Connect(const SOCKADDR *lpSockAddr, int nSockAddrLen)
{
	BOOL res = ConnectNext(lpSockAddr, nSockAddrLen);
	if (!res)
		if (GetLastError() != WSAEWOULDBLOCK)
			ResetSslSession();
	return res;
}

BOOL CAsyncSslSocketLayer::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
{
	BOOL res = ConnectNext(lpszHostAddress, nHostPort);
	if (!res)
		if (GetLastError()!=WSAEWOULDBLOCK)
			ResetSslSession();
	return res;
}

bool CAsyncSslSocketLayer::InitClientSSL()
{
	if (m_bUseSSL)
		return true;
	if (!InitSSL())
		return false;

	//Create new SSL session
	if (!(m_ssl = pSSL_new( m_ssl_ctx )))
	{
		if (!m_bFailureSent)
		{
			m_bFailureSent=TRUE;
			DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, SSL_FAILURE, SSL_FAILURE_INITSSL);
		}
		ResetSslSession();
		return false;
	}

	//Add current instance to list of active instances
	m_sCriticalSection.Lock();
	t_SslLayerList *tmp = m_pSslLayerList;
	m_pSslLayerList = new t_SslLayerList;
	m_pSslLayerList->pNext = tmp;
	m_pSslLayerList->pLayer = this;
	m_sCriticalSection.Unlock();

	pSSL_set_info_callback(m_ssl, (void(*)())apps_ssl_info_callback);

	//Create bios
	m_sslbio = pBIO_new(pBIO_f_ssl());
	pBIO_new_bio_pair(&m_ibio, 256, &m_nbio, 256);

	if (!m_sslbio || !m_nbio || !m_ibio)
	{
		if (!m_bFailureSent)
		{
			m_bFailureSent = TRUE;
			DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, SSL_FAILURE, SSL_FAILURE_INITSSL);
		}
		ResetSslSession();
		return false;
	}

	//Init SSL connection
	pSSL_set_session(m_ssl, NULL);
	pSSL_set_connect_state(m_ssl);
	pSSL_set_bio(m_ssl, m_ibio, m_ibio);
	pBIO_ctrl(m_sslbio, BIO_C_SET_SSL, BIO_NOCLOSE, m_ssl);
	pBIO_read(m_sslbio, (void *)1, 0);

	// Trigger FD_WRITE so that we can initialize SSL negotiation
	if (GetLayerState() == connected)
		TriggerEvent(FD_WRITE, 0);

	m_bUseSSL = true;

	return true;
}

void CAsyncSslSocketLayer::ResetSslSession()
{
	m_bFailureSent = FALSE;
	m_bBlocking = FALSE;
	m_nSslAsyncNotifyId++;
	m_nNetworkError = 0;

	m_bSslEstablished = FALSE;
	if (m_ssl)
		pSSL_set_session(m_ssl,NULL);
	if (m_nbio)
		pBIO_free(m_nbio);
	if (m_ibio)
		pBIO_free(m_ibio);
	if (m_sslbio)
		pBIO_free(m_sslbio);

	delete [] m_pNetworkSendBuffer;
	m_pNetworkSendBuffer = NULL;
	m_nNetworkSendBufferLen = 0;

	m_nbio = 0;
	m_ibio = 0;
	m_sslbio = 0;

	if (m_ssl)
		pSSL_free(m_ssl);
	m_sCriticalSection.Lock();

	m_ssl = 0;

	t_SslLayerList *cur = m_pSslLayerList;
	if (!cur)
	{
		m_sCriticalSection.Unlock();
		return;
	}

	if (cur->pLayer == this)
	{
		m_pSslLayerList = cur->pNext;
		delete cur;
	}
	else
		while (cur->pNext)
		{
			if (cur->pNext->pLayer == this)
			{
				t_SslLayerList *tmp = cur->pNext;
				cur->pNext = cur->pNext->pNext;
				delete tmp;

				m_sCriticalSection.Unlock();
				return;
			}
			cur = cur->pNext;
		}
	m_sCriticalSection.Unlock();
}

bool CAsyncSslSocketLayer::IsUsingSSL()
{
	return m_bUseSSL;
}

BOOL CAsyncSslSocketLayer::ShutDown(int nHow /*=sends*/)
{
	if (!m_nShutDown)
		m_nShutDown = 1;
	if (m_bUseSSL)
	{
		if (ShutDownComplete())
			return TRUE;
		if (pSSL_shutdown(m_ssl) != -1)
			return ShutDownNext();
		else
		{
			int error = pSSL_get_error(m_ssl,-1);
			if (error==SSL_ERROR_WANT_READ || error==SSL_ERROR_WANT_WRITE)
				return ShutDownNext();
			else
			{
				WSASetLastError(WSAEWOULDBLOCK);
				return FALSE;
			}
		}
	}
	else
		return ShutDownNext();
}

BOOL CAsyncSslSocketLayer::ShutDownComplete()
{
	//If a ShutDown was issued, has the connection already been shut down?
	if (!m_nShutDown)
		return FALSE;
	else if (!m_bUseSSL)
		return FALSE;
	else if (m_nNetworkSendBufferLen)
		return FALSE;
	else if (pBIO_ctrl_pending(m_nbio))
		return FALSE;
	else
		return TRUE;
}

void CAsyncSslSocketLayer::apps_ssl_info_callback(SSL *s, int where, int ret)
{
	CAsyncSslSocketLayer *pLayer = 0;
	m_sCriticalSection.Lock();
	t_SslLayerList *cur = m_pSslLayerList;
	while (cur)
	{
		if (cur->pLayer->m_ssl == s)
			break;
		cur = cur->pNext;
	}
	if (!cur)
	{
		m_sCriticalSection.Unlock();
		MessageBox(0, _T("Can't lookup SSL session!"), _T("Critical error"), MB_ICONEXCLAMATION);
		return;
	}
	else
		pLayer = cur->pLayer;
	m_sCriticalSection.Unlock();

	LPCTSTR str;
	int w;

	w=where& ~SSL_ST_MASK;

	if (w & SSL_ST_CONNECT) str=_T("SSL_connect");
	else if (w & SSL_ST_ACCEPT) str=_T("SSL_accept");
	else str=_T("undefined");

	if (where & SSL_CB_LOOP)
	{
		TCHAR buffer[4096];
		sprintf(buffer, "%s:%s",
				str,
				pSSL_state_string_long(s));
		pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, SSL_VERBOSE_INFO, (int)buffer);
	}
	else if (where & SSL_CB_ALERT)
	{
		/*if (ret==SSL_AD_CLOSE_NOTIFY)
			if (!pLayer->m_nNetworkError)
				pLayer->m_nNetworkError=WSAESHUTDOWN;*/
		str=(where & SSL_CB_READ)?_T("read"):_T("write");
		TCHAR buffer[4096];
		sprintf(buffer, "SSL3 alert %s:%s:%s",
				str,
				pSSL_alert_type_string_long(ret),
				pSSL_alert_desc_string_long(ret));
		pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, SSL_VERBOSE_WARNING, (int)buffer);
	}

	else if (where & SSL_CB_EXIT)
	{
		if (ret == 0)
		{
			TCHAR buffer[4096];
			sprintf(buffer, "%s:failed in %s",
					str,
					pSSL_state_string_long(s));
			pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, SSL_VERBOSE_WARNING, (int)buffer);
			if (!pLayer->m_bFailureSent)
			{
				pLayer->m_bFailureSent=TRUE;
				pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, SSL_FAILURE, pLayer->m_bSslEstablished ? SSL_FAILURE_UNKNOWN : SSL_FAILURE_ESTABLISH);
			}
		}
		else if (ret < 0)
		{
			int error=pSSL_get_error(s,ret);
			if (error!=SSL_ERROR_WANT_READ && error!=SSL_ERROR_WANT_WRITE)
			{
				TCHAR buffer[4096];
				sprintf(buffer, "%s: error in %s",
						str,
						pSSL_state_string_long(s));
				pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, SSL_VERBOSE_WARNING, (int)buffer);
				if (!pLayer->m_bFailureSent)
				{
					pLayer->m_bFailureSent=TRUE;
					pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, SSL_FAILURE, pLayer->m_bSslEstablished ? SSL_FAILURE_UNKNOWN : SSL_FAILURE_ESTABLISH);
				}
			}
		}
	}
	if (where&SSL_CB_HANDSHAKE_DONE)
	{
		int error = pSSL_get_verify_result(pLayer->m_ssl);
		if (error)
		{
			int res = pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, SSL_VERIFY_CERT, error);
			if (res==2)
			{
				pLayer->m_bBlocking=TRUE;
				return;
			}
			else if (!res)
			{
				pLayer->m_nNetworkError = WSAECONNABORTED;
				WSASetLastError(WSAECONNABORTED);
				if (!pLayer->m_bFailureSent)
				{
					pLayer->m_bFailureSent=TRUE;
					pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, SSL_FAILURE, SSL_FAILURE_VERIFYCERT);
				}
				return;
			}
		}
		pLayer->m_bSslEstablished = TRUE;
		pLayer->PrintSessionInfo();
		pLayer->DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, SSL_INFO, SSL_INFO_ESTABLISHED);
	}
}


void CAsyncSslSocketLayer::UnloadSSL()
{
	if (!m_bSslInitialized)
		return;
	ResetSslSession();

	m_bSslInitialized = false;

	m_sCriticalSection.Lock();
	m_nSslRefCount--;
	if (m_nSslRefCount)
	{
		m_sCriticalSection.Unlock();
		return;
	}
	if (m_ssl_ctx)
		pSSL_CTX_free(m_ssl_ctx);
	m_ssl_ctx = 0;

	if (m_hSslDll1)
		FreeLibrary(m_hSslDll1);
	if (m_hSslDll2)
		FreeLibrary(m_hSslDll2);
	m_hSslDll1 = NULL;
	m_hSslDll2 = NULL;

	m_sCriticalSection.Unlock();
}

BOOL CAsyncSslSocketLayer::GetPeerCertificateData(t_SslCertData &SslCertData)
{
	X509 *pX509=pSSL_get_peer_certificate(m_ssl);
	if (!pX509)
		return FALSE;

	//Reset the contents of SslCertData
	memset(&SslCertData, 0, sizeof(t_SslCertData));

	//Set subject data fields
	X509_NAME *pX509Name=pX509_get_subject_name(pX509);

	if (pX509Name)
	{
		int count=pX509_NAME_entry_count(pX509Name);
		for (int i=0;i<count;i++)
		{
			X509_NAME_ENTRY *pX509NameEntry=pX509_NAME_get_entry(pX509Name,i);
			if (!pX509NameEntry)
				continue;
			ASN1_STRING *pString=pX509_NAME_ENTRY_get_data(pX509NameEntry);
			ASN1_OBJECT *pObject=pX509_NAME_ENTRY_get_object(pX509NameEntry);
			const char *str = reinterpret_cast<const char *>(pString->data);
			switch(pOBJ_obj2nid(pObject))
			{
			case NID_organizationName:
				strncpy(SslCertData.subject.Organization, str, 255);
				SslCertData.subject.Organization[255] = 0;
				break;
			case NID_organizationalUnitName:
				strncpy(SslCertData.subject.Unit, str, 255);
				SslCertData.subject.Unit[255] = 0;
				break;
			case NID_commonName:
				strncpy(SslCertData.subject.CommonName, str, 255);
				SslCertData.subject.CommonName[255] = 0;
				break;
			case NID_pkcs9_emailAddress:
				strncpy(SslCertData.subject.Mail, str, 255);
				SslCertData.subject.Mail[255] = 0;
				break;
			case NID_countryName:
				strncpy(SslCertData.subject.Country, str, 255);
				SslCertData.subject.Country[255] = 0;
				break;
			case NID_stateOrProvinceName:
				strncpy(SslCertData.subject.StateProvince, str, 255);
				SslCertData.subject.StateProvince[255] = 0;
				break;
			case NID_localityName:
				strncpy(SslCertData.subject.Town, str, 255);
				SslCertData.subject.Town[255] = 0;
				break;
			default:
				if ( pOBJ_nid2sn(pOBJ_obj2nid(pObject)) )
				{
					TCHAR tmp[20];
					sprintf(tmp, "%d", pOBJ_obj2nid(pObject));
					int maxlen = 1024 - strlen(SslCertData.subject.Other)-1;
					strncpy(SslCertData.subject.Other+strlen(SslCertData.subject.Other), tmp, maxlen);

					maxlen = 1024 - strlen(SslCertData.subject.Other)-1;
					strncpy(SslCertData.subject.Other+strlen(SslCertData.subject.Other), "=", maxlen);

					maxlen = 1024 - strlen(SslCertData.subject.Other)-1;
					strncpy(SslCertData.subject.Other+strlen(SslCertData.subject.Other), str, maxlen);

					maxlen = 1024 - strlen(SslCertData.subject.Other)-1;
					strncpy(SslCertData.subject.Other+strlen(SslCertData.subject.Other), ";", maxlen);
				}
				else
				{
					int maxlen = 1024 - strlen(SslCertData.subject.Other)-1;
					strncpy(SslCertData.subject.Other+strlen(SslCertData.subject.Other), reinterpret_cast<const char *>(pOBJ_nid2sn(pOBJ_obj2nid(pObject))), maxlen);

					maxlen = 1024 - strlen(SslCertData.subject.Other)-1;
					strncpy(SslCertData.subject.Other+strlen(SslCertData.subject.Other), "=", maxlen);

					maxlen = 1024 - strlen(SslCertData.subject.Other)-1;
					strncpy(SslCertData.subject.Other+strlen(SslCertData.subject.Other), str, maxlen);

					maxlen = 1024 - strlen(SslCertData.subject.Other)-1;
					strncpy(SslCertData.subject.Other+strlen(SslCertData.subject.Other), ";", maxlen);
				}
				break;
			}
		}
	}

	//Set issuer data fields
	pX509Name=pX509_get_issuer_name(pX509);
	if (pX509Name)
	{
		int count=pX509_NAME_entry_count(pX509Name);
		for (int i=0;i<count;i++)

⌨️ 快捷键说明

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