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>
13 #include <botan/pem.h>
14 #include <botan/emsa.h>
29 Pss_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())
193 if(sig_info.size() == 2)
194 padding = sig_info[1];
195 else if(sig_info[0] ==
"Ed25519" || sig_info[0] ==
"XMSS")
202 if(padding ==
"EMSA4")
213 const std::string
hash_algo = pss_parameter.hash_algo.get_oid().to_formatted_string();
214 if(hash_algo !=
"SHA-160" &&
215 hash_algo !=
"SHA-224" &&
216 hash_algo !=
"SHA-256" &&
217 hash_algo !=
"SHA-384" &&
218 hash_algo !=
"SHA-512")
223 const std::string mgf_algo = pss_parameter.mask_gen_algo.get_oid().to_formatted_string();
224 if(mgf_algo !=
"MGF1")
231 if(pss_parameter.mask_gen_hash.get_oid() != pss_parameter.hash_algo.get_oid())
236 if(pss_parameter.trailer_field != 1)
241 padding +=
"(" + hash_algo +
"," + mgf_algo +
"," +
std::to_string(pss_parameter.salt_len) +
")";
275 std::vector<uint8_t> output;
290 const std::string& hash_fn,
291 const std::string& user_specified)
293 const std::string algo_name = key.
algo_name();
297 if(algo_name ==
"RSA")
300 padding =
"EMSA3(" + hash_fn +
")";
302 else if(algo_name ==
"DSA" ||
303 algo_name ==
"ECDSA" ||
304 algo_name ==
"ECGDSA" ||
305 algo_name ==
"ECKCDSA" ||
306 algo_name ==
"GOST-34.10" ||
307 algo_name ==
"GOST-34.10-2012-256" ||
308 algo_name ==
"GOST-34.10-2012-512")
310 padding =
"EMSA1(" + hash_fn +
")";
312 else if(algo_name ==
"Ed25519")
316 else if(algo_name ==
"XMSS")
318 if(user_specified.empty() ==
true)
320 throw Invalid_Argument(
"XMSS requires padding scheme");
322 padding = user_specified;
328 throw Invalid_Argument(
"Unknown X.509 signing key type: " + algo_name);
331 if(user_specified.empty() ==
false)
333 padding = user_specified;
336 if(padding !=
"Pure")
339 std::unique_ptr<EMSA> emsa;
353 emsa.reset(
get_emsa(padding +
"(" + hash_fn +
")"));
358 throw Invalid_Argument(
"Could not parse padding scheme " + padding);
361 sig_algo = emsa->config_for_x509(key, hash_fn);
379 const std::string& hash_fn,
380 const std::string& padding_algo)
384 const std::string emsa = choose_sig_algo(sig_algo, key, hash_fn, padding_algo);
386 return std::unique_ptr<PK_Signer>(
new PK_Signer(key, rng, emsa, format));
std::string hash_used_for_signature() const
const std::vector< uint8_t > & signed_body() const
Certificate_Status_Code verify_signature(const Public_Key &key) const
bool verify_message(const uint8_t msg[], size_t msg_length, const uint8_t sig[], size_t sig_length)
std::vector< std::string > split_on(const std::string &str, char delim)
void encode_into(class DER_Encoder &to) const override
static std::vector< uint8_t > make_signed(class PK_Signer *signer, RandomNumberGenerator &rng, const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &tbs)
AlgorithmIdentifier mask_gen_hash
virtual std::string PEM_label() const =0
AlgorithmIdentifier mask_gen_algo
virtual std::string algo_name() const =0
bool maybe_BER(DataSource &source)
std::string to_string(const BER_Object &obj)
std::string to_formatted_string() const
BER_Decoder & raw_bytes(std::vector< uint8_t, Alloc > &out)
BER_Decoder & decode(bool &out)
const AlgorithmIdentifier & signature_algorithm() const
std::vector< uint8_t > sign_message(const uint8_t in[], size_t length, RandomNumberGenerator &rng)
DER_Encoder & raw_bytes(const uint8_t val[], size_t len)
virtual std::vector< std::string > alternate_PEM_labels() const
void decode_from(class BER_Decoder &from) override
const std::vector< uint8_t > & signature() const
DER_Encoder & encode(bool b)
std::string PEM_encode() 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)
std::vector< T, secure_allocator< T >> secure_vector
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)
std::string to_string() const
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
std::vector< uint8_t > BER_encode() const
void load_data(DataSource &src)
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
std::vector< std::string > parse_algorithm_name(const std::string &namex)
const OID & get_oid() const
AlgorithmIdentifier hash_algo
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
std::vector< uint8_t > tbs_data() const
bool check_signature(const Public_Key &key) const
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
EMSA * get_emsa(const std::string &algo_spec)
virtual Signature_Format default_x509_signature_format() const
static OID from_string(const std::string &str)