diff --git a/Crypto/include/Poco/Crypto/DigestEngine.h b/Crypto/include/Poco/Crypto/DigestEngine.h index d44b6f1f4..7f3e2e177 100644 --- a/Crypto/include/Poco/Crypto/DigestEngine.h +++ b/Crypto/include/Poco/Crypto/DigestEngine.h @@ -67,6 +67,9 @@ public: const std::string& algorithm() const; /// Returns the name of the digest algorithm. + int nid() const; + /// Returns the NID (OpenSSL object identifier) of the digest algorithm. + // DigestEngine std::size_t digestLength() const; void reset(); diff --git a/Crypto/include/Poco/Crypto/RSADigestEngine.h b/Crypto/include/Poco/Crypto/RSADigestEngine.h index df5847233..bd63988e9 100644 --- a/Crypto/include/Poco/Crypto/RSADigestEngine.h +++ b/Crypto/include/Poco/Crypto/RSADigestEngine.h @@ -43,8 +43,7 @@ #include "Poco/Crypto/Crypto.h" #include "Poco/Crypto/RSAKey.h" #include "Poco/DigestEngine.h" -#include "Poco/MD5Engine.h" -#include "Poco/SHA1Engine.h" +#include "Poco/Crypto/DigestEngine.h" #include #include #include @@ -58,10 +57,10 @@ class Crypto_API RSADigestEngine: public Poco::DigestEngine /// This class implements a Poco::DigestEngine that can be /// used to compute a secure digital signature. /// - /// First another Poco::DigestEngine (Poco::MD5Engine - /// or Poco::SHA1Engine) is used to compute a cryptographic - /// hash of the data to be signed. Then, the hash value is - /// encrypted, using the RSA private key. + /// First another Poco::Crypto::DigestEngine is created and + /// used to compute a cryptographic hash of the data to be + /// signed. Then, the hash value is encrypted, using + /// the RSA private key. /// /// To verify a signature, pass it to the verify() /// member function. It will decrypt the signature @@ -75,9 +74,19 @@ public: DIGEST_SHA1 }; + //@ deprecated RSADigestEngine(const RSAKey& key, DigestType digestType = DIGEST_SHA1); /// Creates the RSADigestEngine with the given RSA key, - /// using the SHA-1 hash algorithm. + /// using the MD5 or SHA-1 hash algorithm. + /// Kept for backward compatibility + + RSADigestEngine(const RSAKey& key, const std::string &name); + /// Creates the RSADigestEngine with the given RSA key, + /// using the hash algorithm with the given name + /// (e.g., "MD5", "SHA1", "SHA256", "SHA512", etc.). + /// See the OpenSSL documentation for a list of supported digest algorithms. + /// + /// Throws a Poco::NotFoundException if no algorithm with the given name exists. ~RSADigestEngine(); /// Destroys the RSADigestEngine. @@ -113,12 +122,9 @@ protected: private: RSAKey _key; - Poco::DigestEngine& _engine; - int _type; + Poco::Crypto::DigestEngine _engine; Poco::DigestEngine::Digest _digest; Poco::DigestEngine::Digest _signature; - Poco::MD5Engine _md5Engine; - Poco::SHA1Engine _sha1Engine; }; diff --git a/Crypto/src/DigestEngine.cpp b/Crypto/src/DigestEngine.cpp index 59880fab1..05d9daacc 100644 --- a/Crypto/src/DigestEngine.cpp +++ b/Crypto/src/DigestEngine.cpp @@ -57,6 +57,10 @@ DigestEngine::~DigestEngine() EVP_MD_CTX_destroy(_ctx); } +int DigestEngine::nid() const +{ + return EVP_MD_nid(_ctx->digest); +} std::size_t DigestEngine::digestLength() const { diff --git a/Crypto/src/RSADigestEngine.cpp b/Crypto/src/RSADigestEngine.cpp index af5f0a2a4..2d4b86249 100644 --- a/Crypto/src/RSADigestEngine.cpp +++ b/Crypto/src/RSADigestEngine.cpp @@ -36,6 +36,7 @@ #include "Poco/Crypto/RSADigestEngine.h" #include +#include namespace Poco { @@ -44,8 +45,13 @@ namespace Crypto { RSADigestEngine::RSADigestEngine(const RSAKey& key, DigestType digestType): _key(key), - _engine(digestType == DIGEST_MD5 ? static_cast(_md5Engine) : static_cast(_sha1Engine)), - _type(digestType == DIGEST_MD5 ? NID_md5 : NID_sha1) + _engine(digestType == DIGEST_MD5 ? "MD5" : "SHA1") +{ +} + +RSADigestEngine::RSADigestEngine(const RSAKey& key, const std::string &algorithm): + _key(key), + _engine(algorithm) { } @@ -86,7 +92,7 @@ const DigestEngine::Digest& RSADigestEngine::signature() digest(); _signature.resize(_key.size()); unsigned sigLen = static_cast(_signature.size()); - RSA_sign(_type, &_digest[0], static_cast(_digest.size()), &_signature[0], &sigLen, _key.impl()->getRSA()); + RSA_sign(_engine.nid(), &_digest[0], static_cast(_digest.size()), &_signature[0], &sigLen, _key.impl()->getRSA()); // truncate _sig to sigLen if (sigLen < _signature.size()) _signature.resize(sigLen); @@ -99,7 +105,7 @@ bool RSADigestEngine::verify(const DigestEngine::Digest& sig) { digest(); DigestEngine::Digest sigCpy = sig; // copy becausse RSA_verify can modify sigCpy - int ret = RSA_verify(_type, &_digest[0], static_cast(_digest.size()), &sigCpy[0], static_cast(sigCpy.size()), _key.impl()->getRSA()); + int ret = RSA_verify(_engine.nid(), &_digest[0], static_cast(_digest.size()), &sigCpy[0], static_cast(sigCpy.size()), _key.impl()->getRSA()); return ret != 0; } diff --git a/Crypto/testsuite/src/RSATest.cpp b/Crypto/testsuite/src/RSATest.cpp index 556e9fd99..17a113b78 100644 --- a/Crypto/testsuite/src/RSATest.cpp +++ b/Crypto/testsuite/src/RSATest.cpp @@ -149,6 +149,26 @@ void RSATest::testSign() } +void RSATest::testSignSha256() +{ + std::string msg("Test this sign message"); + RSAKey key(RSAKey::KL_2048, RSAKey::EXP_LARGE); + RSADigestEngine eng(key,"SHA256"); + eng.update(msg.c_str(), static_cast(msg.length())); + const Poco::DigestEngine::Digest& sig = eng.signature(); + std::string hexDig = Poco::DigestEngine::digestToHex(sig); + + // verify + std::ostringstream strPub; + key.save(&strPub); + std::string pubKey = strPub.str(); + std::istringstream iPub(pubKey); + RSAKey keyPub(&iPub); + RSADigestEngine eng2(key,"SHA256"); + eng2.update(msg.c_str(), static_cast(msg.length())); + assert (eng2.verify(sig)); +} + void RSATest::testSignManipulated() { std::string msg("Test this sign message"); @@ -244,6 +264,7 @@ CppUnit::Test* RSATest::suite() CppUnit_addTest(pSuite, RSATest, testNewKeys); CppUnit_addTest(pSuite, RSATest, testSign); + CppUnit_addTest(pSuite, RSATest, testSignSha256); CppUnit_addTest(pSuite, RSATest, testSignManipulated); CppUnit_addTest(pSuite, RSATest, testRSACipher); CppUnit_addTest(pSuite, RSATest, testRSACipherLarge); diff --git a/Crypto/testsuite/src/RSATest.h b/Crypto/testsuite/src/RSATest.h index a710e0627..36cfe002b 100644 --- a/Crypto/testsuite/src/RSATest.h +++ b/Crypto/testsuite/src/RSATest.h @@ -48,6 +48,7 @@ public: void testNewKeys(); void testSign(); + void testSignSha256(); void testSignManipulated(); void testRSACipher(); void testRSACipherLarge();