typedef int (__cdecl* _SSL_get_error)(SSL*, int);\r
typedef X509* (__cdecl* _SSL_get_peer_certificate)(const SSL*);\r
typedef long (__cdecl* _SSL_get_verify_result)(const SSL*);\r
+typedef SSL_SESSION* (__cdecl* _SSL_get_session)(SSL*);\r
+typedef int (__cdecl* _SSL_set_session)(SSL*, SSL_SESSION*);\r
typedef BIO_METHOD* (__cdecl* _BIO_s_mem)();\r
typedef BIO* (__cdecl* _BIO_new)(BIO_METHOD*);\r
typedef int (__cdecl* _BIO_free)(BIO*);\r
typedef void (__cdecl* _X509_free)(X509*);\r
typedef int (__cdecl* _X509_print_ex)(BIO*, X509*, unsigned long, unsigned long);\r
typedef X509_NAME* (__cdecl* _X509_get_subject_name)(X509*);\r
-typedef X509_NAME* (__cdecl* _X509_get_issuer_name)(X509*);\r
typedef int (__cdecl* _X509_NAME_print_ex)(BIO*, X509_NAME*, int, unsigned long);\r
\r
_SSL_load_error_strings p_SSL_load_error_strings;\r
_SSL_get_error p_SSL_get_error;\r
_SSL_get_peer_certificate p_SSL_get_peer_certificate;\r
_SSL_get_verify_result p_SSL_get_verify_result;\r
+_SSL_get_session p_SSL_get_session;\r
+_SSL_set_session p_SSL_set_session;\r
_BIO_s_mem p_BIO_s_mem;\r
_BIO_new p_BIO_new;\r
_BIO_free p_BIO_free;\r
_X509_free p_X509_free;\r
_X509_print_ex p_X509_print_ex;\r
_X509_get_subject_name p_X509_get_subject_name;\r
-_X509_get_issuer_name p_X509_get_issuer_name;\r
_X509_NAME_print_ex p_X509_NAME_print_ex;\r
\r
#define MAX_SSL_SOCKET 64\r
SSL_CTX* g_pOpenSSLCTX;\r
SSL* g_pOpenSSLHandle[MAX_SSL_SOCKET];\r
\r
-BOOL __stdcall DefaultSSLTimeoutCallback()\r
+BOOL __stdcall DefaultSSLTimeoutCallback(BOOL* pbAborted)\r
{\r
Sleep(100);\r
- return FALSE;\r
+ return *pbAborted;\r
}\r
\r
-BOOL __stdcall DefaultSSLConfirmCallback(BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName)\r
+BOOL __stdcall DefaultSSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName)\r
{\r
return bVerified;\r
}\r
|| !(p_SSL_read = (_SSL_read)GetProcAddress(g_hOpenSSL, "SSL_read"))\r
|| !(p_SSL_get_error = (_SSL_get_error)GetProcAddress(g_hOpenSSL, "SSL_get_error"))\r
|| !(p_SSL_get_peer_certificate = (_SSL_get_peer_certificate)GetProcAddress(g_hOpenSSL, "SSL_get_peer_certificate"))\r
- || !(p_SSL_get_verify_result = (_SSL_get_verify_result)GetProcAddress(g_hOpenSSL, "SSL_get_verify_result")))\r
+ || !(p_SSL_get_verify_result = (_SSL_get_verify_result)GetProcAddress(g_hOpenSSL, "SSL_get_verify_result"))\r
+ || !(p_SSL_get_session = (_SSL_get_session)GetProcAddress(g_hOpenSSL, "SSL_get_session"))\r
+ || !(p_SSL_set_session = (_SSL_set_session)GetProcAddress(g_hOpenSSL, "SSL_set_session")))\r
{\r
if(g_hOpenSSL)\r
FreeLibrary(g_hOpenSSL);\r
|| !(p_X509_free = (_X509_free)GetProcAddress(g_hOpenSSLCommon, "X509_free"))\r
|| !(p_X509_print_ex = (_X509_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_print_ex"))\r
|| !(p_X509_get_subject_name = (_X509_get_subject_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_subject_name"))\r
- || !(p_X509_get_issuer_name = (_X509_get_issuer_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_issuer_name"))\r
|| !(p_X509_NAME_print_ex = (_X509_NAME_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_NAME_print_ex")))\r
{\r
if(g_hOpenSSL)\r
return NULL;\r
}\r
\r
-BOOL ConfirmSSLCertificate(SSL* pSSL)\r
+BOOL ConfirmSSLCertificate(SSL* pSSL, BOOL* pbAborted)\r
{\r
BOOL bResult;\r
BOOL bVerified;\r
if(pCN = strchr(pCN, ','))\r
pCN++;\r
}\r
- bResult = g_pOpenSSLConfirmCallback(bVerified, pData, pCN);\r
+ bResult = g_pOpenSSLConfirmCallback(pbAborted, bVerified, pData, pCN);\r
if(pData)\r
free(pData);\r
if(pSubject)\r
return bResult;\r
}\r
\r
-BOOL AttachSSL(SOCKET s)\r
+BOOL AttachSSL(SOCKET s, SOCKET parent, BOOL* pbAborted)\r
{\r
BOOL r;\r
DWORD Time;\r
SSL** ppSSL;\r
+ SSL** ppSSLParent;\r
+ SSL_SESSION* pSession;\r
+ int Return;\r
+ int Error;\r
if(!g_bOpenSSLLoaded)\r
return FALSE;\r
r = FALSE;\r
{\r
if(p_SSL_set_fd(*ppSSL, s) != 0)\r
{\r
- r = TRUE;\r
+ if(parent != INVALID_SOCKET)\r
+ {\r
+ if(ppSSLParent = FindSSLPointerFromSocket(parent))\r
+ {\r
+ if(pSession = p_SSL_get_session(*ppSSLParent))\r
+ {\r
+ if(p_SSL_set_session(*ppSSL, pSession) == 1)\r
+ {\r
+ }\r
+ }\r
+ }\r
+ }\r
// SSLのネゴシエーションには時間がかかる場合がある\r
- while(p_SSL_connect(*ppSSL) != 1)\r
+ r = TRUE;\r
+ while(r)\r
{\r
- LeaveCriticalSection(&g_OpenSSLLock);\r
- if(g_pOpenSSLTimeoutCallback() || (g_OpenSSLTimeout > 0 && timeGetTime() - Time >= g_OpenSSLTimeout))\r
+ Return = p_SSL_connect(*ppSSL);\r
+ if(Return == 1)\r
+ break;\r
+ Error = p_SSL_get_error(*ppSSL, Return);\r
+ if(Error == SSL_ERROR_WANT_READ || Error == SSL_ERROR_WANT_WRITE)\r
+ {\r
+ LeaveCriticalSection(&g_OpenSSLLock);\r
+ if(g_pOpenSSLTimeoutCallback(pbAborted) || (g_OpenSSLTimeout > 0 && timeGetTime() - Time >= g_OpenSSLTimeout))\r
+ r = FALSE;\r
+ EnterCriticalSection(&g_OpenSSLLock);\r
+ }\r
+ else\r
+ r = FALSE;\r
+ }\r
+ if(r)\r
+ {\r
+ if(ConfirmSSLCertificate(*ppSSL, pbAborted))\r
{\r
+ }\r
+ else\r
+ {\r
+ LeaveCriticalSection(&g_OpenSSLLock);\r
DetachSSL(s);\r
r = FALSE;\r
EnterCriticalSection(&g_OpenSSLLock);\r
- break;\r
}\r
+ }\r
+ else\r
+ {\r
+ LeaveCriticalSection(&g_OpenSSLLock);\r
+ DetachSSL(s);\r
EnterCriticalSection(&g_OpenSSLLock);\r
}\r
}\r
DetachSSL(s);\r
EnterCriticalSection(&g_OpenSSLLock);\r
}\r
- if(ConfirmSSLCertificate(*ppSSL))\r
- {\r
- }\r
- else\r
- {\r
- DetachSSL(s);\r
- r = FALSE;\r
- }\r
}\r
}\r
}\r
ppSSL = FindSSLPointerFromSocket(s);\r
LeaveCriticalSection(&g_OpenSSLLock);\r
if(!ppSSL)\r
- return TRUE;\r
+ return FALSE;\r
return TRUE;\r
}\r
\r
SOCKET acceptS(SOCKET s, struct sockaddr *addr, int *addrlen)\r
{\r
SOCKET r;\r
+ BOOL bAborted;\r
r = accept(s, addr, addrlen);\r
- if(!AttachSSL(r))\r
+ bAborted = FALSE;\r
+ if(!AttachSSL(r, INVALID_SOCKET, &bAborted))\r
{\r
closesocket(r);\r
return INVALID_SOCKET;\r
int connectS(SOCKET s, const struct sockaddr *name, int namelen)\r
{\r
int r;\r
+ BOOL bAborted;\r
r = connect(s, name, namelen);\r
- if(!AttachSSL(r))\r
+ bAborted = FALSE;\r
+ if(!AttachSSL(r, INVALID_SOCKET, &bAborted))\r
return SOCKET_ERROR;\r
return r;\r
}\r