Botan 3.13.0
Crypto and TLS for C&
ocsp.h
Go to the documentation of this file.
1/*
2* OCSP
3* (C) 2012 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_OCSP_H_
9#define BOTAN_OCSP_H_
10
11#include <botan/asn1_obj.h>
12#include <botan/asn1_time.h>
13#include <botan/bigint.h>
14#include <botan/pkix_types.h>
15#include <botan/x509cert.h>
16
17#include <chrono>
18#include <optional>
19
20namespace Botan {
21
24class URI;
25
26namespace OCSP {
27
28class BOTAN_PUBLIC_API(2, 0) CertID final : public ASN1_Object {
29 public:
30 CertID() = default;
31
32 CertID(const X509_Certificate& issuer, const BigInt& subject_serial);
33
34 CertID(const X509_Certificate& issuer, const X509_Serial_Number& subject_serial);
35
36 bool is_id_for(const X509_Certificate& issuer, const X509_Certificate& subject) const;
37
38 void encode_into(DER_Encoder& to) const override;
39
40 void decode_from(BER_Decoder& from) override;
41
42 const std::vector<uint8_t>& issuer_key_hash() const { return m_issuer_key_hash; }
43
44 private:
45 AlgorithmIdentifier m_hash_id;
46 std::vector<uint8_t> m_issuer_dn_hash;
47 std::vector<uint8_t> m_issuer_key_hash;
48 X509_Serial_Number m_subject_serial;
49};
50
51class BOTAN_PUBLIC_API(2, 0) SingleResponse final : public ASN1_Object {
52 public:
53 SingleResponse() = default;
54
55 /**
56 * Create a SingleResponse asserting a good status, as emitted by an
57 * OCSP responder. All times must be tagged as GeneralizedTime; an
58 * unset next_update omits the optional nextUpdate field.
59 */
61
62 /// As good(), but asserting an unknown status
64
65 /// As good(), but asserting a revoked status with the given RevokedInfo
68 std::optional<CRL_Code> reason,
71
72 const CertID& certid() const { return m_certid; }
73
74 size_t cert_status() const { return m_cert_status; }
75
76 const X509_Time& this_update() const { return m_thisupdate; }
77
78 const X509_Time& next_update() const { return m_nextupdate; }
79
80 /// The revocationTime; set only when cert_status() is 1 (revoked)
81 const std::optional<X509_Time>& revocation_time() const { return m_revocation_time; }
82
83 /// The revocationReason, when cert_status() is 1 and one was provided
84 const std::optional<CRL_Code>& revocation_reason() const { return m_revocation_reason; }
85
86 void encode_into(DER_Encoder& to) const override;
87
88 void decode_from(BER_Decoder& from) override;
89
90 bool has_unknown_critical_extension() const { return m_has_unknown_critical_ext; }
91
92 private:
94 size_t cert_status,
95 std::optional<X509_Time> revocation_time,
96 std::optional<CRL_Code> revocation_reason,
97 X509_Time this_update,
98 X509_Time next_update);
99
100 CertID m_certid;
101 size_t m_cert_status = 2; // unknown
102 X509_Time m_thisupdate;
103 X509_Time m_nextupdate;
104 std::optional<X509_Time> m_revocation_time;
105 std::optional<CRL_Code> m_revocation_reason;
106 bool m_has_unknown_critical_ext = false;
107};
108
109/**
110* An OCSP request.
111*/
112class BOTAN_PUBLIC_API(2, 0) Request final {
113 public:
114 /**
115 * Create an OCSP request.
116 * @param issuer_cert issuer certificate
117 * @param subject_cert subject certificate
118 */
119 Request(const X509_Certificate& issuer_cert, const X509_Certificate& subject_cert);
120
121 Request(const X509_Certificate& issuer_cert, const BigInt& subject_serial);
122
123 /**
124 * @return BER-encoded OCSP request
125 */
126 std::vector<uint8_t> BER_encode() const;
127
128 /**
129 * @return Base64-encoded OCSP request
130 */
131 std::string base64_encode() const;
132
133 /**
134 * @return issuer certificate
135 */
136 const X509_Certificate& issuer() const { return m_issuer; }
137
138 /**
139 * @return subject certificate
140 * TODO(Botan4) remove this function
141 */
142 const X509_Certificate& subject() const { // NOLINT(*-convert-member-functions-to-static)
143 throw Not_Implemented("Method have been deprecated");
144 }
145
146 const std::vector<uint8_t>& issuer_key_hash() const { return m_certid.issuer_key_hash(); }
147
148 private:
149 X509_Certificate m_issuer;
150 CertID m_certid;
151};
152
153/**
154* OCSP response status.
155*
156* see https://tools.ietf.org/html/rfc6960#section-4.2.1
157*/
166
167/**
168* OCSP response.
169*
170* Note this class is only usable as an OCSP client
171*/
172class BOTAN_PUBLIC_API(2, 0) Response final {
173 public:
174 /**
175 * Create a fake OCSP response from a given status code.
176 * @param status the status code the check functions will return
177 *
178 * TODO(Botan4) make this constructor private
179 */
181
182 /**
183 * Parses an OCSP response.
184 * @param response_bits response bits received
185 */
186 BOTAN_FUTURE_EXPLICIT Response(const std::vector<uint8_t>& response_bits) :
187 Response(response_bits.data(), response_bits.size()) {}
188
189 /**
190 * Parses an OCSP response.
191 * @param response_bits response bits received
192 * @param response_bits_len length of response in bytes
193 */
194 Response(const uint8_t response_bits[], size_t response_bits_len);
195
196 /**
197 * Find the certificate that signed this OCSP response from all possible
198 * candidates and taking the attached certificates into account.
199 *
200 * @param issuer_certificate is the issuer of the certificate in question
201 * @param trusted_ocsp_responders optionally, a certificate store containing
202 * additionally trusted responder certificates
203 *
204 * @return the certificate that signed this response or std::nullopt if not found
205 */
206 std::optional<X509_Certificate> find_signing_certificate(
207 const X509_Certificate& issuer_certificate, const Certificate_Store* trusted_ocsp_responders = nullptr) const;
208
209 /**
210 * Check signature of the OCSP response.
211 *
212 * Note: It is the responsibility of the caller to verify that signing
213 * certificate is trustworthy and authorized to do so.
214 *
215 * @param signing_certificate the certificate that signed this response
216 * (@sa Response::find_signing_certificate).
217 *
218 * @return status code indicating the validity of the signature
219 */
220 Certificate_Status_Code verify_signature(const X509_Certificate& signing_certificate) const;
221
222 /**
223 * Check signature of the OCSP response.
224 *
225 * Note: It is the responsibility of the caller to verify that signing
226 * certificate is trustworthy and authorized to do so.
227 *
228 * @param signing_certificate the certificate that signed this response
229 * (@sa Response::find_signing_certificate)
230 * @param restrictions on the signature validation
231 *
232 * @return status code indicating the validity of the signature
233 */
235 const Path_Validation_Restrictions& restrictions) const;
236
237 /**
238 * @return the status of the response
239 */
240 Response_Status_Code status() const { return m_status; }
241
242 /**
243 * @return the time this OCSP response was supposedly produced at
244 */
245 const X509_Time& produced_at() const { return m_produced_at; }
246
247 /**
248 * @return DN of signer, if provided in response (may be empty)
249 */
250 const X509_DN& signer_name() const { return m_signer_name; }
251
252 /**
253 * @return key hash, if provided in response (may be empty)
254 */
255 const std::vector<uint8_t>& signer_key_hash() const { return m_key_hash; }
256
257 const std::vector<uint8_t>& raw_bits() const { return m_response_bits; }
258
259 /**
260 * Searches the OCSP response for issuer and subject certificate.
261 * @param issuer issuer certificate
262 * @param subject subject certificate
263 * @param ref_time the reference time
264 * @param max_age the maximum age the response should be considered valid
265 * if next_update is not set
266 * @return OCSP status code, possible values:
267 * CERT_IS_REVOKED,
268 * OCSP_NOT_YET_VALID,
269 * OCSP_HAS_EXPIRED,
270 * OCSP_IS_TOO_OLD,
271 * OCSP_RESPONSE_GOOD,
272 * OCSP_BAD_STATUS,
273 * OCSP_CERT_NOT_LISTED
274 */
275 Certificate_Status_Code status_for(
276 const X509_Certificate& issuer,
277 const X509_Certificate& subject,
278 std::chrono::system_clock::time_point ref_time = std::chrono::system_clock::now(),
279 std::chrono::seconds max_age = std::chrono::seconds::zero()) const;
280
281 /**
282 * @return the certificate chain, if provided in response
283 */
284 const std::vector<X509_Certificate>& certificates() const { return m_certs; }
285
286 /**
287 * @return the SingleResponses included in this response (empty for a 'fake'
288 * or non-successful response)
289 */
290 const std::vector<SingleResponse>& responses() const { return m_responses; }
291
292 /**
293 * Return a fake OCSP response indicating the server was not available
294 * This is not normally useful for applications
295 */
299
300 /**
301 * Return a fake OCSP response indicating there was no usable OCSP URL
302 * This is not normally useful for applications
303 */
307
308 /**
309 * Return the dummy response if this is a 'fake' OCSP response otherwise std::nullopt
310 * This is not normally useful for applications
311 */
312 std::optional<Certificate_Status_Code> dummy_status() const { return m_dummy_response_status; }
313
314 private:
315 bool is_issued_by(const X509_Certificate& candidate) const;
316
317 private:
319 std::vector<uint8_t> m_response_bits;
320 X509_Time m_produced_at;
321 X509_DN m_signer_name;
322 std::vector<uint8_t> m_key_hash;
323 std::vector<uint8_t> m_tbs_bits;
324 AlgorithmIdentifier m_sig_algo;
325 std::vector<uint8_t> m_signature;
326 std::vector<X509_Certificate> m_certs;
327
328 std::vector<SingleResponse> m_responses;
329
330 std::optional<Certificate_Status_Code> m_dummy_response_status;
331
332 bool m_has_unknown_critical_ext = false;
333};
334
335#if defined(BOTAN_HAS_HTTP_UTIL)
336
337/**
338* Makes an online OCSP request via HTTP and returns the (unverified!) OCSP response.
339* @param issuer issuer certificate
340* @param subject_serial the subject's serial number
341* @param ocsp_responder the OCSP responder to query
342* @param timeout a timeout on the HTTP request
343* @return OCSP response
344*/
345BOTAN_PUBLIC_API(3, 13)
346Response online_check(const X509_Certificate& issuer,
347 const BigInt& subject_serial,
348 const URI& ocsp_responder,
349 std::chrono::milliseconds timeout = std::chrono::milliseconds(3000));
350
351/**
352* Makes an online OCSP request via HTTP and returns the (unverified!) OCSP response.
353* @param issuer issuer certificate
354* @param subject_serial the subject's serial number
355* @param ocsp_responder the OCSP responder to query
356* @param timeout a timeout on the HTTP request
357* @return OCSP response
358*/
359BOTAN_DEPRECATED_API("Prefer version taking a URI")
360Response online_check(const X509_Certificate& issuer,
361 const BigInt& subject_serial,
362 std::string_view ocsp_responder,
363 std::chrono::milliseconds timeout = std::chrono::milliseconds(3000));
364
365/**
366* Makes an online OCSP request via HTTP and returns the (unverified) OCSP response.
367* @param issuer issuer certificate
368* @param subject subject certificate
369* @param timeout a timeout on the HTTP request
370* @return OCSP response
371*/
373Response online_check(const X509_Certificate& issuer,
374 const X509_Certificate& subject,
375 std::chrono::milliseconds timeout = std::chrono::milliseconds(3000));
376
377#endif
378
379} // namespace OCSP
380
381} // namespace Botan
382
383#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_FUTURE_EXPLICIT
Definition api.h:52
#define BOTAN_DEPRECATED_API(msg)
Definition api.h:27
ASN1_Object()=default
void decode_from(BER_Decoder &from) override
Definition ocsp.cpp:113
const std::vector< uint8_t > & issuer_key_hash() const
Definition ocsp.h:42
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
const X509_Certificate & subject() const
Definition ocsp.h:142
const std::vector< uint8_t > & issuer_key_hash() const
Definition ocsp.h:146
Request(const X509_Certificate &issuer_cert, const X509_Certificate &subject_cert)
Definition ocsp.cpp:325
const X509_Certificate & issuer() const
Definition ocsp.h:136
std::vector< uint8_t > BER_encode() const
Definition ocsp.cpp:335
BOTAN_FUTURE_EXPLICIT Response(Certificate_Status_Code status)
Definition ocsp.cpp:372
const std::vector< SingleResponse > & responses() const
Definition ocsp.h:290
Response_Status_Code status() const
Definition ocsp.h:240
static Response dummy_server_not_available_response()
Definition ocsp.h:296
const X509_DN & signer_name() const
Definition ocsp.h:250
const X509_Time & produced_at() const
Definition ocsp.h:245
std::optional< Certificate_Status_Code > dummy_status() const
Definition ocsp.h:312
const std::vector< X509_Certificate > & certificates() const
Definition ocsp.h:284
const std::vector< uint8_t > & raw_bits() const
Definition ocsp.h:257
static Response dummy_no_revocation_url_response()
Definition ocsp.h:304
const std::vector< uint8_t > & signer_key_hash() const
Definition ocsp.h:255
BOTAN_FUTURE_EXPLICIT Response(const std::vector< uint8_t > &response_bits)
Definition ocsp.h:186
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
bool has_unknown_critical_extension() const
Definition ocsp.h:90
const std::optional< CRL_Code > & revocation_reason() const
The revocationReason, when cert_status() is 1 and one was provided.
Definition ocsp.h:84
const X509_Time & this_update() const
Definition ocsp.h:76
size_t cert_status() const
Definition ocsp.h:74
Response_Status_Code
Definition ocsp.h:158
ASN1_Time X509_Time
Definition asn1_obj.h:27
Certificate_Status_Code
Definition pkix_enums.h:21
bool verify_signature(std::span< const uint8_t, ED448_LEN > pk, bool phflag, std::span< const uint8_t > context, std::span< const uint8_t > sig, std::span< const uint8_t > msg)
Verify a signature(RFC 8032 5.2.7).