Botan 3.12.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
24
25namespace OCSP {
26
27class BOTAN_PUBLIC_API(2, 0) CertID final : public ASN1_Object {
28 public:
29 CertID() = default;
30
31 CertID(const X509_Certificate& issuer, const BigInt& subject_serial);
32
33 bool is_id_for(const X509_Certificate& issuer, const X509_Certificate& subject) const;
34
35 void encode_into(DER_Encoder& to) const override;
36
37 void decode_from(BER_Decoder& from) override;
38
39 const std::vector<uint8_t>& issuer_key_hash() const { return m_issuer_key_hash; }
40
41 private:
42 AlgorithmIdentifier m_hash_id;
43 std::vector<uint8_t> m_issuer_dn_hash;
44 std::vector<uint8_t> m_issuer_key_hash;
45 BigInt m_subject_serial;
46};
47
48class BOTAN_PUBLIC_API(2, 0) SingleResponse final : public ASN1_Object {
49 public:
50 const CertID& certid() const { return m_certid; }
51
52 size_t cert_status() const { return m_cert_status; }
53
54 const X509_Time& this_update() const { return m_thisupdate; }
55
56 const X509_Time& next_update() const { return m_nextupdate; }
57
58 void encode_into(DER_Encoder& to) const override;
59
60 void decode_from(BER_Decoder& from) override;
61
62 bool has_unknown_critical_extension() const { return m_has_unknown_critical_ext; }
63
64 private:
65 CertID m_certid;
66 size_t m_cert_status = 2; // unknown
67 X509_Time m_thisupdate;
68 X509_Time m_nextupdate;
69 bool m_has_unknown_critical_ext = false;
70};
71
72/**
73* An OCSP request.
74*/
75class BOTAN_PUBLIC_API(2, 0) Request final {
76 public:
77 /**
78 * Create an OCSP request.
79 * @param issuer_cert issuer certificate
80 * @param subject_cert subject certificate
81 */
82 Request(const X509_Certificate& issuer_cert, const X509_Certificate& subject_cert);
83
84 Request(const X509_Certificate& issuer_cert, const BigInt& subject_serial);
85
86 /**
87 * @return BER-encoded OCSP request
88 */
89 std::vector<uint8_t> BER_encode() const;
90
91 /**
92 * @return Base64-encoded OCSP request
93 */
94 std::string base64_encode() const;
95
96 /**
97 * @return issuer certificate
98 */
99 const X509_Certificate& issuer() const { return m_issuer; }
100
101 /**
102 * @return subject certificate
103 * TODO(Botan4) remove this function
104 */
105 const X509_Certificate& subject() const { // NOLINT(*-convert-member-functions-to-static)
106 throw Not_Implemented("Method have been deprecated");
107 }
108
109 const std::vector<uint8_t>& issuer_key_hash() const { return m_certid.issuer_key_hash(); }
110
111 private:
112 X509_Certificate m_issuer;
113 CertID m_certid;
114};
115
116/**
117* OCSP response status.
118*
119* see https://tools.ietf.org/html/rfc6960#section-4.2.1
120*/
129
130/**
131* OCSP response.
132*
133* Note this class is only usable as an OCSP client
134*/
135class BOTAN_PUBLIC_API(2, 0) Response final {
136 public:
137 /**
138 * Create a fake OCSP response from a given status code.
139 * @param status the status code the check functions will return
140 */
142
143 /**
144 * Parses an OCSP response.
145 * @param response_bits response bits received
146 */
147 BOTAN_FUTURE_EXPLICIT Response(const std::vector<uint8_t>& response_bits) :
148 Response(response_bits.data(), response_bits.size()) {}
149
150 /**
151 * Parses an OCSP response.
152 * @param response_bits response bits received
153 * @param response_bits_len length of response in bytes
154 */
155 Response(const uint8_t response_bits[], size_t response_bits_len);
156
157 /**
158 * Find the certificate that signed this OCSP response from all possible
159 * candidates and taking the attached certificates into account.
160 *
161 * @param issuer_certificate is the issuer of the certificate in question
162 * @param trusted_ocsp_responders optionally, a certificate store containing
163 * additionally trusted responder certificates
164 *
165 * @return the certificate that signed this response or std::nullopt if not found
166 */
167 std::optional<X509_Certificate> find_signing_certificate(
168 const X509_Certificate& issuer_certificate, const Certificate_Store* trusted_ocsp_responders = nullptr) const;
169
170 /**
171 * Check signature of the OCSP response.
172 *
173 * Note: It is the responsibility of the caller to verify that signing
174 * certificate is trustworthy and authorized to do so.
175 *
176 * @param signing_certificate the certificate that signed this response
177 * (@sa Response::find_signing_certificate).
178 *
179 * @return status code indicating the validity of the signature
180 */
181 Certificate_Status_Code verify_signature(const X509_Certificate& signing_certificate) const;
182
183 /**
184 * Check signature of the OCSP response.
185 *
186 * Note: It is the responsibility of the caller to verify that signing
187 * certificate is trustworthy and authorized to do so.
188 *
189 * @param signing_certificate the certificate that signed this response
190 * (@sa Response::find_signing_certificate)
191 * @param restrictions on the signature validation
192 *
193 * @return status code indicating the validity of the signature
194 */
196 const Path_Validation_Restrictions& restrictions) const;
197
198 /**
199 * @return the status of the response
200 */
201 Response_Status_Code status() const { return m_status; }
202
203 /**
204 * @return the time this OCSP response was supposedly produced at
205 */
206 const X509_Time& produced_at() const { return m_produced_at; }
207
208 /**
209 * @return DN of signer, if provided in response (may be empty)
210 */
211 const X509_DN& signer_name() const { return m_signer_name; }
212
213 /**
214 * @return key hash, if provided in response (may be empty)
215 */
216 const std::vector<uint8_t>& signer_key_hash() const { return m_key_hash; }
217
218 const std::vector<uint8_t>& raw_bits() const { return m_response_bits; }
219
220 /**
221 * Searches the OCSP response for issuer and subject certificate.
222 * @param issuer issuer certificate
223 * @param subject subject certificate
224 * @param ref_time the reference time
225 * @param max_age the maximum age the response should be considered valid
226 * if next_update is not set
227 * @return OCSP status code, possible values:
228 * CERT_IS_REVOKED,
229 * OCSP_NOT_YET_VALID,
230 * OCSP_HAS_EXPIRED,
231 * OCSP_IS_TOO_OLD,
232 * OCSP_RESPONSE_GOOD,
233 * OCSP_BAD_STATUS,
234 * OCSP_CERT_NOT_LISTED
235 */
236 Certificate_Status_Code status_for(
237 const X509_Certificate& issuer,
238 const X509_Certificate& subject,
239 std::chrono::system_clock::time_point ref_time = std::chrono::system_clock::now(),
240 std::chrono::seconds max_age = std::chrono::seconds::zero()) const;
241
242 /**
243 * @return the certificate chain, if provided in response
244 */
245 const std::vector<X509_Certificate>& certificates() const { return m_certs; }
246
247 /**
248 * @return the dummy response if this is a 'fake' OCSP response otherwise std::nullopt
249 */
250 std::optional<Certificate_Status_Code> dummy_status() const { return m_dummy_response_status; }
251
252 private:
253 bool is_issued_by(const X509_Certificate& candidate) const;
254
255 private:
257 std::vector<uint8_t> m_response_bits;
258 X509_Time m_produced_at;
259 X509_DN m_signer_name;
260 std::vector<uint8_t> m_key_hash;
261 std::vector<uint8_t> m_tbs_bits;
262 AlgorithmIdentifier m_sig_algo;
263 std::vector<uint8_t> m_signature;
264 std::vector<X509_Certificate> m_certs;
265
266 std::vector<SingleResponse> m_responses;
267
268 std::optional<Certificate_Status_Code> m_dummy_response_status;
269
270 bool m_has_unknown_critical_ext = false;
271};
272
273#if defined(BOTAN_HAS_HTTP_UTIL)
274
275/**
276* Makes an online OCSP request via HTTP and returns the (unverified) OCSP response.
277* @param issuer issuer certificate
278* @param subject_serial the subject's serial number
279* @param ocsp_responder the OCSP responder to query
280* @param timeout a timeout on the HTTP request
281* @return OCSP response
282*/
284Response online_check(const X509_Certificate& issuer,
285 const BigInt& subject_serial,
286 std::string_view ocsp_responder,
287 std::chrono::milliseconds timeout = std::chrono::milliseconds(3000));
288
289/**
290* Makes an online OCSP request via HTTP and returns the (unverified) OCSP response.
291* @param issuer issuer certificate
292* @param subject subject certificate
293* @param timeout a timeout on the HTTP request
294* @return OCSP response
295*/
297Response online_check(const X509_Certificate& issuer,
298 const X509_Certificate& subject,
299 std::chrono::milliseconds timeout = std::chrono::milliseconds(3000));
300
301#endif
302
303} // namespace OCSP
304
305} // namespace Botan
306
307#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_FUTURE_EXPLICIT
Definition api.h:52
ASN1_Object()=default
void decode_from(BER_Decoder &from) override
Definition ocsp.cpp:80
const std::vector< uint8_t > & issuer_key_hash() const
Definition ocsp.h:39
void encode_into(DER_Encoder &to) const override
Definition ocsp.cpp:71
bool is_id_for(const X509_Certificate &issuer, const X509_Certificate &subject) const
Definition ocsp.cpp:37
std::string base64_encode() const
Definition ocsp.cpp:217
const X509_Certificate & subject() const
Definition ocsp.h:105
const std::vector< uint8_t > & issuer_key_hash() const
Definition ocsp.h:109
Request(const X509_Certificate &issuer_cert, const X509_Certificate &subject_cert)
Definition ocsp.cpp:174
const X509_Certificate & issuer() const
Definition ocsp.h:99
std::vector< uint8_t > BER_encode() const
Definition ocsp.cpp:184
BOTAN_FUTURE_EXPLICIT Response(Certificate_Status_Code status)
Definition ocsp.cpp:221
Response_Status_Code status() const
Definition ocsp.h:201
const X509_DN & signer_name() const
Definition ocsp.h:211
const X509_Time & produced_at() const
Definition ocsp.h:206
std::optional< Certificate_Status_Code > dummy_status() const
Definition ocsp.h:250
const std::vector< X509_Certificate > & certificates() const
Definition ocsp.h:245
const std::vector< uint8_t > & raw_bits() const
Definition ocsp.h:218
const std::vector< uint8_t > & signer_key_hash() const
Definition ocsp.h:216
BOTAN_FUTURE_EXPLICIT Response(const std::vector< uint8_t > &response_bits)
Definition ocsp.h:147
const CertID & certid() const
Definition ocsp.h:50
const X509_Time & next_update() const
Definition ocsp.h:56
bool has_unknown_critical_extension() const
Definition ocsp.h:62
const X509_Time & this_update() const
Definition ocsp.h:54
size_t cert_status() const
Definition ocsp.h:52
Response_Status_Code
Definition ocsp.h:121
ASN1_Time X509_Time
Definition asn1_obj.h:23
Certificate_Status_Code
Definition pkix_enums.h:20
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).