From 28ac6220e9edd8c15eabeaadcefb0f10109e618b Mon Sep 17 00:00:00 2001 From: Sergey Markelov Date: Tue, 12 Mar 2024 17:21:06 -0700 Subject: [PATCH] mbedtls: support CURLOPT_CERTINFO --- lib/vtls/mbedtls.c | 67 +++++++++++++++++++++++++++++++++++++++++++++ lib/vtls/x509asn1.c | 6 ++-- lib/vtls/x509asn1.h | 3 +- tests/data/test3102 | 1 - 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index 3fefb612bd1af3..5b767cacca7b57 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -73,6 +73,7 @@ #include "mbedtls.h" #include "vtls.h" #include "vtls_int.h" +#include "x509asn1.h" #include "parsedate.h" #include "connect.h" /* for the connect timeout */ #include "select.h" @@ -80,6 +81,7 @@ #include "mbedtls_threadlock.h" #include "strdup.h" + /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -744,6 +746,64 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data) return CURLE_OK; } +static int count_server_cert(const mbedtls_x509_crt *peercert) +{ + int count = 1; + + DEBUGASSERT(peercert); + + while(peercert->next) { + ++count; + peercert = peercert->next; + } + return count; +} + +static CURLcode collect_server_cert_single(struct Curl_easy *data, + const mbedtls_x509_crt *server_cert, + int idx) +{ + CURLcode result; + const char *beg, *end; + + DEBUGASSERT(server_cert); + + beg = (const char *)server_cert->raw.p; + end = beg + server_cert->raw.len; + result = Curl_extract_certinfo(data, idx, beg, end); + return result; +} + +static CURLcode collect_server_cert(struct Curl_cfilter *cf, + struct Curl_easy *data, + const struct mbedtls_x509_crt *peercert) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS + const bool show_verbose_server_cert = data->set.verbose; +#else + const bool show_verbose_server_cert = false; +#endif + struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data); + CURLcode result = ssl_config->certinfo ? + CURLE_PEER_FAILED_VERIFICATION : CURLE_OK; + int i, count; + + if(!show_verbose_server_cert && !ssl_config->certinfo) + return CURLE_OK; + + if(!peercert) + return result; + + count = count_server_cert(peercert); + if(ssl_config->certinfo) + result = Curl_ssl_init_certinfo(data, count); + for(i = 0 ; !result && peercert ; i++) { + result = collect_server_cert_single(data, peercert, i); + peercert = peercert->next; + } + return result; +} + static CURLcode mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) { @@ -807,6 +867,12 @@ mbed_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data) peercert = mbedtls_ssl_get_peer_cert(&backend->ssl); + if(peercert) { + const CURLcode result = collect_server_cert(cf, data, peercert); + if(result) + return result; + } + if(peercert && data->set.verbose) { #ifndef MBEDTLS_X509_REMOVE_INFO const size_t bufsize = 16384; @@ -1317,6 +1383,7 @@ const struct Curl_ssl Curl_ssl_mbedtls = { SSLSUPP_CA_PATH | SSLSUPP_CAINFO_BLOB | + SSLSUPP_CERTINFO | SSLSUPP_PINNEDPUBKEY | SSLSUPP_SSL_CTX | SSLSUPP_HTTPS_PROXY, diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c index da079361d2ccca..73e6544aeaa7a3 100644 --- a/lib/vtls/x509asn1.c +++ b/lib/vtls/x509asn1.c @@ -25,13 +25,15 @@ #include "curl_setup.h" #if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \ - defined(USE_SCHANNEL) || defined(USE_SECTRANSP) + defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ + defined(USE_MBEDTLS) #if defined(USE_WOLFSSL) || defined(USE_SCHANNEL) #define WANT_PARSEX509 /* uses Curl_parseX509() */ #endif -#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) +#if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ + defined(USE_MBEDTLS) #define WANT_EXTRACT_CERTINFO /* uses Curl_extract_certinfo() */ #define WANT_PARSEX509 /* ... uses Curl_parseX509() */ #endif diff --git a/lib/vtls/x509asn1.h b/lib/vtls/x509asn1.h index 23a67b828a6ed9..5844460467ccef 100644 --- a/lib/vtls/x509asn1.h +++ b/lib/vtls/x509asn1.h @@ -28,7 +28,8 @@ #include "curl_setup.h" #if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \ - defined(USE_SCHANNEL) || defined(USE_SECTRANSP) + defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ + defined(USE_MBEDTLS) #include "cfilters.h" #include "urldata.h" diff --git a/tests/data/test3102 b/tests/data/test3102 index 4df7ba9c1f6cf2..7635e65432760d 100644 --- a/tests/data/test3102 +++ b/tests/data/test3102 @@ -20,7 +20,6 @@ HTTP GET SSL !bearssl -!mbedtls !rustls !wolfssl