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