aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/x509
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-04-04 16:46:16 -0400
committerJack Lloyd <[email protected]>2017-04-04 16:46:16 -0400
commita17bfd26d81d2182a5ecccb98f75ff05c7c999bd (patch)
treed977c7163cd50329141d32277c4e0a97b787a358 /src/lib/x509
parent542c6cb7338530b4a8f7d93f2410567815d993ef (diff)
parentb0068f74fb15aa4ffcb9225a60c0aaff89209b62 (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.cpp78
-rw-r--r--src/lib/x509/certstor.h12
-rw-r--r--src/lib/x509/certstor_sql/certstor_sql.cpp9
-rw-r--r--src/lib/x509/certstor_sql/certstor_sql.h3
-rw-r--r--src/lib/x509/x509_ca.cpp2
-rw-r--r--src/lib/x509/x509_ca.h2
-rw-r--r--src/lib/x509/x509cert.cpp14
-rw-r--r--src/lib/x509/x509cert.h14
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
*/