Skip to content

Commit 7532932

Browse files
committed
Fix OpenSSL 4.0 deprecation warnings
OpenSSL 4.0 deprecates X509_STORE_get0_objects() and X509_NAME_get_text_by_NID(), producing warnings on the OpenSSL backend (surfaced by Debian bug #1138434, which also reported a const-conversion build error already fixed in v0.43.1). - Fetch CA store objects via X509_STORE_get1_objects() (thread-safe, OpenSSL 3.3+) in get_ca_certs() and get_ca_names(), releasing the snapshot with a scope_exit guard; keep using get0 on older OpenSSL, BoringSSL, and LibreSSL - Extract the subject CN in get_cert_subject_cn() with X509_NAME_get_index_by_NID()/X509_NAME_get_entry() instead of the deprecated X509_NAME_get_text_by_NID() - Delegate SSLClient::verify_host_with_common_name() to tls::get_cert_subject_cn() to drop the remaining deprecated call Verified against OpenSSL 4.0.1, 3.6.2, and 3.0: builds warning-free and passes the full test suite.
1 parent 8829fac commit 7532932

1 file changed

Lines changed: 44 additions & 21 deletions

File tree

httplib.h

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16777,6 +16777,30 @@ inline int openssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
1677716777
return callback(verify_ctx) ? 1 : 0;
1677816778
}
1677916779

16780+
// X509_STORE_get0_objects is deprecated since OpenSSL 4.0 because it is not
16781+
// thread-safe; X509_STORE_get1_objects (OpenSSL 3.3+) returns a snapshot
16782+
// that must be released with release_store_objects
16783+
#if !defined(OPENSSL_IS_BORINGSSL) && !defined(LIBRESSL_VERSION_NUMBER) && \
16784+
OPENSSL_VERSION_NUMBER >= 0x30300000L
16785+
#define CPPHTTPLIB_HAS_X509_STORE_GET1_OBJECTS
16786+
#endif
16787+
16788+
inline STACK_OF(X509_OBJECT) * get_store_objects(X509_STORE *store) {
16789+
#ifdef CPPHTTPLIB_HAS_X509_STORE_GET1_OBJECTS
16790+
return X509_STORE_get1_objects(store);
16791+
#else
16792+
return X509_STORE_get0_objects(store);
16793+
#endif
16794+
}
16795+
16796+
inline void release_store_objects(STACK_OF(X509_OBJECT) * objs) {
16797+
#ifdef CPPHTTPLIB_HAS_X509_STORE_GET1_OBJECTS
16798+
sk_X509_OBJECT_pop_free(objs, X509_OBJECT_free);
16799+
#else
16800+
(void)objs; // get0 variant returns an internal pointer; nothing to free
16801+
#endif
16802+
}
16803+
1678016804
} // namespace impl
1678116805

1678216806
inline ctx_t create_client_context() {
@@ -17298,11 +17322,19 @@ inline std::string get_cert_subject_cn(cert_t cert) {
1729817322
auto subject_name = X509_get_subject_name(x509);
1729917323
if (!subject_name) return "";
1730017324

17301-
char buf[256];
17302-
auto len =
17303-
X509_NAME_get_text_by_NID(subject_name, NID_commonName, buf, sizeof(buf));
17304-
if (len < 0) return "";
17305-
return std::string(buf, static_cast<size_t>(len));
17325+
// X509_NAME_get_text_by_NID is deprecated since OpenSSL 4.0
17326+
auto idx = X509_NAME_get_index_by_NID(subject_name, NID_commonName, -1);
17327+
if (idx < 0) return "";
17328+
17329+
auto entry = X509_NAME_get_entry(subject_name, idx);
17330+
if (!entry) return "";
17331+
17332+
auto data = X509_NAME_ENTRY_get_data(entry);
17333+
if (!data) return "";
17334+
17335+
return std::string(
17336+
reinterpret_cast<const char *>(ASN1_STRING_get0_data(data)),
17337+
static_cast<size_t>(ASN1_STRING_length(data)));
1730617338
}
1730717339

1730817340
inline std::string get_cert_issuer_name(cert_t cert) {
@@ -17507,8 +17539,9 @@ inline size_t get_ca_certs(ctx_t ctx, std::vector<cert_t> &certs) {
1750717539
auto store = SSL_CTX_get_cert_store(ssl_ctx);
1750817540
if (!store) { return 0; }
1750917541

17510-
auto objs = X509_STORE_get0_objects(store);
17542+
auto objs = impl::get_store_objects(store);
1751117543
if (!objs) { return 0; }
17544+
auto se = detail::scope_exit([&] { impl::release_store_objects(objs); });
1751217545

1751317546
auto count = sk_X509_OBJECT_num(objs);
1751417547
for (decltype(count) i = 0; i < count; i++) {
@@ -17534,8 +17567,9 @@ inline std::vector<std::string> get_ca_names(ctx_t ctx) {
1753417567
auto store = SSL_CTX_get_cert_store(ssl_ctx);
1753517568
if (!store) { return names; }
1753617569

17537-
auto objs = X509_STORE_get0_objects(store);
17570+
auto objs = impl::get_store_objects(store);
1753817571
if (!objs) { return names; }
17572+
auto se = detail::scope_exit([&] { impl::release_store_objects(objs); });
1753917573

1754017574
auto count = sk_X509_OBJECT_num(objs);
1754117575
for (decltype(count) i = 0; i < count; i++) {
@@ -17729,20 +17763,9 @@ SSLClient::verify_host_with_subject_alt_name(X509 *server_cert) const {
1772917763
}
1773017764

1773117765
inline bool SSLClient::verify_host_with_common_name(X509 *server_cert) const {
17732-
const auto subject_name = X509_get_subject_name(server_cert);
17733-
17734-
if (subject_name != nullptr) {
17735-
char name[BUFSIZ];
17736-
auto name_len = X509_NAME_get_text_by_NID(subject_name, NID_commonName,
17737-
name, sizeof(name));
17738-
17739-
if (name_len != -1) {
17740-
return detail::match_hostname(
17741-
std::string(name, static_cast<size_t>(name_len)), host_);
17742-
}
17743-
}
17744-
17745-
return false;
17766+
auto cn = tls::get_cert_subject_cn(static_cast<tls::cert_t>(server_cert));
17767+
if (cn.empty()) { return false; }
17768+
return detail::match_hostname(cn, host_);
1774617769
}
1774717770

1774817771
#endif // CPPHTTPLIB_OPENSSL_SUPPORT

0 commit comments

Comments
 (0)