diff options
Diffstat (limited to 'src/crypto/tls_gnutls.c')
| -rw-r--r-- | src/crypto/tls_gnutls.c | 75 |
1 files changed, 68 insertions, 7 deletions
diff --git a/src/crypto/tls_gnutls.c b/src/crypto/tls_gnutls.c index 36dafd2603f0..daa01d9ed4f6 100644 --- a/src/crypto/tls_gnutls.c +++ b/src/crypto/tls_gnutls.c @@ -461,6 +461,12 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, } } + if (params->openssl_ecdh_curves) { + wpa_printf(MSG_INFO, + "GnuTLS: openssl_ecdh_curves not supported"); + return -1; + } + /* TODO: gnutls_certificate_set_verify_flags(xcred, flags); * to force peer validation(?) */ @@ -733,6 +739,9 @@ int tls_global_set_params(void *tls_ctx, struct tls_global *global = tls_ctx; int ret; + if (params->check_cert_subject) + return -1; /* not yet supported */ + /* Currently, global parameters are only set when running in server * mode. */ global->server = 1; @@ -842,7 +851,7 @@ fail: } -int tls_global_set_verify(void *ssl_ctx, int check_crl) +int tls_global_set_verify(void *ssl_ctx, int check_crl, int strict) { /* TODO */ return 0; @@ -889,14 +898,23 @@ int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn, int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, - const char *label, u8 *out, size_t out_len) + const char *label, const u8 *context, + size_t context_len, u8 *out, size_t out_len) { if (conn == NULL || conn->session == NULL) return -1; +#if GNUTLS_VERSION_NUMBER >= 0x030404 + return gnutls_prf_rfc5705(conn->session, os_strlen(label), label, + context_len, (const char *) context, + out_len, (char *) out); +#else /* 3.4.4 */ + if (context) + return -1; return gnutls_prf(conn->session, os_strlen(label), label, 0 /* client_random first */, 0, NULL, out_len, (char *) out); +#endif /* 3.4.4 */ } @@ -1068,6 +1086,52 @@ ocsp_error: } +static int tls_match_suffix_helper(gnutls_x509_crt_t cert, const char *match, + int full) +{ + int res = -1; + +#if GNUTLS_VERSION_NUMBER >= 0x030300 + if (full) + res = gnutls_x509_crt_check_hostname2( + cert, match, + GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS); +#endif /* >= 3.3.0 */ + if (res == -1) + res = gnutls_x509_crt_check_hostname(cert, match); + + wpa_printf(MSG_DEBUG, "TLS: Match domain against %s%s --> res=%d", + full ? "": "suffix ", match, res); + return res; +} + + +static int tls_match_suffix(gnutls_x509_crt_t cert, const char *match, + int full) +{ + char *values, *token, *context = NULL; + int ret = 0; + + if (!os_strchr(match, ';')) + return tls_match_suffix_helper(cert, match, full); + + values = os_strdup(match); + if (!values) + return 0; + + /* Process each match alternative separately until a match is found */ + while ((token = str_token(values, ";", &context))) { + if (tls_match_suffix_helper(cert, token, full)) { + ret = 1; + break; + } + } + + os_free(values); + return ret; +} + + static int tls_connection_verify_peer(gnutls_session_t session) { struct tls_connection *conn; @@ -1263,8 +1327,7 @@ static int tls_connection_verify_peer(gnutls_session_t session) if (i == 0) { if (conn->suffix_match && - !gnutls_x509_crt_check_hostname( - cert, conn->suffix_match)) { + !tls_match_suffix(cert, conn->suffix_match, 0)) { wpa_printf(MSG_WARNING, "TLS: Domain suffix match '%s' not found", conn->suffix_match); @@ -1280,9 +1343,7 @@ static int tls_connection_verify_peer(gnutls_session_t session) #if GNUTLS_VERSION_NUMBER >= 0x030300 if (conn->domain_match && - !gnutls_x509_crt_check_hostname2( - cert, conn->domain_match, - GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) { + !tls_match_suffix(cert, conn->domain_match, 1)) { wpa_printf(MSG_WARNING, "TLS: Domain match '%s' not found", conn->domain_match); |
