Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

x509_ca.cpp
Go to the documentation of this file.
1 /*
2 * X.509 Certificate Authority
3 * (C) 1999-2010 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/x509_ca.h>
9 #include <botan/pubkey.h>
10 #include <botan/der_enc.h>
11 #include <botan/ber_dec.h>
12 #include <botan/bigint.h>
13 #include <botan/parsing.h>
14 #include <botan/oids.h>
15 #include <botan/hash.h>
16 #include <botan/key_constraint.h>
17 #include <algorithm>
18 #include <typeinfo>
19 #include <iterator>
20 #include <set>
21
22 namespace Botan {
23
24 /*
25 * Load the certificate and private key
26 */
27 X509_CA::X509_CA(const X509_Certificate& c,
28 const Private_Key& key,
29 const std::string& hash_fn,
30 RandomNumberGenerator& rng) : m_cert(c)
31 {
32 if(!m_cert.is_CA_cert())
33 throw Invalid_Argument("X509_CA: This certificate is not for a CA");
34
35 m_signer = choose_sig_format(key, rng, hash_fn, m_ca_sig_algo);
36 }
37
38 /*
39 * X509_CA Destructor
40 */
41 X509_CA::~X509_CA()
42 {
43 delete m_signer;
44 }
45
46 /*
47 * Sign a PKCS #10 certificate request
48 */
49 X509_Certificate X509_CA::sign_request(const PKCS10_Request& req,
50 RandomNumberGenerator& rng,
51 const X509_Time& not_before,
52 const X509_Time& not_after) const
53 {
54 Key_Constraints constraints;
55 if(req.is_CA())
56 {
57 constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
58 }
59 else
60 {
61 std::unique_ptr<Public_Key> key(req.subject_public_key());
62 verify_cert_constraints_valid_for_key_type(*key, req.constraints());
63 constraints = req.constraints();
64 }
65
66 Extensions extensions = req.extensions();
67
68 extensions.replace(
69 new Cert_Extension::Basic_Constraints(req.is_CA(), req.path_limit()),
70 true);
71
72 if(constraints != NO_CONSTRAINTS)
73 {
74 extensions.replace(new Cert_Extension::Key_Usage(constraints), true);
75 }
76
77 extensions.replace(new Cert_Extension::Authority_Key_ID(m_cert.subject_key_id()));
78 extensions.replace(new Cert_Extension::Subject_Key_ID(req.raw_public_key()));
79
80 extensions.replace(
81 new Cert_Extension::Subject_Alternative_Name(req.subject_alt_name()));
82
83 extensions.replace(
84 new Cert_Extension::Extended_Key_Usage(req.ex_constraints()));
85
86 return make_cert(m_signer, rng, m_ca_sig_algo,
87 req.raw_public_key(),
88 not_before, not_after,
89 m_cert.subject_dn(), req.subject_dn(),
90 extensions);
91 }
92
93 /*
94 * Create a new certificate
95 */
96 X509_Certificate X509_CA::make_cert(PK_Signer* signer,
97 RandomNumberGenerator& rng,
98 const AlgorithmIdentifier& sig_algo,
99 const std::vector<uint8_t>& pub_key,
100 const X509_Time& not_before,
101 const X509_Time& not_after,
102 const X509_DN& issuer_dn,
103 const X509_DN& subject_dn,
104 const Extensions& extensions)
105 {
106 const size_t X509_CERT_VERSION = 3;
107 const size_t SERIAL_BITS = 128;
108
109 BigInt serial_no(rng, SERIAL_BITS);
110
111 // clang-format off
112 return X509_Certificate(X509_Object::make_signed(
113 signer, rng, sig_algo,
114 DER_Encoder().start_cons(SEQUENCE)
115 .start_explicit(0)
116 .encode(X509_CERT_VERSION-1)
117 .end_explicit()
118
119 .encode(serial_no)
120
121 .encode(sig_algo)
122 .encode(issuer_dn)
123
124 .start_cons(SEQUENCE)
125 .encode(not_before)
126 .encode(not_after)
127 .end_cons()
128
129 .encode(subject_dn)
130 .raw_bytes(pub_key)
131
132 .start_explicit(3)
133 .start_cons(SEQUENCE)
134 .encode(extensions)
135 .end_cons()
136 .end_explicit()
137 .end_cons()
138 .get_contents()
139 ));;
140 // clang-format on
141 }
142
143 /*
144 * Create a new, empty CRL
145 */
146 X509_CRL X509_CA::new_crl(RandomNumberGenerator& rng,
147 uint32_t next_update) const
148 {
149 std::vector<CRL_Entry> empty;
150 return make_crl(empty, 1, next_update, rng);
151 }
152
153 /*
154 * Update a CRL with new entries
155 */
156 X509_CRL X509_CA::update_crl(const X509_CRL& crl,
157 const std::vector<CRL_Entry>& new_revoked,
158 RandomNumberGenerator& rng,
159 uint32_t next_update) const
160 {
161 std::vector<CRL_Entry> revoked = crl.get_revoked();
162
163 std::copy(new_revoked.begin(), new_revoked.end(),
164 std::back_inserter(revoked));
165
166 return make_crl(revoked, crl.crl_number() + 1, next_update, rng);
167 }
168
169 /*
170 * Create a CRL
171 */
172 X509_CRL X509_CA::make_crl(const std::vector<CRL_Entry>& revoked,
173 uint32_t crl_number, uint32_t next_update,
174 RandomNumberGenerator& rng) const
175 {
176 const size_t X509_CRL_VERSION = 2;
177
178 if(next_update == 0)
179 next_update = timespec_to_u32bit("7d");
180
181 // Totally stupid: ties encoding logic to the return of std::time!!
182 auto current_time = std::chrono::system_clock::now();
183 auto expire_time = current_time + std::chrono::seconds(next_update);
184
185 Extensions extensions;
186 extensions.add(
187 new Cert_Extension::Authority_Key_ID(m_cert.subject_key_id()));
188 extensions.add(new Cert_Extension::CRL_Number(crl_number));
189
190 // clang-format off
191 const std::vector<uint8_t> crl = X509_Object::make_signed(
192 m_signer, rng, m_ca_sig_algo,
193 DER_Encoder().start_cons(SEQUENCE)
194 .encode(X509_CRL_VERSION-1)
195 .encode(m_ca_sig_algo)
196 .encode(m_cert.issuer_dn())
197 .encode(X509_Time(current_time))
198 .encode(X509_Time(expire_time))
199 .encode_if(revoked.size() > 0,
200 DER_Encoder()
201 .start_cons(SEQUENCE)
202 .encode_list(revoked)
203 .end_cons()
204 )
205 .start_explicit(0)
206 .start_cons(SEQUENCE)
207 .encode(extensions)
208 .end_cons()
209 .end_explicit()
210 .end_cons()
211 .get_contents());
212 // clang-format on
213
214 return X509_CRL(crl);
215 }
216
217 /*
218 * Return the CA's certificate
219 */
220 X509_Certificate X509_CA::ca_certificate() const
221 {
222 return m_cert;
223 }
224
225 /*
226 * Choose a signing format for the key
227 */
228 PK_Signer* choose_sig_format(const Private_Key& key,
229 RandomNumberGenerator& rng,
230 const std::string& hash_fn,
231 AlgorithmIdentifier& sig_algo)
232 {
233 const std::string algo_name = key.algo_name();
234
235 std::unique_ptr<HashFunction> hash(HashFunction::create_or_throw(hash_fn));
236
237 std::string padding;
238 if(algo_name == "RSA")
239 {
240 padding = "EMSA3";
241 }
242 else if(algo_name == "DSA" ||
243 algo_name == "ECDSA" ||
244 algo_name == "ECGDSA" ||
245 algo_name == "ECKCDSA" ||
246 algo_name == "GOST-34.10")
247 {
248 padding = "EMSA1";
249 }
250 else
251 {
252 throw Invalid_Argument("Unknown X.509 signing key type: " + algo_name);
253 }
254
255 const Signature_Format format = (key.message_parts() > 1) ? DER_SEQUENCE : IEEE_1363;
256
257 padding = padding + "(" + hash->name() + ")";
258
259 sig_algo.oid = OIDS::lookup(algo_name + "/" + padding);
260 sig_algo.parameters = key.algorithm_identifier().parameters;
261
262 return new PK_Signer(key, rng, padding, format);
263 }
264
265 }
Botan::Cert_Extension::Key_Usage
Definition: x509_ext.h:209
Botan::Invalid_Argument
Definition: exceptn.h:34
Botan::DER_Encoder::encode_list
DER_Encoder & encode_list(const std::vector< T > &values)
Definition: der_enc.h:85
Botan::X509_CA::make_cert
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)
Definition: x509_ca.cpp:96
Botan::PKCS10_Request::extensions
Extensions extensions() const
Definition: pkcs10.cpp:228
Botan::HashFunction::create_or_throw
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:303
Botan::BigInt
Definition: bigint.h:23
Botan::X509_CA::~X509_CA
~X509_CA()
Definition: x509_ca.cpp:41
Botan::PKCS10_Request::path_limit
size_t path_limit() const
Definition: pkcs10.cpp:211
Botan::PKCS10_Request::ex_constraints
std::vector< OID > ex_constraints() const
Definition: pkcs10.cpp:185
Botan::RandomNumberGenerator
Definition: rng.h:25
Botan::AlgorithmIdentifier::parameters
std::vector< uint8_t > parameters
Definition: alg_id.h:39
Botan::PKCS10_Request::subject_public_key
Public_Key * subject_public_key() const
Definition: pkcs10.cpp:155
Botan::Private_Key
Definition: pk_keys.h:166
Botan::PKCS10_Request::is_CA
bool is_CA() const
Definition: pkcs10.cpp:198
Botan::Public_Key::algorithm_identifier
virtual AlgorithmIdentifier algorithm_identifier() const =0
Botan::PEM_Code::encode
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
Botan::X509_CA::new_crl
X509_CRL new_crl(RandomNumberGenerator &rng, uint32_t next_update=0) const
Definition: x509_ca.cpp:146
Botan::X509_Object::make_signed
static std::vector< uint8_t > make_signed(class PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &tbs)
Definition: x509_obj.cpp:214
Botan::Signature_Format
Signature_Format
Definition: pubkey.h:29
Botan::Cert_Extension::Subject_Alternative_Name
Definition: x509_ext.h:309
Botan::X509_Certificate::is_CA_cert
bool is_CA_cert() const
Definition: x509cert.cpp:252
Botan::Extensions::replace
void replace(Certificate_Extension *extn, bool critical=false)
Definition: x509_ext.cpp:111
Botan::Public_Key::algo_name
virtual std::string algo_name() const =0
Botan::Extensions
Definition: x509_ext.h:86
Botan::Cert_Extension::Extended_Key_Usage
Definition: x509_ext.h:333
Botan::Cert_Extension::Subject_Key_ID
Definition: x509_ext.h:233
Botan::DER_Encoder::end_cons
DER_Encoder & end_cons()
Definition: der_enc.cpp:147
Botan::Cert_Extension::Basic_Constraints
Definition: x509_ext.h:182
Botan::verify_cert_constraints_valid_for_key_type
void verify_cert_constraints_valid_for_key_type(const Public_Key &pub_key, Key_Constraints constraints)
Definition: key_constraint.cpp:69
Botan::Extensions::add
void add(Certificate_Extension *extn, bool critical=false)
Definition: x509_ext.cpp:91
Botan::NO_CONSTRAINTS
Definition: key_constraint.h:22
Botan::X509_CA::X509_CA
X509_CA(const X509_Certificate &ca_certificate, const Private_Key &key, const std::string &hash_fn, RandomNumberGenerator &rng)
Definition: x509_ca.cpp:27
Botan::DER_Encoder
Definition: der_enc.h:22
Botan::CRL_SIGN
Definition: key_constraint.h:29
Botan::X509_Certificate
Definition: x509cert.h:36
Botan::PKCS10_Request::subject_alt_name
AlternativeName subject_alt_name() const
Definition: pkcs10.cpp:164
Botan::OIDS::lookup
std::string lookup(const OID &oid)
Definition: oids.cpp:18
Botan::Public_Key::message_parts
virtual size_t message_parts() const
Definition: pk_keys.h:103
Botan::AlgorithmIdentifier::oid
OID oid
Definition: alg_id.h:36
Botan::X509_CA::ca_certificate
X509_Certificate ca_certificate() const
Definition: x509_ca.cpp:220
Botan::X509_DN
Definition: x509_dn.h:22
Botan::SEQUENCE
Definition: asn1_obj.h:39
Botan::PKCS10_Request
Definition: pkcs10.h:26
Botan::X509_CA::update_crl
X509_CRL update_crl(const X509_CRL &last_crl, const std::vector< CRL_Entry > &new_entries, RandomNumberGenerator &rng, uint32_t next_update=0) const
Definition: x509_ca.cpp:156
Botan::PKCS10_Request::subject_dn
X509_DN subject_dn() const
Definition: pkcs10.cpp:138
Botan
Definition: alg_id.cpp:13
Botan::PKCS10_Request::constraints
Key_Constraints constraints() const
Definition: pkcs10.cpp:172
Botan::IEEE_1363
Definition: pubkey.h:29
Botan::PKCS10_Request::raw_public_key
std::vector< uint8_t > raw_public_key() const
Definition: pkcs10.cpp:146
Botan::X509_CRL::get_revoked
std::vector< CRL_Entry > get_revoked() const
Definition: x509_crl.cpp:157
Botan::X509_CA::sign_request
X509_Certificate sign_request(const PKCS10_Request &req, RandomNumberGenerator &rng, const X509_Time &not_before, const X509_Time &not_after) const
Definition: x509_ca.cpp:49
Botan::choose_sig_format
PK_Signer * choose_sig_format(const Private_Key &key, RandomNumberGenerator &rng, const std::string &hash_fn, AlgorithmIdentifier &sig_algo)
Definition: x509_ca.cpp:228
Botan::Cert_Extension::CRL_Number
Definition: x509_ext.h:439
Botan::X509_Certificate::issuer_dn
X509_DN issuer_dn() const
Definition: x509cert.cpp:432
Botan::AlgorithmIdentifier
Definition: alg_id.h:20
Botan::DER_Encoder::start_cons
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:137
Botan::DER_SEQUENCE
Definition: pubkey.h:29
Botan::Cert_Extension::Authority_Key_ID
Definition: x509_ext.h:258
Botan::X509_Certificate::subject_key_id
std::vector< uint8_t > subject_key_id() const
Definition: x509cert.cpp:419
Botan::X509_CRL
Definition: x509_crl.h:24
Botan::timespec_to_u32bit
uint32_t timespec_to_u32bit(const std::string &timespec)
Definition: parsing.cpp:54
Botan::PK_Signer
Definition: pubkey.h:161
Botan::X509_Certificate::subject_dn
X509_DN subject_dn() const
Definition: x509cert.cpp:449
Botan::Key_Constraints
Key_Constraints
Definition: key_constraint.h:21
hash
MechanismType hash
Definition: p11_mechanism.cpp:63
Botan::X509_Time
Definition: asn1_time.h:19
Botan::KEY_CERT_SIGN
Definition: key_constraint.h:28
Botan::X509_CRL::crl_number
uint32_t crl_number() const
Definition: x509_crl.cpp:181