Botan  2.11.0
Crypto and TLS for C++11
x509self.cpp
Go to the documentation of this file.
1 /*
2 * PKCS #10/Self Signed Cert Creation
3 * (C) 1999-2008,2018 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/x509self.h>
9 #include <botan/x509_ext.h>
10 #include <botan/x509_ca.h>
11 #include <botan/der_enc.h>
12 #include <botan/pubkey.h>
13 #include <botan/oids.h>
14 #include <botan/hash.h>
15 
16 namespace Botan {
17 
18 namespace {
19 
20 /*
21 * Load information from the X509_Cert_Options
22 */
23 void load_info(const X509_Cert_Options& opts, X509_DN& subject_dn,
24  AlternativeName& subject_alt)
25  {
26  subject_dn.add_attribute("X520.CommonName", opts.common_name);
27  subject_dn.add_attribute("X520.Country", opts.country);
28  subject_dn.add_attribute("X520.State", opts.state);
29  subject_dn.add_attribute("X520.Locality", opts.locality);
30  subject_dn.add_attribute("X520.Organization", opts.organization);
31  subject_dn.add_attribute("X520.OrganizationalUnit", opts.org_unit);
32  for(auto extra_ou : opts.more_org_units) {
33  subject_dn.add_attribute("X520.OrganizationalUnit", extra_ou);
34  }
35 
36  subject_dn.add_attribute("X520.SerialNumber", opts.serial_number);
37  subject_alt = AlternativeName(opts.email, opts.uri, opts.dns, opts.ip);
38  subject_alt.add_othername(OIDS::lookup("PKIX.XMPPAddr"),
39  opts.xmpp, UTF8_STRING);
40 
41  for(auto dns : opts.more_dns)
42  subject_alt.add_attribute("DNS", dns);
43  }
44 }
45 
46 namespace X509 {
47 
48 /*
49 * Create a new self-signed X.509 certificate
50 */
52  const Private_Key& key,
53  const std::string& hash_fn,
55  {
56  AlgorithmIdentifier sig_algo;
57  X509_DN subject_dn;
58  AlternativeName subject_alt;
59 
60  // for now, only the padding option is used
61  std::map<std::string,std::string> sig_opts = { {"padding",opts.padding_scheme} };
62 
63  const std::vector<uint8_t> pub_key = X509::BER_encode(key);
64  std::unique_ptr<PK_Signer> signer(choose_sig_format(key, sig_opts, rng, hash_fn, sig_algo));
65  load_info(opts, subject_dn, subject_alt);
66 
67  Extensions extensions = opts.extensions;
68 
69  Key_Constraints constraints;
70  if(opts.is_CA)
71  {
72  constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
73  }
74  else
75  {
77  constraints = opts.constraints;
78  }
79 
80  extensions.add_new(
82  true);
83 
84  if(constraints != NO_CONSTRAINTS)
85  {
86  extensions.add_new(new Cert_Extension::Key_Usage(constraints), true);
87  }
88 
89  std::unique_ptr<Cert_Extension::Subject_Key_ID> skid(new Cert_Extension::Subject_Key_ID(pub_key, hash_fn));
90 
91  extensions.add_new(new Cert_Extension::Authority_Key_ID(skid->get_key_id()));
92  extensions.add_new(skid.release());
93 
94  extensions.add_new(
96 
97  extensions.add_new(
99 
100  return X509_CA::make_cert(signer.get(), rng, sig_algo, pub_key,
101  opts.start, opts.end,
102  subject_dn, subject_dn,
103  extensions);
104  }
105 
106 /*
107 * Create a PKCS #10 certificate request
108 */
110  const Private_Key& key,
111  const std::string& hash_fn,
113  {
114  X509_DN subject_dn;
115  AlternativeName subject_alt;
116  load_info(opts, subject_dn, subject_alt);
117 
118  Key_Constraints constraints;
119  if(opts.is_CA)
120  {
121  constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
122  }
123  else
124  {
126  constraints = opts.constraints;
127  }
128 
129  Extensions extensions = opts.extensions;
130 
131  extensions.add_new(new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit));
132 
133  if(constraints != NO_CONSTRAINTS)
134  {
135  extensions.add_new(new Cert_Extension::Key_Usage(constraints));
136  }
138  extensions.add_new(new Cert_Extension::Subject_Alternative_Name(subject_alt));
139 
140  return PKCS10_Request::create(key,
141  subject_dn,
142  extensions,
143  hash_fn,
144  rng,
145  opts.padding_scheme,
146  opts.challenge);
147  }
148 
149 }
150 
151 }
PKCS10_Request create_cert_req(const X509_Cert_Options &opts, const Private_Key &key, const std::string &hash_fn, RandomNumberGenerator &rng)
Definition: x509self.cpp:109
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:150
static PKCS10_Request create(const Private_Key &key, const X509_DN &subject_dn, const Extensions &extensions, const std::string &hash_fn, RandomNumberGenerator &rng, const std::string &padding_scheme="", const std::string &challenge="")
Definition: pkcs10.cpp:58
std::vector< uint8_t > BER_encode(const Public_Key &key)
Definition: x509_key.cpp:19
bool add_new(Certificate_Extension *extn, bool critical=false)
Definition: x509_ext.cpp:135
Key_Constraints constraints
Definition: x509self.h:126
std::string padding_scheme
Definition: x509self.h:121
X509_Certificate create_self_signed_cert(const X509_Cert_Options &opts, const Private_Key &key, const std::string &hash_fn, RandomNumberGenerator &rng)
Definition: x509self.cpp:51
Definition: alg_id.cpp:13
void verify_cert_constraints_valid_for_key_type(const Public_Key &pub_key, Key_Constraints constraints)
PK_Signer * choose_sig_format(const Private_Key &key, RandomNumberGenerator &rng, const std::string &hash_fn, AlgorithmIdentifier &sig_algo)
Definition: x509_ca.cpp:318
std::vector< OID > ex_constraints
Definition: x509self.h:131
std::string lookup(const OID &oid)
Definition: oids.cpp:113
std::string challenge
Definition: x509self.h:100