aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-11-14 09:20:28 -0500
committerJack Lloyd <[email protected]>2017-11-14 16:19:44 -0500
commitbc552d5ced2a3727c93070c82a87a4338f95e0db (patch)
treeaa7e92b84ad85c29c753b2a9f232ab582eb63fff /src
parent9f8e50700367bc7775f5cb1fee9dab787316411f (diff)
Store X509_CRL data in shared_ptr
Diffstat (limited to 'src')
-rw-r--r--src/lib/x509/x509_crl.cpp133
-rw-r--r--src/lib/x509/x509_crl.h38
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;
};
}