From 51e49a04f968931c6bd0f9a77d69cabe2c0fc710 Mon Sep 17 00:00:00 2001 From: René Korthaus Date: Sun, 10 Apr 2016 19:45:52 +0200 Subject: Add Unknown_Critical_Extension type --- src/lib/cert/x509/x509_ext.cpp | 25 +++++++++++++++++-------- src/lib/cert/x509/x509_ext.h | 29 ++++++++++++++++++++++++++--- src/lib/cert/x509/x509path.cpp | 5 ----- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/lib/cert/x509/x509_ext.cpp b/src/lib/cert/x509/x509_ext.cpp index 0125719cc..7dd6100ee 100644 --- a/src/lib/cert/x509/x509_ext.cpp +++ b/src/lib/cert/x509/x509_ext.cpp @@ -20,7 +20,7 @@ namespace Botan { /* * List of X.509 Certificate Extensions */ -Certificate_Extension* Extensions::get_extension(const OID& oid) +Certificate_Extension* Extensions::get_extension(const OID& oid, bool critical) { #define X509_EXTENSION(NAME, TYPE) \ if(OIDS::name_of(oid, NAME)) \ @@ -40,7 +40,7 @@ Certificate_Extension* Extensions::get_extension(const OID& oid) X509_EXTENSION("X509v3.CRLNumber", CRL_Number); X509_EXTENSION("X509v3.ReasonCode", CRL_ReasonCode); - return nullptr; + return critical ? new Cert_Extension::Unknown_Critical_Extension() : nullptr; } /* @@ -146,7 +146,7 @@ void Extensions::decode_from(BER_Decoder& from_source) m_extensions_raw.emplace(oid, std::make_pair(value, critical)); - std::unique_ptr ext(get_extension(oid)); + std::unique_ptr ext(get_extension(oid, critical)); if(!ext && critical && m_throw_on_unknown_critical) throw Decoding_Error("Encountered unknown X.509 extension marked " @@ -184,11 +184,6 @@ void Extensions::contents_to(Data_Store& subject_info, } } -bool Extensions::is_known_extension(const OID& oid) - { - return get_extension(oid) != nullptr; - } - namespace Cert_Extension { @@ -745,6 +740,20 @@ void CRL_Distribution_Points::Distribution_Point::decode_from(class BER_Decoder& .end_cons().end_cons(); } +std::vector Unknown_Critical_Extension::encode_inner() const + { + throw Exception("Unknown_Critical_Extension encoding not implemented"); + } + +void Unknown_Critical_Extension::decode_inner(const std::vector& buf) + { + } + +void Unknown_Critical_Extension::contents_to(Data_Store& info, Data_Store&) const + { + // TODO: textual representation? + } + } } diff --git a/src/lib/cert/x509/x509_ext.h b/src/lib/cert/x509/x509_ext.h index 2dfc71509..e1e8666ff 100644 --- a/src/lib/cert/x509/x509_ext.h +++ b/src/lib/cert/x509/x509_ext.h @@ -90,8 +90,6 @@ class BOTAN_DLL Extensions : public ASN1_Object std::map, bool>> extensions_raw() const; - static bool is_known_extension(const OID& oid); - Extensions& operator=(const Extensions&); Extensions(const Extensions&); @@ -99,7 +97,7 @@ class BOTAN_DLL Extensions : public ASN1_Object explicit Extensions(bool st = true) : m_throw_on_unknown_critical(st) {} private: - static Certificate_Extension* get_extension(const OID&); + static Certificate_Extension* get_extension(const OID&, bool); std::vector, bool>> m_extensions; bool m_throw_on_unknown_critical; @@ -478,6 +476,31 @@ class BOTAN_DLL CRL_Distribution_Points final : public Certificate_Extension std::vector m_distribution_points; }; +/** +* An unknown X.509 extension marked as critical +* Will always add a failure to the path validation result. +*/ +class BOTAN_DLL Unknown_Critical_Extension final : public Certificate_Extension + { + public: + Unknown_Critical_Extension* copy() const override + { return new Unknown_Critical_Extension(); } + + void validate(const X509_Certificate& /* current_cert */, std::set& status, + const std::vector& /* cert_path */) + { + status.insert(Certificate_Status_Code::UNKNOWN_CRITICAL_EXTENSION); + } + private: + std::string oid_name() const override + { return "Unknown OID name"; } + + bool should_encode() const { return false; } + std::vector encode_inner() const override; + void decode_inner(const std::vector&) override; + void contents_to(Data_Store&, Data_Store&) const override; + }; + } } diff --git a/src/lib/cert/x509/x509path.cpp b/src/lib/cert/x509/x509path.cpp index dfd45f951..3f760cd54 100644 --- a/src/lib/cert/x509/x509path.cpp +++ b/src/lib/cert/x509/x509path.cpp @@ -205,11 +205,6 @@ check_chain(const std::vector& cert_path, Extensions extensions = subject.v3_extensions(); for (auto& extension : extensions.extensions()) { - if(!Extensions::is_known_extension(extension.first->oid_of()) && extension.second) - { - status.insert(Certificate_Status_Code::UNKNOWN_CRITICAL_EXTENSION); - continue; - } extension.first->validate(cert_path[i], status, cert_path); } } -- cgit v1.2.3