]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
wolfssl: add support for ssl cert blob / ssl key blob options
authorAlex Snast <alexsn@meta.com>
Tue, 25 Jun 2024 16:34:24 +0000 (09:34 -0700)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 5 Aug 2024 06:17:30 +0000 (08:17 +0200)
wolfSSL supports setting certificates/private keys from memory blobs
which allow us to implement both CURLOPT_SSLCERT_BLOB and
CURLOPT_SSLKEY_BLOB options.

Closes #14018

docs/libcurl/opts/CURLOPT_SSLCERT_BLOB.md
docs/libcurl/opts/CURLOPT_SSLKEY_BLOB.md
lib/vtls/wolfssl.c

index 88f60eb2a6ce3dbe2c3f8ff184269e81c2498a84..fb1cc62fa4ab25d86418d83441f516197ec1c0ee 100644 (file)
@@ -15,6 +15,7 @@ TLS-backend:
   - Secure Transport
   - Schannel
   - mbedTLS
+  - wolfSSL
 Added-in: 7.71.0
 ---
 
index 10b047984e074e77e9b4b8a63350fc5829db01a2..bedf2d33ca2398a9f9a27a3386fb2ed67ebc80d3 100644 (file)
@@ -11,6 +11,7 @@ Protocol:
   - TLS
 TLS-backend:
   - OpenSSL
+  - wolfSSL
 Added-in: 7.71.0
 ---
 
index 8ea83187d3ce6b02893232f11083f48a1f40557a..ed5005c881ef313cc203d9cc151b7624d80f9ab4 100644 (file)
@@ -768,40 +768,89 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
     }
   }
 
-#ifndef NO_FILESYSTEM
   /* Load the client certificate, and private key */
-  if(ssl_config->primary.clientcert) {
-    char *key_file = ssl_config->key;
+#ifndef NO_FILESYSTEM
+  if(ssl_config->primary.cert_blob || ssl_config->primary.clientcert) {
+    const char *cert_file = ssl_config->primary.clientcert;
+    const char *key_file = ssl_config->key;
+    const struct curl_blob *cert_blob = ssl_config->primary.cert_blob;
+    const struct curl_blob *key_blob = ssl_config->key_blob;
     int file_type = do_file_type(ssl_config->cert_type);
+    int rc;
 
-    if(file_type == WOLFSSL_FILETYPE_PEM) {
-      if(wolfSSL_CTX_use_certificate_chain_file(backend->ctx,
-                                                ssl_config->primary.clientcert)
-         != 1) {
-        failf(data, "unable to use client certificate");
-        return CURLE_SSL_CONNECT_ERROR;
-      }
+    switch(file_type) {
+    case WOLFSSL_FILETYPE_PEM:
+      rc = cert_blob ?
+        wolfSSL_CTX_use_certificate_chain_buffer(backend->ctx,
+                                                 cert_blob->data,
+                                                 (long)cert_blob->len) :
+        wolfSSL_CTX_use_certificate_chain_file(backend->ctx, cert_file);
+      break;
+    case WOLFSSL_FILETYPE_ASN1:
+      rc = cert_blob ?
+        wolfSSL_CTX_use_certificate_buffer(backend->ctx, cert_blob->data,
+                                           (long)cert_blob->len, file_type) :
+        wolfSSL_CTX_use_certificate_file(backend->ctx, cert_file, file_type);
+      break;
+    default:
+      failf(data, "unknown cert type");
+      return CURLE_BAD_FUNCTION_ARGUMENT;
     }
-    else if(file_type == WOLFSSL_FILETYPE_ASN1) {
-      if(wolfSSL_CTX_use_certificate_file(backend->ctx,
-                                          ssl_config->primary.clientcert,
-                                          file_type) != 1) {
-        failf(data, "unable to use client certificate");
-        return CURLE_SSL_CONNECT_ERROR;
-      }
+    if(rc != 1) {
+      failf(data, "unable to use client certificate");
+      return CURLE_SSL_CONNECT_ERROR;
     }
-    else {
+
+    if(!key_blob && !key_file) {
+      key_blob = cert_blob;
+      key_file = cert_file;
+    }
+    else
+      file_type = do_file_type(ssl_config->key_type);
+
+    rc = key_blob ?
+      wolfSSL_CTX_use_PrivateKey_buffer(backend->ctx, key_blob->data,
+                                        (long)key_blob->len, file_type) :
+      wolfSSL_CTX_use_PrivateKey_file(backend->ctx, key_file, file_type);
+    if(rc != 1) {
+      failf(data, "unable to set private key");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#else /* NO_FILESYSTEM */
+  if(ssl_config->primary.cert_blob) {
+    const struct curl_blob *cert_blob = ssl_config->primary.cert_blob;
+    const struct curl_blob *key_blob = ssl_config->key_blob;
+    int file_type = do_file_type(ssl_config->cert_type);
+    int rc;
+
+    switch(file_type) {
+    case WOLFSSL_FILETYPE_PEM:
+      rc = wolfSSL_CTX_use_certificate_chain_buffer(backend->ctx,
+                                                    cert_blob->data,
+                                                    (long)cert_blob->len);
+      break;
+    case WOLFSSL_FILETYPE_ASN1:
+      rc = wolfSSL_CTX_use_certificate_buffer(backend->ctx, cert_blob->data,
+                                              (long)cert_blob->len, file_type);
+      break;
+    default:
       failf(data, "unknown cert type");
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
+    if(rc != 1) {
+      failf(data, "unable to use client certificate");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
 
-    if(!key_file)
-      key_file = ssl_config->primary.clientcert;
+    if(!key_blob)
+      key_blob = cert_blob;
     else
       file_type = do_file_type(ssl_config->key_type);
 
-    if(wolfSSL_CTX_use_PrivateKey_file(backend->ctx, key_file,
-                                       file_type) != 1) {
+    if(wolfSSL_CTX_use_PrivateKey_buffer(backend->ctx, key_blob->data,
+                                         (long)key_blob->len,
+                                         file_type) != 1) {
       failf(data, "unable to set private key");
       return CURLE_SSL_CONNECT_ERROR;
     }