]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
vtls/rustls: support strong CSRNG data
authorDaniel McCarney <daniel@binaryparadox.net>
Thu, 12 Sep 2024 16:38:51 +0000 (12:38 -0400)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 13 Sep 2024 12:11:56 +0000 (14:11 +0200)
Now that the curl rustls vtls backend is using rustls 0.14 we can
address the weak random situation by using
`rustls_default_crypto_provider_random()` to provide a `Curl_ssl`
`random` callback that fills the provided buffer with cryptographically
secure random data.

The mentions in `docs/` about weak RNG when using rustls are removed as
they are no longer applicable.

Closes #14889

docs/EXPERIMENTAL.md
docs/RUSTLS.md
lib/rand.c
lib/rand.h
lib/vtls/rustls.c

index b1e3710ed7ed59ca3f5295cb73085d6271bf3076..7a9de9a810dae954fa321682d03ae4512467da89 100644 (file)
@@ -56,7 +56,6 @@ Graduation requirements:
 Graduation requirements:
 
 - a reasonable expectation of a stable API going forward.
-- a sufficient approach to avoid using weak random numbers
 
 ### WebSocket
 
index e91a090a7ca3d22d85d850613eb3ce34bd804a8d..47af01a53471cceb97f9cf0701119e7af738816a 100644 (file)
@@ -34,18 +34,3 @@ See the [rustls-ffi README] for more information on cryptography providers and
 their build/platform requirements.
 
 [rustls-ffi README]: https://github.com/rustls/rustls-ffi/blob/main/README.md#cryptography-provide
-
-## Randomness
-
-Every TLS libcurl curl supports - *except* Rustls - provides a function for
-curl to extract cryptographically safe random numbers with.
-
-When you build curl with Rustls, curl uses its own internal attempts to get a
-decent random value:
-
-1. Windows specific APIs
-2. arc4random
-
-If neither of those are present, then curl using Rustls falls back to **weak
-pseudo-random values**, and thus weakening several curl authentication
-implementations.
index 3c1b88db73705245f873d1c61586865bb22e0455..63aebdc8f9b6896265b1d07e4898dabce3964742 100644 (file)
@@ -100,9 +100,9 @@ CURLcode Curl_win32_random(unsigned char *entropy, size_t length)
 }
 #endif
 
-#if !defined(USE_SSL) || defined(USE_RUSTLS)
+#if !defined(USE_SSL)
 /* ---- possibly non-cryptographic version following ---- */
-CURLcode Curl_weak_random(struct Curl_easy *data,
+static CURLcode weak_random(struct Curl_easy *data,
                           unsigned char *entropy,
                           size_t length) /* always 4, size of int */
 {
@@ -151,7 +151,7 @@ CURLcode Curl_weak_random(struct Curl_easy *data,
 #ifdef USE_SSL
 #define _random(x,y,z) Curl_ssl_random(x,y,z)
 #else
-#define _random(x,y,z) Curl_weak_random(x,y,z)
+#define _random(x,y,z) weak_random(x,y,z)
 #endif
 
 static CURLcode randit(struct Curl_easy *data, unsigned int *rnd,
index 7810a903a7f30dd1893a0181d6aa64a2d80b8975..2ba60e72976ed9c440483f5d7ff8e9d6d839ed0c 100644 (file)
@@ -36,11 +36,6 @@ CURLcode Curl_rand_bytes(struct Curl_easy *data,
 #define Curl_rand(a,b,c)   Curl_rand_bytes((a), (b), (c))
 #endif
 
-/* ---- non-cryptographic version following ---- */
-CURLcode Curl_weak_random(struct Curl_easy *data,
-                          unsigned char *rnd,
-                          size_t length);
-
 /*
  * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random
  * hexadecimal digits PLUS a null-terminating byte. It must be an odd number
index 241d2cc54029133697d65d80dc6f954a0dd2fda0..02ed4ec45a8b4e123d2c02b0453da6d6e8d45243 100644 (file)
@@ -216,15 +216,15 @@ cr_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
     }
 
     rresult = rustls_connection_read(rconn,
-      (uint8_t *)plainbuf + plain_bytes_copied,
-      plainlen - plain_bytes_copied,
-      &n);
+                                     (uint8_t *)plainbuf + plain_bytes_copied,
+                                     plainlen - plain_bytes_copied,
+                                     &n);
     if(rresult == RUSTLS_RESULT_PLAINTEXT_EMPTY) {
       backend->data_in_pending = FALSE;
     }
     else if(rresult == RUSTLS_RESULT_UNEXPECTED_EOF) {
       failf(data, "rustls: peer closed TCP connection "
-        "without first closing TLS connection");
+            "without first closing TLS connection");
       *err = CURLE_RECV_ERROR;
       nread = -1;
       goto out;
@@ -449,7 +449,7 @@ cr_get_selected_ciphers(struct Curl_easy *data,
     for(j = 0; j < default_len; j++) {
       entry = rustls_default_crypto_provider_ciphersuites_get(j);
       if(rustls_supported_ciphersuite_protocol_version(entry) !=
-        RUSTLS_TLS_VERSION_TLSV1_3)
+         RUSTLS_TLS_VERSION_TLSV1_3)
         continue;
 
       selected[count++] = entry;
@@ -606,10 +606,10 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
     }
 
     result = rustls_crypto_provider_builder_new_from_default(
-                      &custom_provider_builder);
+      &custom_provider_builder);
     if(result != RUSTLS_RESULT_OK) {
       failf(data,
-        "rustls: failed to create crypto provider builder from default");
+            "rustls: failed to create crypto provider builder from default");
       return CURLE_SSL_ENGINE_INITFAILED;
     }
 
@@ -620,9 +620,9 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
         cipher_suites_len);
     if(result != RUSTLS_RESULT_OK) {
       failf(data,
-        "rustls: failed to set ciphersuites for crypto provider builder");
-        rustls_crypto_provider_builder_free(custom_provider_builder);
-        return CURLE_SSL_ENGINE_INITFAILED;
+            "rustls: failed to set ciphersuites for crypto provider builder");
+      rustls_crypto_provider_builder_free(custom_provider_builder);
+      return CURLE_SSL_ENGINE_INITFAILED;
     }
 
     result = rustls_crypto_provider_builder_build(
@@ -634,9 +634,9 @@ cr_init_backend(struct Curl_cfilter *cf, struct Curl_easy *data,
     }
 
     result = rustls_client_config_builder_new_custom(custom_provider,
-                                                      tls_versions,
-                                                      tls_versions_len,
-                                                      &config_builder);
+                                                     tls_versions,
+                                                     tls_versions_len,
+                                                     &config_builder);
     free(cipher_suites);
     if(result != RUSTLS_RESULT_OK) {
       failf(data, "rustls: failed to create client config");
@@ -1056,6 +1056,16 @@ static size_t cr_version(char *buffer, size_t size)
   return msnprintf(buffer, size, "%.*s", (int)ver.len, ver.data);
 }
 
+static CURLcode
+cr_random(struct Curl_easy *data, unsigned char *entropy, size_t length)
+{
+  rustls_result rresult = 0;
+  (void)data;
+  rresult =
+    rustls_default_crypto_provider_random(entropy, length);
+  return map_error(rresult);
+}
+
 const struct Curl_ssl Curl_ssl_rustls = {
   { CURLSSLBACKEND_RUSTLS, "rustls" },
   SSLSUPP_CAINFO_BLOB |            /* supports */
@@ -1070,7 +1080,7 @@ const struct Curl_ssl Curl_ssl_rustls = {
   Curl_none_check_cxn,             /* check_cxn */
   cr_shutdown,                     /* shutdown */
   cr_data_pending,                 /* data_pending */
-  Curl_weak_random,                /* random */
+  cr_random,                       /* random */
   Curl_none_cert_status_request,   /* cert_status_request */
   cr_connect_blocking,             /* connect */
   cr_connect_nonblocking,          /* connect_nonblocking */