Skip to content

Commit

Permalink
Test VerifyCertificate()
Browse files Browse the repository at this point in the history
  • Loading branch information
Al2Klimov committed Jan 29, 2025
1 parent d55c364 commit e98084c
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 6 deletions.
16 changes: 11 additions & 5 deletions lib/base/tlsutility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -981,21 +981,27 @@ String BinaryToHex(const unsigned char* data, size_t length) {
return output;
}

bool VerifyCertificate(const std::shared_ptr<X509> &caCertificate, const std::shared_ptr<X509> &certificate, const String& crlFile)
bool VerifyCertificate(
const std::shared_ptr<X509>& caCertificate, const std::shared_ptr<X509>& certificate, const String& crlFile,
X509_STORE* (*mockX509_STORE_new)(),
int (*mockX509_STORE_add_cert)(X509_STORE*, X509*),
X509_STORE_CTX* (*mockX509_STORE_CTX_new)(),
int (*mockX509_STORE_CTX_init)(X509_STORE_CTX*, X509_STORE*, X509*, STACK_OF(X509)*)
)
{
X509_STORE *store = X509_STORE_new();
X509_STORE *store = mockX509_STORE_new();

if (!store)
return false;

X509_STORE_add_cert(store, caCertificate.get());
mockX509_STORE_add_cert(store, caCertificate.get());

if (!crlFile.IsEmpty()) {
AddCRLToSSLContext(store, crlFile);
}

X509_STORE_CTX *csc = X509_STORE_CTX_new();
X509_STORE_CTX_init(csc, store, certificate.get(), nullptr);
X509_STORE_CTX *csc = mockX509_STORE_CTX_new();
mockX509_STORE_CTX_init(csc, store, certificate.get(), nullptr);

int rc = X509_verify_cert(csc);

Expand Down
9 changes: 8 additions & 1 deletion lib/base/tlsutility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,14 @@ String SHA256(const String& s);
String RandomString(int length);
String BinaryToHex(const unsigned char* data, size_t length);

bool VerifyCertificate(const std::shared_ptr<X509>& caCertificate, const std::shared_ptr<X509>& certificate, const String& crlFile);
bool VerifyCertificate(
const std::shared_ptr<X509>& caCertificate, const std::shared_ptr<X509>& certificate, const String& crlFile,
X509_STORE* (*mockX509_STORE_new)() = X509_STORE_new,
int (*mockX509_STORE_add_cert)(X509_STORE*, X509*) = X509_STORE_add_cert,
X509_STORE_CTX* (*mockX509_STORE_CTX_new)() = X509_STORE_CTX_new,
int (*mockX509_STORE_CTX_init)(X509_STORE_CTX*, X509_STORE*, X509*, STACK_OF(X509)*) = X509_STORE_CTX_init
);

bool IsCa(const std::shared_ptr<X509>& cacert);
int GetCertificateVersion(const std::shared_ptr<X509>& cert);
String GetSignatureAlgorithm(const std::shared_ptr<X509>& cert);
Expand Down
8 changes: 8 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ add_boost_test(base
base_tlsutility/iscertuptodate_ok
base_tlsutility/iscertuptodate_expiring
base_tlsutility/iscertuptodate_old
base_tlsutility/verifycertificate_ok
base_tlsutility/verifycertificate_leafexpired
base_tlsutility/verifycertificate_caexpired
base_tlsutility/verifycertificate_sigmismatch
base_tlsutility/verifycertificate_X509_STORE_new
base_tlsutility/verifycertificate_X509_STORE_add_cert
base_tlsutility/verifycertificate_X509_STORE_CTX_new
base_tlsutility/verifycertificate_X509_STORE_CTX_init
base_utility/parse_version
base_utility/compare_version
base_utility/comparepasswords_works
Expand Down
139 changes: 139 additions & 0 deletions test/base-tlsutility-certs.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/* Icinga 2 | (c) 2025 Icinga GmbH | GPLv2+ */

// openssl req -x509 -subj /CN=IcingaCA -days 1000000 -newkey rsa:2048 -keyout IcingaCA.key -out IcingaCA.crt -nodes
static const auto l_IcingaCa = R"(
-----BEGIN CERTIFICATE-----
MIIDCTCCAfGgAwIBAgIUdgi1ZtjKYbwQLTgZK3uEesJ7bLMwDQYJKoZIhvcNAQEL
BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwIBcNMjUwMTI5MTExMjI3WhgPNDc2MjEy
MjcxMTEyMjdaMBMxETAPBgNVBAMMCEljaW5nYUNBMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAx3gRHqvT78saJhmuB0IIMy6LsKASh7T/JV/MDLqPYRBM
JyyuEJUWfxc7M7vQsd7VIKbalcdP7+5q1ChCyef68mwmKHMgxjVytmnlaFp06m6b
bHKW4CPPbcAVJA5J6IOMjbYoJJb3B+D92MCj+cA/1TBOMRYNPumjlKn2S7zdeas7
YdQcoO9IT66jp+2+olYfEm/Feef9q0tFlaDnBSD8Fi06O2S7yOv1smUvbUjO27Bp
t5ISVYGAYjPTMfNw9T2YiKcmwtcXi1uwFVdlcyzCyI1uOsJKrqU8wL6vbcTbTJmk
mJuk6EzvGIK5gYKys1swfPkBqTPrQ9bAwsrFMo2wNQIDAQABo1MwUTAdBgNVHQ4E
FgQU6FNaouiwNt1OpoxxxBHx5zx21VEwHwYDVR0jBBgwFoAU6FNaouiwNt1Opoxx
xBHx5zx21VEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAE50o
aLhRrQo0OONxHgZin1azVhCwvEhDdvpREgPMx8RIIkACbpTBc1qD+5Td3/OOi7TF
OanoHyOkPHyjBIlp55iHPEWBTBLBtO9Q5wyv/cg6tNt3xm8P1x0vxS+TrIKhtPzF
IkiJULki4fJARuFj8f/E2kwu+EA3swwqSfAeRUzY8yChdyWyVn+s17ll5OOjjZCA
q1CodrFEk0ZuH5qNTmcLk5GUdUnZEISmRiOcsG66uSzl7WpWGECtK4amRFv+XTij
bRANBuRWGyaw1UpD2RnJKvbTjURbdI8/4ZcgBNk0rbaJQZhRcN59y1wbXp6OYVdE
mB3zuwxqEBlWqr6J6A==
-----END CERTIFICATE-----
)";

// openssl req -x509 -subj /CN=example.com -CA IcingaCA.crt -CAkey IcingaCA.key -days 1000000 -newkey rsa:2048 -keyout example.key -out example.crt -nodes
static const auto l_ExampleCrt = R"(
-----BEGIN CERTIFICATE-----
MIIDDDCCAfSgAwIBAgIUCBXnZvr6kQAzDUEI8y32Dfv0RZIwDQYJKoZIhvcNAQEL
BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwIBcNMjUwMTI5MTExNTQwWhgPNDc2MjEy
MjcxMTE1NDBaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAqCcKAjgS5bKbyn3IC9Yj2UB7dVRlNCZTRt+w6US1
OtCPyhfK+V2IWHG52FZMX3xWEbzwkli9T7BSsTWqsG7nh5luuXkJSiBGaBFDTrHh
TgSEKYIrAv6RXExMmSH9wbrwlSObckVK0ao3cGAu5wOP6pQFJXhBcxfR8Bb0Tmys
IK8TeCWs5dw9+uL6naqhA7PXScmglxn0wt3Jq5HQvcLP9Q47boNvNRsdsH96UKYL
ParA/+VYN24G//K8SvdEauKLBWexs3deUIpvQ9XBZgi4TxhtLmGrSOD+BSRmZtbS
mrJ8teYa8Wn8UqSHn0XkmcJYc4Id5iR8LWjW0K+7+5W1AQIDAQABo1MwUTAdBgNV
HQ4EFgQUCMkOtURchQvy5TD26SERzcPDIBEwHwYDVR0jBBgwFoAU6FNaouiwNt1O
poxxxBHx5zx21VEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA
kS9cavcMaGIVmAu3zg9yJ2RTwn5sdVjnIdFtm2GdtFYXqCuy8cltGYBZa3ksq60k
2E0OuAzM2gnD2xCET+8Kv5SqhM5E/JSVsxp31siBR6Mn23scM16AGK+rThSYYjKU
NiFf0nWhTGZFXQQ+QpLeVbzxgZpy/6I2ae1uDZraSXkd+sChDE9jPTpYliOm2X6A
2r4VK8rtYCxvOy+mUsto37NiAVITXwnPRlKmOatv1Hh9kAhwK+qA0nyykIuef3NZ
uoTqHtDPAOSLBdtCNFh7HW2EuQSU3PLZ2xket8kqURTxxaLSkbsRSG7TqrLfBjMn
YFlQO4soVkFeFifh/aEQEw==
-----END CERTIFICATE-----
)";

// faketime -f -101d openssl req -x509 -subj /CN=example.com -CA IcingaCA.crt -CAkey IcingaCA.key -days 100 -newkey rsa:2048 -keyout expired.key -out expired.crt -nodes
static const auto l_ExpiredCrt = R"(
-----BEGIN CERTIFICATE-----
MIIDCjCCAfKgAwIBAgIUTRwVekfrn1W/65HaURylmpCD5q8wDQYJKoZIhvcNAQEL
BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwHhcNMjQxMDIwMTEzOTU1WhcNMjUwMTI4
MTEzOTU1WjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBALJYc86mEP0k2f1YCxYjm0UMR05PBh8FHqzhj6KiBPCE
rNzKUHJ3mwh4x7lNZtsQuYb2oLTbwvdPp8pBRSO1cDEPLMPl6KdmyfW/6nE4aOnd
4odX+nQXpwU5+fgsdHi9H796/CETzo7zYt1ZOegHPlXNVOCAWKpuwpM4wpD2Jc/U
18nOcPLc+gUyHHkFWnZG3R0RAzBM+Y6tyuTSua1Md+lZLYZbdR+TUlI+iQUVpS5L
VVlfMuvF1goqEGeFd995LDe1iAsaYeb0cwylANaE8Ntw1Y58F1YUeGp2nUQwitwn
cGkEtWW4aYpHmlLz0NWwi4VooBrfOE2e2vuHoTWdn4MCAwEAAaNTMFEwHQYDVR0O
BBYEFPy1bdiqQ77+R9wffW8byBI7m+IWMB8GA1UdIwQYMBaAFOhTWqLosDbdTqaM
ccQR8ec8dtVRMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAYQ
VWlT9HHgE6NxFwRdo6Pdyw7izzTDjQFgfWIFQN7PIXMriP3uCzoZ1lUeJShH4V8C
hliQIVbdH00oVK14H0WI+8pFIFtriVuYcwop93BOKZb7dGv6yPX0tjmWM03G7ykJ
o9HfIycRCUfvyY8++OO4oXiCIXbv0EefCd9GWP9IS1n0EK39L0QBbLp1pYbCJ4U3
LyDa/sHEflHdTUu+do1kCC9f8gnccw6oHwg/GNC3r5/FYBFKddDMsr49xNZCUlS7
CYoTlRVLcKCOxGOU7j1f2Vh0lbrCs9S8qMmyygutl5BSp8QH4XqXGAA3XcU91cc2
Rs6wtqbtpehBKbNCZew=
-----END CERTIFICATE-----
)";

// faketime -f -1001d openssl req -x509 -subj /CN=IcingaCA -days 1000 -newkey rsa:2048 -keyout expiredCA.key -out expiredCA.crt -nodes
static const auto l_ExpiredCa = R"(
-----BEGIN CERTIFICATE-----
MIIDBzCCAe+gAwIBAgIUIFiIyafR/fOJgdcPtE/2cMVzO5wwDQYJKoZIhvcNAQEL
BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwHhcNMjIwNTA0MTE0NzQyWhcNMjUwMTI4
MTE0NzQyWjATMREwDwYDVQQDDAhJY2luZ2FDQTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAMt4h56Ykpv5mImpnaTfnZBgDCwZj6+OTFIOhqE/Hcwb+rw3
EXiIzOuAj/3SOKJDIJHo7BAoZJ0IFl4+/hldim3EVp4i8xjrDL3vww8fyUXJliuO
Li/meuWmO2uTWaMNdXWiIvUYf1gIfBD1hIU2vznTca6NrRmTPLGGYRtV86HhM+tZ
IyWF3O7VmNZBpuj/kHAUQT+RBXxP3J3rf73ICTJvVGBpQshlnxE1uFiEXPfhk2LJ
AXtXmVMXDNaVsNT8kv7hUsKwtpNrmIpAM//kJZl42qEmG/dJ4JYIgU+wy54b/gEM
tWcit9/4Dz7dO4dJPyd1RXRkRLJ1yoXATVuR/kECAwEAAaNTMFEwHQYDVR0OBBYE
FMD7oeGGYaB8CDTzHNaqfJ4pJDW+MB8GA1UdIwQYMBaAFMD7oeGGYaB8CDTzHNaq
fJ4pJDW+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAER61Zzv
Cta8soW4pac9tX3MpTqHvGer/H8gxpRc3hAMBYBdHH9iToRv2e1B8XAr1aD9nDTZ
kpSxrQ6QcIvcNaopZ+4BpgQA0OcnpiJvy1NrzJy4/OXsCwhss4TCi3iGrRFeRscj
1bNRqF6uQUSpGO3Pyr9NRI7uKCxLx0GebjI3m7I1XtdbhO+pCGJxIX7BBgBCyg2S
Rg3NO6D62M2CIXMzmNkUOuEPP8X04gHJG8lenTj/4XA2FRtl3BDkmpgNT+EvXgrE
iKN5RJmanof6Cl3i+5z2G9EE78IKKc1lwIMGEl3TBwBc9vbLGXnyxhQ1KYmdYdMk
qk/B5CUJdl6x4SU=
-----END CERTIFICATE-----
)";

// faketime -f -1001d openssl req -x509 -subj /CN=example.com -CA expiredCA.crt -CAkey expiredCA.key -days 1000000 -newkey rsa:2048 -keyout expiredCAleaf.key -out expiredCAleaf.crt -nodes
static const auto l_ExpiredCaLeaf = R"(
-----BEGIN CERTIFICATE-----
MIIDDDCCAfSgAwIBAgIUdHDoIg27fMxCE8+8qVKG6bkbgAAwDQYJKoZIhvcNAQEL
BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwIBcNMjIwNTA0MTE1MTEyWhgPNDc2MDAz
MzExMTUxMTJaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAv0Fy1zM4r6cs/L4ijHNijQBS0bZPdw+oJQ6wuHS2
wWvSu3rEd42SkwPHb6l5xnazpNiJ6e/QsgjNAe/O2fe2FdShvAQpTEEZDWG5YUHQ
CUULHiLIL3WE7+QbE/L+qv0eeTHsGRvdqlyJfSF6dNpCpfAI+/cwvaQ9+ISGnlyo
xQsvW2oirPJL2Op9UGhA4GuUbjA63W8wZTVnb7WGXpBpUx8igwrEO8cmAgNqDf8a
QuOBcwncbHRiLn+OOFbQ09+PfyqIWsY+HEdSarKsfTcKCH3bdbX1mB3FuPBlioVk
jzo28QvRXrsRVmLdO1Z8KwtDO1J3K+lIlD8ciSIyfkAmeQIDAQABo1MwUTAdBgNV
HQ4EFgQUGM6M1c/X4oIQW6iulEu4v8pgANgwHwYDVR0jBBgwFoAUwPuh4YZhoHwI
NPMc1qp8nikkNb4wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA
wuCTz+iBNm/0K4No1nNDg+CZ6Efh2aGYdd0ra568Q0qaUZvJBkDwHaV62x8c+7oy
g09CSVb5cxjukNak/1z0sArtxOSSPvQr8ZxAbIlBsJLHlUt5qxIDpFar/AUvejPW
SRwXfXoqZvxhvotIVDpC7LyzLv1uGEVC2ut/mdKSRdfC8bjNgvDPueix2IiLuqwD
axtsq0DNuLCml/rFaDpv9GhjEd2BHtd9WkkBE0aZkr7riCVVU+G4333V1lhepmM4
OEDL0q8bF+us7OOBcnKTf8/Z2FBSChX+iBmUx49bYbu+zsB7rd8bRctQ2QsBWrjE
0T27ijYgvlDxVhZkvgGjKg==
-----END CERTIFICATE-----
)";

// openssl req -x509 -subj /CN=IcingaCA -days 1000000 -newkey rsa:2048 -keyout IcingaCA2.key -out IcingaCA2.crt -nodes
static const auto l_IcingaCa2 = R"(
-----BEGIN CERTIFICATE-----
MIIDCTCCAfGgAwIBAgIUOpzxwnBk0qyMmc4kEQM27KXhkNEwDQYJKoZIhvcNAQEL
BQAwEzERMA8GA1UEAwwISWNpbmdhQ0EwIBcNMjUwMTI5MTExMjI5WhgPNDc2MjEy
MjcxMTEyMjlaMBMxETAPBgNVBAMMCEljaW5nYUNBMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAwOn0l2/lU3LG8U6vZLhpQp/3FJL3oKtEeH+sRvnPF2cU
PaUWhpS5oHTJyLlVyTDc8kzr4kteyI5vsB9y9hC9yCKoo/gfo/+qrBrmuB8lDoeQ
LEtpPAD3K09HiTJbHqTxgKj+krRlKj29yyrieR9MYB/gpm73J1qVByLdsImfORQ0
ycllxmr/mcDcpgVzanKaTTo0HXVb9BxuvwWo0eMz8IAqEcoqxcYdBOlRtWE8CINE
rAHCFWnHSBiqQvysBMbdMI0B/n7GWm/KVLGu2jIDMsz8PbiQJ9sbBUAL0FTcXQAf
InxcEAmwSEhnA7qFyJO7XjQG35IJvHWIklDXmneWmwIDAQABo1MwUTAdBgNVHQ4E
FgQU5ZPq54i662pKEJuVpatrx2spEfYwHwYDVR0jBBgwFoAU5ZPq54i662pKEJuV
patrx2spEfYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAS4cj
EucqjyxP+Sisj61Q2fVy+pLvQkqC/fOXTo3KuJX/asWsmxdIrVRyRKfnXxNwdNO5
v6dcEHO0fDU9GmVAYa1JKiKDByjWElh175KqETl4ZSVXod/AX1k1lyYlKaEs2S2T
uzJ5O57IO9AMzDR8IQDTztApkp7si2A3f+ihHLdsZfwnf+4ectTixgxVCy6+3x0t
po7veItIw2L8YRbiVGzpzUe20A/qVxjp7ZswQr6ZI7Zqvs10Na+jK7+xlLf875lk
CTbr/uo8qBLDUf3dXPTWJww4uMiJUvQOasbYg8wXkw9OS2uktjHOjwgLWMoxt5u3
JYdh7REN+0OfpIqdSA==
-----END CERTIFICATE-----
)";
64 changes: 64 additions & 0 deletions test/base-tlsutility.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* Icinga 2 | (c) 2021 Icinga GmbH | GPLv2+ */

#include "base/tlsutility.hpp"
#include "base-tlsutility-certs.hpp"
#include <BoostTestTargetConfig.h>
#include <functional>
#include <memory>
Expand Down Expand Up @@ -132,4 +133,67 @@ BOOST_AUTO_TEST_CASE(iscertuptodate_old)
})));
}

BOOST_AUTO_TEST_CASE(verifycertificate_ok)
{
BOOST_CHECK(VerifyCertificate(
StringToCertificate(l_IcingaCa), StringToCertificate(l_ExampleCrt), String()
));
}

BOOST_AUTO_TEST_CASE(verifycertificate_leafexpired)
{
BOOST_CHECK_THROW(VerifyCertificate(
StringToCertificate(l_IcingaCa), StringToCertificate(l_ExpiredCrt), String()
), openssl_error);
}

BOOST_AUTO_TEST_CASE(verifycertificate_caexpired)
{
BOOST_CHECK_THROW(VerifyCertificate(
StringToCertificate(l_ExpiredCa), StringToCertificate(l_ExpiredCaLeaf), String()
), openssl_error);
}

BOOST_AUTO_TEST_CASE(verifycertificate_sigmismatch)
{
BOOST_CHECK_THROW(VerifyCertificate(
StringToCertificate(l_IcingaCa2), StringToCertificate(l_ExampleCrt), String()
), openssl_error);
}

BOOST_AUTO_TEST_CASE(verifycertificate_X509_STORE_new)
{
BOOST_CHECK(!VerifyCertificate(
StringToCertificate(l_IcingaCa), StringToCertificate(l_ExampleCrt), String(),
[] { return (X509_STORE*)nullptr; }
));
}

BOOST_AUTO_TEST_CASE(verifycertificate_X509_STORE_add_cert)
{
BOOST_CHECK_THROW(VerifyCertificate(
StringToCertificate(l_IcingaCa2), StringToCertificate(l_ExampleCrt), String(),
X509_STORE_new,
[](X509_STORE*, X509*) { return 0; }
), openssl_error);
}

BOOST_AUTO_TEST_CASE(verifycertificate_X509_STORE_CTX_new)
{
BOOST_CHECK(!VerifyCertificate(
StringToCertificate(l_IcingaCa2), StringToCertificate(l_ExampleCrt), String(),
X509_STORE_new, X509_STORE_add_cert,
[] { return (X509_STORE_CTX*)nullptr; }
));
}

BOOST_AUTO_TEST_CASE(verifycertificate_X509_STORE_CTX_init)
{
BOOST_CHECK(!VerifyCertificate(
StringToCertificate(l_IcingaCa2), StringToCertificate(l_ExampleCrt), String(),
X509_STORE_new, X509_STORE_add_cert, X509_STORE_CTX_new,
[](X509_STORE_CTX*, X509_STORE*, X509*, STACK_OF(X509)*) { return 0; }
));
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit e98084c

Please sign in to comment.