]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
rustls: add support for CERTINFO
authorYedaya Katsman <yedaya.ka@gmail.com>
Mon, 24 Feb 2025 19:40:19 +0000 (21:40 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 25 Feb 2025 06:59:39 +0000 (07:59 +0100)
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

docs/cmdline-opts/write-out.md
docs/libcurl/opts/CURLINFO_CERTINFO.md
docs/libcurl/opts/CURLOPT_CERTINFO.md
lib/vtls/rustls.c
lib/vtls/x509asn1.c
lib/vtls/x509asn1.h
tests/data/test3102
tests/data/test417

index bae185b1b9ad73eb2434f253953a8c42d855a2ae..f1cca60ad251d415e131da1e5483ff95784b9624 100644 (file)
@@ -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`
index 39f403ec7e94372cd2bae0fdcae96940ec5892f4..0bf6ab0dc17cc3d874b474233732b6f50580e0ac 100644 (file)
@@ -15,6 +15,7 @@ TLS-backend:
   - GnuTLS
   - Schannel
   - Secure Transport
+  - rustls
 Added-in: 7.19.1
 ---
 
index 2ac7f899665e44352e6706252f014dac2902c348..755367b3c8c712fe1bbd6c9ae1dc7bd7749c98b4 100644 (file)
@@ -17,6 +17,7 @@ TLS-backend:
   - GnuTLS
   - Schannel
   - Secure Transport
+  - rustls
 Added-in: 7.19.1
 ---
 
index 450a0bb9c6cbb91714d5cf85a68577839fab9ad9..529d6b9c1cb3c0ff96d56f384e21ecacd469bf19 100644 (file)
@@ -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 */
index d10dd0957895a1f68ce65324eea783b6f0d7eaa9..62f2a3cf41201d76aa94d879ffdf30f98946d364 100644 (file)
 
 #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 */
index 5de8f18e9ca62b86b45e6664139f3ec17b972f22..e1abff06c8dcaffabae89f08ef930c8dce82bc2c 100644 (file)
@@ -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 */
index 7635e65432760d30b111055c0eab03818e411452..013d0c73efa43cb183532a574ec21187dc653eb1 100644 (file)
@@ -20,7 +20,6 @@ HTTP GET
 <features>
 SSL
 !bearssl
-!rustls
 !wolfssl
 </features>
 <server>
index 50f4b479b4335d4028f1ae563a3e183eb11ab3e2..6c5dfe5bfe84bbbbb715b499c6c593c9d641dd21 100644 (file)
@@ -25,7 +25,6 @@ SSL
 !wolfssl
 !bearssl
 !mbedtls
-!rustls
 </features>
 <server>
 http