vtls_config: adjust to origin
No binary (build failed)
—
(log yok)
| @@ -96,6 +96,7 @@ LIB_VTLS_CFILES = \ | |
| vtls/schannel.c \ | |
| vtls/schannel_verify.c \ | |
| vtls/vtls.c \ | |
| + | vtls/vtls_config.c \ |
| vtls/vtls_scache.c \ | |
| vtls/vtls_spack.c \ | |
| vtls/wolfssl.c \ | |
| @@ -113,6 +114,7 @@ LIB_VTLS_HFILES = \ | |
| vtls/schannel.h \ | |
| vtls/schannel_int.h \ | |
| vtls/vtls.h \ | |
| + | vtls/vtls_config.h \ |
| vtls/vtls_int.h \ | |
| vtls/vtls_scache.h \ | |
| vtls/vtls_spack.h \ | |
| @@ -300,6 +300,10 @@ CURLcode Curl_close(struct Curl_easy **datap) | |
| Curl_netrc_cleanup(&data->state.netrc); | |
| #ifndef CURL_DISABLE_DIGEST_AUTH | |
| curlx_free(data->state.envproxy); | |
| + | #endif |
| + | Curl_ssl_config_cleanup(&data->set.ssl.primary); |
| + | #ifndef CURL_DISABLE_PROXY |
| + | Curl_ssl_config_cleanup(&data->set.proxy_ssl.primary); |
| #endif | |
| curlx_free(data); | |
| return CURLE_OK; | |
| @@ -355,7 +359,9 @@ void Curl_init_userdefined(struct Curl_easy *data) | |
| set->httpauth = CURLAUTH_BASIC; /* defaults to basic */ | |
| + | Curl_ssl_config_init(&data->set.ssl.primary); |
| #ifndef CURL_DISABLE_PROXY | |
| + | Curl_ssl_config_init(&data->set.proxy_ssl.primary); |
| set->proxyport = 0; | |
| set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ | |
| set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */ | |
| @@ -363,7 +369,6 @@ void Curl_init_userdefined(struct Curl_easy *data) | |
| set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI; | |
| #endif | |
| - | Curl_ssl_easy_config_init(data); |
| #ifndef CURL_DISABLE_DOH | |
| set->doh_verifyhost = TRUE; | |
| set->doh_verifypeer = TRUE; | |
| @@ -2782,7 +2787,7 @@ static CURLcode url_find_or_create_conn(struct Curl_easy *data) | |
| #endif | |
| /* Complete the easy's SSL configuration for connection cache matching */ | |
| - | result = Curl_ssl_easy_config_complete(data); |
| + | result = Curl_ssl_easy_config_complete(data, needle->origin); |
| if(result) | |
| goto out; | |
| @@ -69,6 +69,7 @@ | |
| #include "request.h" | |
| #include "ratelimit.h" | |
| #include "netrc.h" | |
| + | #include "vtls/vtls_config.h" |
| /* On error return, the value of `pnwritten` has no meaning */ | |
| typedef CURLcode (Curl_send)(struct Curl_easy *data, /* transfer */ | |
| @@ -140,62 +141,6 @@ typedef CURLcode (Curl_recv)(struct Curl_easy *data, /* transfer */ | |
| ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER)) | |
| #endif | |
| - | struct ssl_primary_config { |
| - | char *CApath; /* certificate directory (does not work on Windows) */ |
| - | char *CAfile; /* certificate to verify peer against */ |
| - | char *issuercert; /* optional issuer certificate filename */ |
| - | char *clientcert; |
| - | char *cipher_list; /* list of ciphers to use */ |
| - | char *cipher_list13; /* list of TLS 1.3 cipher suites to use */ |
| - | char *signature_algorithms; /* list of signature algorithms to use */ |
| - | char *pinned_key; |
| - | char *CRLfile; /* CRL to check certificate revocation */ |
| - | char *cert_type; /* format for certificate (default: PEM) */ |
| - | char *key; /* private key filename */ |
| - | char *key_type; /* format for private key (default: PEM) */ |
| - | char *key_passwd; /* plain text private key password */ |
| - | struct curl_blob *cert_blob; |
| - | struct curl_blob *ca_info_blob; |
| - | struct curl_blob *issuercert_blob; |
| - | struct curl_blob *key_blob; |
| - | #ifdef USE_TLS_SRP |
| - | char *username; /* TLS username (for, e.g., SRP) */ |
| - | char *password; /* TLS password (for, e.g., SRP) */ |
| - | #endif |
| - | char *curves; /* list of curves to use */ |
| - | uint32_t version_max; /* max supported version the client wants to use */ |
| - | uint8_t ssl_options; /* the CURLOPT_SSL_OPTIONS bitmask */ |
| - | uint8_t version; /* what version the client wants to use */ |
| - | BIT(verifypeer); /* set TRUE if this is desired */ |
| - | BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */ |
| - | BIT(verifystatus); /* set TRUE if certificate status must be checked */ |
| - | BIT(cache_session); /* cache session or not */ |
| - | }; |
| - | |
| - | struct ssl_config_data { |
| - | struct ssl_primary_config primary; |
| - | long certverifyresult; /* result from the certificate verification */ |
| - | curl_ssl_ctx_callback fsslctx; /* function to initialize SSL ctx */ |
| - | void *fsslctxp; /* parameter for call back */ |
| - | BIT(certinfo); /* gather lots of certificate info */ |
| - | BIT(earlydata); /* use TLS 1.3 early data */ |
| - | BIT(enable_beast); /* allow this flaw for interoperability's sake */ |
| - | BIT(no_revoke); /* disable SSL certificate revocation checks */ |
| - | BIT(no_partialchain); /* do not accept partial certificate chains */ |
| - | BIT(revoke_best_effort); /* ignore SSL revocation offline/missing revocation |
| - | list errors */ |
| - | BIT(native_ca_store); /* use the native CA store of operating system */ |
| - | BIT(auto_client_cert); /* automatically locate and use a client |
| - | certificate for authentication (Schannel) */ |
| - | BIT(custom_cafile); /* application has set custom CA file */ |
| - | BIT(custom_capath); /* application has set custom CA path */ |
| - | BIT(custom_cablob); /* application has set custom CA blob */ |
| - | }; |
| - | |
| - | struct ssl_general_config { |
| - | int ca_cache_timeout; /* Certificate store cache timeout (seconds) */ |
| - | }; |
| - | |
| #ifdef USE_WINDOWS_SSPI | |
| #include "curl_sspi.h" | |
| #endif | |
| @@ -78,57 +78,6 @@ | |
| #include <Security/Security.h> | |
| #endif | |
| - | |
| - | #define CLONE_STRING(var) \ |
| - | do { \ |
| - | if(source->var) { \ |
| - | dest->var = curlx_strdup(source->var); \ |
| - | if(!dest->var) \ |
| - | return FALSE; \ |
| - | } \ |
| - | else \ |
| - | dest->var = NULL; \ |
| - | } while(0) |
| - | |
| - | #define CLONE_BLOB(var) \ |
| - | do { \ |
| - | if(blobdup(&dest->var, source->var)) \ |
| - | return FALSE; \ |
| - | } while(0) |
| - | |
| - | static CURLcode blobdup(struct curl_blob **dest, struct curl_blob *src) |
| - | { |
| - | DEBUGASSERT(dest); |
| - | DEBUGASSERT(!*dest); |
| - | if(src) { |
| - | /* only if there is data to dupe! */ |
| - | struct curl_blob *d; |
| - | d = curlx_malloc(sizeof(struct curl_blob) + src->len); |
| - | if(!d) |
| - | return CURLE_OUT_OF_MEMORY; |
| - | d->len = src->len; |
| - | /* Always duplicate because the connection may survive longer than the |
| - | handle that passed in the blob. */ |
| - | d->flags = CURL_BLOB_COPY; |
| - | d->data = (void *)((char *)d + sizeof(struct curl_blob)); |
| - | memcpy(d->data, src->data, src->len); |
| - | *dest = d; |
| - | } |
| - | return CURLE_OK; |
| - | } |
| - | |
| - | /* returns TRUE if the blobs are identical */ |
| - | static bool blobcmp(struct curl_blob *first, struct curl_blob *second) |
| - | { |
| - | if(!first && !second) /* both are NULL */ |
| - | return TRUE; |
| - | if(!first || !second) /* one is NULL */ |
| - | return FALSE; |
| - | if(first->len != second->len) /* different sizes */ |
| - | return FALSE; |
| - | return !memcmp(first->data, second->data, first->len); /* same data */ |
| - | } |
| - | |
| #ifdef USE_SSL | |
| #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_PROXY) | |
| static const struct alpn_spec ALPN_SPEC_H11 = { | |
| @@ -177,280 +126,6 @@ static const struct alpn_spec *alpn_get_spec(http_majors wanted, | |
| #endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_PROXY */ | |
| #endif /* USE_SSL */ | |
| - | void Curl_ssl_easy_config_init(struct Curl_easy *data) |
| - | { |
| - | /* |
| - | * libcurl 7.10 introduced SSL verification *by default*! This needs to be |
| - | * switched off unless wanted. |
| - | */ |
| - | data->set.ssl.primary.verifypeer = TRUE; |
| - | data->set.ssl.primary.verifyhost = TRUE; |
| - | data->set.ssl.primary.cache_session = TRUE; /* caching by default */ |
| - | #ifndef CURL_DISABLE_PROXY |
| - | data->set.proxy_ssl = data->set.ssl; |
| - | #endif |
| - | } |
| - | |
| - | static bool match_ssl_primary_config(struct Curl_easy *data, |
| - | struct ssl_primary_config *c1, |
| - | struct ssl_primary_config *c2) |
| - | { |
| - | (void)data; |
| - | if((c1->version == c2->version) && |
| - | (c1->version_max == c2->version_max) && |
| - | (c1->ssl_options == c2->ssl_options) && |
| - | (c1->verifypeer == c2->verifypeer) && |
| - | (c1->verifyhost == c2->verifyhost) && |
| - | (c1->verifystatus == c2->verifystatus) && |
| - | blobcmp(c1->cert_blob, c2->cert_blob) && |
| - | blobcmp(c1->ca_info_blob, c2->ca_info_blob) && |
| - | blobcmp(c1->issuercert_blob, c2->issuercert_blob) && |
| - | blobcmp(c1->key_blob, c2->key_blob) && |
| - | Curl_safecmp(c1->CApath, c2->CApath) && |
| - | Curl_safecmp(c1->CAfile, c2->CAfile) && |
| - | Curl_safecmp(c1->issuercert, c2->issuercert) && |
| - | Curl_safecmp(c1->clientcert, c2->clientcert) && |
| - | #ifdef USE_TLS_SRP |
| - | !Curl_timestrcmp(c1->username, c2->username) && |
| - | !Curl_timestrcmp(c1->password, c2->password) && |
| - | #endif |
| - | curl_strequal(c1->cipher_list, c2->cipher_list) && |
| - | curl_strequal(c1->cipher_list13, c2->cipher_list13) && |
| - | curl_strequal(c1->curves, c2->curves) && |
| - | curl_strequal(c1->signature_algorithms, c2->signature_algorithms) && |
| - | Curl_safecmp(c1->CRLfile, c2->CRLfile) && |
| - | Curl_safecmp(c1->pinned_key, c2->pinned_key) && |
| - | curl_strequal(c1->cert_type, c2->cert_type) && |
| - | Curl_safecmp(c1->key, c2->key) && |
| - | curl_strequal(c1->key_type, c2->key_type) && |
| - | !Curl_timestrcmp(c1->key_passwd, c2->key_passwd)) |
| - | return TRUE; |
| - | |
| - | return FALSE; |
| - | } |
| - | |
| - | bool Curl_ssl_conn_config_match(struct Curl_easy *data, |
| - | struct connectdata *candidate, |
| - | bool proxy) |
| - | { |
| - | #ifndef CURL_DISABLE_PROXY |
| - | if(proxy) |
| - | return match_ssl_primary_config(data, &data->set.proxy_ssl.primary, |
| - | &candidate->proxy_ssl_config); |
| - | #else |
| - | (void)proxy; |
| - | #endif |
| - | return match_ssl_primary_config(data, &data->set.ssl.primary, |
| - | &candidate->ssl_config); |
| - | } |
| - | |
| - | static bool clone_ssl_primary_config(struct ssl_primary_config *source, |
| - | struct ssl_primary_config *dest) |
| - | { |
| - | dest->version = source->version; |
| - | dest->version_max = source->version_max; |
| - | dest->verifypeer = source->verifypeer; |
| - | dest->verifyhost = source->verifyhost; |
| - | dest->verifystatus = source->verifystatus; |
| - | dest->cache_session = source->cache_session; |
| - | dest->ssl_options = source->ssl_options; |
| - | |
| - | CLONE_BLOB(cert_blob); |
| - | CLONE_BLOB(ca_info_blob); |
| - | CLONE_BLOB(issuercert_blob); |
| - | CLONE_BLOB(key_blob); |
| - | CLONE_STRING(CApath); |
| - | CLONE_STRING(CAfile); |
| - | CLONE_STRING(issuercert); |
| - | CLONE_STRING(clientcert); |
| - | CLONE_STRING(cipher_list); |
| - | CLONE_STRING(cipher_list13); |
| - | CLONE_STRING(pinned_key); |
| - | CLONE_STRING(curves); |
| - | CLONE_STRING(signature_algorithms); |
| - | CLONE_STRING(CRLfile); |
| - | CLONE_STRING(cert_type); |
| - | CLONE_STRING(key); |
| - | CLONE_STRING(key_type); |
| - | CLONE_STRING(key_passwd); |
| - | #ifdef USE_TLS_SRP |
| - | CLONE_STRING(username); |
| - | CLONE_STRING(password); |
| - | #endif |
| - | |
| - | return TRUE; |
| - | } |
| - | |
| - | static void free_primary_ssl_config(struct ssl_primary_config *sslc) |
| - | { |
| - | curlx_safefree(sslc->CApath); |
| - | curlx_safefree(sslc->CAfile); |
| - | curlx_safefree(sslc->issuercert); |
| - | curlx_safefree(sslc->clientcert); |
| - | curlx_safefree(sslc->cipher_list); |
| - | curlx_safefree(sslc->cipher_list13); |
| - | curlx_safefree(sslc->pinned_key); |
| - | curlx_safefree(sslc->cert_blob); |
| - | curlx_safefree(sslc->ca_info_blob); |
| - | curlx_safefree(sslc->issuercert_blob); |
| - | curlx_safefree(sslc->key_blob); |
| - | curlx_safefree(sslc->curves); |
| - | curlx_safefree(sslc->signature_algorithms); |
| - | curlx_safefree(sslc->CRLfile); |
| - | curlx_safefree(sslc->cert_type); |
| - | curlx_safefree(sslc->key); |
| - | curlx_safefree(sslc->key_type); |
| - | curlx_safefree(sslc->key_passwd); |
| - | #ifdef USE_TLS_SRP |
| - | curlx_safefree(sslc->username); |
| - | curlx_safefree(sslc->password); |
| - | #endif |
| - | } |
| - | |
| - | CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data) |
| - | { |
| - | struct ssl_config_data *sslc = &data->set.ssl; |
| - | #if defined(CURL_CA_PATH) || defined(CURL_CA_BUNDLE) |
| - | struct UserDefined *set = &data->set; |
| - | CURLcode result; |
| - | #endif |
| - | |
| - | if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { |
| - | #if defined(USE_APPLE_SECTRUST) || defined(CURL_CA_NATIVE) |
| - | if(!sslc->custom_capath && !sslc->custom_cafile && !sslc->custom_cablob) |
| - | sslc->native_ca_store = TRUE; |
| - | #endif |
| - | #ifdef CURL_CA_PATH |
| - | if(!sslc->custom_capath && !set->str[STRING_SSL_CAPATH]) { |
| - | result = Curl_setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH); |
| - | if(result) |
| - | return result; |
| - | } |
| - | #endif |
| - | #ifdef CURL_CA_BUNDLE |
| - | if(!sslc->custom_cafile && !set->str[STRING_SSL_CAFILE]) { |
| - | result = Curl_setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE); |
| - | if(result) |
| - | return result; |
| - | } |
| - | #endif |
| - | } |
| - | sslc->primary.CAfile = data->set.str[STRING_SSL_CAFILE]; |
| - | sslc->primary.CRLfile = data->set.str[STRING_SSL_CRLFILE]; |
| - | sslc->primary.CApath = data->set.str[STRING_SSL_CAPATH]; |
| - | sslc->primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; |
| - | sslc->primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; |
| - | sslc->primary.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; |
| - | sslc->primary.cipher_list13 = data->set.str[STRING_SSL_CIPHER13_LIST]; |
| - | sslc->primary.signature_algorithms = |
| - | data->set.str[STRING_SSL_SIGNATURE_ALGORITHMS]; |
| - | sslc->primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; |
| - | sslc->primary.cert_blob = data->set.blobs[BLOB_CERT]; |
| - | sslc->primary.ca_info_blob = data->set.blobs[BLOB_CAINFO]; |
| - | sslc->primary.curves = data->set.str[STRING_SSL_EC_CURVES]; |
| - | #ifdef USE_TLS_SRP |
| - | sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME]; |
| - | sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD]; |
| - | #endif |
| - | sslc->primary.cert_type = data->set.str[STRING_CERT_TYPE]; |
| - | sslc->primary.key = data->set.str[STRING_KEY]; |
| - | sslc->primary.key_type = data->set.str[STRING_KEY_TYPE]; |
| - | sslc->primary.key_passwd = data->set.str[STRING_KEY_PASSWD]; |
| - | sslc->primary.clientcert = data->set.str[STRING_CERT]; |
| - | sslc->primary.key_blob = data->set.blobs[BLOB_KEY]; |
| - | |
| - | #ifndef CURL_DISABLE_PROXY |
| - | sslc = &data->set.proxy_ssl; |
| - | if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { |
| - | #if defined(USE_APPLE_SECTRUST) || defined(CURL_CA_NATIVE) |
| - | if(!sslc->custom_capath && !sslc->custom_cafile && !sslc->custom_cablob) |
| - | sslc->native_ca_store = TRUE; |
| - | #endif |
| - | #ifdef CURL_CA_PATH |
| - | if(!sslc->custom_capath && !set->str[STRING_SSL_CAPATH_PROXY]) { |
| - | result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_PROXY], |
| - | CURL_CA_PATH); |
| - | if(result) |
| - | return result; |
| - | } |
| - | #endif |
| - | #ifdef CURL_CA_BUNDLE |
| - | if(!sslc->custom_cafile && !set->str[STRING_SSL_CAFILE_PROXY]) { |
| - | result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY], |
| - | CURL_CA_BUNDLE); |
| - | if(result) |
| - | return result; |
| - | } |
| - | #endif |
| - | } |
| - | sslc->primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; |
| - | sslc->primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; |
| - | sslc->primary.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; |
| - | sslc->primary.cipher_list13 = data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; |
| - | sslc->primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]; |
| - | sslc->primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; |
| - | sslc->primary.ca_info_blob = data->set.blobs[BLOB_CAINFO_PROXY]; |
| - | sslc->primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; |
| - | sslc->primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY]; |
| - | sslc->primary.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; |
| - | sslc->primary.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; |
| - | sslc->primary.key = data->set.str[STRING_KEY_PROXY]; |
| - | sslc->primary.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; |
| - | sslc->primary.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; |
| - | sslc->primary.clientcert = data->set.str[STRING_CERT_PROXY]; |
| - | sslc->primary.key_blob = data->set.blobs[BLOB_KEY_PROXY]; |
| - | #ifdef USE_TLS_SRP |
| - | sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; |
| - | sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; |
| - | #endif |
| - | #endif /* CURL_DISABLE_PROXY */ |
| - | |
| - | return CURLE_OK; |
| - | } |
| - | |
| - | CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data, |
| - | struct connectdata *conn) |
| - | { |
| - | /* Clone "primary" SSL configurations from the easy handle to |
| - | * the connection. They are used for connection cache matching and |
| - | * probably outlive the easy handle */ |
| - | if(!clone_ssl_primary_config(&data->set.ssl.primary, &conn->ssl_config)) |
| - | return CURLE_OUT_OF_MEMORY; |
| - | #ifndef CURL_DISABLE_PROXY |
| - | if(!clone_ssl_primary_config(&data->set.proxy_ssl.primary, |
| - | &conn->proxy_ssl_config)) |
| - | return CURLE_OUT_OF_MEMORY; |
| - | #endif |
| - | return CURLE_OK; |
| - | } |
| - | |
| - | void Curl_ssl_conn_config_cleanup(struct connectdata *conn) |
| - | { |
| - | free_primary_ssl_config(&conn->ssl_config); |
| - | #ifndef CURL_DISABLE_PROXY |
| - | free_primary_ssl_config(&conn->proxy_ssl_config); |
| - | #endif |
| - | } |
| - | |
| - | void Curl_ssl_conn_config_update(struct Curl_easy *data, bool for_proxy) |
| - | { |
| - | /* May be called on an easy that has no connection yet */ |
| - | if(data->conn) { |
| - | struct ssl_primary_config *src, *dest; |
| - | #ifndef CURL_DISABLE_PROXY |
| - | src = for_proxy ? &data->set.proxy_ssl.primary : &data->set.ssl.primary; |
| - | dest = for_proxy ? &data->conn->proxy_ssl_config : &data->conn->ssl_config; |
| - | #else |
| - | (void)for_proxy; |
| - | src = &data->set.ssl.primary; |
| - | dest = &data->conn->ssl_config; |
| - | #endif |
| - | dest->verifyhost = src->verifyhost; |
| - | dest->verifypeer = src->verifypeer; |
| - | dest->verifystatus = src->verifystatus; |
| - | } |
| - | } |
| - | |
| #ifdef USE_SSL | |
| static int multissl_setup(const struct Curl_ssl *backend); | |
| #endif | |
| @@ -103,43 +103,6 @@ CURLsslset Curl_init_sslset_nolock(curl_sslbackend id, const char *name, | |
| curl_sslbackend Curl_ssl_backend(void); | |
| - | /** |
| - | * Init SSL config for a new easy handle. |
| - | */ |
| - | void Curl_ssl_easy_config_init(struct Curl_easy *data); |
| - | |
| - | /** |
| - | * Init the `data->set.ssl` and `data->set.proxy_ssl` for |
| - | * connection matching use. |
| - | */ |
| - | CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data); |
| - | |
| - | /** |
| - | * Init SSL configs (main + proxy) for a new connection from the easy handle. |
| - | */ |
| - | CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data, |
| - | struct connectdata *conn); |
| - | |
| - | /** |
| - | * Free allocated resources in SSL configs (main + proxy) for |
| - | * the given connection. |
| - | */ |
| - | void Curl_ssl_conn_config_cleanup(struct connectdata *conn); |
| - | |
| - | /** |
| - | * Return TRUE iff SSL configuration from `data` is functionally the |
| - | * same as the one on `candidate`. |
| - | * @param proxy match the proxy SSL config or the main one |
| - | */ |
| - | bool Curl_ssl_conn_config_match(struct Curl_easy *data, |
| - | struct connectdata *candidate, |
| - | bool proxy); |
| - | |
| - | /* Update certain connection SSL config flags after they have |
| - | * been changed on the easy handle. Works for `verifypeer`, |
| - | * `verifyhost` and `verifystatus`. */ |
| - | void Curl_ssl_conn_config_update(struct Curl_easy *data, bool for_proxy); |
| - | |
| /** | |
| * Init SSL peer information for filter. Can be called repeatedly. | |
| */ | |
| @@ -0,0 +1,399 @@ | |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * Project ___| | | | _ \| | |
| + | * / __| | | | |_) | | |
| + | * | (__| |_| | _ <| |___ |
| + | * \___|\___/|_| \_\_____| |
| + | * |
| + | * Copyright (C) Daniel Stenberg, <[email protected]>, et al. |
| + | * |
| + | * This software is licensed as described in the file COPYING, which |
| + | * you should have received as part of this distribution. The terms |
| + | * are also available at https://curl.se/docs/copyright.html. |
| + | * |
| + | * You may opt to use, copy, modify, merge, publish, distribute and/or sell |
| + | * copies of the Software, and permit persons to whom the Software is |
| + | * furnished to do so, under the terms of the COPYING file. |
| + | * |
| + | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| + | * KIND, either express or implied. |
| + | * |
| + | * SPDX-License-Identifier: curl |
| + | * |
| + | ***************************************************************************/ |
| + | |
| + | /* This file is for implementing all "generic" SSL functions that all libcurl |
| + | internals should use. It is then responsible for calling the proper |
| + | "backend" function. |
| + | |
| + | SSL-functions in libcurl should call functions in this source file, and not |
| + | to any specific SSL-layer. |
| + | |
| + | Curl_ssl_ - prefix for generic ones |
| + | |
| + | Note that this source code uses the functions of the configured SSL |
| + | backend via the global Curl_ssl instance. |
| + | |
| + | "SSL/TLS Strong Encryption: An Introduction" |
| + | https://httpd.apache.org/docs/2.0/ssl/ssl_intro.html |
| + | */ |
| + | |
| + | #include "curl_setup.h" |
| + | |
| + | #ifdef HAVE_SYS_TYPES_H |
| + | #include <sys/types.h> |
| + | #endif |
| + | |
| + | #include "urldata.h" |
| + | #include "setopt.h" |
| + | #include "strcase.h" |
| + | #include "vtls/vtls.h" |
| + | #include "vtls/vtls_config.h" |
| + | |
| + | |
| + | #define CLONE_STRING(var) \ |
| + | do { \ |
| + | if(source->var) { \ |
| + | dest->var = curlx_strdup(source->var); \ |
| + | if(!dest->var) \ |
| + | return FALSE; \ |
| + | } \ |
| + | else \ |
| + | dest->var = NULL; \ |
| + | } while(0) |
| + | |
| + | #define CLONE_BLOB(var) \ |
| + | do { \ |
| + | if(blobdup(&dest->var, source->var)) \ |
| + | return FALSE; \ |
| + | } while(0) |
| + | |
| + | static CURLcode blobdup(struct curl_blob **dest, struct curl_blob *src) |
| + | { |
| + | DEBUGASSERT(dest); |
| + | DEBUGASSERT(!*dest); |
| + | if(src) { |
| + | /* only if there is data to dupe! */ |
| + | struct curl_blob *d; |
| + | d = curlx_malloc(sizeof(struct curl_blob) + src->len); |
| + | if(!d) |
| + | return CURLE_OUT_OF_MEMORY; |
| + | d->len = src->len; |
| + | /* Always duplicate because the connection may survive longer than the |
| + | handle that passed in the blob. */ |
| + | d->flags = CURL_BLOB_COPY; |
| + | d->data = (void *)((char *)d + sizeof(struct curl_blob)); |
| + | memcpy(d->data, src->data, src->len); |
| + | *dest = d; |
| + | } |
| + | return CURLE_OK; |
| + | } |
| + | |
| + | /* returns TRUE if the blobs are identical */ |
| + | static bool blobcmp(struct curl_blob *first, struct curl_blob *second) |
| + | { |
| + | if(!first && !second) /* both are NULL */ |
| + | return TRUE; |
| + | if(!first || !second) /* one is NULL */ |
| + | return FALSE; |
| + | if(first->len != second->len) /* different sizes */ |
| + | return FALSE; |
| + | return !memcmp(first->data, second->data, first->len); /* same data */ |
| + | } |
| + | |
| + | void Curl_ssl_config_init(struct ssl_primary_config *sslc) |
| + | { |
| + | /* |
| + | * libcurl 7.10 introduced SSL verification *by default*! This needs to be |
| + | * switched off unless wanted. |
| + | */ |
| + | sslc->verifypeer = TRUE; |
| + | sslc->verifyhost = TRUE; |
| + | sslc->cache_session = TRUE; /* caching by default */ |
| + | } |
| + | |
| + | void Curl_ssl_config_cleanup(struct ssl_primary_config *sslc) |
| + | { |
| + | if(sslc->deep_copy) { |
| + | curlx_safefree(sslc->CApath); |
| + | curlx_safefree(sslc->CAfile); |
| + | curlx_safefree(sslc->issuercert); |
| + | curlx_safefree(sslc->clientcert); |
| + | curlx_safefree(sslc->cipher_list); |
| + | curlx_safefree(sslc->cipher_list13); |
| + | curlx_safefree(sslc->pinned_key); |
| + | curlx_safefree(sslc->cert_blob); |
| + | curlx_safefree(sslc->ca_info_blob); |
| + | curlx_safefree(sslc->issuercert_blob); |
| + | curlx_safefree(sslc->key_blob); |
| + | curlx_safefree(sslc->curves); |
| + | curlx_safefree(sslc->signature_algorithms); |
| + | curlx_safefree(sslc->CRLfile); |
| + | curlx_safefree(sslc->cert_type); |
| + | curlx_safefree(sslc->key); |
| + | curlx_safefree(sslc->key_type); |
| + | curlx_safefree(sslc->key_passwd); |
| + | #ifdef USE_TLS_SRP |
| + | curlx_safefree(sslc->username); |
| + | curlx_safefree(sslc->password); |
| + | #endif |
| + | sslc->deep_copy = FALSE; |
| + | } |
| + | } |
| + | |
| + | static bool match_ssl_primary_config(struct Curl_easy *data, |
| + | struct ssl_primary_config *c1, |
| + | struct ssl_primary_config *c2) |
| + | { |
| + | (void)data; |
| + | if((c1->version == c2->version) && |
| + | (c1->version_max == c2->version_max) && |
| + | (c1->ssl_options == c2->ssl_options) && |
| + | (c1->verifypeer == c2->verifypeer) && |
| + | (c1->verifyhost == c2->verifyhost) && |
| + | (c1->verifystatus == c2->verifystatus) && |
| + | blobcmp(c1->cert_blob, c2->cert_blob) && |
| + | blobcmp(c1->ca_info_blob, c2->ca_info_blob) && |
| + | blobcmp(c1->issuercert_blob, c2->issuercert_blob) && |
| + | blobcmp(c1->key_blob, c2->key_blob) && |
| + | Curl_safecmp(c1->CApath, c2->CApath) && |
| + | Curl_safecmp(c1->CAfile, c2->CAfile) && |
| + | Curl_safecmp(c1->issuercert, c2->issuercert) && |
| + | Curl_safecmp(c1->clientcert, c2->clientcert) && |
| + | #ifdef USE_TLS_SRP |
| + | !Curl_timestrcmp(c1->username, c2->username) && |
| + | !Curl_timestrcmp(c1->password, c2->password) && |
| + | #endif |
| + | curl_strequal(c1->cipher_list, c2->cipher_list) && |
| + | curl_strequal(c1->cipher_list13, c2->cipher_list13) && |
| + | curl_strequal(c1->curves, c2->curves) && |
| + | curl_strequal(c1->signature_algorithms, c2->signature_algorithms) && |
| + | Curl_safecmp(c1->CRLfile, c2->CRLfile) && |
| + | Curl_safecmp(c1->pinned_key, c2->pinned_key) && |
| + | curl_strequal(c1->cert_type, c2->cert_type) && |
| + | Curl_safecmp(c1->key, c2->key) && |
| + | curl_strequal(c1->key_type, c2->key_type) && |
| + | !Curl_timestrcmp(c1->key_passwd, c2->key_passwd)) |
| + | return TRUE; |
| + | |
| + | return FALSE; |
| + | } |
| + | |
| + | bool Curl_ssl_conn_config_match(struct Curl_easy *data, |
| + | struct connectdata *candidate, |
| + | bool proxy) |
| + | { |
| + | #ifndef CURL_DISABLE_PROXY |
| + | if(proxy) |
| + | return match_ssl_primary_config(data, &data->set.proxy_ssl.primary, |
| + | &candidate->proxy_ssl_config); |
| + | #else |
| + | (void)proxy; |
| + | #endif |
| + | return match_ssl_primary_config(data, &data->set.ssl.primary, |
| + | &candidate->ssl_config); |
| + | } |
| + | |
| + | static bool clone_ssl_primary_config(struct ssl_primary_config *source, |
| + | struct ssl_primary_config *dest) |
| + | { |
| + | DEBUGASSERT(!dest->deep_copy); |
| + | dest->deep_copy = TRUE; |
| + | dest->version = source->version; |
| + | dest->version_max = source->version_max; |
| + | dest->verifypeer = source->verifypeer; |
| + | dest->verifyhost = source->verifyhost; |
| + | dest->verifystatus = source->verifystatus; |
| + | dest->cache_session = source->cache_session; |
| + | dest->ssl_options = source->ssl_options; |
| + | |
| + | CLONE_BLOB(cert_blob); |
| + | CLONE_BLOB(ca_info_blob); |
| + | CLONE_BLOB(issuercert_blob); |
| + | CLONE_STRING(CApath); |
| + | CLONE_STRING(CAfile); |
| + | CLONE_STRING(issuercert); |
| + | CLONE_STRING(cipher_list); |
| + | CLONE_STRING(cipher_list13); |
| + | CLONE_STRING(pinned_key); |
| + | CLONE_STRING(curves); |
| + | CLONE_STRING(signature_algorithms); |
| + | CLONE_STRING(CRLfile); |
| + | /* SSL credentials: client certificate, SRP auth */ |
| + | CLONE_STRING(clientcert); |
| + | CLONE_STRING(cert_type); |
| + | CLONE_STRING(key); |
| + | CLONE_STRING(key_type); |
| + | CLONE_STRING(key_passwd); |
| + | CLONE_BLOB(key_blob); |
| + | #ifdef USE_TLS_SRP |
| + | CLONE_STRING(username); |
| + | CLONE_STRING(password); |
| + | #endif |
| + | |
| + | return TRUE; |
| + | } |
| + | |
| + | CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data, |
| + | struct Curl_peer *origin) |
| + | { |
| + | struct ssl_config_data *sslc = &data->set.ssl; |
| + | #if defined(CURL_CA_PATH) || defined(CURL_CA_BUNDLE) |
| + | struct UserDefined *set = &data->set; |
| + | CURLcode result; |
| + | #endif |
| + | |
| + | if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { |
| + | #if defined(USE_APPLE_SECTRUST) || defined(CURL_CA_NATIVE) |
| + | if(!sslc->custom_capath && !sslc->custom_cafile && !sslc->custom_cablob) |
| + | sslc->native_ca_store = TRUE; |
| + | #endif |
| + | #ifdef CURL_CA_PATH |
| + | if(!sslc->custom_capath && !set->str[STRING_SSL_CAPATH]) { |
| + | result = Curl_setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH); |
| + | if(result) |
| + | return result; |
| + | } |
| + | #endif |
| + | #ifdef CURL_CA_BUNDLE |
| + | if(!sslc->custom_cafile && !set->str[STRING_SSL_CAFILE]) { |
| + | result = Curl_setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE); |
| + | if(result) |
| + | return result; |
| + | } |
| + | #endif |
| + | } |
| + | sslc->primary.CAfile = data->set.str[STRING_SSL_CAFILE]; |
| + | sslc->primary.CRLfile = data->set.str[STRING_SSL_CRLFILE]; |
| + | sslc->primary.CApath = data->set.str[STRING_SSL_CAPATH]; |
| + | sslc->primary.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; |
| + | sslc->primary.cipher_list13 = data->set.str[STRING_SSL_CIPHER13_LIST]; |
| + | sslc->primary.signature_algorithms = |
| + | data->set.str[STRING_SSL_SIGNATURE_ALGORITHMS]; |
| + | sslc->primary.ca_info_blob = data->set.blobs[BLOB_CAINFO]; |
| + | sslc->primary.curves = data->set.str[STRING_SSL_EC_CURVES]; |
| + | /* Maybe these should not be used for another origin. But for |
| + | * backwards compatibility, keep them in. */ |
| + | sslc->primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; |
| + | sslc->primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT]; |
| + | |
| + | if(Curl_peer_equal(data->state.initial_origin, origin)) { |
| + | sslc->primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; |
| + | sslc->primary.cert_blob = data->set.blobs[BLOB_CERT]; |
| + | sslc->primary.cert_type = data->set.str[STRING_CERT_TYPE]; |
| + | sslc->primary.key = data->set.str[STRING_KEY]; |
| + | sslc->primary.key_type = data->set.str[STRING_KEY_TYPE]; |
| + | sslc->primary.key_passwd = data->set.str[STRING_KEY_PASSWD]; |
| + | sslc->primary.clientcert = data->set.str[STRING_CERT]; |
| + | sslc->primary.key_blob = data->set.blobs[BLOB_KEY]; |
| + | #ifdef USE_TLS_SRP |
| + | sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME]; |
| + | sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD]; |
| + | #endif |
| + | } |
| + | else { |
| + | sslc->primary.pinned_key = NULL; |
| + | sslc->primary.cert_blob = NULL; |
| + | sslc->primary.cert_type = NULL; |
| + | sslc->primary.key = NULL; |
| + | sslc->primary.key_type = NULL; |
| + | sslc->primary.key_passwd = NULL; |
| + | sslc->primary.clientcert = NULL; |
| + | sslc->primary.key_blob = NULL; |
| + | #ifdef USE_TLS_SRP |
| + | sslc->primary.username = NULL; |
| + | sslc->primary.password = NULL; |
| + | #endif |
| + | } |
| + | |
| + | #ifndef CURL_DISABLE_PROXY |
| + | sslc = &data->set.proxy_ssl; |
| + | if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) { |
| + | #if defined(USE_APPLE_SECTRUST) || defined(CURL_CA_NATIVE) |
| + | if(!sslc->custom_capath && !sslc->custom_cafile && !sslc->custom_cablob) |
| + | sslc->native_ca_store = TRUE; |
| + | #endif |
| + | #ifdef CURL_CA_PATH |
| + | if(!sslc->custom_capath && !set->str[STRING_SSL_CAPATH_PROXY]) { |
| + | result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_PROXY], |
| + | CURL_CA_PATH); |
| + | if(result) |
| + | return result; |
| + | } |
| + | #endif |
| + | #ifdef CURL_CA_BUNDLE |
| + | if(!sslc->custom_cafile && !set->str[STRING_SSL_CAFILE_PROXY]) { |
| + | result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY], |
| + | CURL_CA_BUNDLE); |
| + | if(result) |
| + | return result; |
| + | } |
| + | #endif |
| + | } |
| + | sslc->primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; |
| + | sslc->primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; |
| + | sslc->primary.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; |
| + | sslc->primary.cipher_list13 = data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; |
| + | sslc->primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]; |
| + | sslc->primary.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; |
| + | sslc->primary.ca_info_blob = data->set.blobs[BLOB_CAINFO_PROXY]; |
| + | sslc->primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; |
| + | sslc->primary.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY]; |
| + | sslc->primary.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; |
| + | sslc->primary.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; |
| + | sslc->primary.key = data->set.str[STRING_KEY_PROXY]; |
| + | sslc->primary.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; |
| + | sslc->primary.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; |
| + | sslc->primary.clientcert = data->set.str[STRING_CERT_PROXY]; |
| + | sslc->primary.key_blob = data->set.blobs[BLOB_KEY_PROXY]; |
| + | #ifdef USE_TLS_SRP |
| + | sslc->primary.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; |
| + | sslc->primary.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; |
| + | #endif |
| + | #endif /* CURL_DISABLE_PROXY */ |
| + | |
| + | return CURLE_OK; |
| + | } |
| + | |
| + | CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data, |
| + | struct connectdata *conn) |
| + | { |
| + | /* Clone "primary" SSL configurations from the easy handle to |
| + | * the connection. They are used for connection cache matching and |
| + | * probably outlive the easy handle */ |
| + | if(!clone_ssl_primary_config(&data->set.ssl.primary, &conn->ssl_config)) |
| + | return CURLE_OUT_OF_MEMORY; |
| + | #ifndef CURL_DISABLE_PROXY |
| + | if(!clone_ssl_primary_config(&data->set.proxy_ssl.primary, |
| + | &conn->proxy_ssl_config)) |
| + | return CURLE_OUT_OF_MEMORY; |
| + | #endif |
| + | return CURLE_OK; |
| + | } |
| + | |
| + | void Curl_ssl_conn_config_cleanup(struct connectdata *conn) |
| + | { |
| + | Curl_ssl_config_cleanup(&conn->ssl_config); |
| + | #ifndef CURL_DISABLE_PROXY |
| + | Curl_ssl_config_cleanup(&conn->proxy_ssl_config); |
| + | #endif |
| + | } |
| + | |
| + | void Curl_ssl_conn_config_update(struct Curl_easy *data, bool for_proxy) |
| + | { |
| + | /* May be called on an easy that has no connection yet */ |
| + | if(data->conn) { |
| + | struct ssl_primary_config *src, *dest; |
| + | #ifndef CURL_DISABLE_PROXY |
| + | src = for_proxy ? &data->set.proxy_ssl.primary : &data->set.ssl.primary; |
| + | dest = for_proxy ? &data->conn->proxy_ssl_config : &data->conn->ssl_config; |
| + | #else |
| + | (void)for_proxy; |
| + | src = &data->set.ssl.primary; |
| + | dest = &data->conn->ssl_config; |
| + | #endif |
| + | dest->verifyhost = src->verifyhost; |
| + | dest->verifypeer = src->verifypeer; |
| + | dest->verifystatus = src->verifystatus; |
| + | } |
| + | } |
| @@ -0,0 +1,125 @@ | |
| + | #ifndef HEADER_CURL_VTLS_CONFIG_H |
| + | #define HEADER_CURL_VTLS_CONFIG_H |
| + | /*************************************************************************** |
| + | * _ _ ____ _ |
| + | * Project ___| | | | _ \| | |
| + | * / __| | | | |_) | | |
| + | * | (__| |_| | _ <| |___ |
| + | * \___|\___/|_| \_\_____| |
| + | * |
| + | * Copyright (C) Daniel Stenberg, <[email protected]>, et al. |
| + | * |
| + | * This software is licensed as described in the file COPYING, which |
| + | * you should have received as part of this distribution. The terms |
| + | * are also available at https://curl.se/docs/copyright.html. |
| + | * |
| + | * You may opt to use, copy, modify, merge, publish, distribute and/or sell |
| + | * copies of the Software, and permit persons to whom the Software is |
| + | * furnished to do so, under the terms of the COPYING file. |
| + | * |
| + | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| + | * KIND, either express or implied. |
| + | * |
| + | * SPDX-License-Identifier: curl |
| + | * |
| + | ***************************************************************************/ |
| + | #include "curl_setup.h" |
| + | |
| + | struct Curl_easy; |
| + | struct connectdata; |
| + | struct Curl_peer; |
| + | |
| + | struct ssl_primary_config { |
| + | char *CApath; /* certificate directory (does not work on Windows) */ |
| + | char *CAfile; /* certificate to verify peer against */ |
| + | char *issuercert; /* optional issuer certificate filename */ |
| + | char *clientcert; |
| + | char *cipher_list; /* list of ciphers to use */ |
| + | char *cipher_list13; /* list of TLS 1.3 cipher suites to use */ |
| + | char *signature_algorithms; /* list of signature algorithms to use */ |
| + | char *pinned_key; |
| + | char *CRLfile; /* CRL to check certificate revocation */ |
| + | char *cert_type; /* format for certificate (default: PEM) */ |
| + | char *key; /* private key filename */ |
| + | char *key_type; /* format for private key (default: PEM) */ |
| + | char *key_passwd; /* plain text private key password */ |
| + | struct curl_blob *cert_blob; |
| + | struct curl_blob *ca_info_blob; |
| + | struct curl_blob *issuercert_blob; |
| + | struct curl_blob *key_blob; |
| + | #ifdef USE_TLS_SRP |
| + | char *username; /* TLS username (for, e.g., SRP) */ |
| + | char *password; /* TLS password (for, e.g., SRP) */ |
| + | #endif |
| + | char *curves; /* list of curves to use */ |
| + | uint32_t version_max; /* max supported version the client wants to use */ |
| + | uint8_t ssl_options; /* the CURLOPT_SSL_OPTIONS bitmask */ |
| + | uint8_t version; /* what version the client wants to use */ |
| + | BIT(verifypeer); /* set TRUE if this is desired */ |
| + | BIT(verifyhost); /* set TRUE if CN/SAN must match hostname */ |
| + | BIT(verifystatus); /* set TRUE if certificate status must be checked */ |
| + | BIT(cache_session); /* cache session or not */ |
| + | BIT(deep_copy); /* members are deep copies, eg. owned here */ |
| + | }; |
| + | |
| + | struct ssl_config_data { |
| + | struct ssl_primary_config primary; |
| + | long certverifyresult; /* result from the certificate verification */ |
| + | curl_ssl_ctx_callback fsslctx; /* function to initialize SSL ctx */ |
| + | void *fsslctxp; /* parameter for call back */ |
| + | BIT(certinfo); /* gather lots of certificate info */ |
| + | BIT(earlydata); /* use TLS 1.3 early data */ |
| + | BIT(enable_beast); /* allow this flaw for interoperability's sake */ |
| + | BIT(no_revoke); /* disable SSL certificate revocation checks */ |
| + | BIT(no_partialchain); /* do not accept partial certificate chains */ |
| + | BIT(revoke_best_effort); /* ignore SSL revocation offline/missing revocation |
| + | list errors */ |
| + | BIT(native_ca_store); /* use the native CA store of operating system */ |
| + | BIT(auto_client_cert); /* automatically locate and use a client |
| + | certificate for authentication (Schannel) */ |
| + | BIT(custom_cafile); /* application has set custom CA file */ |
| + | BIT(custom_capath); /* application has set custom CA path */ |
| + | BIT(custom_cablob); /* application has set custom CA blob */ |
| + | }; |
| + | |
| + | struct ssl_general_config { |
| + | int ca_cache_timeout; /* Certificate store cache timeout (seconds) */ |
| + | }; |
| + | |
| + | void Curl_ssl_config_init(struct ssl_primary_config *sslc); |
| + | void Curl_ssl_config_cleanup(struct ssl_primary_config *sslc); |
| + | |
| + | /** |
| + | * Init the `data->set.ssl` and `data->set.proxy_ssl` for |
| + | * connection matching use. |
| + | */ |
| + | CURLcode Curl_ssl_easy_config_complete(struct Curl_easy *data, |
| + | struct Curl_peer *origin); |
| + | |
| + | /** |
| + | * Init SSL configs (main + proxy) for a new connection from the easy handle. |
| + | */ |
| + | CURLcode Curl_ssl_conn_config_init(struct Curl_easy *data, |
| + | struct connectdata *conn); |
| + | |
| + | /** |
| + | * Free allocated resources in SSL configs (main + proxy) for |
| + | * the given connection. |
| + | */ |
| + | void Curl_ssl_conn_config_cleanup(struct connectdata *conn); |
| + | |
| + | /** |
| + | * Return TRUE iff SSL configuration from `data` is functionally the |
| + | * same as the one on `candidate`. |
| + | * @param proxy match the proxy SSL config or the main one |
| + | */ |
| + | bool Curl_ssl_conn_config_match(struct Curl_easy *data, |
| + | struct connectdata *candidate, |
| + | bool proxy); |
| + | |
| + | /* Update certain connection SSL config flags after they have |
| + | * been changed on the easy handle. Works for `verifypeer`, |
| + | * `verifyhost` and `verifystatus`. */ |
| + | void Curl_ssl_conn_config_update(struct Curl_easy *data, bool for_proxy); |
| + | |
| + | #endif /* HEADER_CURL_VTLS_CONFIG_H */ |
| @@ -41,6 +41,8 @@ static CURLcode test_unit3303(const char *arg) | |
| static char alt_key[] = "other.key"; | |
| static char alt_ktype[] = "DER"; | |
| static char alt_ctype[] = "P12"; | |
| + | struct Curl_peer *origin = NULL; |
| + | CURLcode result; |
| curl_global_init(CURL_GLOBAL_ALL); | |
| curl = curl_easy_init(); | |
| @@ -49,13 +51,24 @@ static CURLcode test_unit3303(const char *arg) | |
| goto unit_test_abort; | |
| } | |
| + | result = Curl_peer_create((struct Curl_easy *)curl, |
| + | &Curl_scheme_https, |
| + | "test.curl.se", 1234, &origin); |
| + | if(result) { |
| + | curl_easy_cleanup(curl); |
| + | curl_global_cleanup(); |
| + | goto unit_test_abort; |
| + | } |
| + | Curl_peer_link(&((struct Curl_easy *)curl)->state.initial_origin, origin); |
| + | |
| curl_easy_setopt(curl, CURLOPT_SSLCERT, "client.pem"); | |
| curl_easy_setopt(curl, CURLOPT_SSLKEY, "client.key"); | |
| curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "secret"); | |
| curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM"); | |
| curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); | |
| - | if(Curl_ssl_easy_config_complete((struct Curl_easy *)curl)) { |
| + | if(Curl_ssl_easy_config_complete((struct Curl_easy *)curl, origin)) { |
| + | Curl_peer_unlink(&origin); |
| curl_easy_cleanup(curl); | |
| curl_global_cleanup(); | |
| goto unit_test_abort; | |
| @@ -66,6 +79,7 @@ static CURLcode test_unit3303(const char *arg) | |
| if(conn) | |
| Curl_ssl_conn_config_cleanup(conn); | |
| curlx_free(conn); | |
| + | Curl_peer_unlink(&origin); |
| curl_easy_cleanup(curl); | |
| curl_global_cleanup(); | |
| goto unit_test_abort; | |
| @@ -118,6 +132,7 @@ static CURLcode test_unit3303(const char *arg) | |
| Curl_ssl_conn_config_cleanup(conn); | |
| curlx_free(conn); | |
| curl_easy_cleanup(curl); | |
| + | Curl_peer_unlink(&origin); |
| curl_global_cleanup(); | |
| #endif /* USE_SSL */ | |