diff --git a/lib/tls/mbedtls/mbedtls-client.c b/lib/tls/mbedtls/mbedtls-client.c index 6e790ca21e..5fb46b416c 100644 --- a/lib/tls/mbedtls/mbedtls-client.c +++ b/lib/tls/mbedtls/mbedtls-client.c @@ -416,39 +416,48 @@ lws_tls_client_create_vhost_context(struct lws_vhost *vh, return 1; } - if (!ca_filepath && (!ca_mem || !ca_mem_len)) - return 0; - - if (ca_filepath) { + if (!ca_filepath && (!ca_mem || !ca_mem_len)) { +#if defined(LWS_HAVE_SSL_CTX_load_verify_dir) + if (!SSL_CTX_load_verify_dir( + vh->tls.ssl_client_ctx, LWS_OPENSSL_CLIENT_CERTS)) +#else + if (!SSL_CTX_load_verify_locations( + vh->tls.ssl_client_ctx, NULL, LWS_OPENSSL_CLIENT_CERTS)) +#endif + 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 if (ca_filepath) { #if !defined(LWS_PLAT_OPTEE) - uint8_t *buf; - lws_filepos_t len; - - if (alloc_file(vh->context, ca_filepath, &buf, &len)) { - lwsl_err("Load CA cert file %s failed\n", ca_filepath); - return 1; +#if defined(LWS_HAVE_SSL_CTX_load_verify_file) + if (!SSL_CTX_load_verify_file( + vh->tls.ssl_client_ctx, ca_filepath)) { +#else + if (!SSL_CTX_load_verify_locations( + vh->tls.ssl_client_ctx, ca_filepath, NULL)) { +#endif + lwsl_err( + "Unable to load SSL Client certs " + "file from %s -- client ssl isn't " + "going to work\n", ca_filepath); } - vh->tls.x509_client_CA = d2i_X509(NULL, (const uint8_t **)&buf, (long)len); - free(buf); - - lwsl_info("Loading vh %s client CA for verification %s\n", vh->name, ca_filepath); #endif } else { vh->tls.x509_client_CA = d2i_X509(NULL, (const uint8_t **)&ca_mem, (long)ca_mem_len); lwsl_info("%s: using mem client CA cert %d\n", __func__, ca_mem_len); - } + if (!vh->tls.x509_client_CA) { + lwsl_err("client CA: x509 parse failed\n"); + return 1; + } - if (!vh->tls.x509_client_CA) { - lwsl_err("client CA: x509 parse failed\n"); - return 1; + if (!vh->tls.ssl_ctx) + SSL_CTX_add_client_CA(vh->tls.ssl_client_ctx, vh->tls.x509_client_CA); + else + SSL_CTX_add_client_CA(vh->tls.ssl_ctx, vh->tls.x509_client_CA); } - if (!vh->tls.ssl_ctx) - SSL_CTX_add_client_CA(vh->tls.ssl_client_ctx, vh->tls.x509_client_CA); - else - SSL_CTX_add_client_CA(vh->tls.ssl_ctx, vh->tls.x509_client_CA); - /* support for client-side certificate authentication */ if (cert_filepath) { #if !defined(LWS_PLAT_OPTEE) diff --git a/lib/tls/mbedtls/wrapper/include/internal/ssl_methods.h b/lib/tls/mbedtls/wrapper/include/internal/ssl_methods.h index cd2f8c0533..39637592fa 100644 --- a/lib/tls/mbedtls/wrapper/include/internal/ssl_methods.h +++ b/lib/tls/mbedtls/wrapper/include/internal/ssl_methods.h @@ -72,12 +72,16 @@ new, \ free, \ load, \ + load_file, \ + load_path, \ show_info) \ const X509_METHOD* func_name(void) { \ static const X509_METHOD func_name##_data LOCAL_ATRR = { \ new, \ free, \ load, \ + load_file, \ + load_path, \ show_info \ }; \ return &func_name##_data; \ diff --git a/lib/tls/mbedtls/wrapper/include/openssl/ssl.h b/lib/tls/mbedtls/wrapper/include/openssl/ssl.h index 8ff1e77445..ec9d682c95 100755 --- a/lib/tls/mbedtls/wrapper/include/openssl/ssl.h +++ b/lib/tls/mbedtls/wrapper/include/openssl/ssl.h @@ -1822,6 +1822,44 @@ const char *SSL_get_psk_identity_hint(SSL *ssl); */ const char *SSL_get_psk_identity(SSL *ssl); +/** + * @brief Load a file containing CA certificates for verification into the SSL context + * + * @param ctx - SSL context pointer + * @param CAfile - Path to the file containing CA certificates. + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile); + +/** + * @brief Load a directory containing CA certificates for verification into the SSL context + * + * @param ctx - SSL context pointer + * @param CApath - Path to the directory containing CA certificates. + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath); + +/** + * @brief Load CA certificates from file and/or directory for verification + * + * @param ctx - SSL context pointer + * @param CAfile - Path to the file containing CA certificates. + * @param CApath - Path to the directory containing CA certificates. + * + * @return result + * 1 : OK + * 0 : failed + */ +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath); + #ifdef __cplusplus } #endif diff --git a/lib/tls/mbedtls/wrapper/include/platform/ssl_pm.h b/lib/tls/mbedtls/wrapper/include/platform/ssl_pm.h index 874d2d1150..e494737ac5 100644 --- a/lib/tls/mbedtls/wrapper/include/platform/ssl_pm.h +++ b/lib/tls/mbedtls/wrapper/include/platform/ssl_pm.h @@ -47,6 +47,8 @@ int x509_pm_show_info(X509 *x); int x509_pm_new(X509 *x, X509 *m_x); void x509_pm_free(X509 *x); int x509_pm_load(X509 *x, const unsigned char *buffer, int len); +int x509_pm_load_file(X509 *x, const char *path); +int x509_pm_load_path(X509 *x, const char *path); int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pk, void *rngctx); void pkey_pm_free(EVP_PKEY *pk); diff --git a/lib/tls/mbedtls/wrapper/library/ssl_lib.c b/lib/tls/mbedtls/wrapper/library/ssl_lib.c index 6bc5ff4227..b91a79b64d 100644 --- a/lib/tls/mbedtls/wrapper/library/ssl_lib.c +++ b/lib/tls/mbedtls/wrapper/library/ssl_lib.c @@ -1257,3 +1257,59 @@ void SSL_set_alpn_select_cb(SSL *ssl, void *arg) _ssl_set_alpn_list(ssl); } + +int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile) +{ + X509 *x; + int ret; + + SSL_ASSERT1(ctx); + SSL_ASSERT1(CAfile); + + x = X509_new(); + ret = X509_METHOD_CALL(load_file, x, CAfile); + if (ret) { + X509_free(x); + return 0; + } + + SSL_CTX_add_client_CA(ctx, x); + return 1; +} + +int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath) +{ + X509 *x; + int ret; + + SSL_ASSERT1(ctx); + SSL_ASSERT1(CApath); + + x = X509_new(); + ret = X509_METHOD_CALL(load_path, x, CApath); + if (ret) { + X509_free(x); + return 0; + } + + SSL_CTX_add_client_CA(ctx, x); + return 1; +} + +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath) +{ + if (CAfile == NULL && CApath == NULL) { + return 0; + } + + if (CAfile != NULL && !SSL_CTX_load_verify_file(ctx, CAfile)) { + return 0; + } + + if (CApath != NULL && !SSL_CTX_load_verify_dir(ctx, CApath)) { + return 0; + } + + return 1; +} diff --git a/lib/tls/mbedtls/wrapper/library/ssl_methods.c b/lib/tls/mbedtls/wrapper/library/ssl_methods.c index bfa9c9beeb..14e5008f57 100644 --- a/lib/tls/mbedtls/wrapper/library/ssl_methods.c +++ b/lib/tls/mbedtls/wrapper/library/ssl_methods.c @@ -79,7 +79,8 @@ IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method); */ IMPLEMENT_X509_METHOD(X509_method, x509_pm_new, x509_pm_free, - x509_pm_load, x509_pm_show_info); + x509_pm_load, x509_pm_load_file, + x509_pm_load_path, x509_pm_show_info); /** * @brief get private key object method diff --git a/lib/tls/mbedtls/wrapper/platform/ssl_pm.c b/lib/tls/mbedtls/wrapper/platform/ssl_pm.c index 19b071f13b..92951e3adb 100755 --- a/lib/tls/mbedtls/wrapper/platform/ssl_pm.c +++ b/lib/tls/mbedtls/wrapper/platform/ssl_pm.c @@ -722,6 +722,42 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len) return -1; } +int x509_pm_load_file(X509 *x, const char *path) +{ + int ret; + struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; + + mbedtls_x509_crt_free(&x509_pm->x509_crt); + mbedtls_x509_crt_init(&x509_pm->x509_crt); + ret = mbedtls_x509_crt_parse_file(&x509_pm->x509_crt, path); + if (ret) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, + "mbedtls_x509_crt_parse_file return -0x%x", -ret); + mbedtls_x509_crt_free(&x509_pm->x509_crt); + return -1; + } + + return 0; +} + +int x509_pm_load_path(X509 *x, const char *path) +{ + int ret; + struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; + + mbedtls_x509_crt_free(&x509_pm->x509_crt); + mbedtls_x509_crt_init(&x509_pm->x509_crt); + ret = mbedtls_x509_crt_parse_path(&x509_pm->x509_crt, path); + if (ret) { + SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, + "mbedtls_x509_crt_parse_file return -0x%x", -ret); + mbedtls_x509_crt_free(&x509_pm->x509_crt); + return -1; + } + + return 0; +} + int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pkey, void *rngctx) { struct pkey_pm *pkey_pm;