diff options
author | Jack Lloyd <[email protected]> | 2017-05-19 10:43:11 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-05-19 10:43:11 -0400 |
commit | 08ea995eb6f55ae52ec74c5c76ea8a114c72ccf8 (patch) | |
tree | e49b1b1ea62e1f787064944f9a3910e1d88ffc55 | |
parent | 2165cda540bac5311f46ac63480c5138a03adaca (diff) | |
parent | bebecf225713bc7e8b2082adfd163a173e4483c1 (diff) |
Merge GH #1051 Extensions for PKCSv1.5 signature formatting
-rw-r--r-- | src/lib/ffi/ffi.cpp | 21 | ||||
-rw-r--r-- | src/lib/ffi/ffi.h | 2 | ||||
-rw-r--r-- | src/lib/pk_pad/emsa.cpp | 6 | ||||
-rw-r--r-- | src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp | 25 | ||||
-rw-r--r-- | src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h | 7 | ||||
-rw-r--r-- | src/lib/pk_pad/hash_id/hash_id.cpp | 5 | ||||
-rw-r--r-- | src/tests/data/pubkey/rsa_sig.vec | 8 | ||||
-rw-r--r-- | src/tests/test_ffi.cpp | 27 |
8 files changed, 96 insertions, 5 deletions
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp index 9442634c4..3686c26f1 100644 --- a/src/lib/ffi/ffi.cpp +++ b/src/lib/ffi/ffi.cpp @@ -73,6 +73,10 @@ #include <botan/bcrypt.h> #endif +#if defined(BOTAN_HAS_HASH_ID) + #include <botan/hash_id.h> +#endif + #if defined(BOTAN_HAS_TLS) #include <botan/tls_client.h> #include <botan/tls_server.h> @@ -2249,6 +2253,23 @@ int botan_x509_cert_allowed_usage(botan_x509_cert_t cert, unsigned int key_usage }); } +int botan_pkcs_hash_id(const char* hash_name, uint8_t pkcs_id[], size_t* pkcs_id_len) + { +#if defined(BOTAN_HAS_HASH_ID) + try + { + const std::vector<uint8_t> hash_id = Botan::pkcs_hash_id(hash_name); + return write_output(pkcs_id, pkcs_id_len, hash_id.data(), hash_id.size()); + } + catch(...) + { + return BOTAN_FFI_ERROR_EXCEPTION_THROWN; + } +#else + return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; +#endif + } + int botan_mceies_decrypt(botan_privkey_t mce_key_obj, const char* aead, const uint8_t ct[], size_t ct_len, diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h index f93265e22..4953bce06 100644 --- a/src/lib/ffi/ffi.h +++ b/src/lib/ffi/ffi.h @@ -911,6 +911,8 @@ BOTAN_DLL int botan_pk_op_key_agreement(botan_pk_op_ka_t op, const uint8_t other_key[], size_t other_key_len, const uint8_t salt[], size_t salt_len); +BOTAN_DLL int botan_pkcs_hash_id(const char* hash_name, uint8_t pkcs_id[], size_t* pkcs_id_len); + /* * diff --git a/src/lib/pk_pad/emsa.cpp b/src/lib/pk_pad/emsa.cpp index 94274916e..074af273a 100644 --- a/src/lib/pk_pad/emsa.cpp +++ b/src/lib/pk_pad/emsa.cpp @@ -50,7 +50,11 @@ EMSA* get_emsa(const std::string& algo_spec) req.algo_name() == "EMSA-PKCS1-v1_5" || req.algo_name() == "EMSA3") { - if(req.arg_count() == 1) + if(req.arg_count() == 2 && req.arg(0) == "Raw") + { + return new EMSA_PKCS1v15_Raw(req.arg(1)); + } + else if(req.arg_count() == 1) { if(req.arg(0) == "Raw") { diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp index ebe6f5fa7..d5a6aa8fb 100644 --- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp +++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.cpp @@ -85,6 +85,20 @@ EMSA_PKCS1v15::EMSA_PKCS1v15(HashFunction* hash) : m_hash(hash) m_hash_id = pkcs_hash_id(m_hash->name()); } +EMSA_PKCS1v15_Raw::EMSA_PKCS1v15_Raw(const std::string& hash_algo) + { + if(!hash_algo.empty()) + { + m_hash_id = pkcs_hash_id(hash_algo); + std::unique_ptr<HashFunction> hash(HashFunction::create(hash_algo)); + m_hash_output_len = hash->output_length(); + } + else + { + m_hash_output_len = 0; + } + } + void EMSA_PKCS1v15_Raw::update(const uint8_t input[], size_t length) { m_message += std::make_pair(input, length); @@ -94,6 +108,10 @@ secure_vector<uint8_t> EMSA_PKCS1v15_Raw::raw_data() { secure_vector<uint8_t> ret; std::swap(ret, m_message); + + if(m_hash_output_len > 0 && ret.size() != m_hash_output_len) + throw Encoding_Error("EMSA_PKCS1v15_Raw::encoding_of: Bad input length"); + return ret; } @@ -102,16 +120,19 @@ EMSA_PKCS1v15_Raw::encoding_of(const secure_vector<uint8_t>& msg, size_t output_bits, RandomNumberGenerator&) { - return emsa3_encoding(msg, output_bits, nullptr, 0); + return emsa3_encoding(msg, output_bits, m_hash_id.data(), m_hash_id.size()); } bool EMSA_PKCS1v15_Raw::verify(const secure_vector<uint8_t>& coded, const secure_vector<uint8_t>& raw, size_t key_bits) { + if(m_hash_output_len > 0 && raw.size() != m_hash_output_len) + return false; + try { - return (coded == emsa3_encoding(raw, key_bits, nullptr, 0)); + return (coded == emsa3_encoding(raw, key_bits, m_hash_id.data(), m_hash_id.size())); } catch(...) { diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h index 95ccafa4d..ddfabeae3 100644 --- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h +++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h @@ -62,7 +62,14 @@ class BOTAN_DLL EMSA_PKCS1v15_Raw final : public EMSA bool verify(const secure_vector<uint8_t>&, const secure_vector<uint8_t>&, size_t) override; + /** + * @param hash_algo if non-empty, the digest id for that hash is + * included in the signature. + */ + EMSA_PKCS1v15_Raw(const std::string& hash_algo = ""); private: + size_t m_hash_output_len = 0; + std::vector<uint8_t> m_hash_id; secure_vector<uint8_t> m_message; }; diff --git a/src/lib/pk_pad/hash_id/hash_id.cpp b/src/lib/pk_pad/hash_id/hash_id.cpp index 70b7470c4..71a3dbe22 100644 --- a/src/lib/pk_pad/hash_id/hash_id.cpp +++ b/src/lib/pk_pad/hash_id/hash_id.cpp @@ -67,7 +67,7 @@ std::vector<uint8_t> pkcs_hash_id(const std::string& name) return std::vector<uint8_t>(RIPEMD_160_PKCS_ID, RIPEMD_160_PKCS_ID + sizeof(RIPEMD_160_PKCS_ID)); - if(name == "SHA-160") + if(name == "SHA-160" || name == "SHA-1" || name == "SHA1") return std::vector<uint8_t>(SHA_160_PKCS_ID, SHA_160_PKCS_ID + sizeof(SHA_160_PKCS_ID)); @@ -103,7 +103,8 @@ std::vector<uint8_t> pkcs_hash_id(const std::string& name) */ uint8_t ieee1363_hash_id(const std::string& name) { - if(name == "SHA-160") return 0x33; + if(name == "SHA-160" || name == "SHA-1" || name == "SHA1") + return 0x33; if(name == "SHA-224") return 0x38; if(name == "SHA-256") return 0x34; diff --git a/src/tests/data/pubkey/rsa_sig.vec b/src/tests/data/pubkey/rsa_sig.vec index 19641cc19..1560a78d6 100644 --- a/src/tests/data/pubkey/rsa_sig.vec +++ b/src/tests/data/pubkey/rsa_sig.vec @@ -239,6 +239,14 @@ Q = 1300628500736091066469357724169131719350514861299470388096939255066412050709 Msg = 2C88F626457046190AEB16FF2A499DF5820240A5248074445B2D54DDF0C298F57BFF Signature = 0EB5DC0D319B97F56F1C71E381BC26F40012054BB9A597484946955886F83333D21E916D60C3FB667869383CF9AAF6C0A98641ECECCB9F3BD71943696A78609E6324386B2030D2B2DEF1692677E205282617AA40EBAEB48C86B884CF51884BC807BE2D7C83AE3C671DB24E141B76646F0466B0DBFF20362991D465F7A0F7B4324E54092A742E0FE4C66A200AF324706B7D1BDE1C0371AB5FAFD58EBDE5555D24DECF399553C94E45A3E5B3F491BEF76EA9B08C41C2F233F13F83C99D6D88EDAD +Padding = EMSA3(Raw,MD5) +E = 17 +P = 13029564622157791280616891297384459345543528892729268050647908228725108502227809382105716872483480064224030258864846430267698903993578412414816903162894041 +Q = 11607519244599001458239888881356890329831441554346650600093035021905318722027819107556373878744770935515508357488960347997325733372608114236427580844273703 +Msg = BA34C71DB7D125ED4E6B3A246D6F235C +Signature = AA5E96F061E0F6FEAEEDAABA83BEA346BD4129B1F9F8380E8CB1E61860E47DA5262F0A2ADFECE7DBC02A53FFEA0C24EE162ABD8B818D4C125BC8351CCE0FA7C533C18EC7264593C3CB9201A5C0889DBB211CEB659135854C6510F3FE96DFD5A172D1037C4C7B1CFA6BA56529B6C5FAB72754F6518E114CB14F1CF63AD12E3B2A + + Padding = EMSA3(MD5) E = 17 P = 13029564622157791280616891297384459345543528892729268050647908228725108502227809382105716872483480064224030258864846430267698903993578412414816903162894041 diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp index 45c4c8a5b..624b01032 100644 --- a/src/tests/test_ffi.cpp +++ b/src/tests/test_ffi.cpp @@ -341,6 +341,7 @@ class FFI_Unit_Tests : public Test results.push_back(ffi_test_ciphers_cbc()); results.push_back(ffi_test_ciphers_aead()); results.push_back(ffi_test_stream_ciphers()); + results.push_back(ffi_test_pkcs_hash_id()); #if defined(BOTAN_HAS_RSA) results.push_back(ffi_test_rsa(rng)); @@ -373,6 +374,32 @@ class FFI_Unit_Tests : public Test } private: + Test::Result ffi_test_pkcs_hash_id() + { + Test::Result result("FFI PKCS hash id"); + +#if defined(BOTAN_HAS_HASH_ID) + std::vector<uint8_t> hash_id(64); + size_t hash_id_len; + + hash_id_len = 3; // too short + TEST_FFI_RC(BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE, + botan_pkcs_hash_id, ("SHA-256", hash_id.data(), &hash_id_len)); + + result.test_eq("Expected SHA-256 PKCS hash id len", hash_id_len, 19); + + TEST_FFI_OK(botan_pkcs_hash_id, ("SHA-256", hash_id.data(), &hash_id_len)); + + result.test_eq("Expected SHA-256 PKCS hash id len", hash_id_len, 19); + + hash_id.resize(hash_id_len); + result.test_eq("Expected SHA_256 PKCS hash id", + hash_id, "3031300D060960864801650304020105000420"); +#endif + + return result; + } + Test::Result ffi_test_ciphers_cbc() { Test::Result result("FFI CBC cipher"); |