3
* (C) 1999-2007 Jack Lloyd
5
* Botan is released under the Simplified BSD License (see license.txt)
8
#include <botan/x509_obj.h>
9
#include <botan/pubkey.h>
10
#include <botan/oids.h>
11
#include <botan/der_enc.h>
12
#include <botan/ber_dec.h>
13
#include <botan/parsing.h>
14
#include <botan/pem.h>
22
AlgorithmIdentifier hash_algo;
23
AlgorithmIdentifier mask_gen_algo;
24
AlgorithmIdentifier mask_gen_hash; // redundant: decoded mask_gen_algo.parameters
29
Pss_params decode_pss_params(const std::vector<uint8_t>& encoded_pss_params)
31
Pss_params pss_parameter;
32
BER_Decoder(encoded_pss_params)
34
.decode_optional(pss_parameter.hash_algo, ASN1_Tag(0), PRIVATE, AlgorithmIdentifier("SHA-160",
35
AlgorithmIdentifier::USE_NULL_PARAM))
36
.decode_optional(pss_parameter.mask_gen_algo, ASN1_Tag(1), PRIVATE,
37
AlgorithmIdentifier("MGF1", DER_Encoder().encode(AlgorithmIdentifier("SHA-160",
38
AlgorithmIdentifier::USE_NULL_PARAM)).get_contents_unlocked()))
39
.decode_optional(pss_parameter.salt_len, ASN1_Tag(2), PRIVATE, size_t(20))
40
.decode_optional(pss_parameter.trailer_field, ASN1_Tag(3), PRIVATE, size_t(1))
43
BER_Decoder(pss_parameter.mask_gen_algo.get_parameters()).decode(pss_parameter.mask_gen_hash);
50
* Read a PEM or BER X.509 object
52
void X509_Object::load_data(DataSource& in)
55
if(ASN1::maybe_BER(in) && !PEM_Code::matches(in))
62
std::string got_label;
63
DataSource_Memory ber(PEM_Code::decode(in, got_label));
65
if(got_label != PEM_label())
67
bool is_alternate = false;
68
for(std::string alt_label : alternate_PEM_labels())
70
if(got_label == alt_label)
78
throw Decoding_Error("Unexpected PEM label for " + PEM_label() + " of " + got_label);
85
catch(Decoding_Error& e)
87
throw Decoding_Error(PEM_label() + " decoding failed: " + e.what());
92
void X509_Object::encode_into(DER_Encoder& to) const
94
to.start_cons(SEQUENCE)
96
.raw_bytes(signed_body())
98
.encode(signature_algorithm())
99
.encode(signature(), BIT_STRING)
104
* Read a BER encoded X.509 object
106
void X509_Object::decode_from(BER_Decoder& from)
108
from.start_cons(SEQUENCE)
109
.start_cons(SEQUENCE)
110
.raw_bytes(m_tbs_bits)
113
.decode(m_sig, BIT_STRING)
120
* Return a BER encoded X.509 object
122
std::vector<uint8_t> X509_Object::BER_encode() const
126
return der.get_contents_unlocked();
130
* Return a PEM encoded X.509 object
132
std::string X509_Object::PEM_encode() const
134
return PEM_Code::encode(BER_encode(), PEM_label());
138
* Return the TBS data
140
std::vector<uint8_t> X509_Object::tbs_data() const
142
return ASN1::put_in_sequence(m_tbs_bits);
146
* Return the hash used in generating the signature
148
std::string X509_Object::hash_used_for_signature() const
150
const OID& oid = m_sig_algo.get_oid();
151
std::vector<std::string> sig_info = split_on(OIDS::lookup(oid), '/');
153
if(sig_info.size() != 2)
154
throw Internal_Error("Invalid name format found for " +
157
if(sig_info[1] == "EMSA4")
159
return OIDS::lookup(decode_pss_params(signature_algorithm().get_parameters()).hash_algo.get_oid());
163
std::vector<std::string> pad_and_hash =
164
parse_algorithm_name(sig_info[1]);
166
if(pad_and_hash.size() != 2)
168
throw Internal_Error("Invalid name format " + sig_info[1]);
171
return pad_and_hash[1];
176
* Check the signature on an object
178
bool X509_Object::check_signature(const Public_Key* pub_key) const
181
throw Exception("No key provided for " + PEM_label() + " signature check");
182
std::unique_ptr<const Public_Key> key(pub_key);
183
return check_signature(*key);
186
bool X509_Object::check_signature(const Public_Key& pub_key) const
188
const Certificate_Status_Code code = verify_signature(pub_key);
189
return (code == Certificate_Status_Code::VERIFIED);
192
Certificate_Status_Code X509_Object::verify_signature(const Public_Key& pub_key) const
194
const std::vector<std::string> sig_info =
195
split_on(OIDS::lookup(m_sig_algo.get_oid()), '/');
197
if(sig_info.size() != 2 || sig_info[0] != pub_key.algo_name())
198
return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
200
std::string padding = sig_info[1];
201
const Signature_Format format =
202
(pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363;
204
if(padding == "EMSA4")
206
// "MUST contain RSASSA-PSS-params"
207
if(signature_algorithm().parameters.empty())
209
return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
212
Pss_params pss_parameter = decode_pss_params(signature_algorithm().parameters);
214
// hash_algo must be SHA1, SHA2-224, SHA2-256, SHA2-384 or SHA2-512
215
const std::string hash_algo = OIDS::lookup(pss_parameter.hash_algo.oid);
216
if(hash_algo != "SHA-160" &&
217
hash_algo != "SHA-224" &&
218
hash_algo != "SHA-256" &&
219
hash_algo != "SHA-384" &&
220
hash_algo != "SHA-512")
222
return Certificate_Status_Code::UNTRUSTED_HASH;
225
const std::string mgf_algo = OIDS::lookup(pss_parameter.mask_gen_algo.oid);
226
if(mgf_algo != "MGF1")
228
return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
231
// For MGF1, it is strongly RECOMMENDED that the underlying hash function be the same as the one identified by hashAlgorithm
232
// Must be SHA1, SHA2-224, SHA2-256, SHA2-384 or SHA2-512
233
if(pss_parameter.mask_gen_hash.oid != pss_parameter.hash_algo.oid)
235
return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
238
if(pss_parameter.trailer_field != 1)
240
return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS;
243
// salt_len is actually not used for verification. Length is inferred from the signature
244
padding += "(" + hash_algo + "," + mgf_algo + "," + std::to_string(pss_parameter.salt_len) + ")";
249
PK_Verifier verifier(pub_key, padding, format);
250
const bool valid = verifier.verify_message(tbs_data(), signature());
253
return Certificate_Status_Code::VERIFIED;
255
return Certificate_Status_Code::SIGNATURE_ERROR;
257
catch(Algorithm_Not_Found&)
259
return Certificate_Status_Code::SIGNATURE_ALGO_UNKNOWN;
263
// This shouldn't happen, fallback to generic signature error
264
return Certificate_Status_Code::SIGNATURE_ERROR;
269
* Apply the X.509 SIGNED macro
271
std::vector<uint8_t> X509_Object::make_signed(PK_Signer* signer,
272
RandomNumberGenerator& rng,
273
const AlgorithmIdentifier& algo,
274
const secure_vector<uint8_t>& tbs_bits)
276
const std::vector<uint8_t> signature = signer->sign_message(tbs_bits, rng);
279
.start_cons(SEQUENCE)
282
.encode(signature, BIT_STRING)
284
.get_contents_unlocked();