]> granicus.if.org Git - icinga2/commitdiff
Make sure the serial number field is always initialized
authorGunnar Beutner <gunnar@beutner.name>
Tue, 18 Aug 2015 12:40:23 +0000 (14:40 +0200)
committerGunnar Beutner <gunnar@beutner.name>
Tue, 18 Aug 2015 13:05:53 +0000 (15:05 +0200)
fixes #9947

lib/base/tlsutility.cpp
lib/base/tlsutility.hpp
lib/cli/pkiutility.cpp

index 3d5c8fe92e7c0da4fc1b9c2ca4176b79e1091db4..37f3328ce5d2b44a273c4e141d77688b6e10e65d 100644 (file)
@@ -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 <fstream>
@@ -247,7 +248,7 @@ boost::shared_ptr<X509> GetX509Certificate(const String& pemfile)
        return boost::shared_ptr<X509>(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];
 
@@ -291,7 +292,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<X509> cert = CreateCert(key, subject, subject, key, ca);
+               boost::shared_ptr<X509> cert = CreateCert(key, subject, subject, key, ca, serialfile);
 
                X509_NAME_free(subject);
 
@@ -379,16 +380,18 @@ boost::shared_ptr<X509> CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NA
        X509_set_subject_name(cert, subject);
        X509_set_issuer_name(cert, issuer);
 
-       if (!serialfile.IsEmpty()) {
-               int serial = 0;
-
-               std::ifstream ifp;
-               ifp.open(serialfile.CStr());
-               ifp >> std::hex >> serial;
-               ifp.close();
+       int serial = 1;
 
-               if (ifp.fail())
-                       BOOST_THROW_EXCEPTION(std::runtime_error("Could not read serial file."));
+       if (!serialfile.IsEmpty()) {
+               if (Utility::PathExists(serialfile)) {
+                       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."));
+               }
 
                std::ofstream ofp;
                ofp.open(serialfile.CStr());
@@ -397,22 +400,28 @@ boost::shared_ptr<X509> 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<char *>("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<char *>(attr));
+
+       if (ext)
+               X509_add_ext(cert, ext, -1);
+
+       X509_EXTENSION_free(ext);
 
        X509_sign(cert, cakey, EVP_sha256());
 
index c3b5f07fc091ec630df99f9fbe4e9a301b1eb50e..d994754c98a9471290f3537c2ccf0280ff9bcf62 100644 (file)
@@ -42,7 +42,7 @@ boost::shared_ptr<SSL_CTX> I2_BASE_API MakeSSLContext(const String& pubkey, cons
 void I2_BASE_API AddCRLToSSLContext(const boost::shared_ptr<SSL_CTX>& context, const String& crlPath);
 String I2_BASE_API GetCertificateCN(const boost::shared_ptr<X509>& certificate);
 boost::shared_ptr<X509> 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<X509> 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<X509>& cert);
index 9a1c11ef099e5f5dbe0366b0511a05d17f7361cd..5c49006d7bb35d61d801ea0c8ea13c2e125bb8b9 100644 (file)
@@ -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;
 }