diff --git a/httplib.h b/httplib.h index 666cd9d3..bfc322c2 100644 --- a/httplib.h +++ b/httplib.h @@ -21986,24 +21986,23 @@ inline ca_store_t create_ca_store(const char *pem, size_t len) { if (!detail::ensure_mbedtls_psa_crypto()) { return nullptr; } #endif + if (!pem) { return nullptr; } + + // mbedtls_x509_crt_parse expects null-terminated PEM + std::string pem_str(pem, len); + auto *ca_chain = new (std::nothrow) mbedtls_x509_crt; if (!ca_chain) { return nullptr; } mbedtls_x509_crt_init(ca_chain); - // mbedtls_x509_crt_parse expects null-terminated PEM - int ret = mbedtls_x509_crt_parse(ca_chain, - reinterpret_cast(pem), - len + 1); // +1 for null terminator + auto ret = mbedtls_x509_crt_parse( + ca_chain, reinterpret_cast(pem_str.c_str()), + pem_str.size() + 1); if (ret != 0) { - // Try without +1 in case PEM is already null-terminated - ret = mbedtls_x509_crt_parse( - ca_chain, reinterpret_cast(pem), len); - if (ret != 0) { - mbedtls_x509_crt_free(ca_chain); - delete ca_chain; - return nullptr; - } + mbedtls_x509_crt_free(ca_chain); + delete ca_chain; + return nullptr; } return static_cast(ca_chain); diff --git a/test/test.cc b/test/test.cc index f426c5d5..78d273c9 100644 --- a/test/test.cc +++ b/test/test.cc @@ -18304,6 +18304,17 @@ TEST(SSLClientTest, EmptyCustomCaKeepsSystemCasOut) { } #endif +// A PEM given to create_ca_store() needs no NUL after it +TEST(SSLClientTest, CreateCaStoreFromPemWithoutNul) { + std::string pem; + read_file(SERVER_CERT2_FILE, pem); + auto buf = pem + "X"; + auto store = tls::create_ca_store(buf.data(), pem.size()); + EXPECT_TRUE(store != nullptr); + SSLClient cli("localhost"); + cli.set_ca_cert_store(store); +} + // enable_system_ca(false) prevents system CA loading entirely TEST(SSLClientTest, DisableSystemCa_Online) { SSLClient cli("google.com");