Botan  2.1.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 
39 namespace X509 {
40 
41 /*
42 * Create a new self-signed X.509 certificate
43 */
45  const Private_Key& key,
46  const std::string& hash_fn,
48  {
49  AlgorithmIdentifier sig_algo;
50  X509_DN subject_dn;
51  AlternativeName subject_alt;
52 
53  std::vector<uint8_t> pub_key = X509::BER_encode(key);
54  std::unique_ptr<PK_Signer> signer(choose_sig_format(key, rng, hash_fn, sig_algo));
55  load_info(opts, subject_dn, subject_alt);
56 
57  Key_Constraints constraints;
58  if(opts.is_CA)
59  {
60  constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
61  }
62  else
63  {
65  constraints = opts.constraints;
66  }
67 
68  Extensions extensions = opts.extensions;
69 
70  extensions.add(
72  true);
73 
74  if(constraints != NO_CONSTRAINTS)
75  {
76  extensions.add(new Cert_Extension::Key_Usage(constraints), true);
77  }
78 
79  extensions.add(new Cert_Extension::Subject_Key_ID(pub_key));
80 
81  extensions.add(
83 
84  extensions.add(
86 
87  return X509_CA::make_cert(signer.get(), rng, sig_algo, pub_key,
88  opts.start, opts.end,
89  subject_dn, subject_dn,
90  extensions);
91  }
92 
93 /*
94 * Create a PKCS #10 certificate request
95 */
97  const Private_Key& key,
98  const std::string& hash_fn,
100  {
101  AlgorithmIdentifier sig_algo;
102  X509_DN subject_dn;
103  AlternativeName subject_alt;
104 
105  std::vector<uint8_t> pub_key = X509::BER_encode(key);
106  std::unique_ptr<PK_Signer> signer(choose_sig_format(key, rng, hash_fn, sig_algo));
107  load_info(opts, subject_dn, subject_alt);
108 
109  const size_t PKCS10_VERSION = 0;
110 
111  Key_Constraints constraints;
112  if(opts.is_CA)
113  {
114  constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
115  }
116  else
117  {
119  constraints = opts.constraints;
120  }
121 
122  Extensions extensions = opts.extensions;
123 
124  extensions.add(
126 
127  if(constraints != NO_CONSTRAINTS)
128  {
129  extensions.add(
130  new Cert_Extension::Key_Usage(constraints));
131  }
132  extensions.add(
134  extensions.add(
136 
137  DER_Encoder tbs_req;
138 
139  tbs_req.start_cons(SEQUENCE)
140  .encode(PKCS10_VERSION)
141  .encode(subject_dn)
142  .raw_bytes(pub_key)
143  .start_explicit(0);
144 
145  if(!opts.challenge.empty())
146  {
147  ASN1_String challenge(opts.challenge, DIRECTORY_STRING);
148 
149  tbs_req.encode(
150  Attribute("PKCS9.ChallengePassword",
151  DER_Encoder().encode(challenge).get_contents_unlocked()
152  )
153  );
154  }
155 
156  tbs_req.encode(
157  Attribute("PKCS9.ExtensionRequest",
158  DER_Encoder()
159  .start_cons(SEQUENCE)
160  .encode(extensions)
161  .end_cons()
162  .get_contents_unlocked()
163  )
164  )
165  .end_explicit()
166  .end_cons();
167 
168  const std::vector<uint8_t> req =
169  X509_Object::make_signed(signer.get(), rng, sig_algo,
170  tbs_req.get_contents());
171 
172  return PKCS10_Request(req);
173  }
174 
175 }
176 
177 }
PKCS10_Request create_cert_req(const X509_Cert_Options &opts, const Private_Key &key, const std::string &hash_fn, RandomNumberGenerator &rng)
Definition: x509self.cpp:96
std::vector< uint8_t > BER_encode(const Public_Key &key)
Definition: x509_key.cpp:19
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:96
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
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:214
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:124
DER_Encoder & end_explicit()
Definition: der_enc.cpp:174
DER_Encoder & end_cons()
Definition: der_enc.cpp:147
void verify_cert_constraints_valid_for_key_type(const Public_Key &pub_key, Key_Constraints constraints)
DER_Encoder & raw_bytes(const uint8_t val[], size_t len)
Definition: der_enc.cpp:195
void add(Certificate_Extension *extn, bool critical=false)
Definition: x509_ext.cpp:91
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:216
std::string lookup(const OID &oid)
Definition: oids.cpp:18
Key_Constraints constraints
Definition: x509self.h:111
Definition: alg_id.cpp:13
PK_Signer * choose_sig_format(const Private_Key &key, RandomNumberGenerator &rng, const std::string &hash_fn, AlgorithmIdentifier &sig_algo)
Definition: x509_ca.cpp:228
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:137
CK_ATTRIBUTE Attribute
Definition: p11.h:845
std::vector< OID > ex_constraints
Definition: x509self.h:116
std::string challenge
Definition: x509self.h:87
DER_Encoder & start_explicit(uint16_t type_tag)
Definition: der_enc.cpp:161
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:44