wolfssl: refactor Curl_wssl_ctx_init into sub functions
No binary (build failed)
—
(log yok)
| @@ -911,9 +911,9 @@ static int wssl_legacy_CTX_set_max_proto_version(WOLFSSL_CTX *ctx, int version) | |
| #define wolfSSL_CTX_set_max_proto_version wssl_legacy_CTX_set_max_proto_version | |
| #endif /* OPENSSL_EXTRA */ | |
| - | static CURLcode client_certificate(struct Curl_easy *data, |
| - | struct ssl_config_data *ssl_config, |
| - | struct wssl_ctx *wctx) |
| + | static CURLcode wssl_client_cert(struct Curl_easy *data, |
| + | struct ssl_config_data *ssl_config, |
| + | struct wssl_ctx *wctx) |
| { | |
| /* Load the client certificate, and private key */ | |
| #ifndef NO_FILESYSTEM | |
| @@ -1076,76 +1076,28 @@ static CURLcode ssl_version(struct Curl_easy *data, | |
| } | |
| #define QUIC_GROUPS "P-256:P-384:P-521" | |
| - | |
| - | CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, |
| - | struct Curl_cfilter *cf, |
| - | struct Curl_easy *data, |
| - | struct ssl_peer *peer, |
| - | const struct alpn_spec *alpns_requested, |
| - | Curl_wssl_ctx_setup_cb *cb_setup, |
| - | void *cb_user_data, |
| - | void *ssl_user_data, |
| - | Curl_wssl_init_session_reuse_cb *sess_reuse_cb) |
| - | { |
| - | struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); |
| - | struct ssl_primary_config *conn_config; |
| - | WOLFSSL_METHOD *req_method = NULL; |
| - | struct alpn_spec alpns; |
| - | char *curves; |
| - | #ifdef WOLFSSL_HAVE_KYBER |
| - | word16 pqkem = 0; |
| - | size_t idx = 0; |
| + | #ifdef WOLFSSL_TLS13 |
| + | #define MAX_CIPHER_LEN 4096 |
| #endif | |
| - | CURLcode result = CURLE_FAILED_INIT; |
| - | unsigned char transport; |
| - | int tls_min, tls_max; |
| - | |
| - | DEBUGASSERT(!wctx->ssl_ctx); |
| - | DEBUGASSERT(!wctx->ssl); |
| - | conn_config = Curl_ssl_cf_get_primary_config(cf); |
| - | if(!conn_config) { |
| - | result = CURLE_FAILED_INIT; |
| - | goto out; |
| - | } |
| - | Curl_alpn_copy(&alpns, alpns_requested); |
| - | DEBUGASSERT(cf->next); |
| - | transport = Curl_conn_cf_get_transport(cf->next, data); |
| - | |
| - | req_method = wolfTLS_client_method(); |
| - | if(!req_method) { |
| - | failf(data, "wolfSSL: could not create a client method"); |
| - | result = CURLE_OUT_OF_MEMORY; |
| - | goto out; |
| - | } |
| - | |
| - | if(wctx->ssl_ctx) |
| - | wolfSSL_CTX_free(wctx->ssl_ctx); |
| - | |
| - | wctx->ssl_ctx = wolfSSL_CTX_new(req_method); |
| - | if(!wctx->ssl_ctx) { |
| - | failf(data, "wolfSSL: could not create a context"); |
| - | result = CURLE_OUT_OF_MEMORY; |
| - | goto out; |
| - | } |
| - | |
| - | result = ssl_version(data, conn_config, wctx, &tls_min, &tls_max); |
| - | if(result) |
| - | goto out; |
| + | static CURLcode wssl_init_ciphers(struct Curl_easy *data, |
| + | struct wssl_ctx *wctx, |
| + | struct ssl_primary_config *conn_config, |
| + | int tls_min, int tls_max) |
| + | { |
| #ifndef WOLFSSL_TLS13 | |
| - | { |
| - | const char *ciphers = conn_config->cipher_list; |
| - | if(ciphers) { |
| - | if(!SSL_CTX_set_cipher_list(wctx->ssl_ctx, ciphers)) { |
| - | failf(data, "failed setting cipher list: %s", ciphers); |
| - | result = CURLE_SSL_CIPHER; |
| - | goto out; |
| - | } |
| - | infof(data, "Cipher selection: %s", ciphers); |
| + | const char *ciphers = conn_config->cipher_list; |
| + | (void)tls_min; |
| + | (void)tls_max; |
| + | if(ciphers) { |
| + | if(!SSL_CTX_set_cipher_list(wctx->ssl_ctx, ciphers)) { |
| + | failf(data, "failed setting cipher list: %s", ciphers); |
| + | return CURLE_SSL_CIPHER; |
| } | |
| + | infof(data, "Cipher selection: %s", ciphers); |
| } | |
| #else | |
| - | #define MAX_CIPHER_LEN 4096 |
| + | CURLcode result = CURLE_OK; |
| if(conn_config->cipher_list || conn_config->cipher_list13) { | |
| const char *ciphers12 = conn_config->cipher_list; | |
| const char *ciphers13 = conn_config->cipher_list13; | |
| @@ -1169,115 +1121,73 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, | |
| else | |
| result = wssl_add_default_ciphers(FALSE, &c); | |
| } | |
| - | if(result) |
| - | goto out; |
| - | |
| - | if(!wolfSSL_CTX_set_cipher_list(wctx->ssl_ctx, curlx_dyn_ptr(&c))) { |
| - | failf(data, "failed setting cipher list: %s", curlx_dyn_ptr(&c)); |
| - | curlx_dyn_free(&c); |
| - | result = CURLE_SSL_CIPHER; |
| - | goto out; |
| + | if(!result) { |
| + | if(!wolfSSL_CTX_set_cipher_list(wctx->ssl_ctx, curlx_dyn_ptr(&c))) { |
| + | failf(data, "failed setting cipher list: %s", curlx_dyn_ptr(&c)); |
| + | result = CURLE_SSL_CIPHER; |
| + | } |
| + | else |
| + | infof(data, "Cipher selection: %s", curlx_dyn_ptr(&c)); |
| } | |
| - | infof(data, "Cipher selection: %s", curlx_dyn_ptr(&c)); |
| curlx_dyn_free(&c); | |
| } | |
| #endif | |
| + | return result; |
| + | } |
| - | curves = conn_config->curves; |
| + | static CURLcode wssl_init_curves(struct Curl_easy *data, |
| + | struct wssl_ctx *wctx, |
| + | struct ssl_primary_config *conn_config, |
| + | unsigned char transport |
| + | #ifdef WOLFSSL_HAVE_KYBER |
| + | , word16 *out_pqkem |
| + | #endif |
| + | ) |
| + | { |
| + | char *curves = conn_config->curves; |
| if(!curves && (transport == TRNSPRT_QUIC)) | |
| curves = (char *)CURL_UNCONST(QUIC_GROUPS); | |
| if(curves) { | |
| #ifdef WOLFSSL_HAVE_KYBER | |
| + | size_t idx; |
| for(idx = 0; gnm[idx].name != NULL; idx++) { | |
| - | if(strncmp(curves, gnm[idx].name, strlen(gnm[idx].name)) == 0) { |
| - | pqkem = gnm[idx].group; |
| + | if(!strncmp(curves, gnm[idx].name, strlen(gnm[idx].name))) { |
| + | *out_pqkem = gnm[idx].group; |
| break; | |
| } | |
| } | |
| - | if(pqkem == 0) |
| + | if(*out_pqkem == 0) |
| #endif | |
| { | |
| if(!wolfSSL_CTX_set1_curves_list(wctx->ssl_ctx, curves)) { | |
| failf(data, "failed setting curves list: '%s'", curves); | |
| - | result = CURLE_SSL_CIPHER; |
| - | goto out; |
| + | return CURLE_SSL_CIPHER; |
| } | |
| } | |
| } | |
| + | return CURLE_OK; |
| + | } |
| - | result = client_certificate(data, ssl_config, wctx); |
| - | if(result) |
| - | goto out; |
| - | |
| - | /* SSL always tries to verify the peer, this only says whether it should |
| - | * fail to connect if the verification fails, or if it should continue |
| - | * anyway. In the latter case the result of the verification is checked with |
| - | * SSL_get_verify_result() below. */ |
| - | wolfSSL_CTX_set_verify(wctx->ssl_ctx, |
| - | conn_config->verifypeer ? WOLFSSL_VERIFY_PEER : |
| - | WOLFSSL_VERIFY_NONE, NULL); |
| - | |
| - | #ifdef HAVE_SNI |
| - | if(peer->sni) { |
| - | size_t sni_len = strlen(peer->sni); |
| - | if((sni_len < USHRT_MAX)) { |
| - | if(wolfSSL_CTX_UseSNI(wctx->ssl_ctx, WOLFSSL_SNI_HOST_NAME, |
| - | peer->sni, (unsigned short)sni_len) != 1) { |
| - | failf(data, "Failed to set SNI"); |
| - | result = CURLE_SSL_CONNECT_ERROR; |
| - | goto out; |
| - | } |
| - | CURL_TRC_CF(data, cf, "set SNI '%s'", peer->sni); |
| - | } |
| - | } |
| - | #endif |
| - | |
| - | #ifdef HAVE_EX_DATA |
| - | if(Curl_ssl_scache_use(cf, data) && (transport != TRNSPRT_QUIC)) { |
| - | /* Register to get notified when a new session is received */ |
| - | wolfSSL_CTX_sess_set_new_cb(wctx->ssl_ctx, wssl_vtls_new_session_cb); |
| - | } |
| - | #endif |
| - | |
| - | if(cb_setup) { |
| - | result = cb_setup(cf, data, cb_user_data); |
| - | if(result) |
| - | goto out; |
| - | } |
| - | |
| - | /* give application a chance to interfere with SSL set up. */ |
| - | if(data->set.ssl.fsslctx) { |
| - | if(!wctx->x509_store_setup) { |
| - | result = Curl_wssl_setup_x509_store(cf, data, wctx); |
| - | if(result) |
| - | goto out; |
| - | } |
| - | result = (*data->set.ssl.fsslctx)(data, wctx->ssl_ctx, |
| - | data->set.ssl.fsslctxp); |
| - | if(result) { |
| - | failf(data, "error signaled by ssl ctx callback"); |
| - | goto out; |
| - | } |
| - | } |
| - | #ifdef NO_FILESYSTEM |
| - | else if(conn_config->verifypeer) { |
| - | failf(data, "SSL: Certificates cannot be loaded because wolfSSL was built" |
| - | " with \"no file system\". Either disable peer verification" |
| - | " (insecure) or if you are building an application with libcurl you" |
| - | " can load certificates via CURLOPT_SSL_CTX_FUNCTION."); |
| - | result = CURLE_SSL_CONNECT_ERROR; |
| - | goto out; |
| - | } |
| + | static CURLcode wssl_init_ssl_handle(struct wssl_ctx *wctx, |
| + | struct Curl_cfilter *cf, |
| + | struct Curl_easy *data, |
| + | struct ssl_peer *peer, |
| + | struct alpn_spec *alpns, |
| + | void *ssl_user_data, |
| + | unsigned char transport, |
| + | #ifdef WOLFSSL_HAVE_KYBER |
| + | word16 pqkem, |
| #endif | |
| - | |
| + | Curl_wssl_init_session_reuse_cb |
| + | *sess_reuse_cb) |
| + | { |
| /* Let's make an SSL structure */ | |
| wctx->ssl = wolfSSL_new(wctx->ssl_ctx); | |
| if(!wctx->ssl) { | |
| failf(data, "SSL: could not create a handle"); | |
| - | result = CURLE_OUT_OF_MEMORY; |
| - | goto out; |
| + | return CURLE_OUT_OF_MEMORY; |
| } | |
| #ifdef HAVE_EX_DATA | |
| @@ -1288,11 +1198,14 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, | |
| #ifdef WOLFSSL_QUIC | |
| if(transport == TRNSPRT_QUIC) | |
| wolfSSL_set_quic_use_legacy_codepoint(wctx->ssl, 0); | |
| + | #else |
| + | (void)transport; |
| #endif | |
| #ifdef WOLFSSL_HAVE_KYBER | |
| if(pqkem) { | |
| - | if(wolfSSL_UseKeyShare(wctx->ssl, pqkem) != WOLFSSL_SUCCESS) { |
| + | if(wolfSSL_UseKeyShare(wctx->ssl, pqkem) != |
| + | WOLFSSL_SUCCESS) { |
| failf(data, "unable to use PQ KEM"); | |
| } | |
| } | |
| @@ -1301,22 +1214,22 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, | |
| /* Check if there is a cached ID we can/should use here! */ | |
| if(Curl_ssl_scache_use(cf, data)) { | |
| /* Set session from cache if there is one */ | |
| - | (void)wssl_setup_session(cf, data, wctx, &alpns, |
| - | peer->scache_key, sess_reuse_cb); |
| + | (void)wssl_setup_session(cf, data, wctx, alpns, peer->scache_key, |
| + | sess_reuse_cb); |
| } | |
| #ifdef HAVE_ALPN | |
| - | if(alpns.count) { |
| + | if(alpns->count) { |
| struct alpn_proto_buf proto; | |
| memset(&proto, 0, sizeof(proto)); | |
| - | Curl_alpn_to_proto_str(&proto, &alpns); |
| + | Curl_alpn_to_proto_str(&proto, alpns); |
| if(wolfSSL_UseALPN(wctx->ssl, (char *)proto.data, | |
| (unsigned int)proto.len, | |
| - | WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != WOLFSSL_SUCCESS) { |
| + | WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) |
| + | != WOLFSSL_SUCCESS) { |
| failf(data, "SSL: failed setting ALPN protocols"); | |
| - | result = CURLE_SSL_CONNECT_ERROR; |
| - | goto out; |
| + | return CURLE_SSL_CONNECT_ERROR; |
| } | |
| CURL_TRC_CF(data, cf, "set ALPN: %s", proto.data); | |
| } | |
| @@ -1335,101 +1248,251 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, | |
| #ifdef HAVE_SECURE_RENEGOTIATION | |
| if(wolfSSL_UseSecureRenegotiation(wctx->ssl) != SSL_SUCCESS) { | |
| failf(data, "SSL: failed setting secure renegotiation"); | |
| - | result = CURLE_SSL_CONNECT_ERROR; |
| - | goto out; |
| + | return CURLE_SSL_CONNECT_ERROR; |
| } | |
| #endif /* HAVE_SECURE_RENEGOTIATION */ | |
| + | return CURLE_OK; |
| + | } |
| + | |
| #ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG | |
| - | if(CURLECH_ENABLED(data)) { |
| - | int trying_ech_now = 0; |
| + | static CURLcode wssl_init_ech(struct wssl_ctx *wctx, |
| + | struct Curl_cfilter *cf, |
| + | struct Curl_easy *data) |
| + | { |
| + | int trying_ech_now = 0; |
| - | if(data->set.str[STRING_ECH_PUBLIC]) { |
| - | infof(data, "ECH: outername not (yet) supported with wolfSSL"); |
| - | result = CURLE_SSL_CONNECT_ERROR; |
| - | goto out; |
| + | if(data->set.str[STRING_ECH_PUBLIC]) { |
| + | infof(data, "ECH: outername not (yet) supported" |
| + | " with wolfSSL"); |
| + | return CURLE_SSL_CONNECT_ERROR; |
| + | } |
| + | if(data->set.tls_ech == CURLECH_GREASE) { |
| + | infof(data, "ECH: GREASE is done by default by" |
| + | " wolfSSL: no need to ask"); |
| + | } |
| + | if(data->set.tls_ech & CURLECH_CLA_CFG && |
| + | data->set.str[STRING_ECH_CONFIG]) { |
| + | char *b64val = data->set.str[STRING_ECH_CONFIG]; |
| + | word32 b64len = 0; |
| + | |
| + | b64len = (word32)strlen(b64val); |
| + | if(b64len && wolfSSL_SetEchConfigsBase64(wctx->ssl, b64val, |
| + | b64len) != WOLFSSL_SUCCESS) { |
| + | if(data->set.tls_ech & CURLECH_HARD) |
| + | return CURLE_SSL_CONNECT_ERROR; |
| } | |
| - | if(data->set.tls_ech == CURLECH_GREASE) { |
| - | infof(data, "ECH: GREASE is done by default by wolfSSL: no need to ask"); |
| + | else { |
| + | trying_ech_now = 1; |
| + | infof(data, "ECH: ECHConfig from command line"); |
| } | |
| - | if(data->set.tls_ech & CURLECH_CLA_CFG && |
| - | data->set.str[STRING_ECH_CONFIG]) { |
| - | char *b64val = data->set.str[STRING_ECH_CONFIG]; |
| - | word32 b64len = 0; |
| - | |
| - | b64len = (word32)strlen(b64val); |
| - | if(b64len && |
| - | wolfSSL_SetEchConfigsBase64(wctx->ssl, |
| - | b64val, b64len) != WOLFSSL_SUCCESS) { |
| - | if(data->set.tls_ech & CURLECH_HARD) { |
| - | result = CURLE_SSL_CONNECT_ERROR; |
| - | goto out; |
| - | } |
| - | } |
| - | else { |
| - | trying_ech_now = 1; |
| - | infof(data, "ECH: ECHConfig from command line"); |
| + | } |
| + | else { |
| + | struct ssl_connect_data *connssl = cf->ctx; |
| + | struct Curl_dns_entry *dns = NULL; |
| + | CURLcode result; |
| + | |
| + | result = Curl_dnscache_get(data, connssl->peer.hostname, |
| + | connssl->peer.port, cf->conn->ip_version, |
| + | &dns); |
| + | if(!dns) { |
| + | if(result) { |
| + | failf(data, "ECH: could not resolve %s:%d", |
| + | connssl->peer.hostname, |
| + | connssl->peer.port); |
| + | return result; |
| } | |
| + | infof(data, "ECH: requested but no DNS info" |
| + | " available"); |
| + | if(data->set.tls_ech & CURLECH_HARD) |
| + | return CURLE_SSL_CONNECT_ERROR; |
| } | |
| else { | |
| - | struct ssl_connect_data *connssl = cf->ctx; |
| - | struct Curl_dns_entry *dns = NULL; |
| - | |
| - | result = Curl_dnscache_get(data, connssl->peer.hostname, |
| - | connssl->peer.port, |
| - | cf->conn->ip_version, &dns); |
| - | if(!dns) { |
| - | if(result) { |
| - | failf(data, "ECH: could not resolve %s:%d", |
| - | connssl->peer.hostname, connssl->peer.port); |
| - | goto out; |
| + | struct Curl_https_rrinfo *rinfo = NULL; |
| + | |
| + | rinfo = dns->hinfo; |
| + | if(rinfo && rinfo->echconfiglist) { |
| + | unsigned char *ecl = rinfo->echconfiglist; |
| + | size_t elen = rinfo->echconfiglist_len; |
| + | |
| + | infof(data, "ECH: ECHConfig from DoH HTTPS RR"); |
| + | if(wolfSSL_SetEchConfigs(wctx->ssl, ecl, (word32)elen) != |
| + | WOLFSSL_SUCCESS) { |
| + | infof(data, "ECH: wolfSSL_SetEchConfigs failed"); |
| + | if(data->set.tls_ech & CURLECH_HARD) { |
| + | Curl_dns_entry_unlink(data, &dns); |
| + | return CURLE_SSL_CONNECT_ERROR; |
| + | } |
| } | |
| - | infof(data, "ECH: requested but no DNS info available"); |
| - | if(data->set.tls_ech & CURLECH_HARD) { |
| - | result = CURLE_SSL_CONNECT_ERROR; |
| - | goto out; |
| + | else { |
| + | trying_ech_now = 1; |
| + | infof(data, "ECH: imported ECHConfigList of length %zu", elen); |
| } | |
| } | |
| else { | |
| - | struct Curl_https_rrinfo *rinfo = NULL; |
| - | |
| - | rinfo = dns->hinfo; |
| - | if(rinfo && rinfo->echconfiglist) { |
| - | unsigned char *ecl = rinfo->echconfiglist; |
| - | size_t elen = rinfo->echconfiglist_len; |
| - | |
| - | infof(data, "ECH: ECHConfig from DoH HTTPS RR"); |
| - | if(wolfSSL_SetEchConfigs(wctx->ssl, ecl, (word32)elen) != |
| - | WOLFSSL_SUCCESS) { |
| - | infof(data, "ECH: wolfSSL_SetEchConfigs failed"); |
| - | if(data->set.tls_ech & CURLECH_HARD) { |
| - | result = CURLE_SSL_CONNECT_ERROR; |
| - | goto out; |
| - | } |
| - | } |
| - | else { |
| - | trying_ech_now = 1; |
| - | infof(data, "ECH: imported ECHConfigList of length %ld", elen); |
| - | } |
| - | } |
| - | else { |
| - | infof(data, "ECH: requested but no ECHConfig available"); |
| - | if(data->set.tls_ech & CURLECH_HARD) { |
| - | result = CURLE_SSL_CONNECT_ERROR; |
| - | goto out; |
| - | } |
| + | infof(data, "ECH: requested but no ECHConfig available"); |
| + | if(data->set.tls_ech & CURLECH_HARD) { |
| + | Curl_dns_entry_unlink(data, &dns); |
| + | return CURLE_SSL_CONNECT_ERROR; |
| } | |
| - | Curl_dns_entry_unlink(data, &dns); |
| } | |
| + | Curl_dns_entry_unlink(data, &dns); |
| + | } |
| + | } |
| + | |
| + | if(trying_ech_now && |
| + | wolfSSL_set_min_proto_version(wctx->ssl, TLS1_3_VERSION) != 1) { |
| + | infof(data, "ECH: cannot force TLSv1.3 [ERROR]"); |
| + | return CURLE_SSL_CONNECT_ERROR; |
| + | } |
| + | return CURLE_OK; |
| + | } |
| + | #endif /* HAVE_WOLFSSL_CTX_GENERATEECHCONFIG */ |
| + | |
| + | CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx, |
| + | struct Curl_cfilter *cf, |
| + | struct Curl_easy *data, |
| + | struct ssl_peer *peer, |
| + | const struct alpn_spec *alpns_requested, |
| + | Curl_wssl_ctx_setup_cb *cb_setup, |
| + | void *cb_user_data, |
| + | void *ssl_user_data, |
| + | Curl_wssl_init_session_reuse_cb *sess_reuse_cb) |
| + | { |
| + | struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); |
| + | struct ssl_primary_config *conn_config; |
| + | WOLFSSL_METHOD *req_method = NULL; |
| + | struct alpn_spec alpns; |
| + | #ifdef WOLFSSL_HAVE_KYBER |
| + | word16 pqkem = 0; |
| + | #endif |
| + | CURLcode result = CURLE_FAILED_INIT; |
| + | unsigned char transport; |
| + | int tls_min, tls_max; |
| + | |
| + | DEBUGASSERT(!wctx->ssl_ctx); |
| + | DEBUGASSERT(!wctx->ssl); |
| + | conn_config = Curl_ssl_cf_get_primary_config(cf); |
| + | if(!conn_config) { |
| + | result = CURLE_FAILED_INIT; |
| + | goto out; |
| + | } |
| + | Curl_alpn_copy(&alpns, alpns_requested); |
| + | DEBUGASSERT(cf->next); |
| + | transport = Curl_conn_cf_get_transport(cf->next, data); |
| + | |
| + | req_method = wolfTLS_client_method(); |
| + | if(!req_method) { |
| + | failf(data, "wolfSSL: could not create a client method"); |
| + | result = CURLE_OUT_OF_MEMORY; |
| + | goto out; |
| + | } |
| + | |
| + | if(wctx->ssl_ctx) |
| + | wolfSSL_CTX_free(wctx->ssl_ctx); |
| + | |
| + | wctx->ssl_ctx = wolfSSL_CTX_new(req_method); |
| + | if(!wctx->ssl_ctx) { |
| + | failf(data, "wolfSSL: could not create a context"); |
| + | result = CURLE_OUT_OF_MEMORY; |
| + | goto out; |
| + | } |
| + | |
| + | result = ssl_version(data, conn_config, wctx, &tls_min, &tls_max); |
| + | if(result) |
| + | goto out; |
| + | |
| + | result = wssl_init_ciphers(data, wctx, conn_config, tls_min, tls_max); |
| + | if(result) |
| + | goto out; |
| + | |
| + | result = wssl_init_curves(data, wctx, conn_config, transport |
| + | #ifdef WOLFSSL_HAVE_KYBER |
| + | , &pqkem |
| + | #endif |
| + | ); |
| + | if(result) |
| + | goto out; |
| + | |
| + | result = wssl_client_cert(data, ssl_config, wctx); |
| + | if(result) |
| + | goto out; |
| + | |
| + | /* SSL always tries to verify the peer, this only says whether it should |
| + | * fail to connect if the verification fails, or if it should continue |
| + | * anyway. In the latter case the result of the verification is checked with |
| + | * SSL_get_verify_result() below. */ |
| + | wolfSSL_CTX_set_verify(wctx->ssl_ctx, conn_config->verifypeer ? |
| + | WOLFSSL_VERIFY_PEER : WOLFSSL_VERIFY_NONE, NULL); |
| + | |
| + | #ifdef HAVE_SNI |
| + | if(peer->sni) { |
| + | size_t sni_len = strlen(peer->sni); |
| + | if((sni_len < USHRT_MAX)) { |
| + | if(wolfSSL_CTX_UseSNI(wctx->ssl_ctx, WOLFSSL_SNI_HOST_NAME, |
| + | peer->sni, (unsigned short)sni_len) != 1) { |
| + | failf(data, "Failed to set SNI"); |
| + | result = CURLE_SSL_CONNECT_ERROR; |
| + | goto out; |
| + | } |
| + | CURL_TRC_CF(data, cf, "set SNI '%s'", peer->sni); |
| } | |
| + | } |
| + | #endif |
| - | if(trying_ech_now && wolfSSL_set_min_proto_version(wctx->ssl, |
| - | TLS1_3_VERSION) != 1) { |
| - | infof(data, "ECH: cannot force TLSv1.3 [ERROR]"); |
| - | result = CURLE_SSL_CONNECT_ERROR; |
| + | #ifdef HAVE_EX_DATA |
| + | if(Curl_ssl_scache_use(cf, data) && (transport != TRNSPRT_QUIC)) { |
| + | /* Register to get notified when a new session is received */ |
| + | wolfSSL_CTX_sess_set_new_cb(wctx->ssl_ctx, wssl_vtls_new_session_cb); |
| + | } |
| + | #endif |
| + | |
| + | if(cb_setup) { |
| + | result = cb_setup(cf, data, cb_user_data); |
| + | if(result) |
| + | goto out; |
| + | } |
| + | |
| + | /* give application a chance to interfere with SSL set up. */ |
| + | if(data->set.ssl.fsslctx) { |
| + | if(!wctx->x509_store_setup) { |
| + | result = Curl_wssl_setup_x509_store(cf, data, wctx); |
| + | if(result) |
| + | goto out; |
| + | } |
| + | result = (*data->set.ssl.fsslctx)(data, wctx->ssl_ctx, |
| + | data->set.ssl.fsslctxp); |
| + | if(result) { |
| + | failf(data, "error signaled by ssl ctx callback"); |
| goto out; | |
| } | |
| } | |
| + | #ifdef NO_FILESYSTEM |
| + | else if(conn_config->verifypeer) { |
| + | failf(data, "SSL: Certificates cannot be loaded because wolfSSL was built" |
| + | " with no file system. Either disable peer verification" |
| + | " (insecure) or if you are building an application with libcurl you" |
| + | " can load certificates via CURLOPT_SSL_CTX_FUNCTION."); |
| + | result = CURLE_SSL_CONNECT_ERROR; |
| + | goto out; |
| + | } |
| + | #endif |
| + | |
| + | result = wssl_init_ssl_handle(wctx, cf, data, peer, &alpns, ssl_user_data, |
| + | transport, |
| + | #ifdef WOLFSSL_HAVE_KYBER |
| + | pqkem, |
| + | #endif |
| + | sess_reuse_cb); |
| + | if(result) |
| + | goto out; |
| + | |
| + | #ifdef HAVE_WOLFSSL_CTX_GENERATEECHCONFIG |
| + | if(CURLECH_ENABLED(data)) { |
| + | result = wssl_init_ech(wctx, cf, data); |
| + | if(result) |
| + | goto out; |
| + | } |
| #endif /* HAVE_WOLFSSL_CTX_GENERATEECHCONFIG */ | |
| result = CURLE_OK; | |
| @@ -1463,9 +1526,8 @@ static CURLcode wssl_connect_step1(struct Curl_cfilter *cf, | |
| if(connssl->state == ssl_connection_complete) | |
| return CURLE_OK; | |
| - | result = Curl_wssl_ctx_init(wssl, cf, data, &connssl->peer, |
| - | connssl->alpn, NULL, NULL, cf, |
| - | wssl_on_session_reuse); |
| + | result = Curl_wssl_ctx_init(wssl, cf, data, &connssl->peer, connssl->alpn, |
| + | NULL, NULL, cf, wssl_on_session_reuse); |
| if(result) | |
| return result; | |