aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests/test_certstor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/test_certstor.cpp')
-rw-r--r--src/tests/test_certstor.cpp374
1 files changed, 226 insertions, 148 deletions
diff --git a/src/tests/test_certstor.cpp b/src/tests/test_certstor.cpp
index cacaf8d0e..abe4a4ed0 100644
--- a/src/tests/test_certstor.cpp
+++ b/src/tests/test_certstor.cpp
@@ -6,178 +6,271 @@
#include "tests.h"
-#if defined(BOTAN_HAS_CERTSTOR_SQLITE3)
- #include <botan/certstor_sqlite.h>
- #include <botan/sqlite3.h>
+#if defined(BOTAN_HAS_CERTSTOR_SQL)
+ #include <botan/certstor.h>
#include <botan/internal/filesystem.h>
#include <botan/pkcs8.h>
#include <sstream>
+ #if defined(BOTAN_HAS_CERTSTOR_SQLITE3)
+ #include <botan/certstor_sqlite.h>
+ #include <botan/sqlite3.h>
+ #endif
#endif
-
namespace Botan_Tests {
namespace {
-#if defined(BOTAN_HAS_CERTSTOR_SQLITE3)
+#if defined(BOTAN_HAS_CERTSTOR_SQL)
+struct CertificateAndKey
+ {
+ const Botan::X509_Certificate certificate;
+ const std::shared_ptr<Botan::Private_Key> private_key;
+ bool operator!=(const CertificateAndKey& rhs) const
+ {
+ return std::tie(certificate, private_key) != std::tie(rhs.certificate, rhs.private_key);
+ }
+ };
-Test::Result test_certstor_insert_find_remove_test(
- const std::vector<std::pair<Botan::X509_Certificate,std::shared_ptr<Botan::Private_Key>>>& certs,
- Botan::Certificate_Store_In_SQL& store)
+#if defined(BOTAN_HAS_CERTSTOR_SQLITE3)
+Test::Result test_certstor_sqlite3_insert_find_remove_test(const std::vector<CertificateAndKey>& certsandkeys)
{
- Test::Result result("Certificate Store - Insert, Find, Remove");
+ Test::Result result("Certificate Store SQLITE3 - Insert, Find, Remove");
- for(auto cert_key: certs)
+ try
{
- auto cert = cert_key.first;
- auto key = cert_key.second;
- auto wo_keyid = store.find_cert(cert.subject_dn(),{});
- auto w_keyid = store.find_cert(cert.subject_dn(),cert.subject_key_id());
+ auto& rng = Test::rng();
+ const std::string passwd(reinterpret_cast<const char*>(rng.random_vec(8).data()), 8);
+ // Just create a database in memory for testing (https://sqlite.org/inmemorydb.html)
+ Botan::Certificate_Store_In_SQLite store(":memory:", passwd, rng);
- if(!wo_keyid || !w_keyid)
- {
- result.test_failure("Can't retrieve certificate");
- return result;
- }
+ for(const auto& a : certsandkeys)
+ store.insert_key(a.certificate, *a.private_key);
- auto priv = store.find_key(cert);
- if(!priv && (certs[1] != cert_key && certs[0] != cert_key))
+ for(const auto certandkey : certsandkeys)
{
- result.test_failure("Can't retrieve private key for " + cert.fingerprint("SHA1"));
- return result;
- }
+ const auto cert = certandkey.certificate;
+ const auto key = certandkey.private_key;
+ const auto wo_keyid = store.find_cert(cert.subject_dn(), {});
+ const auto w_keyid = store.find_cert(cert.subject_dn(), cert.subject_key_id());
- result.test_eq("Got wrong certificate",cert.fingerprint(),w_keyid->fingerprint());
+ if(!wo_keyid || !w_keyid)
+ {
+ result.test_failure("Can't retrieve certificate");
+ return result;
+ }
- if(priv)
- {
- result.test_eq("Got wrong private key",key->private_key_bits(),priv->private_key_bits());
+ const auto priv = store.find_key(cert);
+ if(!priv && (certsandkeys[1] != certandkey && certsandkeys[0] != certandkey))
+ {
+ result.test_failure("Can't retrieve private key for " + cert.fingerprint("SHA1"));
+ return result;
+ }
- auto rev_certs = store.find_certs_for_key(*priv);
+ result.test_eq("Got wrong certificate", cert.fingerprint(), w_keyid->fingerprint());
- if(rev_certs.empty())
+ if(priv)
{
- result.test_failure("No certificate");
+ result.test_eq("Got wrong private key", key->private_key_bits(), priv->private_key_bits());
+
+ const auto rev_certs = store.find_certs_for_key(*priv);
+
+ if(rev_certs.empty())
+ {
+ result.test_failure("No certificate");
+ }
+ else
+ {
+ const bool found = std::any_of(rev_certs.begin(),
+ rev_certs.end(), [&](std::shared_ptr<const Botan::X509_Certificate> c) { return c->fingerprint() == cert.fingerprint(); });
+
+ result.test_eq("Got wrong/no certificate", found, true);
+ }
}
- else
+
+ if(certsandkeys[4] != certandkey && certsandkeys[5] != certandkey)
{
- bool found = std::any_of(rev_certs.begin(),rev_certs.end(),[&](std::shared_ptr<const Botan::X509_Certificate> c)
- { return c->fingerprint() == cert.fingerprint(); });
+ result.test_eq("Got wrong certificate", cert.fingerprint(), wo_keyid->fingerprint());
+ }
- result.test_eq("Got wrong/no certificate",found,true);
+ result.test_eq("Can't remove certificate", store.remove_cert(cert), true);
+ result.test_eq("Can't remove certificate", !store.find_cert(cert.subject_dn(), cert.subject_key_id()), true);
+
+ if(priv)
+ {
+ store.remove_key(*key);
}
+
+ result.test_eq("Can't remove key", !store.find_key(cert), true);
}
- if(certs[4] != cert_key && certs[5] != cert_key)
+ return result;
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(e.what());
+ return result;
+ }
+ }
+
+Test::Result test_certstor_sqlite3_crl_test(const std::vector<CertificateAndKey>& certsandkeys)
+ {
+ Test::Result result("Certificate Store SQLITE3 - CRL");
+ try
+ {
+ auto& rng = Test::rng();
+ const std::string passwd(reinterpret_cast<const char*>(rng.random_vec(8).data()), 8);
+ // Just create a database in memory for testing (https://sqlite.org/inmemorydb.html)
+ Botan::Certificate_Store_In_SQLite store(":memory:", passwd, rng);
+
+ for(const auto& a : certsandkeys)
+ store.insert_cert(a.certificate);
+
+ store.revoke_cert(certsandkeys[0].certificate, Botan::CA_COMPROMISE);
+ store.revoke_cert(certsandkeys[3].certificate, Botan::CA_COMPROMISE);
+ store.revoke_cert(certsandkeys[3].certificate, Botan::CA_COMPROMISE);
+
{
- result.test_eq("Got wrong certificate",cert.fingerprint(),wo_keyid->fingerprint());
+ const auto crls = store.generate_crls();
+
+ result.test_eq("Can't revoke certificate", crls.size(), 2);
+ result.test_eq("Can't revoke certificate",
+ crls[0].is_revoked(certsandkeys[0].certificate) ^ crls[1].is_revoked(certsandkeys[0].certificate), true);
+ result.test_eq("Can't revoke certificate",
+ crls[0].is_revoked(certsandkeys[3].certificate) ^ crls[1].is_revoked(certsandkeys[3].certificate), true);
}
-
- result.test_eq("Can't remove certificate",store.remove_cert(cert),true);
- result.test_eq("Can't remove certificate",!store.find_cert(cert.subject_dn(),cert.subject_key_id()),true);
- if(priv)
+ store.affirm_cert(certsandkeys[3].certificate);
+
{
- store.remove_key(*key);
+ const auto crls = store.generate_crls();
+
+ result.test_eq("Can't revoke certificate, wrong crl size", crls.size(), 1);
+ result.test_eq("Can't revoke certificate, cert 0 not revoked", crls[0].is_revoked(certsandkeys[0].certificate), true);
}
- result.test_eq("Can't remove key",!store.find_key(cert),true);
- }
+ const auto cert0_crl = store.find_crl_for(certsandkeys[0].certificate);
- return result;
- }
+ result.test_eq("Can't revoke certificate, crl for cert 0", !cert0_crl, false);
+ result.test_eq("Can't revoke certificate, crl for cert 0 size check", cert0_crl->get_revoked().size(), 1);
+ result.test_eq("Can't revoke certificate, no crl for cert 0", cert0_crl->is_revoked(certsandkeys[0].certificate), true);
-Test::Result test_certstor_crl_test(
- const std::vector<std::pair<Botan::X509_Certificate,std::shared_ptr<Botan::Private_Key>>>& certs,
- Botan::Certificate_Store_In_SQL& store)
- {
- Test::Result result("Certificate Store - CRL");
+ const auto cert3_crl = store.find_crl_for(certsandkeys[3].certificate);
+
+ result.test_eq("Can't revoke certificate, crl for cert 3", !cert3_crl, true);
- store.revoke_cert(certs[0].first,Botan::CA_COMPROMISE);
- store.revoke_cert(certs[3].first,Botan::CA_COMPROMISE);
- store.revoke_cert(certs[3].first,Botan::CA_COMPROMISE);
+ return result;
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(e.what());
+ return result;
+ }
+ }
+Test::Result test_certstor_sqlite3_all_subjects_test(const std::vector<CertificateAndKey>& certsandkeys)
{
- auto crls = store.generate_crls();
+ Test::Result result("Certificate Store SQLITE3 - All subjects");
+ try
+ {
+ auto& rng = Test::rng();
+ const std::string passwd(reinterpret_cast<const char*>(rng.random_vec(8).data()), 8);
+ // Just create a database in memory for testing (https://sqlite.org/inmemorydb.html)
+ Botan::Certificate_Store_In_SQLite store(":memory:", passwd, rng);
- result.test_eq("Can't revoke certificate",crls.size(),2);
- result.test_eq("Can't revoke certificate",crls[0].is_revoked(certs[0].first) ^ crls[1].is_revoked(certs[0].first),true);
- result.test_eq("Can't revoke certificate",crls[0].is_revoked(certs[3].first) ^ crls[1].is_revoked(certs[3].first),true);
- }
+ for(const auto& a : certsandkeys)
+ store.insert_cert(a.certificate);
- store.affirm_cert(certs[3].first);
+ const auto subjects = store.all_subjects();
- {
- auto crls = store.generate_crls();
+ result.test_eq("Check subject list length", subjects.size(), 6);
- result.test_eq("Can't revoke certificate, wrong crl size",crls.size(),1);
- result.test_eq("Can't revoke certificate, cert 0 not revoked",crls[0].is_revoked(certs[0].first),true);
+ for(const auto sub : subjects)
+ {
+ std::stringstream ss;
+
+ ss << sub;
+ result.test_eq("Check subject " + ss.str(),
+ certsandkeys[0].certificate.subject_dn() == sub ||
+ certsandkeys[1].certificate.subject_dn() == sub ||
+ certsandkeys[2].certificate.subject_dn() == sub ||
+ certsandkeys[3].certificate.subject_dn() == sub ||
+ certsandkeys[4].certificate.subject_dn() == sub ||
+ certsandkeys[5].certificate.subject_dn() == sub,
+ true);
+ }
+ return result;
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(e.what());
+ return result;
+ }
}
- auto cert0_crl = store.find_crl_for(certs[0].first);
+#endif
- result.test_eq("Can't revoke certificate, crl for cert 0",!cert0_crl,false);
- result.test_eq("Can't revoke certificate, crl for cert 0 size check",cert0_crl->get_revoked().size(),1);
- result.test_eq("Can't revoke certificate, no crl for cert 0",cert0_crl->is_revoked(certs[0].first),true);
+Test::Result test_certstor_find_hash_subject(const std::vector<CertificateAndKey>& certsandkeys)
+ {
+ Test::Result result("Certificate Store - Find by subject hash");
- auto cert3_crl = store.find_crl_for(certs[3].first);
+ try
+ {
+ Botan::Certificate_Store_In_Memory store;
- result.test_eq("Can't revoke certificate, crl for cert 3",!cert3_crl,true);
+ for(const auto& a : certsandkeys)
+ store.add_certificate(a.certificate);
- return result;
- }
+ for(const auto certandkey : certsandkeys)
+ {
+ const auto cert = certandkey.certificate;
+ const auto hash = cert.raw_subject_dn_sha256();
-Test::Result test_certstor_all_subjects_test(
- const std::vector<std::pair<Botan::X509_Certificate,std::shared_ptr<Botan::Private_Key>>>& certs,
- Botan::Certificate_Store_In_SQL& store)
- {
- Test::Result result("Certificate Store - All subjects");
+ const auto found = store.find_cert_by_raw_subject_dn_sha256(hash);
+ if(!found)
+ {
+ result.test_failure("Can't retrieve certificate " + cert.fingerprint("SHA1"));
+ return result;
+ }
- auto subjects = store.all_subjects();
-
- result.test_eq("Check subject list length",subjects.size(),6);
+ result.test_eq("Got wrong certificate", hash, found->raw_subject_dn_sha256());
+ }
- for(auto sub: subjects)
+ const auto found = store.find_cert_by_raw_subject_dn_sha256(std::vector<uint8_t>(32,0));
+ if(found)
+ {
+ result.test_failure("Certificate found for dummy hash");
+ return result;
+ }
+
+ return result;
+ }
+ catch(std::exception& e)
{
- std::stringstream ss;
-
- ss << sub;
- result.test_eq("Check subject " + ss.str(),
- certs[0].first.subject_dn() == sub ||
- certs[1].first.subject_dn() == sub ||
- certs[2].first.subject_dn() == sub ||
- certs[3].first.subject_dn() == sub ||
- certs[4].first.subject_dn() == sub ||
- certs[5].first.subject_dn() == sub,true);
-
+ result.test_failure(e.what());
+ return result;
}
- return result;
}
class Certstor_Tests : public Test
{
public:
- std::vector<Test::Result> run() override
+ std::vector<Test::Result> run() override
{
const std::string test_dir = Test::data_dir() + "/certstor";
- const std::vector<std::pair<std::string,std::string>> test_data({
- std::make_pair("cert1.crt","key01.pem"),
- std::make_pair("cert2.crt","key01.pem"),
- std::make_pair("cert3.crt","key03.pem"),
- std::make_pair("cert4.crt","key04.pem"),
- std::make_pair("cert5a.crt","key05.pem"),
- std::make_pair("cert5b.crt","key06.pem")
- });
-
- std::vector<Test::Result> results;
- std::vector<std::pair<std::string,std::function<Test::Result(
- const std::vector<std::pair<Botan::X509_Certificate,std::shared_ptr<Botan::Private_Key>>>&,
- Botan::Certificate_Store_In_SQL&)>>>
- fns({
- std::make_pair("Certificate Store - Insert, Find, Remove",test_certstor_insert_find_remove_test),
- std::make_pair("Certificate Store - CRL",test_certstor_crl_test),
- std::make_pair("Certificate Store - All subjects",test_certstor_all_subjects_test)
- });
+ struct CertificateAndKeyFilenames
+ {
+ const std::string certificate;
+ const std::string private_key;
+ } const certsandkeys_filenames[]
+ {
+ {"cert1.crt", "key01.pem"},
+ {"cert2.crt", "key01.pem"},
+ {"cert3.crt", "key03.pem"},
+ {"cert4.crt", "key04.pem"},
+ {"cert5a.crt", "key05.pem"},
+ {"cert5b.crt", "key06.pem"},
+ };
try
{
@@ -200,53 +293,38 @@ class Certstor_Tests : public Test
return {result};
}
- for(auto fn: fns)
- {
- Test::Result result(fn.first);
-
- try
- {
- auto& rng = Test::rng();
- std::string passwd(reinterpret_cast<const char*>(rng.random_vec(8).data()),8);
-
- // Just create a database in memory for testing (https://sqlite.org/inmemorydb.html)
- Botan::Certificate_Store_In_SQLite store(":memory:", passwd, rng);
- std::vector<std::pair<Botan::X509_Certificate,std::shared_ptr<Botan::Private_Key>>> retrieve;
-
- for(auto&& cert_key_pair : test_data)
- {
- Botan::X509_Certificate cert(test_dir + "/" + cert_key_pair.first);
- std::shared_ptr<Botan::Private_Key> key(Botan::PKCS8::load_key(test_dir + "/" + cert_key_pair.second,rng));
-
- if(!key)
- {
- result.test_failure("Failed to load key from disk");
- results.push_back(fn.second(retrieve,store));
- continue;
- }
+ auto& rng = Test::rng();
+ std::vector<CertificateAndKey> certsandkeys;
+ for(const auto& certandkey_filenames : certsandkeys_filenames)
+ {
+ const Botan::X509_Certificate certificate(test_dir + "/" + certandkey_filenames.certificate);
+ std::shared_ptr<Botan::Private_Key> private_key(Botan::PKCS8::load_key(test_dir + "/" +
+ certandkey_filenames.private_key, rng));
- store.insert_cert(cert);
- store.insert_key(cert,*key);
- retrieve.push_back(std::make_pair(cert,key));
- }
-
- results.push_back(fn.second(retrieve,store));
- }
- catch(std::exception& e)
+ if(!private_key)
{
- results.push_back(Test::Result::Failure("Certstor test '" + fn.first + "'", e.what()));
+ Test::Result result("Certificate Store");
+ result.test_failure("Failed to load key from disk at path: " + test_dir + "/" + certandkey_filenames.private_key);
+ return {result};
}
+
+ certsandkeys.push_back({certificate, private_key});
}
+ std::vector<Test::Result> results;
+
+ results.push_back(test_certstor_find_hash_subject(certsandkeys));
+#if defined(BOTAN_HAS_CERTSTOR_SQLITE3)
+ results.push_back(test_certstor_sqlite3_insert_find_remove_test(certsandkeys));
+ results.push_back(test_certstor_sqlite3_crl_test(certsandkeys));
+ results.push_back(test_certstor_sqlite3_all_subjects_test(certsandkeys));
+#endif
return results;
}
};
BOTAN_REGISTER_TEST("certstor", Certstor_Tests);
-
#endif
-
}
-
}