Botan  2.4.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 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 
15 namespace Botan {
16 
17 namespace {
18 
19 /*
20 * Load information from the X509_Cert_Options
21 */
22 void load_info(const X509_Cert_Options& opts, X509_DN& subject_dn,
23  AlternativeName& subject_alt)
24  {
25  subject_dn.add_attribute("X520.CommonName", opts.common_name);
26  subject_dn.add_attribute("X520.Country", opts.country);
27  subject_dn.add_attribute("X520.State", opts.state);
28  subject_dn.add_attribute("X520.Locality", opts.locality);
29  subject_dn.add_attribute("X520.Organization", opts.organization);
30  subject_dn.add_attribute("X520.OrganizationalUnit", opts.org_unit);
31  subject_dn.add_attribute("X520.SerialNumber", opts.serial_number);
32  subject_alt = AlternativeName(opts.email, opts.uri, opts.dns, opts.ip);
33  subject_alt.add_othername(OIDS::lookup("PKIX.XMPPAddr"),
34  opts.xmpp, UTF8_STRING);
35  }
36 }
37 
38 namespace X509 {
39 
40 /*
41 * Create a new self-signed X.509 certificate
42 */
44  const Private_Key& key,
45  const std::string& hash_fn,
47  {
48  AlgorithmIdentifier sig_algo;
49  X509_DN subject_dn;
50  AlternativeName subject_alt;
51 
52  // for now, only the padding option is used
53  std::map<std::string,std::string> sig_opts = { {"padding",opts.padding_scheme} };
54 
55  std::vector<uint8_t> pub_key = X509::BER_encode(key);
56  std::unique_ptr<PK_Signer> signer(choose_sig_format(key, sig_opts, rng, hash_fn, sig_algo));
57  load_info(opts, subject_dn, subject_alt);
58 
59  Key_Constraints constraints;
60  if(opts.is_CA)
61  {
62  constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
63  }
64  else
65  {
67  constraints = opts.constraints;
68  }
69 
70  Extensions extensions = opts.extensions;
71 
72  extensions.add(
74  true);
75 
76  if(constraints != NO_CONSTRAINTS)
77  {
78  extensions.add(new Cert_Extension::Key_Usage(constraints), true);
79  }
80 
81  extensions.add(new Cert_Extension::Subject_Key_ID(pub_key, hash_fn));
82 
83  extensions.add(
85 
86  extensions.add(
88 
89  return X509_CA::make_cert(signer.get(), rng, sig_algo, pub_key,
90  opts.start, opts.end,
91  subject_dn, subject_dn,
92  extensions);
93  }
94 
95 /*
96 * Create a PKCS #10 certificate request
97 */
99  const Private_Key& key,
100  const std::string& hash_fn,
102  {
103  AlgorithmIdentifier sig_algo;
104  X509_DN subject_dn;
105  AlternativeName subject_alt;
106 
107  // for now, only the padding option is used
108  std::map<std::string,std::string> sig_opts = { {"padding",opts.padding_scheme} };
109 
110  std::vector<uint8_t> pub_key = X509::BER_encode(key);
111  std::unique_ptr<PK_Signer> signer(choose_sig_format(key, sig_opts, rng, hash_fn, sig_algo));
112  load_info(opts, subject_dn, subject_alt);
113 
114  const size_t PKCS10_VERSION = 0;
115 
116  Key_Constraints constraints;
117  if(opts.is_CA)
118  {
119  constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
120  }
121  else
122  {
124  constraints = opts.constraints;
125  }
126 
127  Extensions extensions = opts.extensions;
128 
129  extensions.add(
131 
132  if(constraints != NO_CONSTRAINTS)
133  {
134  extensions.add(
135  new Cert_Extension::Key_Usage(constraints));
136  }
137  extensions.add(
139  extensions.add(
141 
142  DER_Encoder tbs_req;
143 
144  tbs_req.start_cons(SEQUENCE)
145  .encode(PKCS10_VERSION)
146  .encode(subject_dn)
147  .raw_bytes(pub_key)
148  .start_explicit(0);
149 
150  if(!opts.challenge.empty())
151  {
152  ASN1_String challenge(opts.challenge, DIRECTORY_STRING);
153 
154  tbs_req.encode(
155  Attribute("PKCS9.ChallengePassword",
156  DER_Encoder().encode(challenge).get_contents_unlocked()
157  )
158  );
159  }
160 
161  tbs_req.encode(
162  Attribute("PKCS9.ExtensionRequest",
163  DER_Encoder()
164  .start_cons(SEQUENCE)
165  .encode(extensions)
166  .end_cons()
167  .get_contents_unlocked()
168  )
169  )
170  .end_explicit()
171  .end_cons();
172 
173  const std::vector<uint8_t> req =
174  X509_Object::make_signed(signer.get(), rng, sig_algo,
175  tbs_req.get_contents());
176 
177  return PKCS10_Request(req);
178  }
179 
180 }
181 
182 }
PKCS10_Request create_cert_req(const X509_Cert_Options &opts, const Private_Key &key, const std::string &hash_fn, RandomNumberGenerator &rng)
Definition: x509self.cpp:98
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:125
std::vector< uint8_t > BER_encode(const Public_Key &key)
Definition: x509_key.cpp:19
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:271
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:123
DER_Encoder & end_explicit()
Definition: der_enc.cpp:173
DER_Encoder & end_cons()
Definition: der_enc.cpp:146
DER_Encoder & raw_bytes(const uint8_t val[], size_t len)
Definition: der_enc.cpp:181
void add(Certificate_Extension *extn, bool critical=false)
Definition: x509_ext.cpp:122
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:202
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
Key_Constraints constraints
Definition: x509self.h:116
std::string padding_scheme
Definition: x509self.h:111
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:43
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:275
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:136
CK_ATTRIBUTE Attribute
Definition: p11.h:845
std::vector< OID > ex_constraints
Definition: x509self.h:121
std::string lookup(const OID &oid)
Definition: oids.cpp:18
std::string challenge
Definition: x509self.h:90
DER_Encoder & start_explicit(uint16_t type_tag)
Definition: der_enc.cpp:160