monotone

monotone Mtn Source Tree

Root/botan/x509_ca.cpp

1/*************************************************
2* X.509 Certificate Authority Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/x509_ca.h>
7#include <botan/x509stor.h>
8#include <botan/conf.h>
9#include <botan/lookup.h>
10#include <botan/look_pk.h>
11#include <botan/numthry.h>
12#include <botan/oids.h>
13#include <botan/util.h>
14#include <memory>
15#include <set>
16
17namespace Botan {
18
19namespace {
20
21/*************************************************
22* Load the certificate and private key *
23*************************************************/
24MemoryVector<byte> make_SKID(const MemoryRegion<byte>& pub_key)
25 {
26 std::auto_ptr<HashFunction> hash(get_hash("SHA-1"));
27 return hash->process(pub_key);
28 }
29
30}
31
32/*************************************************
33* Load the certificate and private key *
34*************************************************/
35X509_CA::X509_CA(const X509_Certificate& c,
36 const PKCS8_PrivateKey& key) : cert(c)
37 {
38 const PKCS8_PrivateKey* key_pointer = &key;
39 if(!dynamic_cast<const PK_Signing_Key*>(key_pointer))
40 throw Invalid_Argument("X509_CA: " + key.algo_name() + " cannot sign");
41
42 if(!cert.is_CA_cert())
43 throw Invalid_Argument("X509_CA: This certificate is not for a CA");
44
45 std::string padding;
46 Signature_Format format;
47
48 Config::choose_sig_format(key.algo_name(), padding, format);
49
50 ca_sig_algo.oid = OIDS::lookup(key.algo_name() + "/" + padding);
51 ca_sig_algo.parameters = key.DER_encode_params();
52
53 const PK_Signing_Key& sig_key = dynamic_cast<const PK_Signing_Key&>(key);
54 signer = get_pk_signer(sig_key, padding, format);
55 }
56
57/*************************************************
58* Sign a PKCS #10 certificate request *
59*************************************************/
60X509_Certificate X509_CA::sign_request(const PKCS10_Request& req,
61 u32bit expire_time) const
62 {
63 if(req.is_CA() && !Config::get_bool("x509/ca/allow_ca"))
64 throw Policy_Violation("X509_CA: Attempted to sign new CA certificate");
65
66 Key_Constraints constraints;
67 if(req.is_CA())
68 constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
69 else
70 {
71 std::auto_ptr<X509_PublicKey> key(req.subject_public_key());
72 constraints = X509::find_constraints(*key, req.constraints());
73 }
74
75 if(expire_time == 0)
76 expire_time = Config::get_time("x509/ca/default_expire");
77
78 const u64bit current_time = system_time();
79
80 X509_Time not_before(current_time);
81 X509_Time not_after(current_time + expire_time);
82
83 return make_cert(signer, ca_sig_algo, req.raw_public_key(),
84 cert.subject_key_id(), not_before, not_after,
85 cert.subject_dn(), req.subject_dn(),
86 req.is_CA(), req.path_limit(), req.subject_alt_name(),
87 constraints, req.ex_constraints());
88 }
89
90/*************************************************
91* Create a new certificate *
92*************************************************/
93X509_Certificate X509_CA::make_cert(PK_Signer* signer,
94 const AlgorithmIdentifier& sig_algo,
95 const MemoryRegion<byte>& pub_key,
96 const MemoryRegion<byte>& auth_key_id,
97 const X509_Time& not_before,
98 const X509_Time& not_after,
99 const X509_DN& issuer_dn,
100 const X509_DN& subject_dn,
101 bool is_CA, u32bit path_limit,
102 const AlternativeName& subject_alt,
103 Key_Constraints constraints,
104 const std::vector<OID>& ex_constraints)
105 {
106 const u32bit X509_CERT_VERSION = 2;
107 const u32bit SERIAL_BITS = 128;
108
109 DER_Encoder tbs_cert;
110
111 tbs_cert.start_sequence();
112 tbs_cert.start_explicit(ASN1_Tag(0));
113 DER::encode(tbs_cert, X509_CERT_VERSION);
114 tbs_cert.end_explicit(ASN1_Tag(0));
115
116 DER::encode(tbs_cert, random_integer(SERIAL_BITS, Nonce));
117 DER::encode(tbs_cert, sig_algo);
118 DER::encode(tbs_cert, issuer_dn);
119 tbs_cert.start_sequence();
120 DER::encode(tbs_cert, not_before);
121 DER::encode(tbs_cert, not_after);
122 tbs_cert.end_sequence();
123 DER::encode(tbs_cert, subject_dn);
124 tbs_cert.add_raw_octets(pub_key);
125
126 tbs_cert.start_explicit(ASN1_Tag(3));
127 tbs_cert.start_sequence();
128
129 DER_Encoder v3_ext;
130
131 DER::encode(v3_ext, make_SKID(pub_key), OCTET_STRING);
132 do_ext(tbs_cert, v3_ext, "X509v3.SubjectKeyIdentifier", "subject_key_id");
133
134 if(auth_key_id.size())
135 {
136 v3_ext.start_sequence();
137 DER::encode(v3_ext, auth_key_id, OCTET_STRING,
138 ASN1_Tag(0), CONTEXT_SPECIFIC);
139 v3_ext.end_sequence();
140 do_ext(tbs_cert, v3_ext, "X509v3.AuthorityKeyIdentifier",
141 "authority_key_id");
142 }
143
144 if(is_CA || (Config::get_string("x509/ca/basic_constraints") == "always"))
145 {
146 v3_ext.start_sequence();
147 if(is_CA)
148 {
149 DER::encode(v3_ext, true);
150 if(path_limit != NO_CERT_PATH_LIMIT)
151 DER::encode(v3_ext, path_limit);
152 }
153 v3_ext.end_sequence();
154 do_ext(tbs_cert, v3_ext, "X509v3.BasicConstraints", "basic_constraints");
155 }
156
157 if(subject_alt.has_items())
158 {
159 DER::encode(v3_ext, subject_alt);
160 do_ext(tbs_cert, v3_ext, "X509v3.SubjectAlternativeName",
161 "subject_alternative_name");
162 }
163
164 if(constraints != NO_CONSTRAINTS)
165 {
166 DER::encode(v3_ext, constraints);
167 do_ext(tbs_cert, v3_ext, "X509v3.KeyUsage", "key_usage");
168 }
169
170 if(ex_constraints.size())
171 {
172 v3_ext.start_sequence();
173 for(u32bit j = 0; j != ex_constraints.size(); j++)
174 DER::encode(v3_ext, ex_constraints[j]);
175 v3_ext.end_sequence();
176 do_ext(tbs_cert, v3_ext, "X509v3.ExtendedKeyUsage",
177 "extended_key_usage");
178 }
179
180 tbs_cert.end_sequence();
181 tbs_cert.end_explicit(ASN1_Tag(3));
182 tbs_cert.end_sequence();
183
184 MemoryVector<byte> tbs_bits = tbs_cert.get_contents();
185 MemoryVector<byte> sig = signer->sign_message(tbs_bits);
186
187 DER_Encoder full_cert;
188 full_cert.start_sequence();
189 full_cert.add_raw_octets(tbs_bits);
190 DER::encode(full_cert, sig_algo);
191 DER::encode(full_cert, sig, BIT_STRING);
192 full_cert.end_sequence();
193
194 DataSource_Memory source(full_cert.get_contents());
195
196 return X509_Certificate(source);
197 }
198
199/*************************************************
200* Handle encoding a v3 extension *
201*************************************************/
202void X509_CA::do_ext(DER_Encoder& new_cert, DER_Encoder& extension,
203 const std::string& oid, const std::string& opt)
204 {
205 std::string EXT_SETTING = "yes";
206
207 if(opt != "")
208 {
209 EXT_SETTING = Config::get_string("x509/exts/" + opt);
210
211 if(EXT_SETTING == "")
212 throw Exception("X509_CA: No policy setting for using " + oid);
213 }
214
215 if(EXT_SETTING == "no")
216 return;
217 else if(EXT_SETTING == "yes" || EXT_SETTING == "noncritical" ||
218 EXT_SETTING == "critical")
219 {
220 Extension extn(oid, extension.get_contents());
221 if(EXT_SETTING == "critical")
222 extn.critical = true;
223 DER::encode(new_cert, extn);
224 }
225 else
226 throw Invalid_Argument("X509_CA:: Invalid value for option x509/exts/" +
227 opt + " of " + EXT_SETTING);
228 }
229
230/*************************************************
231* Create a new, empty CRL *
232*************************************************/
233X509_CRL X509_CA::new_crl(u32bit next_update) const
234 {
235 std::vector<CRL_Entry> empty;
236 return make_crl(empty, 1, next_update);
237 }
238
239/*************************************************
240* Update a CRL with new entries *
241*************************************************/
242X509_CRL X509_CA::update_crl(const X509_CRL& crl,
243 const std::vector<CRL_Entry>& new_revoked,
244 u32bit next_update) const
245 {
246 std::vector<CRL_Entry> already_revoked = crl.get_revoked();
247 std::vector<CRL_Entry> all_revoked;
248
249 X509_Store store;
250 store.add_cert(cert, true);
251 if(store.add_crl(crl) != VERIFIED)
252 throw Invalid_Argument("X509_CA::update_crl: Invalid CRL provided");
253
254 std::set<SecureVector<byte> > removed_from_crl;
255 for(u32bit j = 0; j != new_revoked.size(); j++)
256 {
257 if(new_revoked[j].reason == DELETE_CRL_ENTRY)
258 removed_from_crl.insert(new_revoked[j].serial);
259 else
260 all_revoked.push_back(new_revoked[j]);
261 }
262
263 for(u32bit j = 0; j != already_revoked.size(); j++)
264 {
265 std::set<SecureVector<byte> >::const_iterator i;
266 i = removed_from_crl.find(already_revoked[j].serial);
267
268 if(i == removed_from_crl.end())
269 all_revoked.push_back(already_revoked[j]);
270 }
271 std::sort(all_revoked.begin(), all_revoked.end());
272
273 std::vector<CRL_Entry> cert_list;
274 std::unique_copy(all_revoked.begin(), all_revoked.end(),
275 std::back_inserter(cert_list));
276
277 return make_crl(cert_list, crl.crl_number() + 1, next_update);
278 }
279
280/*************************************************
281* Create a CRL *
282*************************************************/
283X509_CRL X509_CA::make_crl(const std::vector<CRL_Entry>& revoked,
284 u32bit crl_number, u32bit next_update) const
285 {
286 const u32bit X509_CRL_VERSION = 1;
287
288 if(next_update == 0)
289 next_update = Config::get_time("x509/crl/next_update");
290
291 DER_Encoder tbs_crl;
292
293 const u64bit current_time = system_time();
294
295 tbs_crl.start_sequence();
296 DER::encode(tbs_crl, X509_CRL_VERSION);
297 DER::encode(tbs_crl, ca_sig_algo);
298 DER::encode(tbs_crl, cert.subject_dn());
299 DER::encode(tbs_crl, X509_Time(current_time));
300 DER::encode(tbs_crl, X509_Time(current_time + next_update));
301
302 if(revoked.size())
303 {
304 tbs_crl.start_sequence();
305 for(u32bit j = 0; j != revoked.size(); j++)
306 DER::encode(tbs_crl, revoked[j]);
307 tbs_crl.end_sequence();
308 }
309
310 tbs_crl.start_explicit(ASN1_Tag(0));
311 tbs_crl.start_sequence();
312
313 DER_Encoder crl_ext;
314
315 if(cert.subject_key_id().size())
316 {
317 crl_ext.start_sequence();
318 crl_ext.start_explicit(ASN1_Tag(0));
319 DER::encode(crl_ext, cert.subject_key_id(), OCTET_STRING);
320 crl_ext.end_explicit(ASN1_Tag(0));
321 crl_ext.end_sequence();
322 do_ext(tbs_crl, crl_ext, "X509v3.AuthorityKeyIdentifier",
323 "authority_key_id");
324 }
325
326 if(crl_number)
327 {
328 DER::encode(crl_ext, crl_number);
329 do_ext(tbs_crl, crl_ext, "X509v3.CRLNumber", "crl_number");
330 }
331
332 tbs_crl.end_sequence();
333 tbs_crl.end_explicit(ASN1_Tag(0));
334 tbs_crl.end_sequence();
335
336 MemoryVector<byte> tbs_bits = tbs_crl.get_contents();
337 MemoryVector<byte> sig = signer->sign_message(tbs_bits);
338
339 DER_Encoder full_crl;
340 full_crl.start_sequence();
341 full_crl.add_raw_octets(tbs_bits);
342 DER::encode(full_crl, ca_sig_algo);
343 DER::encode(full_crl, sig, BIT_STRING);
344 full_crl.end_sequence();
345
346 DataSource_Memory source(full_crl.get_contents());
347
348 return X509_CRL(source);
349 }
350
351/*************************************************
352* Return the CA's certificate *
353*************************************************/
354X509_Certificate X509_CA::ca_certificate() const
355 {
356 return cert;
357 }
358
359/*************************************************
360* X509_CA Destructor *
361*************************************************/
362X509_CA::~X509_CA()
363 {
364 delete signer;
365 }
366
367}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status