diff options
Diffstat (limited to 'src/lib/x509/x509_obj.cpp')
-rw-r--r-- | src/lib/x509/x509_obj.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/lib/x509/x509_obj.cpp b/src/lib/x509/x509_obj.cpp index 01a92a001..78413c121 100644 --- a/src/lib/x509/x509_obj.cpp +++ b/src/lib/x509/x509_obj.cpp @@ -12,6 +12,7 @@ #include <botan/ber_dec.h> #include <botan/parsing.h> #include <botan/pem.h> +#include <botan/emsa.h> #include <algorithm> namespace Botan { @@ -284,4 +285,70 @@ std::vector<uint8_t> X509_Object::make_signed(PK_Signer* signer, .get_contents_unlocked(); } +/* +* Choose a signing format for the key +*/ +std::unique_ptr<PK_Signer> X509_Object::choose_sig_format(AlgorithmIdentifier& sig_algo, + const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& hash_fn, + const std::string& padding_algo) + { + const std::string algo_name = key.algo_name(); + + std::string padding; + + // check algo_name and set default + if(algo_name == "RSA") + { + // set to EMSA3 for compatibility reasons, originally it was the only option + padding = "EMSA3(" + hash_fn + ")"; + } + else if(algo_name == "DSA" || + algo_name == "ECDSA" || + algo_name == "ECGDSA" || + algo_name == "ECKCDSA" || + algo_name == "GOST-34.10") + { + padding = "EMSA1(" + hash_fn + ")"; + } + else + { + throw Invalid_Argument("Unknown X.509 signing key type: " + algo_name); + } + + if(padding_algo.empty() == false) + { + padding = padding_algo; + } + + // try to construct an EMSA object from the padding options or default + std::unique_ptr<EMSA> emsa = nullptr; + try + { + emsa.reset(get_emsa(padding)); + } + /* + * get_emsa will throw if opts contains {"padding",<valid_padding>} but + * <valid_padding> does not specify a hash function. + * Omitting it is valid since it needs to be identical to hash_fn. + * If it still throws, something happened that we cannot repair here, + * e.g. the algorithm/padding combination is not supported. + */ + catch(...) + { + emsa.reset(get_emsa(padding + "(" + hash_fn + ")")); + } + if(emsa == nullptr) + { + throw Invalid_Argument("Could not parse padding scheme " + padding); + } + + const Signature_Format format = (key.message_parts() > 1) ? DER_SEQUENCE : IEEE_1363; + + sig_algo = emsa->config_for_x509(key, hash_fn); + + return std::unique_ptr<PK_Signer>(new PK_Signer(key, rng, emsa->name(), format)); + } + } |