aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/x509/x509_obj.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/x509/x509_obj.cpp')
-rw-r--r--src/lib/x509/x509_obj.cpp67
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));
+ }
+
}