typedef SSL_SESSION* (__cdecl* _SSL_get_session)(SSL*);\r
typedef int (__cdecl* _SSL_set_session)(SSL*, SSL_SESSION*);\r
typedef X509_STORE* (__cdecl* _SSL_CTX_get_cert_store)(const SSL_CTX*);\r
+typedef long (__cdecl* _SSL_CTX_ctrl)(SSL_CTX*, int, long, void*);\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 int (__cdecl* _X509_print_ex)(BIO*, X509*, unsigned long, unsigned long);\r
typedef X509_NAME* (__cdecl* _X509_get_subject_name)(X509*);\r
typedef int (__cdecl* _X509_NAME_print_ex)(BIO*, X509_NAME*, int, unsigned long);\r
+typedef void (__cdecl* _X509_CRL_free)(X509_CRL*);\r
+typedef EVP_PKEY* (__cdecl* _PEM_read_bio_PUBKEY)(BIO*, EVP_PKEY**, pem_password_cb*, void*);\r
typedef X509* (__cdecl* _PEM_read_bio_X509)(BIO*, X509**, pem_password_cb*, void*);\r
+typedef X509_CRL* (__cdecl* _PEM_read_bio_X509_CRL)(BIO*, X509_CRL**, pem_password_cb*, void*);\r
typedef int (__cdecl* _X509_STORE_add_cert)(X509_STORE*, X509*);\r
+typedef int (__cdecl* _X509_STORE_add_crl)(X509_STORE*, X509_CRL*);\r
+typedef void (__cdecl* _EVP_PKEY_free)(EVP_PKEY*);\r
+typedef RSA* (__cdecl* _EVP_PKEY_get1_RSA)(EVP_PKEY*);\r
+typedef void (__cdecl* _RSA_free)(RSA*);\r
+typedef int (__cdecl* _RSA_size)(const RSA*);\r
+typedef int (__cdecl* _RSA_public_decrypt)(int, const unsigned char*, unsigned char*, RSA*, int);\r
+typedef unsigned char* (__cdecl* _SHA1)(const unsigned char*, size_t, unsigned char*);\r
+typedef unsigned char* (__cdecl* _SHA224)(const unsigned char*, size_t, unsigned char*);\r
+typedef unsigned char* (__cdecl* _SHA256)(const unsigned char*, size_t, unsigned char*);\r
+typedef unsigned char* (__cdecl* _SHA384)(const unsigned char*, size_t, unsigned char*);\r
+typedef unsigned char* (__cdecl* _SHA512)(const unsigned char*, size_t, unsigned char*);\r
\r
_SSL_load_error_strings p_SSL_load_error_strings;\r
_SSL_library_init p_SSL_library_init;\r
_SSL_get_session p_SSL_get_session;\r
_SSL_set_session p_SSL_set_session;\r
_SSL_CTX_get_cert_store p_SSL_CTX_get_cert_store;\r
+_SSL_CTX_ctrl p_SSL_CTX_ctrl;\r
_BIO_s_mem p_BIO_s_mem;\r
_BIO_new p_BIO_new;\r
_BIO_free p_BIO_free;\r
_X509_print_ex p_X509_print_ex;\r
_X509_get_subject_name p_X509_get_subject_name;\r
_X509_NAME_print_ex p_X509_NAME_print_ex;\r
+_X509_CRL_free p_X509_CRL_free;\r
+_PEM_read_bio_PUBKEY p_PEM_read_bio_PUBKEY;\r
_PEM_read_bio_X509 p_PEM_read_bio_X509;\r
+_PEM_read_bio_X509_CRL p_PEM_read_bio_X509_CRL;\r
_X509_STORE_add_cert p_X509_STORE_add_cert;\r
+_X509_STORE_add_crl p_X509_STORE_add_crl;\r
+_EVP_PKEY_free p_EVP_PKEY_free;\r
+_EVP_PKEY_get1_RSA p_EVP_PKEY_get1_RSA;\r
+_RSA_free p_RSA_free;\r
+_RSA_size p_RSA_size;\r
+_RSA_public_decrypt p_RSA_public_decrypt;\r
+_SHA1 p_SHA1;\r
+_SHA224 p_SHA224;\r
+_SHA256 p_SHA256;\r
+_SHA384 p_SHA384;\r
+_SHA512 p_SHA512;\r
\r
#define MAX_SSL_SOCKET 16\r
\r
return FALSE;\r
#ifdef ENABLE_PROCESS_PROTECTION\r
// 同梱するOpenSSLのバージョンに合わせてSHA1ハッシュ値を変更すること\r
- // ssleay32.dll 1.0.0e\r
- // libssl32.dll 1.0.0e\r
- RegisterTrustedModuleSHA1Hash("\x4E\xB7\xA0\x22\x14\x4B\x58\x6D\xBC\xF5\x21\x0D\x96\x78\x0D\x79\x7D\x66\xB2\xB0");\r
- // libeay32.dll 1.0.0e\r
- RegisterTrustedModuleSHA1Hash("\x01\x32\x7A\xAE\x69\x26\xE6\x58\xC7\x63\x22\x1E\x53\x5A\x78\xBC\x61\xC7\xB5\xC1");\r
+#if defined(_M_IX86)\r
+ // ssleay32.dll 1.0.1g\r
+ RegisterTrustedModuleSHA1Hash("\xCB\xBA\x62\x61\x3C\x44\x1E\x94\xD2\xF4\xAD\xD5\x03\x43\x6F\x26\xD2\xAF\x2F\x21");\r
+ // libeay32.dll 1.0.1g\r
+ RegisterTrustedModuleSHA1Hash("\x4E\x53\x29\xC4\x32\x1B\x17\xA5\x4D\x40\xDF\x6F\xF6\xD2\x53\x7E\xBC\x54\x69\x1B");\r
+#elif defined(_M_AMD64)\r
+ // ssleay32.dll 1.0.1g\r
+ RegisterTrustedModuleSHA1Hash("\x10\x08\xFE\x10\x3A\xB2\xEC\x9E\x13\xAF\x29\xD7\xF4\xFC\x90\xE3\x9B\x8D\xAF\x12");\r
+ // libeay32.dll 1.0.1g\r
+ RegisterTrustedModuleSHA1Hash("\x30\x42\xCF\x84\x2B\x3F\x17\x3B\xF7\x97\xA5\x2B\x5F\x1A\x5A\xA2\x04\x02\x92\x92");\r
+#endif\r
#endif\r
g_hOpenSSL = LoadLibrary("ssleay32.dll");\r
// バージョン固定のためlibssl32.dllの読み込みは脆弱性の原因になり得るので廃止\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
- || !(p_SSL_CTX_get_cert_store = (_SSL_CTX_get_cert_store)GetProcAddress(g_hOpenSSL, "SSL_CTX_get_cert_store")))\r
+ || !(p_SSL_CTX_get_cert_store = (_SSL_CTX_get_cert_store)GetProcAddress(g_hOpenSSL, "SSL_CTX_get_cert_store"))\r
+ || !(p_SSL_CTX_ctrl = (_SSL_CTX_ctrl)GetProcAddress(g_hOpenSSL, "SSL_CTX_ctrl")))\r
{\r
if(g_hOpenSSL)\r
FreeLibrary(g_hOpenSSL);\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_NAME_print_ex = (_X509_NAME_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_NAME_print_ex"))\r
+ || !(p_X509_CRL_free = (_X509_CRL_free)GetProcAddress(g_hOpenSSLCommon, "X509_CRL_free"))\r
+ || !(p_PEM_read_bio_PUBKEY = (_PEM_read_bio_PUBKEY)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_PUBKEY"))\r
|| !(p_PEM_read_bio_X509 = (_PEM_read_bio_X509)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_X509"))\r
- || !(p_X509_STORE_add_cert = (_X509_STORE_add_cert)GetProcAddress(g_hOpenSSLCommon, "X509_STORE_add_cert")))\r
+ || !(p_PEM_read_bio_X509_CRL = (_PEM_read_bio_X509_CRL)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_X509_CRL"))\r
+ || !(p_X509_STORE_add_cert = (_X509_STORE_add_cert)GetProcAddress(g_hOpenSSLCommon, "X509_STORE_add_cert"))\r
+ || !(p_X509_STORE_add_crl = (_X509_STORE_add_crl)GetProcAddress(g_hOpenSSLCommon, "X509_STORE_add_crl"))\r
+ || !(p_EVP_PKEY_free = (_EVP_PKEY_free)GetProcAddress(g_hOpenSSLCommon, "EVP_PKEY_free"))\r
+ || !(p_EVP_PKEY_get1_RSA = (_EVP_PKEY_get1_RSA)GetProcAddress(g_hOpenSSLCommon, "EVP_PKEY_get1_RSA"))\r
+ || !(p_RSA_free = (_RSA_free)GetProcAddress(g_hOpenSSLCommon, "RSA_free"))\r
+ || !(p_RSA_size = (_RSA_size)GetProcAddress(g_hOpenSSLCommon, "RSA_size"))\r
+ || !(p_RSA_public_decrypt = (_RSA_public_decrypt)GetProcAddress(g_hOpenSSLCommon, "RSA_public_decrypt"))\r
+ || !(p_SHA1 = (_SHA1)GetProcAddress(g_hOpenSSLCommon, "SHA1"))\r
+ || !(p_SHA224 = (_SHA224)GetProcAddress(g_hOpenSSLCommon, "SHA224"))\r
+ || !(p_SHA256 = (_SHA256)GetProcAddress(g_hOpenSSLCommon, "SHA256"))\r
+ || !(p_SHA384 = (_SHA384)GetProcAddress(g_hOpenSSLCommon, "SHA384"))\r
+ || !(p_SHA512 = (_SHA512)GetProcAddress(g_hOpenSSLCommon, "SHA512")))\r
{\r
if(g_hOpenSSL)\r
FreeLibrary(g_hOpenSSL);\r
BYTE* p;\r
BYTE* pBegin;\r
BYTE* pEnd;\r
+ DWORD Left;\r
BIO* pBIO;\r
X509* pX509;\r
+ X509_CRL* pX509_CRL;\r
if(!g_bOpenSSLLoaded)\r
return FALSE;\r
r = FALSE;\r
EnterCriticalSection(&g_OpenSSLLock);\r
if(!g_pOpenSSLCTX)\r
+ {\r
g_pOpenSSLCTX = p_SSL_CTX_new(p_SSLv23_method());\r
+ p_SSL_CTX_ctrl(g_pOpenSSLCTX, SSL_CTRL_MODE, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_AUTO_RETRY, NULL);\r
+ }\r
if(g_pOpenSSLCTX)\r
{\r
if(pStore = p_SSL_CTX_get_cert_store(g_pOpenSSLCTX))\r
p = (BYTE*)pData;\r
pBegin = NULL;\r
pEnd = NULL;\r
- while(Length > 0)\r
+ Left = Length;\r
+ while(Left > 0)\r
{\r
if(!pBegin)\r
{\r
- if(Length < 27)\r
+ if(Left < 27)\r
break;\r
if(memcmp(p, "-----BEGIN CERTIFICATE-----", 27) == 0)\r
pBegin = p;\r
}\r
else if(!pEnd)\r
{\r
- if(Length < 25)\r
+ if(Left < 25)\r
break;\r
if(memcmp(p, "-----END CERTIFICATE-----", 25) == 0)\r
pEnd = p + 25;\r
pEnd = NULL;\r
}\r
p++;\r
- Length--;\r
+ Left--;\r
+ }\r
+ p = (BYTE*)pData;\r
+ pBegin = NULL;\r
+ pEnd = NULL;\r
+ Left = Length;\r
+ while(Left > 0)\r
+ {\r
+ if(!pBegin)\r
+ {\r
+ if(Left < 24)\r
+ break;\r
+ if(memcmp(p, "-----BEGIN X509 CRL-----", 24) == 0)\r
+ pBegin = p;\r
+ }\r
+ else if(!pEnd)\r
+ {\r
+ if(Left < 22)\r
+ break;\r
+ if(memcmp(p, "-----END X509 CRL-----", 22) == 0)\r
+ pEnd = p + 22;\r
+ }\r
+ if(pBegin && pEnd)\r
+ {\r
+ if(pBIO = p_BIO_new_mem_buf(pBegin, (int)((size_t)pEnd - (size_t)pBegin)))\r
+ {\r
+ if(pX509_CRL = p_PEM_read_bio_X509_CRL(pBIO, NULL, NULL, NULL))\r
+ {\r
+ if(p_X509_STORE_add_crl(pStore, pX509_CRL) == 1)\r
+ r = TRUE;\r
+ p_X509_CRL_free(pX509_CRL);\r
+ }\r
+ p_BIO_free(pBIO);\r
+ }\r
+ pBegin = NULL;\r
+ pEnd = NULL;\r
+ }\r
+ p++;\r
+ Left--;\r
}\r
}\r
}\r
return bResult;\r
}\r
\r
+// RSA復号化\r
+// 主に自動更新ファイルのハッシュの改竄確認\r
+BOOL DecryptSignature(const char* PublicKey, const void* pIn, DWORD InLength, void* pOut, DWORD OutLength, DWORD* pOutLength)\r
+{\r
+ BOOL bResult;\r
+ BIO* pBIO;\r
+ EVP_PKEY* pPKEY;\r
+ RSA* pRSA;\r
+ int i;\r
+ bResult = FALSE;\r
+ if(pBIO = p_BIO_new_mem_buf((void*)PublicKey, sizeof(char) * strlen(PublicKey)))\r
+ {\r
+ if(pPKEY = p_PEM_read_bio_PUBKEY(pBIO, NULL, NULL, NULL))\r
+ {\r
+ if(pRSA = p_EVP_PKEY_get1_RSA(pPKEY))\r
+ {\r
+ if(p_RSA_size(pRSA) <= (int)OutLength)\r
+ {\r
+ i = p_RSA_public_decrypt((int)InLength, (const unsigned char*)pIn, (unsigned char*)pOut, pRSA, RSA_PKCS1_PADDING);\r
+ if(i >= 0)\r
+ {\r
+ *pOutLength = (DWORD)i;\r
+ bResult = TRUE;\r
+ }\r
+ }\r
+ p_RSA_free(pRSA);\r
+ }\r
+ p_EVP_PKEY_free(pPKEY);\r
+ }\r
+ p_BIO_free(pBIO);\r
+ }\r
+ return bResult;\r
+}\r
+\r
+// ハッシュ計算\r
+// 他にも同等の関数はあるが主にマルウェア対策のための冗長化\r
+void GetHashSHA1(const void* pData, DWORD Size, void* pHash)\r
+{\r
+ p_SHA1((const unsigned char*)pData, (size_t)Size, (unsigned char*)pHash);\r
+}\r
+\r
+void GetHashSHA224(const void* pData, DWORD Size, void* pHash)\r
+{\r
+ p_SHA224((const unsigned char*)pData, (size_t)Size, (unsigned char*)pHash);\r
+}\r
+\r
+void GetHashSHA256(const void* pData, DWORD Size, void* pHash)\r
+{\r
+ p_SHA256((const unsigned char*)pData, (size_t)Size, (unsigned char*)pHash);\r
+}\r
+\r
+void GetHashSHA384(const void* pData, DWORD Size, void* pHash)\r
+{\r
+ p_SHA384((const unsigned char*)pData, (size_t)Size, (unsigned char*)pHash);\r
+}\r
+\r
+void GetHashSHA512(const void* pData, DWORD Size, void* pHash)\r
+{\r
+ p_SHA512((const unsigned char*)pData, (size_t)Size, (unsigned char*)pHash);\r
+}\r
+\r
// SSLセッションを開始\r
BOOL AttachSSL(SOCKET s, SOCKET parent, BOOL* pbAborted)\r
{\r
Time = timeGetTime();\r
EnterCriticalSection(&g_OpenSSLLock);\r
if(!g_pOpenSSLCTX)\r
+ {\r
g_pOpenSSLCTX = p_SSL_CTX_new(p_SSLv23_method());\r
+ p_SSL_CTX_ctrl(g_pOpenSSLCTX, SSL_CTRL_MODE, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_AUTO_RETRY, NULL);\r
+ }\r
if(g_pOpenSSLCTX)\r
{\r
if(ppSSL = GetUnusedSSLPointer())\r
// send相当の関数\r
int FTPS_send(SOCKET s, const char * buf, int len, int flags)\r
{\r
+ int r;\r
SSL** ppSSL;\r
if(!g_bOpenSSLLoaded)\r
return send(s, buf, len, flags);\r
LeaveCriticalSection(&g_OpenSSLLock);\r
if(!ppSSL)\r
return send(s, buf, len, flags);\r
- return p_SSL_write(*ppSSL, buf, len);\r
+ r = p_SSL_write(*ppSSL, buf, len);\r
+ if(r < 0)\r
+ return SOCKET_ERROR;\r
+ return r;\r
}\r
\r
// recv相当の関数\r
int FTPS_recv(SOCKET s, char * buf, int len, int flags)\r
{\r
+ int r;\r
SSL** ppSSL;\r
if(!g_bOpenSSLLoaded)\r
return recv(s, buf, len, flags);\r
if(!ppSSL)\r
return recv(s, buf, len, flags);\r
if(flags & MSG_PEEK)\r
- return p_SSL_peek(*ppSSL, buf, len);\r
- return p_SSL_read(*ppSSL, buf, len);\r
+ r = p_SSL_peek(*ppSSL, buf, len);\r
+ else\r
+ r = p_SSL_read(*ppSSL, buf, len);\r
+ if(r < 0)\r
+ return SOCKET_ERROR;\r
+ return r;\r
}\r
\r
// IPv6対応\r
\r
+const struct in6_addr IN6ADDR_NONE = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};\r
+\r
typedef struct\r
{\r
HANDLE h;\r
pHost->h_addr_list[0] = (char*)(&pHost->h_addr_list[2]);\r
pHost->h_addr_list[1] = NULL;\r
memcpy(pHost->h_addr_list[0], &((struct sockaddr_in*)p->ai_addr)->sin_addr, sizeof(struct in_addr));\r
- PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(sizeof(struct hostent) + sizeof(char*) * 2 + p->ai_addrlen));\r
+ PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(sizeof(struct hostent) + sizeof(char*) * 2 + sizeof(struct in_addr)));\r
}\r
else\r
PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(WSAENOBUFS << 16));\r
pHost->h_addr_list[0] = (char*)(&pHost->h_addr_list[2]);\r
pHost->h_addr_list[1] = NULL;\r
memcpy(pHost->h_addr_list[0], &((struct sockaddr_in6*)p->ai_addr)->sin6_addr, sizeof(struct in6_addr));\r
- PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(sizeof(struct hostent) + sizeof(char*) * 2 + p->ai_addrlen));\r
+ PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(sizeof(struct hostent) + sizeof(char*) * 2 + sizeof(struct in6_addr)));\r
}\r
else\r
PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(WSAENOBUFS << 16));\r
}\r
else\r
PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(ERROR_INVALID_FUNCTION << 16));\r
- free(pData->name);\r
- free(pData);\r
// CreateThreadが返すハンドルが重複するのを回避\r
Sleep(10000);\r
+ CloseHandle(pData->h);\r
+ free(pData->name);\r
+ free(pData);\r
return 0;\r
}\r
\r
int Result;\r
Result = SOCKET_ERROR;\r
if(TerminateThread(hAsyncTaskHandle, 0))\r
+ {\r
+ CloseHandle(hAsyncTaskHandle);\r
Result = 0;\r
+ }\r
return Result;\r
}\r
\r
+char* AddressToStringIPv4(char* str, void* in)\r
+{\r
+ char* pResult;\r
+ unsigned char* p;\r
+ pResult = str;\r
+ p = (unsigned char*)in;\r
+ sprintf(str, "%u.%u.%u.%u", p[0], p[1], p[2], p[3]);\r
+ return pResult;\r
+}\r
+\r
char* AddressToStringIPv6(char* str, void* in6)\r
{\r
char* pResult;\r
{\r
if(!cp)\r
{\r
- memset(&Result, 0xff, sizeof(Result));\r
+ memcpy(&Result, &IN6ADDR_NONE, sizeof(struct in6_addr));\r
break;\r
}\r
if(i >= AfterZero)\r
Result.u.Word[i] = ((Result.u.Word[i] & 0xff00) >> 8) | ((Result.u.Word[i] & 0x00ff) << 8);\r
if(strncmp(p, ":", 1) != 0 && strlen(p) > 0)\r
{\r
- memset(&Result, 0xff, sizeof(Result));\r
+ memcpy(&Result, &IN6ADDR_NONE, sizeof(struct in6_addr));\r
break;\r
}\r
if(cp = strstr(cp, ":"))\r
Length = 0;\r
while(*InputString != '\0')\r
{\r
- *p = (punycode_uint)GetNextCharM(InputString, &InputString);\r
+ *p = (punycode_uint)GetNextCharM(InputString, NULL, &InputString);\r
if(*p >= 0x80)\r
bNeeded = TRUE;\r
p++;\r
return FALSE;\r
#ifdef ENABLE_PROCESS_PROTECTION\r
// ビルドしたputty.dllに合わせてSHA1ハッシュ値を変更すること\r
+#if defined(_M_IX86)\r
RegisterTrustedModuleSHA1Hash("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");\r
+#elif defined(_M_AMD64)\r
+ RegisterTrustedModuleSHA1Hash("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");\r
+#endif\r
#endif\r
// デバッグ用\r
-// g_hPuTTY = LoadLibrary("putty.dll");\r
- g_hPuTTY = LoadLibrary("C:\\SourceForge\\ffftp\\putty\\Debug\\PuTTY.dll");\r
+#ifdef _DEBUG\r
+ {\r
+ char Path[MAX_PATH];\r
+ GetModuleFileName(NULL, Path, MAX_PATH);\r
+ strcpy(strrchr(Path, '\\'), "\\..\\putty\\Debug\\PuTTY.dll");\r
+ g_hPuTTY = LoadLibrary(Path);\r
+ }\r
+#else\r
+ g_hPuTTY = LoadLibrary("putty.dll");\r
+#endif\r
if(!g_hPuTTY\r
|| !(p_SFTP_Create = (_SFTP_Create)GetProcAddress(g_hPuTTY, "SFTP_Create"))\r
|| !(p_SFTP_Destroy = (_SFTP_Destroy)GetProcAddress(g_hPuTTY, "SFTP_Destroy"))\r