diff options
author | lloyd <[email protected]> | 2009-11-09 13:22:52 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-11-09 13:22:52 +0000 |
commit | 4049ba134674d78c07c8b0453cb5e5f312469639 (patch) | |
tree | b9214ede8da1600a46560fe061017fa124b2b465 /src/cert/x509/x509_ca.cpp | |
parent | b5d4cf01a893718c8796652f3cf0f68b867bab94 (diff) |
In creating X.509 certificates and PKCS #10 requests, let (actually: require)
the user to specify the hash function to use, instead of always using SHA-1.
This was a sensible default a few years ago, when there wasn't a ~2^60 attack
on SHA-1 and support for SHA-2 was pretty much nil, but using something else
makes a lot more sense these days.
Diffstat (limited to 'src/cert/x509/x509_ca.cpp')
-rw-r--r-- | src/cert/x509/x509_ca.cpp | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/src/cert/x509/x509_ca.cpp b/src/cert/x509/x509_ca.cpp index f0eb9c3e5..48ec0bd1c 100644 --- a/src/cert/x509/x509_ca.cpp +++ b/src/cert/x509/x509_ca.cpp @@ -9,9 +9,10 @@ #include <botan/x509stor.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> -#include <botan/look_pk.h> #include <botan/bigint.h> #include <botan/parsing.h> +#include <botan/lookup.h> +#include <botan/look_pk.h> #include <botan/oids.h> #include <botan/timer.h> #include <algorithm> @@ -20,22 +21,33 @@ #include <memory> #include <set> +#include <stdio.h> + namespace Botan { /* * Load the certificate and private key */ X509_CA::X509_CA(const X509_Certificate& c, - const Private_Key& key) : cert(c) + const Private_Key& key, + const std::string& hash_fn) : cert(c) { - const Private_Key* key_pointer = &key; - if(!dynamic_cast<const PK_Signing_Key*>(key_pointer)) + // Use pointer dynamic_cast to avoid exception if cast fails + if(!dynamic_cast<const PK_Signing_Key*>(&key)) throw Invalid_Argument("X509_CA: " + key.algo_name() + " cannot sign"); if(!cert.is_CA_cert()) throw Invalid_Argument("X509_CA: This certificate is not for a CA"); - signer = choose_sig_format(key, ca_sig_algo); + signer = choose_sig_format(key, hash_fn, ca_sig_algo); + } + +/* +* X509_CA Destructor +*/ +X509_CA::~X509_CA() + { + delete signer; } /* @@ -70,7 +82,8 @@ X509_Certificate X509_CA::sign_request(const PKCS10_Request& req, extensions.add( new Cert_Extension::Subject_Alternative_Name(req.subject_alt_name())); - return make_cert(signer, rng, ca_sig_algo, req.raw_public_key(), + return make_cert(signer, rng, ca_sig_algo, + req.raw_public_key(), not_before, not_after, cert.subject_dn(), req.subject_dn(), extensions); @@ -231,17 +244,10 @@ X509_Certificate X509_CA::ca_certificate() const } /* -* X509_CA Destructor -*/ -X509_CA::~X509_CA() - { - delete signer; - } - -/* * Choose a signing format for the key */ PK_Signer* choose_sig_format(const Private_Key& key, + const std::string& hash_fn, AlgorithmIdentifier& sig_algo) { std::string padding; @@ -249,24 +255,36 @@ PK_Signer* choose_sig_format(const Private_Key& key, const std::string algo_name = key.algo_name(); + const HashFunction* proto_hash = retrieve_hash(hash_fn); + if(!proto_hash) + throw Algorithm_Not_Found(hash_fn); + + if(key.max_input_bits() < proto_hash->OUTPUT_LENGTH*8) + { + printf("%d %d\n", key.max_input_bits(), proto_hash->OUTPUT_LENGTH*8); + throw Invalid_Argument("Key is too small for chosen hash function"); + } + if(algo_name == "RSA") { - padding = "EMSA3(SHA-160)"; + padding = "EMSA3"; format = IEEE_1363; } else if(algo_name == "DSA") { - padding = "EMSA1(SHA-160)"; + padding = "EMSA1"; format = DER_SEQUENCE; } else if(algo_name == "ECDSA") { - padding = "EMSA1_BSI(SHA-160)"; + padding = "EMSA1_BSI"; format = IEEE_1363; } else throw Invalid_Argument("Unknown X.509 signing key type: " + algo_name); + padding = padding + '(' + proto_hash->name() + ')'; + sig_algo.oid = OIDS::lookup(algo_name + "/" + padding); std::auto_ptr<X509_Encoder> encoding(key.x509_encoder()); |