summaryrefslogtreecommitdiffstats
path: root/lib/vtls/mbedtls.c
diff options
context:
space:
mode:
authorCurl Upstream <curl-library@cool.haxx.se>2021-09-14 07:02:52 (GMT)
committerBrad King <brad.king@kitware.com>2021-09-15 19:28:31 (GMT)
commit386467c9dc939cd20711c451dd7d60341fd0e802 (patch)
tree73d1b75e65ec941fff25153f1a10b88dee1e6c2c /lib/vtls/mbedtls.c
parent18b2a8d7604f3aced9c93220806851f96e231f36 (diff)
downloadCMake-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.c202
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;