Botan  1.10.9
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 * Distributed under the terms of the Botan license
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/oids.h>
13 #include <botan/pipe.h>
14 #include <memory>
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  subject_dn.add_attribute("X520.SerialNumber", opts.serial_number);
33  subject_alt = AlternativeName(opts.email, opts.uri, opts.dns, opts.ip);
34  subject_alt.add_othername(OIDS::lookup("PKIX.XMPPAddr"),
35  opts.xmpp, UTF8_STRING);
36  }
37 
38 }
39 
40 namespace X509 {
41 
42 /*
43 * Create a new self-signed X.509 certificate
44 */
46  const Private_Key& key,
47  const std::string& hash_fn,
49  {
50  AlgorithmIdentifier sig_algo;
51  X509_DN subject_dn;
52  AlternativeName subject_alt;
53 
54  opts.sanity_check();
55 
56  MemoryVector<byte> pub_key = X509::BER_encode(key);
57  std::auto_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo));
58  load_info(opts, subject_dn, subject_alt);
59 
60  Key_Constraints constraints;
61  if(opts.is_CA)
62  constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
63  else
64  constraints = find_constraints(key, opts.constraints);
65 
66  Extensions extensions;
67 
68  extensions.add(
70  true);
71 
72  extensions.add(new Cert_Extension::Key_Usage(constraints), true);
73 
74  extensions.add(new Cert_Extension::Subject_Key_ID(pub_key));
75 
76  extensions.add(
78 
79  extensions.add(
81 
82  return X509_CA::make_cert(signer.get(), rng, sig_algo, pub_key,
83  opts.start, opts.end,
84  subject_dn, subject_dn,
85  extensions);
86  }
87 
88 /*
89 * Create a PKCS #10 certificate request
90 */
92  const Private_Key& key,
93  const std::string& hash_fn,
95  {
96  AlgorithmIdentifier sig_algo;
97  X509_DN subject_dn;
98  AlternativeName subject_alt;
99 
100  opts.sanity_check();
101 
102  MemoryVector<byte> pub_key = X509::BER_encode(key);
103  std::auto_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo));
104  load_info(opts, subject_dn, subject_alt);
105 
106  const size_t PKCS10_VERSION = 0;
107 
108  Extensions extensions;
109 
110  extensions.add(
112  extensions.add(
115  find_constraints(key, opts.constraints)
116  )
117  );
118  extensions.add(
120  extensions.add(
122 
123  DER_Encoder tbs_req;
124 
125  tbs_req.start_cons(SEQUENCE)
126  .encode(PKCS10_VERSION)
127  .encode(subject_dn)
128  .raw_bytes(pub_key)
129  .start_explicit(0);
130 
131  if(opts.challenge != "")
132  {
133  ASN1_String challenge(opts.challenge, DIRECTORY_STRING);
134 
135  tbs_req.encode(
136  Attribute("PKCS9.ChallengePassword",
137  DER_Encoder().encode(challenge).get_contents()
138  )
139  );
140  }
141 
142  tbs_req.encode(
143  Attribute("PKCS9.ExtensionRequest",
144  DER_Encoder()
145  .start_cons(SEQUENCE)
146  .encode(extensions)
147  .end_cons()
148  .get_contents()
149  )
150  )
151  .end_explicit()
152  .end_cons();
153 
154  DataSource_Memory source(
155  X509_Object::make_signed(signer.get(),
156  rng,
157  sig_algo,
158  tbs_req.get_contents())
159  );
160 
161  return PKCS10_Request(source);
162  }
163 
164 }
165 
166 }
PKCS10_Request create_cert_req(const X509_Cert_Options &opts, const Private_Key &key, const std::string &hash_fn, RandomNumberGenerator &rng)
Definition: x509self.cpp:91
SecureVector< byte > get_contents()
Definition: der_enc.cpp:122
static X509_Certificate make_cert(PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &sig_algo, const MemoryRegion< 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:90
DER_Encoder & raw_bytes(const byte val[], size_t len)
Definition: der_enc.cpp:188
MemoryVector< byte > BER_encode(const Public_Key &key)
Definition: x509_key.cpp:21
DER_Encoder & end_explicit()
Definition: der_enc.cpp:172
DER_Encoder & start_explicit(u16bit type_tag)
Definition: der_enc.cpp:159
DER_Encoder & end_cons()
Definition: der_enc.cpp:145
void add(Certificate_Extension *extn, bool critical=false)
Definition: x509_ext.cpp:77
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:209
RandomNumberGenerator * rng
Definition: global_rng.cpp:165
Key_Constraints find_constraints(const Public_Key &pub_key, Key_Constraints limits)
Definition: x509_key.cpp:113
std::string lookup(const OID &oid)
Definition: oids.cpp:31
void encode(const Public_Key &key, Pipe &pipe, X509_Encoding encoding=PEM)
Definition: x509_key.h:87
Key_Constraints constraints
Definition: x509self.h:110
static MemoryVector< byte > make_signed(class PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &alg_id, const MemoryRegion< byte > &tbs)
Definition: x509_obj.cpp:204
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:135
void sanity_check() const
Definition: x509opt.cpp:67
Key_Constraints
Definition: pubkey_enums.h:18
std::vector< OID > ex_constraints
Definition: x509self.h:115
std::string challenge
Definition: x509self.h:86
PK_Signer * choose_sig_format(const Private_Key &key, const std::string &hash_fn, AlgorithmIdentifier &sig_algo)
Definition: x509_ca.cpp:218
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:45