diff options
author | Jack Lloyd <[email protected]> | 2018-03-20 15:47:11 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-03-20 15:47:11 -0400 |
commit | e3e1c536e312511f25004e93f6ce7175e41ae288 (patch) | |
tree | 57eca1b49ec5e023d04b0e3e4fe33a05bbaf933d /src/lib | |
parent | 737f33c09a18500e044dca3e2ae13bd2c08bafdd (diff) | |
parent | a54ba4ab24684c63557ece809de1f41adeaddf77 (diff) |
Merge GH #1501 Support Ed25519 certificates
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/asn1/alg_id.h | 2 | ||||
-rw-r--r-- | src/lib/x509/key_constraint.cpp | 4 | ||||
-rw-r--r-- | src/lib/x509/x509_obj.cpp | 107 |
3 files changed, 74 insertions, 39 deletions
diff --git a/src/lib/asn1/alg_id.h b/src/lib/asn1/alg_id.h index 22978b847..dc9ca2398 100644 --- a/src/lib/asn1/alg_id.h +++ b/src/lib/asn1/alg_id.h @@ -21,7 +21,7 @@ namespace Botan { class BOTAN_PUBLIC_API(2,0) AlgorithmIdentifier final : public ASN1_Object { public: - enum Encoding_Option { USE_NULL_PARAM }; + enum Encoding_Option { USE_NULL_PARAM, USE_EMPTY_PARAM }; void encode_into(class DER_Encoder&) const override; void decode_from(class BER_Decoder&) override; diff --git a/src/lib/x509/key_constraint.cpp b/src/lib/x509/key_constraint.cpp index e27d2aff2..dfadedac5 100644 --- a/src/lib/x509/key_constraint.cpp +++ b/src/lib/x509/key_constraint.cpp @@ -84,7 +84,9 @@ void verify_cert_constraints_valid_for_key_type(const Public_Key& pub_key, permitted |= KEY_ENCIPHERMENT | DATA_ENCIPHERMENT; } - if(name == "RSA" || name == "DSA" || name == "ECDSA" || name == "ECGDSA" || name == "ECKCDSA" || name == "GOST-34.10") + if(name == "RSA" || name == "DSA" || + name == "ECDSA" || name == "ECGDSA" || name == "ECKCDSA" || name == "GOST-34.10" || + name == "Ed25519") { permitted |= DIGITAL_SIGNATURE | NON_REPUDIATION | KEY_CERT_SIGN | CRL_SIGN; } diff --git a/src/lib/x509/x509_obj.cpp b/src/lib/x509/x509_obj.cpp index 78413c121..41cf74acc 100644 --- a/src/lib/x509/x509_obj.cpp +++ b/src/lib/x509/x509_obj.cpp @@ -149,11 +149,12 @@ std::vector<uint8_t> X509_Object::tbs_data() const std::string X509_Object::hash_used_for_signature() const { const OID& oid = m_sig_algo.get_oid(); - std::vector<std::string> sig_info = split_on(OIDS::lookup(oid), '/'); + const std::vector<std::string> sig_info = split_on(OIDS::lookup(oid), '/'); - if(sig_info.size() != 2) - throw Internal_Error("Invalid name format found for " + - oid.as_string()); + if(sig_info.size() == 1 && sig_info[0] == "Ed25519") + return "SHA-512"; + else if(sig_info.size() != 2) + throw Internal_Error("Invalid name format found for " + oid.as_string()); if(sig_info[1] == "EMSA4") { @@ -161,7 +162,7 @@ std::string X509_Object::hash_used_for_signature() const } else { - std::vector<std::string> pad_and_hash = + const std::vector<std::string> pad_and_hash = parse_algorithm_name(sig_info[1]); if(pad_and_hash.size() != 2) @@ -195,10 +196,17 @@ Certificate_Status_Code X509_Object::verify_signature(const Public_Key& pub_key) const std::vector<std::string> sig_info = split_on(OIDS::lookup(m_sig_algo.get_oid()), '/'); - if(sig_info.size() != 2 || sig_info[0] != pub_key.algo_name()) + if(sig_info.size() < 1 || sig_info.size() > 2 || sig_info[0] != pub_key.algo_name()) + return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; + + std::string padding; + if(sig_info.size() == 2) + padding = sig_info[1]; + else if(sig_info[0] == "Ed25519") + padding = "Pure"; + else return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; - std::string padding = sig_info[1]; const Signature_Format format = (pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363; @@ -285,17 +293,14 @@ 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) +namespace { + +std::string choose_sig_algo(AlgorithmIdentifier& sig_algo, + const Private_Key& key, + const std::string& hash_fn, + const std::string& user_specified) { const std::string algo_name = key.algo_name(); - std::string padding; // check algo_name and set default @@ -312,43 +317,71 @@ std::unique_ptr<PK_Signer> X509_Object::choose_sig_format(AlgorithmIdentifier& s { padding = "EMSA1(" + hash_fn + ")"; } + else if(algo_name == "Ed25519") + { + padding = "Pure"; + } else { throw Invalid_Argument("Unknown X.509 signing key type: " + algo_name); } - if(padding_algo.empty() == false) + if(user_specified.empty() == false) { - padding = padding_algo; + padding = user_specified; } - // 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(...) + if(padding != "Pure") { - emsa.reset(get_emsa(padding + "(" + hash_fn + ")")); + // try to construct an EMSA object from the padding options or default + std::unique_ptr<EMSA> emsa; + 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) + { + throw Invalid_Argument("Could not parse padding scheme " + padding); + } + + sig_algo = emsa->config_for_x509(key, hash_fn); + return emsa->name(); } - if(emsa == nullptr) + else { - throw Invalid_Argument("Could not parse padding scheme " + padding); + sig_algo = AlgorithmIdentifier(OIDS::lookup("Ed25519"), AlgorithmIdentifier::USE_EMPTY_PARAM); + return "Pure"; } + } +} + +/* +* 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 Signature_Format format = (key.message_parts() > 1) ? DER_SEQUENCE : IEEE_1363; - sig_algo = emsa->config_for_x509(key, hash_fn); + const std::string emsa = choose_sig_algo(sig_algo, key, hash_fn, padding_algo); - return std::unique_ptr<PK_Signer>(new PK_Signer(key, rng, emsa->name(), format)); + return std::unique_ptr<PK_Signer>(new PK_Signer(key, rng, emsa, format)); } } |