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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
/*
* X.509 Certificate Authority
* (C) 1999-2008 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_X509_CA_H_
#define BOTAN_X509_CA_H_
#include <botan/x509cert.h>
#include <botan/x509_crl.h>
#include <chrono>
#include <map>
namespace Botan {
class RandomNumberGenerator;
class BigInt;
class Private_Key;
class PKCS10_Request;
class PK_Signer;
/**
* This class represents X.509 Certificate Authorities (CAs).
*/
class BOTAN_PUBLIC_API(2,0) X509_CA final
{
public:
/**
* Sign a PKCS#10 Request.
* @param req the request to sign
* @param rng the rng to use
* @param not_before the starting time for the certificate
* @param not_after the expiration time for the certificate
* @return resulting certificate
*/
X509_Certificate sign_request(const PKCS10_Request& req,
RandomNumberGenerator& rng,
const X509_Time& not_before,
const X509_Time& not_after) const;
/**
* Sign a PKCS#10 Request.
* @param req the request to sign
* @param rng the rng to use
* @param serial_number the serial number the cert will be assigned.
* @param not_before the starting time for the certificate
* @param not_after the expiration time for the certificate
* @return resulting certificate
*/
X509_Certificate sign_request(const PKCS10_Request& req,
RandomNumberGenerator& rng,
const BigInt& serial_number,
const X509_Time& not_before,
const X509_Time& not_after) const;
/**
* Get the certificate of this CA.
* @return CA certificate
*/
X509_Certificate ca_certificate() const;
/**
* Create a new and empty CRL for this CA.
* @param rng the random number generator to use
* @param issue_time the issue time (typically system_clock::now)
* @param next_update the time interval after issue_data within which
* a new CRL will be produced.
* @return new CRL
*/
X509_CRL new_crl(RandomNumberGenerator& rng,
std::chrono::system_clock::time_point issue_time,
std::chrono::seconds next_update) const;
/**
* Create a new CRL by with additional entries.
* @param last_crl the last CRL of this CA to add the new entries to
* @param new_entries contains the new CRL entries to be added to the CRL
* @param rng the random number generator to use
* @param issue_time the issue time (typically system_clock::now)
* @param next_update the time interval after issue_data within which
* a new CRL will be produced.
*/
X509_CRL update_crl(const X509_CRL& last_crl,
const std::vector<CRL_Entry>& new_entries,
RandomNumberGenerator& rng,
std::chrono::system_clock::time_point issue_time,
std::chrono::seconds next_update) const;
/**
* Create a new and empty CRL for this CA.
* @param rng the random number generator to use
* @param next_update the time to set in next update in seconds
* as the offset from the current time
* @return new CRL
*/
X509_CRL new_crl(RandomNumberGenerator& rng,
uint32_t next_update = 604800) const;
/**
* Create a new CRL by with additional entries.
* @param last_crl the last CRL of this CA to add the new entries to
* @param new_entries contains the new CRL entries to be added to the CRL
* @param rng the random number generator to use
* @param next_update the time to set in next update in seconds
* as the offset from the current time
*/
X509_CRL update_crl(const X509_CRL& last_crl,
const std::vector<CRL_Entry>& new_entries,
RandomNumberGenerator& rng,
uint32_t next_update = 604800) const;
/**
* Interface for creating new certificates
* @param signer a signing object
* @param rng a random number generator
* @param sig_algo the signature algorithm identifier
* @param pub_key the serialized public key
* @param not_before the start time of the certificate
* @param not_after the end time of the certificate
* @param issuer_dn the DN of the issuer
* @param subject_dn the DN of the subject
* @param extensions an optional list of certificate extensions
* @returns newly minted certificate
*/
static X509_Certificate make_cert(PK_Signer* signer,
RandomNumberGenerator& rng,
const AlgorithmIdentifier& sig_algo,
const std::vector<uint8_t>& pub_key,
const X509_Time& not_before,
const X509_Time& not_after,
const X509_DN& issuer_dn,
const X509_DN& subject_dn,
const Extensions& extensions);
/**
* Interface for creating new certificates
* @param signer a signing object
* @param rng a random number generator
* @param serial_number the serial number the cert will be assigned
* @param sig_algo the signature algorithm identifier
* @param pub_key the serialized public key
* @param not_before the start time of the certificate
* @param not_after the end time of the certificate
* @param issuer_dn the DN of the issuer
* @param subject_dn the DN of the subject
* @param extensions an optional list of certificate extensions
* @returns newly minted certificate
*/
static X509_Certificate make_cert(PK_Signer* signer,
RandomNumberGenerator& rng,
const BigInt& serial_number,
const AlgorithmIdentifier& sig_algo,
const std::vector<uint8_t>& pub_key,
const X509_Time& not_before,
const X509_Time& not_after,
const X509_DN& issuer_dn,
const X509_DN& subject_dn,
const Extensions& extensions);
/**
* Create a new CA object.
* @param ca_certificate the certificate of the CA
* @param key the private key of the CA
* @param hash_fn name of a hash function to use for signing
* @param rng the random generator to use
*/
X509_CA(const X509_Certificate& ca_certificate,
const Private_Key& key,
const std::string& hash_fn,
RandomNumberGenerator& rng);
/**
* Create a new CA object.
* @param ca_certificate the certificate of the CA
* @param key the private key of the CA
* @param opts additional options, e.g. padding, as key value pairs
* @param hash_fn name of a hash function to use for signing
* @param rng the random generator to use
*/
X509_CA(const X509_Certificate& ca_certificate,
const Private_Key& key,
const std::map<std::string,std::string>& opts,
const std::string& hash_fn,
RandomNumberGenerator& rng);
X509_CA(const X509_CA&) = delete;
X509_CA& operator=(const X509_CA&) = delete;
X509_CA(X509_CA&&) = default;
X509_CA& operator=(X509_CA&&) = default;
~X509_CA();
private:
X509_CRL make_crl(const std::vector<CRL_Entry>& entries,
uint32_t crl_number,
RandomNumberGenerator& rng,
std::chrono::system_clock::time_point issue_time,
std::chrono::seconds next_update) const;
AlgorithmIdentifier m_ca_sig_algo;
X509_Certificate m_ca_cert;
std::string m_hash_fn;
std::unique_ptr<PK_Signer> m_signer;
};
/**
* Choose the default signature format for a certain public key signature
* scheme.
* @param key will be the key to choose a padding scheme for
* @param rng the random generator to use
* @param hash_fn is the desired hash function
* @param alg_id will be set to the chosen scheme
* @return A PK_Signer object for generating signatures
*/
BOTAN_PUBLIC_API(2,0) PK_Signer* choose_sig_format(const Private_Key& key,
RandomNumberGenerator& rng,
const std::string& hash_fn,
AlgorithmIdentifier& alg_id);
/**
* @verbatim
* Choose the default signature format for a certain public key signature
* scheme.
*
* The only option recognized by opts at this moment is "padding"
* Find an entry from src/build-data/oids.txt under [signature] of the form
* <sig_algo>/<padding>[(<hash_algo>)] and add {"padding",<padding>}
* to opts.
* @endverbatim
*
* @param key will be the key to choose a padding scheme for
* @param opts contains additional options for building the certificate
* @param rng the random generator to use
* @param hash_fn is the desired hash function
* @param alg_id will be set to the chosen scheme
* @return A PK_Signer object for generating signatures
*/
PK_Signer* choose_sig_format(const Private_Key& key,
const std::map<std::string,std::string>& opts,
RandomNumberGenerator& rng,
const std::string& hash_fn,
AlgorithmIdentifier& alg_id);
}
#endif
|