Botan 3.12.0
Crypto and TLS for C&
Botan::PKIX Namespace Reference

Functions

Certificate_Status_Code build_all_certificate_paths (std::vector< std::vector< X509_Certificate > > &cert_paths, const std::vector< Certificate_Store * > &trusted_certstores, const X509_Certificate &end_entity, const std::vector< X509_Certificate > &end_entity_extra)
Certificate_Status_Code build_certificate_path (std::vector< X509_Certificate > &cert_path_out, const std::vector< Certificate_Store * > &trusted_certstores, const X509_Certificate &end_entity, const std::vector< X509_Certificate > &end_entity_extra)
CertificatePathStatusCodes check_chain (const std::vector< X509_Certificate > &cert_path, std::chrono::system_clock::time_point ref_time, std::string_view hostname, Usage_Type usage, const Path_Validation_Restrictions &restrictions)
CertificatePathStatusCodes check_crl (const std::vector< X509_Certificate > &cert_path, const std::vector< Certificate_Store * > &certstores, std::chrono::system_clock::time_point ref_time)
CertificatePathStatusCodes check_crl (const std::vector< X509_Certificate > &cert_path, const std::vector< std::optional< X509_CRL > > &crls, std::chrono::system_clock::time_point ref_time)
CertificatePathStatusCodes check_ocsp (const std::vector< X509_Certificate > &cert_path, const std::vector< std::optional< OCSP::Response > > &ocsp_responses, const std::vector< Certificate_Store * > &certstores, std::chrono::system_clock::time_point ref_time, const Path_Validation_Restrictions &restrictions)
void merge_revocation_status (CertificatePathStatusCodes &chain_status, const CertificatePathStatusCodes &crl_status, const CertificatePathStatusCodes &ocsp_status, const Path_Validation_Restrictions &restrictions)
Certificate_Status_Code overall_status (const CertificatePathStatusCodes &cert_status)

Detailed Description

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.

Function Documentation

◆ build_all_certificate_paths()

Certificate_Status_Code Botan::PKIX::build_all_certificate_paths ( std::vector< std::vector< X509_Certificate > > & cert_paths,
const std::vector< Certificate_Store * > & trusted_certstores,
const X509_Certificate & end_entity,
const std::vector< X509_Certificate > & end_entity_extra )

Create all certificate paths by identifying all possible routes from the end-entity certificate to any certificate in the certificate store list. Paths may also end in intermediate or leaf certificates found in the certificate stores.

WARNING: The validity (e.g. signatures or constraints) of the output path IS NOT checked.

Parameters
cert_pathsoutput parameter to be filled with all discovered certificate paths
trusted_certstoreslist of certificate stores that contain trusted certificates
end_entitythe cert to be validated
end_entity_extraoptional list of additional untrusted certs for path building
Returns
result of the path building operation (OK or error)

Definition at line 847 of file x509path.cpp.

850 {
851 if(!cert_paths_out.empty()) {
852 throw Invalid_Argument("PKIX::build_all_certificate_paths: cert_paths_out must be empty");
853 }
854 CertificatePathBuilder builder(trusted_certstores, end_entity, end_entity_extra);
855
856 while(auto path = builder.next()) {
857 BOTAN_ASSERT_NOMSG(path->empty() == false);
858 cert_paths_out.push_back(std::move(*path));
859 }
860
861 if(!cert_paths_out.empty()) {
862 // Was able to generate at least one potential path
864 } else {
865 // Could not construct any potentially valid path...
866 return builder.error();
867 }
868}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References BOTAN_ASSERT_NOMSG, and Botan::OK.

◆ build_certificate_path()

Certificate_Status_Code Botan::PKIX::build_certificate_path ( std::vector< X509_Certificate > & cert_path_out,
const std::vector< Certificate_Store * > & trusted_certstores,
const X509_Certificate & end_entity,
const std::vector< X509_Certificate > & end_entity_extra )

Same as build_all_certificate_paths but only outputs a single path. If there are paths ending in self-signed certificates, these are prioritized over paths ending in intermediate or leaf certificates of the certificate store.

WARNING: The validity (e.g. signatures or constraints) of the output path IS NOT checked.

Parameters
cert_path_outoutput parameter, cert_path will be appended to this vector
trusted_certstoreslist of certificate stores that contain trusted certificates
end_entitythe cert to be validated
end_entity_extraoptional list of additional untrusted certs for path building
Returns
result of the path building operation (OK or error)

Definition at line 814 of file x509path.cpp.

817 {
818 CertificatePathBuilder builder(trusted_certstores, end_entity, end_entity_extra);
819
820 std::vector<X509_Certificate> first_path;
821
822 while(auto path = builder.next()) {
823 BOTAN_ASSERT_NOMSG(path->empty() == false);
824
825 // Prefer paths ending in self-signed certificates.
826 if(path->back().is_self_signed()) {
827 cert_path.insert(cert_path.end(), path->begin(), path->end());
829 }
830
831 // Save the first path for later just in case we find nothing better
832 if(first_path.empty()) {
833 first_path = std::move(*path);
834 }
835 }
836
837 if(!first_path.empty()) {
838 // We found a path, it's not self-signed but it's as good as can be formed...
839 cert_path.insert(cert_path.end(), first_path.begin(), first_path.end());
841 }
842
843 // Failed to build any path at all
844 return builder.error();
845}

References BOTAN_ASSERT_NOMSG, and Botan::OK.

◆ check_chain()

CertificatePathStatusCodes Botan::PKIX::check_chain ( const std::vector< X509_Certificate > & cert_path,
std::chrono::system_clock::time_point ref_time,
std::string_view hostname,
Usage_Type usage,
const Path_Validation_Restrictions & restrictions )

Check the certificate chain, but not any revocation data

Parameters
cert_pathpath built by build_certificate_path with OK result. The first element is the end entity certificate, the last element is the trusted root certificate.
ref_timewhatever time you want to perform the validation against (normally current system clock)
hostnamethe hostname
usageend entity usage checks
restrictionsthe relevant path validation restrictions object
Returns
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

Definition at line 209 of file x509path.cpp.

213 {
214 if(cert_path.empty()) {
215 throw Invalid_Argument("PKIX::check_chain cert_path empty");
216 }
217
218 const bool is_end_entity_trust_anchor = (cert_path.size() == 1);
219
220 const X509_Time validation_time(ref_time);
221
222 CertificatePathStatusCodes cert_status(cert_path.size());
223
224 // Before anything else verify the entire chain of signatures
225 for(size_t i = 0; i != cert_path.size(); ++i) {
226 std::set<Certificate_Status_Code>& status = cert_status.at(i);
227
228 const bool at_trust_anchor = (i == cert_path.size() - 1);
229
230 const X509_Certificate& subject = cert_path[i];
231
232 // If using intermediate CAs as trust anchors, the signature of the trust
233 // anchor cannot be verified since the issuer is not part of the
234 // certificate chain
235 if(!restrictions.require_self_signed_trust_anchors() && at_trust_anchor && !subject.is_self_signed()) {
236 continue;
237 }
238
239 const X509_Certificate& issuer = cert_path[at_trust_anchor ? (i) : (i + 1)];
240
241 // Check the signature algorithm is known
242 if(!subject.signature_algorithm().oid().registered_oid()) {
244 } else {
245 std::unique_ptr<Public_Key> issuer_key;
246 try {
247 issuer_key = issuer.subject_public_key();
248 } catch(...) {
250 }
251
252 if(issuer_key) {
253 if(issuer_key->estimated_strength() < restrictions.minimum_key_strength()) {
255 }
256
257 const auto sig_status = subject.verify_signature(*issuer_key);
258
259 if(sig_status.first != Certificate_Status_Code::VERIFIED) {
260 status.insert(sig_status.first);
261 } else {
262 // Signature is valid, check if hash used was acceptable
263 const std::string hash_used_for_signature = sig_status.second;
264 BOTAN_ASSERT_NOMSG(!hash_used_for_signature.empty());
265 const auto& trusted_hashes = restrictions.trusted_hashes();
266
267 // Ignore untrusted hashes on self-signed roots
268 if(!trusted_hashes.empty() && !at_trust_anchor) {
269 if(!trusted_hashes.contains(hash_used_for_signature)) {
271 }
272 }
273 }
274 }
275 }
276 }
277
278 // If any of the signatures were invalid, return immediately; we know the
279 // chain is invalid and signature failure is always considered the most
280 // critical result. This does mean other problems in the certificate (eg
281 // expired) will not be reported, but we'd have to assume any such data is
282 // anyway arbitrary considering we couldn't verify the signature chain
283
284 for(size_t i = 0; i != cert_path.size(); ++i) {
285 for(auto status : cert_status.at(i)) {
286 // This ignores errors relating to the key or hash being weak since
287 // these are somewhat advisory
288 if(static_cast<uint32_t>(status) >= 5000) {
289 return cert_status;
290 }
291 }
292 }
293
294 if(!hostname.empty() && !cert_path[0].matches_dns_name(hostname)) {
295 cert_status[0].insert(Certificate_Status_Code::CERT_NAME_NOMATCH);
296 }
297
298 if(!cert_path[0].allowed_usage(usage)) {
299 if(usage == Usage_Type::OCSP_RESPONDER) {
301 }
302 cert_status[0].insert(Certificate_Status_Code::INVALID_USAGE);
303 }
304
305 if(cert_path[0].has_constraints(Key_Constraints::KeyCertSign) && cert_path[0].is_CA_cert() == false) {
306 /*
307 "If the keyCertSign bit is asserted, then the cA bit in the
308 basic constraints extension (Section 4.2.1.9) MUST also be
309 asserted." - RFC 5280
310
311 We don't bother doing this check on the rest of the path since they
312 must have the cA bit asserted or the validation will fail anyway.
313 */
314 cert_status[0].insert(Certificate_Status_Code::INVALID_USAGE);
315 }
316
317 for(size_t i = 0; i != cert_path.size(); ++i) {
318 std::set<Certificate_Status_Code>& status = cert_status.at(i);
319
320 const bool at_trust_anchor = (i == cert_path.size() - 1);
321
322 const X509_Certificate& subject = cert_path[i];
323 const auto issuer = [&]() -> std::optional<X509_Certificate> {
324 if(!at_trust_anchor) {
325 return cert_path[i + 1];
326 } else if(subject.is_self_signed()) {
327 return cert_path[i];
328 } else {
329 return {}; // Non self-signed trust anchors have no checkable issuers.
330 }
331 }();
332
333 if(restrictions.require_self_signed_trust_anchors() && !issuer.has_value()) {
335 }
336
337 // This should never happen; it indicates a bug in path building
338 if(issuer.has_value() && subject.issuer_dn() != issuer->subject_dn()) {
340 }
341
342 // Check the serial number
343 if(subject.is_serial_negative()) {
345 }
346
347 // Check the subject's DN components' length
348
349 for(const auto& dn_pair : subject.subject_dn().dn_info()) {
350 const size_t dn_ub = X509_DN::lookup_ub(dn_pair.first);
351 // dn_pair = <OID,str>
352 if(dn_ub > 0 && dn_pair.second.size() > dn_ub) {
354 }
355 }
356
357 // If so configured, allow trust anchors outside the validity period with
358 // a warning rather than a hard error
359 const bool enforce_validity_period = !at_trust_anchor || !restrictions.ignore_trusted_root_time_range();
360 // Check all certs for valid time range
361 if(validation_time < subject.not_before()) {
362 if(enforce_validity_period) {
364 } else {
365 status.insert(Certificate_Status_Code::TRUSTED_CERT_NOT_YET_VALID); // only warn
366 }
367 }
368
369 if(validation_time > subject.not_after()) {
370 if(enforce_validity_period) {
372 } else {
373 status.insert(Certificate_Status_Code::TRUSTED_CERT_HAS_EXPIRED); // only warn
374 }
375 }
376
377 // Check issuer constraints
378 if(issuer.has_value() && !issuer->is_CA_cert() && !is_end_entity_trust_anchor) {
380 }
381
382 // Check cert extensions
383
384 if(subject.x509_version() == 1) {
385 if(subject.v2_issuer_key_id().empty() == false || subject.v2_subject_key_id().empty() == false) {
387 }
388 }
389
390 const Extensions& extensions = subject.v3_extensions();
391 const auto& extensions_vec = extensions.extensions();
392 if(subject.x509_version() < 3 && !extensions_vec.empty()) {
394 }
395
396 for(const auto& extension : extensions_vec) {
397 extension.first->validate(subject, issuer, cert_path, cert_status, i);
398 }
399
400 if(extensions_vec.size() != extensions.get_extension_oids().size()) {
402 }
403 }
404
405 // path len check
406 size_t max_path_length = cert_path.size();
407 for(size_t i = cert_path.size() - 1; i > 0; --i) {
408 std::set<Certificate_Status_Code>& status = cert_status.at(i);
409 const X509_Certificate& subject = cert_path[i];
410
411 /*
412 * If the certificate was not self-issued, verify that max_path_length is
413 * greater than zero and decrement max_path_length by 1.
414 */
415 if(subject.subject_dn() != subject.issuer_dn()) {
416 if(max_path_length > 0) {
417 max_path_length -= 1;
418 } else {
420 }
421 }
422
423 /*
424 * If pathLenConstraint is present in the certificate and is less than max_path_length,
425 * set max_path_length to the value of pathLenConstraint.
426 */
427 if(auto path_len_constraint = subject.path_length_constraint()) {
428 max_path_length = std::min(max_path_length, *path_len_constraint);
429 }
430 }
431
432 return cert_status;
433}
const OID & oid() const
Definition asn1_obj.h:407
bool registered_oid() const
Definition asn1_oid.cpp:151
const std::set< std::string > & trusted_hashes() const
Definition x509path.h:119
bool ignore_trusted_root_time_range() const
Definition x509path.h:150
bool require_self_signed_trust_anchors() const
Definition x509path.h:159
bool is_self_signed() const
Definition x509cert.cpp:354
static size_t lookup_ub(const OID &oid)
const AlgorithmIdentifier & signature_algorithm() const
Definition x509_obj.cpp:73
std::pair< Certificate_Status_Code, std::string > verify_signature(const Public_Key &key) const
Definition x509_obj.cpp:130
std::vector< std::set< Certificate_Status_Code > > CertificatePathStatusCodes
Definition x509path.h:28
ASN1_Time X509_Time
Definition asn1_obj.h:23

References BOTAN_ASSERT_NOMSG, Botan::CA_CERT_NOT_FOR_CERT_ISSUER, Botan::CERT_CHAIN_TOO_LONG, Botan::CERT_HAS_EXPIRED, Botan::CERT_NAME_NOMATCH, Botan::CERT_NOT_YET_VALID, Botan::CERT_PUBKEY_INVALID, Botan::CERT_SERIAL_NEGATIVE, Botan::CHAIN_LACKS_TRUST_ROOT, Botan::CHAIN_NAME_MISMATCH, Botan::X509_DN::dn_info(), Botan::DN_TOO_LONG, Botan::DUPLICATE_CERT_EXTENSION, Botan::EXT_IN_V1_V2_CERT, Botan::Extensions::extensions(), Botan::Extensions::get_extension_oids(), Botan::Path_Validation_Restrictions::ignore_trusted_root_time_range(), Botan::INVALID_USAGE, Botan::X509_Certificate::is_self_signed(), Botan::X509_Certificate::is_serial_negative(), Botan::X509_Certificate::issuer_dn(), Botan::Key_Constraints::KeyCertSign, Botan::X509_DN::lookup_ub(), Botan::Path_Validation_Restrictions::minimum_key_strength(), Botan::X509_Certificate::not_after(), Botan::X509_Certificate::not_before(), Botan::OCSP_RESPONDER, Botan::OCSP_RESPONSE_MISSING_KEYUSAGE, Botan::AlgorithmIdentifier::oid(), Botan::X509_Certificate::path_length_constraint(), Botan::OID::registered_oid(), Botan::Path_Validation_Restrictions::require_self_signed_trust_anchors(), Botan::SIGNATURE_ALGO_UNKNOWN, Botan::X509_Object::signature_algorithm(), Botan::SIGNATURE_METHOD_TOO_WEAK, Botan::X509_Certificate::subject_dn(), Botan::X509_Certificate::subject_public_key(), Botan::TRUSTED_CERT_HAS_EXPIRED, Botan::TRUSTED_CERT_NOT_YET_VALID, Botan::Path_Validation_Restrictions::trusted_hashes(), Botan::UNTRUSTED_HASH, Botan::V2_IDENTIFIERS_IN_V1_CERT, Botan::X509_Certificate::v2_issuer_key_id(), Botan::X509_Certificate::v2_subject_key_id(), Botan::X509_Certificate::v3_extensions(), Botan::VERIFIED, Botan::X509_Object::verify_signature(), and Botan::X509_Certificate::x509_version().

Referenced by Botan::x509_path_validate().

◆ check_crl() [1/2]

CertificatePathStatusCodes Botan::PKIX::check_crl ( const std::vector< X509_Certificate > & cert_path,
const std::vector< Certificate_Store * > & certstores,
std::chrono::system_clock::time_point ref_time )

Check CRLs for revocation information

Parameters
cert_pathpath already validated by check_chain
certstoresa list of certificate stores to query for the CRL
ref_timewhatever time you want to perform the validation against (normally current system clock)
Returns
revocation status

Definition at line 644 of file x509path.cpp.

646 {
647 if(cert_path.empty()) {
648 throw Invalid_Argument("PKIX::check_crl cert_path empty");
649 }
650
651 if(certstores.empty()) {
652 throw Invalid_Argument("PKIX::check_crl certstores empty");
653 }
654
655 std::vector<std::optional<X509_CRL>> crls(cert_path.size());
656
657 for(size_t i = 0; i != cert_path.size(); ++i) {
658 for(auto* certstore : certstores) {
659 crls[i] = certstore->find_crl_for(cert_path[i]);
660 if(crls[i]) {
661 break;
662 }
663 }
664 }
665
666 return PKIX::check_crl(cert_path, crls, ref_time);
667}
CertificatePathStatusCodes check_crl(const std::vector< X509_Certificate > &cert_path, const std::vector< std::optional< X509_CRL > > &crls, std::chrono::system_clock::time_point ref_time)
Definition x509path.cpp:579

References check_crl().

◆ check_crl() [2/2]

CertificatePathStatusCodes Botan::PKIX::check_crl ( const std::vector< X509_Certificate > & cert_path,
const std::vector< std::optional< X509_CRL > > & crls,
std::chrono::system_clock::time_point ref_time )

Check CRLs for revocation information

Parameters
cert_pathpath already validated by check_chain
crlsthe 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].
ref_timewhatever time you want to perform the validation against (normally current system clock)
Returns
revocation status

Definition at line 579 of file x509path.cpp.

581 {
582 if(cert_path.empty()) {
583 throw Invalid_Argument("PKIX::check_crl cert_path empty");
584 }
585
586 CertificatePathStatusCodes cert_status(cert_path.size());
587 const X509_Time validation_time(ref_time);
588
589 for(size_t i = 0; i != cert_path.size() - 1; ++i) {
590 std::set<Certificate_Status_Code>& status = cert_status.at(i);
591
592 if(i < crls.size() && crls[i].has_value()) {
593 const X509_Certificate& subject = cert_path.at(i);
594 const X509_Certificate& ca = cert_path.at(i + 1);
595
598 }
599
600 if(validation_time < crls[i]->this_update()) {
602 }
603
604 if(crls[i]->next_update().time_is_set() && validation_time > crls[i]->next_update()) {
606 }
607
608 auto ca_key = ca.subject_public_key();
609 if(crls[i]->check_signature(*ca_key) == false) {
611 } else {
613
614 if(crls[i]->is_revoked(subject)) {
616 }
617
618 if(!crls[i]->has_matching_distribution_point(subject)) {
620 }
621
622 for(const auto& [extension, critical] : crls[i]->extensions().extensions()) {
623 if(critical) {
624 /* NIST Certificate Path Validation Testing document: "When an implementation does
625 * not recognize a critical extension in the crlExtensions field, it shall assume
626 * that identified certificates have been revoked and are no longer valid"
627 */
628 if(dynamic_cast<const Cert_Extension::Unknown_Extension*>(extension.get()) != nullptr) {
630 }
631 }
632 }
633 }
634 }
635 }
636
637 while(!cert_status.empty() && cert_status.back().empty()) {
638 cert_status.pop_back();
639 }
640
641 return cert_status;
642}
bool allowed_usage(Key_Constraints usage) const
Definition x509cert.cpp:486
std::unique_ptr< Public_Key > subject_public_key() const
Definition x509cert.cpp:659

References Botan::X509_Certificate::allowed_usage(), Botan::CA_CERT_NOT_FOR_CRL_ISSUER, Botan::CERT_IS_REVOKED, Botan::CRL_BAD_SIGNATURE, Botan::CRL_HAS_EXPIRED, Botan::CRL_NOT_YET_VALID, Botan::Key_Constraints::CrlSign, Botan::NO_MATCHING_CRLDP, Botan::X509_Certificate::subject_public_key(), and Botan::VALID_CRL_CHECKED.

Referenced by check_crl(), and Botan::x509_path_validate().

◆ check_ocsp()

CertificatePathStatusCodes Botan::PKIX::check_ocsp ( const std::vector< X509_Certificate > & cert_path,
const std::vector< std::optional< OCSP::Response > > & ocsp_responses,
const std::vector< Certificate_Store * > & certstores,
std::chrono::system_clock::time_point ref_time,
const Path_Validation_Restrictions & restrictions )

Check OCSP responses for revocation information

Parameters
cert_pathpath already validated by check_chain
ocsp_responsesthe OCSP responses to consider
certstorestrusted roots
ref_timewhatever time you want to perform the validation against (normally current system clock)
restrictionsthe relevant path validation restrictions object
Returns
revocation status

Definition at line 550 of file x509path.cpp.

554 {
555 if(cert_path.empty()) {
556 throw Invalid_Argument("PKIX::check_ocsp cert_path empty");
557 }
558
559 CertificatePathStatusCodes cert_status(cert_path.size() - 1);
560
561 for(size_t i = 0; i != cert_path.size() - 1; ++i) {
562 const X509_Certificate& subject = cert_path.at(i);
563 const X509_Certificate& ca = cert_path.at(i + 1);
564
565 if(i < ocsp_responses.size() && ocsp_responses.at(i).has_value() &&
566 ocsp_responses.at(i)->status() == OCSP::Response_Status_Code::Successful) {
567 try {
568 cert_status.at(i) = evaluate_ocsp_response(
569 ocsp_responses.at(i).value(), subject, ca, cert_path, certstores, ref_time, restrictions);
570 } catch(Exception&) {
571 cert_status.at(i).insert(Certificate_Status_Code::OCSP_RESPONSE_INVALID);
572 }
573 }
574 }
575
576 return cert_status;
577}

References Botan::OCSP_RESPONSE_INVALID, and Botan::OCSP::Successful.

Referenced by Botan::x509_path_validate().

◆ merge_revocation_status()

void Botan::PKIX::merge_revocation_status ( CertificatePathStatusCodes & chain_status,
const CertificatePathStatusCodes & crl_status,
const CertificatePathStatusCodes & ocsp_status,
const Path_Validation_Restrictions & restrictions )

Merge the results from CRL and/or OCSP checks into chain_status

Parameters
chain_statusthe certificate status
crl_statusresults from check_crl
ocsp_statusresults from check_ocsp
restrictionsthe relevant path validation restrictions object

Definition at line 870 of file x509path.cpp.

873 {
874 if(chain_status.empty()) {
875 throw Invalid_Argument("PKIX::merge_revocation_status chain_status was empty");
876 }
877
878 for(size_t i = 0; i != chain_status.size() - 1; ++i) {
879 bool had_crl = false;
880 bool had_ocsp = false;
881
882 if(i < crl_status.size() && !crl_status[i].empty()) {
883 for(auto&& code : crl_status[i]) {
885 had_crl = true;
886 }
887 chain_status[i].insert(code);
888 }
889 }
890
891 if(i < ocsp_status.size() && !ocsp_status[i].empty()) {
892 for(auto&& code : ocsp_status[i]) {
893 // NO_REVOCATION_URL and OCSP_SERVER_NOT_AVAILABLE are softfail
897 had_ocsp = true;
898 }
899
900 chain_status[i].insert(code);
901 }
902 }
903
904 if(had_crl == false && had_ocsp == false) {
905 if((restrictions.require_revocation_information() && i == 0) ||
906 (restrictions.ocsp_all_intermediates() && i > 0)) {
907 chain_status[i].insert(Certificate_Status_Code::NO_REVOCATION_DATA);
908 }
909 }
910 }
911}
bool require_revocation_information() const
Definition x509path.h:108

References Botan::NO_REVOCATION_DATA, Botan::Path_Validation_Restrictions::ocsp_all_intermediates(), Botan::OCSP_NO_REVOCATION_URL, Botan::OCSP_RESPONSE_GOOD, Botan::OCSP_SERVER_NOT_AVAILABLE, Botan::Path_Validation_Restrictions::require_revocation_information(), and Botan::VALID_CRL_CHECKED.

Referenced by Botan::x509_path_validate().

◆ overall_status()

Certificate_Status_Code Botan::PKIX::overall_status ( const CertificatePathStatusCodes & cert_status)

Find overall status (OK, error) of a validation

Parameters
cert_statusresult of merge_revocation_status or check_chain

Definition at line 913 of file x509path.cpp.

913 {
914 if(cert_status.empty()) {
915 throw Invalid_Argument("PKIX::overall_status empty cert status");
916 }
917
919
920 // take the "worst" error as overall
921 for(const std::set<Certificate_Status_Code>& s : cert_status) {
922 if(!s.empty()) {
923 auto worst = *s.rbegin();
924 // Leave informative OCSP/CRL confirmations on cert-level status only
926 overall_status = worst;
927 }
928 }
929 }
930 return overall_status;
931}
Certificate_Status_Code overall_status(const CertificatePathStatusCodes &cert_status)
Definition x509path.cpp:913
Certificate_Status_Code
Definition pkix_enums.h:20

References Botan::FIRST_ERROR_STATUS, Botan::OK, and overall_status().

Referenced by overall_status(), and Botan::x509_path_validate().