Botan  1.11.34
Crypto and TLS for C++11
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 */
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 */
42  {
43  delete m_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  {
57  constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
58  }
59  else
60  {
61  std::unique_ptr<Public_Key> key(req.subject_public_key());
63  constraints = req.constraints();
64  }
65 
66  Extensions extensions;
67 
68  extensions.add(
70  true);
71 
72  if(constraints != NO_CONSTRAINTS)
73  {
74  extensions.add(new Cert_Extension::Key_Usage(constraints), true);
75  }
76 
77  extensions.add(new Cert_Extension::Authority_Key_ID(m_cert.subject_key_id()));
78  extensions.add(new Cert_Extension::Subject_Key_ID(req.raw_public_key()));
79 
80  extensions.add(
82 
83  extensions.add(
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 */
98  const AlgorithmIdentifier& sig_algo,
99  const std::vector<byte>& 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
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 */
147  u32bit 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 */
157  const std::vector<CRL_Entry>& new_revoked,
159  u32bit 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  u32bit crl_number, u32bit 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(
188  extensions.add(new Cert_Extension::CRL_Number(crl_number));
189 
190  // clang-format off
191  const std::vector<byte> 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()
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 */
221  {
222  return m_cert;
223  }
224 
225 /*
226 * Choose a signing format for the key
227 */
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 }
X509_DN issuer_dn() const
Definition: x509cert.cpp:433
std::vector< byte > raw_public_key() const
Definition: pkcs10.cpp:150
X509_DN subject_dn() const
Definition: x509cert.cpp:443
DER_Encoder & encode_list(const std::vector< T > &values)
Definition: der_enc.h:85
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:303
virtual AlgorithmIdentifier algorithm_identifier() const =0
u32bit crl_number() const
Definition: x509_crl.cpp:181
AlternativeName subject_alt_name() const
Definition: pkcs10.cpp:168
X509_Certificate ca_certificate() const
Definition: x509_ca.cpp:220
Signature_Format
Definition: pubkey.h:29
virtual std::string algo_name() const =0
std::uint32_t u32bit
Definition: types.h:33
DER_Encoder & end_cons()
Definition: der_enc.cpp:147
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:156
void verify_cert_constraints_valid_for_key_type(const Public_Key &pub_key, Key_Constraints constraints)
bool is_CA_cert() const
Definition: x509cert.cpp:253
void add(Certificate_Extension *extn, bool critical=false)
Definition: x509_ext.cpp:91
X509_CA(const X509_Certificate &ca_certificate, const Private_Key &key, const std::string &hash_fn, RandomNumberGenerator &rng)
Definition: x509_ca.cpp:27
std::vector< byte > parameters
Definition: alg_id.h:39
static std::vector< byte > make_signed(class PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &alg_id, const secure_vector< byte > &tbs)
Definition: x509_obj.cpp:215
std::string lookup(const OID &oid)
Definition: oids.cpp:18
std::vector< CRL_Entry > get_revoked() const
Definition: x509_crl.cpp:157
bool is_CA() const
Definition: pkcs10.cpp:197
Key_Constraints constraints() const
Definition: pkcs10.cpp:176
Definition: alg_id.cpp:13
std::vector< byte > subject_key_id() const
Definition: x509cert.cpp:420
PK_Signer * choose_sig_format(const Private_Key &key, RandomNumberGenerator &rng, const std::string &hash_fn, AlgorithmIdentifier &sig_algo)
Definition: x509_ca.cpp:228
std::string encode(const byte der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
static X509_Certificate make_cert(PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &sig_algo, const std::vector< 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:96
u32bit path_limit() const
Definition: pkcs10.cpp:205
u32bit timespec_to_u32bit(const std::string &timespec)
Definition: parsing.cpp:54
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:137
X509_DN subject_dn() const
Definition: pkcs10.cpp:142
Public_Key * subject_public_key() const
Definition: pkcs10.cpp:159
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
X509_CRL new_crl(RandomNumberGenerator &rng, u32bit next_update=0) const
Definition: x509_ca.cpp:146
MechanismType hash
virtual size_t message_parts() const
Definition: pk_keys.h:95
std::vector< OID > ex_constraints() const
Definition: pkcs10.cpp:184