diff options
author | Jack Lloyd <[email protected]> | 2016-11-25 11:22:44 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-11-25 11:22:44 -0500 |
commit | e30d8d0fad3f9316ef31170ecec9d291288289f5 (patch) | |
tree | 453f6e29dbee78b414b37e9b57f46b7dfcea38b2 /src/lib/x509/x509path.h | |
parent | 6a3be8fa07d337b78a2d4aad5e45023fa6015ecd (diff) |
Address review comments from @cordney
Primarily doc updates but also expose some more logic in PKIX namespace,
overall_status and merge_revocation_status. This allows calling more or less all
of the logic used by the monolitic x509_path_validate in any way needed by an
application.
Add Certificate_Store_In_Memory::add_crl variant taking shared_ptr
Add optional Certificate_Store_In_Memory* pointer to check_crl_online,
valid CRLs are saved there.
Diffstat (limited to 'src/lib/x509/x509path.h')
-rw-r--r-- | src/lib/x509/x509path.h | 237 |
1 files changed, 164 insertions, 73 deletions
diff --git a/src/lib/x509/x509path.h b/src/lib/x509/x509path.h index 6b544dba3..e8d90b4a9 100644 --- a/src/lib/x509/x509path.h +++ b/src/lib/x509/x509path.h @@ -34,6 +34,9 @@ class BOTAN_DLL Path_Validation_Restrictions * operations, eg 80 means 2^80) of a signature. Signatures * weaker than this are rejected. If more than 80, SHA-1 * signatures are also rejected. + * 80 bit strength requires 1024 bit RSA + * 110 bit strength requires 2048 bit RSA + * Using 128 requires ECC (P-256) or ~3000 bit RSA keys. * @param ocsp_all_intermediates Make OCSP requests for all CAs as * well as end entity (if OCSP enabled in path validation request) */ @@ -68,7 +71,8 @@ class BOTAN_DLL Path_Validation_Restrictions { return m_require_revocation_information; } /** - * FIXME add doc + * @return whether all intermediate CAs should also be OCSPed. If false + * then only end entity OCSP is required/requested. */ bool ocsp_all_intermediates() const { return m_ocsp_all_intermediates; } @@ -160,82 +164,11 @@ class BOTAN_DLL Path_Validation_Result explicit Path_Validation_Result(Certificate_Status_Code status) : m_overall(status) {} private: - Certificate_Status_Code m_overall; std::vector<std::set<Certificate_Status_Code>> m_all_status; std::vector<std::shared_ptr<const X509_Certificate>> m_cert_path; + Certificate_Status_Code m_overall; }; -namespace PKIX { - -/** -* Build certificate path -* @param cert_path_out output parameter, cert_path will be appended to this vector -* @param trusted_certstores list of certificate stores that contain trusted certificates -* @param end_entity the cert to be validated -* @param end_entity_extra optional list of additional untrusted certs for path building -* @return result of the path building operation (OK or error) -*/ -Certificate_Status_Code -BOTAN_DLL build_certificate_path(std::vector<std::shared_ptr<const X509_Certificate>>& cert_path_out, - const std::vector<Certificate_Store*>& trusted_certstores, - const std::shared_ptr<const X509_Certificate>& end_entity, - const std::vector<std::shared_ptr<const X509_Certificate>>& end_entity_extra); - -/** -* Perform certificate validation -* @param cert_path path built by build_certificate_path with OK result -* @param ref_time whatever time you want to perform the validation -* against (normally current system clock) -* @param hostname the hostname -* @param usage end entity usage checks -* @param min_signature_algo_strength 80 or 128 typically -* @param trusted_hashes set of trusted hash functions, -* empty means accept any hash we have an OID for -*/ -std::vector<std::set<Certificate_Status_Code>> -BOTAN_DLL check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, - std::chrono::system_clock::time_point ref_time, - const std::string& hostname, - Usage_Type usage, - size_t min_signature_algo_strength, - const std::set<std::string>& trusted_hashes); - -std::vector<std::set<Certificate_Status_Code>> -BOTAN_DLL check_ocsp(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses, - const std::vector<Certificate_Store*>& certstores, - std::chrono::system_clock::time_point ref_time); - -std::vector<std::set<Certificate_Status_Code>> -BOTAN_DLL check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, - const std::vector<std::shared_ptr<const X509_CRL>>& crls, - std::chrono::system_clock::time_point ref_time); - -std::vector<std::set<Certificate_Status_Code>> -BOTAN_DLL check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, - const std::vector<Certificate_Store*>& certstores, - std::chrono::system_clock::time_point ref_time); - -#if defined(BOTAN_HAS_ONLINE_REVOCATION_CHECKS) - -std::vector<std::set<Certificate_Status_Code>> -BOTAN_DLL check_ocsp_online(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, - const std::vector<Certificate_Store*>& trusted_certstores, - std::chrono::system_clock::time_point ref_time, - std::chrono::milliseconds timeout, - bool ocsp_check_intermediate_CAs); - -std::vector<std::set<Certificate_Status_Code>> -BOTAN_DLL check_crl_online(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, - const std::vector<Certificate_Store*>& trusted_certstores, - std::chrono::system_clock::time_point ref_time, - std::chrono::milliseconds timeout); - -#endif - -} - - /** * PKIX Path Validation * @param end_certs certificate chain to validate @@ -316,6 +249,164 @@ Path_Validation_Result BOTAN_DLL x509_path_validate( std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0)); + +/** +* namespace PKIX holds the building blocks that are called by x509_path_validate. +* This allows custom validation logic to be written by applications and makes +* for easier testing, but unless you're positive you know what you're doing you +* probably want to just call x509_path_validate instead. +*/ +namespace PKIX { + +/** +* Build certificate path +* @param cert_path_out output parameter, cert_path will be appended to this vector +* @param trusted_certstores list of certificate stores that contain trusted certificates +* @param end_entity the cert to be validated +* @param end_entity_extra optional list of additional untrusted certs for path building +* @return result of the path building operation (OK or error) +*/ +Certificate_Status_Code +BOTAN_DLL build_certificate_path(std::vector<std::shared_ptr<const X509_Certificate>>& cert_path_out, + const std::vector<Certificate_Store*>& trusted_certstores, + const std::shared_ptr<const X509_Certificate>& end_entity, + const std::vector<std::shared_ptr<const X509_Certificate>>& end_entity_extra); + +/** +* Check the certificate chain, but not any revocation data +* +* @param cert_path path built by build_certificate_path with OK result +* @param ref_time whatever time you want to perform the validation +* against (normally current system clock) +* @param hostname the hostname +* @param usage end entity usage checks +* @param min_signature_algo_strength 80 or 110 typically +* Note 80 allows 1024 bit RSA and SHA-1. 110 allows 2048 bit RSA and SHA-2. +* Using 128 requires ECC (P-256) or ~3000 bit RSA keys. +* @param trusted_hashes set of trusted hash functions, empty means accept any +* hash we have an OID for +* @return vector of results on per certificate in the path, each containing a set of +* results. If all codes in the set are < Certificate_Status_Code::FIRST_ERROR_STATUS, +* then the result for that certificate is successful. If all results are +*/ +std::vector<std::set<Certificate_Status_Code>> +BOTAN_DLL check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, + std::chrono::system_clock::time_point ref_time, + const std::string& hostname, + Usage_Type usage, + size_t min_signature_algo_strength, + const std::set<std::string>& trusted_hashes); + +/** +* Check OCSP responses for revocation information +* @param cert_path path already validated by check_chain +* @param ocsp_responses the OCSP responses to consider +* @param certstores trusted roots +* @param ref_time whatever time you want to perform the validation against +* (normally current system clock) +* @return revocation status +*/ +std::vector<std::set<Certificate_Status_Code>> +BOTAN_DLL check_ocsp(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, + const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses, + const std::vector<Certificate_Store*>& certstores, + std::chrono::system_clock::time_point ref_time); + +/** +* Check CRLs for revocation infomration +* @param cert_path path already validated by check_chain +* @param crls the list of CRLs to check, it is assumed that crls[i] (if not null) +* is the associated CRL for the subject in cert_path[i]. +* @param ref_time whatever time you want to perform the validation against +* (normally current system clock) +* @return revocation status +*/ +std::vector<std::set<Certificate_Status_Code>> +BOTAN_DLL check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, + const std::vector<std::shared_ptr<const X509_CRL>>& crls, + std::chrono::system_clock::time_point ref_time); + +/** +* Check CRLs for revocation infomration +* @param cert_path path already validated by check_chain +* @param certstores a list of certificate stores to query for the CRL +* @param ref_time whatever time you want to perform the validation against +* (normally current system clock) +* @return revocation status +*/ +std::vector<std::set<Certificate_Status_Code>> +BOTAN_DLL check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, + const std::vector<Certificate_Store*>& certstores, + std::chrono::system_clock::time_point ref_time); + +#if defined(BOTAN_HAS_ONLINE_REVOCATION_CHECKS) + +/** +* Check OCSP using online (HTTP) access. Current version creates a thread and +* network connection per OCSP request made. +* +* @param cert_path path already validated by check_chain +* @param trusted_certstores a list of certstores with trusted certs +* @param ref_time whatever time you want to perform the validation against +* (normally current system clock) +* @param timeout for timing out the responses, though actually this function +* may block for up to timeout*cert_path.size()*C for some small C. +* @param ocsp_check_intermediate_CAs if true also performs OCSP on any intermediate +* CA certificates. If false, only does OCSP on the end entity cert. +* @return revocation status +*/ +std::vector<std::set<Certificate_Status_Code>> +BOTAN_DLL check_ocsp_online(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, + const std::vector<Certificate_Store*>& trusted_certstores, + std::chrono::system_clock::time_point ref_time, + std::chrono::milliseconds timeout, + bool ocsp_check_intermediate_CAs); + +/** +* Check CRL using online (HTTP) access. Current version creates a thread and +* network connection per CRL access. + +* @param cert_path path already validated by check_chain +* @param trusted_certstores a list of certstores with trusted certs +* @param certstore_to_recv_crls optional (nullptr to disable), all CRLs +* retreived will be saved to this cert store. +* @param ref_time whatever time you want to perform the validation against +* (normally current system clock) +* @param timeout for timing out the responses, though actually this function +* may block for up to timeout*cert_path.size()*C for some small C. +* @return revocation status +*/ +std::vector<std::set<Certificate_Status_Code>> +BOTAN_DLL check_crl_online(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, + const std::vector<Certificate_Store*>& trusted_certstores, + Certificate_Store_In_Memory* certstore_to_recv_crls, + std::chrono::system_clock::time_point ref_time, + std::chrono::milliseconds timeout); + +#endif + +/** +* Find overall status (OK, error) of a validation +* @param cert_status result of merge_revocation_status or check_chain +*/ +Certificate_Status_Code BOTAN_DLL overall_status(const std::vector<std::set<Certificate_Status_Code>>& cert_status); + +/** +* Merge the results from CRL and/or OCSP checks into chain_status +* @param chain_status the certificate status +* @param crl_status results from check_crl +* @param ocsp_status results from check_ocsp +* @param require_rev_on_end_entity require valid CRL or OCSP on end-entity cert +* @param require_rev_on_intermediates require valid CRL or OCSP on all intermediate certificates +*/ +void BOTAN_DLL merge_revocation_status(std::vector<std::set<Certificate_Status_Code>>& chain_status, + const std::vector<std::set<Certificate_Status_Code>>& crl_status, + const std::vector<std::set<Certificate_Status_Code>>& ocsp_status, + bool require_rev_on_end_entity, + bool require_rev_on_intermediates); + +} + } #endif |