• R/O
  • SSH
  • HTTPS

tortoisesvn: Commit


Commit MetaInfo

Revision28844 (tree)
Zeit2020-04-25 15:30:01
Autorstefankueng

Log Message

apply the e_capi patch.

Ändern Zusammenfassung

Diff

--- trunk/ext/build/openssl.patch (revision 28843)
+++ trunk/ext/build/openssl.patch (revision 28844)
@@ -1,6 +1,6 @@
11 Index: engines/e_capi.c
22 ===================================================================
3---- engines/e_capi.c (revision 28672)
3+--- engines/e_capi.c (revision 28843)
44 +++ engines/e_capi.c (working copy)
55 @@ -9,7 +9,7 @@
66
--- trunk/ext/openssl/engines/e_capi.c (revision 28843)
+++ trunk/ext/openssl/engines/e_capi.c (revision 28844)
@@ -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
@@ -1507,9 +1624,11 @@
15071624 dwFlags = CRYPT_MACHINE_KEYSET;
15081625 if (!CryptAcquireContextW(&key->hprov, contname, provname, ptype,
15091626 dwFlags)) {
1510- CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
1511- capi_addlasterror();
1512- goto err;
1627+ if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, dwFlags)) {
1628+ CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
1629+ capi_addlasterror();
1630+ goto err;
1631+ }
15131632 }
15141633 if (!CryptGetUserKey(key->hprov, keyspec, &key->key)) {
15151634 CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
@@ -1703,6 +1822,7 @@
17031822 PCCERT_CONTEXT cert = NULL, excert = NULL;
17041823 CAPI_CTX *ctx;
17051824 CAPI_KEY *key;
1825+ char hash[100];
17061826 ctx = ENGINE_get_ex_data(e, capi_idx);
17071827
17081828 *pcert = NULL;
@@ -1759,9 +1879,22 @@
17591879 return 0;
17601880
17611881 /* 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+ }
17621897
1763- client_cert_idx = ctx->client_cert_select(e, ssl, certs);
1764-
17651898 /* Set the selected certificate and free the rest */
17661899
17671900 for (i = 0; i < sk_X509_num(certs); i++) {
@@ -1794,7 +1927,9 @@
17941927
17951928 static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
17961929 {
1797- return 0;
1930+ if (sk_X509_num(certs) == 1)
1931+ return 0;
1932+ return -1; /* let TSVN decide which certificate to use */
17981933 }
17991934
18001935 # ifdef OPENSSL_CAPIENG_DIALOG
@@ -1814,7 +1949,7 @@
18141949 # define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004
18151950 # endif
18161951
1817-# define dlg_title L"OpenSSL Application SSL Client Certificate Selection"
1952+# define dlg_title L"TortoiseSVN SSL Client Certificate Selection"
18181953 # define dlg_prompt L"Select a certificate to use for authentication"
18191954 # define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \
18201955 |CRYPTUI_SELECT_INTENDEDUSE_COLUMN
@@ -1852,8 +1987,10 @@
18521987 }
18531988
18541989 }
1855- hwnd = GetForegroundWindow();
1990+ EnumWindows(FindWindoProc, (LPARAM)&hwnd);
18561991 if (!hwnd)
1992+ hwnd = GetForegroundWindow();
1993+ if (!hwnd)
18571994 hwnd = GetActiveWindow();
18581995 if (!hwnd && ctx->getconswindow)
18591996 hwnd = ctx->getconswindow();
Show on old repository browser