Botan  2.4.0
Crypto and TLS for C++11
Public Member Functions | List of all members
Botan::OCSP::Response Class Referencefinal

#include <ocsp.h>

Public Member Functions

const std::vector< X509_Certificate > & certificates () const
 
Certificate_Status_Code check_signature (const std::vector< Certificate_Store *> &trust_roots, const std::vector< std::shared_ptr< const X509_Certificate >> &cert_path={}) const
 
const X509_Timeproduced_at () const
 
const std::vector< uint8_t > & raw_bits () const
 
 Response ()=default
 
 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
 
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()) const
 
Certificate_Status_Code verify_signature (const X509_Certificate &issuer) const
 

Detailed Description

OCSP response.

Note this class is only usable as an OCSP client

Definition at line 71 of file ocsp.h.

Constructor & Destructor Documentation

◆ Response() [1/3]

Botan::OCSP::Response::Response ( )
default

Creates an empty OCSP response.

◆ 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 83 of file ocsp.h.

83  :
84  Response(response_bits.data(), response_bits.size())
85  {}

◆ 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 90 of file ocsp.cpp.

References Botan::BIT_STRING, Botan::CONSTRUCTED, Botan::CONTEXT_SPECIFIC, 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::BER_Decoder::end_cons(), Botan::ENUMERATED, Botan::BER_Decoder::get_next_octet_string(), Botan::BER_Decoder::more_items(), Botan::OCTET_STRING, Botan::BER_Decoder::raw_bytes(), Botan::SEQUENCE, Botan::BER_Decoder::start_cons(), Botan::ASN1::to_string(), and Botan::UNIVERSAL.

90  :
91  m_response_bits(response_bits, response_bits + response_bits_len)
92  {
93  BER_Decoder response_outer = BER_Decoder(m_response_bits).start_cons(SEQUENCE);
94 
95  size_t resp_status = 0;
96 
97  response_outer.decode(resp_status, ENUMERATED, UNIVERSAL);
98 
99  if(resp_status != 0)
100  throw Exception("OCSP response status " + std::to_string(resp_status));
101 
102  if(response_outer.more_items())
103  {
104  BER_Decoder response_bytes =
105  response_outer.start_cons(ASN1_Tag(0), CONTEXT_SPECIFIC).start_cons(SEQUENCE);
106 
107  response_bytes.decode_and_check(OID("1.3.6.1.5.5.7.48.1.1"),
108  "Unknown response type in OCSP response");
109 
110  BER_Decoder basicresponse =
111  BER_Decoder(response_bytes.get_next_octet_string()).start_cons(SEQUENCE);
112 
113  basicresponse.start_cons(SEQUENCE)
114  .raw_bytes(m_tbs_bits)
115  .end_cons()
116  .decode(m_sig_algo)
117  .decode(m_signature, BIT_STRING);
118  decode_optional_list(basicresponse, ASN1_Tag(0), m_certs);
119 
120  size_t responsedata_version = 0;
121  Extensions extensions;
122 
123  BER_Decoder(m_tbs_bits)
124  .decode_optional(responsedata_version, ASN1_Tag(0),
126 
127  .decode_optional(m_signer_name, ASN1_Tag(1),
129 
130  .decode_optional_string(m_key_hash, OCTET_STRING, 2,
132 
133  .decode(m_produced_at)
134 
135  .decode_list(m_responses)
136 
137  .decode_optional(extensions, ASN1_Tag(1),
139  }
140 
141  response_outer.end_cons();
142  }
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:108
ASN1_Tag
Definition: asn1_obj.h:22

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 151 of file ocsp.h.

References BOTAN_PUBLIC_API.

151 { return m_certs; }

◆ check_signature()

Certificate_Status_Code Botan::OCSP::Response::check_signature ( const std::vector< Certificate_Store *> &  trust_roots,
const std::vector< std::shared_ptr< const X509_Certificate >> &  cert_path = {} 
) const

Check signature and return status The optional cert_path is the (already validated!) certificate path of the end entity which is being inquired about

Parameters
trust_rootslist of certstores containing trusted roots
cert_pathoptionally, the (already verified!) certificate path for the certificate this is an OCSP response for. This is necessary to find the correct intermediate CA in some cases.

Definition at line 172 of file ocsp.cpp.

References Botan::CRL_SIGN, Botan::X509_DN::empty(), Botan::OCSP_ISSUER_NOT_FOUND, Botan::OCSP_RESPONSE_INVALID, Botan::OCSP_RESPONSE_MISSING_KEYUSAGE, and verify_signature().

Referenced by status_for().

174  {
175  std::shared_ptr<const X509_Certificate> signing_cert;
176 
177  for(size_t i = 0; i != trusted_roots.size(); ++i)
178  {
179  if(m_signer_name.empty() && m_key_hash.empty())
181 
182  if(!m_signer_name.empty())
183  {
184  signing_cert = trusted_roots[i]->find_cert(m_signer_name, std::vector<uint8_t>());
185  if(signing_cert)
186  {
187  break;
188  }
189  }
190 
191  if(m_key_hash.size() > 0)
192  {
193  signing_cert = trusted_roots[i]->find_cert_by_pubkey_sha1(m_key_hash);
194  if(signing_cert)
195  {
196  break;
197  }
198  }
199  }
200 
201  if(!signing_cert && ee_cert_path.size() > 1)
202  {
203  // End entity cert is not allowed to sign their own OCSP request :)
204  for(size_t i = 1; i < ee_cert_path.size(); ++i)
205  {
206  // Check all CA certificates in the (assumed validated) EE cert path
207  if(!m_signer_name.empty() && ee_cert_path[i]->subject_dn() == m_signer_name)
208  {
209  signing_cert = ee_cert_path[i];
210  break;
211  }
212 
213  if(m_key_hash.size() > 0 && ee_cert_path[i]->subject_public_key_bitstring_sha1() == m_key_hash)
214  {
215  signing_cert = ee_cert_path[i];
216  break;
217  }
218  }
219  }
220 
221  if(!signing_cert && m_certs.size() > 0)
222  {
223  for(size_t i = 0; i < m_certs.size(); ++i)
224  {
225  // Check all CA certificates in the (assumed validated) EE cert path
226  if(!m_signer_name.empty() && m_certs[i].subject_dn() == m_signer_name)
227  {
228  signing_cert = std::make_shared<const X509_Certificate>(m_certs[i]);
229  break;
230  }
231 
232  if(m_key_hash.size() > 0 && m_certs[i].subject_public_key_bitstring_sha1() == m_key_hash)
233  {
234  signing_cert = std::make_shared<const X509_Certificate>(m_certs[i]);
235  break;
236  }
237  }
238  }
239 
240  if(!signing_cert)
242 
243  if(!signing_cert->allowed_usage(CRL_SIGN) &&
244  !signing_cert->allowed_extended_usage("PKIX.OCSPSigning"))
245  {
247  }
248 
249  return this->verify_signature(*signing_cert);
250  }
bool empty() const
Definition: x509_dn.h:56
Certificate_Status_Code verify_signature(const X509_Certificate &issuer) const
Definition: ocsp.cpp:144

◆ 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 117 of file ocsp.h.

117 { return m_produced_at; }

◆ raw_bits()

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

Definition at line 129 of file ocsp.h.

129 { 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 127 of file ocsp.h.

127 { 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 122 of file ocsp.h.

122 { return m_signer_name; }

◆ 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() 
) const

Searches the OCSP response for issuer and subject certificate.

Parameters
issuerissuer certificate
subjectsubject certificate
ref_timethe reference time
Returns
OCSP status code, possible values: CERT_IS_REVOKED, OCSP_NOT_YET_VALID, OCSP_HAS_EXPIRED, OCSP_RESPONSE_GOOD, OCSP_BAD_STATUS, OCSP_CERT_NOT_LISTED

Definition at line 252 of file ocsp.cpp.

References Botan::OCSP::Request::BER_encode(), Botan::CERT_IS_REVOKED, check_signature(), Botan::BigInt::decode(), Botan::X509_Certificate::issuer_dn(), Botan::OCSP_BAD_STATUS, Botan::OCSP_CERT_NOT_LISTED, Botan::OCSP_HAS_EXPIRED, Botan::OCSP_NOT_YET_VALID, Botan::X509_Certificate::ocsp_responder(), Botan::OCSP_RESPONSE_GOOD, Botan::HTTP::POST_sync(), Botan::X509_Certificate::serial_number(), Botan::X509_Certificate::subject_dn(), and Botan::HTTP::Response::throw_unless_ok().

255  {
256  for(const auto& response : m_responses)
257  {
258  if(response.certid().is_id_for(issuer, subject))
259  {
260  X509_Time x509_ref_time(ref_time);
261 
262  if(response.cert_status() == 1)
264 
265  if(response.this_update() > x509_ref_time)
267 
268  if(response.next_update().time_is_set() && x509_ref_time > response.next_update())
270 
271  if(response.cert_status() == 0)
273  else
275  }
276  }
277 
279  }

◆ verify_signature()

Certificate_Status_Code Botan::OCSP::Response::verify_signature ( const X509_Certificate issuer) const

Verify that issuer's key signed this response

Parameters
issuercertificate of issuer
Returns
if signature valid OCSP_SIGNATURE_OK else an error code

Definition at line 144 of file ocsp.cpp.

References Botan::DER_SEQUENCE, Botan::AlgorithmIdentifier::get_oid(), Botan::IEEE_1363, Botan::OIDS::lookup(), Botan::OCSP_RESPONSE_INVALID, Botan::OCSP_SIGNATURE_ERROR, Botan::OCSP_SIGNATURE_OK, Botan::ASN1::put_in_sequence(), Botan::split_on(), Botan::X509_Certificate::subject_public_key(), and Botan::PK_Verifier::verify_message().

Referenced by check_signature().

145  {
146  try
147  {
148  std::unique_ptr<Public_Key> pub_key(issuer.subject_public_key());
149 
150  const std::vector<std::string> sig_info =
151  split_on(OIDS::lookup(m_sig_algo.get_oid()), '/');
152 
153  if(sig_info.size() != 2 || sig_info[0] != pub_key->algo_name())
155 
156  std::string padding = sig_info[1];
157  Signature_Format format = (pub_key->message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363;
158 
159  PK_Verifier verifier(*pub_key, padding, format);
160 
161  if(verifier.verify_message(ASN1::put_in_sequence(m_tbs_bits), m_signature))
163  else
165  }
166  catch(Exception&)
167  {
169  }
170  }
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:142
Signature_Format
Definition: pubkey.h:27
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition: asn1_obj.cpp:96
const OID & get_oid() const
Definition: alg_id.h:37
std::string lookup(const OID &oid)
Definition: oids.cpp:18

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