aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/cert/x509/x509path.cpp
diff options
context:
space:
mode:
authorRenĂ© Korthaus <[email protected]>2016-04-05 11:55:59 +0200
committerRenĂ© Korthaus <[email protected]>2016-04-06 16:25:52 +0200
commit6bb53f89ef97bb8c5bee8d78c85ccb96a29e8f46 (patch)
tree70ac1d4719b160135a0e19c68b68457d09e61c7a /src/lib/cert/x509/x509path.cpp
parent6a902a886c5b71ac16f2d957b5bdd319ab6eae0b (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.cpp17
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";