diff options
author | Jack Lloyd <[email protected]> | 2017-04-04 16:46:16 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-04-04 16:46:16 -0400 |
commit | a17bfd26d81d2182a5ecccb98f75ff05c7c999bd (patch) | |
tree | d977c7163cd50329141d32277c4e0a97b787a358 /src/lib/x509 | |
parent | 542c6cb7338530b4a8f7d93f2410567815d993ef (diff) | |
parent | b0068f74fb15aa4ffcb9225a60c0aaff89209b62 (diff) |
Merge GH #900 Add ability to search by X509 DN hash
Diffstat (limited to 'src/lib/x509')
-rw-r--r-- | src/lib/x509/certstor.cpp | 78 | ||||
-rw-r--r-- | src/lib/x509/certstor.h | 12 | ||||
-rw-r--r-- | src/lib/x509/certstor_sql/certstor_sql.cpp | 9 | ||||
-rw-r--r-- | src/lib/x509/certstor_sql/certstor_sql.h | 3 | ||||
-rw-r--r-- | src/lib/x509/x509_ca.cpp | 2 | ||||
-rw-r--r-- | src/lib/x509/x509_ca.h | 2 | ||||
-rw-r--r-- | src/lib/x509/x509cert.cpp | 14 | ||||
-rw-r--r-- | src/lib/x509/x509cert.h | 14 |
8 files changed, 95 insertions, 39 deletions
diff --git a/src/lib/x509/certstor.cpp b/src/lib/x509/certstor.cpp index 10178a526..df4fc3365 100644 --- a/src/lib/x509/certstor.cpp +++ b/src/lib/x509/certstor.cpp @@ -13,27 +13,23 @@ namespace Botan { std::shared_ptr<const X509_CRL> Certificate_Store::find_crl_for(const X509_Certificate&) const { - return std::shared_ptr<const X509_CRL>(); + return {}; } void Certificate_Store_In_Memory::add_certificate(const X509_Certificate& cert) { - for(size_t i = 0; i != m_certs.size(); ++i) - { - if(*m_certs[i] == cert) + for(const auto& c : m_certs) + if(*c == cert) return; - } m_certs.push_back(std::make_shared<const X509_Certificate>(cert)); } void Certificate_Store_In_Memory::add_certificate(std::shared_ptr<const X509_Certificate> cert) { - for(size_t i = 0; i != m_certs.size(); ++i) - { - if(*m_certs[i] == *cert) + for(const auto& c : m_certs) + if(*c == *cert) return; - } m_certs.push_back(cert); } @@ -41,8 +37,8 @@ void Certificate_Store_In_Memory::add_certificate(std::shared_ptr<const X509_Cer std::vector<X509_DN> Certificate_Store_In_Memory::all_subjects() const { std::vector<X509_DN> subjects; - for(size_t i = 0; i != m_certs.size(); ++i) - subjects.push_back(m_certs[i]->subject_dn()); + for(const auto& cert : m_certs) + subjects.push_back(cert->subject_dn()); return subjects; } @@ -50,22 +46,22 @@ std::shared_ptr<const X509_Certificate> Certificate_Store_In_Memory::find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { - for(size_t i = 0; i != m_certs.size(); ++i) + for(const auto& cert : m_certs) { // Only compare key ids if set in both call and in the cert if(key_id.size()) { - std::vector<uint8_t> skid = m_certs[i]->subject_key_id(); + std::vector<uint8_t> skid = cert->subject_key_id(); if(skid.size() && skid != key_id) // no match continue; } - if(m_certs[i]->subject_dn() == subject_dn) - return m_certs[i]; + if(cert->subject_dn() == subject_dn) + return cert; } - return std::shared_ptr<const X509_Certificate>(); + return nullptr; } @@ -75,14 +71,30 @@ Certificate_Store_In_Memory::find_cert_by_pubkey_sha1(const std::vector<uint8_t> if(key_hash.size() != 20) throw Invalid_Argument("Certificate_Store_In_Memory::find_cert_by_pubkey_sha1 invalid hash"); - for(size_t i = 0; i != m_certs.size(); ++i) - { - const std::vector<uint8_t> hash_i = m_certs[i]->subject_public_key_bitstring_sha1(); - if(key_hash == hash_i) - { - return m_certs[i]; - } - } + std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-1")); + + for(const auto& cert : m_certs){ + hash->update(cert->subject_public_key_bitstring()); + if(key_hash == hash->final_stdvec()) //final_stdvec also clears the hash to initial state + return cert; + } + + return nullptr; + } + +std::shared_ptr<const X509_Certificate> +Certificate_Store_In_Memory::find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const + { + if(subject_hash.size() != 32) + throw Invalid_Argument("Certificate_Store_In_Memory::find_cert_by_raw_subject_dn_sha256 invalid hash"); + + std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-256")); + + for(const auto& cert : m_certs){ + hash->update(cert->raw_subject_dn()); + if(subject_hash == hash->final_stdvec()) //final_stdvec also clears the hash to initial state + return cert; + } return nullptr; } @@ -97,13 +109,13 @@ void Certificate_Store_In_Memory::add_crl(std::shared_ptr<const X509_CRL> crl) { X509_DN crl_issuer = crl->issuer_dn(); - for(size_t i = 0; i != m_crls.size(); ++i) + for(auto& c : m_crls) { // Found an update of a previously existing one; replace it - if(m_crls[i]->issuer_dn() == crl_issuer) + if(c->issuer_dn() == crl_issuer) { - if(m_crls[i]->this_update() <= crl->this_update()) - m_crls[i] = crl; + if(c->this_update() <= crl->this_update()) + c = crl; return; } } @@ -116,22 +128,22 @@ std::shared_ptr<const X509_CRL> Certificate_Store_In_Memory::find_crl_for(const { const std::vector<uint8_t>& key_id = subject.authority_key_id(); - for(size_t i = 0; i != m_crls.size(); ++i) + for(const auto& c : m_crls) { // Only compare key ids if set in both call and in the CRL if(key_id.size()) { - std::vector<uint8_t> akid = m_crls[i]->authority_key_id(); + std::vector<uint8_t> akid = c->authority_key_id(); if(akid.size() && akid != key_id) // no match continue; } - if(m_crls[i]->issuer_dn() == subject.issuer_dn()) - return m_crls[i]; + if(c->issuer_dn() == subject.issuer_dn()) + return c; } - return std::shared_ptr<const X509_CRL>(); + return {}; } Certificate_Store_In_Memory::Certificate_Store_In_Memory(const X509_Certificate& cert) diff --git a/src/lib/x509/certstor.h b/src/lib/x509/certstor.h index 6f0dc9cb3..2b68147f0 100644 --- a/src/lib/x509/certstor.h +++ b/src/lib/x509/certstor.h @@ -40,6 +40,15 @@ class BOTAN_DLL Certificate_Store find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const = 0; /** + * Find a certificate by searching for one with a matching SHA-256 hash of + * raw subject name. Used for OCSP. + * @param subject_hash SHA-256 hash of the subject's raw name + * @return a matching certificate or nullptr otherwise + */ + virtual std::shared_ptr<const X509_Certificate> + find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const = 0; + + /** * Finds a CRL for the given certificate * @param subject the subject certificate * @return the CRL for subject or nullptr otherwise @@ -120,6 +129,9 @@ class BOTAN_DLL Certificate_Store_In_Memory : public Certificate_Store std::shared_ptr<const X509_Certificate> find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override; + std::shared_ptr<const X509_Certificate> + find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override; + /** * Finds a CRL for the given certificate */ diff --git a/src/lib/x509/certstor_sql/certstor_sql.cpp b/src/lib/x509/certstor_sql/certstor_sql.cpp index 06e0fda1b..fc8a05eb2 100644 --- a/src/lib/x509/certstor_sql/certstor_sql.cpp +++ b/src/lib/x509/certstor_sql/certstor_sql.cpp @@ -81,8 +81,13 @@ Certificate_Store_In_SQL::find_cert(const X509_DN& subject_dn, const std::vector std::shared_ptr<const X509_Certificate> Certificate_Store_In_SQL::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& /*key_hash*/) const { - // TODO! - return nullptr; + throw Not_Implemented("TODO!"); + } + +std::shared_ptr<const X509_Certificate> +Certificate_Store_In_SQL::find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& /*subject_hash*/) const + { + throw Not_Implemented("TODO!"); } std::shared_ptr<const X509_CRL> diff --git a/src/lib/x509/certstor_sql/certstor_sql.h b/src/lib/x509/certstor_sql/certstor_sql.h index 91d8d5c00..f95aea9b4 100644 --- a/src/lib/x509/certstor_sql/certstor_sql.h +++ b/src/lib/x509/certstor_sql/certstor_sql.h @@ -44,6 +44,9 @@ class BOTAN_DLL Certificate_Store_In_SQL : public Certificate_Store std::shared_ptr<const X509_Certificate> find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override; + std::shared_ptr<const X509_Certificate> + find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override; + /** * Returns all subject DNs known to the store instance. */ diff --git a/src/lib/x509/x509_ca.cpp b/src/lib/x509/x509_ca.cpp index 692f837ae..e1a8c3af7 100644 --- a/src/lib/x509/x509_ca.cpp +++ b/src/lib/x509/x509_ca.cpp @@ -49,7 +49,7 @@ X509_CA::~X509_CA() X509_Certificate X509_CA::sign_request(const PKCS10_Request& req, RandomNumberGenerator& rng, const X509_Time& not_before, - const X509_Time& not_after) + const X509_Time& not_after) const { Key_Constraints constraints; if(req.is_CA()) diff --git a/src/lib/x509/x509_ca.h b/src/lib/x509/x509_ca.h index 0448e109b..bc4b3a506 100644 --- a/src/lib/x509/x509_ca.h +++ b/src/lib/x509/x509_ca.h @@ -38,7 +38,7 @@ class BOTAN_DLL X509_CA X509_Certificate sign_request(const PKCS10_Request& req, RandomNumberGenerator& rng, const X509_Time& not_before, - const X509_Time& not_after); + const X509_Time& not_after) const; /** * Get the certificate of this CA. diff --git a/src/lib/x509/x509cert.cpp b/src/lib/x509/x509cert.cpp index b6e15a3e0..512e4aa63 100644 --- a/src/lib/x509/x509cert.cpp +++ b/src/lib/x509/x509cert.cpp @@ -439,6 +439,13 @@ std::vector<uint8_t> X509_Certificate::raw_issuer_dn() const return m_issuer.get1_memvec("X509.Certificate.dn_bits"); } +std::vector<uint8_t> X509_Certificate::raw_issuer_dn_sha256() const + { + std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-256")); + hash->update(raw_issuer_dn()); + return hash->final_stdvec(); + } + X509_DN X509_Certificate::subject_dn() const { return create_dn(m_subject); @@ -449,6 +456,13 @@ std::vector<uint8_t> X509_Certificate::raw_subject_dn() const return m_subject.get1_memvec("X509.Certificate.dn_bits"); } +std::vector<uint8_t> X509_Certificate::raw_subject_dn_sha256() const + { + std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-256")); + hash->update(raw_subject_dn()); + return hash->final_stdvec(); + } + std::string X509_Certificate::fingerprint(const std::string& hash_name) const { std::unique_ptr<HashFunction> hash(HashFunction::create(hash_name)); diff --git a/src/lib/x509/x509cert.h b/src/lib/x509/x509cert.h index ab943db4b..ceadf88c5 100644 --- a/src/lib/x509/x509cert.h +++ b/src/lib/x509/x509cert.h @@ -96,16 +96,26 @@ class BOTAN_DLL X509_Certificate : public X509_Object std::vector<std::string> issuer_info(const std::string& name) const; /** - * Raw subject DN + * Raw issuer DN */ std::vector<uint8_t> raw_issuer_dn() const; /** - * Raw issuer DN + * SHA-256 of Raw issuer DN + */ + std::vector<uint8_t> raw_issuer_dn_sha256() const; + + /** + * Raw subject DN */ std::vector<uint8_t> raw_subject_dn() const; /** + * SHA-256 of Raw subject DN + */ + std::vector<uint8_t> raw_subject_dn_sha256() const; + + /** * Get the notBefore of the certificate. * @return notBefore of the certificate */ |