diff --git a/dlls/secur32/schannel_gnutls.c b/dlls/secur32/schannel_gnutls.c index 0a494214116..a962c675ed3 100644 --- a/dlls/secur32/schannel_gnutls.c +++ b/dlls/secur32/schannel_gnutls.c @@ -23,6 +23,7 @@ #include "wine/port.h" #include +#include #ifdef SONAME_LIBGNUTLS #include #include @@ -150,6 +151,7 @@ static const struct { DWORD enable_flag; const char *gnutls_flag; } protocol_priority_flags[] = { + {SP_PROT_TLS1_3_CLIENT, "VERS-TLS1.3"}, {SP_PROT_TLS1_2_CLIENT, "VERS-TLS1.2"}, {SP_PROT_TLS1_1_CLIENT, "VERS-TLS1.1"}, {SP_PROT_TLS1_0_CLIENT, "VERS-TLS1.0"}, @@ -157,10 +159,41 @@ static const struct { /* {SP_PROT_SSL2_CLIENT} is not supported by GnuTLS */ }; +static DWORD supported_protocols; + +static void check_supported_protocols(void) +{ + gnutls_session_t session; + char priority[64]; + unsigned i; + int err; + + err = pgnutls_init(&session, GNUTLS_CLIENT); + if (err != GNUTLS_E_SUCCESS) + { + pgnutls_perror(err); + return; + } + + for(i = 0; i < ARRAY_SIZE(protocol_priority_flags); i++) + { + sprintf(priority, "NORMAL:-%s", protocol_priority_flags[i].gnutls_flag); + err = pgnutls_priority_set_direct(session, priority, NULL); + if (err == GNUTLS_E_SUCCESS) + { + TRACE("%s is supported\n", protocol_priority_flags[i].gnutls_flag); + supported_protocols |= protocol_priority_flags[i].enable_flag; + } + else + TRACE("%s is not supported\n", protocol_priority_flags[i].gnutls_flag); + } + + pgnutls_deinit(session); +} + DWORD schan_imp_enabled_protocols(void) { - /* NOTE: No support for SSL 2.0 */ - return SP_PROT_SSL3_CLIENT | SP_PROT_TLS1_0_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT; + return supported_protocols; } BOOL schan_imp_create_session(schan_imp_session *session, schan_credentials *cred) @@ -593,6 +626,7 @@ BOOL schan_imp_init(void) pgnutls_global_set_log_function(schan_gnutls_log); } + check_supported_protocols(); return TRUE; fail: