diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index c7550c1f7..b1abe0ce8 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -2883,6 +2883,12 @@ struct lws_context_creation_info { * via openSSL library calls */ const char *client_ssl_ca_filepath; /**< VHOST: Client SSL context init: CA certificate filepath or NULL */ + const void *client_ssl_ca_mem; + /**< VHOST: Client SSL context init: CA certificate memory buffer or NULL + * use this to load CA cert from memory instead of file */ + unsigned int client_ssl_ca_mem_len; + /**< VHOST: Client SSL context init: length of client_ssl_ca_mem in bytes */ + const char *client_ssl_cipher_list; /**< VHOST: Client SSL context init: List of valid ciphers to use (eg, * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" diff --git a/lib/tls/mbedtls/mbedtls-client.c b/lib/tls/mbedtls/mbedtls-client.c index a7864ab79..833e58dbc 100644 --- a/lib/tls/mbedtls/mbedtls-client.c +++ b/lib/tls/mbedtls/mbedtls-client.c @@ -188,6 +188,8 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh, const struct lws_context_creation_info *info, const char *cipher_list, const char *ca_filepath, + const void *ca_mem, + unsigned int ca_mem_len, const char *cert_filepath, const char *private_key_filepath) { @@ -214,16 +216,20 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh, return 1; } - if (!ca_filepath) + if (!ca_filepath && (!ca_mem || !ca_mem_len)) return 0; - if (alloc_file(vh->context, ca_filepath, &buf, &len)) { - lwsl_err("Load CA cert file %s failed\n", ca_filepath); - return 1; + if (ca_filepath) { + if (alloc_file(vh->context, ca_filepath, &buf, &len)) { + lwsl_err("Load CA cert file %s failed\n", ca_filepath); + return 1; + } + vh->tls.x509_client_CA = d2i_X509(NULL, buf, len); + free(buf); + } else { + vh->tls.x509_client_CA = d2i_X509(NULL, (uint8_t*)ca_mem, ca_mem_len); } - vh->tls.x509_client_CA = d2i_X509(NULL, buf, len); - free(buf); if (!vh->tls.x509_client_CA) { lwsl_err("client CA: x509 parse failed\n"); return 1; diff --git a/lib/tls/openssl/openssl-client.c b/lib/tls/openssl/openssl-client.c index bff3d4042..13ddd5e28 100644 --- a/lib/tls/openssl/openssl-client.c +++ b/lib/tls/openssl/openssl-client.c @@ -327,12 +327,17 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh, const struct lws_context_creation_info *info, const char *cipher_list, const char *ca_filepath, + const void *ca_mem, + unsigned int ca_mem_len, const char *cert_filepath, const char *private_key_filepath) { SSL_METHOD *method; unsigned long error; int n; + const unsigned char **ca_mem_ptr; + X509 *client_CA; + X509_STORE *x509_store; /* basic openssl init already happened in context init */ @@ -379,14 +384,14 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh, #endif /* openssl init for cert verification (for client sockets) */ - if (!ca_filepath) { + if (!ca_filepath && (!ca_mem || !ca_mem_len)) { if (!SSL_CTX_load_verify_locations( vh->tls.ssl_client_ctx, NULL, LWS_OPENSSL_CLIENT_CERTS)) lwsl_err("Unable to load SSL Client certs from %s " "(set by LWS_OPENSSL_CLIENT_CERTS) -- " "client ssl isn't going to work\n", LWS_OPENSSL_CLIENT_CERTS); - } else + } else if (ca_filepath) { if (!SSL_CTX_load_verify_locations( vh->tls.ssl_client_ctx, ca_filepath, NULL)) { lwsl_err( @@ -397,6 +402,23 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh, } else lwsl_info("loaded ssl_ca_filepath\n"); + } else { + ca_mem_ptr = (const unsigned char**)&ca_mem; + client_CA = d2i_X509(NULL, ca_mem_ptr, ca_mem_len); + x509_store = X509_STORE_new(); + if (!client_CA || !X509_STORE_add_cert(x509_store, client_CA)) { + X509_STORE_free(x509_store); + lwsl_err("Unable to load SSL Client certs from ssl_ca_mem -- " + "client ssl isn't going to work\n"); + lws_ssl_elaborate_error(); + } else { + /* it doesn't increment x509_store ref counter */ + SSL_CTX_set_cert_store(vh->tls.ssl_client_ctx, x509_store); + lwsl_info("loaded ssl_ca_mem\n"); + } + if (client_CA) + X509_free(client_CA); + } /* * callback allowing user code to load extra verification certs diff --git a/lib/tls/private.h b/lib/tls/private.h index 606e2574d..fa1205cee 100644 --- a/lib/tls/private.h +++ b/lib/tls/private.h @@ -260,6 +260,8 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh, const struct lws_context_creation_info *info, const char *cipher_list, const char *ca_filepath, + const void *ca_mem, + unsigned int ca_mem_len, const char *cert_filepath, const char *private_key_filepath); diff --git a/lib/tls/tls-client.c b/lib/tls/tls-client.c index 8a5012101..3772aaa88 100644 --- a/lib/tls/tls-client.c +++ b/lib/tls/tls-client.c @@ -128,7 +128,7 @@ int lws_context_init_client_ssl(const struct lws_context_creation_info *info, } if (lws_tls_client_create_vhost_context(vhost, info, cipher_list, - ca_filepath, cert_filepath, + ca_filepath, info->client_ssl_ca_mem, info->client_ssl_ca_mem_len, cert_filepath, private_key_filepath)) return 1;