diff options
author | René Korthaus <[email protected]> | 2016-04-05 11:55:59 +0200 |
---|---|---|
committer | René Korthaus <[email protected]> | 2016-04-06 16:25:52 +0200 |
commit | 6bb53f89ef97bb8c5bee8d78c85ccb96a29e8f46 (patch) | |
tree | 70ac1d4719b160135a0e19c68b68457d09e61c7a /src/lib/cert/x509/x509path.cpp | |
parent | 6a902a886c5b71ac16f2d957b5bdd319ab6eae0b (diff) |
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.
Diffstat (limited to 'src/lib/cert/x509/x509path.cpp')
-rw-r--r-- | src/lib/cert/x509/x509path.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/lib/cert/x509/x509path.cpp b/src/lib/cert/x509/x509path.cpp index dd9df6f51..dfd45f951 100644 --- a/src/lib/cert/x509/x509path.cpp +++ b/src/lib/cert/x509/x509path.cpp @@ -113,10 +113,12 @@ check_chain(const std::vector<X509_Certificate>& cert_path, // Check issuer constraints + // TODO: put into Certificate_Extensions::Basic_Constraints::validate() // Don't require CA bit set on self-signed end entity cert if(!issuer.is_CA_cert() && !self_signed_ee_cert) status.insert(Certificate_Status_Code::CA_CERT_NOT_FOR_CERT_ISSUER); + // TODO: put into Certificate_Extensions::Basic_Constraints::validate() if(issuer.path_limit() < i) status.insert(Certificate_Status_Code::CERT_CHAIN_TOO_LONG); @@ -142,6 +144,7 @@ check_chain(const std::vector<X509_Certificate>& cert_path, status.insert(Certificate_Status_Code::UNTRUSTED_HASH); } + // TODO: put into Certificate_Extensions::Name_Constraints::validate() const NameConstraints& name_constr = issuer.name_constraints(); if(!name_constr.permitted().empty() || !name_constr.excluded().empty()) @@ -197,6 +200,18 @@ check_chain(const std::vector<X509_Certificate>& cert_path, } } } + + // Check cert extensions + 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); + } } for(size_t i = 0; i != cert_path.size() - 1; ++i) @@ -472,6 +487,8 @@ const char* Path_Validation_Result::status_string(Certificate_Status_Code code) return "Certificate does not match provided name"; case Certificate_Status_Code::NAME_CONSTRAINT_ERROR: return "Certificate does not pass name constraint"; + case Certificate_Status_Code::UNKNOWN_CRITICAL_EXTENSION: + return "Unknown critical extension encountered"; case Certificate_Status_Code::CERT_IS_REVOKED: return "Certificate is revoked"; |