From 6bb53f89ef97bb8c5bee8d78c85ccb96a29e8f46 Mon Sep 17 00:00:00 2001 From: René Korthaus Date: Tue, 5 Apr 2016 11:55:59 +0200 Subject: Generate error on unknown critical extension during path validation Previously unknown critical extensions were rejected during X509_Certificate constructor, which inhibited inspecting other parts of such a certificate. Refactored the certificate extensions code so that the path validation routine performs this check only. Additionally, added an interface for extensions to inspect the path during path validation. TODOs were added in places where existing path validation code can use the new interface. Fixes GH #449. --- src/lib/cert/x509/x509_ext.h | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'src/lib/cert/x509/x509_ext.h') diff --git a/src/lib/cert/x509/x509_ext.h b/src/lib/cert/x509/x509_ext.h index ac456b998..2dfc71509 100644 --- a/src/lib/cert/x509/x509_ext.h +++ b/src/lib/cert/x509/x509_ext.h @@ -10,11 +10,17 @@ #include #include +#include +#include #include +#include +#include #include namespace Botan { +class X509_Certificate; + /** * X.509 Certificate Extension */ @@ -46,6 +52,19 @@ class BOTAN_DLL Certificate_Extension */ virtual std::string oid_name() const = 0; + /* + * Callback visited during path validation + * + * If an error occurs during validation of this extension, + * an appropriate status code shall be added to status. + * + * @param current_cert Certificate that contains this extension + * @param status Certificate validation status codes for current_cert + * @param cert_path Certificate path which is currently validated + */ + virtual void validate(const X509_Certificate& current_cert, std::set& status, + const std::vector& cert_path) = 0; + virtual ~Certificate_Extension() {} protected: friend class Extensions; @@ -67,8 +86,12 @@ class BOTAN_DLL Extensions : public ASN1_Object void add(Certificate_Extension* extn, bool critical = false); + std::vector, bool>> extensions() const; + std::map, bool>> extensions_raw() const; + static bool is_known_extension(const OID& oid); + Extensions& operator=(const Extensions&); Extensions(const Extensions&); @@ -101,6 +124,9 @@ class BOTAN_DLL Basic_Constraints final : public Certificate_Extension bool get_is_ca() const { return m_is_ca; } size_t get_path_limit() const; + + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return "X509v3.BasicConstraints"; } @@ -124,6 +150,9 @@ class BOTAN_DLL Key_Usage final : public Certificate_Extension explicit Key_Usage(Key_Constraints c = NO_CONSTRAINTS) : m_constraints(c) {} Key_Constraints get_constraints() const { return m_constraints; } + + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return "X509v3.KeyUsage"; } @@ -149,6 +178,9 @@ class BOTAN_DLL Subject_Key_ID final : public Certificate_Extension explicit Subject_Key_ID(const std::vector&); std::vector get_key_id() const { return m_key_id; } + + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return "X509v3.SubjectKeyIdentifier"; } @@ -174,6 +206,9 @@ class BOTAN_DLL Authority_Key_ID final : public Certificate_Extension explicit Authority_Key_ID(const std::vector& k) : m_key_id(k) {} std::vector get_key_id() const { return m_key_id; } + + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return "X509v3.AuthorityKeyIdentifier"; } @@ -198,6 +233,9 @@ class BOTAN_DLL Alternative_Name : public Certificate_Extension Alternative_Name(const AlternativeName&, const std::string& oid_name); Alternative_Name(const std::string&, const std::string&); + + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return m_oid_name_str; } @@ -247,6 +285,9 @@ class BOTAN_DLL Extended_Key_Usage final : public Certificate_Extension explicit Extended_Key_Usage(const std::vector& o) : m_oids(o) {} std::vector get_oids() const { return m_oids; } + + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return "X509v3.ExtendedKeyUsage"; } @@ -270,6 +311,9 @@ class BOTAN_DLL Name_Constraints : public Certificate_Extension Name_Constraints() {} Name_Constraints(const NameConstraints &nc) : m_name_constraints(nc) {} + + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return "X509v3.NameConstraints"; } @@ -295,6 +339,9 @@ class BOTAN_DLL Certificate_Policies final : public Certificate_Extension explicit Certificate_Policies(const std::vector& o) : m_oids(o) {} std::vector get_oids() const { return m_oids; } + + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return "X509v3.CertificatePolicies"; } @@ -318,6 +365,8 @@ class BOTAN_DLL Authority_Information_Access final : public Certificate_Extensio explicit Authority_Information_Access(const std::string& ocsp) : m_ocsp_responder(ocsp) {} + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return "PKIX.AuthorityInformationAccess"; } @@ -344,6 +393,9 @@ class BOTAN_DLL CRL_Number final : public Certificate_Extension CRL_Number(size_t n) : m_has_value(true), m_crl_number(n) {} size_t get_crl_number() const; + + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return "X509v3.CRLNumber"; } @@ -368,6 +420,9 @@ class BOTAN_DLL CRL_ReasonCode final : public Certificate_Extension explicit CRL_ReasonCode(CRL_Code r = UNSPECIFIED) : m_reason(r) {} CRL_Code get_reason() const { return m_reason; } + + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return "X509v3.ReasonCode"; } @@ -407,6 +462,8 @@ class BOTAN_DLL CRL_Distribution_Points final : public Certificate_Extension std::vector distribution_points() const { return m_distribution_points; } + void validate(const X509_Certificate& /* current_cert */, std::set& /* status */, + const std::vector& /* cert_path */) {} private: std::string oid_name() const override { return "X509v3.CRLDistributionPoints"; } -- cgit v1.2.3