OSDN Git Service

Add routines for automatic software updates.
[ffftp/ffftp.git] / socketwrapper.c
index e4c9b29..3dad22c 100644 (file)
@@ -49,8 +49,22 @@ typedef void (__cdecl* _X509_free)(X509*);
 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
@@ -83,8 +97,22 @@ _X509_free p_X509_free;
 _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
@@ -116,10 +144,17 @@ BOOL LoadOpenSSL()
                return FALSE;\r
 #ifdef ENABLE_PROCESS_PROTECTION\r
        // 同梱するOpenSSLのバージョンに合わせてSHA1ハッシュ値を変更すること\r
-       // ssleay32.dll 1.0.1e\r
-       RegisterTrustedModuleSHA1Hash("\xE8\x9A\x16\xDF\xCE\xA2\x7E\x55\x28\xC4\x78\x1A\x21\x40\xCB\x57\xDC\x40\xCD\x61");\r
-       // libeay32.dll 1.0.1e\r
-       RegisterTrustedModuleSHA1Hash("\x38\xC8\x30\xCB\xE0\x5D\x4E\xF7\xA1\x93\xBB\xF7\x54\xA5\x21\xC8\xF7\xA1\x85\xC5");\r
+#if defined(_M_IX86)\r
+       // ssleay32.dll 1.0.1h\r
+       RegisterTrustedModuleSHA1Hash("\x1B\x27\x4E\x29\x14\x78\x72\x0D\x33\x73\xD5\x98\xCF\xEA\x32\x07\x2B\x35\x69\x66");\r
+       // libeay32.dll 1.0.1h\r
+       RegisterTrustedModuleSHA1Hash("\x1D\x2E\x70\x49\x84\x2C\xE9\x1F\x64\xE8\x84\xD4\x62\x5B\xF4\x34\x9A\x0F\x82\xFC");\r
+#elif defined(_M_AMD64)\r
+       // ssleay32.dll 1.0.1h\r
+       RegisterTrustedModuleSHA1Hash("\xB7\x5C\x31\xF3\x28\x73\xA0\x3C\x33\xDD\xBC\xB5\x8F\xD1\x38\xB6\xCE\x67\x4C\x40");\r
+       // libeay32.dll 1.0.1h\r
+       RegisterTrustedModuleSHA1Hash("\x5E\xBF\x56\x8C\xED\x06\xE8\x90\xE3\xC0\x3B\x6C\x51\x66\x4F\xC9\x9F\x1F\xF5\x89");\r
+#endif\r
 #endif\r
        g_hOpenSSL = LoadLibrary("ssleay32.dll");\r
        // バージョン固定のためlibssl32.dllの読み込みは脆弱性の原因になり得るので廃止\r
@@ -165,8 +200,22 @@ BOOL LoadOpenSSL()
                || !(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
@@ -341,8 +390,10 @@ BOOL SetSSLRootCertificate(const void* pData, DWORD Length)
        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
@@ -359,18 +410,19 @@ BOOL SetSSLRootCertificate(const void* pData, DWORD Length)
                        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
@@ -391,7 +443,45 @@ BOOL SetSSLRootCertificate(const void* pData, DWORD Length)
                                        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
@@ -440,6 +530,67 @@ BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName)
        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
@@ -794,6 +945,16 @@ int WSACancelAsyncRequestIPv6(HANDLE hAsyncTaskHandle)
        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
@@ -1066,7 +1227,11 @@ BOOL LoadPuTTY()
                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
 #ifdef _DEBUG\r