diff options
author | Jack Lloyd <[email protected]> | 2017-11-14 09:20:28 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-11-14 16:19:44 -0500 |
commit | bc552d5ced2a3727c93070c82a87a4338f95e0db (patch) | |
tree | aa7e92b84ad85c29c753b2a9f232ab582eb63fff /src/lib/x509 | |
parent | 9f8e50700367bc7775f5cb1fee9dab787316411f (diff) |
Store X509_CRL data in shared_ptr
Diffstat (limited to 'src/lib/x509')
-rw-r--r-- | src/lib/x509/x509_crl.cpp | 133 | ||||
-rw-r--r-- | src/lib/x509/x509_crl.h | 38 |
2 files changed, 102 insertions, 69 deletions
diff --git a/src/lib/x509/x509_crl.cpp b/src/lib/x509/x509_crl.cpp index e27733d32..4a6c4249a 100644 --- a/src/lib/x509/x509_crl.cpp +++ b/src/lib/x509/x509_crl.cpp @@ -12,11 +12,24 @@ namespace Botan { +struct CRL_Data + { + X509_DN m_issuer; + X509_Time m_this_update; + X509_Time m_next_update; + std::vector<CRL_Entry> m_entries; + Extensions m_extensions; + + // cached values from extensions + size_t m_crl_number = 0; + std::vector<uint8_t> m_auth_key_id; + }; + /* * Load a X.509 CRL */ -X509_CRL::X509_CRL(DataSource& in, bool touc) : - X509_Object(in, "X509 CRL/CRL"), m_throw_on_unknown_critical(touc) +X509_CRL::X509_CRL(DataSource& in) : + X509_Object(in, "X509 CRL/CRL") { do_decode(); } @@ -25,26 +38,30 @@ X509_CRL::X509_CRL(DataSource& in, bool touc) : /* * Load a X.509 CRL */ -X509_CRL::X509_CRL(const std::string& fsname, bool touc) : - X509_Object(fsname, "CRL/X509 CRL"), m_throw_on_unknown_critical(touc) +X509_CRL::X509_CRL(const std::string& fsname) : + X509_Object(fsname, "CRL/X509 CRL") { do_decode(); } #endif -X509_CRL::X509_CRL(const std::vector<uint8_t>& in, bool touc) : - X509_Object(in, "CRL/X509 CRL"), m_throw_on_unknown_critical(touc) +X509_CRL::X509_CRL(const std::vector<uint8_t>& in) : + X509_Object(in, "CRL/X509 CRL") { do_decode(); } -X509_CRL::X509_CRL(const X509_DN& issuer, const X509_Time& thisUpdate, - const X509_Time& nextUpdate, const std::vector<CRL_Entry>& revoked) : - X509_Object(), m_throw_on_unknown_critical(false), m_revoked(revoked) +X509_CRL::X509_CRL(const X509_DN& issuer, + const X509_Time& this_update, + const X509_Time& next_update, + const std::vector<CRL_Entry>& revoked) : + X509_Object() { - m_info.add(issuer.contents()); - m_info.add("X509.CRL.start", thisUpdate.to_string()); - m_info.add("X509.CRL.end", nextUpdate.to_string()); + m_data.reset(new CRL_Data); + m_data->m_issuer = issuer; + m_data->m_this_update = this_update; + m_data->m_next_update = next_update; + m_data->m_entries = revoked; } /** @@ -63,18 +80,21 @@ bool X509_CRL::is_revoked(const X509_Certificate& cert) const std::vector<uint8_t> cert_akid = cert.authority_key_id(); if(!crl_akid.empty() && !cert_akid.empty()) + { if(crl_akid != cert_akid) return false; + } std::vector<uint8_t> cert_serial = cert.serial_number(); bool is_revoked = false; - for(size_t i = 0; i != m_revoked.size(); ++i) + // FIXME would be nice to avoid a linear scan here - maybe sort the entries? + for(const CRL_Entry& entry : get_revoked()) { - if(cert_serial == m_revoked[i].serial_number()) + if(cert_serial == entry.serial_number()) { - if(m_revoked[i].reason_code() == REMOVE_FROM_CRL) + if(entry.reason_code() == REMOVE_FROM_CRL) is_revoked = false; else is_revoked = true; @@ -87,31 +107,31 @@ bool X509_CRL::is_revoked(const X509_Certificate& cert) const /* * Decode the TBSCertList data */ -void X509_CRL::force_decode() +namespace { + +std::unique_ptr<CRL_Data> decode_crl_body(const std::vector<uint8_t>& body, + const AlgorithmIdentifier& sig_algo) { - BER_Decoder tbs_crl(signed_body()); + std::unique_ptr<CRL_Data> data(new CRL_Data); + + BER_Decoder tbs_crl(body); size_t version; tbs_crl.decode_optional(version, INTEGER, UNIVERSAL); if(version != 0 && version != 1) - throw X509_CRL_Error("Unknown X.509 CRL version " + + throw X509_CRL::X509_CRL_Error("Unknown X.509 CRL version " + std::to_string(version+1)); AlgorithmIdentifier sig_algo_inner; tbs_crl.decode(sig_algo_inner); - if(signature_algorithm() != sig_algo_inner) - throw X509_CRL_Error("Algorithm identifier mismatch"); - - X509_DN dn_issuer; - tbs_crl.decode(dn_issuer); - m_info.add(dn_issuer.contents()); + if(sig_algo != sig_algo_inner) + throw X509_CRL::X509_CRL_Error("Algorithm identifier mismatch"); - X509_Time start, end; - tbs_crl.decode(start).decode(end); - m_info.add("X509.CRL.start", start.to_string()); - m_info.add("X509.CRL.end", end.to_string()); + tbs_crl.decode(data->m_issuer) + .decode(data->m_this_update) + .decode(data->m_next_update); BER_Object next = tbs_crl.get_next_object(); @@ -121,9 +141,9 @@ void X509_CRL::force_decode() while(cert_list.more_items()) { - CRL_Entry entry(m_throw_on_unknown_critical); + CRL_Entry entry; cert_list.decode(entry); - m_revoked.push_back(entry); + data->m_entries.push_back(entry); } next = tbs_crl.get_next_object(); } @@ -132,44 +152,59 @@ void X509_CRL::force_decode() next.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) { BER_Decoder crl_options(next.value); - - Extensions extensions(m_throw_on_unknown_critical); - - crl_options.decode(extensions).verify_end(); - - extensions.contents_to(m_info, m_info); - + crl_options.decode(data->m_extensions).verify_end(); next = tbs_crl.get_next_object(); } if(next.type_tag != NO_OBJECT) - throw X509_CRL_Error("Unknown tag in CRL"); + throw X509_CRL::X509_CRL_Error("Unknown tag in CRL"); tbs_crl.verify_end(); + + return data; + } + +} + +void X509_CRL::force_decode() + { + m_data.reset(decode_crl_body(signed_body(), signature_algorithm()).release()); + } + +const CRL_Data& X509_CRL::data() const + { + if(!m_data) + throw Decoding_Error("Error decoding X509 CRL"); + return *m_data.get(); + } + +const Extensions& X509_CRL::extensions() const + { + return data().m_extensions; } /* * Return the list of revoked certificates */ -std::vector<CRL_Entry> X509_CRL::get_revoked() const +const std::vector<CRL_Entry>& X509_CRL::get_revoked() const { - return m_revoked; + return data().m_entries; } /* * Return the distinguished name of the issuer */ -X509_DN X509_CRL::issuer_dn() const +const X509_DN& X509_CRL::issuer_dn() const { - return create_dn(m_info); + return data().m_issuer; } /* * Return the key identifier of the issuer */ -std::vector<uint8_t> X509_CRL::authority_key_id() const +const std::vector<uint8_t>& X509_CRL::authority_key_id() const { - return m_info.get1_memvec("X509v3.AuthorityKeyIdentifier"); + return data().m_auth_key_id; } /* @@ -177,23 +212,23 @@ std::vector<uint8_t> X509_CRL::authority_key_id() const */ uint32_t X509_CRL::crl_number() const { - return m_info.get1_uint32("X509v3.CRLNumber"); + return data().m_crl_number; } /* * Return the issue data of the CRL */ -X509_Time X509_CRL::this_update() const +const X509_Time& X509_CRL::this_update() const { - return X509_Time(m_info.get1("X509.CRL.start"), ASN1_Tag::UTC_OR_GENERALIZED_TIME); + return data().m_this_update; } /* * Return the date when a new CRL will be issued */ -X509_Time X509_CRL::next_update() const +const X509_Time& X509_CRL::next_update() const { - return X509_Time(m_info.get1("X509.CRL.end"), ASN1_Tag::UTC_OR_GENERALIZED_TIME); + return data().m_next_update; } } diff --git a/src/lib/x509/x509_crl.h b/src/lib/x509/x509_crl.h index 865117300..c3c986cc1 100644 --- a/src/lib/x509/x509_crl.h +++ b/src/lib/x509/x509_crl.h @@ -11,11 +11,12 @@ #include <botan/x509_obj.h> #include <botan/x509_dn.h> #include <botan/crl_ent.h> -#include <botan/datastor.h> #include <vector> namespace Botan { +class CRL_Data; +class Extensions; class X509_Certificate; /** @@ -43,19 +44,24 @@ class BOTAN_PUBLIC_API(2,0) X509_CRL final : public X509_Object * Get the entries of this CRL in the form of a vector. * @return vector containing the entries of this CRL. */ - std::vector<CRL_Entry> get_revoked() const; + const std::vector<CRL_Entry>& get_revoked() const; /** * Get the issuer DN of this CRL. * @return CRLs issuer DN */ - X509_DN issuer_dn() const; + const X509_DN& issuer_dn() const; + + /** + * @return extension data for this CRL + */ + const Extensions& extensions() const; /** * Get the AuthorityKeyIdentifier of this CRL. * @return this CRLs AuthorityKeyIdentifier */ - std::vector<uint8_t> authority_key_id() const; + const std::vector<uint8_t>& authority_key_id() const; /** * Get the serial number of this CRL. @@ -67,41 +73,33 @@ class BOTAN_PUBLIC_API(2,0) X509_CRL final : public X509_Object * Get the CRL's thisUpdate value. * @return CRLs thisUpdate */ - X509_Time this_update() const; + const X509_Time& this_update() const; /** * Get the CRL's nextUpdate value. * @return CRLs nextdUpdate */ - X509_Time next_update() const; + const X509_Time& next_update() const; /** * Construct a CRL from a data source. * @param source the data source providing the DER or PEM encoded CRL. - * @param throw_on_unknown_critical should we throw an exception - * if an unknown CRL extension marked as critical is encountered. */ - X509_CRL(DataSource& source, bool throw_on_unknown_critical = false); + X509_CRL(DataSource& source); #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) /** * Construct a CRL from a file containing the DER or PEM encoded CRL. * @param filename the name of the CRL file - * @param throw_on_unknown_critical should we throw an exception - * if an unknown CRL extension marked as critical is encountered. */ - X509_CRL(const std::string& filename, - bool throw_on_unknown_critical = false); + X509_CRL(const std::string& filename); #endif /** * Construct a CRL from a binary vector * @param vec the binary (DER) representation of the CRL - * @param throw_on_unknown_critical should we throw an exception - * if an unknown CRL extension marked as critical is encountered. */ - X509_CRL(const std::vector<uint8_t>& vec, - bool throw_on_unknown_critical = false); + X509_CRL(const std::vector<uint8_t>& vec); /** * Construct a CRL @@ -116,9 +114,9 @@ class BOTAN_PUBLIC_API(2,0) X509_CRL final : public X509_Object private: void force_decode() override; - bool m_throw_on_unknown_critical; - std::vector<CRL_Entry> m_revoked; - Data_Store m_info; + const CRL_Data& data() const; + + std::shared_ptr<CRL_Data> m_data; }; } |