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