• R/O
  • SSH
  • HTTPS

tortoisesvn: Commit


Commit MetaInfo

Revision28484 (tree)
Time2019-01-08 04:05:54
Authorstefankueng

Log Message

apply the e_capi patch

Change Summary

Incremental Difference

--- trunk/ext/build/openssl.patch (revision 28483)
+++ trunk/ext/build/openssl.patch (revision 28484)
@@ -1,6 +1,6 @@
11 Index: engines/e_capi.c
22 ===================================================================
3---- engines/e_capi.c (revision 28366)
3+--- engines/e_capi.c (revision 28483)
44 +++ engines/e_capi.c (working copy)
55 @@ -9,7 +9,7 @@
66
@@ -168,7 +168,7 @@
168168 }
169169 # endif
170170
171-@@ -1491,9 +1608,11 @@
171+@@ -1505,9 +1622,11 @@
172172 dwFlags = CRYPT_MACHINE_KEYSET;
173173 if (!CryptAcquireContextW(&key->hprov, contname, provname, ptype,
174174 dwFlags)) {
@@ -183,7 +183,7 @@
183183 }
184184 if (!CryptGetUserKey(key->hprov, keyspec, &key->key)) {
185185 CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
186-@@ -1687,6 +1806,7 @@
186+@@ -1701,6 +1820,7 @@
187187 PCCERT_CONTEXT cert = NULL, excert = NULL;
188188 CAPI_CTX *ctx;
189189 CAPI_KEY *key;
@@ -191,7 +191,7 @@
191191 ctx = ENGINE_get_ex_data(e, capi_idx);
192192
193193 *pcert = NULL;
194-@@ -1743,9 +1863,22 @@
194+@@ -1757,9 +1877,22 @@
195195 return 0;
196196
197197 /* Select the appropriate certificate */
@@ -216,7 +216,7 @@
216216 /* Set the selected certificate and free the rest */
217217
218218 for (i = 0; i < sk_X509_num(certs); i++) {
219-@@ -1778,7 +1911,9 @@
219+@@ -1792,7 +1925,9 @@
220220
221221 static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
222222 {
@@ -227,7 +227,7 @@
227227 }
228228
229229 # ifdef OPENSSL_CAPIENG_DIALOG
230-@@ -1798,7 +1933,7 @@
230+@@ -1812,7 +1947,7 @@
231231 # define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004
232232 # endif
233233
@@ -236,7 +236,7 @@
236236 # define dlg_prompt L"Select a certificate to use for authentication"
237237 # define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \
238238 |CRYPTUI_SELECT_INTENDEDUSE_COLUMN
239-@@ -1836,8 +1971,10 @@
239+@@ -1850,8 +1985,10 @@
240240 }
241241
242242 }
--- trunk/ext/openssl/engines/e_capi.c (revision 28483)
+++ trunk/ext/openssl/engines/e_capi.c (revision 28484)
@@ -9,7 +9,7 @@
99
1010 #ifdef _WIN32
1111 # ifndef _WIN32_WINNT
12-# define _WIN32_WINNT 0x0400
12+# define _WIN32_WINNT 0x0600
1313 # endif
1414 # include <windows.h>
1515 # include <wincrypt.h>
@@ -18,10 +18,11 @@
1818 # include <string.h>
1919 # include <stdlib.h>
2020 # include <malloc.h>
21+# include <shlwapi.h>
2122 # ifndef alloca
2223 # define alloca _alloca
2324 # endif
24-
25+# pragma comment(lib, "shlwapi.lib")
2526 # include <openssl/crypto.h>
2627
2728 # ifndef OPENSSL_NO_CAPIENG
@@ -31,6 +32,15 @@
3132 # include <openssl/rsa.h>
3233 # include <openssl/dsa.h>
3334
35+struct X509_name_st {
36+ STACK_OF(X509_NAME_ENTRY) *entries; /* DN components */
37+ int modified; /* true if 'bytes' needs to be built */
38+ BUF_MEM *bytes; /* cached encoding: cannot be NULL */
39+ /* canonical encoding used for rapid Name comparison */
40+ unsigned char *canon_enc;
41+ int canon_enclen;
42+} /* X509_NAME */ ;
43+
3444 /*
3545 * This module uses several "new" interfaces, among which is
3646 * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is
@@ -99,6 +109,96 @@
99109 # include "e_capi_err.h"
100110 # include "e_capi_err.c"
101111
112+char lastUsedAuthCacheHash[100] = {0};
113+
114+ void TSVN_GetSHA1HashFromX509(STACK_OF(X509_NAME) *ca_dn, char * outbuf)
115+ {
116+ HCRYPTPROV hProv = 0;
117+ HCRYPTHASH hHash = 0;
118+ DWORD cbHash = 0;
119+ BYTE rgbHash[20];
120+ char sha1hashstring[50];
121+ CHAR rgbDigits[] = "0123456789abcdef";
122+ int i;
123+ X509_NAME * nm;
124+
125+ outbuf[0] = 0;
126+ if (CryptAcquireContext(&hProv,
127+ NULL,
128+ NULL,
129+ PROV_RSA_FULL,
130+ CRYPT_VERIFYCONTEXT))
131+ {
132+ if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
133+ {
134+ for (i = 0; i < sk_X509_NAME_num(ca_dn); ++i)
135+ {
136+ nm = sk_X509_NAME_value(ca_dn, i);
137+ CryptHashData(hHash, nm->canon_enc, nm->canon_enclen, 0);
138+ }
139+
140+ cbHash = 20;
141+ if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
142+ {
143+ for (i = 0; i < (int)cbHash; ++i)
144+ {
145+ sha1hashstring[i*2] = rgbDigits[rgbHash[i] >> 4];
146+ sha1hashstring[i*2+1] = rgbDigits[rgbHash[i] & 0xf];
147+ }
148+ sha1hashstring[cbHash] = 0;
149+ strcpy(outbuf, sha1hashstring);
150+ }
151+ CryptDestroyHash(hHash);
152+ }
153+ CryptReleaseContext(hProv, 0);
154+ }
155+ }
156+
157+ int TSVN_GetSavedIndexForHash(const char* hash)
158+ {
159+ int ret = -1;
160+ DWORD dwType = 0;
161+ DWORD dwData = 0;
162+ DWORD dwDataSize = 4;
163+ int bLoad = 1;
164+ if (SHGetValueA(HKEY_CURRENT_USER, "Software\\TortoiseSVN\\CAPIAuthz", hash, &dwType, &dwData, &dwDataSize) == ERROR_SUCCESS)
165+ {
166+ if (dwType == REG_DWORD)
167+ {
168+ ret = (int)dwData;
169+ }
170+ }
171+ return ret;
172+ }
173+
174+ void TSVN_SaveIndexForHash(const char* hash, int index)
175+ {
176+ DWORD value = index;
177+ SHSetValueA(HKEY_CURRENT_USER, "Software\\TortoiseSVN\\CAPIAuthz", hash, REG_DWORD, &value, sizeof(value));
178+ }
179+
180+ void TSVN_ClearLastUsedAuthCache()
181+ {
182+ SHDeleteValueA(HKEY_CURRENT_USER, "Software\\TortoiseSVN\\CAPIAuthz", lastUsedAuthCacheHash);
183+ }
184+
185+ BOOL CALLBACK FindWindoProc(HWND hwnd, LPARAM lParam)
186+ {
187+ HWND * pWnd;
188+ DWORD pid = 0;
189+ if ((GetWindowLongPtr(hwnd, GWL_STYLE) & WS_VISIBLE))
190+ {
191+ GetWindowThreadProcessId(hwnd, &pid);
192+ if (pid == GetCurrentProcessId())
193+ {
194+ pWnd = (HWND*)lParam;
195+ (*pWnd) = hwnd;
196+ return FALSE;
197+ }
198+ }
199+ return TRUE;
200+ }
201+
102202 static const char *engine_capi_id = "capi";
103203 static const char *engine_capi_name = "CryptoAPI ENGINE";
104204
@@ -593,6 +693,22 @@
593693
594694 void engine_load_capi_int(void)
595695 {
696+ DWORD dwType = 0;
697+ DWORD dwData = 0;
698+ DWORD dwDataSize = 4;
699+ int bLoad = 1;
700+ if (SHGetValueA(HKEY_CURRENT_USER, "Software\\TortoiseSVN", "OpenSSLCapi", &dwType, &dwData, &dwDataSize) == ERROR_SUCCESS)
701+ {
702+ if (dwType == REG_DWORD)
703+ {
704+ if (dwData == 0)
705+ {
706+ bLoad = 0;
707+ }
708+ }
709+ }
710+ if (bLoad)
711+ {
596712 /* Copied from eng_[openssl|dyn].c */
597713 ENGINE *toadd = engine_capi();
598714 if (!toadd)
@@ -600,6 +716,7 @@
600716 ENGINE_add(toadd);
601717 ENGINE_free(toadd);
602718 ERR_clear_error();
719+ }
603720 }
604721 # endif
605722
@@ -1505,9 +1622,11 @@
15051622 dwFlags = CRYPT_MACHINE_KEYSET;
15061623 if (!CryptAcquireContextW(&key->hprov, contname, provname, ptype,
15071624 dwFlags)) {
1508- CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
1509- capi_addlasterror();
1510- goto err;
1625+ if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, dwFlags)) {
1626+ CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
1627+ capi_addlasterror();
1628+ goto err;
1629+ }
15111630 }
15121631 if (!CryptGetUserKey(key->hprov, keyspec, &key->key)) {
15131632 CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
@@ -1701,6 +1820,7 @@
17011820 PCCERT_CONTEXT cert = NULL, excert = NULL;
17021821 CAPI_CTX *ctx;
17031822 CAPI_KEY *key;
1823+ char hash[100];
17041824 ctx = ENGINE_get_ex_data(e, capi_idx);
17051825
17061826 *pcert = NULL;
@@ -1757,9 +1877,22 @@
17571877 return 0;
17581878
17591879 /* Select the appropriate certificate */
1880+ TSVN_GetSHA1HashFromX509(ca_dn, hash);
1881+ strcpy(lastUsedAuthCacheHash, hash);
1882+ client_cert_idx = TSVN_GetSavedIndexForHash(hash);
1883+ if ((client_cert_idx < 0) || (client_cert_idx >= sk_X509_num(certs)))
1884+ {
1885+ client_cert_idx = ctx->client_cert_select(e, ssl, certs);
1886+ if (client_cert_idx >= 0)
1887+ {
1888+ TSVN_SaveIndexForHash(hash, client_cert_idx);
1889+ }
1890+ }
1891+ else if (client_cert_idx >= sk_X509_num(certs))
1892+ {
1893+ TSVN_ClearLastUsedAuthCache();
1894+ }
17601895
1761- client_cert_idx = ctx->client_cert_select(e, ssl, certs);
1762-
17631896 /* Set the selected certificate and free the rest */
17641897
17651898 for (i = 0; i < sk_X509_num(certs); i++) {
@@ -1792,7 +1925,9 @@
17921925
17931926 static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
17941927 {
1795- return 0;
1928+ if (sk_X509_num(certs) == 1)
1929+ return 0;
1930+ return -1; /* let TSVN decide which certificate to use */
17961931 }
17971932
17981933 # ifdef OPENSSL_CAPIENG_DIALOG
@@ -1812,7 +1947,7 @@
18121947 # define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004
18131948 # endif
18141949
1815-# define dlg_title L"OpenSSL Application SSL Client Certificate Selection"
1950+# define dlg_title L"TortoiseSVN SSL Client Certificate Selection"
18161951 # define dlg_prompt L"Select a certificate to use for authentication"
18171952 # define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \
18181953 |CRYPTUI_SELECT_INTENDEDUSE_COLUMN
@@ -1850,8 +1985,10 @@
18501985 }
18511986
18521987 }
1853- hwnd = GetForegroundWindow();
1988+ EnumWindows(FindWindoProc, (LPARAM)&hwnd);
18541989 if (!hwnd)
1990+ hwnd = GetForegroundWindow();
1991+ if (!hwnd)
18551992 hwnd = GetActiveWindow();
18561993 if (!hwnd && ctx->getconswindow)
18571994 hwnd = ctx->getconswindow();
Show on old repository browser