Botan 1.10.17
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#include <memory>
18
19namespace Botan {
20
21/*
22* Create a generic X.509 object
23*/
24X509_Object::X509_Object(DataSource& stream, const std::string& labels)
25 {
26 init(stream, labels);
27 }
28
29/*
30* Createa a generic X.509 object
31*/
32X509_Object::X509_Object(const std::string& file, const std::string& labels)
33 {
34 DataSource_Stream stream(file, true);
35 init(stream, labels);
36 }
37
38/*
39* Read a PEM or BER X.509 object
40*/
41void X509_Object::init(DataSource& in, const std::string& labels)
42 {
43 PEM_labels_allowed = split_on(labels, '/');
44 if(PEM_labels_allowed.size() < 1)
45 throw Invalid_Argument("Bad labels argument to X509_Object");
46
47 PEM_label_pref = PEM_labels_allowed[0];
48 std::sort(PEM_labels_allowed.begin(), PEM_labels_allowed.end());
49
50 try {
52 decode_info(in);
53 else
54 {
55 std::string got_label;
56 DataSource_Memory ber(PEM_Code::decode(in, got_label));
57
58 if(!std::binary_search(PEM_labels_allowed.begin(),
59 PEM_labels_allowed.end(), got_label))
60 throw Decoding_Error("Invalid PEM label: " + got_label);
61 decode_info(ber);
62 }
63 }
64 catch(Decoding_Error& e)
65 {
66 throw Decoding_Error(PEM_label_pref + " decoding failed: " + e.what());
67 }
68 }
69
70/*
71* Read a BER encoded X.509 object
72*/
73void X509_Object::decode_info(DataSource& source)
74 {
75 BER_Decoder(source)
76 .start_cons(SEQUENCE)
77 .start_cons(SEQUENCE)
78 .raw_bytes(tbs_bits)
79 .end_cons()
80 .decode(sig_algo)
81 .decode(sig, BIT_STRING)
82 .verify_end()
83 .end_cons();
84 }
85
86/*
87* Return a BER or PEM encoded X.509 object
88*/
89void X509_Object::encode(Pipe& out, X509_Encoding encoding) const
90 {
91 if(encoding == PEM)
92 out.write(this->PEM_encode());
93 else
94 out.write(this->BER_encode());
95 }
96
97/*
98* Return a BER encoded X.509 object
99*/
112
113/*
114* Return a PEM encoded X.509 object
115*/
116std::string X509_Object::PEM_encode() const
117 {
118 return PEM_Code::encode(BER_encode(), PEM_label_pref);
119 }
120
121/*
122* Return the TBS data
123*/
128
129/*
130* Return the signature of this object
131*/
133 {
134 return sig;
135 }
136
137/*
138* Return the algorithm used to sign this object
139*/
144
145/*
146* Return the hash used in generating the signature
147*/
149 {
150 std::vector<std::string> sig_info =
152
153 if(sig_info.size() != 2)
154 throw Internal_Error("Invalid name format found for " +
156
157 std::vector<std::string> pad_and_hash =
158 parse_algorithm_name(sig_info[1]);
159
160 if(pad_and_hash.size() != 2)
161 throw Internal_Error("Invalid name format " + sig_info[1]);
162
163 return pad_and_hash[1];
164 }
165
166/*
167* Check the signature on an object
168*/
170 {
171 std::auto_ptr<Public_Key> key(pub_key);
172 return check_signature(*key);
173 }
174
175/*
176* Check the signature on an object
177*/
179 {
180 try {
181 std::vector<std::string> sig_info =
183
184 if(sig_info.size() != 2 || sig_info[0] != pub_key.algo_name())
185 return false;
186
187 std::string padding = sig_info[1];
188 Signature_Format format =
189 (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363;
190
191 PK_Verifier verifier(pub_key, padding, format);
192
193 return verifier.verify_message(tbs_data(), signature());
194 }
195 catch(...)
196 {
197 return false;
198 }
199 }
200
201/*
202* Apply the X.509 SIGNED macro
203*/
217
218/*
219* Try to decode the actual information
220*/
222 {
223 try {
224 force_decode();
225 }
226 catch(Decoding_Error& e)
227 {
228 throw Decoding_Error(PEM_label_pref + " decoding failed (" +
229 e.what() + ")");
230 }
231 catch(Invalid_Argument& e)
232 {
233 throw Decoding_Error(PEM_label_pref + " decoding failed (" +
234 e.what() + ")");
235 }
236 }
237
238}
BER_Decoder(DataSource &)
Definition ber_dec.cpp:264
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition der_enc.cpp:135
DER_Encoder & raw_bytes(const byte val[], size_t len)
Definition der_enc.cpp:188
SecureVector< byte > get_contents()
Definition der_enc.cpp:122
DER_Encoder & end_cons()
Definition der_enc.cpp:145
DER_Encoder & encode(bool b)
Definition der_enc.cpp:209
std::string as_string() const
Definition asn1_oid.cpp:50
SecureVector< byte > sign_message(const byte in[], size_t length, RandomNumberGenerator &rng)
Definition pubkey.cpp:160
bool verify_message(const byte msg[], size_t msg_length, const byte sig[], size_t sig_length)
Definition pubkey.cpp:283
void write(const byte in[], size_t length)
Definition pipe_rw.cpp:34
virtual std::string algo_name() const =0
virtual size_t message_parts() const
Definition pk_keys.h:50
static MemoryVector< byte > make_signed(class PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &alg_id, const MemoryRegion< byte > &tbs)
Definition x509_obj.cpp:204
bool check_signature(class Public_Key &key) const
Definition x509_obj.cpp:178
MemoryVector< byte > sig
Definition x509_obj.h:102
std::string hash_used_for_signature() const
Definition x509_obj.cpp:148
std::string PEM_encode() const
Definition x509_obj.cpp:116
AlgorithmIdentifier signature_algorithm() const
Definition x509_obj.cpp:140
MemoryVector< byte > tbs_data() const
Definition x509_obj.cpp:124
MemoryVector< byte > signature() const
Definition x509_obj.cpp:132
AlgorithmIdentifier sig_algo
Definition x509_obj.h:101
MemoryVector< byte > BER_encode() const
Definition x509_obj.cpp:100
MemoryVector< byte > tbs_bits
Definition x509_obj.h:102
void encode(Pipe &out, X509_Encoding encoding=PEM) const
Definition x509_obj.cpp:89
bool maybe_BER(DataSource &source)
Definition asn1_int.cpp:55
SecureVector< byte > put_in_sequence(const MemoryRegion< byte > &contents)
Definition asn1_int.cpp:34
std::string lookup(const OID &oid)
Definition oids.cpp:31
std::string encode(const byte der[], size_t length, const std::string &label, size_t width)
Definition pem.cpp:19
bool matches(DataSource &source, const std::string &extra, size_t search_range)
Definition pem.cpp:116
SecureVector< byte > decode(DataSource &source, std::string &label)
Definition pem.cpp:56
std::vector< std::string > parse_algorithm_name(const std::string &namex)
Definition parsing.cpp:96
std::invalid_argument Invalid_Argument
Definition exceptn.h:20
@ BIT_STRING
Definition asn1_int.h:30
@ SEQUENCE
Definition asn1_int.h:35
std::vector< std::string > split_on(const std::string &str, char delim)
Definition parsing.cpp:152
Signature_Format
Definition pubkey.h:24
@ DER_SEQUENCE
Definition pubkey.h:24
@ IEEE_1363
Definition pubkey.h:24
Decoding_Error(const std::string &name)
Definition exceptn.h:140
Internal_Error(const std::string &err)
Definition exceptn.h:47