diff options
author | lloyd <[email protected]> | 2014-02-16 14:22:33 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2014-02-16 14:22:33 +0000 |
commit | 4b09a2480c30e1b58473265f95550faa10b04af2 (patch) | |
tree | 5ed53d4e9d60967cfd96cb78c86656398e42ac13 /src/lib | |
parent | 08413f0bc40ed37acd5b05a9e1fe427f197e209c (diff) |
Don't assume the leading cert chain is presented in-order
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/cert/x509/x509path.cpp | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/src/lib/cert/x509/x509path.cpp b/src/lib/cert/x509/x509path.cpp index 4f1971311..317c34718 100644 --- a/src/lib/cert/x509/x509path.cpp +++ b/src/lib/cert/x509/x509path.cpp @@ -1,6 +1,6 @@ /* * X.509 Certificate Path Validation -* (C) 2010,2011,2012 Jack Lloyd +* (C) 2010,2011,2012,2014 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -19,12 +19,17 @@ namespace Botan { namespace { -const X509_Certificate* find_issuing_cert(const X509_Certificate& cert, - const std::vector<Certificate_Store*>& certstores) +const X509_Certificate* +find_issuing_cert(const X509_Certificate& cert, + Certificate_Store& end_certs, + const std::vector<Certificate_Store*>& certstores) { const X509_DN issuer_dn = cert.issuer_dn(); const std::vector<byte> auth_key_id = cert.authority_key_id(); + if(const X509_Certificate* cert = end_certs.find_cert(issuer_dn, auth_key_id)) + return cert; + for(size_t i = 0; i != certstores.size(); ++i) { if(const X509_Certificate* cert = certstores[i]->find_cert(issuer_dn, auth_key_id)) @@ -192,14 +197,21 @@ Path_Validation_Result x509_path_validate( if(end_certs.empty()) throw std::invalid_argument("x509_path_validate called with no subjects"); - std::vector<X509_Certificate> cert_path = end_certs; + std::vector<X509_Certificate> cert_path; + cert_path.push_back(end_certs[0]); + + Certificate_Store_Overlay extra(end_certs); // iterate until we reach a root or cannot find the issuer while(!cert_path.back().is_self_signed()) { - const X509_Certificate* cert = find_issuing_cert(cert_path.back(), certstores); + const X509_Certificate* cert = find_issuing_cert(cert_path.back(), extra, certstores); if(!cert) return Path_Validation_Result(Certificate_Status_Code::CERT_ISSUER_NOT_FOUND); + + if(cert->path_limit() && (cert->path_limit() < cert_path.size()-1)) + return Path_Validation_Result(Certificate_Status_Code::CERT_CHAIN_TOO_LONG); + cert_path.push_back(*cert); } |