Skip to content

Commit ec26a2d

Browse files
committed
Test internal cert generation & verification process
1 parent 87df80d commit ec26a2d

File tree

8 files changed

+216
-118
lines changed

8 files changed

+216
-118
lines changed

lib/base/tlsutility.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ std::shared_ptr<X509> GetX509Certificate(const String& pemfile)
478478
return std::shared_ptr<X509>(cert, X509_free);
479479
}
480480

481-
int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile, const String& certfile, bool ca)
481+
int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile, const String& certfile, int validFor, bool ca)
482482
{
483483
char errbuf[256];
484484

@@ -547,7 +547,7 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
547547
X509_NAME *subject = X509_NAME_new();
548548
X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC, (unsigned char *)cn.CStr(), -1, -1, 0);
549549

550-
std::shared_ptr<X509> cert = CreateCert(key, subject, subject, key, ca);
550+
std::shared_ptr<X509> cert = CreateCert(key, subject, subject, key, validFor, ca);
551551

552552
X509_NAME_free(subject);
553553

@@ -640,12 +640,16 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
640640
return 1;
641641
}
642642

643-
std::shared_ptr<X509> CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, bool ca)
643+
std::shared_ptr<X509> CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, int validFor, bool ca)
644644
{
645645
X509 *cert = X509_new();
646646
X509_set_version(cert, 2);
647-
X509_gmtime_adj(X509_get_notBefore(cert), 0);
648-
X509_gmtime_adj(X509_get_notAfter(cert), ca ? ROOT_VALID_FOR : LEAF_VALID_FOR);
647+
auto notBefore = 0;
648+
if (validFor < 0) {
649+
notBefore = validFor - validFor / 4; // Add 25% of the validity period to the past
650+
}
651+
X509_gmtime_adj(X509_get_notBefore(cert), notBefore);
652+
X509_gmtime_adj(X509_get_notAfter(cert), validFor);
649653
X509_set_pubkey(cert, pubkey);
650654

651655
X509_set_subject_name(cert, subject);
@@ -728,7 +732,7 @@ String GetIcingaCADir()
728732
return Configuration::DataDir + "/ca";
729733
}
730734

731-
std::shared_ptr<X509> CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject, bool ca)
735+
std::shared_ptr<X509> CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject, int validFor, bool ca)
732736
{
733737
char errbuf[256];
734738

@@ -765,13 +769,20 @@ std::shared_ptr<X509> CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject, b
765769
EVP_PKEY *privkey = EVP_PKEY_new();
766770
EVP_PKEY_assign_RSA(privkey, rsa);
767771

768-
return CreateCert(pubkey, subject, X509_get_subject_name(cacert.get()), privkey, ca);
772+
return CreateCert(pubkey, subject, X509_get_subject_name(cacert.get()), privkey, validFor, ca);
769773
}
770774

771-
std::shared_ptr<X509> CreateCertIcingaCA(const std::shared_ptr<X509>& cert)
775+
/**
776+
* Creates a new X509 certificate signed by the Icinga CA.
777+
*
778+
* @param cert The certificate containing the public key and subject name.
779+
* @param validFor The validity period in seconds. Defaults to LEAF_VALID_FOR.
780+
* @returns The new X509 certificate or an empty shared_ptr on error.
781+
*/
782+
std::shared_ptr<X509> CreateCertIcingaCA(const std::shared_ptr<X509>& cert, int validFor)
772783
{
773784
std::shared_ptr<EVP_PKEY> pkey = std::shared_ptr<EVP_PKEY>(X509_get_pubkey(cert.get()), EVP_PKEY_free);
774-
return CreateCertIcingaCA(pkey.get(), X509_get_subject_name(cert.get()));
785+
return CreateCertIcingaCA(pkey.get(), X509_get_subject_name(cert.get()), validFor);
775786
}
776787

777788
static inline

lib/base/tlsutility.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ Shared<boost::asio::ssl::context>::Ptr SetupSslContext(String certPath, String k
5454

5555
String GetCertificateCN(const std::shared_ptr<X509>& certificate);
5656
std::shared_ptr<X509> GetX509Certificate(const String& pemfile);
57-
int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile = String(), const String& certfile = String(), bool ca = false);
58-
std::shared_ptr<X509> CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, bool ca);
57+
int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile = String(), const String& certfile = String(), int validFor = LEAF_VALID_FOR, bool ca = false);
58+
std::shared_ptr<X509> CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, int validFor, bool ca);
5959

6060
String GetIcingaCADir();
6161
String CertificateToString(X509* cert);
@@ -66,8 +66,8 @@ inline String CertificateToString(const std::shared_ptr<X509>& cert)
6666
}
6767

6868
std::shared_ptr<X509> StringToCertificate(const String& cert);
69-
std::shared_ptr<X509> CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject, bool ca = false);
70-
std::shared_ptr<X509> CreateCertIcingaCA(const std::shared_ptr<X509>& cert);
69+
std::shared_ptr<X509> CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject, int validFor, bool ca = false);
70+
std::shared_ptr<X509> CreateCertIcingaCA(const std::shared_ptr<X509>& cert, int validFor = LEAF_VALID_FOR);
7171
bool IsCertUptodate(const std::shared_ptr<X509>& cert);
7272
bool IsCaUptodate(X509* cert);
7373

lib/remote/apilistener.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ std::shared_ptr<X509> ApiListener::RenewCert(const std::shared_ptr<X509>& cert,
186186
std::shared_ptr<EVP_PKEY> pubkey (X509_get_pubkey(cert.get()), EVP_PKEY_free);
187187
auto subject (X509_get_subject_name(cert.get()));
188188
auto cacert (GetX509Certificate(GetDefaultCaPath()));
189-
auto newcert (CreateCertIcingaCA(pubkey.get(), subject, ca));
189+
auto newcert (CreateCertIcingaCA(pubkey.get(), subject, ca ? ROOT_VALID_FOR : LEAF_VALID_FOR, ca));
190190

191191
/* verify that the new cert matches the CA we're using for the ApiListener;
192192
* this ensures that the CA we have in /var/lib/icinga2/ca matches the one

lib/remote/pkiutility.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include "base/logger.hpp"
88
#include "base/application.hpp"
99
#include "base/tcpsocket.hpp"
10-
#include "base/tlsutility.hpp"
1110
#include "base/console.hpp"
1211
#include "base/tlsstream.hpp"
1312
#include "base/tcpsocket.hpp"
@@ -37,7 +36,7 @@ int PkiUtility::NewCa()
3736

3837
Utility::MkDirP(caDir, 0700);
3938

40-
MakeX509CSR("Icinga CA", caKeyFile, String(), caCertFile, true);
39+
MakeX509CSR("Icinga CA", caKeyFile, String(), caCertFile, ROOT_VALID_FOR, true);
4140

4241
return 0;
4342
}
@@ -53,7 +52,7 @@ int PkiUtility::NewCert(const String& cn, const String& keyfile, const String& c
5352
return 0;
5453
}
5554

56-
int PkiUtility::SignCsr(const String& csrfile, const String& certfile)
55+
int PkiUtility::SignCsr(const String& csrfile, const String& certfile, long validFor)
5756
{
5857
char errbuf[256];
5958

@@ -72,7 +71,7 @@ int PkiUtility::SignCsr(const String& csrfile, const String& certfile)
7271
BIO_free(csrbio);
7372

7473
std::shared_ptr<EVP_PKEY> pubkey = std::shared_ptr<EVP_PKEY>(X509_REQ_get_pubkey(req), EVP_PKEY_free);
75-
std::shared_ptr<X509> cert = CreateCertIcingaCA(pubkey.get(), X509_REQ_get_subject_name(req));
74+
std::shared_ptr<X509> cert = CreateCertIcingaCA(pubkey.get(), X509_REQ_get_subject_name(req), validFor);
7675

7776
X509_REQ_free(req);
7877

lib/remote/pkiutility.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "base/exception.hpp"
88
#include "base/dictionary.hpp"
99
#include "base/string.hpp"
10+
#include "base/tlsutility.hpp"
1011
#include <openssl/x509v3.h>
1112
#include <memory>
1213

@@ -21,7 +22,7 @@ class PkiUtility
2122
public:
2223
static int NewCa();
2324
static int NewCert(const String& cn, const String& keyfile, const String& csrfile, const String& certfile);
24-
static int SignCsr(const String& csrfile, const String& certfile);
25+
static int SignCsr(const String& csrfile, const String& certfile, long validFor = LEAF_VALID_FOR);
2526
static std::shared_ptr<X509> FetchCert(const String& host, const String& port);
2627
static int WriteCert(const std::shared_ptr<X509>& cert, const String& trustedfile);
2728
static int GenTicket(const String& cn, const String& salt, std::ostream& ticketfp);

test/CMakeLists.txt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,8 @@ add_boost_test(base
176176
base_timer/invoke
177177
base_timer/scope
178178
base_tlsutility/sha1
179-
base_tlsutility/iscauptodate_ok
180-
base_tlsutility/iscauptodate_expiring
181-
base_tlsutility/iscertuptodate_ok
182-
base_tlsutility/iscertuptodate_expiring
183-
base_tlsutility/iscertuptodate_old
184-
base_tlsutility/VerifyCertificate_revalidate
179+
base_tlsutility/create_verify_ca
180+
base_tlsutility/create_verify_leaf_certs
185181
base_utility/parse_version
186182
base_utility/compare_version
187183
base_utility/comparepasswords_works

0 commit comments

Comments
 (0)