FFFTPのソースコードです。
リビジョン | 9ade514641b46ed744acb24265eff6616954113d (tree) |
---|---|
日時 | 2011-11-15 23:47:39 |
作者 | s_kawamoto <s_kawamoto@user...> |
コミッター | s_kawamoto |
Add support for SSL root CA certificates (please put "ssl.pem" manually).
Fix bugs of opening wrong files when they contain no extensions.
Modify documents.
@@ -1369,7 +1369,7 @@ END | ||
1369 | 1369 | |
1370 | 1370 | savecrypt_dlg DIALOG 0, 0, 146, 50 |
1371 | 1371 | STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION |
1372 | -CAPTION "パスワードの保存" | |
1372 | +CAPTION "暗号化の状態の保存" | |
1373 | 1373 | FONT 9, "MS Pゴシック" |
1374 | 1374 | BEGIN |
1375 | 1375 | LTEXT "現在の暗号化の状態を保存しますか?",-1,7,7,132,17 |
@@ -1377,6 +1377,16 @@ BEGIN | ||
1377 | 1377 | PUSHBUTTON "いいえ",IDCANCEL,78,29,50,14 |
1378 | 1378 | END |
1379 | 1379 | |
1380 | +updatesslroot_dlg DIALOG 0, 0, 211, 64 | |
1381 | +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | |
1382 | +CAPTION "SSLルート証明書を更新" | |
1383 | +FONT 9, "MS Pゴシック" | |
1384 | +BEGIN | |
1385 | + LTEXT "SSLルート証明書の変更が検出されました。手動で証明書を更新していない場合、マルウェアなどにより改竄された可能性があります。\r\n変更された証明書を使用しますか。",-1,7,7,196,36 | |
1386 | + DEFPUSHBUTTON "いいえ",IDCANCEL,112,42,50,14 | |
1387 | + PUSHBUTTON "はい",IDOK,48,42,50,14 | |
1388 | +END | |
1389 | + | |
1380 | 1390 | |
1381 | 1391 | ///////////////////////////////////////////////////////////////////////////// |
1382 | 1392 | // |
@@ -2016,6 +2026,14 @@ BEGIN | ||
2016 | 2026 | TOPMARGIN, 7 |
2017 | 2027 | BOTTOMMARGIN, 43 |
2018 | 2028 | END |
2029 | + | |
2030 | + updatesslroot_dlg, DIALOG | |
2031 | + BEGIN | |
2032 | + LEFTMARGIN, 7 | |
2033 | + RIGHTMARGIN, 139 | |
2034 | + TOPMARGIN, 7 | |
2035 | + BOTTOMMARGIN, 43 | |
2036 | + END | |
2019 | 2037 | END |
2020 | 2038 | #endif // APSTUDIO_INVOKED |
2021 | 2039 |
@@ -111,6 +111,7 @@ | ||
111 | 111 | #define hset_crypt_dlg 189 |
112 | 112 | #define hset_adv3_dlg 190 |
113 | 113 | #define savecrypt_dlg 191 |
114 | +#define updatesslroot_dlg 192 | |
114 | 115 | #define TRANS_TIME_BAR 1002 |
115 | 116 | #define TRANS_TEXT 1003 |
116 | 117 | #define TRANS_REMOTE 1003 |
@@ -616,7 +617,7 @@ | ||
616 | 617 | // |
617 | 618 | #ifdef APSTUDIO_INVOKED |
618 | 619 | #ifndef APSTUDIO_READONLY_SYMBOLS |
619 | -#define _APS_NEXT_RESOURCE_VALUE 192 | |
620 | +#define _APS_NEXT_RESOURCE_VALUE 193 | |
620 | 621 | #define _APS_NEXT_COMMAND_VALUE 40176 |
621 | 622 | #define _APS_NEXT_CONTROL_VALUE 1208 |
622 | 623 | #define _APS_NEXT_SYMED_VALUE 101 |
@@ -1395,7 +1395,7 @@ END | ||
1395 | 1395 | |
1396 | 1396 | savecrypt_dlg DIALOG 0, 0, 146, 50 |
1397 | 1397 | STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION |
1398 | -CAPTION "パスワードの保存" | |
1398 | +CAPTION "Save Encryption Status" | |
1399 | 1399 | FONT 9, "MS Sans Serif" |
1400 | 1400 | BEGIN |
1401 | 1401 | LTEXT "Save current encryption status?",-1,7,7,132,17 |
@@ -1403,6 +1403,16 @@ BEGIN | ||
1403 | 1403 | PUSHBUTTON "No",IDCANCEL,78,29,50,14 |
1404 | 1404 | END |
1405 | 1405 | |
1406 | +updatesslroot_dlg DIALOG 0, 0, 211, 64 | |
1407 | +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | |
1408 | +CAPTION "Update SSL Root certificate" | |
1409 | +FONT 9, "MS Sans Serif" | |
1410 | +BEGIN | |
1411 | + LTEXT "Modified SSL Root certificate was detected.If you did not update it manually, it might be tampered with by malwares.\r\nUse the modified certificate?",-1,7,7,196,36 | |
1412 | + DEFPUSHBUTTON "No",IDCANCEL,112,42,50,14 | |
1413 | + PUSHBUTTON "Yes",IDOK,48,42,50,14 | |
1414 | +END | |
1415 | + | |
1406 | 1416 | |
1407 | 1417 | ///////////////////////////////////////////////////////////////////////////// |
1408 | 1418 | // |
@@ -2039,6 +2049,14 @@ BEGIN | ||
2039 | 2049 | TOPMARGIN, 7 |
2040 | 2050 | BOTTOMMARGIN, 43 |
2041 | 2051 | END |
2052 | + | |
2053 | + updatesslroot_dlg, DIALOG | |
2054 | + BEGIN | |
2055 | + LEFTMARGIN, 7 | |
2056 | + RIGHTMARGIN, 139 | |
2057 | + TOPMARGIN, 7 | |
2058 | + BOTTOMMARGIN, 43 | |
2059 | + END | |
2042 | 2060 | END |
2043 | 2061 | #endif // APSTUDIO_INVOKED |
2044 | 2062 |
@@ -111,6 +111,7 @@ | ||
111 | 111 | #define hset_crypt_dlg 189 |
112 | 112 | #define hset_adv3_dlg 190 |
113 | 113 | #define savecrypt_dlg 191 |
114 | +#define updatesslroot_dlg 192 | |
114 | 115 | #define TRANS_TIME_BAR 1002 |
115 | 116 | #define TRANS_TEXT 1003 |
116 | 117 | #define TRANS_REMOTE 1003 |
@@ -616,7 +617,7 @@ | ||
616 | 617 | // |
617 | 618 | #ifdef APSTUDIO_INVOKED |
618 | 619 | #ifndef APSTUDIO_READONLY_SYMBOLS |
619 | -#define _APS_NEXT_RESOURCE_VALUE 192 | |
620 | +#define _APS_NEXT_RESOURCE_VALUE 193 | |
620 | 621 | #define _APS_NEXT_COMMAND_VALUE 40176 |
621 | 622 | #define _APS_NEXT_CONTROL_VALUE 1208 |
622 | 623 | #define _APS_NEXT_SYMED_VALUE 101 |
@@ -1250,6 +1250,7 @@ int AskAutoExit(void); | ||
1250 | 1250 | // 暗号化通信対応 |
1251 | 1251 | BOOL __stdcall SSLTimeoutCallback(BOOL* pbAborted); |
1252 | 1252 | BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName); |
1253 | +BOOL LoadSSLRootCAFile(); | |
1253 | 1254 | |
1254 | 1255 | /*===== filelist.c =====*/ |
1255 | 1256 |
@@ -53,6 +53,9 @@ Changes in Ver.1.99 | ||
53 | 53 | This may allow to transfer files successfully as with 1.97b or earlier, |
54 | 54 | but sometimes may cause some errors. |
55 | 55 | |
56 | +-- Changed to verify SSL/TLS certificates with root CAs in FTPS connections. | |
57 | + Please modify "ssl.pem" in PEM format if you want to update root CA list. | |
58 | + | |
56 | 59 | |
57 | 60 | Outline |
58 | 61 | ------- |
@@ -21,6 +21,9 @@ Changes in Ver.1.99 | ||
21 | 21 | |
22 | 22 | -- Changed to detect encoding of strings in INI file automatically. |
23 | 23 | |
24 | +-- Changed to verify SSL/TLS certificates with root CAs in FTPS connections. | |
25 | + Please modify "ssl.pem" in PEM format if you want to update root CA list. | |
26 | + | |
24 | 27 | Changes in Ver.1.98c |
25 | 28 | -------------------- |
26 | 29 |
@@ -55,6 +55,10 @@ Ver 1.99 | ||
55 | 55 | 追加しました。これにより1.97b以前で転送可能だったが1.98で転送不能に |
56 | 56 | なるという症状が改善されますが、不具合が発生する可能性があります。 |
57 | 57 | |
58 | +・FTPSで接続した時にSSL/TLSのルート証明書を用いてホストの証明書を検証 | |
59 | + するように変更しました。ルート証明書を更新するには同梱の"ssl.pem" | |
60 | + ファイルをPEM形式に従って書き換えてください。 | |
61 | + | |
58 | 62 | |
59 | 63 | Ver 1.96d以前へ戻す場合 |
60 | 64 | ----------------------- |
@@ -27,6 +27,10 @@ FFFTP | ||
27 | 27 | 追加しました。これにより1.97b以前で転送可能だったが1.98で転送不能に |
28 | 28 | なるという症状が改善されますが、不具合が発生する可能性があります。 |
29 | 29 | |
30 | +・FTPSで接続した時にSSL/TLSのルート証明書を用いてホストの証明書を検証 | |
31 | + するように変更しました。ルート証明書を更新するには同梱の"ssl.pem" | |
32 | + ファイルをPEM形式に従って書き換えてください。 | |
33 | + | |
30 | 34 | ■Ver 1.98c |
31 | 35 | |
32 | 36 | ・日本語ドメイン名のホストへの接続時にアドレスをPunycodeへ変換してから |
@@ -130,6 +130,9 @@ static int SuppressRefresh = 0; | ||
130 | 130 | |
131 | 131 | static DWORD dwCookie; |
132 | 132 | |
133 | +// 暗号化通信対応 | |
134 | +static char SSLRootCAFilePath[FMAX_PATH+1]; | |
135 | + | |
133 | 136 | |
134 | 137 | /*===== グローバルなワーク =====*/ |
135 | 138 |
@@ -223,6 +226,7 @@ int FolderAttr = NO; | ||
223 | 226 | int FolderAttrNum = 777; |
224 | 227 | // 暗号化通信対応 |
225 | 228 | BYTE CertificateCacheHash[MAX_CERT_CACHE_HASH][20]; |
229 | +BYTE SSLRootCAFileHash[20]; | |
226 | 230 | |
227 | 231 | |
228 | 232 |
@@ -472,6 +476,9 @@ static int InitApp(LPSTR lpszCmdLine, int cmdShow) | ||
472 | 476 | // 暗号化通信対応 |
473 | 477 | SetSSLTimeoutCallback(TimeOut * 1000, SSLTimeoutCallback); |
474 | 478 | SetSSLConfirmCallback(SSLConfirmCallback); |
479 | + GetModuleFileName(NULL, SSLRootCAFilePath, FMAX_PATH); | |
480 | + strcpy(GetFileName(SSLRootCAFilePath), "ssl.pem"); | |
481 | + LoadSSLRootCAFile(); | |
475 | 482 | |
476 | 483 | LoadJre(); |
477 | 484 | if(NoRasControl == NO) |
@@ -2950,3 +2957,35 @@ BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certif | ||
2950 | 2957 | return bResult; |
2951 | 2958 | } |
2952 | 2959 | |
2960 | +BOOL LoadSSLRootCAFile() | |
2961 | +{ | |
2962 | + BOOL bResult; | |
2963 | + HANDLE hFile; | |
2964 | + DWORD Size; | |
2965 | + BYTE* pBuffer; | |
2966 | + uint32 Hash[5]; | |
2967 | + bResult = FALSE; | |
2968 | + if((hFile = CreateFile(SSLRootCAFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) | |
2969 | + { | |
2970 | + Size = GetFileSize(hFile, NULL); | |
2971 | + if(pBuffer = (BYTE*)malloc(Size)) | |
2972 | + { | |
2973 | + if(ReadFile(hFile, pBuffer, Size, &Size, NULL)) | |
2974 | + { | |
2975 | + sha_memory((char*)pBuffer, (uint32)Size, (uint32*)&Hash); | |
2976 | + // 同梱する"ssl.pem"に合わせてSHA1ハッシュ値を変更すること | |
2977 | + if(memcmp(&Hash, &SSLRootCAFileHash, 20) == 0 || memcmp(&Hash, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 20) == 0 | |
2978 | + || DialogBox(GetFtpInst(), MAKEINTRESOURCE(updatesslroot_dlg), GetMainHwnd(), ExeEscDialogProc) == YES) | |
2979 | + { | |
2980 | + memcpy(&SSLRootCAFileHash, &Hash, 20); | |
2981 | + if(SetSSLRootCertificate(pBuffer, Size)) | |
2982 | + bResult = TRUE; | |
2983 | + } | |
2984 | + } | |
2985 | + free(pBuffer); | |
2986 | + } | |
2987 | + CloseHandle(hFile); | |
2988 | + } | |
2989 | + return bResult; | |
2990 | +} | |
2991 | + |
@@ -1733,6 +1733,7 @@ char *MakeNumString(LONGLONG Num, char *Buf, BOOL Comma) | ||
1733 | 1733 | // 現在UNC対応の予定は無い |
1734 | 1734 | char* MakeDistinguishableFileName(char* Out, char* In) |
1735 | 1735 | { |
1736 | + char* Fname; | |
1736 | 1737 | char Tmp[FMAX_PATH+1]; |
1737 | 1738 | char Tmp2[FMAX_PATH+3]; |
1738 | 1739 | HANDLE hFind; |
@@ -1741,6 +1742,7 @@ char* MakeDistinguishableFileName(char* Out, char* In) | ||
1741 | 1742 | strcpy(Out, In); |
1742 | 1743 | else |
1743 | 1744 | { |
1745 | + Fname = GetFileName(In); | |
1744 | 1746 | strcpy(Tmp, In); |
1745 | 1747 | strcpy(Tmp2, Tmp); |
1746 | 1748 | strcat(Tmp2, ".*"); |
@@ -1748,12 +1750,12 @@ char* MakeDistinguishableFileName(char* Out, char* In) | ||
1748 | 1750 | { |
1749 | 1751 | do |
1750 | 1752 | { |
1751 | - if(strchr(Find.cFileName, '.')) | |
1753 | + if(strcmp(Find.cFileName, Fname) != 0) | |
1752 | 1754 | break; |
1753 | 1755 | } |
1754 | 1756 | while(FindNextFile(hFind, &Find)); |
1755 | 1757 | FindClose(hFind); |
1756 | - if(strchr(Find.cFileName, '.')) | |
1758 | + if(strcmp(Find.cFileName, Fname) != 0) | |
1757 | 1759 | { |
1758 | 1760 | strcat(Tmp, " "); |
1759 | 1761 | strcpy(Tmp2, Tmp); |
@@ -86,6 +86,9 @@ static int ReadMultiStringFromReg(void *Handle, char *Name, char *Str, DWORD Siz | ||
86 | 86 | static int WriteMultiStringToReg(void *Handle, char *Name, char *Str); |
87 | 87 | static int ReadBinaryFromReg(void *Handle, char *Name, void *Bin, DWORD Size); |
88 | 88 | static int WriteBinaryToReg(void *Handle, char *Name, void *Bin, int Len); |
89 | +// 暗号化通信対応 | |
90 | +static int StrCatOut(char *Src, int Len, char *Dst); | |
91 | +static int StrReadIn(char *Src, int Max, char *Dst); | |
89 | 92 | |
90 | 93 | int CheckPasswordValidity( char* Password, int length, const char* HashStr ); |
91 | 94 | void CreatePasswordHash( char* Password, int length, char* HashStr ); |
@@ -189,6 +192,7 @@ extern int FolderAttrNum; | ||
189 | 192 | |
190 | 193 | // 暗号化通信対応 |
191 | 194 | extern BYTE CertificateCacheHash[MAX_CERT_CACHE_HASH][20]; |
195 | +extern BYTE SSLRootCAFileHash[20]; | |
192 | 196 | |
193 | 197 | /*----- マスタパスワードの設定 ---------------------------------------------- |
194 | 198 | * |
@@ -295,6 +299,7 @@ void SaveRegistory(void) | ||
295 | 299 | // 暗号化通信対応 |
296 | 300 | // char Str[FMAX_PATH+1]; |
297 | 301 | char Str[PRIVATE_KEY_LEN*4+1]; |
302 | + char Buf[FMAX_PATH+1]; | |
298 | 303 | int i; |
299 | 304 | int n; |
300 | 305 | HOSTDATA DefaultHost; |
@@ -589,6 +594,10 @@ void SaveRegistory(void) | ||
589 | 594 | |
590 | 595 | // 暗号化通信対応 |
591 | 596 | WriteBinaryToReg(hKey4, "CertCacheHash", &CertificateCacheHash, sizeof(CertificateCacheHash)); |
597 | + strcpy(Buf, ""); | |
598 | + StrCatOut((char*)&SSLRootCAFileHash, sizeof(SSLRootCAFileHash), Buf); | |
599 | + EncodePassword(Buf, Str); | |
600 | + WriteStringToReg(hKey4, "RootCertHash", Str); | |
592 | 601 | } |
593 | 602 | CloseSubKey(hKey4); |
594 | 603 | } |
@@ -619,6 +628,7 @@ int LoadRegistory(void) | ||
619 | 628 | // 暗号化通信対応 |
620 | 629 | // char Str[256]; /* ASCII_EXT_LENより大きい事 */ |
621 | 630 | char Str[PRIVATE_KEY_LEN*4+1]; |
631 | + char Buf[FMAX_PATH+1]; | |
622 | 632 | char *Pos; |
623 | 633 | char *Pos2; |
624 | 634 | HOSTDATA Host; |
@@ -944,6 +954,9 @@ int LoadRegistory(void) | ||
944 | 954 | |
945 | 955 | // 暗号化通信対応 |
946 | 956 | ReadBinaryFromReg(hKey4, "CertCacheHash", &CertificateCacheHash, sizeof(CertificateCacheHash)); |
957 | + ReadStringFromReg(hKey4, "RootCertHash", Str, PRIVATE_KEY_LEN*4+1); | |
958 | + DecodePassword(Str, Buf); | |
959 | + StrReadIn(Buf, sizeof(SSLRootCAFileHash), (char*)&SSLRootCAFileHash); | |
947 | 960 | |
948 | 961 | CloseSubKey(hKey4); |
949 | 962 | } |
@@ -1796,8 +1809,9 @@ typedef struct regdatatbl { | ||
1796 | 1809 | |
1797 | 1810 | static BOOL WriteOutRegToFile(REGDATATBL *Pos); |
1798 | 1811 | static int ReadInReg(char *Name, REGDATATBL **Handle); |
1799 | -static int StrCatOut(char *Src, int Len, char *Dst); | |
1800 | -static int StrReadIn(char *Src, int Max, char *Dst); | |
1812 | +// 暗号化通信対応 | |
1813 | +//static int StrCatOut(char *Src, int Len, char *Dst); | |
1814 | +//static int StrReadIn(char *Src, int Max, char *Dst); | |
1801 | 1815 | static char *ScanValue(void *Handle, char *Name); |
1802 | 1816 | |
1803 | 1817 |
@@ -36,7 +36,7 @@ typedef X509* (__cdecl* _SSL_get_peer_certificate)(const SSL*); | ||
36 | 36 | typedef long (__cdecl* _SSL_get_verify_result)(const SSL*); |
37 | 37 | typedef SSL_SESSION* (__cdecl* _SSL_get_session)(SSL*); |
38 | 38 | typedef int (__cdecl* _SSL_set_session)(SSL*, SSL_SESSION*); |
39 | -typedef int (__cdecl* _SSL_CTX_use_certificate)(SSL_CTX*, X509*); | |
39 | +typedef X509_STORE* (__cdecl* _SSL_CTX_get_cert_store)(const SSL_CTX*); | |
40 | 40 | typedef BIO_METHOD* (__cdecl* _BIO_s_mem)(); |
41 | 41 | typedef BIO* (__cdecl* _BIO_new)(BIO_METHOD*); |
42 | 42 | typedef int (__cdecl* _BIO_free)(BIO*); |
@@ -47,6 +47,7 @@ typedef int (__cdecl* _X509_print_ex)(BIO*, X509*, unsigned long, unsigned long) | ||
47 | 47 | typedef X509_NAME* (__cdecl* _X509_get_subject_name)(X509*); |
48 | 48 | typedef int (__cdecl* _X509_NAME_print_ex)(BIO*, X509_NAME*, int, unsigned long); |
49 | 49 | typedef X509* (__cdecl* _PEM_read_bio_X509)(BIO*, X509**, pem_password_cb*, void*); |
50 | +typedef int (__cdecl* _X509_STORE_add_cert)(X509_STORE*, X509*); | |
50 | 51 | |
51 | 52 | _SSL_load_error_strings p_SSL_load_error_strings; |
52 | 53 | _SSL_library_init p_SSL_library_init; |
@@ -68,7 +69,7 @@ _SSL_get_peer_certificate p_SSL_get_peer_certificate; | ||
68 | 69 | _SSL_get_verify_result p_SSL_get_verify_result; |
69 | 70 | _SSL_get_session p_SSL_get_session; |
70 | 71 | _SSL_set_session p_SSL_set_session; |
71 | -_SSL_CTX_use_certificate p_SSL_CTX_use_certificate; | |
72 | +_SSL_CTX_get_cert_store p_SSL_CTX_get_cert_store; | |
72 | 73 | _BIO_s_mem p_BIO_s_mem; |
73 | 74 | _BIO_new p_BIO_new; |
74 | 75 | _BIO_free p_BIO_free; |
@@ -79,6 +80,7 @@ _X509_print_ex p_X509_print_ex; | ||
79 | 80 | _X509_get_subject_name p_X509_get_subject_name; |
80 | 81 | _X509_NAME_print_ex p_X509_NAME_print_ex; |
81 | 82 | _PEM_read_bio_X509 p_PEM_read_bio_X509; |
83 | +_X509_STORE_add_cert p_X509_STORE_add_cert; | |
82 | 84 | |
83 | 85 | #define MAX_SSL_SOCKET 16 |
84 | 86 |
@@ -141,7 +143,7 @@ BOOL LoadOpenSSL() | ||
141 | 143 | || !(p_SSL_get_verify_result = (_SSL_get_verify_result)GetProcAddress(g_hOpenSSL, "SSL_get_verify_result")) |
142 | 144 | || !(p_SSL_get_session = (_SSL_get_session)GetProcAddress(g_hOpenSSL, "SSL_get_session")) |
143 | 145 | || !(p_SSL_set_session = (_SSL_set_session)GetProcAddress(g_hOpenSSL, "SSL_set_session")) |
144 | - || !(p_SSL_CTX_use_certificate = (_SSL_CTX_use_certificate)GetProcAddress(g_hOpenSSL, "SSL_CTX_use_certificate"))) | |
146 | + || !(p_SSL_CTX_get_cert_store = (_SSL_CTX_get_cert_store)GetProcAddress(g_hOpenSSL, "SSL_CTX_get_cert_store"))) | |
145 | 147 | { |
146 | 148 | if(g_hOpenSSL) |
147 | 149 | FreeLibrary(g_hOpenSSL); |
@@ -159,7 +161,8 @@ BOOL LoadOpenSSL() | ||
159 | 161 | || !(p_X509_print_ex = (_X509_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_print_ex")) |
160 | 162 | || !(p_X509_get_subject_name = (_X509_get_subject_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_subject_name")) |
161 | 163 | || !(p_X509_NAME_print_ex = (_X509_NAME_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_NAME_print_ex")) |
162 | - || !(p_PEM_read_bio_X509 = (_PEM_read_bio_X509)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_X509"))) | |
164 | + || !(p_PEM_read_bio_X509 = (_PEM_read_bio_X509)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_X509")) | |
165 | + || !(p_X509_STORE_add_cert = (_X509_STORE_add_cert)GetProcAddress(g_hOpenSSLCommon, "X509_STORE_add_cert"))) | |
163 | 166 | { |
164 | 167 | if(g_hOpenSSL) |
165 | 168 | FreeLibrary(g_hOpenSSL); |
@@ -283,7 +286,7 @@ BOOL ConfirmSSLCertificate(SSL* pSSL, BOOL* pbAborted) | ||
283 | 286 | } |
284 | 287 | p_X509_free(pX509); |
285 | 288 | } |
286 | - if(p_SSL_get_verify_result(pSSL) == X509_V_OK) | |
289 | + if(pX509 && p_SSL_get_verify_result(pSSL) == X509_V_OK) | |
287 | 290 | bVerified = TRUE; |
288 | 291 | pCN = pSubject; |
289 | 292 | while(pCN) |
@@ -326,9 +329,14 @@ void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback) | ||
326 | 329 | } |
327 | 330 | |
328 | 331 | // SSLルート証明書を設定 |
329 | -BOOL SetSSLRootCertificate(void* pData, DWORD Length) | |
332 | +// PEM形式のみ指定可能 | |
333 | +BOOL SetSSLRootCertificate(const void* pData, DWORD Length) | |
330 | 334 | { |
331 | 335 | BOOL r; |
336 | + X509_STORE* pStore; | |
337 | + BYTE* p; | |
338 | + BYTE* pBegin; | |
339 | + BYTE* pEnd; | |
332 | 340 | BIO* pBIO; |
333 | 341 | X509* pX509; |
334 | 342 | if(!g_bOpenSSLLoaded) |
@@ -339,15 +347,45 @@ BOOL SetSSLRootCertificate(void* pData, DWORD Length) | ||
339 | 347 | g_pOpenSSLCTX = p_SSL_CTX_new(p_SSLv23_method()); |
340 | 348 | if(g_pOpenSSLCTX) |
341 | 349 | { |
342 | - if(pBIO = p_BIO_new_mem_buf(pData, Length)) | |
350 | + if(pStore = p_SSL_CTX_get_cert_store(g_pOpenSSLCTX)) | |
343 | 351 | { |
344 | - if(pX509 = p_PEM_read_bio_X509(pBIO, NULL, NULL, NULL)) | |
352 | + p = (BYTE*)pData; | |
353 | + pBegin = NULL; | |
354 | + pEnd = NULL; | |
355 | + while(Length > 0) | |
345 | 356 | { |
346 | - if(p_SSL_CTX_use_certificate(g_pOpenSSLCTX, pX509) == 1) | |
347 | - r = TRUE; | |
348 | - p_X509_free(pX509); | |
357 | + if(!pBegin) | |
358 | + { | |
359 | + if(Length < 27) | |
360 | + break; | |
361 | + if(memcmp(p, "-----BEGIN CERTIFICATE-----", 27) == 0) | |
362 | + pBegin = p; | |
363 | + } | |
364 | + else if(!pEnd) | |
365 | + { | |
366 | + if(Length < 25) | |
367 | + break; | |
368 | + if(memcmp(p, "-----END CERTIFICATE-----", 25) == 0) | |
369 | + pEnd = p + 25; | |
370 | + } | |
371 | + if(pBegin && pEnd) | |
372 | + { | |
373 | + if(pBIO = p_BIO_new_mem_buf(pBegin, (int)((size_t)pEnd - (size_t)pBegin))) | |
374 | + { | |
375 | + if(pX509 = p_PEM_read_bio_X509(pBIO, NULL, NULL, NULL)) | |
376 | + { | |
377 | + if(p_X509_STORE_add_cert(pStore, pX509) == 1) | |
378 | + r = TRUE; | |
379 | + p_X509_free(pX509); | |
380 | + } | |
381 | + p_BIO_free(pBIO); | |
382 | + } | |
383 | + pBegin = NULL; | |
384 | + pEnd = NULL; | |
385 | + } | |
386 | + p++; | |
387 | + Length--; | |
349 | 388 | } |
350 | - p_BIO_free(pBIO); | |
351 | 389 | } |
352 | 390 | } |
353 | 391 | LeaveCriticalSection(&g_OpenSSLLock); |
@@ -18,7 +18,7 @@ void FreeOpenSSL(); | ||
18 | 18 | BOOL IsOpenSSLLoaded(); |
19 | 19 | void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback); |
20 | 20 | void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback); |
21 | -BOOL SetSSLRootCertificate(void* pData, DWORD Length); | |
21 | +BOOL SetSSLRootCertificate(const void* pData, DWORD Length); | |
22 | 22 | BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName); |
23 | 23 | BOOL AttachSSL(SOCKET s, SOCKET parent, BOOL* pbAborted); |
24 | 24 | BOOL DetachSSL(SOCKET s); |