• R/O
  • HTTP
  • SSH
  • HTTPS

ffftp: Commit

FFFTPのソースコードです。


Commit MetaInfo

Revision2335c90d75fc705460a84d66f6a13bf57115f8ca (tree)
Time2018-01-07 16:01:12
Authors_kawamoto <s_kawamoto@user...>
Commiters_kawamoto

Log Message

Implement Subject Alternative Names check.

Change Summary

Incremental Difference

Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
Binary files a/FFFTP_Eng_Release_64/FFFTP.exe and b/FFFTP_Eng_Release_64/FFFTP.exe differ
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
Binary files a/Release_64/FFFTP.exe and b/Release_64/FFFTP.exe differ
--- a/doc/eng/FFFTP.txt
+++ b/doc/eng/FFFTP.txt
@@ -65,6 +65,9 @@ This list includes changes applied by automatic software updates.
6565 -- Implemented Server Name Indication.
6666 This solves the problem that it cannot connect to some shared servers.
6767
68+-- Changed to check Subject Alternative Names at validation of SSL/TLS
69+ certificates.
70+
6871 -- Fixed bugs that sometimes it cannot reconnect after transfer failure.
6972
7073 -- Fixed bugs that the queue of file transfer is not released on disconnection.
--- a/doc/eng/history.txt
+++ b/doc/eng/history.txt
@@ -35,6 +35,9 @@ Changes in Ver.2.00
3535 -- Implemented Server Name Indication.
3636 This solves the problem that it cannot connect to some shared servers.
3737
38+-- Changed to check Subject Alternative Names at validation of SSL/TLS
39+ certificates.
40+
3841 -- Fixed bugs that sometimes it cannot reconnect after transfer failure.
3942
4043 -- Fixed bugs that the queue of file transfer is not released on disconnection.
--- a/doc/jpn/FFFTP.txt
+++ b/doc/jpn/FFFTP.txt
@@ -61,7 +61,10 @@ Ver 2.00
6161 ・バグ対策の副作用によるウィンドウのちらつきを解消しました。
6262
6363 ・Server Name Indicationを実装しました。
64- これにより一部の共用サーバーに接続できない問題が解消されます。
64+ これにより一部の共用サーバーに接続できない問題が解消されます。
65+
66+・SSL/TLS証明書の検証時にSubject Alternative Namesを確認するように
67+ 変更しました。
6568
6669 ・転送失敗時に再接続できない場合があるバグを修正しました。
6770
--- a/doc/jpn/history.txt
+++ b/doc/jpn/history.txt
@@ -31,7 +31,10 @@ FFFTP
3131 ・バグ対策の副作用によるウィンドウのちらつきを解消しました。
3232
3333 ・Server Name Indicationを実装しました。
34- これにより一部の共用サーバーに接続できない問題が解消されます。
34+ これにより一部の共用サーバーに接続できない問題が解消されます。
35+
36+・SSL/TLS証明書の検証時にSubject Alternative Namesを確認するように
37+ 変更しました。
3538
3639 ・転送失敗時に再接続できない場合があるバグを修正しました。
3740
--- a/src/common.h
+++ b/src/common.h
@@ -81,7 +81,7 @@
8181 // ソフトウェア自動更新
8282 // リリースバージョンはリリース予定年(10進数4桁)+月(2桁)+日(2桁)+通し番号(0スタート2桁)とする
8383 // 2014年7月31日中の30個目のリリースは2014073129
84-#define RELEASE_VERSION_NUM 2017110400 /* リリースバージョン */
84+#define RELEASE_VERSION_NUM 2018010700 /* リリースバージョン */
8585
8686
8787 // SourceForge.JPによるフォーク
@@ -1423,7 +1423,7 @@ void ResetAutoExitFlg(void);
14231423 int AskAutoExit(void);
14241424 // 暗号化通信対応
14251425 BOOL __stdcall SSLTimeoutCallback(BOOL* pbAborted);
1426-BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName);
1426+BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate);
14271427 BOOL LoadSSLRootCAFile();
14281428 // マルチコアCPUの特定環境下でファイル通信中にクラッシュするバグ対策
14291429 BOOL IsMainThread();
--- a/src/main.c
+++ b/src/main.c
@@ -3588,7 +3588,7 @@ BOOL __stdcall SSLTimeoutCallback(BOOL* pbAborted)
35883588 return FALSE;
35893589 }
35903590
3591-BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName)
3591+BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate)
35923592 {
35933593 BOOL bResult;
35943594 uint32 Hash[5];
@@ -3616,7 +3616,7 @@ BOOL __stdcall SSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certif
36163616 {
36173617 if(pm1 = AllocateStringM(strlen(Certificate) * 2 + 1024))
36183618 {
3619- sprintf(pm0, MSGJPN326, IsHostNameMatched(AskHostAdrs(), CommonName) ? MSGJPN327 : MSGJPN328, bVerified ? MSGJPN327 : MSGJPN328, Certificate);
3619+ sprintf(pm0, MSGJPN326, bVerified ? MSGJPN327 : MSGJPN328, Certificate);
36203620 ReplaceAllStrings(pm1, pm0, "\n", "\r\n");
36213621 if(DialogBoxParam(GetFtpInst(), MAKEINTRESOURCE(ssl_confirm_dlg), GetMainHwnd(), ExeEscTextDialogProc, (LPARAM)pm1) == YES)
36223622 {
--- a/src/mesg-eng.h
+++ b/src/mesg-eng.h
@@ -324,7 +324,7 @@
324324 #define MSGJPN323 _Tu8("Failed to unload untrustworthy DLLs.", "Failed to unload untrustworthy DLLs.")
325325 #define MSGJPN324 _Tu8("Failed to hook required functions to protect the process.", "Failed to hook required functions to protect the process.")
326326 #define MSGJPN325 _Tu8("New master passwords are not identical.", "New master passwords are not identical.")
327-#define MSGJPN326 _Tu8("Summary\nCN is identical: %s\nVerified successfully: %s\n\nDetailed information\n%s", "Summary\nCN is identical: %s\nVerified successfully: %s\n\nDetailed information\n%s")
327+#define MSGJPN326 _Tu8("Summary\nVerified successfully: %s\n\nDetailed information\n%s", "Summary\nVerified successfully: %s\n\nDetailed information\n%s")
328328 #define MSGJPN327 _Tu8("Yes", "Yes")
329329 #define MSGJPN328 _Tu8("No", "No")
330330 #define MSGJPN329 _Tu8("UTF-8 BOM", "UTF-8 BOM")
--- a/src/mesg-jpn.h
+++ b/src/mesg-jpn.h
@@ -324,7 +324,7 @@
324324 #define MSGJPN323 _Tu8("信頼できないDLLをアンロードできませんでした.", "\xE4\xBF\xA1\xE9\xA0\xBC\xE3\x81\xA7\xE3\x81\x8D\xE3\x81\xAA\xE3\x81\x84\x44LL\xE3\x82\x92\xE3\x82\xA2\xE3\x83\xB3\xE3\x83\xAD\xE3\x83\xBC\xE3\x83\x89\xE3\x81\xA7\xE3\x81\x8D\xE3\x81\xBE\xE3\x81\x9B\xE3\x82\x93\xE3\x81\xA7\xE3\x81\x97\xE3\x81\x9F.")
325325 #define MSGJPN324 _Tu8("プロセスの保護に必要な関数をフックできませんでした.", "\xE3\x83\x97\xE3\x83\xAD\xE3\x82\xBB\xE3\x82\xB9\xE3\x81\xAE\xE4\xBF\x9D\xE8\xAD\xB7\xE3\x81\xAB\xE5\xBF\x85\xE8\xA6\x81\xE3\x81\xAA\xE9\x96\xA2\xE6\x95\xB0\xE3\x82\x92\xE3\x83\x95\xE3\x83\x83\xE3\x82\xAF\xE3\x81\xA7\xE3\x81\x8D\xE3\x81\xBE\xE3\x81\x9B\xE3\x82\x93\xE3\x81\xA7\xE3\x81\x97\xE3\x81\x9F.")
326326 #define MSGJPN325 _Tu8("新しいマスターパスワードが一致しません.", "\xE6\x96\xB0\xE3\x81\x97\xE3\x81\x84\xE3\x83\x9E\xE3\x82\xB9\xE3\x82\xBF\xE3\x83\xBC\xE3\x83\x91\xE3\x82\xB9\xE3\x83\xAF\xE3\x83\xBC\xE3\x83\x89\xE3\x81\x8C\xE4\xB8\x80\xE8\x87\xB4\xE3\x81\x97\xE3\x81\xBE\xE3\x81\x9B\xE3\x82\x93.")
327-#define MSGJPN326 _Tu8("概要\nCNの一致: %s\n検証に成功: %s\n\n詳細情報\n%s", "\xE6\xA6\x82\xE8\xA6\x81\nCN\xE3\x81\xAE\xE4\xB8\x80\xE8\x87\xB4: %s\n\xE6\xA4\x9C\xE8\xA8\xBC\xE3\x81\xAB\xE6\x88\x90\xE5\x8A\x9F: %s\n\n\xE8\xA9\xB3\xE7\xB4\xB0\xE6\x83\x85\xE5\xA0\xB1\n%s")
327+#define MSGJPN326 _Tu8("概要\n検証に成功: %s\n\n詳細情報\n%s", "\xE6\xA6\x82\xE8\xA6\x81\n\xE6\xA4\x9C\xE8\xA8\xBC\xE3\x81\xAB\xE6\x88\x90\xE5\x8A\x9F: %s\n\n\xE8\xA9\xB3\xE7\xB4\xB0\xE6\x83\x85\xE5\xA0\xB1\n%s")
328328 #define MSGJPN327 _Tu8("はい", "\xE3\x81\xAF\xE3\x81\x84")
329329 #define MSGJPN328 _Tu8("いいえ", "\xE3\x81\x84\xE3\x81\x84\xE3\x81\x88")
330330 #define MSGJPN329 _Tu8("UTF-8 BOM", "UTF-8 BOM")
--- a/src/socketwrapper.c
+++ b/src/socketwrapper.c
@@ -38,6 +38,7 @@ typedef int (__cdecl* _SSL_write)(SSL*, const void*, int);
3838 typedef int (__cdecl* _SSL_peek)(SSL*, void*, int);
3939 typedef int (__cdecl* _SSL_read)(SSL*, void*, int);
4040 typedef int (__cdecl* _SSL_get_error)(SSL*, int);
41+typedef int (__cdecl* _SSL_set1_param)(SSL*, X509_VERIFY_PARAM*);
4142 typedef X509* (__cdecl* _SSL_get_peer_certificate)(const SSL*);
4243 typedef long (__cdecl* _SSL_get_verify_result)(const SSL*);
4344 typedef SSL_SESSION* (__cdecl* _SSL_get_session)(SSL*);
@@ -56,6 +57,9 @@ typedef void (__cdecl* _X509_free)(X509*);
5657 typedef int (__cdecl* _X509_print_ex)(BIO*, X509*, unsigned long, unsigned long);
5758 typedef X509_NAME* (__cdecl* _X509_get_subject_name)(X509*);
5859 typedef int (__cdecl* _X509_NAME_print_ex)(BIO*, X509_NAME*, int, unsigned long);
60+typedef X509_VERIFY_PARAM* (__cdecl* _X509_VERIFY_PARAM_new)();
61+typedef void (__cdecl* _X509_VERIFY_PARAM_free)(X509_VERIFY_PARAM*);
62+typedef int (__cdecl* _X509_VERIFY_PARAM_set1_host)(X509_VERIFY_PARAM*, const char*, size_t);
5963 typedef void (__cdecl* _X509_CRL_free)(X509_CRL*);
6064 typedef EVP_PKEY* (__cdecl* _PEM_read_bio_PrivateKey)(BIO*, EVP_PKEY**, pem_password_cb*, void*);
6165 typedef EVP_PKEY* (__cdecl* _PEM_read_bio_PUBKEY)(BIO*, EVP_PKEY**, pem_password_cb*, void*);
@@ -94,6 +98,7 @@ _SSL_write p_SSL_write;
9498 _SSL_peek p_SSL_peek;
9599 _SSL_read p_SSL_read;
96100 _SSL_get_error p_SSL_get_error;
101+_SSL_set1_param p_SSL_set1_param;
97102 _SSL_get_peer_certificate p_SSL_get_peer_certificate;
98103 _SSL_get_verify_result p_SSL_get_verify_result;
99104 _SSL_get_session p_SSL_get_session;
@@ -112,6 +117,9 @@ _X509_free p_X509_free;
112117 _X509_print_ex p_X509_print_ex;
113118 _X509_get_subject_name p_X509_get_subject_name;
114119 _X509_NAME_print_ex p_X509_NAME_print_ex;
120+_X509_VERIFY_PARAM_new p_X509_VERIFY_PARAM_new;
121+_X509_VERIFY_PARAM_free p_X509_VERIFY_PARAM_free;
122+_X509_VERIFY_PARAM_set1_host p_X509_VERIFY_PARAM_set1_host;
115123 _X509_CRL_free p_X509_CRL_free;
116124 _PEM_read_bio_PrivateKey p_PEM_read_bio_PrivateKey;
117125 _PEM_read_bio_PUBKEY p_PEM_read_bio_PUBKEY;
@@ -149,7 +157,7 @@ BOOL __stdcall DefaultSSLTimeoutCallback(BOOL* pbAborted)
149157 return *pbAborted;
150158 }
151159
152-BOOL __stdcall DefaultSSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate, LPCSTR CommonName)
160+BOOL __stdcall DefaultSSLConfirmCallback(BOOL* pbAborted, BOOL bVerified, LPCSTR Certificate)
153161 {
154162 return bVerified;
155163 }
@@ -195,6 +203,7 @@ BOOL LoadOpenSSL()
195203 || !(p_SSL_peek = (_SSL_peek)GetProcAddress(g_hOpenSSL, "SSL_peek"))
196204 || !(p_SSL_read = (_SSL_read)GetProcAddress(g_hOpenSSL, "SSL_read"))
197205 || !(p_SSL_get_error = (_SSL_get_error)GetProcAddress(g_hOpenSSL, "SSL_get_error"))
206+ || !(p_SSL_set1_param = (_SSL_set1_param)GetProcAddress(g_hOpenSSL, "SSL_set1_param"))
198207 || !(p_SSL_get_peer_certificate = (_SSL_get_peer_certificate)GetProcAddress(g_hOpenSSL, "SSL_get_peer_certificate"))
199208 || !(p_SSL_get_verify_result = (_SSL_get_verify_result)GetProcAddress(g_hOpenSSL, "SSL_get_verify_result"))
200209 || !(p_SSL_get_session = (_SSL_get_session)GetProcAddress(g_hOpenSSL, "SSL_get_session"))
@@ -227,6 +236,9 @@ BOOL LoadOpenSSL()
227236 || !(p_X509_print_ex = (_X509_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_print_ex"))
228237 || !(p_X509_get_subject_name = (_X509_get_subject_name)GetProcAddress(g_hOpenSSLCommon, "X509_get_subject_name"))
229238 || !(p_X509_NAME_print_ex = (_X509_NAME_print_ex)GetProcAddress(g_hOpenSSLCommon, "X509_NAME_print_ex"))
239+ || !(p_X509_VERIFY_PARAM_new = (_X509_VERIFY_PARAM_new)GetProcAddress(g_hOpenSSLCommon, "X509_VERIFY_PARAM_new"))
240+ || !(p_X509_VERIFY_PARAM_free = (_X509_VERIFY_PARAM_free)GetProcAddress(g_hOpenSSLCommon, "X509_VERIFY_PARAM_free"))
241+ || !(p_X509_VERIFY_PARAM_set1_host = (_X509_VERIFY_PARAM_set1_host)GetProcAddress(g_hOpenSSLCommon, "X509_VERIFY_PARAM_set1_host"))
230242 || !(p_X509_CRL_free = (_X509_CRL_free)GetProcAddress(g_hOpenSSLCommon, "X509_CRL_free"))
231243 || !(p_PEM_read_bio_PrivateKey = (_PEM_read_bio_PrivateKey)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_PrivateKey"))
232244 || !(p_PEM_read_bio_PUBKEY = (_PEM_read_bio_PUBKEY)GetProcAddress(g_hOpenSSLCommon, "PEM_read_bio_PUBKEY"))
@@ -340,8 +352,6 @@ BOOL ConfirmSSLCertificate(SSL* pSSL, BOOL* pbAborted)
340352 BIO* pBIO;
341353 long Length;
342354 char* pBuffer;
343- char* pCN;
344- char* p;
345355 bResult = FALSE;
346356 bVerified = FALSE;
347357 pData = NULL;
@@ -374,24 +384,10 @@ BOOL ConfirmSSLCertificate(SSL* pSSL, BOOL* pbAborted)
374384 }
375385 p_BIO_free(pBIO);
376386 }
377- p_X509_free(pX509);
378387 }
379388 if(pX509 && p_SSL_get_verify_result(pSSL) == X509_V_OK)
380389 bVerified = TRUE;
381- pCN = pSubject;
382- while(pCN)
383- {
384- if(strncmp(pCN, "CN=", strlen("CN=")) == 0)
385- {
386- pCN += strlen("CN=");
387- if(p = strchr(pCN, ','))
388- *p = '\0';
389- break;
390- }
391- if(pCN = strchr(pCN, ','))
392- pCN++;
393- }
394- bResult = g_pOpenSSLConfirmCallback(pbAborted, bVerified, pData, pCN);
390+ bResult = g_pOpenSSLConfirmCallback(pbAborted, bVerified, pData);
395391 if(pData)
396392 free(pData);
397393 if(pSubject)
@@ -528,55 +524,6 @@ BOOL SetSSLRootCertificate(const void* pData, DWORD Length)
528524 return r;
529525 }
530526
531-// ワイルドカードの比較
532-// 主にSSL証明書のCN確認用
533-BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName)
534-{
535- BOOL bResult;
536- char* pa0;
537- const char* pAsterisk;
538- size_t BeforeAsterisk;
539- const char* pBeginAsterisk;
540- const char* pEndAsterisk;
541- const char* pDot;
542- bResult = FALSE;
543- if(HostName && CommonName)
544- {
545- if(pa0 = AllocateStringA(strlen(HostName) * 4))
546- {
547- if(ConvertNameToPunycode(pa0, HostName))
548- {
549- if(pAsterisk = strchr(CommonName, '*'))
550- {
551- BeforeAsterisk = ((size_t)pAsterisk - (size_t)CommonName) / sizeof(char);
552- pBeginAsterisk = pa0 + BeforeAsterisk;
553- while(*pAsterisk == '*')
554- {
555- pAsterisk++;
556- }
557- pEndAsterisk = pa0 + strlen(pa0) - strlen(pAsterisk);
558- // "*"より前は大文字小文字を無視して完全一致
559- if(_strnicmp(pa0, CommonName, BeforeAsterisk) == 0)
560- {
561- // "*"より後は大文字小文字を無視して完全一致
562- if(_stricmp(pEndAsterisk, pAsterisk) == 0)
563- {
564- // "*"と一致する範囲に"."が含まれてはならない
565- pDot = strchr(pBeginAsterisk, '.');
566- if(!pDot || pDot >= pEndAsterisk)
567- bResult = TRUE;
568- }
569- }
570- }
571- else if(_stricmp(pa0, CommonName) == 0)
572- bResult = TRUE;
573- }
574- }
575- FreeDuplicatedString(pa0);
576- }
577- return bResult;
578-}
579-
580527 #pragma warning(push)
581528 #pragma warning(disable:4090)
582529
@@ -705,6 +652,7 @@ BOOL AttachSSL(SOCKET s, SOCKET parent, BOOL* pbAborted, BOOL bStrengthen, const
705652 SSL** ppSSLParent;
706653 SSL_SESSION* pSession;
707654 char* pa0;
655+ X509_VERIFY_PARAM* pParam;
708656 int Return;
709657 int Error;
710658 if(!g_bOpenSSLLoaded)
@@ -753,7 +701,15 @@ BOOL AttachSSL(SOCKET s, SOCKET parent, BOOL* pbAborted, BOOL bStrengthen, const
753701 if(pa0 = AllocateStringA(strlen(ServerName) * 4))
754702 {
755703 if(ConvertNameToPunycode(pa0, ServerName))
704+ {
756705 p_SSL_ctrl(*ppSSL, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, pa0);
706+ if(pParam = p_X509_VERIFY_PARAM_new())
707+ {
708+ p_X509_VERIFY_PARAM_set1_host(pParam, pa0, 0);
709+ p_SSL_set1_param(*ppSSL, pParam);
710+ p_X509_VERIFY_PARAM_free(pParam);
711+ }
712+ }
757713 }
758714 FreeDuplicatedString(pa0);
759715 }
--- a/src/socketwrapper.h
+++ b/src/socketwrapper.h
@@ -11,7 +11,7 @@
1111 #define USE_OPENSSL
1212
1313 typedef BOOL (__stdcall* LPSSLTIMEOUTCALLBACK)(BOOL*);
14-typedef BOOL (__stdcall* LPSSLCONFIRMCALLBACK)(BOOL*, BOOL, LPCSTR, LPCSTR);
14+typedef BOOL (__stdcall* LPSSLCONFIRMCALLBACK)(BOOL*, BOOL, LPCSTR);
1515
1616 BOOL LoadOpenSSL();
1717 void FreeOpenSSL();
@@ -19,7 +19,6 @@ BOOL IsOpenSSLLoaded();
1919 void SetSSLTimeoutCallback(DWORD Timeout, LPSSLTIMEOUTCALLBACK pCallback);
2020 void SetSSLConfirmCallback(LPSSLCONFIRMCALLBACK pCallback);
2121 BOOL SetSSLRootCertificate(const void* pData, DWORD Length);
22-BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName);
2322 BOOL EncryptSignature(const char* PrivateKey, const char* Password, const void* pIn, DWORD InLength, void* pOut, DWORD OutLength, DWORD* pOutLength);
2423 BOOL DecryptSignature(const char* PublicKey, const char* Password, const void* pIn, DWORD InLength, void* pOut, DWORD OutLength, DWORD* pOutLength);
2524 BOOL GetHashSHA1(const void* pData, DWORD Size, void* pHash);
Show on old repository browser