Botan 3.9.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/bigint.h>
13#include <botan/pkix_types.h>
14#include <botan/x509cert.h>
15
16#include <chrono>
17#include <optional>
18
19namespace Botan {
20
22
23namespace OCSP {
24
25class BOTAN_PUBLIC_API(2, 0) CertID final : public ASN1_Object {
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
46class BOTAN_PUBLIC_API(2, 0) SingleResponse final : public ASN1_Object {
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*/
70class BOTAN_PUBLIC_API(2, 0) Request final {
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 * TODO(Botan4) remove this function
99 */
100 const X509_Certificate& subject() const { // NOLINT(*-convert-member-functions-to-static)
101 throw Not_Implemented("Method have been deprecated");
102 }
103
104 const std::vector<uint8_t>& issuer_key_hash() const { return m_certid.issuer_key_hash(); }
105
106 private:
107 X509_Certificate m_issuer;
108 CertID m_certid;
109};
110
111/**
112* OCSP response status.
113*
114* see https://tools.ietf.org/html/rfc6960#section-4.2.1
115*/
124
125/**
126* OCSP response.
127*
128* Note this class is only usable as an OCSP client
129*/
130class BOTAN_PUBLIC_API(2, 0) Response final {
131 public:
132 /**
133 * Create a fake OCSP response from a given status code.
134 * @param status the status code the check functions will return
135 */
137
138 /**
139 * Parses an OCSP response.
140 * @param response_bits response bits received
141 */
142 BOTAN_FUTURE_EXPLICIT Response(const std::vector<uint8_t>& response_bits) :
143 Response(response_bits.data(), response_bits.size()) {}
144
145 /**
146 * Parses an OCSP response.
147 * @param response_bits response bits received
148 * @param response_bits_len length of response in bytes
149 */
150 Response(const uint8_t response_bits[], size_t response_bits_len);
151
152 /**
153 * Find the certificate that signed this OCSP response from all possible
154 * candidates and taking the attached certificates into account.
155 *
156 * @param issuer_certificate is the issuer of the certificate in question
157 * @param trusted_ocsp_responders optionally, a certificate store containing
158 * additionally trusted responder certificates
159 *
160 * @return the certificate that signed this response or std::nullopt if not found
161 */
162 std::optional<X509_Certificate> find_signing_certificate(
163 const X509_Certificate& issuer_certificate, const Certificate_Store* trusted_ocsp_responders = nullptr) const;
164
165 /**
166 * Check signature of the OCSP response.
167 *
168 * Note: It is the responsibility of the caller to verify that signing
169 * certificate is trustworthy and authorized to do so.
170 *
171 * @param signing_certificate the certificate that signed this response
172 * (@sa Response::find_signing_certificate).
173 *
174 * @return status code indicating the validity of the signature
175 */
176 Certificate_Status_Code verify_signature(const X509_Certificate& signing_certificate) const;
177
178 /**
179 * @return the status of the response
180 */
181 Response_Status_Code status() const { return m_status; }
182
183 /**
184 * @return the time this OCSP response was supposedly produced at
185 */
186 const X509_Time& produced_at() const { return m_produced_at; }
187
188 /**
189 * @return DN of signer, if provided in response (may be empty)
190 */
191 const X509_DN& signer_name() const { return m_signer_name; }
192
193 /**
194 * @return key hash, if provided in response (may be empty)
195 */
196 const std::vector<uint8_t>& signer_key_hash() const { return m_key_hash; }
197
198 const std::vector<uint8_t>& raw_bits() const { return m_response_bits; }
199
200 /**
201 * Searches the OCSP response for issuer and subject certificate.
202 * @param issuer issuer certificate
203 * @param subject subject certificate
204 * @param ref_time the reference time
205 * @param max_age the maximum age the response should be considered valid
206 * if next_update is not set
207 * @return OCSP status code, possible values:
208 * CERT_IS_REVOKED,
209 * OCSP_NOT_YET_VALID,
210 * OCSP_HAS_EXPIRED,
211 * OCSP_IS_TOO_OLD,
212 * OCSP_RESPONSE_GOOD,
213 * OCSP_BAD_STATUS,
214 * OCSP_CERT_NOT_LISTED
215 */
216 Certificate_Status_Code status_for(
217 const X509_Certificate& issuer,
218 const X509_Certificate& subject,
219 std::chrono::system_clock::time_point ref_time = std::chrono::system_clock::now(),
220 std::chrono::seconds max_age = std::chrono::seconds::zero()) const;
221
222 /**
223 * @return the certificate chain, if provided in response
224 */
225 const std::vector<X509_Certificate>& certificates() const { return m_certs; }
226
227 /**
228 * @return the dummy response if this is a 'fake' OCSP response otherwise std::nullopt
229 */
230 std::optional<Certificate_Status_Code> dummy_status() const { return m_dummy_response_status; }
231
232 private:
233 bool is_issued_by(const X509_Certificate& candidate) const;
234
235 private:
237 std::vector<uint8_t> m_response_bits;
238 X509_Time m_produced_at;
239 X509_DN m_signer_name;
240 std::vector<uint8_t> m_key_hash;
241 std::vector<uint8_t> m_tbs_bits;
242 AlgorithmIdentifier m_sig_algo;
243 std::vector<uint8_t> m_signature;
244 std::vector<X509_Certificate> m_certs;
245
246 std::vector<SingleResponse> m_responses;
247
248 std::optional<Certificate_Status_Code> m_dummy_response_status;
249};
250
251#if defined(BOTAN_HAS_HTTP_UTIL)
252
253/**
254* Makes an online OCSP request via HTTP and returns the (unverified) OCSP response.
255* @param issuer issuer certificate
256* @param subject_serial the subject's serial number
257* @param ocsp_responder the OCSP responder to query
258* @param timeout a timeout on the HTTP request
259* @return OCSP response
260*/
262Response online_check(const X509_Certificate& issuer,
263 const BigInt& subject_serial,
264 std::string_view ocsp_responder,
265 std::chrono::milliseconds timeout = std::chrono::milliseconds(3000));
266
267/**
268* Makes an online OCSP request via HTTP and returns the (unverified) OCSP response.
269* @param issuer issuer certificate
270* @param subject subject certificate
271* @param timeout a timeout on the HTTP request
272* @return OCSP response
273*/
275Response online_check(const X509_Certificate& issuer,
276 const X509_Certificate& subject,
277 std::chrono::milliseconds timeout = std::chrono::milliseconds(3000));
278
279#endif
280
281} // namespace OCSP
282
283} // namespace Botan
284
285#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
const std::vector< uint8_t > & issuer_key_hash() const
Definition ocsp.h:37
void encode_into(DER_Encoder &to) const override
bool is_id_for(const X509_Certificate &issuer, const X509_Certificate &subject) const
std::string base64_encode() const
Definition ocsp.cpp:80
const X509_Certificate & subject() const
Definition ocsp.h:100
const std::vector< uint8_t > & issuer_key_hash() const
Definition ocsp.h:104
Request(const X509_Certificate &issuer_cert, const X509_Certificate &subject_cert)
Definition ocsp.cpp:51
const X509_Certificate & issuer() const
Definition ocsp.h:94
std::vector< uint8_t > BER_encode() const
Definition ocsp.cpp:61
BOTAN_FUTURE_EXPLICIT Response(Certificate_Status_Code status)
Definition ocsp.cpp:84
Response_Status_Code status() const
Definition ocsp.h:181
const X509_DN & signer_name() const
Definition ocsp.h:191
const X509_Time & produced_at() const
Definition ocsp.h:186
std::optional< Certificate_Status_Code > dummy_status() const
Definition ocsp.h:230
const std::vector< X509_Certificate > & certificates() const
Definition ocsp.h:225
const std::vector< uint8_t > & raw_bits() const
Definition ocsp.h:198
const std::vector< uint8_t > & signer_key_hash() const
Definition ocsp.h:196
BOTAN_FUTURE_EXPLICIT Response(const std::vector< uint8_t > &response_bits)
Definition ocsp.h:142
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
Response_Status_Code
Definition ocsp.h:116
ASN1_Time X509_Time
Definition asn1_obj.h:424
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)