From 8f15307318daa49ecde9f0be7942a07633713b3b Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Fri, 9 Feb 2018 13:18:53 +0100 Subject: [PATCH] CKM: Check certificate validity before test When a certificate expires or a systemd date is incorrectly set the certificate chain tests fail suggesting key-manager failure. This commit adds a simple certificate validity check before the certificate is used. If the certificate is not valid the test fails and a clear message is delivered to the user. Each certificate is validated only once. Change-Id: I4de5549e49b761472c224f6bb672d512386d398d --- src/ckm/test-certs.cpp | 108 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 85 insertions(+), 23 deletions(-) diff --git a/src/ckm/test-certs.cpp b/src/ckm/test-certs.cpp index 6dddb7a..a844cf5 100644 --- a/src/ckm/test-certs.cpp +++ b/src/ckm/test-certs.cpp @@ -20,6 +20,10 @@ */ #include +#include +#include +#include +#include #include #include #include @@ -50,7 +54,23 @@ enum RawCertificateID { NO_CERT }; -typedef map> CertMap; + +struct TestCert { + enum Validity { + UNKNOWN, + VALID, + NOT_YET_VALID, + EXPIRED + }; + + TestCert() : valid(UNKNOWN) {} + + string raw_base64; + CKM::CertificateShPtr certPtr; + Validity valid; +}; + +typedef map CertMap; CKM::CertificateShPtr createCert(const string& cert) { CKM::RawBuffer buffer_cert(cert.begin(), cert.end()); @@ -106,8 +126,8 @@ CertMap initializeTestCerts() "qMn7nf7taidDKLO2T4bhujztnTYOhhaXKgPy7AtZ28N2wvX96VyAPB/vrchGmyBK\n" "kOg11TpPdNDkhb1J4ZCh2gupDg==\n" "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::TEST_ROOT_CA] = - std::make_pair(raw_base64, createCert(raw_base64)); + cm[RawCertificateID::TEST_ROOT_CA].raw_base64 = raw_base64; + cm[RawCertificateID::TEST_ROOT_CA].certPtr = createCert(raw_base64); } // TEST_IM_CA, signed by TEST_ROOT_CA, expires 2035 @@ -135,8 +155,8 @@ CertMap initializeTestCerts() "SLoHQ9s1i7Zyb7HU6UAaqMOz15LBkyAqtNyJcO2p7Q/p5YK0xfD4xisI5qXucqVm\n" "F2obL5qJSTN/RQ==\n" "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::TEST_IM_CA] = - std::make_pair(raw_base64, createCert(raw_base64)); + cm[RawCertificateID::TEST_IM_CA].raw_base64 = raw_base64; + cm[RawCertificateID::TEST_IM_CA].certPtr = createCert(raw_base64); } // TEST_LEAF, signed by TEST_IM_CA, expires 2035 @@ -162,8 +182,8 @@ CertMap initializeTestCerts() "Zj/T1JkYXKkEwZU6nAR2jdZp3EP9xj3o15V/tyFcXHx6l8NTxn4cJb+Xe4VquQJz\n" "6ON7PVe0ABN/AlwVQiFE\n" "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::TEST_LEAF] = - std::make_pair(raw_base64, createCert(raw_base64)); + cm[RawCertificateID::TEST_LEAF].raw_base64 = raw_base64; + cm[RawCertificateID::TEST_LEAF].certPtr = createCert(raw_base64); } // BING.COM, signed by MICROSOFT_IM_CA, expires 10 Jul 2019 @@ -236,8 +256,8 @@ CertMap initializeTestCerts() "AfqkzSUxhqHXuThe7KIoX9/0zv4AA1WZFis1QvAG7dpl9eio6vCdC/73HvBAlqRL\n" "+7Mb1uu0\n" "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::BING_COM] = - std::make_pair(raw_base64, createCert(raw_base64)); + cm[RawCertificateID::BING_COM].raw_base64 = raw_base64; + cm[RawCertificateID::BING_COM].certPtr = createCert(raw_base64); } @@ -277,8 +297,8 @@ CertMap initializeTestCerts() "TlHk/R4RFsyeANmXGpfjZceGNRtTdr4y0SxBSUujPpMMW3dXBzA8NYuM0WmiJ/pV\n" "6KudEB7RF9+6bInTyVvXC5SIqdi0ldeO\n" "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::MICROSOFT_IM_CA] = - std::make_pair(raw_base64, createCert(raw_base64)); + cm[RawCertificateID::MICROSOFT_IM_CA].raw_base64 = raw_base64; + cm[RawCertificateID::MICROSOFT_IM_CA].certPtr = createCert(raw_base64); } @@ -308,8 +328,8 @@ CertMap initializeTestCerts() "vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\n" "+OkuE6N36B9K\n" "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::DIGICERT_ROOT_CA] = - std::make_pair(raw_base64, createCert(raw_base64)); + cm[RawCertificateID::DIGICERT_ROOT_CA].raw_base64 = raw_base64; + cm[RawCertificateID::DIGICERT_ROOT_CA].certPtr = createCert(raw_base64); } // DIGICERT_IM_CA, signed by DIGICERT_ROOT_CA, expires 22 Oct 2028 @@ -343,8 +363,8 @@ CertMap initializeTestCerts() "0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae\n" "cPUeybQ=\n" "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::DIGICERT_IM_CA] = - std::make_pair(raw_base64, createCert(raw_base64)); + cm[RawCertificateID::DIGICERT_IM_CA].raw_base64 = raw_base64; + cm[RawCertificateID::DIGICERT_IM_CA].certPtr = createCert(raw_base64); } // FACEBOOK_COM, *.facebook.com - signed by DIGICERT_IM_CA, expires 25 Jan 2018 @@ -395,8 +415,8 @@ CertMap initializeTestCerts() "EP0UhYknI1B6LBecJuj7jI26eXZdX35CYkpI/SZA9KK+OYKHh6vCxKqnRZ9ZQUOj\n" "XnIWKQeV5Hg=\n" "-----END CERTIFICATE-----\n"); - cm[RawCertificateID::FACEBOOK_COM] = - std::make_pair(raw_base64, createCert(raw_base64)); + cm[RawCertificateID::FACEBOOK_COM].raw_base64 = raw_base64; + cm[RawCertificateID::FACEBOOK_COM].certPtr = createCert(raw_base64); } return cm; @@ -406,6 +426,44 @@ CertMap TEST_CERTS = initializeTestCerts(); } // namespace TestData::anonymous +void checkCertificateValidity(std::map::iterator& it) +{ + if (it->second.valid == TestCert::UNKNOWN) + { + auto buff = BIO_new(BIO_s_mem()); + BIO_write(buff, it->second.raw_base64.c_str(), it->second.raw_base64.size()); + + X509* x509 = PEM_read_bio_X509(buff, nullptr, nullptr, nullptr); + BIO_free_all(buff); + + RUNNER_ASSERT_MSG(x509 != NULL, "Test certificate " << it->first << " can't be parsed"); + + if (X509_cmp_current_time(X509_get_notBefore(x509)) > 0) + it->second.valid = TestCert::NOT_YET_VALID; + else if (X509_cmp_current_time(X509_get_notAfter(x509)) < 0) + it->second.valid = TestCert::EXPIRED; + else + it->second.valid = TestCert::VALID; + + X509_free(x509); + } + + switch (it->second.valid) + { + case TestCert::NOT_YET_VALID: + RUNNER_FAIL_MSG( + "Test certificate " << it->first << + " is not yet valid. Check the certificate and the system date."); + break; + case TestCert::EXPIRED: + RUNNER_FAIL_MSG( + "Test certificate " << it->first << + " has expired. Check the certificate and the system date."); + break; + default: + break; + } +} std::string getTestCertificateBase64(certificateID id) { @@ -413,10 +471,12 @@ std::string getTestCertificateBase64(certificateID id) RUNNER_ASSERT_MSG(cert != TEST_CERTS.end(), "Unknown certificate index!"); - auto &certPair = cert->second; - RUNNER_ASSERT_MSG(certPair.first.size() > 0, "Certificate is empty!"); + auto &certStruct = cert->second; + RUNNER_ASSERT_MSG(certStruct.raw_base64.size() > 0, "Certificate is empty!"); - return certPair.first; + checkCertificateValidity(cert); + + return certStruct.raw_base64; } CKM::CertificateShPtr getTestCertificate(certificateID id) @@ -425,10 +485,12 @@ CKM::CertificateShPtr getTestCertificate(certificateID id) RUNNER_ASSERT_MSG(cert != TEST_CERTS.end(), "Unknown certificate index!"); - auto &certPair = cert->second; - RUNNER_ASSERT_MSG(certPair.second != nullptr, "Certificate is empty!"); + auto &certStruct = cert->second; + RUNNER_ASSERT_MSG(certStruct.certPtr != nullptr, "Certificate is empty!"); + + checkCertificateValidity(cert); - return certPair.second; + return certStruct.certPtr; } } // namespace TestData -- 2.7.4