Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- Class List
- Class Index
- Class Hierarchy
- Class Members

Public Member Functions | List of all members
Botan::OCSP::Response Class Reference

`#include <ocsp.h>`

## Public Member Functions
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_Time & | produced_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_DN & | signer_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 69 of file ocsp.h.

## Constructor & Destructor Documentation

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

Creates an empty OCSP response.

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

Parses an OCSP response.

Parameters

  response_bits | response bits received

Definition at line 81 of file ocsp.h.

81 :
82 Response(response_bits.data(), response_bits.size())
83 {}
Botan::OCSP::Response::Response
Response()=default

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

Parses an OCSP response.

Parameters

  response_bits | response bits received
  response_bits_len | length 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),
125 ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
126
127 .decode_optional(m_signer_name, ASN1_Tag(1),
128 ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
129
130 .decode_optional_string(m_key_hash, OCTET_STRING, 2,
131 ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC))
132
133 .decode(m_produced_at)
134
135 .decode_list(m_responses)
136
137 .decode_optional(extensions, ASN1_Tag(1),
138 ASN1_Tag(CONSTRUCTED | CONTEXT_SPECIFIC));
139 }
140
141 response_outer.end_cons();
142 }
Botan::CONTEXT_SPECIFIC
Definition: asn1_obj.h:25
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
Botan::ENUMERATED
Definition: asn1_obj.h:38
Botan::UNIVERSAL
Definition: asn1_obj.h:23
Botan::OCTET_STRING
Definition: asn1_obj.h:35
Botan::CONSTRUCTED
Definition: asn1_obj.h:27
Botan::ASN1_Tag
ASN1_Tag
Definition: asn1_obj.h:22
Botan::SEQUENCE
Definition: asn1_obj.h:39
Botan::BIT_STRING
Definition: asn1_obj.h:34

## Member Function Documentation

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_roots | list of certstores containing trusted roots
  cert_path | optionally, 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().

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())
180 return Certificate_Status_Code::OCSP_RESPONSE_INVALID;
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)
241 return Certificate_Status_Code::OCSP_ISSUER_NOT_FOUND;
242
243 if(!signing_cert->allowed_usage(CRL_SIGN) &&
244 !signing_cert->allowed_extended_usage("PKIX.OCSPSigning"))
245 {
246 return Certificate_Status_Code::OCSP_RESPONSE_MISSING_KEYUSAGE;
247 }
248
249 return this->verify_signature(*signing_cert);
250 }
Botan::Certificate_Status_Code::OCSP_RESPONSE_MISSING_KEYUSAGE
Botan::X509_DN::empty
bool empty() const
Definition: x509_dn.h:40
Botan::CRL_SIGN
Definition: key_constraint.h:29
Botan::Certificate_Status_Code::OCSP_RESPONSE_INVALID
Botan::OCSP::Response::verify_signature
Certificate_Status_Code verify_signature(const X509_Certificate &issuer) const
Definition: ocsp.cpp:144
Botan::Certificate_Status_Code::OCSP_ISSUER_NOT_FOUND

const X509_Time& Botan::OCSP::Response::produced_at | ( |  | ) | const
| inline

Returns
  the time this OCSP response was supposedly produced at

Definition at line 115 of file ocsp.h.

115 { return m_produced_at; }

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

Definition at line 127 of file ocsp.h.

127 { return m_response_bits; }

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

125 { return m_key_hash; }

const X509_DN& Botan::OCSP::Response::signer_name | ( |  | ) | const
| inline

Returns
  DN of signer, if provided in response (may be empty)

Definition at line 120 of file ocsp.h.

120 { return m_signer_name; }

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

  issuer | issuer certificate
  subject | subject certificate
  ref_time | the 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::CERT_IS_REVOKED, Botan::OCSP_BAD_STATUS, Botan::OCSP_CERT_NOT_LISTED, Botan::OCSP_HAS_EXPIRED, Botan::OCSP_NOT_YET_VALID, and Botan::OCSP_RESPONSE_GOOD.

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)
263 return Certificate_Status_Code::CERT_IS_REVOKED;
264
265 if(response.this_update() > x509_ref_time)
266 return Certificate_Status_Code::OCSP_NOT_YET_VALID;
267
268 if(response.next_update().time_is_set() && x509_ref_time > response.next_update())
269 return Certificate_Status_Code::OCSP_HAS_EXPIRED;
270
271 if(response.cert_status() == 0)
272 return Certificate_Status_Code::OCSP_RESPONSE_GOOD;
273 else
274 return Certificate_Status_Code::OCSP_BAD_STATUS;
275 }
276 }
277
278 return Certificate_Status_Code::OCSP_CERT_NOT_LISTED;
279 }
Botan::Certificate_Status_Code::OCSP_CERT_NOT_LISTED
Botan::Certificate_Status_Code::OCSP_RESPONSE_GOOD
Botan::Certificate_Status_Code::OCSP_BAD_STATUS
Botan::Certificate_Status_Code::OCSP_NOT_YET_VALID
Botan::Certificate_Status_Code::OCSP_HAS_EXPIRED
Botan::Certificate_Status_Code::CERT_IS_REVOKED

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

Verify that issuer's key signed this response

Parameters

  issuer | certificate 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::IEEE_1363, Botan::OIDS::lookup(), Botan::OCSP_RESPONSE_INVALID, Botan::OCSP_SIGNATURE_ERROR, Botan::OCSP_SIGNATURE_OK, Botan::AlgorithmIdentifier::oid, 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.oid), '/');
152
153 if(sig_info.size() != 2 || sig_info[0] != pub_key->algo_name())
154 return Certificate_Status_Code::OCSP_RESPONSE_INVALID;
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))
162 return Certificate_Status_Code::OCSP_SIGNATURE_OK;
163 else
164 return Certificate_Status_Code::OCSP_SIGNATURE_ERROR;
165 }
166 catch(Exception&)
167 {
168 return Certificate_Status_Code::OCSP_SIGNATURE_ERROR;
169 }
170 }
Botan::Certificate_Status_Code::OCSP_SIGNATURE_ERROR
Botan::Signature_Format
Signature_Format
Definition: pubkey.h:29
Botan::split_on
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:138
Botan::OIDS::lookup
std::string lookup(const OID &oid)
Definition: oids.cpp:18
Botan::AlgorithmIdentifier::oid
OID oid
Definition: alg_id.h:36
Botan::IEEE_1363
Definition: pubkey.h:29
Botan::ASN1::put_in_sequence
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition: asn1_obj.cpp:35
Botan::DER_SEQUENCE
Definition: pubkey.h:29
Botan::Certificate_Status_Code::OCSP_SIGNATURE_OK
Botan::Certificate_Status_Code::OCSP_RESPONSE_INVALID

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

- src/lib/x509/ocsp.h
- src/lib/x509/ocsp.cpp