mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-22 11:46:13 +00:00
Parse a CA store PEM through a NUL-terminated copy on Mbed TLS
tls::create_ca_store() on Mbed TLS parsed the caller's buffer with one byte more than its length, so it read past the end of the buffer, and when that byte was not a NUL the PEM was not recognized and the call returned NULL. Parse a NUL-terminated copy instead, as load_ca_pem() does. DER input still parses, since its own length ends it.
This commit is contained in:
1 parent
3599533c24
commit
3b8b9cf9d5
2 files changed
+22
-12
No files matched your search
@@ -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; }
|
if (!detail::ensure_mbedtls_psa_crypto()) { return nullptr; }
|
||||||
#endif
|
#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;
|
auto *ca_chain = new (std::nothrow) mbedtls_x509_crt;
|
||||||
if (!ca_chain) { return nullptr; }
|
if (!ca_chain) { return nullptr; }
|
||||||
|
|
||||||
mbedtls_x509_crt_init(ca_chain);
|
mbedtls_x509_crt_init(ca_chain);
|
||||||
|
|
||||||
// mbedtls_x509_crt_parse expects null-terminated PEM
|
auto ret = mbedtls_x509_crt_parse(
|
||||||
int ret = mbedtls_x509_crt_parse(ca_chain,
|
ca_chain, reinterpret_cast<const unsigned char *>(pem_str.c_str()),
|
||||||
reinterpret_cast<const unsigned char *>(pem),
|
pem_str.size() + 1);
|
||||||
len + 1); // +1 for null terminator
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
// Try without +1 in case PEM is already null-terminated
|
mbedtls_x509_crt_free(ca_chain);
|
||||||
ret = mbedtls_x509_crt_parse(
|
delete ca_chain;
|
||||||
ca_chain, reinterpret_cast<const unsigned char *>(pem), len);
|
return nullptr;
|
||||||
if (ret != 0) {
|
|
||||||
mbedtls_x509_crt_free(ca_chain);
|
|
||||||
delete ca_chain;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<ca_store_t>(ca_chain);
|
return static_cast<ca_store_t>(ca_chain);
|
||||||
|
|||||||
@@ -18304,6 +18304,17 @@ TEST(SSLClientTest, EmptyCustomCaKeepsSystemCasOut) {
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
// enable_system_ca(false) prevents system CA loading entirely
|
||||||
TEST(SSLClientTest, DisableSystemCa_Online) {
|
TEST(SSLClientTest, DisableSystemCa_Online) {
|
||||||
SSLClient cli("google.com");
|
SSLClient cli("google.com");
|
||||||
|
|||||||
Reference in new issue
Block a user