1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
/*
* OCSP
* (C) 2012 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_OCSP_H_
#define BOTAN_OCSP_H_
#include <botan/cert_status.h>
#include <botan/ocsp_types.h>
#include <botan/x509_dn.h>
#include <chrono>
namespace Botan {
class Certificate_Store;
namespace OCSP {
/**
* An OCSP request.
*/
class BOTAN_PUBLIC_API(2,0) Request final
{
public:
/**
* Create an OCSP request.
* @param issuer_cert issuer certificate
* @param subject_cert subject certificate
*/
Request(const X509_Certificate& issuer_cert,
const X509_Certificate& subject_cert);
Request(const X509_Certificate& issuer_cert,
const BigInt& subject_serial);
/**
* @return BER-encoded OCSP request
*/
std::vector<uint8_t> BER_encode() const;
/**
* @return Base64-encoded OCSP request
*/
std::string base64_encode() const;
/**
* @return issuer certificate
*/
const X509_Certificate& issuer() const { return m_issuer; }
/**
* @return subject certificate
*/
const X509_Certificate& subject() const { throw Not_Implemented("Method have been deprecated"); }
const std::vector<uint8_t>& issuer_key_hash() const
{ return m_certid.issuer_key_hash(); }
private:
X509_Certificate m_issuer;
CertID m_certid;
};
/**
* OCSP response.
*
* Note this class is only usable as an OCSP client
*/
class BOTAN_PUBLIC_API(2,0) Response final
{
public:
/**
* Creates an empty OCSP response.
*/
Response() = default;
/**
* Create a fake OCSP response from a given status code.
* @param status the status code the check functions will return
*/
Response(Certificate_Status_Code status);
/**
* Parses an OCSP response.
* @param response_bits response bits received
*/
Response(const std::vector<uint8_t>& response_bits) :
Response(response_bits.data(), response_bits.size())
{}
/**
* Parses an OCSP response.
* @param response_bits response bits received
* @param response_bits_len length of response in bytes
*/
Response(const uint8_t response_bits[],
size_t response_bits_len);
/**
* Check signature and return status
* The optional cert_path is the (already validated!) certificate path of
* the end entity which is being inquired about
* @param trust_roots list of certstores containing trusted roots
* @param cert_path optionally, the (already verified!) certificate path for the certificate
* this is an OCSP response for. This is necessary to find the correct intermediate CA in
* some cases.
*/
Certificate_Status_Code check_signature(const std::vector<Certificate_Store*>& trust_roots,
const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path = {}) const;
/**
* Verify that issuer's key signed this response
* @param issuer certificate of issuer
* @return if signature valid OCSP_SIGNATURE_OK else an error code
*/
Certificate_Status_Code verify_signature(const X509_Certificate& issuer) const;
/**
* @return the time this OCSP response was supposedly produced at
*/
const X509_Time& produced_at() const { return m_produced_at; }
/**
* @return DN of signer, if provided in response (may be empty)
*/
const X509_DN& signer_name() const { return m_signer_name; }
/**
* @return key hash, if provided in response (may be empty)
*/
const std::vector<uint8_t>& signer_key_hash() const { return m_key_hash; }
const std::vector<uint8_t>& raw_bits() const { return m_response_bits; }
/**
* Searches the OCSP response for issuer and subject certificate.
* @param issuer issuer certificate
* @param subject subject certificate
* @param ref_time the reference time
* @return OCSP status code, possible values:
* CERT_IS_REVOKED,
* OCSP_NOT_YET_VALID,
* OCSP_HAS_EXPIRED,
* OCSP_RESPONSE_GOOD,
* OCSP_BAD_STATUS,
* OCSP_CERT_NOT_LISTED
*/
Certificate_Status_Code status_for(const X509_Certificate& issuer,
const X509_Certificate& subject,
std::chrono::system_clock::time_point ref_time = std::chrono::system_clock::now()) const;
/**
* @return the certificate chain, if provided in response
*/
const std::vector<X509_Certificate> &certificates() const { return m_certs; }
private:
std::vector<uint8_t> m_response_bits;
X509_Time m_produced_at;
X509_DN m_signer_name;
std::vector<uint8_t> m_key_hash;
std::vector<uint8_t> m_tbs_bits;
AlgorithmIdentifier m_sig_algo;
std::vector<uint8_t> m_signature;
std::vector<X509_Certificate> m_certs;
std::vector<SingleResponse> m_responses;
Certificate_Status_Code m_dummy_response_status;
};
#if defined(BOTAN_HAS_HTTP_UTIL)
/**
* Makes an online OCSP request via HTTP and returns the OCSP response.
* @param issuer issuer certificate
* @param subject_serial the subject's serial number
* @param ocsp_responder the OCSP responder to query
* @param trusted_roots trusted roots for the OCSP response
* @param timeout a timeout on the HTTP request
* @return OCSP response
*/
BOTAN_PUBLIC_API(2,1)
Response online_check(const X509_Certificate& issuer,
const BigInt& subject_serial,
const std::string& ocsp_responder,
Certificate_Store* trusted_roots,
std::chrono::milliseconds timeout = std::chrono::milliseconds(3000));
/**
* Makes an online OCSP request via HTTP and returns the OCSP response.
* @param issuer issuer certificate
* @param subject subject certificate
* @param trusted_roots trusted roots for the OCSP response
* @param timeout a timeout on the HTTP request
* @return OCSP response
*/
BOTAN_PUBLIC_API(2,0)
Response online_check(const X509_Certificate& issuer,
const X509_Certificate& subject,
Certificate_Store* trusted_roots,
std::chrono::milliseconds timeout = std::chrono::milliseconds(3000));
#endif
}
}
#endif
|