From e1781a0e15c5f6b6c1c1df9a5d9cac98ed1bd2d2 Mon Sep 17 00:00:00 2001 From: Sergey Markelov Date: Tue, 12 Mar 2024 17:21:06 -0700 Subject: [PATCH 1/2] mbedtls: support CURLOPT_CERTINFO --- lib/vtls/mbedtls.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ lib/vtls/x509asn1.c | 6 +++-- lib/vtls/x509asn1.h | 3 ++- tests/data/test3102 | 1 - 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index 875f3319dcf73a..776a9ce3fbffb8 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -75,6 +75,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" @@ -896,6 +897,60 @@ 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) +{ + const char *beg, *end; + + DEBUGASSERT(server_cert); + + beg = (const char *)server_cert->raw.p; + end = beg + server_cert->raw.len; + return Curl_extract_certinfo(data, idx, beg, end); +} + +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 = CURLE_PEER_FAILED_VERIFICATION; + int i, count; + + if(!show_verbose_server_cert && !ssl_config->certinfo) + return CURLE_OK; + + if(!peercert) + return result; + + count = count_server_cert(peercert); + 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) { @@ -972,6 +1027,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; @@ -1488,6 +1549,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 4564ea958aea2d..55345c3eb5adde 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 From c94fe5ef6d52acd42eb636bc2ecf8ad3cad12052 Mon Sep 17 00:00:00 2001 From: Sergey Markelov Date: Thu, 23 May 2024 19:04:08 -0700 Subject: [PATCH 2/2] mbedtls: update manual about CURLOPT_CERTINFO/CURLINFO_CERTINFO support --- docs/libcurl/opts/CURLINFO_CERTINFO.md | 7 ++++--- docs/libcurl/opts/CURLOPT_CERTINFO.md | 1 + tests/test1275.pl | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/libcurl/opts/CURLINFO_CERTINFO.md b/docs/libcurl/opts/CURLINFO_CERTINFO.md index 633beed17bee3c..203e39ccddd6b8 100644 --- a/docs/libcurl/opts/CURLINFO_CERTINFO.md +++ b/docs/libcurl/opts/CURLINFO_CERTINFO.md @@ -93,9 +93,10 @@ See also the *certinfo.c* example. # AVAILABILITY -This option is only working in libcurl built with OpenSSL, GnuTLS, Schannel or -Secure Transport. GnuTLS support added in 7.42.0. Schannel support added in -7.50.0. Secure Transport support added in 7.79.0. +This option is only working in libcurl built with OpenSSL, GnuTLS, Schannel, +Secure Transport or mbedTLS. GnuTLS support added in 7.42.0. Schannel support +added in 7.50.0. Secure Transport support added in 7.79.0. mbedTLS support added +in 8.9.0. Added in 7.19.1 diff --git a/docs/libcurl/opts/CURLOPT_CERTINFO.md b/docs/libcurl/opts/CURLOPT_CERTINFO.md index 71339cd0322dbb..5aaa219b90b2d7 100644 --- a/docs/libcurl/opts/CURLOPT_CERTINFO.md +++ b/docs/libcurl/opts/CURLOPT_CERTINFO.md @@ -85,6 +85,7 @@ int main(void) # AVAILABILITY Schannel support added in 7.50.0. Secure Transport support added in 7.79.0. +mbedTLS support added in 8.9.0. # RETURN VALUE diff --git a/tests/test1275.pl b/tests/test1275.pl index 47ce7995789f07..353391d2f3d9f7 100755 --- a/tests/test1275.pl +++ b/tests/test1275.pl @@ -32,6 +32,7 @@ my %accepted=('curl' => 1, 'libcurl' => 1, 'macOS' => 1, + 'mbedTLS' => 1, 'c-ares' => 1); sub checkfile {