diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 663c4dd0264..8bc2dc4f091 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -37,6 +37,7 @@ jobs: - fedora:42 - fedora:43 - fedora:44 + - fedora:45 - opensuse/leap:15.6 - opensuse/leap:16.0 diff --git a/lib/base/tlsutility.cpp b/lib/base/tlsutility.cpp index bf8a2076345..9ba840b43aa 100644 --- a/lib/base/tlsutility.cpp +++ b/lib/base/tlsutility.cpp @@ -403,7 +403,7 @@ void AddCRLToSSLContext(X509_STORE *x509_store, const String& crlPath) X509_VERIFY_PARAM_free(param); } -static String GetX509NameCN(X509_NAME *name) +static String GetX509NameCN(X509NameConstPtr name) { char errbuf[256]; char buffer[256]; @@ -598,8 +598,25 @@ int MakeX509CSR( X509_REQ_set_version(req, 0); X509_REQ_set_pubkey(req, key); - X509_NAME *name = X509_REQ_get_subject_name(req); - X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)cn.CStr(), -1, -1, 0); + std::unique_ptr name{X509_NAME_new(), &X509_NAME_free}; + if (!name) { + unsigned long err = ERR_peek_error(); + BOOST_THROW_EXCEPTION(openssl_error() + << boost::errinfo_api_function("X509_NAME_new") + << errinfo_openssl_error(err)); + } + + X509_NAME_add_entry_by_txt(name.get(), "CN", MBSTRING_ASC, (unsigned char *)cn.CStr(), -1, -1, 0); + + if (!X509_REQ_set_subject_name(req, name.get())) { + unsigned long err = ERR_peek_error(); + ERR_error_string_n(err, errbuf, sizeof errbuf); + Log(LogCritical, "SSL") + << "Error while setting CSR subject name: " << err << ", \"" << errbuf << "\""; + BOOST_THROW_EXCEPTION(openssl_error() + << boost::errinfo_api_function("X509_REQ_set_subject_name") + << errinfo_openssl_error(err)); + } if (!ca) { String san = "DNS:" + cn; @@ -652,8 +669,8 @@ int MakeX509CSR( std::shared_ptr CreateCert( EVP_PKEY* pubkey, - X509_NAME* subject, - X509_NAME* issuer, + X509NameConstPtr subject, + X509NameConstPtr issuer, EVP_PKEY* cakey, long validFrom, long validFor, @@ -746,7 +763,7 @@ String GetIcingaCADir() return Configuration::DataDir + "/ca"; } -std::shared_ptr CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject, long validFrom, long validFor, bool ca) +std::shared_ptr CreateCertIcingaCA(EVP_PKEY *pubkey, X509NameConstPtr subject, long validFrom, long validFor, bool ca) { char errbuf[256]; diff --git a/lib/base/tlsutility.hpp b/lib/base/tlsutility.hpp index 008fc90d69b..d39523c9a9b 100644 --- a/lib/base/tlsutility.hpp +++ b/lib/base/tlsutility.hpp @@ -39,6 +39,11 @@ const auto LEAF_VALID_FOR = 60 * 60 * 24 * 397; const auto RENEW_THRESHOLD = 60 * 60 * 24 * 30; const auto RENEW_INTERVAL = 60 * 60 * 24; +// Tracks the constness of X509_NAME* across OpenSSL versions: on 1.x getters return X509_NAME* and +// setters expect X509_NAME*; on 4.x both sides became const X509_NAME*. Using decltype on the getter +// gives us the right type automatically, so we can accept getter results and pass to setters cast-free. +using X509NameConstPtr = decltype(X509_get_subject_name(nullptr)); + void InitializeOpenSSL(); String GetOpenSSLVersion(); @@ -66,8 +71,8 @@ int MakeX509CSR( ); std::shared_ptr CreateCert( EVP_PKEY* pubkey, - X509_NAME* subject, - X509_NAME* issuer, + X509NameConstPtr subject, + X509NameConstPtr issuer, EVP_PKEY* cakey, long validFrom, long validFor, @@ -83,7 +88,7 @@ inline String CertificateToString(const std::shared_ptr& cert) } std::shared_ptr StringToCertificate(const String& cert); -std::shared_ptr CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject, long validFrom, long validFor, bool ca = false); +std::shared_ptr CreateCertIcingaCA(EVP_PKEY *pubkey, X509NameConstPtr subject, long validFrom, long validFor, bool ca = false); std::shared_ptr CreateCertIcingaCA(const std::shared_ptr& cert, long validFrom = 0, long validFor = LEAF_VALID_FOR); bool IsCertUptodate(const std::shared_ptr& cert); bool IsCaUptodate(X509* cert); diff --git a/lib/remote/pkiutility.cpp b/lib/remote/pkiutility.cpp index c8c6b01174a..bd36b947854 100644 --- a/lib/remote/pkiutility.cpp +++ b/lib/remote/pkiutility.cpp @@ -345,10 +345,8 @@ String PkiUtility::GetCertificateInformation(const std::shared_ptr& cert) pre = "\n Serial: "; BIO_write(out, pre.CStr(), pre.GetLength()); - ASN1_INTEGER *asn1_serial = X509_get_serialNumber(cert.get()); - for (int i = 0; i < asn1_serial->length; i++) { - BIO_printf(out, "%02x%c", asn1_serial->data[i], ((i + 1 == asn1_serial->length) ? '\n' : ':')); - } + i2a_ASN1_INTEGER(out, X509_get0_serialNumber(cert.get())); + BIO_write(out, "\n", 1); pre = "\n Signature Algorithm: " + GetSignatureAlgorithm(cert); BIO_write(out, pre.CStr(), pre.GetLength());