• R/O
  • SSH
  • HTTPS

tortoisesvn: Commit


Commit MetaInfo

Revision28477 (tree)
Time2019-01-08 03:47:38
Authorstefankueng

Log Message

apply the e_capi patch.

Change Summary

Incremental Difference

--- branches/1.9.x/ext/openssl/engines/e_capi.c (revision 28476)
+++ branches/1.9.x/ext/openssl/engines/e_capi.c (revision 28477)
@@ -66,15 +66,17 @@
6666 # include <openssl/rsa.h>
6767
6868 # ifndef _WIN32_WINNT
69-# define _WIN32_WINNT 0x0400
69+# define _WIN32_WINNT 0x0600
7070 # endif
7171
7272 # include <windows.h>
7373 # include <wincrypt.h>
7474 # include <malloc.h>
75+# include <shlwapi.h>
7576 # ifndef alloca
7677 # define alloca _alloca
7778 # endif
79+# pragma comment(lib, "shlwapi.lib")
7880
7981 /*
8082 * This module uses several "new" interfaces, among which is
@@ -141,6 +143,96 @@
141143 # include "e_capi_err.h"
142144 # include "e_capi_err.c"
143145
146+char lastUsedAuthCacheHash[100] = {0};
147+
148+ void TSVN_GetSHA1HashFromX509(STACK_OF(X509_NAME) *ca_dn, char * outbuf)
149+ {
150+ HCRYPTPROV hProv = 0;
151+ HCRYPTHASH hHash = 0;
152+ DWORD cbHash = 0;
153+ BYTE rgbHash[20];
154+ char sha1hashstring[50];
155+ CHAR rgbDigits[] = "0123456789abcdef";
156+ int i;
157+ X509_NAME * nm;
158+
159+ outbuf[0] = 0;
160+ if (CryptAcquireContext(&hProv,
161+ NULL,
162+ NULL,
163+ PROV_RSA_FULL,
164+ CRYPT_VERIFYCONTEXT))
165+ {
166+ if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
167+ {
168+ for (i = 0; i < sk_X509_NAME_num(ca_dn); ++i)
169+ {
170+ nm = sk_X509_NAME_value(ca_dn, i);
171+ CryptHashData(hHash, nm->canon_enc, nm->canon_enclen, 0);
172+ }
173+
174+ cbHash = 20;
175+ if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
176+ {
177+ for (i = 0; i < (int)cbHash; ++i)
178+ {
179+ sha1hashstring[i*2] = rgbDigits[rgbHash[i] >> 4];
180+ sha1hashstring[i*2+1] = rgbDigits[rgbHash[i] & 0xf];
181+ }
182+ sha1hashstring[cbHash] = 0;
183+ strcpy(outbuf, sha1hashstring);
184+ }
185+ CryptDestroyHash(hHash);
186+ }
187+ CryptReleaseContext(hProv, 0);
188+ }
189+ }
190+
191+ int TSVN_GetSavedIndexForHash(const char* hash)
192+ {
193+ int ret = -1;
194+ DWORD dwType = 0;
195+ DWORD dwData = 0;
196+ DWORD dwDataSize = 4;
197+ int bLoad = 1;
198+ if (SHGetValueA(HKEY_CURRENT_USER, "Software\\TortoiseSVN\\CAPIAuthz", hash, &dwType, &dwData, &dwDataSize) == ERROR_SUCCESS)
199+ {
200+ if (dwType == REG_DWORD)
201+ {
202+ ret = (int)dwData;
203+ }
204+ }
205+ return ret;
206+ }
207+
208+ void TSVN_SaveIndexForHash(const char* hash, int index)
209+ {
210+ DWORD value = index;
211+ SHSetValueA(HKEY_CURRENT_USER, "Software\\TortoiseSVN\\CAPIAuthz", hash, REG_DWORD, &value, sizeof(value));
212+ }
213+
214+ void TSVN_ClearLastUsedAuthCache()
215+ {
216+ SHDeleteValueA(HKEY_CURRENT_USER, "Software\\TortoiseSVN\\CAPIAuthz", lastUsedAuthCacheHash);
217+ }
218+
219+ BOOL CALLBACK FindWindoProc(HWND hwnd, LPARAM lParam)
220+ {
221+ HWND * pWnd;
222+ DWORD pid = 0;
223+ if ((GetWindowLongPtr(hwnd, GWL_STYLE) & WS_VISIBLE))
224+ {
225+ GetWindowThreadProcessId(hwnd, &pid);
226+ if (pid == GetCurrentProcessId())
227+ {
228+ pWnd = (HWND*)lParam;
229+ (*pWnd) = hwnd;
230+ return FALSE;
231+ }
232+ }
233+ return TRUE;
234+ }
235+
144236 static const char *engine_capi_id = "capi";
145237 static const char *engine_capi_name = "CryptoAPI ENGINE";
146238
@@ -591,6 +683,22 @@
591683
592684 void ENGINE_load_capi(void)
593685 {
686+ DWORD dwType = 0;
687+ DWORD dwData = 0;
688+ DWORD dwDataSize = 4;
689+ int bLoad = 1;
690+ if (SHGetValueA(HKEY_CURRENT_USER, "Software\\TortoiseSVN", "OpenSSLCapi", &dwType, &dwData, &dwDataSize) == ERROR_SUCCESS)
691+ {
692+ if (dwType == REG_DWORD)
693+ {
694+ if (dwData == 0)
695+ {
696+ bLoad = 0;
697+ }
698+ }
699+ }
700+ if (bLoad)
701+ {
594702 /* Copied from eng_[openssl|dyn].c */
595703 ENGINE *toadd = engine_capi();
596704 if (!toadd)
@@ -598,6 +706,7 @@
598706 ENGINE_add(toadd);
599707 ENGINE_free(toadd);
600708 ERR_clear_error();
709+ }
601710 }
602711 # endif
603712
@@ -1482,10 +1591,14 @@
14821591 }
14831592 if (ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE)
14841593 dwFlags = CRYPT_MACHINE_KEYSET;
1485- if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, dwFlags)) {
1486- CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
1487- capi_addlasterror();
1488- goto err;
1594+ // first try enhanced version
1595+ if(!CryptAcquireContext(&key->hprov, contname, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, dwFlags))
1596+ {
1597+ if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, dwFlags)) {
1598+ CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
1599+ capi_addlasterror();
1600+ goto err;
1601+ }
14891602 }
14901603 if (!CryptGetUserKey(key->hprov, keyspec, &key->key)) {
14911604 CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
@@ -1709,6 +1822,7 @@
17091822 PCCERT_CONTEXT cert = NULL, excert = NULL;
17101823 CAPI_CTX *ctx;
17111824 CAPI_KEY *key;
1825+ char hash[100];
17121826 ctx = ENGINE_get_ex_data(e, capi_idx);
17131827
17141828 *pcert = NULL;
@@ -1765,9 +1879,22 @@
17651879 return 0;
17661880
17671881 /* Select the appropriate certificate */
1882+ TSVN_GetSHA1HashFromX509(ca_dn, hash);
1883+ strcpy(lastUsedAuthCacheHash, hash);
1884+ client_cert_idx = TSVN_GetSavedIndexForHash(hash);
1885+ if ((client_cert_idx < 0) || (client_cert_idx >= sk_X509_num(certs)))
1886+ {
1887+ client_cert_idx = ctx->client_cert_select(e, ssl, certs);
1888+ if (client_cert_idx >= 0)
1889+ {
1890+ TSVN_SaveIndexForHash(hash, client_cert_idx);
1891+ }
1892+ }
1893+ else if (client_cert_idx >= sk_X509_num(certs))
1894+ {
1895+ TSVN_ClearLastUsedAuthCache();
1896+ }
17681897
1769- client_cert_idx = ctx->client_cert_select(e, ssl, certs);
1770-
17711898 /* Set the selected certificate and free the rest */
17721899
17731900 for (i = 0; i < sk_X509_num(certs); i++) {
@@ -1800,7 +1927,9 @@
18001927
18011928 static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
18021929 {
1803- return 0;
1930+ if (sk_X509_num(certs) == 1)
1931+ return 0;
1932+ return -1; /* let TSVN decide which certificate to use */
18041933 }
18051934
18061935 # ifdef OPENSSL_CAPIENG_DIALOG
@@ -1820,7 +1949,7 @@
18201949 # define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004
18211950 # endif
18221951
1823-# define dlg_title L"OpenSSL Application SSL Client Certificate Selection"
1952+# define dlg_title L"TortoiseSVN SSL Client Certificate Selection"
18241953 # define dlg_prompt L"Select a certificate to use for authentication"
18251954 # define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \
18261955 |CRYPTUI_SELECT_INTENDEDUSE_COLUMN
@@ -1858,8 +1987,10 @@
18581987 }
18591988
18601989 }
1861- hwnd = GetForegroundWindow();
1990+ EnumWindows(FindWindoProc, (LPARAM)&hwnd);
18621991 if (!hwnd)
1992+ hwnd = GetForegroundWindow();
1993+ if (!hwnd)
18631994 hwnd = GetActiveWindow();
18641995 if (!hwnd && ctx->getconswindow)
18651996 hwnd = ctx->getconswindow();
Show on old repository browser