Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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<uint8_t>& 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
86 void X509_Object::encode_into(DER_Encoder& to) const
87 {
88 to.start_cons(SEQUENCE)
89 .start_cons(SEQUENCE)
90 .raw_bytes(m_tbs_bits)
91 .end_cons()
92 .encode(m_sig_algo)
93 .encode(m_sig, BIT_STRING)
94 .end_cons();
95 }
96
97 /*
98 * Read a BER encoded X.509 object
99 */
100 void X509_Object::decode_from(BER_Decoder& from)
101 {
102 from.start_cons(SEQUENCE)
103 .start_cons(SEQUENCE)
104 .raw_bytes(m_tbs_bits)
105 .end_cons()
106 .decode(m_sig_algo)
107 .decode(m_sig, BIT_STRING)
108 .end_cons();
109 }
110
111 /*
112 * Return a BER encoded X.509 object
113 */
114 std::vector<uint8_t> X509_Object::BER_encode() const
115 {
116 DER_Encoder der;
117 encode_into(der);
118 return der.get_contents_unlocked();
119 }
120
121 /*
122 * Return a PEM encoded X.509 object
123 */
124 std::string X509_Object::PEM_encode() const
125 {
126 return PEM_Code::encode(BER_encode(), m_PEM_label_pref);
127 }
128
129 /*
130 * Return the TBS data
131 */
132 std::vector<uint8_t> X509_Object::tbs_data() const
133 {
134 return ASN1::put_in_sequence(m_tbs_bits);
135 }
136
137 /*
138 * Return the signature of this object
139 */
140 std::vector<uint8_t> X509_Object::signature() const
141 {
142 return m_sig;
143 }
144
145 /*
146 * Return the algorithm used to sign this object
147 */
148 AlgorithmIdentifier X509_Object::signature_algorithm() const
149 {
150 return m_sig_algo;
151 }
152
153 /*
154 * Return the hash used in generating the signature
155 */
156 std::string X509_Object::hash_used_for_signature() const
157 {
158 std::vector<std::string> sig_info =
159 split_on(OIDS::lookup(m_sig_algo.oid), '/');
160
161 if(sig_info.size() != 2)
162 throw Internal_Error("Invalid name format found for " +
163 m_sig_algo.oid.as_string());
164
165 std::vector<std::string> pad_and_hash =
166 parse_algorithm_name(sig_info[1]);
167
168 if(pad_and_hash.size() != 2)
169 throw Internal_Error("Invalid name format " + sig_info[1]);
170
171 return pad_and_hash[1];
172 }
173
174 /*
175 * Check the signature on an object
176 */
177 bool X509_Object::check_signature(const Public_Key* pub_key) const
178 {
179 if(!pub_key)
180 throw Exception("No key provided for " + m_PEM_label_pref + " signature check");
181 std::unique_ptr<const Public_Key> key(pub_key);
182 return check_signature(*key);
183 }
184
185 /*
186 * Check the signature on an object
187 */
188 bool X509_Object::check_signature(const Public_Key& pub_key) const
189 {
190 try {
191 std::vector<std::string> sig_info =
192 split_on(OIDS::lookup(m_sig_algo.oid), '/');
193
194 if(sig_info.size() != 2 || sig_info[0] != pub_key.algo_name())
195 return false;
196
197 std::string padding = sig_info[1];
198 Signature_Format format =
199 (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363;
200
201 PK_Verifier verifier(pub_key, padding, format);
202
203 return verifier.verify_message(tbs_data(), signature());
204 }
205 catch(std::exception&)
206 {
207 return false;
208 }
209 }
210
211 /*
212 * Apply the X.509 SIGNED macro
213 */
214 std::vector<uint8_t> X509_Object::make_signed(PK_Signer* signer,
215 RandomNumberGenerator& rng,
216 const AlgorithmIdentifier& algo,
217 const secure_vector<uint8_t>& tbs_bits)
218 {
219 return DER_Encoder()
220 .start_cons(SEQUENCE)
221 .raw_bytes(tbs_bits)
222 .encode(algo)
223 .encode(signer->sign_message(tbs_bits, rng), BIT_STRING)
224 .end_cons()
225 .get_contents_unlocked();
226 }
227
228 /*
229 * Try to decode the actual information
230 */
231 void X509_Object::do_decode()
232 {
233 try {
234 force_decode();
235 }
236 catch(Decoding_Error& e)
237 {
238 throw Decoding_Error(m_PEM_label_pref + " decoding failed (" +
239 e.what() + ")");
240 }
241 catch(Invalid_Argument& e)
242 {
243 throw Decoding_Error(m_PEM_label_pref + " decoding failed (" +
244 e.what() + ")");
245 }
246 }
247
248 }
Botan::parse_algorithm_name
std::vector< std::string > parse_algorithm_name(const std::string &namex)
Definition: parsing.cpp:85
Botan::X509_Object::m_sig_algo
AlgorithmIdentifier m_sig_algo
Definition: x509_obj.h:109
Botan::Invalid_Argument
Definition: exceptn.h:34
Botan::DataSource_Stream
Definition: data_src.h:143
Botan::PEM_Code::decode
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition: pem.cpp:68
Botan::Exception
Definition: exceptn.h:21
Botan::X509_Object::hash_used_for_signature
std::string hash_used_for_signature() const
Definition: x509_obj.cpp:156
Botan::X509_Object::BER_encode
std::vector< uint8_t > BER_encode() const
Definition: x509_obj.cpp:114
Botan::DER_Encoder::get_contents_unlocked
std::vector< uint8_t > get_contents_unlocked()
Definition: der_enc.h:27
Botan::PK_Verifier::verify_message
bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length)
Definition: pubkey.cpp:280
Botan::RandomNumberGenerator
Definition: rng.h:25
Botan::X509_Object::encode_into
void encode_into(class DER_Encoder &to) const override
Definition: x509_obj.cpp:86
Botan::PEM_Code::encode
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
Botan::X509_Object::make_signed
static std::vector< uint8_t > make_signed(class PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &tbs)
Definition: x509_obj.cpp:214
Botan::Signature_Format
Signature_Format
Definition: pubkey.h:29
Botan::Internal_Error
Definition: exceptn.h:88
Botan::split_on
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:138
Botan::Public_Key::algo_name
virtual std::string algo_name() const =0
Botan::BER_Decoder::decode
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:376
Botan::ASN1::maybe_BER
bool maybe_BER(DataSource &source)
Definition: asn1_obj.cpp:55
Botan::DER_Encoder::end_cons
DER_Encoder & end_cons()
Definition: der_enc.cpp:147
Botan::DataSource
Definition: data_src.h:21
Botan::X509_Object::X509_Object
X509_Object()=default
Botan::PK_Signer::sign_message
std::vector< uint8_t > sign_message(const uint8_t in[], size_t length, RandomNumberGenerator &rng)
Definition: pubkey.h:209
Botan::DER_Encoder::raw_bytes
DER_Encoder & raw_bytes(const uint8_t val[], size_t len)
Definition: der_enc.cpp:195
Botan::X509_Object::decode_from
void decode_from(class BER_Decoder &from) override
Definition: x509_obj.cpp:100
Botan::DER_Encoder::encode
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:216
Botan::DER_Encoder
Definition: der_enc.h:22
Botan::X509_Object::PEM_encode
std::string PEM_encode() const
Definition: x509_obj.cpp:124
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
Botan::X509_Object::m_tbs_bits
std::vector< uint8_t > m_tbs_bits
Definition: x509_obj.h:110
Botan::BER_Decoder::end_cons
BER_Decoder & end_cons()
Definition: ber_dec.cpp:272
Botan::X509_Object::do_decode
void do_decode()
Definition: x509_obj.cpp:231
Botan::OIDS::lookup
std::string lookup(const OID &oid)
Definition: oids.cpp:18
Botan::Public_Key::message_parts
virtual size_t message_parts() const
Definition: pk_keys.h:103
Botan::AlgorithmIdentifier::oid
OID oid
Definition: alg_id.h:36
Botan::Decoding_Error
Definition: exceptn.h:189
Botan::Exception::what
const char * what() const BOTAN_NOEXCEPT override
Definition: exceptn.h:26
Botan::SEQUENCE
Definition: asn1_obj.h:39
Botan::BER_Decoder::start_cons
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.cpp:258
Botan
Definition: alg_id.cpp:13
Botan::PK_Verifier
Definition: pubkey.h:288
Botan::PEM_Code::matches
bool matches(DataSource &source, const std::string &extra, size_t search_range)
Definition: pem.cpp:140
Botan::X509_Object::signature
std::vector< uint8_t > signature() const
Definition: x509_obj.cpp:140
Botan::Public_Key
Definition: pk_keys.h:24
Botan::IEEE_1363
Definition: pubkey.h:29
Botan::ASN1::put_in_sequence
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition: asn1_obj.cpp:35
Botan::X509_Object::tbs_data
std::vector< uint8_t > tbs_data() const
Definition: x509_obj.cpp:132
Botan::X509_Object::check_signature
bool check_signature(const Public_Key &key) const
Definition: x509_obj.cpp:188
Botan::BIT_STRING
Definition: asn1_obj.h:34
Botan::DataSource_Memory
Definition: data_src.h:98
Botan::OID::as_string
std::string as_string() const
Definition: asn1_oid.cpp:50
Botan::AlgorithmIdentifier
Definition: alg_id.h:20
Botan::DER_Encoder::start_cons
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:137
Botan::DER_SEQUENCE
Definition: pubkey.h:29
Botan::PK_Signer
Definition: pubkey.h:161
Botan::BER_Decoder::raw_bytes
BER_Decoder & raw_bytes(secure_vector< uint8_t > &v)
Definition: ber_dec.cpp:178
Botan::BER_Decoder
Definition: ber_dec.h:19
Botan::X509_Object::m_sig
std::vector< uint8_t > m_sig
Definition: x509_obj.h:110
Botan::X509_Object::signature_algorithm
AlgorithmIdentifier signature_algorithm() const
Definition: x509_obj.cpp:148