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