Botan 3.6.1
Crypto and TLS for C&
Botan::OCSP::Response Class Referencefinal

#include <ocsp.h>

Public Member Functions

const std::vector< X509_Certificate > & certificates () const
 
std::optional< Certificate_Status_Codedummy_status () const
 
std::optional< X509_Certificatefind_signing_certificate (const X509_Certificate &issuer_certificate, const Certificate_Store *trusted_ocsp_responders=nullptr) const
 
const X509_Timeproduced_at () const
 
const std::vector< uint8_t > & raw_bits () const
 
 Response (Certificate_Status_Code status)
 
 Response (const std::vector< uint8_t > &response_bits)
 
 Response (const uint8_t response_bits[], size_t response_bits_len)
 
const std::vector< uint8_t > & signer_key_hash () const
 
const X509_DNsigner_name () const
 
Response_Status_Code status () const
 
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
 
Certificate_Status_Code verify_signature (const X509_Certificate &signing_certificate) const
 

Detailed Description

OCSP response.

Note this class is only usable as an OCSP client

Definition at line 127 of file ocsp.h.

Constructor & Destructor Documentation

◆ Response() [1/3]

Botan::OCSP::Response::Response ( Certificate_Status_Code status)

Create a fake OCSP response from a given status code.

Parameters
statusthe status code the check functions will return

Definition at line 81 of file ocsp.cpp.

81 :
82 m_status(Response_Status_Code::Successful), m_dummy_response_status(status) {}
Response_Status_Code status() const
Definition ocsp.h:177

◆ Response() [2/3]

Botan::OCSP::Response::Response ( const std::vector< uint8_t > & response_bits)
inline

Parses an OCSP response.

Parameters
response_bitsresponse bits received

Definition at line 139 of file ocsp.h.

139: Response(response_bits.data(), response_bits.size()) {}
Response(Certificate_Status_Code status)
Definition ocsp.cpp:81

◆ Response() [3/3]

Botan::OCSP::Response::Response ( const uint8_t response_bits[],
size_t response_bits_len )

Parses an OCSP response.

Parameters
response_bitsresponse bits received
response_bits_lenlength of response in bytes

Definition at line 84 of file ocsp.cpp.

84 :
85 m_response_bits(response_bits, response_bits + response_bits_len) {
86 BER_Decoder response_outer = BER_Decoder(m_response_bits).start_sequence();
87
88 size_t resp_status = 0;
89
90 response_outer.decode(resp_status, ASN1_Type::Enumerated, ASN1_Class::Universal);
91
92 m_status = static_cast<Response_Status_Code>(resp_status);
93
94 if(m_status != Response_Status_Code::Successful) {
95 return;
96 }
97
98 if(response_outer.more_items()) {
99 BER_Decoder response_bytes = response_outer.start_context_specific(0).start_sequence();
100
101 response_bytes.decode_and_check(OID("1.3.6.1.5.5.7.48.1.1"), "Unknown response type in OCSP response");
102
103 BER_Decoder basicresponse = BER_Decoder(response_bytes.get_next_octet_string()).start_sequence();
104
105 basicresponse.start_sequence()
106 .raw_bytes(m_tbs_bits)
107 .end_cons()
108 .decode(m_sig_algo)
109 .decode(m_signature, ASN1_Type::BitString);
110 decode_optional_list(basicresponse, ASN1_Type(0), m_certs);
111
112 size_t responsedata_version = 0;
113 Extensions extensions;
114
115 BER_Decoder(m_tbs_bits)
116 .decode_optional(responsedata_version, ASN1_Type(0), ASN1_Class::ContextSpecific | ASN1_Class::Constructed)
117
118 .decode_optional(m_signer_name, ASN1_Type(1), ASN1_Class::ContextSpecific | ASN1_Class::Constructed)
119
120 .decode_optional_string(
122
123 .decode(m_produced_at)
124
125 .decode_list(m_responses)
126
127 .decode_optional(extensions, ASN1_Type(1), ASN1_Class::ContextSpecific | ASN1_Class::Constructed);
128
129 const bool has_signer = !m_signer_name.empty();
130 const bool has_key_hash = !m_key_hash.empty();
131
132 if(has_signer && has_key_hash) {
133 throw Decoding_Error("OCSP response includes both byName and byKey in responderID field");
134 }
135 if(!has_signer && !has_key_hash) {
136 throw Decoding_Error("OCSP response contains neither byName nor byKey in responderID field");
137 }
138 }
139
140 response_outer.end_cons();
141}
bool empty() const
Definition pkix_types.h:67
Response_Status_Code
Definition ocsp.h:113
ASN1_Type
Definition asn1_obj.h:44

References Botan::BitString, Botan::Constructed, Botan::ContextSpecific, Botan::BER_Decoder::decode(), Botan::BER_Decoder::decode_and_check(), Botan::BER_Decoder::decode_list(), Botan::BER_Decoder::decode_optional(), Botan::BER_Decoder::decode_optional_string(), Botan::X509_DN::empty(), Botan::BER_Decoder::end_cons(), Botan::Enumerated, Botan::BER_Decoder::get_next_octet_string(), Botan::BER_Decoder::more_items(), Botan::OctetString, Botan::BER_Decoder::raw_bytes(), Botan::BER_Decoder::start_context_specific(), Botan::BER_Decoder::start_sequence(), Botan::OCSP::Successful, and Botan::Universal.

Member Function Documentation

◆ certificates()

const std::vector< X509_Certificate > & Botan::OCSP::Response::certificates ( ) const
inline
Returns
the certificate chain, if provided in response

Definition at line 221 of file ocsp.h.

221{ return m_certs; }

◆ dummy_status()

std::optional< Certificate_Status_Code > Botan::OCSP::Response::dummy_status ( ) const
inline
Returns
the dummy response if this is a 'fake' OCSP response otherwise std::nullopt

Definition at line 226 of file ocsp.h.

226{ return m_dummy_response_status; }

◆ find_signing_certificate()

std::optional< X509_Certificate > Botan::OCSP::Response::find_signing_certificate ( const X509_Certificate & issuer_certificate,
const Certificate_Store * trusted_ocsp_responders = nullptr ) const

Find the certificate that signed this OCSP response from all possible candidates and taking the attached certificates into account.

Parameters
issuer_certificateis the issuer of the certificate in question
trusted_ocsp_respondersoptionally, a certificate store containing additionally trusted responder certificates
Returns
the certificate that signed this response or std::nullopt if not found

Definition at line 183 of file ocsp.cpp.

184 {
185 using namespace std::placeholders;
186
187 // Check whether the CA issuing the certificate in question also signed this
188 if(is_issued_by(issuer_certificate)) {
189 return issuer_certificate;
190 }
191
192 // Then try to find a delegated responder certificate in the stapled certs
193 auto match = std::find_if(m_certs.begin(), m_certs.end(), std::bind(&Response::is_issued_by, this, _1));
194 if(match != m_certs.end()) {
195 return *match;
196 }
197
198 // Last resort: check the additionally provides trusted OCSP responders
199 if(trusted_ocsp_responders) {
200 if(!m_key_hash.empty()) {
201 auto signing_cert = trusted_ocsp_responders->find_cert_by_pubkey_sha1(m_key_hash);
202 if(signing_cert) {
203 return signing_cert;
204 }
205 }
206
207 if(!m_signer_name.empty()) {
208 auto signing_cert = trusted_ocsp_responders->find_cert(m_signer_name, {});
209 if(signing_cert) {
210 return signing_cert;
211 }
212 }
213 }
214
215 return std::nullopt;
216}

References Botan::X509_DN::empty(), Botan::Certificate_Store::find_cert(), and Botan::Certificate_Store::find_cert_by_pubkey_sha1().

◆ produced_at()

const X509_Time & Botan::OCSP::Response::produced_at ( ) const
inline
Returns
the time this OCSP response was supposedly produced at

Definition at line 182 of file ocsp.h.

182{ return m_produced_at; }

◆ raw_bits()

const std::vector< uint8_t > & Botan::OCSP::Response::raw_bits ( ) const
inline

Definition at line 194 of file ocsp.h.

194{ return m_response_bits; }

◆ signer_key_hash()

const std::vector< uint8_t > & Botan::OCSP::Response::signer_key_hash ( ) const
inline
Returns
key hash, if provided in response (may be empty)

Definition at line 192 of file ocsp.h.

192{ return m_key_hash; }

◆ signer_name()

const X509_DN & Botan::OCSP::Response::signer_name ( ) const
inline
Returns
DN of signer, if provided in response (may be empty)

Definition at line 187 of file ocsp.h.

187{ return m_signer_name; }

◆ status()

Response_Status_Code Botan::OCSP::Response::status ( ) const
inline
Returns
the status of the response

Definition at line 177 of file ocsp.h.

177{ return m_status; }

◆ status_for()

Certificate_Status_Code Botan::OCSP::Response::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

Searches the OCSP response for issuer and subject certificate.

Parameters
issuerissuer certificate
subjectsubject certificate
ref_timethe reference time
max_agethe maximum age the response should be considered valid if next_update is not set
Returns
OCSP status code, possible values: CERT_IS_REVOKED, OCSP_NOT_YET_VALID, OCSP_HAS_EXPIRED, OCSP_IS_TOO_OLD, OCSP_RESPONSE_GOOD, OCSP_BAD_STATUS, OCSP_CERT_NOT_LISTED

Definition at line 218 of file ocsp.cpp.

221 {
222 if(m_dummy_response_status) {
223 return m_dummy_response_status.value();
224 }
225
226 for(const auto& response : m_responses) {
227 if(response.certid().is_id_for(issuer, subject)) {
228 X509_Time x509_ref_time(ref_time);
229
230 if(response.cert_status() == 1) {
232 }
233
234 if(response.this_update() > x509_ref_time) {
236 }
237
238 if(response.next_update().time_is_set()) {
239 if(x509_ref_time > response.next_update()) {
241 }
242 } else if(max_age > std::chrono::seconds::zero() &&
243 ref_time - response.this_update().to_std_timepoint() > max_age) {
245 }
246
247 if(response.cert_status() == 0) {
249 } else {
251 }
252 }
253 }
254
256}
ASN1_Time X509_Time
Definition asn1_obj.h:409

References Botan::CERT_IS_REVOKED, Botan::OCSP_BAD_STATUS, Botan::OCSP_CERT_NOT_LISTED, Botan::OCSP_HAS_EXPIRED, Botan::OCSP_IS_TOO_OLD, Botan::OCSP_NOT_YET_VALID, and Botan::OCSP_RESPONSE_GOOD.

◆ verify_signature()

Certificate_Status_Code Botan::OCSP::Response::verify_signature ( const X509_Certificate & signing_certificate) const

Check signature of the OCSP response.

Note: It is the responsibility of the caller to verify that signing certificate is trustworthy and authorized to do so.

Parameters
signing_certificatethe certificate that signed this response (
See also
Response::find_signing_certificate).
Returns
status code indicating the validity of the signature

Definition at line 155 of file ocsp.cpp.

155 {
156 if(m_dummy_response_status) {
157 return m_dummy_response_status.value();
158 }
159
160 if(m_signer_name.empty() && m_key_hash.empty()) {
162 }
163
164 if(!is_issued_by(issuer)) {
166 }
167
168 try {
169 auto pub_key = issuer.subject_public_key();
170
171 PK_Verifier verifier(*pub_key, m_sig_algo);
172
173 if(verifier.verify_message(ASN1::put_in_sequence(m_tbs_bits), m_signature)) {
175 } else {
177 }
178 } catch(Exception&) {
180 }
181}
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition asn1_obj.cpp:172

References Botan::X509_DN::empty(), Botan::OCSP_ISSUER_NOT_FOUND, Botan::OCSP_RESPONSE_INVALID, Botan::OCSP_SIGNATURE_ERROR, Botan::OCSP_SIGNATURE_OK, Botan::ASN1::put_in_sequence(), Botan::X509_Certificate::subject_public_key(), and Botan::PK_Verifier::verify_message().


The documentation for this class was generated from the following files: