diff options
author | lloyd <[email protected]> | 2010-09-17 14:13:48 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-09-17 14:13:48 +0000 |
commit | 4ef234d711e1dd40f1cd7ec328e9933fb19dc5ee (patch) | |
tree | d0a9209ad8576e99bae3f85ff669695b4c4d416c /src/cert/x509crl | |
parent | 8fa7d0b4f91eec572d8b2971d87e68741d1cd330 (diff) |
Split up src/cert/x509 into a set of modules, though mostly mutually
dependent right now.
Diffstat (limited to 'src/cert/x509crl')
-rw-r--r-- | src/cert/x509crl/crl_ent.cpp | 107 | ||||
-rw-r--r-- | src/cert/x509crl/crl_ent.h | 79 | ||||
-rw-r--r-- | src/cert/x509crl/x509_crl.cpp | 147 | ||||
-rw-r--r-- | src/cert/x509crl/x509_crl.h | 94 |
4 files changed, 427 insertions, 0 deletions
diff --git a/src/cert/x509crl/crl_ent.cpp b/src/cert/x509crl/crl_ent.cpp new file mode 100644 index 000000000..807e99ac9 --- /dev/null +++ b/src/cert/x509crl/crl_ent.cpp @@ -0,0 +1,107 @@ +/* +* CRL Entry +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/crl_ent.h> +#include <botan/x509_ext.h> +#include <botan/der_enc.h> +#include <botan/ber_dec.h> +#include <botan/bigint.h> +#include <botan/oids.h> +#include <botan/time.h> + +namespace Botan { + +/* +* Create a CRL_Entry +*/ +CRL_Entry::CRL_Entry(bool t_on_unknown_crit) : + throw_on_unknown_critical(t_on_unknown_crit) + { + reason = UNSPECIFIED; + } + +/* +* Create a CRL_Entry +*/ +CRL_Entry::CRL_Entry(const X509_Certificate& cert, CRL_Code why) : + throw_on_unknown_critical(false) + { + serial = cert.serial_number(); + time = X509_Time(system_time()); + reason = why; + } + +/* +* Compare two CRL_Entrys for equality +*/ +bool operator==(const CRL_Entry& a1, const CRL_Entry& a2) + { + if(a1.serial_number() != a2.serial_number()) + return false; + if(a1.expire_time() != a2.expire_time()) + return false; + if(a1.reason_code() != a2.reason_code()) + return false; + return true; + } + +/* +* Compare two CRL_Entrys for inequality +*/ +bool operator!=(const CRL_Entry& a1, const CRL_Entry& a2) + { + return !(a1 == a2); + } + +/* +* Compare two CRL_Entrys +*/ +bool operator<(const CRL_Entry& a1, const CRL_Entry& a2) + { + return (a1.expire_time().cmp(a2.expire_time()) < 0); + } + +/* +* DER encode a CRL_Entry +*/ +void CRL_Entry::encode_into(DER_Encoder& der) const + { + Extensions extensions; + + extensions.add(new Cert_Extension::CRL_ReasonCode(reason)); + + der.start_cons(SEQUENCE) + .encode(BigInt::decode(serial)) + .encode(time) + .encode(extensions) + .end_cons(); + } + +/* +* Decode a BER encoded CRL_Entry +*/ +void CRL_Entry::decode_from(BER_Decoder& source) + { + BigInt serial_number_bn; + + source.start_cons(SEQUENCE) + .decode(serial_number_bn) + .decode(time); + + if(source.more_items()) + { + Extensions extensions(throw_on_unknown_critical); + source.decode(extensions); + Data_Store info; + extensions.contents_to(info, info); + reason = CRL_Code(info.get1_u32bit("X509v3.CRLReasonCode")); + } + + serial = BigInt::encode(serial_number_bn); + } + +} diff --git a/src/cert/x509crl/crl_ent.h b/src/cert/x509crl/crl_ent.h new file mode 100644 index 000000000..ec90750db --- /dev/null +++ b/src/cert/x509crl/crl_ent.h @@ -0,0 +1,79 @@ +/* +* CRL Entry +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_CRL_ENTRY_H__ +#define BOTAN_CRL_ENTRY_H__ + +#include <botan/x509cert.h> + +namespace Botan { + +/** +* This class represents CRL entries +*/ +class BOTAN_DLL CRL_Entry : public ASN1_Object + { + public: + void encode_into(class DER_Encoder&) const; + void decode_from(class BER_Decoder&); + + /** + * Get the serial number of the certificate associated with this entry. + * @return certificate's serial number + */ + MemoryVector<byte> serial_number() const { return serial; } + + /** + * Get the revocation date of the certificate associated with this entry + * @return certificate's revocation date + */ + X509_Time expire_time() const { return time; } + + /** + * Get the entries reason code + * @return reason code + */ + CRL_Code reason_code() const { return reason; } + + /** + * Construct an empty CRL entry. + */ + CRL_Entry(bool throw_on_unknown_critical_extension = false); + + /** + * Construct an CRL entry. + * @param cert the certificate to revoke + * @param reason the reason code to set in the entry + */ + CRL_Entry(const X509_Certificate& cert, + CRL_Code reason = UNSPECIFIED); + + private: + bool throw_on_unknown_critical; + MemoryVector<byte> serial; + X509_Time time; + CRL_Code reason; + }; + +/** +* Test two CRL entries for equality in all fields. +*/ +BOTAN_DLL bool operator==(const CRL_Entry&, const CRL_Entry&); + +/** +* Test two CRL entries for inequality in at least one field. +*/ +BOTAN_DLL bool operator!=(const CRL_Entry&, const CRL_Entry&); + +/** +* Order two entries based on the revocation date. +*/ +BOTAN_DLL bool operator<(const CRL_Entry&, const CRL_Entry&); + +} + +#endif diff --git a/src/cert/x509crl/x509_crl.cpp b/src/cert/x509crl/x509_crl.cpp new file mode 100644 index 000000000..f6a344dba --- /dev/null +++ b/src/cert/x509crl/x509_crl.cpp @@ -0,0 +1,147 @@ +/* +* X.509 CRL +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/x509_crl.h> +#include <botan/x509_ext.h> +#include <botan/ber_dec.h> +#include <botan/parsing.h> +#include <botan/bigint.h> +#include <botan/oids.h> + +namespace Botan { + +/* +* Load a X.509 CRL +*/ +X509_CRL::X509_CRL(DataSource& in, bool touc) : + X509_Object(in, "X509 CRL/CRL"), throw_on_unknown_critical(touc) + { + do_decode(); + } + +/* +* Load a X.509 CRL +*/ +X509_CRL::X509_CRL(const std::string& in, bool touc) : + X509_Object(in, "CRL/X509 CRL"), throw_on_unknown_critical(touc) + { + do_decode(); + } + +/* +* Decode the TBSCertList data +*/ +void X509_CRL::force_decode() + { + BER_Decoder tbs_crl(tbs_bits); + + u32bit version; + tbs_crl.decode_optional(version, INTEGER, UNIVERSAL); + + if(version != 0 && version != 1) + throw X509_CRL_Error("Unknown X.509 CRL version " + + to_string(version+1)); + + AlgorithmIdentifier sig_algo_inner; + tbs_crl.decode(sig_algo_inner); + + if(sig_algo != sig_algo_inner) + throw X509_CRL_Error("Algorithm identifier mismatch"); + + X509_DN dn_issuer; + tbs_crl.decode(dn_issuer); + info.add(dn_issuer.contents()); + + X509_Time start, end; + tbs_crl.decode(start).decode(end); + info.add("X509.CRL.start", start.readable_string()); + info.add("X509.CRL.end", end.readable_string()); + + BER_Object next = tbs_crl.get_next_object(); + + if(next.type_tag == SEQUENCE && next.class_tag == CONSTRUCTED) + { + BER_Decoder cert_list(next.value); + + while(cert_list.more_items()) + { + CRL_Entry entry(throw_on_unknown_critical); + cert_list.decode(entry); + revoked.push_back(entry); + } + next = tbs_crl.get_next_object(); + } + + if(next.type_tag == 0 && + next.class_tag == ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC)) + { + BER_Decoder crl_options(next.value); + + Extensions extensions(throw_on_unknown_critical); + + crl_options.decode(extensions).verify_end(); + + extensions.contents_to(info, info); + + next = tbs_crl.get_next_object(); + } + + if(next.type_tag != NO_OBJECT) + throw X509_CRL_Error("Unknown tag in CRL"); + + tbs_crl.verify_end(); + } + +/* +* Return the list of revoked certificates +*/ +std::vector<CRL_Entry> X509_CRL::get_revoked() const + { + return revoked; + } + +/* +* Return the distinguished name of the issuer +*/ +X509_DN X509_CRL::issuer_dn() const + { + return create_dn(info); + } + +/* +* Return the key identifier of the issuer +*/ +MemoryVector<byte> X509_CRL::authority_key_id() const + { + return info.get1_memvec("X509v3.AuthorityKeyIdentifier"); + } + +/* +* Return the CRL number of this CRL +*/ +u32bit X509_CRL::crl_number() const + { + return info.get1_u32bit("X509v3.CRLNumber"); + } + +/* +* Return the issue data of the CRL +*/ +X509_Time X509_CRL::this_update() const + { + return info.get1("X509.CRL.start"); + } + +/* +* Return the date when a new CRL will be issued +*/ +X509_Time X509_CRL::next_update() const + { + return info.get1("X509.CRL.end"); + } + +} diff --git a/src/cert/x509crl/x509_crl.h b/src/cert/x509crl/x509_crl.h new file mode 100644 index 000000000..c2b3c4f5c --- /dev/null +++ b/src/cert/x509crl/x509_crl.h @@ -0,0 +1,94 @@ +/* +* X.509 CRL +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_X509_CRL_H__ +#define BOTAN_X509_CRL_H__ + +#include <botan/x509_obj.h> +#include <botan/crl_ent.h> +#include <vector> + +namespace Botan { + +/** +* This class represents X.509 Certificate Revocation Lists (CRLs). +*/ +class BOTAN_DLL X509_CRL : public X509_Object + { + public: + /** + * This class represents CRL related errors. + */ + struct BOTAN_DLL X509_CRL_Error : public Exception + { + X509_CRL_Error(const std::string& error) : + Exception("X509_CRL: " + error) {} + }; + + /** + * 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; + + /** + * Get the issuer DN of this CRL. + * @return CRLs issuer DN + */ + X509_DN issuer_dn() const; + + /** + * Get the AuthorityKeyIdentifier of this CRL. + * @return this CRLs AuthorityKeyIdentifier + */ + MemoryVector<byte> authority_key_id() const; + + /** + * Get the serial number of this CRL. + * @return CRLs serial number + */ + u32bit crl_number() const; + + /** + * Get the CRL's thisUpdate value. + * @return CRLs thisUpdate + */ + X509_Time this_update() const; + + /** + * Get the CRL's nextUpdate value. + * @return CRLs nextdUpdate + */ + 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); + + /** + * 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); + private: + void force_decode(); + + bool throw_on_unknown_critical; + std::vector<CRL_Entry> revoked; + Data_Store info; + }; + +} + +#endif |