monotone

monotone Mtn Source Tree

Root/botan/x509self.cpp

1/*************************************************
2* PKCS #10/Self Signed Cert Creation Source File *
3* (C) 1999-2006 The Botan Project *
4*************************************************/
5
6#include <botan/x509self.h>
7#include <botan/x509_ext.h>
8#include <botan/x509_ca.h>
9#include <botan/der_enc.h>
10#include <botan/config.h>
11#include <botan/look_pk.h>
12#include <botan/oids.h>
13#include <botan/pipe.h>
14#include <memory>
15
16namespace Botan {
17
18namespace {
19
20/*************************************************
21* Shared setup for self-signed items *
22*************************************************/
23MemoryVector<byte> shared_setup(const X509_Cert_Options& opts,
24 const Private_Key& key)
25 {
26 const Private_Key* key_pointer = &key;
27 if(!dynamic_cast<const PK_Signing_Key*>(key_pointer))
28 throw Invalid_Argument("Key type " + key.algo_name() + " cannot sign");
29
30 opts.sanity_check();
31
32 Pipe key_encoder;
33 key_encoder.start_msg();
34 X509::encode(key, key_encoder, RAW_BER);
35 key_encoder.end_msg();
36
37 return key_encoder.read_all();
38 }
39
40/*************************************************
41* Load information from the X509_Cert_Options *
42*************************************************/
43void load_info(const X509_Cert_Options& opts, X509_DN& subject_dn,
44 AlternativeName& subject_alt)
45 {
46 subject_dn.add_attribute("X520.CommonName", opts.common_name);
47 subject_dn.add_attribute("X520.Country", opts.country);
48 subject_dn.add_attribute("X520.State", opts.state);
49 subject_dn.add_attribute("X520.Locality", opts.locality);
50 subject_dn.add_attribute("X520.Organization", opts.organization);
51 subject_dn.add_attribute("X520.OrganizationalUnit", opts.org_unit);
52 subject_dn.add_attribute("X520.SerialNumber", opts.serial_number);
53 subject_alt = AlternativeName(opts.email, opts.uri, opts.dns);
54 subject_alt.add_othername(OIDS::lookup("PKIX.XMPPAddr"),
55 opts.xmpp, UTF8_STRING);
56 }
57
58}
59
60namespace X509 {
61
62/*************************************************
63* Create a new self-signed X.509 certificate *
64*************************************************/
65X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts,
66 const Private_Key& key)
67 {
68 AlgorithmIdentifier sig_algo;
69 X509_DN subject_dn;
70 AlternativeName subject_alt;
71
72 MemoryVector<byte> pub_key = shared_setup(opts, key);
73 std::auto_ptr<PK_Signer> signer(choose_sig_format(key, sig_algo));
74 load_info(opts, subject_dn, subject_alt);
75
76 Key_Constraints constraints;
77 if(opts.is_CA)
78 constraints = Key_Constraints(KEY_CERT_SIGN | CRL_SIGN);
79 else
80 constraints = find_constraints(key, opts.constraints);
81
82 Extensions extensions;
83
84 extensions.add(new Cert_Extension::Subject_Key_ID(pub_key));
85 extensions.add(new Cert_Extension::Key_Usage(constraints));
86 extensions.add(
87 new Cert_Extension::Extended_Key_Usage(opts.ex_constraints));
88 extensions.add(
89 new Cert_Extension::Subject_Alternative_Name(subject_alt));
90 extensions.add(
91 new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit));
92
93 return X509_CA::make_cert(signer.get(), sig_algo, pub_key,
94 opts.start, opts.end,
95 subject_dn, subject_dn,
96 extensions);
97 }
98
99/*************************************************
100* Create a PKCS #10 certificate request *
101*************************************************/
102PKCS10_Request create_cert_req(const X509_Cert_Options& opts,
103 const Private_Key& key)
104 {
105 AlgorithmIdentifier sig_algo;
106 X509_DN subject_dn;
107 AlternativeName subject_alt;
108
109 MemoryVector<byte> pub_key = shared_setup(opts, key);
110 std::auto_ptr<PK_Signer> signer(choose_sig_format(key, sig_algo));
111 load_info(opts, subject_dn, subject_alt);
112
113 const u32bit PKCS10_VERSION = 0;
114
115 Extensions extensions;
116
117 extensions.add(
118 new Cert_Extension::Basic_Constraints(opts.is_CA, opts.path_limit));
119 extensions.add(
120 new Cert_Extension::Key_Usage(
121 opts.is_CA ? Key_Constraints(KEY_CERT_SIGN | CRL_SIGN) :
122 find_constraints(key, opts.constraints)
123 )
124 );
125 extensions.add(
126 new Cert_Extension::Extended_Key_Usage(opts.ex_constraints));
127 extensions.add(
128 new Cert_Extension::Subject_Alternative_Name(subject_alt));
129
130 DER_Encoder tbs_req;
131
132 tbs_req.start_cons(SEQUENCE)
133 .encode(PKCS10_VERSION)
134 .encode(subject_dn)
135 .raw_bytes(pub_key)
136 .start_explicit(0);
137
138 if(opts.challenge != "")
139 {
140 ASN1_String challenge(opts.challenge, DIRECTORY_STRING);
141
142 tbs_req.encode(
143 Attribute("PKCS9.ChallengePassword",
144 DER_Encoder().encode(challenge).get_contents()
145 )
146 );
147 }
148
149 tbs_req.encode(
150 Attribute("PKCS9.ExtensionRequest",
151 DER_Encoder()
152 .start_cons(SEQUENCE)
153 .encode(extensions)
154 .end_cons()
155 .get_contents()
156 )
157 )
158 .end_explicit()
159 .end_cons();
160
161 DataSource_Memory source(
162 X509_Object::make_signed(signer.get(), sig_algo,
163 tbs_req.get_contents())
164 );
165
166 return PKCS10_Request(source);
167 }
168
169}
170
171}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status