mirror of
https://github.com/yhirose/cpp-httplib
synced 2024-11-21 14:29:10 -07:00
Load in-memory CA certificates (#1579)
* Load in-memory CA certs * Add test cases for in-memory cert loading * Don't use the IIFE style
This commit is contained in:
parent
3e287b3a26
commit
eab5ea01d7
2 changed files with 84 additions and 0 deletions
41
httplib.h
41
httplib.h
|
@ -1124,6 +1124,7 @@ public:
|
|||
void set_ca_cert_path(const std::string &ca_cert_file_path,
|
||||
const std::string &ca_cert_dir_path = std::string());
|
||||
void set_ca_cert_store(X509_STORE *ca_cert_store);
|
||||
X509_STORE *create_ca_cert_store(const char *ca_cert, std::size_t size);
|
||||
#endif
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
|
@ -1504,6 +1505,7 @@ public:
|
|||
const std::string &ca_cert_dir_path = std::string());
|
||||
|
||||
void set_ca_cert_store(X509_STORE *ca_cert_store);
|
||||
void load_ca_cert_store(const char *ca_cert, std::size_t size);
|
||||
|
||||
long get_openssl_verify_result() const;
|
||||
|
||||
|
@ -1563,6 +1565,7 @@ public:
|
|||
bool is_valid() const override;
|
||||
|
||||
void set_ca_cert_store(X509_STORE *ca_cert_store);
|
||||
void load_ca_cert_store(const char *ca_cert, std::size_t size);
|
||||
|
||||
long get_openssl_verify_result() const;
|
||||
|
||||
|
@ -7590,6 +7593,35 @@ inline void ClientImpl::set_ca_cert_store(X509_STORE *ca_cert_store) {
|
|||
ca_cert_store_ = ca_cert_store;
|
||||
}
|
||||
}
|
||||
|
||||
inline X509_STORE *ClientImpl::create_ca_cert_store(const char *ca_cert,
|
||||
std::size_t size) {
|
||||
auto mem = BIO_new_mem_buf(ca_cert, size);
|
||||
if (!mem) return nullptr;
|
||||
|
||||
auto inf = PEM_X509_INFO_read_bio(mem, nullptr, nullptr, nullptr);
|
||||
if (!inf) {
|
||||
BIO_free_all(mem);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto cts = X509_STORE_new();
|
||||
if (cts) {
|
||||
for (int first = 0, last = sk_X509_INFO_num(inf); first < last; ++first) {
|
||||
auto itmp = sk_X509_INFO_value(inf, first);
|
||||
if (!itmp) continue;
|
||||
|
||||
if (itmp->x509) X509_STORE_add_cert(cts, itmp->x509);
|
||||
|
||||
if (itmp->crl) X509_STORE_add_crl(cts, itmp->crl);
|
||||
}
|
||||
}
|
||||
|
||||
sk_X509_INFO_pop_free(inf, X509_INFO_free);
|
||||
BIO_free_all(mem);
|
||||
|
||||
return cts;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
|
@ -7990,6 +8022,11 @@ inline void SSLClient::set_ca_cert_store(X509_STORE *ca_cert_store) {
|
|||
}
|
||||
}
|
||||
|
||||
inline void SSLClient::load_ca_cert_store(const char *ca_cert,
|
||||
std::size_t size) {
|
||||
set_ca_cert_store(ClientImpl::create_ca_cert_store(ca_cert, size));
|
||||
}
|
||||
|
||||
inline long SSLClient::get_openssl_verify_result() const {
|
||||
return verify_result_;
|
||||
}
|
||||
|
@ -8773,6 +8810,10 @@ inline void Client::set_ca_cert_store(X509_STORE *ca_cert_store) {
|
|||
}
|
||||
}
|
||||
|
||||
inline void Client::load_ca_cert_store(const char *ca_cert, std::size_t size) {
|
||||
set_ca_cert_store(cli_->create_ca_cert_store(ca_cert, size));
|
||||
}
|
||||
|
||||
inline long Client::get_openssl_verify_result() const {
|
||||
if (is_ssl_) {
|
||||
return static_cast<SSLClient &>(*cli_).get_openssl_verify_result();
|
||||
|
|
43
test/test.cc
43
test/test.cc
|
@ -4710,6 +4710,49 @@ TEST(SSLClientTest, ServerCertificateVerification4) {
|
|||
ASSERT_EQ(200, res->status);
|
||||
}
|
||||
|
||||
TEST(SSLClientTest, ServerCertificateVerification5_Online) {
|
||||
std::string cert;
|
||||
detail::read_file(CA_CERT_FILE, cert);
|
||||
|
||||
SSLClient cli("google.com");
|
||||
cli.load_ca_cert_store(cert.data(), cert.size());
|
||||
const auto res = cli.Get("/");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(301, res->status);
|
||||
}
|
||||
|
||||
TEST(SSLClientTest, ServerCertificateVerification6_Online) {
|
||||
// clang-format off
|
||||
static constexpr char cert[] =
|
||||
"GlobalSign Root CA\n"
|
||||
"==================\n"
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx\n"
|
||||
"GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds\n"
|
||||
"b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV\n"
|
||||
"BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD\n"
|
||||
"VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa\n"
|
||||
"DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc\n"
|
||||
"THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb\n"
|
||||
"Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP\n"
|
||||
"c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX\n"
|
||||
"gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\n"
|
||||
"HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF\n"
|
||||
"AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj\n"
|
||||
"Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG\n"
|
||||
"j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH\n"
|
||||
"hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC\n"
|
||||
"X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
// clang-format on
|
||||
|
||||
SSLClient cli("google.com");
|
||||
cli.load_ca_cert_store(cert, sizeof(cert));
|
||||
const auto res = cli.Get("/");
|
||||
ASSERT_TRUE(res);
|
||||
ASSERT_EQ(301, res->status);
|
||||
}
|
||||
|
||||
TEST(SSLClientTest, WildcardHostNameMatch_Online) {
|
||||
SSLClient cli("www.youtube.com");
|
||||
|
||||
|
|
Loading…
Reference in a new issue