diff options
author | Jack Lloyd <[email protected]> | 2020-06-07 09:36:55 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2020-06-09 12:31:04 -0400 |
commit | 25ded4f693bea388045c4a3d62c30cbacd0325ec (patch) | |
tree | c3e0daaf7a23480e0df62016c7bd5f4d38b1962d /src/lib/x509/x509_obj.cpp | |
parent | 7bc3d7501c2cdf6479c8bd799e0fff696810d9e4 (diff) |
Check that X.509 SignatureAlgorithm parameters are as expected
For modes where the parameters should be either NULL or empty,
we previously accepted anything at all.
We can't enforce strictly empty or strictly NULL for most cases
because practice has changed over time and there are certs using
empty params with RSA and NULL params with ECSDA and etc. We
do attempt to enforce the strict RFC requirement for XMSS and
Ed25519 since they are new algorithms and hopefully everyone just
followed the spec.
Issue reported by Mario Korth of Ruhr-Universität Bochum.
Diffstat (limited to 'src/lib/x509/x509_obj.cpp')
-rw-r--r-- | src/lib/x509/x509_obj.cpp | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/src/lib/x509/x509_obj.cpp b/src/lib/x509/x509_obj.cpp index 644a1ca5e..2bb67629a 100644 --- a/src/lib/x509/x509_obj.cpp +++ b/src/lib/x509/x509_obj.cpp @@ -1,6 +1,6 @@ /* * X.509 SIGNED Object -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2020 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -189,10 +189,11 @@ Certificate_Status_Code X509_Object::verify_signature(const Public_Key& pub_key) if(sig_info.size() < 1 || sig_info.size() > 2 || sig_info[0] != pub_key.algo_name()) return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; + const std::string pub_key_algo = sig_info[0]; std::string padding; if(sig_info.size() == 2) padding = sig_info[1]; - else if(sig_info[0] == "Ed25519" || sig_info[0] == "XMSS") + else if(pub_key_algo == "Ed25519" || pub_key_algo == "XMSS") padding = "Pure"; else return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; @@ -240,6 +241,40 @@ Certificate_Status_Code X509_Object::verify_signature(const Public_Key& pub_key) padding += "(" + hash_algo + "," + mgf_algo + "," + std::to_string(pss_parameter.salt_len) + ")"; } + else + { + /* + * For all other signature types the signature parameters should + * be either NULL or empty. In theory there is some distinction between + * these but in practice they seem to be used somewhat interchangeably. + * + * The various RFCs all have prescriptions of what is allowed: + * RSA - NULL (RFC 3279) + * DSA - empty (RFC 3279) + * ECDSA - empty (RFC 3279) + * GOST - empty (RFC 4491) + * Ed25519 - empty (RFC 8410) + * XMSS - empty (draft-vangeest-x509-hash-sigs) + * + * But in practice we find RSA with empty and ECDSA will NULL all + * over the place so it's not really possible to enforce. For Ed25519 + * and XMSS because they are new we attempt to enforce. + */ + if(pub_key_algo == "Ed25519" || pub_key_algo == "XMSS") + { + if(!signature_algorithm().parameters_are_empty()) + { + return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; + } + } + else + { + if(!signature_algorithm().parameters_are_null_or_empty()) + { + return Certificate_Status_Code::SIGNATURE_ALGO_BAD_PARAMS; + } + } + } try { |