diff options
author | lloyd <[email protected]> | 2012-06-13 18:06:57 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-06-13 18:06:57 +0000 |
commit | 6dc2f28174e110427899727690c82a8d230c908e (patch) | |
tree | 0d092b56dd740b15552b211a2f9b7ffd50d59964 | |
parent | 9644a3ecebb15d8241e65dcae63bd6d0382a95a6 (diff) |
Add support (decoding only) for the CRL Distribution Point extension.
-rw-r--r-- | src/asn1/ber_dec.h | 38 | ||||
-rw-r--r-- | src/cert/x509/x509_ext.cpp | 54 | ||||
-rw-r--r-- | src/cert/x509/x509_ext.h | 62 | ||||
-rw-r--r-- | src/cert/x509/x509cert.cpp | 7 | ||||
-rw-r--r-- | src/cert/x509/x509cert.h | 5 | ||||
-rw-r--r-- | src/libstate/policy.cpp | 1 | ||||
-rw-r--r-- | src/utils/datastor/datastor.cpp | 16 | ||||
-rw-r--r-- | src/utils/datastor/datastor.h | 5 |
8 files changed, 156 insertions, 32 deletions
diff --git a/src/asn1/ber_dec.h b/src/asn1/ber_dec.h index e9f519d59..0d0d0ec72 100644 --- a/src/asn1/ber_dec.h +++ b/src/asn1/ber_dec.h @@ -97,6 +97,15 @@ class BOTAN_DLL BER_Decoder const T& default_value = T()); template<typename T> + BER_Decoder& decode_optional_implicit( + T& out, + ASN1_Tag type_tag, + ASN1_Tag class_tag, + ASN1_Tag real_type, + ASN1_Tag real_class, + const T& default_value = T()); + + template<typename T> BER_Decoder& decode_list(std::vector<T>& out, ASN1_Tag type_tag = SEQUENCE, ASN1_Tag class_tag = UNIVERSAL); @@ -172,6 +181,35 @@ BER_Decoder& BER_Decoder::decode_optional(T& out, } /* +* Decode an OPTIONAL or DEFAULT element +*/ +template<typename T> +BER_Decoder& BER_Decoder::decode_optional_implicit( + T& out, + ASN1_Tag type_tag, + ASN1_Tag class_tag, + ASN1_Tag real_type, + ASN1_Tag real_class, + const T& default_value) + { + BER_Object obj = get_next_object(); + + if(obj.type_tag == type_tag && obj.class_tag == class_tag) + { + obj.type_tag = real_type; + obj.class_tag = real_class; + push_back(obj); + decode(out, real_type, real_class); + } + else + { + out = default_value; + push_back(obj); + } + + return (*this); + } +/* * Decode a list of homogenously typed values */ template<typename T> diff --git a/src/cert/x509/x509_ext.cpp b/src/cert/x509/x509_ext.cpp index 6be0c7571..7cef2969b 100644 --- a/src/cert/x509/x509_ext.cpp +++ b/src/cert/x509/x509_ext.cpp @@ -1,6 +1,6 @@ /* * X.509 Certificate Extensions -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2010,2012 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -34,6 +34,7 @@ Certificate_Extension* Extensions::get_extension(const OID& oid) X509_EXTENSION("X509v3.IssuerAlternativeName", Issuer_Alternative_Name); X509_EXTENSION("X509v3.SubjectAlternativeName", Subject_Alternative_Name); X509_EXTENSION("X509v3.CertificatePolicies", Certificate_Policies); + X509_EXTENSION("X509v3.CRLDistributionPoints", CRL_Distribution_Points); X509_EXTENSION("PKIX.AuthorityInformationAccess", Authority_Information_Access); X509_EXTENSION("X509v3.CRLNumber", CRL_Number); X509_EXTENSION("X509v3.ReasonCode", CRL_ReasonCode); @@ -375,22 +376,18 @@ void Alternative_Name::contents_to(Data_Store& subject_info, * Alternative_Name Constructor */ Alternative_Name::Alternative_Name(const AlternativeName& alt_name, - const std::string& oid_name_str, - const std::string& config_name_str) + const std::string& oid_name_str) { this->alt_name = alt_name; this->oid_name_str = oid_name_str; - this->config_name_str = config_name_str; } /* * Subject_Alternative_Name Constructor */ Subject_Alternative_Name::Subject_Alternative_Name( - const AlternativeName& name) : - - Alternative_Name(name, "X509v3.SubjectAlternativeName", - "subject_alternative_name") + const AlternativeName& name) : + Alternative_Name(name, "X509v3.SubjectAlternativeName") { } @@ -398,8 +395,7 @@ Subject_Alternative_Name::Subject_Alternative_Name( * Issuer_Alternative_Name Constructor */ Issuer_Alternative_Name::Issuer_Alternative_Name(const AlternativeName& name) : - Alternative_Name(name, "X509v3.IssuerAlternativeName", - "issuer_alternative_name") + Alternative_Name(name, "X509v3.IssuerAlternativeName") { } @@ -621,6 +617,44 @@ void CRL_ReasonCode::contents_to(Data_Store& info, Data_Store&) const info.add("X509v3.CRLReasonCode", reason); } +std::vector<byte> CRL_Distribution_Points::encode_inner() const + { + throw std::runtime_error("CRL_Distribution_Points encoding not implemented"); + } + +void CRL_Distribution_Points::decode_inner(const std::vector<byte>& buf) + { + BER_Decoder(buf).decode_list(m_distribution_points).verify_end(); + } + +void CRL_Distribution_Points::contents_to(Data_Store& info, Data_Store&) const + { + for(size_t i = 0; i != m_distribution_points.size(); ++i) + { + auto point = m_distribution_points[i].point().contents(); + + auto uris = point.equal_range("URI"); + + for(auto uri = uris.first; uri != uris.second; ++uri) + info.add("CRL.DistributionPoint", uri->second); + } + } + +void CRL_Distribution_Points::Distribution_Point::encode_into(class DER_Encoder&) const + { + throw std::runtime_error("CRL_Distribution_Points encoding not implemented"); + } + +void CRL_Distribution_Points::Distribution_Point::decode_from(class BER_Decoder& ber) + { + ber.start_cons(SEQUENCE) + .start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC) + .decode_optional_implicit(m_point, ASN1_Tag(0), + ASN1_Tag(CONTEXT_SPECIFIC | CONSTRUCTED), + SEQUENCE, CONSTRUCTED) + .end_cons().end_cons(); + } + } } diff --git a/src/cert/x509/x509_ext.h b/src/cert/x509/x509_ext.h index 63bbdb072..42434c4c2 100644 --- a/src/cert/x509/x509_ext.h +++ b/src/cert/x509/x509_ext.h @@ -1,6 +1,6 @@ /* * X.509 Certificate Extensions -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2012 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -43,11 +43,6 @@ class BOTAN_DLL Certificate_Extension Data_Store& issuer) const = 0; /* - * @return short readable name - */ - virtual std::string config_id() const = 0; - - /* * @return specific OID name */ virtual std::string oid_name() const = 0; @@ -104,7 +99,6 @@ class BOTAN_DLL Basic_Constraints : public Certificate_Extension bool get_is_ca() const { return is_ca; } size_t get_path_limit() const; private: - std::string config_id() const { return "basic_constraints"; } std::string oid_name() const { return "X509v3.BasicConstraints"; } std::vector<byte> encode_inner() const; @@ -127,7 +121,6 @@ class BOTAN_DLL Key_Usage : public Certificate_Extension Key_Constraints get_constraints() const { return constraints; } private: - std::string config_id() const { return "key_usage"; } std::string oid_name() const { return "X509v3.KeyUsage"; } bool should_encode() const { return (constraints != NO_CONSTRAINTS); } @@ -151,7 +144,6 @@ class BOTAN_DLL Subject_Key_ID : public Certificate_Extension std::vector<byte> get_key_id() const { return key_id; } private: - std::string config_id() const { return "subject_key_id"; } std::string oid_name() const { return "X509v3.SubjectKeyIdentifier"; } bool should_encode() const { return (key_id.size() > 0); } @@ -175,7 +167,6 @@ class BOTAN_DLL Authority_Key_ID : public Certificate_Extension std::vector<byte> get_key_id() const { return key_id; } private: - std::string config_id() const { return "authority_key_id"; } std::string oid_name() const { return "X509v3.AuthorityKeyIdentifier"; } bool should_encode() const { return (key_id.size() > 0); } @@ -195,12 +186,10 @@ class BOTAN_DLL Alternative_Name : public Certificate_Extension AlternativeName get_alt_name() const { return alt_name; } protected: - Alternative_Name(const AlternativeName&, - const std::string&, const std::string&); + Alternative_Name(const AlternativeName&, const std::string& oid_name); Alternative_Name(const std::string&, const std::string&); private: - std::string config_id() const { return config_name_str; } std::string oid_name() const { return oid_name_str; } bool should_encode() const { return alt_name.has_items(); } @@ -208,7 +197,7 @@ class BOTAN_DLL Alternative_Name : public Certificate_Extension void decode_inner(const std::vector<byte>&); void contents_to(Data_Store&, Data_Store&) const; - std::string config_name_str, oid_name_str; + std::string oid_name_str; AlternativeName alt_name; }; @@ -249,7 +238,6 @@ class BOTAN_DLL Extended_Key_Usage : public Certificate_Extension std::vector<OID> get_oids() const { return oids; } private: - std::string config_id() const { return "extended_key_usage"; } std::string oid_name() const { return "X509v3.ExtendedKeyUsage"; } bool should_encode() const { return (oids.size() > 0); } @@ -274,7 +262,6 @@ class BOTAN_DLL Certificate_Policies : public Certificate_Extension std::vector<OID> get_oids() const { return oids; } private: - std::string config_id() const { return "policy_info"; } std::string oid_name() const { return "X509v3.CertificatePolicies"; } bool should_encode() const { return (oids.size() > 0); } @@ -297,7 +284,6 @@ class BOTAN_DLL Authority_Information_Access : public Certificate_Extension m_ocsp_responder(ocsp) {} private: - std::string config_id() const { return "auth_information_access"; } std::string oid_name() const { return "PKIX.AuthorityInformationAccess"; } bool should_encode() const { return (m_ocsp_responder != ""); } @@ -323,7 +309,6 @@ class BOTAN_DLL CRL_Number : public Certificate_Extension size_t get_crl_number() const; private: - std::string config_id() const { return "crl_number"; } std::string oid_name() const { return "X509v3.CRLNumber"; } bool should_encode() const { return has_value; } @@ -347,7 +332,6 @@ class BOTAN_DLL CRL_ReasonCode : public Certificate_Extension CRL_Code get_reason() const { return reason; } private: - std::string config_id() const { return "crl_reason"; } std::string oid_name() const { return "X509v3.ReasonCode"; } bool should_encode() const { return (reason != UNSPECIFIED); } @@ -358,6 +342,46 @@ class BOTAN_DLL CRL_ReasonCode : public Certificate_Extension CRL_Code reason; }; +/** +* CRL Distribution Points Extension +*/ +class BOTAN_DLL CRL_Distribution_Points : public Certificate_Extension + { + public: + class BOTAN_DLL Distribution_Point : public ASN1_Object + { + public: + void encode_into(class DER_Encoder&) const; + void decode_from(class BER_Decoder&); + + const AlternativeName& point() const { return m_point; } + private: + AlternativeName m_point; + }; + + CRL_Distribution_Points* copy() const + { return new CRL_Distribution_Points(m_distribution_points); } + + CRL_Distribution_Points() {} + + CRL_Distribution_Points(const std::vector<Distribution_Point>& points) : + m_distribution_points(points) {} + + std::vector<Distribution_Point> distribution_points() const + { return m_distribution_points; } + + private: + std::string oid_name() const { return "X509v3.CRLDistributionPoints"; } + + bool should_encode() const { return !m_distribution_points.empty(); } + + std::vector<byte> encode_inner() const; + void decode_inner(const std::vector<byte>&); + void contents_to(Data_Store&, Data_Store&) const; + + std::vector<Distribution_Point> m_distribution_points; + }; + } } diff --git a/src/cert/x509/x509cert.cpp b/src/cert/x509/x509cert.cpp index 05a548be4..1a99192c8 100644 --- a/src/cert/x509/x509cert.cpp +++ b/src/cert/x509/x509cert.cpp @@ -278,7 +278,12 @@ std::vector<std::string> X509_Certificate::policies() const std::string X509_Certificate::ocsp_responder() const { - return subject.get1("OCSP.responder"); + return subject.get1("OCSP.responder", ""); + } + +std::string X509_Certificate::crl_distribution_point() const + { + return subject.get1("CRL.DistributionPoint", ""); } /* diff --git a/src/cert/x509/x509cert.h b/src/cert/x509/x509cert.h index c226928dc..c4f2dfb72 100644 --- a/src/cert/x509/x509cert.h +++ b/src/cert/x509/x509cert.h @@ -171,6 +171,11 @@ class BOTAN_DLL X509_Certificate : public X509_Object std::string ocsp_responder() const; /** + * Return the CRL distribution point, or empty if not set + */ + std::string crl_distribution_point() const; + + /** * @return a string describing the certificate */ std::string to_string() const; diff --git a/src/libstate/policy.cpp b/src/libstate/policy.cpp index 527833e61..fc127478e 100644 --- a/src/libstate/policy.cpp +++ b/src/libstate/policy.cpp @@ -189,6 +189,7 @@ void set_default_oids(Library_State& config) add_oid(config, "2.5.29.21", "X509v3.ReasonCode"); add_oid(config, "2.5.29.23", "X509v3.HoldInstructionCode"); add_oid(config, "2.5.29.24", "X509v3.InvalidityDate"); + add_oid(config, "2.5.29.31", "X509v3.CRLDistributionPoints"); add_oid(config, "2.5.29.32", "X509v3.CertificatePolicies"); add_oid(config, "2.5.29.35", "X509v3.AuthorityKeyIdentifier"); add_oid(config, "2.5.29.36", "X509v3.PolicyConstraints"); diff --git a/src/utils/datastor/datastor.cpp b/src/utils/datastor/datastor.cpp index d32c4787e..7563e9309 100644 --- a/src/utils/datastor/datastor.cpp +++ b/src/utils/datastor/datastor.cpp @@ -64,13 +64,27 @@ std::string Data_Store::get1(const std::string& key) const std::vector<std::string> vals = get(key); if(vals.empty()) - throw Invalid_State("Data_Store::get1: Not values for " + key); + throw Invalid_State("Data_Store::get1: No values set for " + key); if(vals.size() > 1) throw Invalid_State("Data_Store::get1: More than one value for " + key); return vals[0]; } +std::string Data_Store::get1(const std::string& key, + const std::string& default_value) const + { + std::vector<std::string> vals = get(key); + + if(vals.size() > 1) + throw Invalid_State("Data_Store::get1: More than one value for " + key); + + if(vals.empty()) + return default_value; + + return vals[0]; + } + /* * Get a single std::vector atom */ diff --git a/src/utils/datastor/datastor.h b/src/utils/datastor/datastor.h index b471f85e1..1c0504fc9 100644 --- a/src/utils/datastor/datastor.h +++ b/src/utils/datastor/datastor.h @@ -33,7 +33,10 @@ class BOTAN_DLL Data_Store std::vector<std::string> get(const std::string&) const; - std::string get1(const std::string&) const; + std::string get1(const std::string& key) const; + + std::string get1(const std::string& key, + const std::string& default_value) const; std::vector<byte> get1_memvec(const std::string&) const; u32bit get1_u32bit(const std::string&, u32bit = 0) const; |