Package: openvpn3-client Followup-For: Bug #1138369 X-Debbugs-Cc: [email protected] Control: tags -1 patch ftbfs
Dear Maintainer, The upstream has a patch of their own. I have attached it. -- System Information: Debian Release: trixie/sid APT prefers noble-updates APT policy: (500, 'noble-updates'), (500, 'noble-security'), (500, 'noble'), (100, 'noble-backports') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 6.8.0-124-generic (SMP w/12 CPU threads; PREEMPT) Kernel taint flags: TAINT_WARN Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8), LANGUAGE not set Shell: /bin/sh linked to /usr/bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled
>From 33985a9e6d8941f54eb2d8ddf0c1643d9756e695 Mon Sep 17 00:00:00 2001 From: Arne Schwabe <[email protected]> Date: Wed, 25 Mar 2026 12:01:35 +0100 Subject: [PATCH] Support OpenSSL 4.0 ASN1 integers are now opaque, so use the proper methods to access them. A few methods now return const pointers. Jira: OVPN3-1420 Signed-off-by: Arne Schwabe <[email protected]> Origin: upstream, https://github.com/schwabe/openvpn3/commit/33985a9e6d8941f54eb2d8ddf0c1643d9756e695 Bug-Ubuntu: https://launchpad.net/bugs/2154917 Bug-Debian: https://bugs.debian.org/1138369 Last-Update: 2026-08-04 diff --git a/openvpn3-core/openvpn/openssl/pki/x509certinfo.hpp b/openvpn3-core/openvpn/openssl/pki/x509certinfo.hpp index 9eed7a708..0311e4ea2 100644 --- a/openvpn3-core/openvpn/openssl/pki/x509certinfo.hpp +++ b/openvpn3-core/openvpn/openssl/pki/x509certinfo.hpp @@ -29,6 +29,8 @@ namespace openvpn::OpenSSLPKI { +using BIGNUM_ptr = std::unique_ptr<::BIGNUM, decltype(&::BN_free)>; + /** * Retrieve the complete X.509 Certificate Subject field * @@ -137,14 +139,14 @@ static inline std::string x509_get_field(::X509 *cert, const int nid) { static const char nullc = '\0'; std::string ret; - X509_NAME *x509_name = X509_get_subject_name(cert); + const X509_NAME *x509_name = X509_get_subject_name(cert); int i = X509_NAME_get_index_by_NID(x509_name, nid, -1); if (i >= 0) { - X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i); + const X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i); if (ent) { - ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent); + const ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent); unsigned char *buf; buf = (unsigned char *)1; // bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 // requires this workaround @@ -162,7 +164,9 @@ static inline std::string x509_get_field(::X509 *cert, const int nid) i = X509_get_ext_by_NID(cert, nid, -1); if (i >= 0) { - X509_EXTENSION *ext = X509_get_ext(cert, i); + /* auto is used here to get const with newer OpenSSL 4.0 and without const + * otherwise to match the call to X509V3_EXT_print */ + auto *ext = X509_get_ext(cert, i); if (ext) { BIO *bio = BIO_new(BIO_s_mem()); @@ -194,21 +198,28 @@ static inline std::string x509_get_field(::X509 *cert, const int nid) * * @return Returns the numeric representation of the certificate serial number * as a std::string. + * + * In case of failure, an empty string is returned. */ static inline std::string x509_get_serial(::X509 *cert) { const ASN1_INTEGER *asn1_i = X509_get_serialNumber(cert); - BIGNUM *bignum = ASN1_INTEGER_to_BN(asn1_i, NULL); - char *openssl_serial = BN_bn2dec(bignum); - BN_free(bignum); + const OpenSSLPKI::BIGNUM_ptr bignum(ASN1_INTEGER_to_BN(asn1_i, nullptr), BN_free); + if (!bignum) + { + return {}; + } - if (openssl_serial) + char *openssl_serial = BN_bn2dec(bignum.get()); + + if (!openssl_serial) { - const std::string ret = openssl_serial; - OPENSSL_free(openssl_serial); - return ret; + return {}; } - return std::string(); + + const std::string ret = openssl_serial; + OPENSSL_free(openssl_serial); + return ret; } /** @@ -219,11 +230,23 @@ static inline std::string x509_get_serial(::X509 *cert) * * @return Returns the hexadecimal representation of the certificate * serial number as a std::string. + * + * In case of failure, an empty string is returned. */ static inline std::string x509_get_serial_hex(::X509 *cert) { - const ASN1_INTEGER *asn1_i = X509_get_serialNumber(cert); - return render_hex_sep(asn1_i->data, asn1_i->length, ':', false); + const ASN1_INTEGER *asn1_i = X509_get0_serialNumber(cert); + const OpenSSLPKI::BIGNUM_ptr serial(ASN1_INTEGER_to_BN(asn1_i, nullptr), BN_free); + + if (!serial) + return {}; + + int numbytesoutput = BN_num_bytes(serial.get()); + + std::unique_ptr<unsigned char[]> buf(new unsigned char[numbytesoutput]); + + BN_bn2binpad(serial.get(), buf.get(), numbytesoutput); + return render_hex_sep(buf.get(), numbytesoutput, ':', false); } /** diff --git a/openvpn3-core/openvpn/openssl/ssl/sslctx.hpp b/openvpn3-core/openvpn/openssl/ssl/sslctx.hpp index bf612b894..63be115a1 100644 --- a/openvpn3-core/openvpn/openssl/ssl/sslctx.hpp +++ b/openvpn3-core/openvpn/openssl/ssl/sslctx.hpp @@ -1824,16 +1824,17 @@ class OpenSSLContext : public SSLFactoryAPI const ASN1_INTEGER *ai = X509_get_serialNumber(cert); if (!ai) return; - if (ai->type == V_ASN1_NEG_INTEGER) // negative serial number is considered to be undefined + + OpenSSLPKI::BIGNUM_ptr bn(ASN1_INTEGER_to_BN(ai, nullptr), BN_free); + if (!bn) return; - if (!is_safe_conversion<int>(authcert.serial.size())) + if (BN_is_negative(bn.get())) // negative serial number is considered to be undefined return; - BIGNUM *bn = ASN1_INTEGER_to_BN(ai, NULL); - if (!bn) + + if (!is_safe_conversion<int>(authcert.serial.size())) return; - BN_bn2binpad(bn, authcert.serial.number(), static_cast<int>(authcert.serial.size())); - BN_free(bn); + BN_bn2binpad(bn.get(), authcert.serial.number(), static_cast<int>(authcert.serial.size())); } static std::string cert_status_line(int preverify_ok,

