diff options
Diffstat (limited to 'Utilities/cmcurl/lib/vtls/gtls.c')
-rw-r--r-- | Utilities/cmcurl/lib/vtls/gtls.c | 92 |
1 files changed, 64 insertions, 28 deletions
diff --git a/Utilities/cmcurl/lib/vtls/gtls.c b/Utilities/cmcurl/lib/vtls/gtls.c index 18864aa..0535011 100644 --- a/Utilities/cmcurl/lib/vtls/gtls.c +++ b/Utilities/cmcurl/lib/vtls/gtls.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -55,6 +55,14 @@ /* The last #include file should be: */ #include "memdebug.h" +#ifdef HAVE_GNUTLS_SRP +/* the function exists */ +#ifdef USE_TLS_SRP +/* the functionality is not disabled */ +#define USE_GNUTLS_SRP +#endif +#endif + /* Enable GnuTLS debugging by defining GTLSDEBUG */ /*#define GTLSDEBUG */ @@ -75,7 +83,7 @@ static bool gtls_inited = FALSE; struct ssl_backend_data { gnutls_session_t session; gnutls_certificate_credentials_t cred; -#ifdef HAVE_GNUTLS_SRP +#ifdef USE_GNUTLS_SRP gnutls_srp_client_credentials_t srp_client_cred; #endif }; @@ -202,9 +210,12 @@ static CURLcode handshake(struct Curl_easy *data, { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - gnutls_session_t session = backend->session; + gnutls_session_t session; curl_socket_t sockfd = conn->sock[sockindex]; + DEBUGASSERT(backend); + session = backend->session; + for(;;) { timediff_t timeout_ms; int rc; @@ -406,6 +417,8 @@ gtls_connect_step1(struct Curl_easy *data, const char *tls13support; CURLcode result; + DEBUGASSERT(backend); + if(connssl->state == ssl_connection_complete) /* to make us tolerant against being called more than once for the same connection */ @@ -431,12 +444,12 @@ gtls_connect_step1(struct Curl_easy *data, return CURLE_SSL_CONNECT_ERROR; } -#ifdef HAVE_GNUTLS_SRP - if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { +#ifdef USE_GNUTLS_SRP + if((SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) && + Curl_allow_auth_to_host(data)) { infof(data, "Using TLS-SRP username: %s", SSL_SET_OPTION(username)); - rc = gnutls_srp_allocate_client_credentials( - &backend->srp_client_cred); + rc = gnutls_srp_allocate_client_credentials(&backend->srp_client_cred); if(rc != GNUTLS_E_SUCCESS) { failf(data, "gnutls_srp_allocate_client_cred() failed: %s", gnutls_strerror(rc)); @@ -542,11 +555,15 @@ gtls_connect_step1(struct Curl_easy *data, #ifdef ENABLE_IPV6 (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) && #endif - sni && - (gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname, - strlen(hostname)) < 0)) - infof(data, "WARNING: failed to configure server name indication (SNI) " - "TLS extension"); + sni) { + size_t snilen; + char *snihost = Curl_ssl_snihost(data, hostname, &snilen); + if(!snihost || gnutls_server_name_set(session, GNUTLS_NAME_DNS, snihost, + snilen) < 0) { + failf(data, "Failed to set SNI"); + return CURLE_SSL_CONNECT_ERROR; + } + } /* Use default priorities */ rc = gnutls_set_default_priority(session); @@ -578,7 +595,7 @@ gtls_connect_step1(struct Curl_easy *data, if(result) return result; -#ifdef HAVE_GNUTLS_SRP +#ifdef USE_GNUTLS_SRP /* Only add SRP to the cipher list if SRP is requested. Otherwise * GnuTLS will disable TLS 1.3 support. */ if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { @@ -600,7 +617,7 @@ gtls_connect_step1(struct Curl_easy *data, #endif infof(data, "GnuTLS ciphers: %s", prioritylist); rc = gnutls_priority_set_direct(session, prioritylist, &err); -#ifdef HAVE_GNUTLS_SRP +#ifdef USE_GNUTLS_SRP } #endif @@ -623,14 +640,14 @@ gtls_connect_step1(struct Curl_easy *data, protocols[cur].data = (unsigned char *)ALPN_H2; protocols[cur].size = ALPN_H2_LENGTH; cur++; - infof(data, "ALPN, offering %.*s", ALPN_H2_LENGTH, ALPN_H2); + infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2); } #endif protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1; protocols[cur].size = ALPN_HTTP_1_1_LENGTH; cur++; - infof(data, "ALPN, offering %s", ALPN_HTTP_1_1); + infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1); if(gnutls_alpn_set_protocols(session, protocols, cur, 0)) { failf(data, "failed setting ALPN"); @@ -674,7 +691,7 @@ gtls_connect_step1(struct Curl_easy *data, } } -#ifdef HAVE_GNUTLS_SRP +#ifdef USE_GNUTLS_SRP /* put the credentials to the current session */ if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) { rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP, @@ -697,7 +714,10 @@ gtls_connect_step1(struct Curl_easy *data, #ifndef CURL_DISABLE_PROXY if(conn->proxy_ssl[sockindex].use) { - transport_ptr = conn->proxy_ssl[sockindex].backend->session; + struct ssl_backend_data *proxy_backend; + proxy_backend = conn->proxy_ssl[sockindex].backend; + DEBUGASSERT(proxy_backend); + transport_ptr = proxy_backend->session; gnutls_transport_push = gtls_push_ssl; gnutls_transport_pull = gtls_pull_ssl; } @@ -854,7 +874,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data, if(SSL_CONN_CONFIG(verifypeer) || SSL_CONN_CONFIG(verifyhost) || SSL_CONN_CONFIG(issuercert)) { -#ifdef HAVE_GNUTLS_SRP +#ifdef USE_GNUTLS_SRP if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP && SSL_SET_OPTION(username) != NULL && !SSL_CONN_CONFIG(verifypeer) @@ -867,7 +887,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data, failf(data, "failed to get server cert"); *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND; return CURLE_PEER_FAILED_VERIFICATION; -#ifdef HAVE_GNUTLS_SRP +#ifdef USE_GNUTLS_SRP } #endif } @@ -1186,7 +1206,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data, if(ptr) { result = pkp_pin_peer_pubkey(data, x509_cert, ptr); if(result != CURLE_OK) { - failf(data, "SSL: public key does not match pinned public key!"); + failf(data, "SSL: public key does not match pinned public key"); gnutls_x509_crt_deinit(x509_cert); return result; } @@ -1243,8 +1263,8 @@ Curl_gtls_verifyserver(struct Curl_easy *data, if(conn->bits.tls_enable_alpn) { rc = gnutls_alpn_get_selected_protocol(session, &proto); if(rc == 0) { - infof(data, "ALPN, server accepted to use %.*s", proto.size, - proto.data); + infof(data, VTLS_INFOF_ALPN_ACCEPTED_LEN_1STR, proto.size, + proto.data); #ifdef USE_HTTP2 if(proto.size == ALPN_H2_LENGTH && @@ -1260,7 +1280,7 @@ Curl_gtls_verifyserver(struct Curl_easy *data, } } else - infof(data, "ALPN, server did not agree to a protocol"); + infof(data, VTLS_INFOF_NO_ALPN); Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); @@ -1352,7 +1372,9 @@ gtls_connect_common(struct Curl_easy *data, /* Finish connecting once the handshake is done */ if(ssl_connect_1 == connssl->connecting_state) { struct ssl_backend_data *backend = connssl->backend; - gnutls_session_t session = backend->session; + gnutls_session_t session; + DEBUGASSERT(backend); + session = backend->session; rc = Curl_gtls_verifyserver(data, conn, session, sockindex); if(rc) return rc; @@ -1393,6 +1415,9 @@ static bool gtls_data_pending(const struct connectdata *conn, const struct ssl_connect_data *connssl = &conn->ssl[connindex]; bool res = FALSE; struct ssl_backend_data *backend = connssl->backend; + + DEBUGASSERT(backend); + if(backend->session && 0 != gnutls_record_check_pending(backend->session)) res = TRUE; @@ -1400,6 +1425,7 @@ static bool gtls_data_pending(const struct connectdata *conn, #ifndef CURL_DISABLE_PROXY connssl = &conn->proxy_ssl[connindex]; backend = connssl->backend; + DEBUGASSERT(backend); if(backend->session && 0 != gnutls_record_check_pending(backend->session)) res = TRUE; @@ -1417,7 +1443,10 @@ static ssize_t gtls_send(struct Curl_easy *data, struct connectdata *conn = data->conn; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - ssize_t rc = gnutls_record_send(backend->session, mem, len); + ssize_t rc; + + DEBUGASSERT(backend); + rc = gnutls_record_send(backend->session, mem, len); if(rc < 0) { *curlcode = (rc == GNUTLS_E_AGAIN) @@ -1433,6 +1462,8 @@ static ssize_t gtls_send(struct Curl_easy *data, static void close_one(struct ssl_connect_data *connssl) { struct ssl_backend_data *backend = connssl->backend; + DEBUGASSERT(backend); + if(backend->session) { char buf[32]; /* Maybe the server has already sent a close notify alert. @@ -1446,7 +1477,7 @@ static void close_one(struct ssl_connect_data *connssl) gnutls_certificate_free_credentials(backend->cred); backend->cred = NULL; } -#ifdef HAVE_GNUTLS_SRP +#ifdef USE_GNUTLS_SRP if(backend->srp_client_cred) { gnutls_srp_free_client_credentials(backend->srp_client_cred); backend->srp_client_cred = NULL; @@ -1475,6 +1506,8 @@ static int gtls_shutdown(struct Curl_easy *data, struct connectdata *conn, struct ssl_backend_data *backend = connssl->backend; int retval = 0; + DEBUGASSERT(backend); + #ifndef CURL_DISABLE_FTP /* This has only been tested on the proftpd server, and the mod_tls code sends a close notify alert without waiting for a close notify alert in @@ -1530,7 +1563,7 @@ static int gtls_shutdown(struct Curl_easy *data, struct connectdata *conn, } gnutls_certificate_free_credentials(backend->cred); -#ifdef HAVE_GNUTLS_SRP +#ifdef USE_GNUTLS_SRP if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP && SSL_SET_OPTION(username) != NULL) gnutls_srp_free_client_credentials(backend->srp_client_cred); @@ -1553,6 +1586,8 @@ static ssize_t gtls_recv(struct Curl_easy *data, /* connection data */ struct ssl_backend_data *backend = connssl->backend; ssize_t ret; + DEBUGASSERT(backend); + ret = gnutls_record_recv(backend->session, buf, buffersize); if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) { *curlcode = CURLE_AGAIN; @@ -1624,6 +1659,7 @@ static void *gtls_get_internals(struct ssl_connect_data *connssl, { struct ssl_backend_data *backend = connssl->backend; (void)info; + DEBUGASSERT(backend); return backend->session; } |