diff options
author | Curl Upstream <curl-library@cool.haxx.se> | 2021-09-14 07:02:52 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2021-09-15 19:28:31 (GMT) |
commit | 386467c9dc939cd20711c451dd7d60341fd0e802 (patch) | |
tree | 73d1b75e65ec941fff25153f1a10b88dee1e6c2c /lib/vtls/mbedtls.c | |
parent | 18b2a8d7604f3aced9c93220806851f96e231f36 (diff) | |
download | CMake-386467c9dc939cd20711c451dd7d60341fd0e802.zip CMake-386467c9dc939cd20711c451dd7d60341fd0e802.tar.gz CMake-386467c9dc939cd20711c451dd7d60341fd0e802.tar.bz2 |
curl 2021-09-14 (8e82f2a0)
Code extracted from:
https://github.com/curl/curl.git
at commit 8e82f2a04a238c54ba91e553e9a8452e6d405965 (curl-7_79_0).
Diffstat (limited to 'lib/vtls/mbedtls.c')
-rw-r--r-- | lib/vtls/mbedtls.c | 202 |
1 files changed, 142 insertions, 60 deletions
diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index 3a0be0f..780d13e 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -41,7 +41,9 @@ #include <mbedtls/net.h> #endif #include <mbedtls/ssl.h> +#if MBEDTLS_VERSION_NUMBER < 0x03000000 #include <mbedtls/certs.h> +#endif #include <mbedtls/x509.h> #include <mbedtls/error.h> @@ -89,6 +91,10 @@ struct ssl_backend_data { #define THREADING_SUPPORT #endif +#ifndef MBEDTLS_ERROR_C +#define mbedtls_strerror(a,b,c) b[0] = 0 +#endif + #if defined(THREADING_SUPPORT) static mbedtls_entropy_context ts_entropy; @@ -179,6 +185,17 @@ static Curl_send mbed_send; static CURLcode mbedtls_version_from_curl(int *mbedver, long version) { +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 + switch(version) { + case CURL_SSLVERSION_TLSv1_0: + case CURL_SSLVERSION_TLSv1_1: + case CURL_SSLVERSION_TLSv1_2: + *mbedver = MBEDTLS_SSL_MINOR_VERSION_3; + return CURLE_OK; + case CURL_SSLVERSION_TLSv1_3: + break; + } +#else switch(version) { case CURL_SSLVERSION_TLSv1_0: *mbedver = MBEDTLS_SSL_MINOR_VERSION_1; @@ -192,6 +209,8 @@ static CURLcode mbedtls_version_from_curl(int *mbedver, long version) case CURL_SSLVERSION_TLSv1_3: break; } +#endif + return CURLE_SSL_CONNECT_ERROR; } @@ -201,8 +220,13 @@ set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn, { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 + int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_3; + int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_3; +#else int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1; int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1; +#endif long ssl_version = SSL_CONN_CONFIG(version); long ssl_version_max = SSL_CONN_CONFIG(version_max); CURLcode result = CURLE_OK; @@ -250,12 +274,14 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, const bool verifypeer = SSL_CONN_CONFIG(verifypeer); const char * const ssl_capath = SSL_CONN_CONFIG(CApath); char * const ssl_cert = SSL_SET_OPTION(primary.clientcert); + const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob); const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile); const char * const hostname = SSL_HOST_NAME(); +#ifndef CURL_DISABLE_VERBOSE_STRINGS const long int port = SSL_HOST_PORT(); +#endif int ret = -1; char errorbuf[128]; - errorbuf[0] = 0; if((SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) || (SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)) { @@ -270,9 +296,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, entropy_func_mutex, &ts_entropy, NULL, 0); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s", -ret, errorbuf); } @@ -283,9 +307,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_ctr_drbg_seed(&backend->ctr_drbg, mbedtls_entropy_func, &backend->entropy, NULL, 0); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s", -ret, errorbuf); } @@ -298,9 +320,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_x509_crt_parse_file(&backend->cacert, ssl_cafile); if(ret<0) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s", ssl_cafile, -ret, errorbuf); @@ -313,9 +333,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_x509_crt_parse_path(&backend->cacert, ssl_capath); if(ret<0) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s", ssl_capath, -ret, errorbuf); @@ -331,9 +349,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_x509_crt_parse_file(&backend->clicert, ssl_cert); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s", ssl_cert, -ret, errorbuf); @@ -341,27 +357,72 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, } } - /* Load the client private key */ - mbedtls_pk_init(&backend->pk); - - if(SSL_SET_OPTION(key)) { - ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key), - SSL_SET_OPTION(key_passwd)); - if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) || - mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY))) - ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; + if(ssl_cert_blob) { + const unsigned char *blob_data = + (const unsigned char *)ssl_cert_blob->data; + ret = mbedtls_x509_crt_parse(&backend->clicert, blob_data, + ssl_cert_blob->len); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s", SSL_SET_OPTION(key), -ret, errorbuf); - return CURLE_SSL_CERTPROBLEM; } } + /* Load the client private key */ + mbedtls_pk_init(&backend->pk); + + if(SSL_SET_OPTION(key) || SSL_SET_OPTION(key_blob)) { + if(SSL_SET_OPTION(key)) { +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 + ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key), + SSL_SET_OPTION(key_passwd), + mbedtls_ctr_drbg_random, + &backend->ctr_drbg); +#else + ret = mbedtls_pk_parse_keyfile(&backend->pk, SSL_SET_OPTION(key), + SSL_SET_OPTION(key_passwd)); +#endif + + if(ret) { + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s", + SSL_SET_OPTION(key), -ret, errorbuf); + return CURLE_SSL_CERTPROBLEM; + } + } + else { + const struct curl_blob *ssl_key_blob = SSL_SET_OPTION(key_blob); + const unsigned char *key_data = + (const unsigned char *)ssl_key_blob->data; + const char *passwd = SSL_SET_OPTION(key_passwd); +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 + ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len, + (const unsigned char *)passwd, + passwd ? strlen(passwd) : 0, + mbedtls_ctr_drbg_random, + &backend->ctr_drbg); +#else + ret = mbedtls_pk_parse_key(&backend->pk, key_data, ssl_key_blob->len, + (const unsigned char *)passwd, + passwd ? strlen(passwd) : 0); +#endif + + if(ret) { + mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); + failf(data, "Error parsing private key - mbedTLS: (-0x%04X) %s", + -ret, errorbuf); + return CURLE_SSL_CERTPROBLEM; + } + } + + if(ret == 0 && !(mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_RSA) || + mbedtls_pk_can_do(&backend->pk, MBEDTLS_PK_ECKEY))) + ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; + } + /* Load the CRL */ mbedtls_x509_crl_init(&backend->crl); @@ -369,9 +430,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, ret = mbedtls_x509_crl_parse_file(&backend->crl, ssl_crlfile); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s", ssl_crlfile, -ret, errorbuf); @@ -379,7 +438,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, } } - infof(data, "mbedTLS: Connecting to %s:%ld\n", hostname, port); + infof(data, "mbedTLS: Connecting to %s:%ld", hostname, port); mbedtls_ssl_config_init(&backend->config); @@ -404,10 +463,12 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, switch(SSL_CONN_CONFIG(version)) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: +#if MBEDTLS_VERSION_NUMBER < 0x03000000 mbedtls_ssl_conf_min_version(&backend->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1); - infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n"); + infof(data, "mbedTLS: Set min SSL version to TLS 1.0"); break; +#endif case CURL_SSLVERSION_TLSv1_0: case CURL_SSLVERSION_TLSv1_1: case CURL_SSLVERSION_TLSv1_2: @@ -459,7 +520,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret); return CURLE_SSL_CONNECT_ERROR; } - infof(data, "mbedTLS re-using session\n"); + infof(data, "mbedTLS re-using session"); } Curl_ssl_sessionid_unlock(data); } @@ -468,7 +529,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, &backend->cacert, &backend->crl); - if(SSL_SET_OPTION(key)) { + if(SSL_SET_OPTION(key) || SSL_SET_OPTION(key_blob)) { mbedtls_ssl_conf_own_cert(&backend->config, &backend->clicert, &backend->pk); } @@ -497,7 +558,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn, return CURLE_SSL_CONNECT_ERROR; } for(p = &backend->protocols[0]; *p; ++p) - infof(data, "ALPN, offering %s\n", *p); + infof(data, "ALPN, offering %s", *p); } #endif @@ -553,18 +614,14 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, } else if(ret) { char errorbuf[128]; - errorbuf[0] = 0; -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s", -ret, errorbuf); return CURLE_SSL_CONNECT_ERROR; } - infof(data, "mbedTLS: Handshake complete, cipher is %s\n", - mbedtls_ssl_get_ciphersuite(&backend->ssl) - ); + infof(data, "mbedTLS: Handshake complete, cipher is %s", + mbedtls_ssl_get_ciphersuite(&backend->ssl)); ret = mbedtls_ssl_get_verify_result(&backend->ssl); @@ -601,9 +658,9 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, return CURLE_OUT_OF_MEMORY; if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0) - infof(data, "Dumping cert info:\n%s\n", buffer); + infof(data, "Dumping cert info: %s", buffer); else - infof(data, "Unable to dump certificate information.\n"); + infof(data, "Unable to dump certificate information"); free(buffer); } @@ -611,10 +668,15 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, if(pinnedpubkey) { int size; CURLcode result; - mbedtls_x509_crt *p; - unsigned char pubkey[PUB_DER_MAX_BYTES]; + mbedtls_x509_crt *p = NULL; + unsigned char *pubkey = NULL; +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 + if(!peercert || !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p) || + !peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len)) { +#else if(!peercert || !peercert->raw.p || !peercert->raw.len) { +#endif failf(data, "Failed due to missing peer certificate"); return CURLE_SSL_PINNEDPUBKEYNOTMATCH; } @@ -624,39 +686,54 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, if(!p) return CURLE_OUT_OF_MEMORY; + pubkey = malloc(PUB_DER_MAX_BYTES); + + if(!pubkey) { + result = CURLE_OUT_OF_MEMORY; + goto pinnedpubkey_error; + } + mbedtls_x509_crt_init(p); /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der needs a non-const key, for now. https://github.com/ARMmbed/mbedtls/issues/396 */ +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 + if(mbedtls_x509_crt_parse_der(p, + peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(p), + peercert->MBEDTLS_PRIVATE(raw).MBEDTLS_PRIVATE(len))) { +#else if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { +#endif failf(data, "Failed copying peer certificate"); - mbedtls_x509_crt_free(p); - free(p); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + goto pinnedpubkey_error; } +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 + size = mbedtls_pk_write_pubkey_der(&p->MBEDTLS_PRIVATE(pk), pubkey, + PUB_DER_MAX_BYTES); +#else size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); +#endif if(size <= 0) { failf(data, "Failed copying public key from peer certificate"); - mbedtls_x509_crt_free(p); - free(p); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; + result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; + goto pinnedpubkey_error; } /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */ result = Curl_pin_peer_pubkey(data, pinnedpubkey, &pubkey[PUB_DER_MAX_BYTES - size], size); + pinnedpubkey_error: + mbedtls_x509_crt_free(p); + free(p); + free(pubkey); if(result) { - mbedtls_x509_crt_free(p); - free(p); return result; } - - mbedtls_x509_crt_free(p); - free(p); } #ifdef HAS_ALPN @@ -664,7 +741,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, const char *next_protocol = mbedtls_ssl_get_alpn_protocol(&backend->ssl); if(next_protocol) { - infof(data, "ALPN, server accepted to use %s\n", next_protocol); + infof(data, "ALPN, server accepted to use %s", next_protocol); #ifdef USE_NGHTTP2 if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, NGHTTP2_PROTO_VERSION_ID_LEN) && @@ -679,7 +756,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, } } else { - infof(data, "ALPN, server did not agree to a protocol\n"); + infof(data, "ALPN, server did not agree to a protocol"); } Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ? BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE); @@ -687,7 +764,7 @@ mbed_connect_step2(struct Curl_easy *data, struct connectdata *conn, #endif connssl->connecting_state = ssl_connect_3; - infof(data, "SSL connected\n"); + infof(data, "SSL connected"); return CURLE_OK; } @@ -775,8 +852,13 @@ static void mbedtls_close(struct Curl_easy *data, { struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_backend_data *backend = connssl->backend; - + char buf[32]; (void) data; + + /* Maybe the server has already sent a close notify alert. + Read it to avoid an RST on the TCP connection. */ + (void)mbedtls_ssl_read(&backend->ssl, (unsigned char *)buf, sizeof(buf)); + mbedtls_pk_free(&backend->pk); mbedtls_x509_crt_free(&backend->clicert); mbedtls_x509_crt_free(&backend->cacert); @@ -844,15 +926,12 @@ static CURLcode mbedtls_random(struct Curl_easy *data, mbedtls_ctr_drbg_context ctr_drbg; mbedtls_entropy_init(&ctr_entropy); mbedtls_ctr_drbg_init(&ctr_drbg); - errorbuf[0] = 0; ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &ctr_entropy, NULL, 0); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s", -ret, errorbuf); } @@ -860,9 +939,7 @@ static CURLcode mbedtls_random(struct Curl_easy *data, ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length); if(ret) { -#ifdef MBEDTLS_ERROR_C mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s", -ret, errorbuf); } @@ -1046,12 +1123,17 @@ static CURLcode mbedtls_sha256sum(const unsigned char *input, unsigned char *sha256sum, size_t sha256len UNUSED_PARAM) { + /* TODO: explain this for different mbedtls 2.x vs 3 version */ (void)sha256len; #if MBEDTLS_VERSION_NUMBER < 0x02070000 mbedtls_sha256(input, inputlen, sha256sum, 0); #else /* returns 0 on success, otherwise failure */ +#if MBEDTLS_VERSION_NUMBER >= 0x03000000 + if(mbedtls_sha256(input, inputlen, sha256sum, 0) != 0) +#else if(mbedtls_sha256_ret(input, inputlen, sha256sum, 0) != 0) +#endif return CURLE_BAD_FUNCTION_ARGUMENT; #endif return CURLE_OK; |