Botan  1.11.34
Crypto and TLS for C++11
x509_obj.cpp
Go to the documentation of this file.
1 /*
2 * X.509 SIGNED Object
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/x509_obj.h>
9 #include <botan/x509_key.h>
10 #include <botan/pubkey.h>
11 #include <botan/oids.h>
12 #include <botan/der_enc.h>
13 #include <botan/ber_dec.h>
14 #include <botan/parsing.h>
15 #include <botan/pem.h>
16 #include <algorithm>
17 
18 namespace Botan {
19 
20 /*
21 * Create a generic X.509 object
22 */
23 X509_Object::X509_Object(DataSource& stream, const std::string& labels)
24  {
25  init(stream, labels);
26  }
27 
28 #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
29 /*
30 * Create a generic X.509 object
31 */
32 X509_Object::X509_Object(const std::string& file, const std::string& labels)
33  {
34  DataSource_Stream stream(file, true);
35  init(stream, labels);
36  }
37 #endif
38 
39 /*
40 * Create a generic X.509 object
41 */
42 X509_Object::X509_Object(const std::vector<byte>& vec, const std::string& labels)
43  {
44  DataSource_Memory stream(vec.data(), vec.size());
45  init(stream, labels);
46  }
47 
48 /*
49 * Read a PEM or BER X.509 object
50 */
51 void X509_Object::init(DataSource& in, const std::string& labels)
52  {
53  m_PEM_labels_allowed = split_on(labels, '/');
54  if(m_PEM_labels_allowed.size() < 1)
55  throw Invalid_Argument("Bad labels argument to X509_Object");
56 
57  m_PEM_label_pref = m_PEM_labels_allowed[0];
58  std::sort(m_PEM_labels_allowed.begin(), m_PEM_labels_allowed.end());
59 
60  try {
61  if(ASN1::maybe_BER(in) && !PEM_Code::matches(in))
62  {
63  BER_Decoder dec(in);
64  decode_from(dec);
65  }
66  else
67  {
68  std::string got_label;
69  DataSource_Memory ber(PEM_Code::decode(in, got_label));
70 
71  if(!std::binary_search(m_PEM_labels_allowed.begin(),
72  m_PEM_labels_allowed.end(), got_label))
73  throw Decoding_Error("Invalid PEM label: " + got_label);
74 
75  BER_Decoder dec(ber);
76  decode_from(dec);
77  }
78  }
79  catch(Decoding_Error& e)
80  {
81  throw Decoding_Error(m_PEM_label_pref + " decoding failed: " + e.what());
82  }
83  }
84 
85 
87  {
91  .end_cons()
94  .end_cons();
95  }
96 
97 /*
98 * Read a BER encoded X.509 object
99 */
101  {
102  from.start_cons(SEQUENCE)
105  .end_cons()
108  .verify_end()
109  .end_cons();
110  }
111 
112 /*
113 * Return a BER encoded X.509 object
114 */
115 std::vector<byte> X509_Object::BER_encode() const
116  {
117  DER_Encoder der;
118  encode_into(der);
119  return der.get_contents_unlocked();
120  }
121 
122 /*
123 * Return a PEM encoded X.509 object
124 */
125 std::string X509_Object::PEM_encode() const
126  {
127  return PEM_Code::encode(BER_encode(), m_PEM_label_pref);
128  }
129 
130 /*
131 * Return the TBS data
132 */
133 std::vector<byte> X509_Object::tbs_data() const
134  {
136  }
137 
138 /*
139 * Return the signature of this object
140 */
141 std::vector<byte> X509_Object::signature() const
142  {
143  return m_sig;
144  }
145 
146 /*
147 * Return the algorithm used to sign this object
148 */
150  {
151  return m_sig_algo;
152  }
153 
154 /*
155 * Return the hash used in generating the signature
156 */
158  {
159  std::vector<std::string> sig_info =
161 
162  if(sig_info.size() != 2)
163  throw Internal_Error("Invalid name format found for " +
165 
166  std::vector<std::string> pad_and_hash =
167  parse_algorithm_name(sig_info[1]);
168 
169  if(pad_and_hash.size() != 2)
170  throw Internal_Error("Invalid name format " + sig_info[1]);
171 
172  return pad_and_hash[1];
173  }
174 
175 /*
176 * Check the signature on an object
177 */
178 bool X509_Object::check_signature(const Public_Key* pub_key) const
179  {
180  if(!pub_key)
181  throw Exception("No key provided for " + m_PEM_label_pref + " signature check");
182  std::unique_ptr<const Public_Key> key(pub_key);
183  return check_signature(*key);
184 }
185 
186 /*
187 * Check the signature on an object
188 */
189 bool X509_Object::check_signature(const Public_Key& pub_key) const
190  {
191  try {
192  std::vector<std::string> sig_info =
194 
195  if(sig_info.size() != 2 || sig_info[0] != pub_key.algo_name())
196  return false;
197 
198  std::string padding = sig_info[1];
199  Signature_Format format =
200  (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363;
201 
202  PK_Verifier verifier(pub_key, padding, format);
203 
204  return verifier.verify_message(tbs_data(), signature());
205  }
206  catch(std::exception&)
207  {
208  return false;
209  }
210  }
211 
212 /*
213 * Apply the X.509 SIGNED macro
214 */
215 std::vector<byte> X509_Object::make_signed(PK_Signer* signer,
217  const AlgorithmIdentifier& algo,
218  const secure_vector<byte>& tbs_bits)
219  {
220  return DER_Encoder()
222  .raw_bytes(tbs_bits)
223  .encode(algo)
224  .encode(signer->sign_message(tbs_bits, rng), BIT_STRING)
225  .end_cons()
227  }
228 
229 /*
230 * Try to decode the actual information
231 */
233  {
234  try {
235  force_decode();
236  }
237  catch(Decoding_Error& e)
238  {
239  throw Decoding_Error(m_PEM_label_pref + " decoding failed (" +
240  e.what() + ")");
241  }
242  catch(Invalid_Argument& e)
243  {
244  throw Decoding_Error(m_PEM_label_pref + " decoding failed (" +
245  e.what() + ")");
246  }
247  }
248 
249 }
std::vector< std::string > parse_algorithm_name(const std::string &namex)
Definition: parsing.cpp:85
std::vector< byte > sign_message(const byte in[], size_t length, RandomNumberGenerator &rng)
Definition: pubkey.h:208
std::vector< byte > BER_encode() const
Definition: x509_obj.cpp:115
AlgorithmIdentifier m_sig_algo
Definition: x509_obj.h:107
BER_Decoder & raw_bytes(secure_vector< byte > &v)
Definition: ber_dec.cpp:178
DER_Encoder & raw_bytes(const byte val[], size_t len)
Definition: der_enc.cpp:195
void encode_into(class DER_Encoder &to) const override
Definition: x509_obj.cpp:86
std::string as_string() const
Definition: asn1_oid.cpp:50
Signature_Format
Definition: pubkey.h:29
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:138
virtual std::string algo_name() const =0
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:376
bool maybe_BER(DataSource &source)
Definition: asn1_obj.cpp:55
DER_Encoder & end_cons()
Definition: der_enc.cpp:147
bool check_signature(const Public_Key &key) const
Definition: x509_obj.cpp:189
std::vector< byte > signature() const
Definition: x509_obj.cpp:141
void decode_from(class BER_Decoder &from) override
Definition: x509_obj.cpp:100
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:216
AlgorithmIdentifier signature_algorithm() const
Definition: x509_obj.cpp:149
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:113
std::vector< byte > get_contents_unlocked()
Definition: der_enc.h:27
BER_Decoder & end_cons()
Definition: ber_dec.cpp:272
static std::vector< byte > make_signed(class PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &alg_id, const secure_vector< byte > &tbs)
Definition: x509_obj.cpp:215
std::string lookup(const OID &oid)
Definition: oids.cpp:18
std::vector< byte > m_tbs_bits
Definition: x509_obj.h:108
bool verify_message(const byte msg[], size_t msg_length, const byte sig[], size_t sig_length)
Definition: pubkey.cpp:280
const char * what() const BOTAN_NOEXCEPT override
Definition: exceptn.h:26
std::vector< byte > m_sig
Definition: x509_obj.h:108
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.cpp:258
Definition: alg_id.cpp:13
bool matches(DataSource &source, const std::string &extra, size_t search_range)
Definition: pem.cpp:140
std::string hash_used_for_signature() const
Definition: x509_obj.cpp:157
std::string encode(const byte der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
BER_Decoder & verify_end()
Definition: ber_dec.cpp:168
std::vector< byte > tbs_data() const
Definition: x509_obj.cpp:133
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:137
std::vector< byte > put_in_sequence(const std::vector< byte > &contents)
Definition: asn1_obj.cpp:35
std::string PEM_encode() const
Definition: x509_obj.cpp:125
secure_vector< byte > decode(DataSource &source, std::string &label)
Definition: pem.cpp:68
virtual size_t message_parts() const
Definition: pk_keys.h:95