Botan  2.0.1
Crypto and TLS for C++11
pkcs10.cpp
Go to the documentation of this file.
1 /*
2 * PKCS #10
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/pkcs10.h>
9 #include <botan/x509_ext.h>
10 #include <botan/x509cert.h>
11 #include <botan/der_enc.h>
12 #include <botan/ber_dec.h>
13 #include <botan/parsing.h>
14 #include <botan/oids.h>
15 #include <botan/pem.h>
16 
17 namespace Botan {
18 
19 /*
20 * PKCS10_Request Constructor
21 */
23  X509_Object(in, "CERTIFICATE REQUEST/NEW CERTIFICATE REQUEST")
24  {
25  do_decode();
26  }
27 
28 #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
29 /*
30 * PKCS10_Request Constructor
31 */
32 PKCS10_Request::PKCS10_Request(const std::string& fsname) :
33  X509_Object(fsname, "CERTIFICATE REQUEST/NEW CERTIFICATE REQUEST")
34  {
35  do_decode();
36  }
37 #endif
38 
39 /*
40 * PKCS10_Request Constructor
41 */
42 PKCS10_Request::PKCS10_Request(const std::vector<uint8_t>& in) :
43  X509_Object(in, "CERTIFICATE REQUEST/NEW CERTIFICATE REQUEST")
44  {
45  do_decode();
46  }
47 
48 /*
49 * Decode the CertificateRequestInfo
50 */
51 void PKCS10_Request::force_decode()
52  {
53  BER_Decoder cert_req_info(m_tbs_bits);
54 
55  size_t version;
56  cert_req_info.decode(version);
57  if(version != 0)
58  throw Decoding_Error("Unknown version code in PKCS #10 request: " +
59  std::to_string(version));
60 
61  X509_DN dn_subject;
62  cert_req_info.decode(dn_subject);
63 
64  m_info.add(dn_subject.contents());
65 
66  BER_Object public_key = cert_req_info.get_next_object();
67  if(public_key.type_tag != SEQUENCE || public_key.class_tag != CONSTRUCTED)
68  throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for public key",
69  public_key.type_tag, public_key.class_tag);
70 
71  m_info.add("X509.Certificate.public_key",
73  ASN1::put_in_sequence(unlock(public_key.value)),
74  "PUBLIC KEY"
75  )
76  );
77 
78  BER_Object attr_bits = cert_req_info.get_next_object();
79 
80  if(attr_bits.type_tag == 0 &&
82  {
83  BER_Decoder attributes(attr_bits.value);
84  while(attributes.more_items())
85  {
86  Attribute attr;
87  attributes.decode(attr);
88  handle_attribute(attr);
89  }
90  attributes.verify_end();
91  }
92  else if(attr_bits.type_tag != NO_OBJECT)
93  throw BER_Bad_Tag("PKCS10_Request: Unexpected tag for attributes",
94  attr_bits.type_tag, attr_bits.class_tag);
95 
96  cert_req_info.verify_end();
97 
99  throw Decoding_Error("PKCS #10 request: Bad signature detected");
100  }
101 
102 /*
103 * Handle attributes in a PKCS #10 request
104 */
105 void PKCS10_Request::handle_attribute(const Attribute& attr)
106  {
107  BER_Decoder value(attr.parameters);
108 
109  if(attr.oid == OIDS::lookup("PKCS9.EmailAddress"))
110  {
111  ASN1_String email;
112  value.decode(email);
113  m_info.add("RFC822", email.value());
114  }
115  else if(attr.oid == OIDS::lookup("PKCS9.ChallengePassword"))
116  {
118  value.decode(challenge_password);
119  m_info.add("PKCS9.ChallengePassword", challenge_password.value());
120  }
121  else if(attr.oid == OIDS::lookup("PKCS9.ExtensionRequest"))
122  {
123  value.decode(m_extensions).verify_end();
124  }
125  }
126 
127 /*
128 * Return the challenge password (if any)
129 */
131  {
132  return m_info.get1("PKCS9.ChallengePassword");
133  }
134 
135 /*
136 * Return the name of the requestor
137 */
139  {
140  return create_dn(m_info);
141  }
142 
143 /*
144 * Return the public key of the requestor
145 */
146 std::vector<uint8_t> PKCS10_Request::raw_public_key() const
147  {
148  DataSource_Memory source(m_info.get1("X509.Certificate.public_key"));
149  return unlock(PEM_Code::decode_check_label(source, "PUBLIC KEY"));
150  }
151 
152 /*
153 * Return the public key of the requestor
154 */
156  {
157  DataSource_Memory source(m_info.get1("X509.Certificate.public_key"));
158  return X509::load_key(source);
159  }
160 
161 /*
162 * Return the alternative names of the requestor
163 */
165  {
166  return create_alt_name(m_info);
167  }
168 
169 /*
170 * Return the key constraints (if any)
171 */
173  {
174  if(auto ext = m_extensions.get(OIDS::lookup("X509v3.KeyUsage")))
175  {
176  return dynamic_cast<Cert_Extension::Key_Usage&>(*ext).get_constraints();
177  }
178 
179  return NO_CONSTRAINTS;
180  }
181 
182 /*
183 * Return the extendend key constraints (if any)
184 */
185 std::vector<OID> PKCS10_Request::ex_constraints() const
186  {
187  if(auto ext = m_extensions.get(OIDS::lookup("X509v3.ExtendedKeyUsage")))
188  {
189  return dynamic_cast<Cert_Extension::Extended_Key_Usage&>(*ext).get_oids();
190  }
191 
192  return {};
193  }
194 
195 /*
196 * Return is a CA certificate is requested
197 */
199  {
200  if(auto ext = m_extensions.get(OIDS::lookup("X509v3.BasicConstraints")))
201  {
202  return dynamic_cast<Cert_Extension::Basic_Constraints&>(*ext).get_is_ca();
203  }
204 
205  return false;
206  }
207 
208 /*
209 * Return the desired path limit (if any)
210 */
212  {
213  if(auto ext = m_extensions.get(OIDS::lookup("X509v3.BasicConstraints")))
214  {
215  Cert_Extension::Basic_Constraints& basic_constraints = dynamic_cast<Cert_Extension::Basic_Constraints&>(*ext);
216  if(basic_constraints.get_is_ca())
217  {
218  return basic_constraints.get_path_limit();
219  }
220  }
221 
222  return 0;
223  }
224 
225 /*
226 * Return the X509v3 extensions
227 */
229  {
230  return m_extensions;
231  }
232 
233 }
std::unique_ptr< Certificate_Extension > get(const OID &oid) const
Definition: x509_ext.cpp:126
Extensions extensions() const
Definition: pkcs10.cpp:228
Key_Constraints get_constraints() const
Definition: x509_ext.h:216
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
Public_Key * load_key(DataSource &source)
Definition: x509_key.cpp:37
AlternativeName subject_alt_name() const
Definition: pkcs10.cpp:164
size_t path_limit() const
Definition: pkcs10.cpp:211
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:376
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
std::vector< uint8_t > raw_public_key() const
Definition: pkcs10.cpp:146
std::string challenge_password() const
Definition: pkcs10.cpp:130
bool check_signature(const Public_Key &key) const
Definition: x509_obj.cpp:188
X509_Object()=default
std::vector< uint8_t > m_tbs_bits
Definition: x509_obj.h:110
secure_vector< uint8_t > value
Definition: asn1_obj.h:94
X509_DN create_dn(const Data_Store &info)
Definition: x509cert.cpp:673
std::string value() const
Definition: asn1_str.cpp:99
AlternativeName create_alt_name(const Data_Store &info)
Definition: x509cert.cpp:692
std::string lookup(const OID &oid)
Definition: oids.cpp:18
ASN1_Tag
Definition: asn1_obj.h:22
bool is_CA() const
Definition: pkcs10.cpp:198
Key_Constraints constraints() const
Definition: pkcs10.cpp:172
std::vector< uint8_t > parameters
Definition: alg_id.cpp:13
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition: asn1_obj.cpp:35
BER_Object get_next_object()
Definition: ber_dec.cpp:210
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:125
std::vector< OID > get_oids() const
Definition: x509_ext.h:342
ASN1_Tag class_tag
Definition: asn1_obj.h:91
secure_vector< uint8_t > decode_check_label(DataSource &source, const std::string &label_want)
Definition: pem.cpp:54
ASN1_Tag type_tag
Definition: asn1_obj.h:91
std::string get1(const std::string &key) const
Definition: datastor.cpp:62
BER_Decoder & verify_end()
Definition: ber_dec.cpp:168
PKCS10_Request(DataSource &source)
Definition: pkcs10.cpp:22
X509_DN subject_dn() const
Definition: pkcs10.cpp:138
Public_Key * subject_public_key() const
Definition: pkcs10.cpp:155
bool more_items() const
Definition: ber_dec.cpp:158
std::multimap< std::string, std::string > contents() const
Definition: x509_dn.cpp:85
void add(const std::multimap< std::string, std::string > &)
Definition: datastor.cpp:154
std::vector< OID > ex_constraints() const
Definition: pkcs10.cpp:185