diff --git a/include/libwebsockets/lws-client.h b/include/libwebsockets/lws-client.h index c2e40a232..9688e3466 100644 --- a/include/libwebsockets/lws-client.h +++ b/include/libwebsockets/lws-client.h @@ -218,8 +218,20 @@ lws_http_client_read(struct lws *wsi, char **buf, int *len); LWS_VISIBLE LWS_EXTERN unsigned int lws_http_client_http_response(struct lws *wsi); -LWS_VISIBLE LWS_EXTERN void -lws_client_http_body_pending(struct lws *wsi, int something_left_to_send); +/** + * lws_tls_client_vhost_extra_cert_mem() - add more certs to vh client tls ctx + * + * \param vh: the vhost to give more client certs to + * \param der: pointer to der format additional cert + * \param der_len: size in bytes of der + * + * After the vhost is created with one cert for client verification, you + * can add additional, eg, intermediate, certs to the client tls context + * of the vhost, for use with validating the incoming server cert(s). + */ +LWS_VISIBLE LWS_EXTERN int +lws_tls_client_vhost_extra_cert_mem(struct lws_vhost *vh, + const uint8_t *der, size_t der_len); /** * lws_client_http_body_pending() - control if client connection neeeds to send body @@ -240,5 +252,7 @@ lws_client_http_body_pending(struct lws *wsi, int something_left_to_send); * if there is more to come, or lws_client_http_body_pending(wsi, 0); to * let lws know the last part is sent and the connection can move on. */ +LWS_VISIBLE LWS_EXTERN void +lws_client_http_body_pending(struct lws *wsi, int something_left_to_send); ///@} diff --git a/lib/tls/mbedtls/mbedtls-client.c b/lib/tls/mbedtls/mbedtls-client.c index ff96bcae3..88d7aa260 100644 --- a/lib/tls/mbedtls/mbedtls-client.c +++ b/lib/tls/mbedtls/mbedtls-client.c @@ -306,3 +306,16 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh, return 0; } + +int +lws_tls_client_vhost_extra_cert_mem(struct lws_vhost *vh, + const uint8_t *der, size_t der_len) +{ + if (SSL_CTX_add_client_CA_ASN1(vh->tls.ssl_client_ctx, der_len, der) != 1) { + lwsl_err("%s: failed\n", __func__); + return 1; + } + + return 0; +} + diff --git a/lib/tls/openssl/openssl-client.c b/lib/tls/openssl/openssl-client.c index 744ccb4fb..180c00e6c 100644 --- a/lib/tls/openssl/openssl-client.c +++ b/lib/tls/openssl/openssl-client.c @@ -372,6 +372,36 @@ lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len) #endif } +int +lws_tls_client_vhost_extra_cert_mem(struct lws_vhost *vh, + const uint8_t *der, size_t der_len) +{ + X509_STORE *st; + X509 *x = d2i_X509(NULL, &der, der_len); + int n; + + if (!x) { + lwsl_err("%s: Failed to load DER\n", __func__); + lws_tls_err_describe_clear(); + return 1; + } + + st = SSL_CTX_get_cert_store(vh->tls.ssl_client_ctx); + if (!st) { + lwsl_err("%s: failed to get cert store\n", __func__); + X509_free(x); + return 1; + } + + n = X509_STORE_add_cert(st, x); + if (n != 1) + lwsl_err("%s: failed to add cert\n", __func__); + + X509_free(x); + + return n != 1; +} + int lws_tls_client_create_vhost_context(struct lws_vhost *vh, const struct lws_context_creation_info *info, @@ -609,6 +639,7 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh, } if (client_CA) X509_free(client_CA); + // lws_tls_client_vhost_extra_cert_mem(vh, ca_mem, ca_mem_len); } /* @@ -667,3 +698,5 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh, return 0; } + + diff --git a/lib/tls/tls-client.c b/lib/tls/tls-client.c index 60e4dbb91..7bafffbb7 100644 --- a/lib/tls/tls-client.c +++ b/lib/tls/tls-client.c @@ -162,3 +162,4 @@ int lws_context_init_client_ssl(const struct lws_context_creation_info *info, return 0; } +