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