OSDN Git Service

Add support for SSL root CA certificates (please put "ssl.pem" manually).
authors_kawamoto <s_kawamoto@users.sourceforge.jp>
Tue, 15 Nov 2011 14:47:39 +0000 (23:47 +0900)
committers_kawamoto <s_kawamoto@users.sourceforge.jp>
Tue, 15 Nov 2011 14:47:39 +0000 (23:47 +0900)
Fix bugs of opening wrong files when they contain no extensions.
Modify documents.

16 files changed:
FFFTP_Eng_Release/FFFTP.exe
Release/FFFTP.exe
Resource/FFFTP.rc
Resource/resource.h
Resource_eng/FFFTP-eng.rc
Resource_eng/resource.h
common.h
doc/eng/FFFTP.txt
doc/eng/history.txt
doc/jpn/FFFTP.txt
doc/jpn/history.txt
main.c
misc.c
registry.c
socketwrapper.c
socketwrapper.h

index b53e809..99db118 100644 (file)
Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
index a02bae6..d7d320f 100644 (file)
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
index 7be4eb3..2461492 100644 (file)
@@ -1369,7 +1369,7 @@ END
 \r
 savecrypt_dlg DIALOG  0, 0, 146, 50\r
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION\r
-CAPTION "\83p\83X\83\8f\81[\83h\82Ì\95Û\91¶"\r
+CAPTION "\88Ã\8d\86\89»\82Ì\8fó\91Ô\82Ì\95Û\91¶"\r
 FONT 9, "\82l\82\82o\83S\83V\83b\83N"\r
 BEGIN\r
     LTEXT           "\8c»\8dÝ\82Ì\88Ã\8d\86\89»\82Ì\8fó\91Ô\82ð\95Û\91\82µ\82Ü\82·\82©\81H",-1,7,7,132,17\r
@@ -1377,6 +1377,16 @@ BEGIN
     PUSHBUTTON      "\82¢\82¢\82¦",IDCANCEL,78,29,50,14\r
 END\r
 \r
+updatesslroot_dlg DIALOG  0, 0, 211, 64\r
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION\r
+CAPTION "SSL\83\8b\81[\83g\8fØ\96¾\8f\91\82ð\8dX\90V"\r
+FONT 9, "\82l\82\82o\83S\83V\83b\83N"\r
+BEGIN\r
+    LTEXT           "SSL\83\8b\81[\83g\8fØ\96¾\8f\91\82Ì\95Ï\8dX\82ª\8c\9f\8fo\82³\82ê\82Ü\82µ\82½\81B\8eè\93®\82Å\8fØ\96¾\8f\91\82ð\8dX\90V\82µ\82Ä\82¢\82È\82¢\8fê\8d\87\81A\83}\83\8b\83E\83F\83A\82È\82Ç\82É\82æ\82è\89üâ\82\82³\82ê\82½\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r\n\95Ï\8dX\82³\82ê\82½\8fØ\96¾\8f\91\82ð\8eg\97p\82µ\82Ü\82·\82©\81B",-1,7,7,196,36\r
+    DEFPUSHBUTTON   "\82¢\82¢\82¦",IDCANCEL,112,42,50,14\r
+    PUSHBUTTON      "\82Í\82¢",IDOK,48,42,50,14\r
+END\r
+\r
 \r
 /////////////////////////////////////////////////////////////////////////////\r
 //\r
@@ -2016,6 +2026,14 @@ BEGIN
         TOPMARGIN, 7\r
         BOTTOMMARGIN, 43\r
     END\r
+\r
+    updatesslroot_dlg, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 139\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 43\r
+    END\r
 END\r
 #endif    // APSTUDIO_INVOKED\r
 \r
index b8b7d24..ed0bcb6 100644 (file)
 #define hset_crypt_dlg                  189\r
 #define hset_adv3_dlg                   190\r
 #define savecrypt_dlg                   191\r
+#define updatesslroot_dlg               192\r
 #define TRANS_TIME_BAR                  1002\r
 #define TRANS_TEXT                      1003\r
 #define TRANS_REMOTE                    1003\r
 // \r
 #ifdef APSTUDIO_INVOKED\r
 #ifndef APSTUDIO_READONLY_SYMBOLS\r
-#define _APS_NEXT_RESOURCE_VALUE        192\r
+#define _APS_NEXT_RESOURCE_VALUE        193\r
 #define _APS_NEXT_COMMAND_VALUE         40176\r
 #define _APS_NEXT_CONTROL_VALUE         1208\r
 #define _APS_NEXT_SYMED_VALUE           101\r
index 1b6644c..5dd9fbf 100644 (file)
@@ -1395,7 +1395,7 @@ END
 \r
 savecrypt_dlg DIALOG  0, 0, 146, 50\r
 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION\r
-CAPTION "\83p\83X\83\8f\81[\83h\82Ì\95Û\91"\r
+CAPTION "Save Encryption Status"\r
 FONT 9, "MS Sans Serif"\r
 BEGIN\r
     LTEXT           "Save current encryption status?",-1,7,7,132,17\r
@@ -1403,6 +1403,16 @@ BEGIN
     PUSHBUTTON      "No",IDCANCEL,78,29,50,14\r
 END\r
 \r
+updatesslroot_dlg DIALOG  0, 0, 211, 64\r
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION\r
+CAPTION "Update SSL Root certificate"\r
+FONT 9, "MS Sans Serif"\r
+BEGIN\r
+    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\r
+    DEFPUSHBUTTON   "No",IDCANCEL,112,42,50,14\r
+    PUSHBUTTON      "Yes",IDOK,48,42,50,14\r
+END\r
+\r
 \r
 /////////////////////////////////////////////////////////////////////////////\r
 //\r
@@ -2039,6 +2049,14 @@ BEGIN
         TOPMARGIN, 7\r
         BOTTOMMARGIN, 43\r
     END\r
+\r
+    updatesslroot_dlg, DIALOG\r
+    BEGIN\r
+        LEFTMARGIN, 7\r
+        RIGHTMARGIN, 139\r
+        TOPMARGIN, 7\r
+        BOTTOMMARGIN, 43\r
+    END\r
 END\r
 #endif    // APSTUDIO_INVOKED\r
 \r
index aa76123..477bfeb 100644 (file)
 #define hset_crypt_dlg                  189\r
 #define hset_adv3_dlg                   190\r
 #define savecrypt_dlg                   191\r
+#define updatesslroot_dlg               192\r
 #define TRANS_TIME_BAR                  1002\r
 #define TRANS_TEXT                      1003\r
 #define TRANS_REMOTE                    1003\r
 // \r
 #ifdef APSTUDIO_INVOKED\r
 #ifndef APSTUDIO_READONLY_SYMBOLS\r
-#define _APS_NEXT_RESOURCE_VALUE        192\r
+#define _APS_NEXT_RESOURCE_VALUE        193\r
 #define _APS_NEXT_COMMAND_VALUE         40176\r
 #define _APS_NEXT_CONTROL_VALUE         1208\r
 #define _APS_NEXT_SYMED_VALUE           101\r
index 1a867af..aa0f07b 100644 (file)
--- a/common.h
+++ b/common.h
@@ -1250,6 +1250,7 @@ int AskAutoExit(void);
 // 暗号化通信対応\r
 BOOL __stdcall SSLTimeoutCallback(BOOL* pbAborted);\r
 BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName);\r
+BOOL LoadSSLRootCAFile();\r
 \r
 /*===== filelist.c =====*/\r
 \r
index f031633..05bf22e 100644 (file)
@@ -53,6 +53,9 @@ Changes in Ver.1.99
    This may allow to transfer files successfully as with 1.97b or earlier,\r
    but sometimes may cause some errors.\r
 \r
+-- Changed to verify SSL/TLS certificates with root CAs in FTPS connections.\r
+   Please modify "ssl.pem" in PEM format if you want to update root CA list.\r
+\r
 \r
 Outline\r
 -------\r
index fcbaed7..571aa6c 100644 (file)
@@ -21,6 +21,9 @@ Changes in Ver.1.99
 \r
 -- Changed to detect encoding of strings in INI file automatically.\r
 \r
+-- Changed to verify SSL/TLS certificates with root CAs in FTPS connections.\r
+   Please modify "ssl.pem" in PEM format if you want to update root CA list.\r
+\r
 Changes in Ver.1.98c\r
 --------------------\r
 \r
index a0b5905..d6338f7 100644 (file)
@@ -55,6 +55,10 @@ Ver 1.99
 \81@\92Ç\89Á\82µ\82Ü\82µ\82½\81B\82±\82ê\82É\82æ\82è1.97b\88È\91O\82Å\93]\91\97\89Â\94\\82¾\82Á\82½\82ª1.98\82Å\93]\91\97\95s\94\\82É\r
 \81@\82È\82é\82Æ\82¢\82¤\8fÇ\8fó\82ª\89ü\91P\82³\82ê\82Ü\82·\82ª\81A\95s\8bï\8d\87\82ª\94­\90\82·\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
 \r
+\81EFTPS\82Å\90Ú\91±\82µ\82½\8e\9e\82ÉSSL/TLS\82Ì\83\8b\81[\83g\8fØ\96¾\8f\91\82ð\97p\82¢\82Ä\83z\83X\83g\82Ì\8fØ\96¾\8f\91\82ð\8c\9f\8fØ\r
+\81@\82·\82é\82æ\82¤\82É\95Ï\8dX\82µ\82Ü\82µ\82½\81B\83\8b\81[\83g\8fØ\96¾\8f\91\82ð\8dX\90V\82·\82é\82É\82Í\93¯\8d«\82Ì"ssl.pem"\r
+\81@\83t\83@\83C\83\8b\82ðPEM\8c`\8e®\82É\8f]\82Á\82Ä\8f\91\82«\8a·\82¦\82Ä\82­\82¾\82³\82¢\81B\r
+\r
 \r
 Ver 1.96d\88È\91O\82Ö\96ß\82·\8fê\8d\87\r
 -----------------------\r
index c61b99a..d4105d6 100644 (file)
@@ -27,6 +27,10 @@ FFFTP
 \81@\92Ç\89Á\82µ\82Ü\82µ\82½\81B\82±\82ê\82É\82æ\82è1.97b\88È\91O\82Å\93]\91\97\89Â\94\\82¾\82Á\82½\82ª1.98\82Å\93]\91\97\95s\94\\82É\r
 \81@\82È\82é\82Æ\82¢\82¤\8fÇ\8fó\82ª\89ü\91P\82³\82ê\82Ü\82·\82ª\81A\95s\8bï\8d\87\82ª\94­\90\82·\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B\r
 \r
+\81EFTPS\82Å\90Ú\91±\82µ\82½\8e\9e\82ÉSSL/TLS\82Ì\83\8b\81[\83g\8fØ\96¾\8f\91\82ð\97p\82¢\82Ä\83z\83X\83g\82Ì\8fØ\96¾\8f\91\82ð\8c\9f\8fØ\r
+\81@\82·\82é\82æ\82¤\82É\95Ï\8dX\82µ\82Ü\82µ\82½\81B\83\8b\81[\83g\8fØ\96¾\8f\91\82ð\8dX\90V\82·\82é\82É\82Í\93¯\8d«\82Ì"ssl.pem"\r
+\81@\83t\83@\83C\83\8b\82ðPEM\8c`\8e®\82É\8f]\82Á\82Ä\8f\91\82«\8a·\82¦\82Ä\82­\82¾\82³\82¢\81B\r
+\r
 \81¡Ver 1.98c\r
 \r
 \81E\93ú\96{\8cê\83h\83\81\83C\83\93\96¼\82Ì\83z\83X\83g\82Ö\82Ì\90Ú\91±\8e\9e\82É\83A\83h\83\8c\83X\82ðPunycode\82Ö\95Ï\8a·\82µ\82Ä\82©\82ç\r
diff --git a/main.c b/main.c
index a182203..8cdfef3 100644 (file)
--- a/main.c
+++ b/main.c
@@ -130,6 +130,9 @@ static int SuppressRefresh = 0;
 \r
 static DWORD dwCookie;\r
 \r
+// 暗号化通信対応\r
+static char SSLRootCAFilePath[FMAX_PATH+1];\r
+\r
 \r
 /*===== グローバルなワーク =====*/\r
 \r
@@ -223,6 +226,7 @@ int FolderAttr = NO;
 int FolderAttrNum = 777;\r
 // 暗号化通信対応\r
 BYTE CertificateCacheHash[MAX_CERT_CACHE_HASH][20];\r
+BYTE SSLRootCAFileHash[20];\r
 \r
 \r
 \r
@@ -472,6 +476,9 @@ static int InitApp(LPSTR lpszCmdLine, int cmdShow)
                        // 暗号化通信対応\r
                        SetSSLTimeoutCallback(TimeOut * 1000, SSLTimeoutCallback);\r
                        SetSSLConfirmCallback(SSLConfirmCallback);\r
+                       GetModuleFileName(NULL, SSLRootCAFilePath, FMAX_PATH);\r
+                       strcpy(GetFileName(SSLRootCAFilePath), "ssl.pem");\r
+                       LoadSSLRootCAFile();\r
 \r
                        LoadJre();\r
                        if(NoRasControl == NO)\r
@@ -2950,3 +2957,35 @@ BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certif
        return bResult;\r
 }\r
 \r
+BOOL LoadSSLRootCAFile()\r
+{\r
+       BOOL bResult;\r
+       HANDLE hFile;\r
+       DWORD Size;\r
+       BYTE* pBuffer;\r
+       uint32 Hash[5];\r
+       bResult = FALSE;\r
+       if((hFile = CreateFile(SSLRootCAFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)\r
+       {\r
+               Size = GetFileSize(hFile, NULL);\r
+               if(pBuffer = (BYTE*)malloc(Size))\r
+               {\r
+                       if(ReadFile(hFile, pBuffer, Size, &Size, NULL))\r
+                       {\r
+                               sha_memory((char*)pBuffer, (uint32)Size, (uint32*)&Hash);\r
+                               // 同梱する"ssl.pem"に合わせてSHA1ハッシュ値を変更すること\r
+                               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\r
+                                       || DialogBox(GetFtpInst(), MAKEINTRESOURCE(updatesslroot_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
+                               {\r
+                                       memcpy(&SSLRootCAFileHash, &Hash, 20);\r
+                                       if(SetSSLRootCertificate(pBuffer, Size))\r
+                                               bResult = TRUE;\r
+                               }\r
+                       }\r
+                       free(pBuffer);\r
+               }\r
+               CloseHandle(hFile);\r
+       }\r
+       return bResult;\r
+}\r
+\r
diff --git a/misc.c b/misc.c
index cc00144..ac0539c 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -1733,6 +1733,7 @@ char *MakeNumString(LONGLONG Num, char *Buf, BOOL Comma)
 // 現在UNC対応の予定は無い\r
 char* MakeDistinguishableFileName(char* Out, char* In)\r
 {\r
+       char* Fname;\r
        char Tmp[FMAX_PATH+1];\r
        char Tmp2[FMAX_PATH+3];\r
        HANDLE hFind;\r
@@ -1741,6 +1742,7 @@ char* MakeDistinguishableFileName(char* Out, char* In)
                strcpy(Out, In);\r
        else\r
        {\r
+               Fname = GetFileName(In);\r
                strcpy(Tmp, In);\r
                strcpy(Tmp2, Tmp);\r
                strcat(Tmp2, ".*");\r
@@ -1748,12 +1750,12 @@ char* MakeDistinguishableFileName(char* Out, char* In)
                {\r
                        do\r
                        {\r
-                               if(strchr(Find.cFileName, '.'))\r
+                               if(strcmp(Find.cFileName, Fname) != 0)\r
                                        break;\r
                        }\r
                        while(FindNextFile(hFind, &Find));\r
                        FindClose(hFind);\r
-                       if(strchr(Find.cFileName, '.'))\r
+                       if(strcmp(Find.cFileName, Fname) != 0)\r
                        {\r
                                strcat(Tmp, " ");\r
                                strcpy(Tmp2, Tmp);\r
index b1cd7f4..b4bfa43 100644 (file)
@@ -86,6 +86,9 @@ static int ReadMultiStringFromReg(void *Handle, char *Name, char *Str, DWORD Siz
 static int WriteMultiStringToReg(void *Handle, char *Name, char *Str);\r
 static int ReadBinaryFromReg(void *Handle, char *Name, void *Bin, DWORD Size);\r
 static int WriteBinaryToReg(void *Handle, char *Name, void *Bin, int Len);\r
+// 暗号化通信対応\r
+static int StrCatOut(char *Src, int Len, char *Dst);\r
+static int StrReadIn(char *Src, int Max, char *Dst);\r
 \r
 int CheckPasswordValidity( char* Password, int length, const char* HashStr );\r
 void CreatePasswordHash( char* Password, int length, char* HashStr );\r
@@ -189,6 +192,7 @@ extern int FolderAttrNum;
 \r
 // 暗号化通信対応\r
 extern BYTE CertificateCacheHash[MAX_CERT_CACHE_HASH][20];\r
+extern BYTE SSLRootCAFileHash[20];\r
 \r
 /*----- マスタパスワードの設定 ----------------------------------------------\r
 *\r
@@ -295,6 +299,7 @@ void SaveRegistory(void)
        // 暗号化通信対応\r
 //     char Str[FMAX_PATH+1];\r
        char Str[PRIVATE_KEY_LEN*4+1];\r
+       char Buf[FMAX_PATH+1];\r
        int i;\r
        int n;\r
        HOSTDATA DefaultHost;\r
@@ -589,6 +594,10 @@ void SaveRegistory(void)
 \r
                                // 暗号化通信対応\r
                                WriteBinaryToReg(hKey4, "CertCacheHash", &CertificateCacheHash, sizeof(CertificateCacheHash));\r
+                               strcpy(Buf, "");\r
+                               StrCatOut((char*)&SSLRootCAFileHash, sizeof(SSLRootCAFileHash), Buf);\r
+                               EncodePassword(Buf, Str);\r
+                               WriteStringToReg(hKey4, "RootCertHash", Str);\r
                        }\r
                        CloseSubKey(hKey4);\r
                }\r
@@ -619,6 +628,7 @@ int LoadRegistory(void)
        // 暗号化通信対応\r
 //     char Str[256];  /* ASCII_EXT_LENより大きい事 */\r
        char Str[PRIVATE_KEY_LEN*4+1];\r
+       char Buf[FMAX_PATH+1];\r
        char *Pos;\r
        char *Pos2;\r
        HOSTDATA Host;\r
@@ -944,6 +954,9 @@ int LoadRegistory(void)
 \r
                        // 暗号化通信対応\r
                        ReadBinaryFromReg(hKey4, "CertCacheHash", &CertificateCacheHash, sizeof(CertificateCacheHash));\r
+                       ReadStringFromReg(hKey4, "RootCertHash", Str, PRIVATE_KEY_LEN*4+1);\r
+                       DecodePassword(Str, Buf);\r
+                       StrReadIn(Buf, sizeof(SSLRootCAFileHash), (char*)&SSLRootCAFileHash);\r
 \r
                        CloseSubKey(hKey4);\r
                }\r
@@ -1796,8 +1809,9 @@ typedef struct regdatatbl {
 \r
 static BOOL WriteOutRegToFile(REGDATATBL *Pos);\r
 static int ReadInReg(char *Name, REGDATATBL **Handle);\r
-static int StrCatOut(char *Src, int Len, char *Dst);\r
-static int StrReadIn(char *Src, int Max, char *Dst);\r
+// 暗号化通信対応\r
+//static int StrCatOut(char *Src, int Len, char *Dst);\r
+//static int StrReadIn(char *Src, int Max, char *Dst);\r
 static char *ScanValue(void *Handle, char *Name);\r
 \r
 \r
index edd8418..2f60ac6 100644 (file)
@@ -36,7 +36,7 @@ typedef X509* (__cdecl* _SSL_get_peer_certificate)(const SSL*);
 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 int (__cdecl* _SSL_CTX_use_certificate)(SSL_CTX*, X509*);\r
+typedef X509_STORE* (__cdecl* _SSL_CTX_get_cert_store)(const SSL_CTX*);\r
 typedef BIO_METHOD* (__cdecl* _BIO_s_mem)();\r
 typedef BIO* (__cdecl* _BIO_new)(BIO_METHOD*);\r
 typedef int (__cdecl* _BIO_free)(BIO*);\r
@@ -47,6 +47,7 @@ typedef int (__cdecl* _X509_print_ex)(BIO*, X509*, unsigned long, unsigned long)
 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 X509* (__cdecl* _PEM_read_bio_X509)(BIO*, X509**, pem_password_cb*, void*);\r
+typedef int (__cdecl* _X509_STORE_add_cert)(X509_STORE*, X509*);\r
 \r
 _SSL_load_error_strings p_SSL_load_error_strings;\r
 _SSL_library_init p_SSL_library_init;\r
@@ -68,7 +69,7 @@ _SSL_get_peer_certificate p_SSL_get_peer_certificate;
 _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
-_SSL_CTX_use_certificate p_SSL_CTX_use_certificate;\r
+_SSL_CTX_get_cert_store p_SSL_CTX_get_cert_store;\r
 _BIO_s_mem p_BIO_s_mem;\r
 _BIO_new p_BIO_new;\r
 _BIO_free p_BIO_free;\r
@@ -79,6 +80,7 @@ _X509_print_ex p_X509_print_ex;
 _X509_get_subject_name p_X509_get_subject_name;\r
 _X509_NAME_print_ex p_X509_NAME_print_ex;\r
 _PEM_read_bio_X509 p_PEM_read_bio_X509;\r
+_X509_STORE_add_cert p_X509_STORE_add_cert;\r
 \r
 #define MAX_SSL_SOCKET 16\r
 \r
@@ -141,7 +143,7 @@ BOOL LoadOpenSSL()
                || !(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_use_certificate = (_SSL_CTX_use_certificate)GetProcAddress(g_hOpenSSL, "SSL_CTX_use_certificate")))\r
+               || !(p_SSL_CTX_get_cert_store = (_SSL_CTX_get_cert_store)GetProcAddress(g_hOpenSSL, "SSL_CTX_get_cert_store")))\r
        {\r
                if(g_hOpenSSL)\r
                        FreeLibrary(g_hOpenSSL);\r
@@ -159,7 +161,8 @@ 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_PEM_read_bio_X509 = (_PEM_read_bio_X509)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_X509")))\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
        {\r
                if(g_hOpenSSL)\r
                        FreeLibrary(g_hOpenSSL);\r
@@ -283,7 +286,7 @@ BOOL ConfirmSSLCertificate(SSL* pSSL, BOOL* pbAborted)
                }\r
                p_X509_free(pX509);\r
        }\r
-       if(p_SSL_get_verify_result(pSSL) == X509_V_OK)\r
+       if(pX509 && p_SSL_get_verify_result(pSSL) == X509_V_OK)\r
                bVerified = TRUE;\r
        pCN = pSubject;\r
        while(pCN)\r
@@ -326,9 +329,14 @@ void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback)
 }\r
 \r
 // SSLルート証明書を設定\r
-BOOL SetSSLRootCertificate(void* pData, DWORD Length)\r
+// PEM形式のみ指定可能\r
+BOOL SetSSLRootCertificate(const void* pData, DWORD Length)\r
 {\r
        BOOL r;\r
+       X509_STORE* pStore;\r
+       BYTE* p;\r
+       BYTE* pBegin;\r
+       BYTE* pEnd;\r
        BIO* pBIO;\r
        X509* pX509;\r
        if(!g_bOpenSSLLoaded)\r
@@ -339,15 +347,45 @@ BOOL SetSSLRootCertificate(void* pData, DWORD Length)
                g_pOpenSSLCTX = p_SSL_CTX_new(p_SSLv23_method());\r
        if(g_pOpenSSLCTX)\r
        {\r
-               if(pBIO = p_BIO_new_mem_buf(pData, Length))\r
+               if(pStore = p_SSL_CTX_get_cert_store(g_pOpenSSLCTX))\r
                {\r
-                       if(pX509 = p_PEM_read_bio_X509(pBIO, NULL, NULL, NULL))\r
+                       p = (BYTE*)pData;\r
+                       pBegin = NULL;\r
+                       pEnd = NULL;\r
+                       while(Length > 0)\r
                        {\r
-                               if(p_SSL_CTX_use_certificate(g_pOpenSSLCTX, pX509) == 1)\r
-                                       r = TRUE;\r
-                               p_X509_free(pX509);\r
+                               if(!pBegin)\r
+                               {\r
+                                       if(Length < 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
+                                               break;\r
+                                       if(memcmp(p, "-----END CERTIFICATE-----", 25) == 0)\r
+                                               pEnd = p + 25;\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 = p_PEM_read_bio_X509(pBIO, NULL, NULL, NULL))\r
+                                               {\r
+                                                       if(p_X509_STORE_add_cert(pStore, pX509) == 1)\r
+                                                               r = TRUE;\r
+                                                       p_X509_free(pX509);\r
+                                               }\r
+                                               p_BIO_free(pBIO);\r
+                                       }\r
+                                       pBegin = NULL;\r
+                                       pEnd = NULL;\r
+                               }\r
+                               p++;\r
+                               Length--;\r
                        }\r
-                       p_BIO_free(pBIO);\r
                }\r
        }\r
        LeaveCriticalSection(&g_OpenSSLLock);\r
index f06c752..ffbef2c 100644 (file)
@@ -18,7 +18,7 @@ void FreeOpenSSL();
 BOOL IsOpenSSLLoaded();\r
 void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback);\r
 void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback);\r
-BOOL SetSSLRootCertificate(void* pData, DWORD Length);\r
+BOOL SetSSLRootCertificate(const void* pData, DWORD Length);\r
 BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName);\r
 BOOL AttachSSL(SOCKET s, SOCKET parent, BOOL* pbAborted);\r
 BOOL DetachSSL(SOCKET s);\r