Botan 3.13.0
Crypto and TLS for C&
ocsp.cpp
Go to the documentation of this file.
1/*
2* OCSP
3* (C) 2012,2013 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/ocsp.h>
9
10#include <botan/assert.h>
11#include <botan/base64.h>
12#include <botan/ber_dec.h>
13#include <botan/certstor.h>
14#include <botan/der_enc.h>
15#include <botan/hash.h>
16#include <botan/pubkey.h>
17#include <botan/uri.h>
18#include <botan/x509_ext.h>
19#include <botan/x509path.h>
20#include <botan/internal/fmt.h>
21
22#if defined(BOTAN_HAS_HTTP_UTIL)
23 #include <botan/internal/http_util.h>
24#endif
25
26namespace Botan::OCSP {
27
28namespace {
29
30/*
31* RFC 6960 requires producedAt, thisUpdate, nextUpdate, and revocationTime
32* to be encoded as GeneralizedTime. ASN1_Time also accepts UTCTime since that
33* is required for X.509 certificates and CRLs (RFC 5280), so enforce the
34* stricter OCSP requirement at the call site.
35*/
36void check_generalized_time(const ASN1_Time& time, const char* field) {
37 if(time.tagging() != ASN1_Type::GeneralizedTime) {
38 throw Decoding_Error(fmt("OCSP response {} was not encoded as GeneralizedTime", field));
39 }
40}
41
42} // namespace
43
44CertID::CertID(const X509_Certificate& issuer, const BigInt& subject_serial) :
45 CertID(issuer, X509_Serial_Number(subject_serial)) {}
46
47CertID::CertID(const X509_Certificate& issuer, const X509_Serial_Number& subject_serial) :
48 m_subject_serial(subject_serial) {
49 /*
50 In practice it seems some responders, including, notably,
51 ocsp.verisign.com, will reject anything but SHA-1 here
52 */
53 auto hash = HashFunction::create_or_throw("SHA-1");
54
56 m_issuer_key_hash = hash->process<std::vector<uint8_t>>(issuer.subject_public_key_bitstring());
57 m_issuer_dn_hash = hash->process<std::vector<uint8_t>>(issuer.raw_subject_dn());
58}
59
60bool CertID::is_id_for(const X509_Certificate& issuer, const X509_Certificate& subject) const {
61 try {
62 if(subject.serial() != m_subject_serial) {
63 return false;
64 }
65
66 const auto hash_algo = m_hash_id.oid().registered_name();
67
68 /*
69 RFC 6960 4.1.1
70 issuerNameHash is the hash of the issuer's distinguished name (DN).
71 The hash shall be calculated over the DER encoding of the issuer's name
72 field in the certificate being checked.
73
74 issuerKeyHash is the hash of the issuer's public key. The hash shall be
75 calculated over the value (excluding tag and length) of the subject public key
76 field in the issuer's certificate.
77 */
78
79 if(hash_algo == "SHA-1") {
80 if(!std::ranges::equal(m_issuer_dn_hash, subject.raw_issuer_dn_sha1())) {
81 return false;
82 }
83 if(!std::ranges::equal(m_issuer_key_hash, issuer.subject_public_key_bitstring_sha1())) {
84 return false;
85 }
86 } else if(hash_algo == "SHA-256") {
87 if(!std::ranges::equal(m_issuer_dn_hash, subject.raw_issuer_dn_sha256())) {
88 return false;
89 }
90 if(!std::ranges::equal(m_issuer_key_hash, issuer.subject_public_key_bitstring_sha256())) {
91 return false;
92 }
93 } else {
94 // Exotic hashes are unlikely to occur in OCSP
95 return false;
96 }
97 } catch(...) {
98 return false;
99 }
100
101 return true;
102}
103
105 to.start_sequence()
106 .encode(m_hash_id)
107 .encode(m_issuer_dn_hash, ASN1_Type::OctetString)
108 .encode(m_issuer_key_hash, ASN1_Type::OctetString)
109 .encode(m_subject_serial)
110 .end_cons();
111}
112
114 /*
115 * RFC 6960 Section 4.1.1
116 *
117 * CertID ::= SEQUENCE {
118 * hashAlgorithm AlgorithmIdentifier,
119 * issuerNameHash OCTET STRING,
120 * issuerKeyHash OCTET STRING,
121 * serialNumber CertificateSerialNumber }
122 */
123 from.start_sequence()
124 .decode(m_hash_id)
125 .decode(m_issuer_dn_hash, ASN1_Type::OctetString)
126 .decode(m_issuer_key_hash, ASN1_Type::OctetString)
127 .decode(m_subject_serial)
128 .end_cons();
129
130 if(!m_hash_id.parameters_are_null_or_empty()) {
131 throw Decoding_Error("OCSP CertID hashAlgorithm has unexpected parameters");
132 }
133}
134
135//static
137 return SingleResponse(
138 std::move(certid), 0, std::nullopt, std::nullopt, std::move(this_update), std::move(next_update));
139}
140
141//static
143 return SingleResponse(
144 std::move(certid), 2, std::nullopt, std::nullopt, std::move(this_update), std::move(next_update));
145}
146
147//static
150 std::optional<CRL_Code> reason,
153 return SingleResponse(
154 std::move(certid), 1, std::move(revocation_time), reason, std::move(this_update), std::move(next_update));
155}
156
158 size_t cert_status,
159 std::optional<X509_Time> revocation_time,
160 std::optional<CRL_Code> revocation_reason,
161 X509_Time this_update,
162 X509_Time next_update) :
163 m_certid(std::move(certid)),
164 m_cert_status(cert_status),
165 m_thisupdate(std::move(this_update)),
166 m_nextupdate(std::move(next_update)),
167 m_revocation_time(std::move(revocation_time)),
168 m_revocation_reason(revocation_reason) {
169 const auto require_generalized_time = [](const X509_Time& t, const char* field) {
171 throw Invalid_Argument(fmt("OCSP SingleResponse {} must be a GeneralizedTime", field));
172 }
173 };
174
175 require_generalized_time(m_thisupdate, "thisUpdate");
176 if(m_nextupdate.time_is_set()) {
177 require_generalized_time(m_nextupdate, "nextUpdate");
178 }
179 if(m_cert_status == 1) {
180 if(!m_revocation_time.has_value()) {
181 throw Invalid_Argument("Revoked OCSP SingleResponse lacks a revocation time");
182 }
183 require_generalized_time(*m_revocation_time, "revocationTime");
184 }
185}
186
188 // The SingleResponse / CertStatus / RevokedInfo ASN.1 is quoted in
189 // decode_from below
190 to.start_sequence();
191 to.encode(m_certid);
192 if(m_cert_status == 1) {
193 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
194 to.start_cons(ASN1_Type(1), ASN1_Class::ContextSpecific).encode(m_revocation_time.value());
195 if(m_revocation_reason.has_value() && *m_revocation_reason != CRL_Code::Unspecified) {
196 to.start_explicit(0)
197 .encode(static_cast<size_t>(*m_revocation_reason), ASN1_Type::Enumerated, ASN1_Class::Universal)
198 .end_explicit();
199 }
200 to.end_cons();
201 } else {
202 // good [0] / unknown [2], both IMPLICIT NULL
203 const std::span<const uint8_t> empty;
204 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
205 to.add_object(ASN1_Type(m_cert_status), ASN1_Class::ContextSpecific, empty);
206 }
207 to.encode(m_thisupdate);
208 if(m_nextupdate.time_is_set()) {
209 to.start_explicit(0).encode(m_nextupdate).end_explicit();
210 }
211 to.end_cons();
212}
213
215 /*
216 * RFC 6960 Section 4.2.1
217 *
218 * SingleResponse ::= SEQUENCE {
219 * certID CertID,
220 * certStatus CertStatus,
221 * thisUpdate GeneralizedTime,
222 * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
223 * singleExtensions [1] EXPLICIT Extensions OPTIONAL }
224 *
225 * CertStatus ::= CHOICE {
226 * good [0] IMPLICIT NULL,
227 * revoked [1] IMPLICIT RevokedInfo,
228 * unknown [2] IMPLICIT UnknownInfo }
229 *
230 * RevokedInfo ::= SEQUENCE {
231 * revocationTime GeneralizedTime,
232 * revocationReason [0] EXPLICIT CRLReason OPTIONAL }
233 */
235 Extensions extensions;
236
237 auto seq = from.start_sequence();
238 seq.decode(m_certid)
240 .decode(m_thisupdate)
242
243 check_generalized_time(m_thisupdate, "thisUpdate");
244 if(m_nextupdate.time_is_set()) {
245 check_generalized_time(m_nextupdate, "nextUpdate");
246 }
247
248 if(seq.more_items()) {
249 const BER_Object next = seq.get_next_object();
251 BER_Decoder ext_decoder(next, BER_Decoder::Limits::DER());
252 extensions.decode_from(ext_decoder, Extension_Context::OCSP_Response);
253 ext_decoder.verify_end();
254 } else {
255 throw Decoding_Error("Unexpected tag in OCSP SingleResponse");
256 }
257 }
258 seq.end_cons();
259
260 const auto cert_status_class = cert_status.get_class();
261 if(cert_status_class != ASN1_Class::ContextSpecific &&
262 cert_status_class != (ASN1_Class::ContextSpecific | ASN1_Class::Constructed)) {
263 throw Decoding_Error("OCSP::SingleResponse: certStatus has unexpected class tag");
264 }
265
266 m_cert_status = static_cast<uint32_t>(cert_status.type());
267 if(m_cert_status > 2) {
268 throw Decoding_Error("Unknown OCSP CertStatus tag");
269 }
270
271 m_revocation_time.reset();
272 m_revocation_reason.reset();
273
274 if(m_cert_status == 1) {
277 revoked_info.decode(revocation_time);
278 check_generalized_time(revocation_time, "revocationTime");
279 m_revocation_time = std::move(revocation_time);
280
282 size_t reason = 0;
284 if(reason == 7 || reason > 10) {
285 throw Decoding_Error(fmt("CRLReason has unknown enumeration value {}", reason));
286 }
287 m_revocation_reason = static_cast<CRL_Code>(reason);
288 }
289 revoked_info.verify_end();
290 } else if(cert_status.length() != 0) {
291 // good [0] / unknown [2] are both IMPLICIT NULL
292 throw Decoding_Error("OCSP CertStatus has unexpected content");
293 }
294
295 // We don't currently recognize any extensions here so if any are critical we should reject
296 m_has_unknown_critical_ext = !extensions.critical_extensions().empty();
297}
298
299namespace {
300
301// TODO: should this be in a header somewhere?
302void decode_optional_list(BER_Decoder& ber, ASN1_Type tag, std::vector<X509_Certificate>& output) {
303 const BER_Object obj = ber.get_next_object();
304
306 ber.push_back(obj);
307 return;
308 }
309
311 auto seq = list.start_sequence();
312 while(seq.more_items()) {
313 output.push_back([&] {
314 X509_Certificate cert;
315 cert.decode_from(seq);
316 return cert;
317 }());
318 }
319 seq.end_cons();
320 list.verify_end();
321}
322
323} // namespace
324
325Request::Request(const X509_Certificate& issuer_cert, const X509_Certificate& subject_cert) :
326 m_issuer(issuer_cert), m_certid(m_issuer, subject_cert.serial()) {
327 if(subject_cert.issuer_dn() != issuer_cert.subject_dn()) {
328 throw Invalid_Argument("Invalid cert pair to OCSP::Request (mismatched issuer,subject args?)");
329 }
330}
331
332Request::Request(const X509_Certificate& issuer_cert, const BigInt& subject_serial) :
333 m_issuer(issuer_cert), m_certid(m_issuer, subject_serial) {}
334
335std::vector<uint8_t> Request::BER_encode() const {
336 /*
337 * RFC 6960 Section 4.1.1
338 *
339 * OCSPRequest ::= SEQUENCE {
340 * tbsRequest TBSRequest,
341 * optionalSignature [0] EXPLICIT Signature OPTIONAL }
342 *
343 * TBSRequest ::= SEQUENCE {
344 * version [0] EXPLICIT Version DEFAULT v1,
345 * requestList SEQUENCE OF Request }
346 *
347 * Request ::= SEQUENCE {
348 * reqCert CertID }
349 */
350 std::vector<uint8_t> output;
351 DER_Encoder(output)
355 .encode(static_cast<size_t>(0)) // version #
356 .end_explicit()
359 .encode(m_certid)
360 .end_cons()
361 .end_cons()
362 .end_cons()
363 .end_cons();
364
365 return output;
366}
367
368std::string Request::base64_encode() const {
370}
371
374
375Response::Response(const uint8_t response_bits[], size_t response_bits_len) :
376 m_response_bits(response_bits, response_bits + response_bits_len) {
377 /*
378 * RFC 6960 Section 4.2.1
379 *
380 * OCSPResponse ::= SEQUENCE {
381 * responseStatus OCSPResponseStatus,
382 * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
383 *
384 * OCSPResponseStatus ::= ENUMERATED { ... }
385 *
386 * ResponseBytes ::= SEQUENCE {
387 * responseType OBJECT IDENTIFIER,
388 * response OCTET STRING }
389 */
390 BER_Decoder outer_decoder(m_response_bits, BER_Decoder::Limits::DER());
391 BER_Decoder response_outer = outer_decoder.start_sequence();
392
393 size_t resp_status = 0;
394
395 response_outer.decode(resp_status, ASN1_Type::Enumerated, ASN1_Class::Universal);
396
397 /*
398 RFC 6960 4.2.1
399
400 OCSPResponseStatus ::= ENUMERATED {
401 successful (0), -- Response has valid confirmations
402 malformedRequest (1), -- Illegal confirmation request
403 internalError (2), -- Internal error in issuer
404 tryLater (3), -- Try again later
405 -- (4) is not used
406 sigRequired (5), -- Must sign the request
407 unauthorized (6) -- Request unauthorized
408 }
409 */
410 if(resp_status == 4 || resp_status >= 7) {
411 throw Decoding_Error("Unknown OCSPResponseStatus code");
412 }
413
414 m_status = static_cast<Response_Status_Code>(resp_status);
415
416 /*
417 * RFC 6960 4.2.1: "If the value of responseStatus is one of the error
418 * conditions, the responseBytes field is not set."
419 */
420 const bool successful = (m_status == Response_Status_Code::Successful);
421 const bool has_response_bytes = response_outer.more_items();
422
423 if(successful && !has_response_bytes) {
424 throw Decoding_Error("OCSP response with successful status is missing responseBytes");
425 }
426 if(!successful && has_response_bytes) {
427 throw Decoding_Error("OCSP response with non-successful status includes responseBytes");
428 }
429
430 if(successful) {
431 BER_Decoder response_bytes_ctx = response_outer.start_context_specific(0);
432 BER_Decoder response_bytes = response_bytes_ctx.start_sequence();
433
434 response_bytes.decode_and_check(OID::from_string("PKIX.OCSP.BasicResponse"),
435 "Unknown response type in OCSP response");
436
437 /*
438 * RFC 6960 Section 4.2.1
439 *
440 * BasicOCSPResponse ::= SEQUENCE {
441 * tbsResponseData ResponseData,
442 * signatureAlgorithm AlgorithmIdentifier,
443 * signature BIT STRING,
444 * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
445 */
446 BER_Decoder basic_response_decoder(response_bytes.get_next_octet_string(), BER_Decoder::Limits::DER());
447 BER_Decoder basicresponse = basic_response_decoder.start_sequence();
448
449 basicresponse.start_sequence()
450 .raw_bytes(m_tbs_bits)
451 .end_cons()
452 .decode(m_sig_algo)
453 .decode_octet_aligned_bitstring(m_signature);
454 decode_optional_list(basicresponse, ASN1_Type(0), m_certs);
455
456 basicresponse.verify_end();
457 basic_response_decoder.verify_end();
458
459 /*
460 * RFC 6960 Section 4.2.1
461 *
462 * ResponseData ::= SEQUENCE {
463 * version [0] EXPLICIT Version DEFAULT v1,
464 * responderID ResponderID,
465 * producedAt GeneralizedTime,
466 * responses SEQUENCE OF SingleResponse,
467 * responseExtensions [1] EXPLICIT Extensions OPTIONAL }
468 *
469 * ResponderID ::= CHOICE {
470 * byName [1] Name,
471 * byKey [2] KeyHash }
472 */
473 size_t responsedata_version = 0;
474 Extensions extensions;
475
476 BER_Decoder tbs_decoder(m_tbs_bits, BER_Decoder::Limits::DER());
477 tbs_decoder
479
481
484
485 .decode(m_produced_at)
486
487 .decode_list(m_responses);
488
489 check_generalized_time(m_produced_at, "producedAt");
490
491 if(tbs_decoder.more_items()) {
492 const BER_Object next = tbs_decoder.get_next_object();
494 BER_Decoder ext_decoder(next, BER_Decoder::Limits::DER());
495 extensions.decode_from(ext_decoder, Extension_Context::OCSP_Response);
496 ext_decoder.verify_end();
497 } else {
498 throw Decoding_Error("Unexpected tag in OCSP ResponseData");
499 }
500 }
501 tbs_decoder.verify_end();
502
503 const bool has_signer = !m_signer_name.empty();
504 const bool has_key_hash = !m_key_hash.empty();
505
506 if(has_signer && has_key_hash) {
507 throw Decoding_Error("OCSP response includes both byName and byKey in responderID field");
508 }
509 if(!has_signer && !has_key_hash) {
510 throw Decoding_Error("OCSP response contains neither byName nor byKey in responderID field");
511 }
512 if(has_key_hash && m_key_hash.size() != 20) {
513 // KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
514 throw Decoding_Error("OCSP response contains a byKey with invalid length");
515 }
516
517 response_bytes.verify_end();
518 response_bytes_ctx.verify_end();
519
520 // We don't currently recognize any extensions here so if any are critical we should reject
521 m_has_unknown_critical_ext = !extensions.critical_extensions().empty();
522 }
523
524 response_outer.verify_end();
525 outer_decoder.verify_end();
526
527 if(m_has_unknown_critical_ext == false) {
528 // Check all of the SingleResponse extensions
529 for(const auto& sr : m_responses) {
530 if(sr.has_unknown_critical_extension()) {
531 m_has_unknown_critical_ext = true;
532 break;
533 }
534 }
535 }
536}
537
538bool Response::is_issued_by(const X509_Certificate& candidate) const {
539 if(!m_signer_name.empty()) {
540 return (candidate.subject_dn() == m_signer_name);
541 }
542
543 if(!m_key_hash.empty()) {
544 return (candidate.subject_public_key_bitstring_sha1() == m_key_hash);
545 }
546
547 return false;
548}
549
551 const Path_Validation_Restrictions restrictions;
552
553 return this->verify_signature(issuer, restrictions);
554}
555
557 const Path_Validation_Restrictions& restrictions) const {
558 if(m_dummy_response_status) {
559 return m_dummy_response_status.value();
560 }
561
562 if(m_signer_name.empty() && m_key_hash.empty()) {
564 }
565
566 if(!is_issued_by(issuer)) {
568 }
569
570 try {
571 auto pub_key = issuer.subject_public_key();
572
573 PK_Verifier verifier(*pub_key, m_sig_algo);
574 verifier.update(ASN1::der_sequence_header(m_tbs_bits.size()));
575 verifier.update(m_tbs_bits);
576 const bool valid_signature = verifier.check_signature(m_signature);
577
578 if(valid_signature == false) {
580 }
581
582 if(m_has_unknown_critical_ext) {
584 }
585
586 const auto& trusted_hashes = restrictions.trusted_hashes();
587 if(!trusted_hashes.empty() && !trusted_hashes.contains(verifier.hash_function())) {
589 }
590
591 if(pub_key->estimated_strength() < restrictions.minimum_key_strength()) {
593 }
594
596 } catch(Exception&) {
598 }
599}
600
601std::optional<X509_Certificate> Response::find_signing_certificate(
602 const X509_Certificate& issuer_certificate, const Certificate_Store* trusted_ocsp_responders) const {
603 using namespace std::placeholders;
604
605 // Check whether the CA issuing the certificate in question also signed this
606 if(is_issued_by(issuer_certificate)) {
607 return issuer_certificate;
608 }
609
610 // Then try to find a delegated responder certificate in the stapled certs
611 for(const auto& cert : m_certs) {
612 if(this->is_issued_by(cert)) {
613 return cert;
614 }
615 }
616
617 // Last resort: check the additionally provides trusted OCSP responders
618 if(trusted_ocsp_responders != nullptr) {
619 if(!m_key_hash.empty()) {
620 auto signing_cert = trusted_ocsp_responders->find_cert_by_pubkey_sha1(m_key_hash);
621 if(signing_cert) {
622 return signing_cert;
623 }
624 }
625
626 if(!m_signer_name.empty()) {
627 auto signing_cert = trusted_ocsp_responders->find_cert(m_signer_name, {});
628 if(signing_cert) {
629 return signing_cert;
630 }
631 }
632 }
633
634 return std::nullopt;
635}
636
638 const X509_Certificate& subject,
639 std::chrono::system_clock::time_point ref_time,
640 std::chrono::seconds max_age) const {
641 if(m_dummy_response_status) {
642 return m_dummy_response_status.value();
643 }
644
645 for(const auto& response : m_responses) {
646 if(response.certid().is_id_for(issuer, subject)) {
647 const X509_Time x509_ref_time(ref_time);
648
649 /*
650 * We check certificate status prior to checking expiration, since otherwise it's
651 * possible to take an OCSP response indicating revocation, wait for it to expire,
652 * and then staple it. If such a response was reported as "expired" rather than
653 * "revoked" it's easy to dismiss as a clock issue or other misconfiguration.
654 */
655
656 if(response.cert_status() == 1) {
658 }
659
660 try {
661 if(response.this_update() > x509_ref_time) {
663 }
664
665 if(response.next_update().time_is_set()) {
666 if(x509_ref_time > response.next_update()) {
668 }
669 } else if(max_age > std::chrono::seconds::zero() &&
670 ref_time - response.this_update().to_std_timepoint() > max_age) {
672 }
673 } catch(Exception&) {
674 // This can occur if eg the OCSP time is not representable by the system clock
676 }
677
678 if(response.cert_status() == 0) {
680 } else {
682 }
683 }
684 }
685
687}
688
689#if defined(BOTAN_HAS_HTTP_UTIL)
690
691Response online_check(const X509_Certificate& issuer,
692 const BigInt& subject_serial,
693 std::string_view ocsp_responder,
694 std::chrono::milliseconds timeout) {
695 if(ocsp_responder.empty()) {
696 throw Invalid_Argument("No OCSP responder specified");
697 }
698
699 if(auto uri = URI::from_string(ocsp_responder)) {
700 return online_check(issuer, subject_serial, *uri, timeout);
701 } else {
702 throw Invalid_Argument("Unparsable URI for OCSP responder");
703 }
704}
705
706Response online_check(const X509_Certificate& issuer,
707 const BigInt& subject_serial,
708 const URI& ocsp_responder,
709 std::chrono::milliseconds timeout) {
710 const OCSP::Request req(issuer, subject_serial);
711
712 auto http = HTTP::POST_sync(ocsp_responder,
713 "application/ocsp-request",
714 req.BER_encode(),
715 HTTP::RequestLimits().set_timeout(timeout).set_max_body_size(64 * 1024));
716
717 http.throw_unless_ok();
718
719 // Check the MIME type?
720
721 return OCSP::Response(http.body());
722}
723
724Response online_check(const X509_Certificate& issuer,
725 const X509_Certificate& subject,
726 std::chrono::milliseconds timeout) {
727 if(subject.issuer_dn() != issuer.subject_dn()) {
728 throw Invalid_Argument("Invalid cert pair to OCSP::online_check (mismatched issuer,subject args?)");
729 }
730
731 const auto responders = URI::filter_scheme("http", subject.ocsp_responder_uris());
732
733 if(responders.empty()) {
734 throw Invalid_Argument("No HTTP OCSP responder URLs available for this certificate");
735 }
736
737 const auto subject_serial = subject.serial().to_bigint();
738
739 // Try the first N - 1 responder addresses in sequence, ignoring errors
740 for(size_t i = 0; i + 1 < responders.size(); ++i) {
741 try {
742 return online_check(issuer, subject_serial, responders[i], timeout);
743 } catch(...) {}
744 }
745
746 // Now try the final responder and let any errors propagate
747 return online_check(issuer, subject_serial, responders.back(), timeout);
748}
749
750#endif
751
752} // namespace Botan::OCSP
ASN1_Type tagging() const
Return the tag (UtcTime or GeneralizedTime) this time was encoded with.
Definition asn1_time.h:36
bool time_is_set() const
Return if the time has been set somehow.
static Limits DER()
Definition ber_dec.h:42
const BER_Object & peek_next_object()
Definition ber_dec.cpp:505
void push_back(const BER_Object &obj)
Definition ber_dec.cpp:600
BER_Object get_next_object()
Definition ber_dec.cpp:516
BER_Decoder & decode(bool &out)
Definition ber_dec.h:358
bool more_items() const
Definition ber_dec.cpp:461
BER_Decoder & raw_bytes(std::vector< uint8_t, Alloc > &out)
Definition ber_dec.h:338
std::vector< uint8_t > get_next_octet_string()
Definition ber_dec.h:373
BER_Decoder & verify_end()
Definition ber_dec.cpp:471
BER_Decoder & end_cons()
Definition ber_dec.cpp:630
BER_Decoder start_sequence()
Definition ber_dec.h:275
BER_Decoder start_context_specific(uint32_t tag)
Definition ber_dec.h:290
BER_Decoder & decode_optional(T &out, ASN1_Type type_tag, ASN1_Class class_tag, const T &default_value=T())
Definition ber_dec.h:553
BER_Decoder & decode_and_check(const T &expected, std::string_view error_msg)
Definition ber_dec.h:701
BER_Decoder & decode_optional_string(std::vector< uint8_t, Alloc > &out, ASN1_Type real_type, uint32_t expected_tag, ASN1_Class class_tag=ASN1_Class::ContextSpecific)
Definition ber_dec.h:721
BER_Decoder & get_next(BER_Object &ber)
Definition ber_dec.h:210
BER_Decoder & decode_list(std::vector< T > &vec, ASN1_Type type_tag=ASN1_Type::Sequence, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.h:880
BER_Decoder & decode_octet_aligned_bitstring(std::vector< uint8_t, Alloc > &out, ASN1_Type type_tag=ASN1_Type::BitString, ASN1_Class class_tag=ASN1_Class::Universal)
Definition ber_dec.h:462
bool is_a(ASN1_Type type_tag, ASN1_Class class_tag) const
Definition asn1_obj.cpp:97
virtual std::optional< X509_Certificate > find_cert_by_pubkey_sha1(const std::vector< uint8_t > &key_hash) const =0
virtual std::optional< X509_Certificate > find_cert(const X509_DN &subject_dn, const std::vector< uint8_t > &key_id) const
Definition certstor.cpp:38
DER_Encoder & add_object(ASN1_Type type_tag, ASN1_Class class_tag, const uint8_t rep[], size_t length)
Definition der_enc.cpp:285
DER_Encoder & end_explicit()
Definition der_enc.cpp:230
DER_Encoder & start_explicit(uint16_t type_tag)
Definition der_enc.cpp:223
DER_Encoder & start_sequence()
Definition der_enc.h:86
DER_Encoder & start_cons(ASN1_Type type_tag, ASN1_Class class_tag)
Definition der_enc.cpp:192
DER_Encoder & end_cons()
Definition der_enc.cpp:208
DER_Encoder & encode(bool b)
Definition der_enc.cpp:313
std::vector< OID > critical_extensions() const
Definition x509_ext.cpp:128
void decode_from(BER_Decoder &from) override
Definition x509_ext.cpp:322
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:308
void decode_from(BER_Decoder &from) override
Definition ocsp.cpp:113
void encode_into(DER_Encoder &to) const override
Definition ocsp.cpp:104
bool is_id_for(const X509_Certificate &issuer, const X509_Certificate &subject) const
Definition ocsp.cpp:60
std::string base64_encode() const
Definition ocsp.cpp:368
Request(const X509_Certificate &issuer_cert, const X509_Certificate &subject_cert)
Definition ocsp.cpp:325
std::vector< uint8_t > BER_encode() const
Definition ocsp.cpp:335
BOTAN_FUTURE_EXPLICIT Response(Certificate_Status_Code status)
Definition ocsp.cpp:372
Certificate_Status_Code status_for(const X509_Certificate &issuer, const X509_Certificate &subject, std::chrono::system_clock::time_point ref_time=std::chrono::system_clock::now(), std::chrono::seconds max_age=std::chrono::seconds::zero()) const
Definition ocsp.cpp:637
Response_Status_Code status() const
Definition ocsp.h:240
std::optional< X509_Certificate > find_signing_certificate(const X509_Certificate &issuer_certificate, const Certificate_Store *trusted_ocsp_responders=nullptr) const
Definition ocsp.cpp:601
Certificate_Status_Code verify_signature(const X509_Certificate &signing_certificate) const
Definition ocsp.cpp:550
const std::optional< X509_Time > & revocation_time() const
The revocationTime; set only when cert_status() is 1 (revoked).
Definition ocsp.h:81
const CertID & certid() const
Definition ocsp.h:72
static SingleResponse unknown(CertID certid, X509_Time this_update, X509_Time next_update)
As good(), but asserting an unknown status.
Definition ocsp.cpp:142
const X509_Time & next_update() const
Definition ocsp.h:78
static SingleResponse revoked(CertID certid, X509_Time revocation_time, std::optional< CRL_Code > reason, X509_Time this_update, X509_Time next_update)
As good(), but asserting a revoked status with the given RevokedInfo.
Definition ocsp.cpp:148
static SingleResponse good(CertID certid, X509_Time this_update, X509_Time next_update)
Definition ocsp.cpp:136
void decode_from(BER_Decoder &from) override
Definition ocsp.cpp:214
const X509_Time & this_update() const
Definition ocsp.h:76
size_t cert_status() const
Definition ocsp.h:74
void encode_into(DER_Encoder &to) const override
Definition ocsp.cpp:187
static OID from_string(std::string_view str)
Definition asn1_oid.cpp:80
void update(uint8_t in)
Definition pubkey.h:339
std::string hash_function() const
Definition pubkey.cpp:404
bool check_signature(const uint8_t sig[], size_t length)
Definition pubkey.cpp:455
const std::set< std::string > & trusted_hashes() const
Definition x509path.h:132
static std::optional< URI > from_string(std::string_view raw)
Definition uri.cpp:164
static std::vector< URI > filter_scheme(std::string_view scheme, std::span< const URI > uris)
Definition uri.cpp:367
const X509_DN & subject_dn() const
Definition x509cert.cpp:460
const X509_Serial_Number & serial() const
Definition x509cert.cpp:444
const std::vector< uint8_t > & raw_subject_dn() const
Definition x509cert.cpp:468
std::span< const uint8_t, 32 > subject_public_key_bitstring_sha256() const
Definition x509cert.cpp:428
const std::vector< uint8_t > & subject_public_key_bitstring_sha1() const
Definition x509cert.cpp:420
const X509_DN & issuer_dn() const
Definition x509cert.cpp:456
const std::vector< uint8_t > & raw_issuer_dn_sha256() const
Definition x509cert.cpp:770
const std::vector< uint8_t > & subject_public_key_bitstring() const
Definition x509cert.cpp:416
std::unique_ptr< Public_Key > subject_public_key() const
Definition x509cert.cpp:758
std::span< const uint8_t, 20 > raw_issuer_dn_sha1() const
Definition x509cert.cpp:784
bool empty() const
Definition pkix_types.h:202
void decode_from(BER_Decoder &from) override
Definition x509_obj.cpp:93
std::vector< uint8_t > der_sequence_header(size_t contents_len)
Definition der_enc.cpp:71
Response POST_sync(const URI &uri, std::string_view content_type, const std::vector< uint8_t > &body, const RequestLimits &limits)
Response_Status_Code
Definition ocsp.h:158
ASN1_Time X509_Time
Definition asn1_obj.h:27
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
ASN1_Type
Definition asn1_obj.h:47
Certificate_Status_Code
Definition pkix_enums.h:21
size_t base64_encode(char out[], const uint8_t in[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition base64.cpp:161