From 6ffdbce21318ab2ade78c92401e4f02942b31b38 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Tue, 18 Aug 2015 14:40:23 +0200 Subject: [PATCH] Make sure the serial number field is always initialized fixes #9947 --- lib/base/tlsutility.cpp | 53 ++++++++++++++++++++++++----------------- lib/base/tlsutility.hpp | 2 +- lib/cli/pkiutility.cpp | 18 +------------- 3 files changed, 33 insertions(+), 40 deletions(-) diff --git a/lib/base/tlsutility.cpp b/lib/base/tlsutility.cpp index 1e40d4e05..81ce1f56f 100644 --- a/lib/base/tlsutility.cpp +++ b/lib/base/tlsutility.cpp @@ -21,6 +21,7 @@ #include "base/convert.hpp" #include "base/logger.hpp" #include "base/context.hpp" +#include "base/utility.hpp" #include "base/application.hpp" #include "base/exception.hpp" #include @@ -246,7 +247,7 @@ boost::shared_ptr GetX509Certificate(const String& pemfile) return boost::shared_ptr(cert, X509_free); } -int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile, const String& certfile, bool ca) +int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile, const String& certfile, const String& serialfile, bool ca) { char errbuf[120]; @@ -290,7 +291,7 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile, X509_NAME *subject = X509_NAME_new(); X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC, (unsigned char *)cn.CStr(), -1, -1, 0); - boost::shared_ptr cert = CreateCert(key, subject, subject, key, ca); + boost::shared_ptr cert = CreateCert(key, subject, subject, key, ca, serialfile); X509_NAME_free(subject); @@ -378,16 +379,18 @@ boost::shared_ptr CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NA X509_set_subject_name(cert, subject); X509_set_issuer_name(cert, issuer); + int serial = 1; + if (!serialfile.IsEmpty()) { - int serial = 0; + if (Utility::PathExists(serialfile)) { + std::ifstream ifp; + ifp.open(serialfile.CStr()); + ifp >> std::hex >> serial; + ifp.close(); - std::ifstream ifp; - ifp.open(serialfile.CStr()); - ifp >> std::hex >> serial; - ifp.close(); - - if (ifp.fail()) - BOOST_THROW_EXCEPTION(std::runtime_error("Could not read serial file.")); + if (ifp.fail()) + BOOST_THROW_EXCEPTION(std::runtime_error("Could not read serial file.")); + } std::ofstream ofp; ofp.open(serialfile.CStr()); @@ -396,22 +399,28 @@ boost::shared_ptr CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NA if (ofp.fail()) BOOST_THROW_EXCEPTION(std::runtime_error("Could not update serial file.")); - - ASN1_INTEGER_set(X509_get_serialNumber(cert), serial); } - if (ca) { - X509_EXTENSION *ext; - X509V3_CTX ctx; - X509V3_set_ctx_nodb(&ctx); - X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); - ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, const_cast("critical,CA:TRUE")); + ASN1_INTEGER_set(X509_get_serialNumber(cert), serial); - if (ext) - X509_add_ext(cert, ext, -1); + X509_EXTENSION *ext; + X509V3_CTX ctx; + X509V3_set_ctx_nodb(&ctx); + X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); - X509_EXTENSION_free(ext); - } + const char *attr; + + if (ca) + attr = "critical,CA:TRUE"; + else + attr = "critical,CA:FALSE"; + + ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, const_cast(attr)); + + if (ext) + X509_add_ext(cert, ext, -1); + + X509_EXTENSION_free(ext); X509_sign(cert, cakey, EVP_sha256()); diff --git a/lib/base/tlsutility.hpp b/lib/base/tlsutility.hpp index c3b5f07fc..d994754c9 100644 --- a/lib/base/tlsutility.hpp +++ b/lib/base/tlsutility.hpp @@ -42,7 +42,7 @@ boost::shared_ptr I2_BASE_API MakeSSLContext(const String& pubkey, cons void I2_BASE_API AddCRLToSSLContext(const boost::shared_ptr& context, const String& crlPath); String I2_BASE_API GetCertificateCN(const boost::shared_ptr& certificate); boost::shared_ptr I2_BASE_API GetX509Certificate(const String& pemfile); -int I2_BASE_API MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile = String(), const String& certfile = String(), bool ca = false); +int I2_BASE_API MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile = String(), const String& certfile = String(), const String& serialFile = String(), bool ca = false); boost::shared_ptr I2_BASE_API CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, bool ca, const String& serialfile = String()); String I2_BASE_API GetIcingaCADir(void); String I2_BASE_API CertificateToString(const boost::shared_ptr& cert); diff --git a/lib/cli/pkiutility.cpp b/lib/cli/pkiutility.cpp index 9a1c11ef0..5c49006d7 100644 --- a/lib/cli/pkiutility.cpp +++ b/lib/cli/pkiutility.cpp @@ -59,23 +59,7 @@ int PkiUtility::NewCa(void) return 1; } - MakeX509CSR("Icinga CA", cadir + "/ca.key", String(), cadir + "/ca.crt", true); - - String serialpath = cadir + "/serial.txt"; - - Log(LogInformation, "cli") - << "Initializing serial file in '" << serialpath << "'."; - - std::ofstream fp; - fp.open(serialpath.CStr()); - fp << "01"; - fp.close(); - - if (fp.fail()) { - Log(LogCritical, "cli") - << "Could not create serial file '" << serialpath << "'"; - return 1; - } + MakeX509CSR("Icinga CA", cadir + "/ca.key", String(), cadir + "/ca.crt", cadir + "/serial.txt", true); return 0; }