From 4b09a2480c30e1b58473265f95550faa10b04af2 Mon Sep 17 00:00:00 2001 From: lloyd Date: Sun, 16 Feb 2014 14:22:33 +0000 Subject: Don't assume the leading cert chain is presented in-order --- src/lib/cert/x509/x509path.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'src/lib/cert/x509') 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& certstores) +const X509_Certificate* +find_issuing_cert(const X509_Certificate& cert, + Certificate_Store& end_certs, + const std::vector& certstores) { const X509_DN issuer_dn = cert.issuer_dn(); const std::vector 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 cert_path = end_certs; + std::vector 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); } -- cgit v1.2.3