[PATCH] secur32/schannel: diabled TLS1.1/1.2 by Default
Hiroshi Miura
miurahr at linux.com
Sun Sep 9 10:14:51 CDT 2012
-Set TLS1.1/1.2 disabled by Default that is
same as Windows 7 default.
See registry entry for schannel and control
enable/disable tls versions.
It also see grbitEnabledProtocols defined in
credentials that take precedence over registry.
-Control a behavoir of unsafe renegotiation
thru registry key MS10-049 shows.
ie. 'AllowInsecureRenegoClients'
Signed-off-by: Hiroshi Miura <miurahr at linux.com>
---
dlls/secur32/schannel_gnutls.c | 137 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 135 insertions(+), 2 deletions(-)
diff --git a/dlls/secur32/schannel_gnutls.c b/dlls/secur32/schannel_gnutls.c
index 16ce0de..9ebc754 100644
--- a/dlls/secur32/schannel_gnutls.c
+++ b/dlls/secur32/schannel_gnutls.c
@@ -34,6 +34,7 @@
#include "secur32_priv.h"
#include "wine/debug.h"
#include "wine/library.h"
+#include "winreg.h"
WINE_DEFAULT_DEBUG_CHANNEL(secur32);
@@ -60,6 +61,8 @@ MAKE_FUNCPTR(gnutls_kx_get);
MAKE_FUNCPTR(gnutls_mac_get);
MAKE_FUNCPTR(gnutls_mac_get_key_size);
MAKE_FUNCPTR(gnutls_perror);
+MAKE_FUNCPTR(gnutls_priority_init);
+MAKE_FUNCPTR(gnutls_priority_set);
MAKE_FUNCPTR(gnutls_protocol_get_version);
MAKE_FUNCPTR(gnutls_set_default_priority);
MAKE_FUNCPTR(gnutls_record_get_max_size);
@@ -106,10 +109,116 @@ static ssize_t schan_push_adapter(gnutls_transport_ptr_t transport,
return buff_len;
}
+#ifndef SSL_OP_NO_TLSv1_2
+#define SSL_OP_NO_TLSv1_2 0x08000000L
+#endif
+#ifndef SSL_OP_NO_TLSv1_1
+#define SSL_OP_NO_TLSv1_1 0x10000000L
+#endif
+#ifndef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
+#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L
+#endif
+
+static long schan_get_tls_option(void) {
+ long tls_option=0;
+ DWORD type, val, size;
+ HKEY hkey,protocols,tls12_client,tls11_client;
+ LONG res;
+ const WCHAR Schannel[] = { /* SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCANNEL */
+ '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', 0};
+ const WCHAR Protocols[] = {'P','r','o','t','o','c','o','l','s',0};
+ const WCHAR AllowInsecureRenegoClients[] = {
+ 'A','l','l','o','w','I','n','s','e','c','u','r','e','R','e','n','e','g','o',
+ 'C','l','i','e','n','t','s', 0};
+#if 0
+ const WCHAR AllowInsecureRenegoServers[] = {
+ 'A','l','l','o','w','I','n','s','e','c','u','r','e','R','e','n','e','g','o',
+ 'S','e','r','v','e','r','s', 0};
+#endif
+ 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};
+
+ res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ Schannel,
+ 0, KEY_READ, &hkey);
+ if (res != ERROR_SUCCESS) {
+ tls_option |= SSL_OP_NO_TLSv1_2;
+ tls_option |= SSL_OP_NO_TLSv1_1;
+ goto end;
+ }
+
+ size = sizeof(DWORD);
+ if (RegQueryValueExW(hkey, AllowInsecureRenegoClients, NULL, &type, (LPBYTE) &val, &size) == ERROR_SUCCESS
+ && type == REG_DWORD) {
+ tls_option |= val?SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION:0;
+ }
+ if (RegOpenKeyExW(hkey, Protocols, 0, KEY_READ, &protocols) == ERROR_SUCCESS) {
+ if (RegOpenKeyExW(protocols, 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?SSL_OP_NO_TLSv1_2:0;
+ }
+ RegCloseKey(tls12_client);
+ } else {
+ tls_option |= SSL_OP_NO_TLSv1_2;
+ }
+ if (RegOpenKeyExW(protocols, 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?SSL_OP_NO_TLSv1_1:0;
+ }
+ RegCloseKey(tls11_client);
+ } else {
+ tls_option |= SSL_OP_NO_TLSv1_1;
+ }
+ RegCloseKey(protocols);
+ }
+
+ RegCloseKey(hkey);
+end:
+ return tls_option;
+}
+
+static gnutls_priority_t gnutls_priorities[2][2][2];
+ /* fields: TLS1.1:TLS1.2:Unsafe renagotiation */
+
+static void schannel_gnutls_init_priorities (void)
+{
+ /* FIXME hardcoded "NORMAL" priority */
+ pgnutls_priority_init (&gnutls_priorities[FALSE][FALSE][FALSE],
+ "NORMAL:!VERS-TLS1.2:!VERS-TLS1.1", NULL);
+ pgnutls_priority_init (&gnutls_priorities[TRUE][FALSE][FALSE],
+ "NORMAL:!VERS-TLS1.2", NULL);
+ pgnutls_priority_init (&gnutls_priorities[FALSE][TRUE][FALSE],
+ "NORMAL:!VERS-TLS1.1", NULL);
+ pgnutls_priority_init (&gnutls_priorities[TRUE][TRUE][FALSE],
+ "NORMAL", NULL);
+
+ pgnutls_priority_init (&gnutls_priorities[FALSE][FALSE][TRUE],
+ "NORMAL:!VERS-TLS1.2:!VERS-TLS1.1:%UNSAFE_RENEGOTIATION", NULL);
+ pgnutls_priority_init (&gnutls_priorities[TRUE][FALSE][TRUE],
+ "NORMAL:!VERS-TLS1.2:%UNSAFE_RENEGOTIATION", NULL);
+ pgnutls_priority_init (&gnutls_priorities[FALSE][TRUE][TRUE],
+ "NORMAL:!VERS-TLS1.1:%UNSAFE_RENEGOTIATION", NULL);
+ pgnutls_priority_init (&gnutls_priorities[TRUE][TRUE][TRUE],
+ "NORMAL:%UNSAFE_RENEGOTIATION", NULL);
+}
+
BOOL schan_imp_create_session(schan_imp_session *session, BOOL is_server,
schan_imp_certificate_credentials cred)
{
gnutls_session_t *s = (gnutls_session_t*)session;
+ long tls_option;
+ int enable_tls11, enable_tls12, unsafe_rehandshake;
int err = pgnutls_init(s, is_server ? GNUTLS_SERVER : GNUTLS_CLIENT);
if (err != GNUTLS_E_SUCCESS)
@@ -118,9 +227,30 @@ BOOL schan_imp_create_session(schan_imp_session *session, BOOL is_server,
return FALSE;
}
+ /* FIXME registory DisabledByDefault value does not take precedence
+ over the grbitEnabledProtocols of credential,
+ but 'Enabled' value should take precedence over it.(for ssl3.0) */
+ tls_option = schan_get_tls_option();
+ if ((int)cred & SP_PROT_TLS1_1_CLIENT) {
+ enable_tls11 = TRUE;
+ } else {
+ enable_tls11 = (tls_option & SSL_OP_NO_TLSv1_1)?FALSE:TRUE;
+ }
+ if ((int)cred & SP_PROT_TLS1_2_CLIENT) {
+ enable_tls12 = TRUE;
+ } else {
+ enable_tls12 = (tls_option & SSL_OP_NO_TLSv1_2)?FALSE:TRUE;
+ }
+ unsafe_rehandshake = (tls_option & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)?TRUE:FALSE;
+
/* FIXME: We should be using the information from the credentials here. */
- FIXME("Using hardcoded \"NORMAL\" priority\n");
- err = pgnutls_set_default_priority(*s);
+ FIXME("Using hardcoded \"NORMAL\" priority with: TLS1.1:%s, TLS1.2:%s, UnsafeRenego:%s\n",
+ enable_tls11?"enabled":"disabled",
+ enable_tls12?"enabled":"disabled",
+ unsafe_rehandshake?"enabled":"disabled"
+ );
+ err = pgnutls_priority_set (*s, gnutls_priorities[enable_tls11][enable_tls12][unsafe_rehandshake]);
+
if (err != GNUTLS_E_SUCCESS)
{
pgnutls_perror(err);
@@ -454,6 +584,8 @@ BOOL schan_imp_init(void)
LOAD_FUNCPTR(gnutls_mac_get)
LOAD_FUNCPTR(gnutls_mac_get_key_size)
LOAD_FUNCPTR(gnutls_perror)
+ LOAD_FUNCPTR(gnutls_priority_init);
+ LOAD_FUNCPTR(gnutls_priority_set);
LOAD_FUNCPTR(gnutls_protocol_get_version)
LOAD_FUNCPTR(gnutls_set_default_priority)
LOAD_FUNCPTR(gnutls_record_get_max_size);
@@ -472,6 +604,7 @@ BOOL schan_imp_init(void)
pgnutls_perror(ret);
goto fail;
}
+ schannel_gnutls_init_priorities();
if (TRACE_ON(secur32))
{
--
1.7.9.5
More information about the wine-patches
mailing list