A patch to behave same as windows that support only SSLv3/TLSv1.0 on WINE. Evernote fails to connect when TLSv1.2 or 1.1 requested.

  • Download Gist
0001-wininet-disable-TLS1.1-1.2-by-default.patch
Diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
From dfb1d62bcfbc70ff22c126b4ddd835eff739ebde Mon Sep 17 00:00:00 2001
From: Hiroshi Miura <miurahr@linux.com>
Date: Tue, 21 Aug 2012 23:32:55 +0900
Subject: [PATCH 1/2] wininet: disable TLS1.1/1.2 by default
 
OpenSSL 1.0.x now support TLSv1.1 and TLSv1.2 but Windows7 is disabled by default.
It looks Schannel registry whether enables TLSv1.1/1.2.
It fixes error connecting Evernote server with evernote client.
http://bugs.winehq.org/show_bug.cgi?id=30598
 
Signed-off-by: Hiroshi Miura <miurahr@linux.com>
---
dlls/wininet/netconnection.c | 68 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
 
diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c
index c944ff3..bc2a1a7 100644
--- a/dlls/wininet/netconnection.c
+++ b/dlls/wininet/netconnection.c
@@ -124,8 +124,10 @@ MAKE_FUNCPTR(SSL_load_error_strings);
MAKE_FUNCPTR(SSLv23_method);
MAKE_FUNCPTR(SSL_CTX_free);
MAKE_FUNCPTR(SSL_CTX_new);
+MAKE_FUNCPTR(SSL_CTX_ctrl);
MAKE_FUNCPTR(SSL_new);
MAKE_FUNCPTR(SSL_free);
+MAKE_FUNCPTR(SSL_ctrl);
MAKE_FUNCPTR(SSL_set_fd);
MAKE_FUNCPTR(SSL_connect);
MAKE_FUNCPTR(SSL_shutdown);
@@ -446,6 +448,58 @@ static int netconn_secure_verify(int preverify_ok, X509_STORE_CTX *ctx)
return ret;
}
+static long get_tls_option(void) {
+ long tls_option;
+ DWORD type, val, size;
+ HKEY hkey,tls12_client,tls11_client;
+ LONG res;
+ const WCHAR Schannel_Prot[] = { /* SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCANNEL\\Protocols */
+ 'S','Y','S','T','E','M','\\',
+ 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+ 'C','o','n','t','r','o','l','\\',
+ 'S','e','c','u','r','i','t','y','P','r','o','v','i','d','e','r','s','\\',
+ 'S','C','H','A','N','N','E','L','\\',
+ 'P','r','o','t','o','c','o','l','s',0 };
+ const WCHAR TLS12_Client[] = {'T','L','S',' ','1','.','2','\\','C','l','i','e','n','t',0};
+ const WCHAR TLS11_Client[] = {'T','L','S',' ','1','.','1','\\','C','l','i','e','n','t',0};
+ const WCHAR DisabledByDefault[] = {'D','i','s','a','b','l','e','d','B','y','D','e','f','a','u','l','t',0};
+
+ tls_option = SSL_OP_NO_SSLv2; /* disable SSLv2 for security reason, secur32/Schannel(GnuTLS) don't support it */
+ res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ Schannel_Prot,
+ 0, KEY_READ, &hkey);
+ if (res != ERROR_SUCCESS) {
+ tls_option |= SSL_OP_NO_TLSv1_2;
+ tls_option |= SSL_OP_NO_TLSv1_1;
+ goto end;
+ }
+ if (RegOpenKeyExW(hkey, TLS12_Client, 0, KEY_READ, &tls12_client) == ERROR_SUCCESS) {
+ size = sizeof(DWORD);
+ if (RegQueryValueExW(tls12_client, DisabledByDefault, NULL, &type, (LPBYTE) &val, &size) || type != REG_DWORD) {
+ tls_option |= SSL_OP_NO_TLSv1_2;
+ } else {
+ tls_option |= val?0:SSL_OP_NO_TLSv1_2;
+ }
+ RegCloseKey(tls12_client);
+ } else {
+ tls_option |= SSL_OP_NO_TLSv1_2;
+ }
+ if (RegOpenKeyExW(hkey, TLS11_Client, 0, KEY_READ, &tls11_client) == ERROR_SUCCESS) {
+ size = sizeof(DWORD);
+ if (RegQueryValueExW(tls11_client, DisabledByDefault, NULL, &type, (LPBYTE) &val, &size) || type != REG_DWORD) {
+ tls_option |= SSL_OP_NO_TLSv1_1;
+ } else {
+ tls_option |= val?0:SSL_OP_NO_TLSv1_1;
+ }
+ RegCloseKey(tls11_client);
+ } else {
+ tls_option |= SSL_OP_NO_TLSv1_1;
+ }
+ RegCloseKey(hkey);
+
+end:
+ return tls_option;
+}
#endif
static CRITICAL_SECTION init_ssl_cs;
@@ -462,6 +516,7 @@ static DWORD init_openssl(void)
{
#if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO)
int i;
+ long tls_option;
if(OpenSSL_ssl_handle)
return ERROR_SUCCESS;
@@ -491,8 +546,10 @@ static DWORD init_openssl(void)
DYNSSL(SSLv23_method);
DYNSSL(SSL_CTX_free);
DYNSSL(SSL_CTX_new);
+ DYNSSL(SSL_CTX_ctrl);
DYNSSL(SSL_new);
DYNSSL(SSL_free);
+ DYNSSL(SSL_ctrl);
DYNSSL(SSL_set_fd);
DYNSSL(SSL_connect);
DYNSSL(SSL_shutdown);
@@ -534,12 +591,19 @@ static DWORD init_openssl(void)
DYNCRYPTO(sk_value);
#undef DYNCRYPTO
+#define pSSL_CTX_set_options(ctx,op) \
+ pSSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
+#define pSSL_set_options(ssl,op) \
+ pSSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL)
+
pSSL_library_init();
pSSL_load_error_strings();
pBIO_new_fp(stderr, BIO_NOCLOSE); /* FIXME: should use winedebug stuff */
meth = pSSLv23_method();
ctx = pSSL_CTX_new(meth);
+ tls_option = get_tls_option();
+ pSSL_CTX_set_options(ctx, tls_option);
if(!pSSL_CTX_set_default_verify_paths(ctx)) {
ERR("SSL_CTX_set_default_verify_paths failed: %s\n",
pERR_error_string(pERR_get_error(), 0));
@@ -782,6 +846,7 @@ DWORD NETCON_secure_connect(netconn_t *connection)
#ifdef SONAME_LIBSSL
void *ssl_s;
int bits;
+ long tls_option;
/* can't connect if we are already connected */
if (connection->ssl_s)
@@ -798,6 +863,9 @@ DWORD NETCON_secure_connect(netconn_t *connection)
return ERROR_OUTOFMEMORY;
}
+ tls_option = get_tls_option();
+ pSSL_set_options(ssl_s, tls_option);
+
if (!pSSL_set_fd(ssl_s, connection->socketFD))
{
ERR("SSL_set_fd failed: %s\n",
--
1.7.9.5
0002-winhttp-disable-TLS1.1-1.2-by-default.patch
Diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
From 83dfe52855c8b04d332ab4cf10398914fd6ecc79 Mon Sep 17 00:00:00 2001
From: Hiroshi Miura <miurahr@linux.com>
Date: Tue, 21 Aug 2012 23:36:27 +0900
Subject: [PATCH 2/2] winhttp: disable TLSv1.1/1.2 by default
 
Windows 7 disables TLSv1.1/1.2 by default.
This patch intend to behave same as Windows.
 
Signed-off-by: Hiroshi Miura <miurahr@linux.com>
---
dlls/winhttp/net.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
 
diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c
index 5ec4e1a..8c4f56c 100644
--- a/dlls/winhttp/net.c
+++ b/dlls/winhttp/net.c
@@ -52,6 +52,7 @@
#include "winbase.h"
#include "winhttp.h"
#include "wincrypt.h"
+#include "winreg.h"
#include "winhttp_private.h"
@@ -109,8 +110,10 @@ MAKE_FUNCPTR( SSL_load_error_strings );
MAKE_FUNCPTR( SSLv23_method );
MAKE_FUNCPTR( SSL_CTX_free );
MAKE_FUNCPTR( SSL_CTX_new );
+MAKE_FUNCPTR( SSL_CTX_ctrl );
MAKE_FUNCPTR( SSL_new );
MAKE_FUNCPTR( SSL_free );
+MAKE_FUNCPTR( SSL_ctrl );
MAKE_FUNCPTR( SSL_set_fd );
MAKE_FUNCPTR( SSL_connect );
MAKE_FUNCPTR( SSL_shutdown );
@@ -408,12 +411,66 @@ static int netconn_secure_verify( int preverify_ok, X509_STORE_CTX *ctx )
}
return ret;
}
+
+static long get_tls_option(void) {
+ long tls_option;
+ DWORD type, val, size;
+ HKEY hkey,tls12_client,tls11_client;
+ LONG res;
+ const WCHAR Schannel_Prot[] = { /* SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCANNEL\\Protocols */
+ 'S','Y','S','T','E','M','\\',
+ 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+ 'C','o','n','t','r','o','l','\\',
+ 'S','e','c','u','r','i','t','y','P','r','o','v','i','d','e','r','s','\\',
+ 'S','C','H','A','N','N','E','L','\\',
+ 'P','r','o','t','o','c','o','l','s',0 };
+ const WCHAR TLS12_Client[] = {'T','L','S',' ','1','.','2','\\','C','l','i','e','n','t',0};
+ const WCHAR TLS11_Client[] = {'T','L','S',' ','1','.','1','\\','C','l','i','e','n','t',0};
+ const WCHAR DisabledByDefault[] = {'D','i','s','a','b','l','e','d','B','y','D','e','f','a','u','l','t',0};
+
+ tls_option = SSL_OP_NO_SSLv2; /* disable SSLv2 for security reason, and secur32/Schannel(GnuTLS) don't support it */
+ res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ Schannel_Prot,
+ 0, KEY_READ, &hkey);
+ if (res != ERROR_SUCCESS) {
+ tls_option |= SSL_OP_NO_TLSv1_2;
+ tls_option |= SSL_OP_NO_TLSv1_1;
+ goto end;
+ }
+ if (RegOpenKeyExW(hkey, TLS12_Client, 0, KEY_READ, &tls12_client) == ERROR_SUCCESS) {
+ size = sizeof(DWORD);
+ if (RegQueryValueExW(tls12_client, DisabledByDefault, NULL, &type, (LPBYTE) &val, &size) || type != REG_DWORD) {
+ tls_option |= SSL_OP_NO_TLSv1_2;
+ } else {
+ tls_option |= val?0:SSL_OP_NO_TLSv1_2;
+ }
+ RegCloseKey(tls12_client);
+ } else {
+ tls_option |= SSL_OP_NO_TLSv1_2;
+ }
+ if (RegOpenKeyExW(hkey, TLS11_Client, 0, KEY_READ, &tls11_client) == ERROR_SUCCESS) {
+ size = sizeof(DWORD);
+ if (RegQueryValueExW(tls11_client, DisabledByDefault, NULL, &type, (LPBYTE) &val, &size) || type != REG_DWORD) {
+ tls_option |= SSL_OP_NO_TLSv1_1;
+ } else {
+ tls_option |= val?0:SSL_OP_NO_TLSv1_1;
+ }
+ RegCloseKey(tls11_client);
+ } else {
+ tls_option |= SSL_OP_NO_TLSv1_1;
+ }
+ RegCloseKey(hkey);
+
+end:
+ return tls_option;
+}
#endif
BOOL netconn_init( netconn_t *conn, BOOL secure )
{
#if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO)
int i;
+ long tls_option;
#endif
conn->socket = -1;
@@ -453,8 +510,10 @@ BOOL netconn_init( netconn_t *conn, BOOL secure )
LOAD_FUNCPTR( SSLv23_method );
LOAD_FUNCPTR( SSL_CTX_free );
LOAD_FUNCPTR( SSL_CTX_new );
+ LOAD_FUNCPTR (SSL_CTX_ctrl);
LOAD_FUNCPTR( SSL_new );
LOAD_FUNCPTR( SSL_free );
+ LOAD_FUNCPTR( SSL_ctrl );
LOAD_FUNCPTR( SSL_set_fd );
LOAD_FUNCPTR( SSL_connect );
LOAD_FUNCPTR( SSL_shutdown );
@@ -494,11 +553,20 @@ BOOL netconn_init( netconn_t *conn, BOOL secure )
LOAD_FUNCPTR( sk_num );
#undef LOAD_FUNCPTR
+#define pSSL_CTX_set_options(ctx,op) \
+ pSSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
+#define pSSL_set_options(ssl,op) \
+ pSSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL)
+
pSSL_library_init();
pSSL_load_error_strings();
method = pSSLv23_method();
ctx = pSSL_CTX_new( method );
+
+ tls_option = get_tls_option();
+ pSSL_CTX_set_options(ctx, tls_option);
+
if (!pSSL_CTX_set_default_verify_paths( ctx ))
{
ERR("SSL_CTX_set_default_verify_paths failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
@@ -676,12 +744,18 @@ BOOL netconn_connect( netconn_t *conn, const struct sockaddr *sockaddr, unsigned
BOOL netconn_secure_connect( netconn_t *conn, WCHAR *hostname )
{
#ifdef SONAME_LIBSSL
+ long tls_option;
+
if (!(conn->ssl_conn = pSSL_new( ctx )))
{
ERR("SSL_new failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
set_last_error( ERROR_OUTOFMEMORY );
goto fail;
}
+
+ tls_option = get_tls_option();
+ pSSL_set_options(conn->ssl_conn, tls_option);
+
if (!pSSL_set_ex_data( conn->ssl_conn, hostname_idx, hostname ))
{
ERR("SSL_set_ex_data failed: %s\n", pERR_error_string( pERR_get_error(), 0 ));
--
1.7.9.5

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.