From: Yedaya Katsman Date: Mon, 24 Feb 2025 19:40:19 +0000 (+0200) Subject: rustls: add support for CERTINFO X-Git-Tag: curl-8_13_0~358 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a55b5b7c62c621618df6f46d47a534659c40cce7;p=thirdparty%2Fcurl.git rustls: add support for CERTINFO This allows you to use the `certs` and `num_certs` writeout variables in the curl tool, and getting information about the server certificates using CURLINFO_CERTINFO. Closes #16459 --- diff --git a/docs/cmdline-opts/write-out.md b/docs/cmdline-opts/write-out.md index bae185b1b9..f1cca60ad2 100644 --- a/docs/cmdline-opts/write-out.md +++ b/docs/cmdline-opts/write-out.md @@ -62,7 +62,7 @@ The variables available are: ## `certs` Output the certificate chain with details. Supported only by the OpenSSL, -GnuTLS, Schannel and Secure Transport backends. (Added in 7.88.0) +GnuTLS, Schannel, Rustls, and Secure Transport backends. (Added in 7.88.0) ## `conn_id` The connection identifier last used by the transfer. The connection id is @@ -128,7 +128,7 @@ The http method used in the most recent HTTP request. (Added in 7.72.0) ## `num_certs` Number of server certificates received in the TLS handshake. Supported only by -the OpenSSL, GnuTLS, Schannel and Secure Transport backends. +the OpenSSL, GnuTLS, Schannel, Rustls and Secure Transport backends. (Added in 7.88.0) ## `num_connects` diff --git a/docs/libcurl/opts/CURLINFO_CERTINFO.md b/docs/libcurl/opts/CURLINFO_CERTINFO.md index 39f403ec7e..0bf6ab0dc1 100644 --- a/docs/libcurl/opts/CURLINFO_CERTINFO.md +++ b/docs/libcurl/opts/CURLINFO_CERTINFO.md @@ -15,6 +15,7 @@ TLS-backend: - GnuTLS - Schannel - Secure Transport + - rustls Added-in: 7.19.1 --- diff --git a/docs/libcurl/opts/CURLOPT_CERTINFO.md b/docs/libcurl/opts/CURLOPT_CERTINFO.md index 2ac7f89966..755367b3c8 100644 --- a/docs/libcurl/opts/CURLOPT_CERTINFO.md +++ b/docs/libcurl/opts/CURLOPT_CERTINFO.md @@ -17,6 +17,7 @@ TLS-backend: - GnuTLS - Schannel - Secure Transport + - rustls Added-in: 7.19.1 --- diff --git a/lib/vtls/rustls.c b/lib/vtls/rustls.c index 450a0bb9c6..529d6b9c1c 100644 --- a/lib/vtls/rustls.c +++ b/lib/vtls/rustls.c @@ -43,6 +43,7 @@ #include "connect.h" /* for the connect timeout */ #include "cipher_suite.h" #include "rand.h" +#include "x509asn1.h" struct rustls_ssl_backend_data { @@ -845,6 +846,43 @@ cr_connect(struct Curl_cfilter *cf, infof(data, "rustls: handshake complete, %s, cipher: %s", ver, buf); } + if(data->set.ssl.certinfo) { + size_t num_certs = 0; + while(rustls_connection_get_peer_certificate(rconn, (int)num_certs)) { + num_certs++; + } + result = Curl_ssl_init_certinfo(data, (int)num_certs); + if(result) + return result; + for(size_t i = 0; i < num_certs; i++) { + const rustls_certificate *cert; + const unsigned char *der_data; + size_t der_len; + rustls_result rresult = RUSTLS_RESULT_OK; + cert = rustls_connection_get_peer_certificate(rconn, i); + DEBUGASSERT(cert); /* Should exist since we counted already */ + rresult = rustls_certificate_get_der(cert, &der_data, &der_len); + if(rresult != RUSTLS_RESULT_OK) { + char errorbuf[255]; + size_t errorlen; + rustls_error(rresult, errorbuf, sizeof(errorbuf), &errorlen); + failf(data, + "Failed getting DER of server certificate #%ld: %.*s", i, + (int)errorlen, errorbuf); + return map_error(rresult); + } + { + const char *beg; + const char *end; + beg = (const char *)der_data; + end = (const char *)(der_data + der_len); + result = Curl_extract_certinfo(data, (int)i, beg, end); + if(result) + return result; + } + } + } + connssl->state = ssl_connection_complete; *done = TRUE; return CURLE_OK; @@ -1011,7 +1049,8 @@ const struct Curl_ssl Curl_ssl_rustls = { SSLSUPP_CAINFO_BLOB | /* supports */ SSLSUPP_HTTPS_PROXY | SSLSUPP_CIPHER_LIST | - SSLSUPP_TLS13_CIPHERSUITES, + SSLSUPP_TLS13_CIPHERSUITES | + SSLSUPP_CERTINFO, sizeof(struct rustls_ssl_backend_data), NULL, /* init */ diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c index d10dd09578..62f2a3cf41 100644 --- a/lib/vtls/x509asn1.c +++ b/lib/vtls/x509asn1.c @@ -26,15 +26,15 @@ #if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \ defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ - defined(USE_MBEDTLS) + defined(USE_MBEDTLS) || defined(USE_RUSTLS) #if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ - defined(USE_MBEDTLS) || defined(USE_WOLFSSL) + defined(USE_MBEDTLS) || defined(USE_WOLFSSL) || defined(USE_RUSTLS) #define WANT_PARSEX509 /* uses Curl_parseX509() */ #endif #if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ - defined(USE_MBEDTLS) + defined(USE_MBEDTLS) || defined(USE_RUSTLS) #define WANT_EXTRACT_CERTINFO /* uses Curl_extract_certinfo() */ #endif @@ -1277,4 +1277,5 @@ done: #endif /* WANT_EXTRACT_CERTINFO */ -#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP */ +#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP + or USE_MBEDTLS or USE_RUSTLS */ diff --git a/lib/vtls/x509asn1.h b/lib/vtls/x509asn1.h index 5de8f18e9c..e1abff06c8 100644 --- a/lib/vtls/x509asn1.h +++ b/lib/vtls/x509asn1.h @@ -29,7 +29,7 @@ #if defined(USE_GNUTLS) || defined(USE_WOLFSSL) || \ defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ - defined(USE_MBEDTLS) + defined(USE_MBEDTLS) || defined(USE_RUSTLS) #include "cfilters.h" #include "urldata.h" @@ -80,7 +80,7 @@ CURLcode Curl_verifyhost(struct Curl_cfilter *cf, struct Curl_easy *data, #ifdef UNITTESTS #if defined(USE_GNUTLS) || defined(USE_SCHANNEL) || defined(USE_SECTRANSP) || \ - defined(USE_MBEDTLS) + defined(USE_MBEDTLS) || defined(USE_RUSTLS) /* used by unit1656.c */ CURLcode Curl_x509_GTime2str(struct dynbuf *store, @@ -91,5 +91,6 @@ CURLcode Curl_x509_getASN1Element(struct Curl_asn1Element *elem, #endif #endif -#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP */ +#endif /* USE_GNUTLS or USE_WOLFSSL or USE_SCHANNEL or USE_SECTRANSP + or USE_MBEDTLS or USE_RUSTLS */ #endif /* HEADER_CURL_X509ASN1_H */ diff --git a/tests/data/test3102 b/tests/data/test3102 index 7635e65432..013d0c73ef 100644 --- a/tests/data/test3102 +++ b/tests/data/test3102 @@ -20,7 +20,6 @@ HTTP GET SSL !bearssl -!rustls !wolfssl diff --git a/tests/data/test417 b/tests/data/test417 index 50f4b479b4..6c5dfe5bfe 100644 --- a/tests/data/test417 +++ b/tests/data/test417 @@ -25,7 +25,6 @@ SSL !wolfssl !bearssl !mbedtls -!rustls http