8#include <botan/x509_obj.h>
9#include <botan/pubkey.h>
10#include <botan/der_enc.h>
11#include <botan/ber_dec.h>
12#include <botan/parsing.h>
14#include <botan/emsa.h>
29Pss_params decode_pss_params(
const std::vector<uint8_t>& encoded_pss_params)
32 const AlgorithmIdentifier default_mgf(
"MGF1", default_hash.BER_encode());
34 Pss_params pss_parameter;
35 BER_Decoder(encoded_pss_params)
37 .decode_optional(pss_parameter.hash_algo,
ASN1_Tag(0),
PRIVATE, default_hash)
38 .decode_optional(pss_parameter.mask_gen_algo,
ASN1_Tag(1),
PRIVATE, default_mgf)
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);
62 std::string got_label;
67 bool is_alternate =
false;
70 if(got_label == alt_label)
143 if(sig_info.size() == 1 && sig_info[0] ==
"Ed25519")
145 else if(sig_info.size() != 2)
148 if(sig_info[1] ==
"EMSA4")
155 const std::vector<std::string> pad_and_hash =
158 if(pad_and_hash.size() != 2)
163 return pad_and_hash[1];
174 std::unique_ptr<const Public_Key> key(pub_key);
186 const std::vector<std::string> sig_info =
189 if(sig_info.size() < 1 || sig_info.size() > 2 || sig_info[0] != pub_key.
algo_name())
192 const std::string pub_key_algo = sig_info[0];
194 if(sig_info.size() == 2)
195 padding = sig_info[1];
196 else if(pub_key_algo ==
"Ed25519" || pub_key_algo ==
"XMSS")
203 if(padding ==
"EMSA4")
214 const std::string
hash_algo = pss_parameter.hash_algo.get_oid().to_formatted_string();
224 const std::string mgf_algo = pss_parameter.mask_gen_algo.get_oid().to_formatted_string();
225 if(mgf_algo !=
"MGF1")
232 if(pss_parameter.mask_gen_hash.get_oid() != pss_parameter.hash_algo.get_oid())
237 if(pss_parameter.trailer_field != 1)
263 if(pub_key_algo ==
"Ed25519" || pub_key_algo ==
"XMSS")
310 std::vector<uint8_t> output;
325 const std::string& hash_fn,
326 const std::string& user_specified)
328 const std::string algo_name = key.
algo_name();
332 if(algo_name ==
"RSA")
335 padding =
"EMSA3(" + hash_fn +
")";
337 else if(algo_name ==
"DSA" ||
338 algo_name ==
"ECDSA" ||
339 algo_name ==
"ECGDSA" ||
340 algo_name ==
"ECKCDSA" ||
341 algo_name ==
"GOST-34.10" ||
342 algo_name ==
"GOST-34.10-2012-256" ||
343 algo_name ==
"GOST-34.10-2012-512")
345 padding =
"EMSA1(" + hash_fn +
")";
347 else if(algo_name ==
"Ed25519")
351 else if(algo_name ==
"XMSS")
353 if(user_specified.empty() ==
true)
355 throw Invalid_Argument(
"XMSS requires padding scheme");
357 padding = user_specified;
363 throw Invalid_Argument(
"Unknown X.509 signing key type: " + algo_name);
366 if(user_specified.empty() ==
false)
368 padding = user_specified;
371 if(padding !=
"Pure")
374 std::unique_ptr<EMSA> emsa;
388 emsa.reset(
get_emsa(padding +
"(" + hash_fn +
")"));
393 throw Invalid_Argument(
"Could not parse padding scheme " + padding);
396 sig_algo = emsa->config_for_x509(key, hash_fn);
414 const std::string& hash_fn,
415 const std::string& padding_algo)
419 const std::string emsa = choose_sig_algo(sig_algo, key, hash_fn, padding_algo);
421 return std::unique_ptr<PK_Signer>(
new PK_Signer(key, rng, emsa, format));
std::vector< uint8_t > BER_encode() const
const OID & get_oid() const
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
BER_Decoder & decode(bool &out)
BER_Decoder & raw_bytes(std::vector< uint8_t, Alloc > &out)
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
DER_Encoder & raw_bytes(const uint8_t val[], size_t len)
DER_Encoder & encode(bool b)
std::string to_formatted_string() const
static OID from_string(const std::string &str)
std::string to_string() const
std::vector< uint8_t > sign_message(const uint8_t in[], size_t length, RandomNumberGenerator &rng)
bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length)
virtual Signature_Format default_x509_signature_format() const
virtual std::string algo_name() const =0
void decode_from(class BER_Decoder &from) override
std::string hash_used_for_signature() const
Certificate_Status_Code verify_signature(const Public_Key &key) const
const std::vector< uint8_t > & signed_body() const
std::string PEM_encode() const
const AlgorithmIdentifier & signature_algorithm() const
static std::unique_ptr< PK_Signer > choose_sig_format(AlgorithmIdentifier &sig_algo, const Private_Key &key, RandomNumberGenerator &rng, const std::string &hash_fn, const std::string &padding_algo)
virtual std::vector< std::string > alternate_PEM_labels() const
std::vector< uint8_t > tbs_data() const
const std::vector< uint8_t > & signature() const
void load_data(DataSource &src)
virtual std::string PEM_label() const =0
static std::vector< uint8_t > make_signed(class PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &tbs)
bool check_signature(const Public_Key &key) const
void encode_into(class DER_Encoder &to) const override
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
bool maybe_BER(DataSource &source)
std::string to_string(const BER_Object &obj)
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
bool matches(DataSource &source, const std::string &extra, size_t search_range)
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
std::vector< std::string > split_on(const std::string &str, char delim)
EMSA * get_emsa(const std::string &algo_spec)
std::vector< std::string > parse_algorithm_name(const std::string &namex)
@ SIGNATURE_ALGO_BAD_PARAMS
std::vector< T, secure_allocator< T > > secure_vector
AlgorithmIdentifier mask_gen_hash
AlgorithmIdentifier mask_gen_algo
AlgorithmIdentifier hash_algo