Botan 1.10.17
x509_ca.cpp
Go to the documentation of this file.
1/*
2* X.509 Certificate Authority
3* (C) 1999-2010 Jack Lloyd
4*
5* Distributed under the terms of the Botan license
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/lookup.h>
15#include <botan/oids.h>
16#include <botan/time.h>
17#include <algorithm>
18#include <typeinfo>
19#include <iterator>
20#include <memory>
21#include <set>
22
23namespace Botan {
24
25/*
26* Load the certificate and private key
27*/
29 const Private_Key& key,
30 const std::string& hash_fn) : cert(c)
31 {
32 if(!cert.is_CA_cert())
33 throw Invalid_Argument("X509_CA: This certificate is not for a CA");
34
35 signer = choose_sig_format(key, hash_fn, ca_sig_algo);
36 }
37
38/*
39* X509_CA Destructor
40*/
42 {
43 delete signer;
44 }
45
46/*
47* Sign a PKCS #10 certificate request
48*/
51 const X509_Time& not_before,
52 const X509_Time& not_after)
53 {
54 Key_Constraints constraints;
55 if(req.is_CA())
56 constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
57 else
58 {
59 std::auto_ptr<Public_Key> key(req.subject_public_key());
60 constraints = X509::find_constraints(*key, req.constraints());
61 }
62
63 Extensions extensions;
64
65 extensions.add(
67 true);
68
69 extensions.add(new Cert_Extension::Key_Usage(constraints), true);
70
71 extensions.add(new Cert_Extension::Authority_Key_ID(cert.subject_key_id()));
73
74 extensions.add(
76
77 extensions.add(
79
80 return make_cert(signer, rng, ca_sig_algo,
81 req.raw_public_key(),
82 not_before, not_after,
83 cert.subject_dn(), req.subject_dn(),
84 extensions);
85 }
86
87/*
88* Create a new certificate
89*/
92 const AlgorithmIdentifier& sig_algo,
93 const MemoryRegion<byte>& pub_key,
94 const X509_Time& not_before,
95 const X509_Time& not_after,
96 const X509_DN& issuer_dn,
97 const X509_DN& subject_dn,
98 const Extensions& extensions)
99 {
100 const size_t X509_CERT_VERSION = 3;
101 const size_t SERIAL_BITS = 128;
102
103 BigInt serial_no(rng, SERIAL_BITS);
104
105 DataSource_Memory source(X509_Object::make_signed(signer, rng, sig_algo,
106 DER_Encoder().start_cons(SEQUENCE)
107 .start_explicit(0)
108 .encode(X509_CERT_VERSION-1)
109 .end_explicit()
110
111 .encode(serial_no)
112
113 .encode(sig_algo)
114 .encode(issuer_dn)
115
116 .start_cons(SEQUENCE)
117 .encode(not_before)
118 .encode(not_after)
119 .end_cons()
120
121 .encode(subject_dn)
122 .raw_bytes(pub_key)
123
124 .start_explicit(3)
125 .start_cons(SEQUENCE)
126 .encode(extensions)
127 .end_cons()
128 .end_explicit()
129 .end_cons()
130 .get_contents()
131 ));
132
133 return X509_Certificate(source);
134 }
135
136/*
137* Create a new, empty CRL
138*/
140 u32bit next_update) const
141 {
142 std::vector<CRL_Entry> empty;
143 return make_crl(empty, 1, next_update, rng);
144 }
145
146/*
147* Update a CRL with new entries
148*/
150 const std::vector<CRL_Entry>& new_revoked,
152 u32bit next_update) const
153 {
154 std::vector<CRL_Entry> revoked = crl.get_revoked();
155
156 std::copy(new_revoked.begin(), new_revoked.end(),
157 std::back_inserter(revoked));
158
159 return make_crl(revoked, crl.crl_number() + 1, next_update, rng);
160 }
161
162/*
163* Create a CRL
164*/
165X509_CRL X509_CA::make_crl(const std::vector<CRL_Entry>& revoked,
166 u32bit crl_number, u32bit next_update,
167 RandomNumberGenerator& rng) const
168 {
169 const size_t X509_CRL_VERSION = 2;
170
171 if(next_update == 0)
172 next_update = timespec_to_u32bit("7d");
173
174 // Totally stupid: ties encoding logic to the return of std::time!!
175 const u64bit current_time = system_time();
176
177 Extensions extensions;
178 extensions.add(
180 extensions.add(new Cert_Extension::CRL_Number(crl_number));
181
182 DataSource_Memory source(X509_Object::make_signed(signer, rng, ca_sig_algo,
183 DER_Encoder().start_cons(SEQUENCE)
184 .encode(X509_CRL_VERSION-1)
185 .encode(ca_sig_algo)
186 .encode(cert.issuer_dn())
187 .encode(X509_Time(current_time))
188 .encode(X509_Time(current_time + next_update))
189 .encode_if(revoked.size() > 0,
191 .start_cons(SEQUENCE)
192 .encode_list(revoked)
193 .end_cons()
194 )
195 .start_explicit(0)
196 .start_cons(SEQUENCE)
197 .encode(extensions)
198 .end_cons()
199 .end_explicit()
200 .end_cons()
201 .get_contents()
202 ));
203
204 return X509_CRL(source);
205 }
206
207/*
208* Return the CA's certificate
209*/
211 {
212 return cert;
213 }
214
215/*
216* Choose a signing format for the key
217*/
219 const std::string& hash_fn,
220 AlgorithmIdentifier& sig_algo)
221 {
222 std::string padding;
223
224 const std::string algo_name = key.algo_name();
225
226 const HashFunction* proto_hash = retrieve_hash(hash_fn);
227 if(!proto_hash)
228 throw Algorithm_Not_Found(hash_fn);
229
230 if(key.max_input_bits() < proto_hash->output_length()*8)
231 throw Invalid_Argument("Key is too small for chosen hash function");
232
233 if(algo_name == "RSA")
234 padding = "EMSA3";
235 else if(algo_name == "DSA")
236 padding = "EMSA1";
237 else if(algo_name == "ECDSA")
238 padding = "EMSA1_BSI";
239 else
240 throw Invalid_Argument("Unknown X.509 signing key type: " + algo_name);
241
242 Signature_Format format =
243 (key.message_parts() > 1) ? DER_SEQUENCE : IEEE_1363;
244
245 padding = padding + '(' + proto_hash->name() + ')';
246
247 sig_algo.oid = OIDS::lookup(algo_name + "/" + padding);
249
250 return new PK_Signer(key, padding, format);
251 }
252
253}
SecureVector< byte > parameters
Definition alg_id.h:36
virtual std::string name() const =0
virtual size_t output_length() const =0
void add(Certificate_Extension *extn, bool critical=false)
Definition x509_ext.cpp:77
AlternativeName subject_alt_name() const
Definition pkcs10.cpp:157
MemoryVector< byte > raw_public_key() const
Definition pkcs10.cpp:139
Public_Key * subject_public_key() const
Definition pkcs10.cpp:148
X509_DN subject_dn() const
Definition pkcs10.cpp:131
std::vector< OID > ex_constraints() const
Definition pkcs10.cpp:173
Key_Constraints constraints() const
Definition pkcs10.cpp:165
bool is_CA() const
Definition pkcs10.cpp:186
u32bit path_limit() const
Definition pkcs10.cpp:194
PK_Signer(const Private_Key &key, const std::string &emsa, Signature_Format format=IEEE_1363, Fault_Protection prot=ENABLE_FAULT_PROTECTION)
Definition pubkey.cpp:128
virtual AlgorithmIdentifier algorithm_identifier() const =0
virtual size_t max_input_bits() const =0
virtual std::string algo_name() const =0
virtual size_t message_parts() const
Definition pk_keys.h:50
X509_CA(const X509_Certificate &ca_certificate, const Private_Key &key, const std::string &hash_fn)
Definition x509_ca.cpp:28
X509_CRL new_crl(RandomNumberGenerator &rng, u32bit next_update=0) const
Definition x509_ca.cpp:139
X509_Certificate sign_request(const PKCS10_Request &req, RandomNumberGenerator &rng, const X509_Time &not_before, const X509_Time &not_after)
Definition x509_ca.cpp:49
static X509_Certificate make_cert(PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &sig_algo, const MemoryRegion< byte > &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:90
X509_CRL update_crl(const X509_CRL &last_crl, const std::vector< CRL_Entry > &new_entries, RandomNumberGenerator &rng, u32bit next_update=0) const
Definition x509_ca.cpp:149
X509_Certificate ca_certificate() const
Definition x509_ca.cpp:210
u32bit crl_number() const
Definition x509_crl.cpp:126
X509_CRL(DataSource &source, bool throw_on_unknown_critical=false)
Definition x509_crl.cpp:20
std::vector< CRL_Entry > get_revoked() const
Definition x509_crl.cpp:102
X509_Certificate(DataSource &source)
Definition x509cert.cpp:47
X509_DN issuer_dn() const
Definition x509cert.cpp:274
MemoryVector< byte > subject_key_id() const
Definition x509cert.cpp:258
static MemoryVector< byte > make_signed(class PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &alg_id, const MemoryRegion< byte > &tbs)
Definition x509_obj.cpp:204
X509_Time(u64bit)
Definition asn1_tm.cpp:28
std::string lookup(const OID &oid)
Definition oids.cpp:31
Key_Constraints find_constraints(const Public_Key &pub_key, Key_Constraints limits)
Definition x509_key.cpp:113
PK_Signer * choose_sig_format(const Private_Key &key, const std::string &hash_fn, AlgorithmIdentifier &sig_algo)
Definition x509_ca.cpp:218
const HashFunction * retrieve_hash(const std::string &algo_spec)
Definition lookup.h:55
unsigned long long u64bit
Definition types.h:49
u64bit system_time()
Definition time.cpp:73
std::invalid_argument Invalid_Argument
Definition exceptn.h:20
@ SEQUENCE
Definition asn1_int.h:35
unsigned int u32bit
Definition types.h:32
u32bit timespec_to_u32bit(const std::string &timespec)
Definition parsing.cpp:65
Signature_Format
Definition pubkey.h:24
@ DER_SEQUENCE
Definition pubkey.h:24
@ IEEE_1363
Definition pubkey.h:24
Key_Constraints
@ KEY_CERT_SIGN
Algorithm_Not_Found(const std::string &name)
Definition exceptn.h:111