• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

FFFTPのソースコードです。


Commit MetaInfo

修訂9ade514641b46ed744acb24265eff6616954113d (tree)
時間2011-11-15 23:47:39
作者s_kawamoto <s_kawamoto@user...>
Commiters_kawamoto

Log Message

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.

Change Summary

差異

Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
--- a/Resource/FFFTP.rc
+++ b/Resource/FFFTP.rc
@@ -1369,7 +1369,7 @@ END
13691369
13701370 savecrypt_dlg DIALOG 0, 0, 146, 50
13711371 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION
1372-CAPTION "パスワードの保存"
1372+CAPTION "暗号化の状態の保存"
13731373 FONT 9, "MS Pゴシック"
13741374 BEGIN
13751375 LTEXT "現在の暗号化の状態を保存しますか?",-1,7,7,132,17
@@ -1377,6 +1377,16 @@ BEGIN
13771377 PUSHBUTTON "いいえ",IDCANCEL,78,29,50,14
13781378 END
13791379
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+
13801390
13811391 /////////////////////////////////////////////////////////////////////////////
13821392 //
@@ -2016,6 +2026,14 @@ BEGIN
20162026 TOPMARGIN, 7
20172027 BOTTOMMARGIN, 43
20182028 END
2029+
2030+ updatesslroot_dlg, DIALOG
2031+ BEGIN
2032+ LEFTMARGIN, 7
2033+ RIGHTMARGIN, 139
2034+ TOPMARGIN, 7
2035+ BOTTOMMARGIN, 43
2036+ END
20192037 END
20202038 #endif // APSTUDIO_INVOKED
20212039
--- a/Resource/resource.h
+++ b/Resource/resource.h
@@ -111,6 +111,7 @@
111111 #define hset_crypt_dlg 189
112112 #define hset_adv3_dlg 190
113113 #define savecrypt_dlg 191
114+#define updatesslroot_dlg 192
114115 #define TRANS_TIME_BAR 1002
115116 #define TRANS_TEXT 1003
116117 #define TRANS_REMOTE 1003
@@ -616,7 +617,7 @@
616617 //
617618 #ifdef APSTUDIO_INVOKED
618619 #ifndef APSTUDIO_READONLY_SYMBOLS
619-#define _APS_NEXT_RESOURCE_VALUE 192
620+#define _APS_NEXT_RESOURCE_VALUE 193
620621 #define _APS_NEXT_COMMAND_VALUE 40176
621622 #define _APS_NEXT_CONTROL_VALUE 1208
622623 #define _APS_NEXT_SYMED_VALUE 101
--- a/Resource_eng/FFFTP-eng.rc
+++ b/Resource_eng/FFFTP-eng.rc
@@ -1395,7 +1395,7 @@ END
13951395
13961396 savecrypt_dlg DIALOG 0, 0, 146, 50
13971397 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION
1398-CAPTION "パスワードの保存"
1398+CAPTION "Save Encryption Status"
13991399 FONT 9, "MS Sans Serif"
14001400 BEGIN
14011401 LTEXT "Save current encryption status?",-1,7,7,132,17
@@ -1403,6 +1403,16 @@ BEGIN
14031403 PUSHBUTTON "No",IDCANCEL,78,29,50,14
14041404 END
14051405
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+
14061416
14071417 /////////////////////////////////////////////////////////////////////////////
14081418 //
@@ -2039,6 +2049,14 @@ BEGIN
20392049 TOPMARGIN, 7
20402050 BOTTOMMARGIN, 43
20412051 END
2052+
2053+ updatesslroot_dlg, DIALOG
2054+ BEGIN
2055+ LEFTMARGIN, 7
2056+ RIGHTMARGIN, 139
2057+ TOPMARGIN, 7
2058+ BOTTOMMARGIN, 43
2059+ END
20422060 END
20432061 #endif // APSTUDIO_INVOKED
20442062
--- a/Resource_eng/resource.h
+++ b/Resource_eng/resource.h
@@ -111,6 +111,7 @@
111111 #define hset_crypt_dlg 189
112112 #define hset_adv3_dlg 190
113113 #define savecrypt_dlg 191
114+#define updatesslroot_dlg 192
114115 #define TRANS_TIME_BAR 1002
115116 #define TRANS_TEXT 1003
116117 #define TRANS_REMOTE 1003
@@ -616,7 +617,7 @@
616617 //
617618 #ifdef APSTUDIO_INVOKED
618619 #ifndef APSTUDIO_READONLY_SYMBOLS
619-#define _APS_NEXT_RESOURCE_VALUE 192
620+#define _APS_NEXT_RESOURCE_VALUE 193
620621 #define _APS_NEXT_COMMAND_VALUE 40176
621622 #define _APS_NEXT_CONTROL_VALUE 1208
622623 #define _APS_NEXT_SYMED_VALUE 101
--- a/common.h
+++ b/common.h
@@ -1250,6 +1250,7 @@ int AskAutoExit(void);
12501250 // 暗号化通信対応
12511251 BOOL __stdcall SSLTimeoutCallback(BOOL* pbAborted);
12521252 BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName);
1253+BOOL LoadSSLRootCAFile();
12531254
12541255 /*===== filelist.c =====*/
12551256
--- a/doc/eng/FFFTP.txt
+++ b/doc/eng/FFFTP.txt
@@ -53,6 +53,9 @@ Changes in Ver.1.99
5353 This may allow to transfer files successfully as with 1.97b or earlier,
5454 but sometimes may cause some errors.
5555
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+
5659
5760 Outline
5861 -------
--- a/doc/eng/history.txt
+++ b/doc/eng/history.txt
@@ -21,6 +21,9 @@ Changes in Ver.1.99
2121
2222 -- Changed to detect encoding of strings in INI file automatically.
2323
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+
2427 Changes in Ver.1.98c
2528 --------------------
2629
--- a/doc/jpn/FFFTP.txt
+++ b/doc/jpn/FFFTP.txt
@@ -55,6 +55,10 @@ Ver 1.99
5555  追加しました。これにより1.97b以前で転送可能だったが1.98で転送不能に
5656  なるという症状が改善されますが、不具合が発生する可能性があります。
5757
58+・FTPSで接続した時にSSL/TLSのルート証明書を用いてホストの証明書を検証
59+ するように変更しました。ルート証明書を更新するには同梱の"ssl.pem"
60+ ファイルをPEM形式に従って書き換えてください。
61+
5862
5963 Ver 1.96d以前へ戻す場合
6064 -----------------------
--- a/doc/jpn/history.txt
+++ b/doc/jpn/history.txt
@@ -27,6 +27,10 @@ FFFTP
2727  追加しました。これにより1.97b以前で転送可能だったが1.98で転送不能に
2828  なるという症状が改善されますが、不具合が発生する可能性があります。
2929
30+・FTPSで接続した時にSSL/TLSのルート証明書を用いてホストの証明書を検証
31+ するように変更しました。ルート証明書を更新するには同梱の"ssl.pem"
32+ ファイルをPEM形式に従って書き換えてください。
33+
3034 ■Ver 1.98c
3135
3236 ・日本語ドメイン名のホストへの接続時にアドレスをPunycodeへ変換してから
--- a/main.c
+++ b/main.c
@@ -130,6 +130,9 @@ static int SuppressRefresh = 0;
130130
131131 static DWORD dwCookie;
132132
133+// 暗号化通信対応
134+static char SSLRootCAFilePath[FMAX_PATH+1];
135+
133136
134137 /*===== グローバルなワーク =====*/
135138
@@ -223,6 +226,7 @@ int FolderAttr = NO;
223226 int FolderAttrNum = 777;
224227 // 暗号化通信対応
225228 BYTE CertificateCacheHash[MAX_CERT_CACHE_HASH][20];
229+BYTE SSLRootCAFileHash[20];
226230
227231
228232
@@ -472,6 +476,9 @@ static int InitApp(LPSTR lpszCmdLine, int cmdShow)
472476 // 暗号化通信対応
473477 SetSSLTimeoutCallback(TimeOut * 1000, SSLTimeoutCallback);
474478 SetSSLConfirmCallback(SSLConfirmCallback);
479+ GetModuleFileName(NULL, SSLRootCAFilePath, FMAX_PATH);
480+ strcpy(GetFileName(SSLRootCAFilePath), "ssl.pem");
481+ LoadSSLRootCAFile();
475482
476483 LoadJre();
477484 if(NoRasControl == NO)
@@ -2950,3 +2957,35 @@ BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certif
29502957 return bResult;
29512958 }
29522959
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+
--- a/misc.c
+++ b/misc.c
@@ -1733,6 +1733,7 @@ char *MakeNumString(LONGLONG Num, char *Buf, BOOL Comma)
17331733 // 現在UNC対応の予定は無い
17341734 char* MakeDistinguishableFileName(char* Out, char* In)
17351735 {
1736+ char* Fname;
17361737 char Tmp[FMAX_PATH+1];
17371738 char Tmp2[FMAX_PATH+3];
17381739 HANDLE hFind;
@@ -1741,6 +1742,7 @@ char* MakeDistinguishableFileName(char* Out, char* In)
17411742 strcpy(Out, In);
17421743 else
17431744 {
1745+ Fname = GetFileName(In);
17441746 strcpy(Tmp, In);
17451747 strcpy(Tmp2, Tmp);
17461748 strcat(Tmp2, ".*");
@@ -1748,12 +1750,12 @@ char* MakeDistinguishableFileName(char* Out, char* In)
17481750 {
17491751 do
17501752 {
1751- if(strchr(Find.cFileName, '.'))
1753+ if(strcmp(Find.cFileName, Fname) != 0)
17521754 break;
17531755 }
17541756 while(FindNextFile(hFind, &Find));
17551757 FindClose(hFind);
1756- if(strchr(Find.cFileName, '.'))
1758+ if(strcmp(Find.cFileName, Fname) != 0)
17571759 {
17581760 strcat(Tmp, " ");
17591761 strcpy(Tmp2, Tmp);
--- a/registry.c
+++ b/registry.c
@@ -86,6 +86,9 @@ static int ReadMultiStringFromReg(void *Handle, char *Name, char *Str, DWORD Siz
8686 static int WriteMultiStringToReg(void *Handle, char *Name, char *Str);
8787 static int ReadBinaryFromReg(void *Handle, char *Name, void *Bin, DWORD Size);
8888 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);
8992
9093 int CheckPasswordValidity( char* Password, int length, const char* HashStr );
9194 void CreatePasswordHash( char* Password, int length, char* HashStr );
@@ -189,6 +192,7 @@ extern int FolderAttrNum;
189192
190193 // 暗号化通信対応
191194 extern BYTE CertificateCacheHash[MAX_CERT_CACHE_HASH][20];
195+extern BYTE SSLRootCAFileHash[20];
192196
193197 /*----- マスタパスワードの設定 ----------------------------------------------
194198 *
@@ -295,6 +299,7 @@ void SaveRegistory(void)
295299 // 暗号化通信対応
296300 // char Str[FMAX_PATH+1];
297301 char Str[PRIVATE_KEY_LEN*4+1];
302+ char Buf[FMAX_PATH+1];
298303 int i;
299304 int n;
300305 HOSTDATA DefaultHost;
@@ -589,6 +594,10 @@ void SaveRegistory(void)
589594
590595 // 暗号化通信対応
591596 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);
592601 }
593602 CloseSubKey(hKey4);
594603 }
@@ -619,6 +628,7 @@ int LoadRegistory(void)
619628 // 暗号化通信対応
620629 // char Str[256]; /* ASCII_EXT_LENより大きい事 */
621630 char Str[PRIVATE_KEY_LEN*4+1];
631+ char Buf[FMAX_PATH+1];
622632 char *Pos;
623633 char *Pos2;
624634 HOSTDATA Host;
@@ -944,6 +954,9 @@ int LoadRegistory(void)
944954
945955 // 暗号化通信対応
946956 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);
947960
948961 CloseSubKey(hKey4);
949962 }
@@ -1796,8 +1809,9 @@ typedef struct regdatatbl {
17961809
17971810 static BOOL WriteOutRegToFile(REGDATATBL *Pos);
17981811 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);
18011815 static char *ScanValue(void *Handle, char *Name);
18021816
18031817
--- a/socketwrapper.c
+++ b/socketwrapper.c
@@ -36,7 +36,7 @@ typedef X509* (__cdecl* _SSL_get_peer_certificate)(const SSL*);
3636 typedef long (__cdecl* _SSL_get_verify_result)(const SSL*);
3737 typedef SSL_SESSION* (__cdecl* _SSL_get_session)(SSL*);
3838 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*);
4040 typedef BIO_METHOD* (__cdecl* _BIO_s_mem)();
4141 typedef BIO* (__cdecl* _BIO_new)(BIO_METHOD*);
4242 typedef int (__cdecl* _BIO_free)(BIO*);
@@ -47,6 +47,7 @@ typedef int (__cdecl* _X509_print_ex)(BIO*, X509*, unsigned long, unsigned long)
4747 typedef X509_NAME* (__cdecl* _X509_get_subject_name)(X509*);
4848 typedef int (__cdecl* _X509_NAME_print_ex)(BIO*, X509_NAME*, int, unsigned long);
4949 typedef X509* (__cdecl* _PEM_read_bio_X509)(BIO*, X509**, pem_password_cb*, void*);
50+typedef int (__cdecl* _X509_STORE_add_cert)(X509_STORE*, X509*);
5051
5152 _SSL_load_error_strings p_SSL_load_error_strings;
5253 _SSL_library_init p_SSL_library_init;
@@ -68,7 +69,7 @@ _SSL_get_peer_certificate p_SSL_get_peer_certificate;
6869 _SSL_get_verify_result p_SSL_get_verify_result;
6970 _SSL_get_session p_SSL_get_session;
7071 _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;
7273 _BIO_s_mem p_BIO_s_mem;
7374 _BIO_new p_BIO_new;
7475 _BIO_free p_BIO_free;
@@ -79,6 +80,7 @@ _X509_print_ex p_X509_print_ex;
7980 _X509_get_subject_name p_X509_get_subject_name;
8081 _X509_NAME_print_ex p_X509_NAME_print_ex;
8182 _PEM_read_bio_X509 p_PEM_read_bio_X509;
83+_X509_STORE_add_cert p_X509_STORE_add_cert;
8284
8385 #define MAX_SSL_SOCKET 16
8486
@@ -141,7 +143,7 @@ BOOL LoadOpenSSL()
141143 || !(p_SSL_get_verify_result = (_SSL_get_verify_result)GetProcAddress(g_hOpenSSL, "SSL_get_verify_result"))
142144 || !(p_SSL_get_session = (_SSL_get_session)GetProcAddress(g_hOpenSSL, "SSL_get_session"))
143145 || !(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")))
145147 {
146148 if(g_hOpenSSL)
147149 FreeLibrary(g_hOpenSSL);
@@ -159,7 +161,8 @@ BOOL LoadOpenSSL()
159161 || !(p_X509_print_ex = (_X509_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_print_ex"))
160162 || !(p_X509_get_subject_name = (_X509_get_subject_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_subject_name"))
161163 || !(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")))
163166 {
164167 if(g_hOpenSSL)
165168 FreeLibrary(g_hOpenSSL);
@@ -283,7 +286,7 @@ BOOL ConfirmSSLCertificate(SSL* pSSL, BOOL* pbAborted)
283286 }
284287 p_X509_free(pX509);
285288 }
286- if(p_SSL_get_verify_result(pSSL) == X509_V_OK)
289+ if(pX509 && p_SSL_get_verify_result(pSSL) == X509_V_OK)
287290 bVerified = TRUE;
288291 pCN = pSubject;
289292 while(pCN)
@@ -326,9 +329,14 @@ void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback)
326329 }
327330
328331 // SSLルート証明書を設定
329-BOOL SetSSLRootCertificate(void* pData, DWORD Length)
332+// PEM形式のみ指定可能
333+BOOL SetSSLRootCertificate(const void* pData, DWORD Length)
330334 {
331335 BOOL r;
336+ X509_STORE* pStore;
337+ BYTE* p;
338+ BYTE* pBegin;
339+ BYTE* pEnd;
332340 BIO* pBIO;
333341 X509* pX509;
334342 if(!g_bOpenSSLLoaded)
@@ -339,15 +347,45 @@ BOOL SetSSLRootCertificate(void* pData, DWORD Length)
339347 g_pOpenSSLCTX = p_SSL_CTX_new(p_SSLv23_method());
340348 if(g_pOpenSSLCTX)
341349 {
342- if(pBIO = p_BIO_new_mem_buf(pData, Length))
350+ if(pStore = p_SSL_CTX_get_cert_store(g_pOpenSSLCTX))
343351 {
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)
345356 {
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--;
349388 }
350- p_BIO_free(pBIO);
351389 }
352390 }
353391 LeaveCriticalSection(&g_OpenSSLLock);
--- a/socketwrapper.h
+++ b/socketwrapper.h
@@ -18,7 +18,7 @@ void FreeOpenSSL();
1818 BOOL IsOpenSSLLoaded();
1919 void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback);
2020 void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback);
21-BOOL SetSSLRootCertificate(void* pData, DWORD Length);
21+BOOL SetSSLRootCertificate(const void* pData, DWORD Length);
2222 BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName);
2323 BOOL AttachSSL(SOCKET s, SOCKET parent, BOOL* pbAborted);
2424 BOOL DetachSSL(SOCKET s);