asyncsslsocketlayer.cpp
字号:
{
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 + -