wolfssl: add support for ssl cert blob / ssl key blob options

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
This commit is contained in:
Alex Snast 2024-06-25 09:34:24 -07:00 committed by Daniel Stenberg
parent 7b14449790
commit 8d98118026
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
3 changed files with 75 additions and 24 deletions

View file

@ -15,6 +15,7 @@ TLS-backend:
- Secure Transport
- Schannel
- mbedTLS
- wolfSSL
Added-in: 7.71.0
---

View file

@ -11,6 +11,7 @@ Protocol:
- TLS
TLS-backend:
- OpenSSL
- wolfSSL
Added-in: 7.71.0
---

View 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;
}
}
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;
}
}
else {
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;
}
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_file) {
key_blob = cert_blob;
key_file = cert_file;
}
else
file_type = do_file_type(ssl_config->key_type);
if(wolfSSL_CTX_use_PrivateKey_file(backend->ctx, key_file,
file_type) != 1) {
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_blob)
key_blob = cert_blob;
else
file_type = do_file_type(ssl_config->key_type);
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;
}