aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests/test_certstor_system.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2019-04-11 21:25:24 -0400
committerJack Lloyd <[email protected]>2019-04-13 09:37:57 -0400
commitec3bc081379427e2eb72566015c4c2fd0d6d2da4 (patch)
treedc35ecd43f1ae1bab9b1064c775b1c08dcd0eeff /src/tests/test_certstor_system.cpp
parentfb171db892e27081afcdd9c7ad450b44cd53feca (diff)
Add a wrapper class that wraps macOS or Linux certificate stores.
Diffstat (limited to 'src/tests/test_certstor_system.cpp')
-rw-r--r--src/tests/test_certstor_system.cpp278
1 files changed, 278 insertions, 0 deletions
diff --git a/src/tests/test_certstor_system.cpp b/src/tests/test_certstor_system.cpp
new file mode 100644
index 000000000..854bf4bae
--- /dev/null
+++ b/src/tests/test_certstor_system.cpp
@@ -0,0 +1,278 @@
+/*
+* (C) 1999-2019 Jack Lloyd
+* (C) 2019 René Meusel
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "tests.h"
+
+#if defined(BOTAN_HAS_CERTSTOR_SYSTEM)
+
+#include "test_certstor_utils.h"
+#include <botan/certstor_system.h>
+#include <botan/ber_dec.h>
+#include <botan/der_enc.h>
+#include <botan/hex.h>
+
+namespace Botan_Tests {
+
+namespace {
+
+Test::Result find_certificate_by_pubkey_sha1(Botan::Certificate_Store& certstore)
+ {
+ Test::Result result("System Certificate Store - Find Certificate by SHA1(pubkey)");
+
+ try
+ {
+ result.start_timer();
+ auto cert = certstore.find_cert_by_pubkey_sha1(get_key_id());
+ result.end_timer();
+
+ if(result.test_not_null("found certificate", cert.get()))
+ {
+ auto cns = cert->subject_dn().get_attribute("CN");
+ result.test_is_eq("exactly one CN", cns.size(), size_t(1));
+ result.test_eq("CN", cns.front(), "DST Root CA X3");
+ }
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(e.what());
+ }
+
+ result.test_throws("on invalid SHA1 hash data", [&]
+ {
+ certstore.find_cert_by_pubkey_sha1({});
+ });
+
+ return result;
+ }
+
+Test::Result find_cert_by_subject_dn(Botan::Certificate_Store& certstore)
+ {
+ Test::Result result("System Certificate Store - Find Certificate by subject DN");
+
+ try
+ {
+ auto dn = get_dn();
+
+ result.start_timer();
+ auto cert = certstore.find_cert(dn, std::vector<uint8_t>());
+ result.end_timer();
+
+ if(result.test_not_null("found certificate", cert.get()))
+ {
+ auto cns = cert->subject_dn().get_attribute("CN");
+ result.test_is_eq("exactly one CN", cns.size(), size_t(1));
+ result.test_eq("CN", cns.front(), "DST Root CA X3");
+ }
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(e.what());
+ }
+
+ return result;
+ }
+
+Test::Result find_cert_by_subject_dn_and_key_id(Botan::Certificate_Store& certstore)
+ {
+ Test::Result result("System Certificate Store - Find Certificate by subject DN and key ID");
+
+ try
+ {
+ auto dn = get_dn();
+
+ result.start_timer();
+ auto cert = certstore.find_cert(dn, get_key_id());
+ result.end_timer();
+
+ if(result.test_not_null("found certificate", cert.get()))
+ {
+ auto cns = cert->subject_dn().get_attribute("CN");
+ result.test_is_eq("exactly one CN", cns.size(), size_t(1));
+ result.test_eq("CN", cns.front(), "DST Root CA X3");
+ }
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(e.what());
+ }
+
+ return result;
+ }
+
+Test::Result find_certs_by_subject_dn_and_key_id(Botan::Certificate_Store& certstore)
+ {
+ Test::Result result("System Certificate Store - Find Certificates by subject DN and key ID");
+
+ try
+ {
+ auto dn = get_dn();
+
+ result.start_timer();
+ auto certs = certstore.find_all_certs(dn, get_key_id());
+ result.end_timer();
+
+ if(result.confirm("result not empty", !certs.empty()) &&
+ result.test_eq("exactly one certificate", certs.size(), 1))
+ {
+ auto cns = certs.front()->subject_dn().get_attribute("CN");
+ result.test_is_eq("exactly one CN", cns.size(), size_t(1));
+ result.test_eq("CN", cns.front(), "DST Root CA X3");
+ }
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(e.what());
+ }
+
+ return result;
+ }
+
+Test::Result find_all_subjects(Botan::Certificate_Store& certstore)
+ {
+ Test::Result result("System Certificate Store - Find all Certificate Subjects");
+
+ try
+ {
+ result.start_timer();
+ auto subjects = certstore.all_subjects();
+ result.end_timer();
+
+ if(result.confirm("result not empty", !subjects.empty()))
+ {
+ auto dn = get_dn();
+ auto needle = std::find_if(subjects.cbegin(),
+ subjects.cend(),
+ [=](const Botan::X509_DN &subject)
+ {
+ return subject == dn;
+ });
+
+ if(result.confirm("found expected certificate", needle != subjects.end()))
+ {
+ result.confirm("expected certificate", *needle == dn);
+ }
+ }
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(e.what());
+ }
+
+ return result;
+ }
+
+Test::Result no_certificate_matches(Botan::Certificate_Store& certstore)
+ {
+ Test::Result result("System Certificate Store - can deal with no matches (regression test)");
+
+ try
+ {
+ auto dn = get_unknown_dn();
+ auto kid = get_unknown_key_id();
+
+ result.start_timer();
+ auto certs = certstore.find_all_certs(dn, kid);
+ auto cert = certstore.find_cert(dn, kid);
+ auto pubk_cert = certstore.find_cert_by_pubkey_sha1(kid);
+ result.end_timer();
+
+ result.confirm("find_all_certs did not find the dummy", certs.empty());
+ result.confirm("find_cert did not find the dummy", !cert);
+ result.confirm("find_cert_by_pubkey_sha1 did not find the dummy", !pubk_cert);
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(e.what());
+ }
+
+ return result;
+ }
+
+#if defined(BOTAN_HAS_CERTSTOR_MACOS)
+
+Test::Result certificate_matching_with_dn_normalization(Botan::Certificate_Store& certstore)
+ {
+ Test::Result result("System Certificate Store - normalization of X.509 DN (regression test)");
+
+ try
+ {
+ auto dn = get_skewed_dn();
+
+ result.start_timer();
+ auto certs = certstore.find_all_certs(dn, std::vector<uint8_t>());
+ auto cert = certstore.find_cert(dn, std::vector<uint8_t>());
+ result.end_timer();
+
+ if(result.confirm("find_all_certs did find the skewed DN", !certs.empty()) &&
+ result.confirm("find_cert did find the skewed DN", cert != nullptr))
+ {
+ result.test_eq("it is the correct cert", certs.front()->subject_dn().get_first_attribute("CN"), "DST Root CA X3");
+ result.test_eq("it is the correct cert", cert->subject_dn().get_first_attribute("CN"), "DST Root CA X3");
+ }
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(e.what());
+ }
+
+ return result;
+ }
+
+#endif
+
+class Certstor_System_Tests final : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ Test::Result open_result("System Certificate Store - Open Keychain");
+
+ std::unique_ptr<Botan::Certificate_Store> system;
+
+ try
+ {
+ open_result.start_timer();
+ system.reset(new Botan::System_Certificate_Store);
+ open_result.end_timer();
+ }
+ catch(Botan::Not_Implemented& e)
+ {
+ open_result.test_note("Skipping due to not available in current build");
+ return {open_result};
+ }
+ catch(std::exception& e)
+ {
+ open_result.test_failure(e.what());
+ return {open_result};
+ }
+
+ open_result.test_success();
+
+ std::vector<Test::Result> results;
+ results.push_back(open_result);
+
+ results.push_back(find_certificate_by_pubkey_sha1(*system));
+ results.push_back(find_cert_by_subject_dn(*system));
+ results.push_back(find_cert_by_subject_dn_and_key_id(*system));
+ results.push_back(find_certs_by_subject_dn_and_key_id(*system));
+ results.push_back(find_all_subjects(*system));
+ results.push_back(no_certificate_matches(*system));
+#if defined(BOTAN_HAS_CERTSTOR_MACOS)
+ results.push_back(certificate_matching_with_dn_normalization(*system));
+#endif
+
+ return results;
+ }
+ };
+
+BOTAN_REGISTER_TEST("certstor_system", Certstor_System_Tests);
+
+}
+
+}
+
+#endif