RSATest.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. //
  2. // RSATest.cpp
  3. //
  4. // Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
  5. // and Contributors.
  6. //
  7. // SPDX-License-Identifier: BSL-1.0
  8. //
  9. #include "RSATest.h"
  10. #include "CppUnit/TestCaller.h"
  11. #include "CppUnit/TestSuite.h"
  12. #include "Poco/Crypto/RSADigestEngine.h"
  13. #include "Poco/Crypto/CipherFactory.h"
  14. #include "Poco/Crypto/Cipher.h"
  15. #include "Poco/Crypto/X509Certificate.h"
  16. #include "Poco/Path.h"
  17. #include "Poco/File.h"
  18. #include <sstream>
  19. #include <fstream>
  20. using namespace Poco::Crypto;
  21. static const std::string anyPem(
  22. "-----BEGIN CERTIFICATE-----\r\n"
  23. "MIICaDCCAdECCQCzfxSsk7yaLjANBgkqhkiG9w0BAQUFADBzMQswCQYDVQQGEwJB\r\n"
  24. "VDESMBAGA1UECBMJQ2FyaW50aGlhMRIwEAYDVQQHEwlTdC4gSmFrb2IxDzANBgNV\r\n"
  25. "BAoTBkFwcEluZjEPMA0GA1UEAxMGQXBwSW5mMRowGAYJKoZIhvcNAQkBFgthcHBA\r\n"
  26. "aW5mLmNvbTAeFw0wNjAzMDExMzA3MzFaFw0wNjAzMzExMzA3MzFaMH4xCzAJBgNV\r\n"
  27. "BAYTAkFUMRIwEAYDVQQIEwlDYXJpbnRoaWExETAPBgNVBAcTCFN0IEpha29iMRww\r\n"
  28. "GgYDVQQKExNBcHBsaWVkIEluZm9ybWF0aWNzMQowCAYDVQQDFAEqMR4wHAYJKoZI\r\n"
  29. "hvcNAQkBFg9pbmZvQGFwcGluZi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ\r\n"
  30. "AoGBAJHGyXDHyCYoWz+65ltNwwZbhwOGnxr9P1WMATuFJh0bPBZxKbZRdbTm9KhZ\r\n"
  31. "OlvsEIsfgiYdsxURYIqXfEgISYLZcZY0pQwGEOmB+0NeC/+ENSfOlNSthx6zSVlc\r\n"
  32. "zhJ7+dJOGwepHAiLr1fRuc5jogYLraE+lKTnqAAFfzwvti77AgMBAAEwDQYJKoZI\r\n"
  33. "hvcNAQEFBQADgYEAY/ZoeY1ukkEJX7259NeoVM0oahlulWV0rlCqyaeosOiDORPT\r\n"
  34. "m6X1w/5MTCf9VyaD1zukoSZ4QqNVjHFXcXidbB7Tgt3yRuZ5PC5LIFCDPv9mgPne\r\n"
  35. "mUA70yfctNfza2z3ZiQ6NDkW3mZX+1tmxYIrJQIrkVeYeqf1Gh2nyZrUMcE=\r\n"
  36. "-----END CERTIFICATE-----\r\n"
  37. "-----BEGIN RSA PRIVATE KEY-----\r\n"
  38. "Proc-Type: 4,ENCRYPTED\r\n"
  39. "DEK-Info: DES-EDE3-CBC,E7AE93C9E49184EA\r\n"
  40. "\r\n"
  41. "A2IqzNcWs+I5vzV+i+woDk56+yr58eU0Onw8eEvXkLjnSc58JU4327IF7yUbKWdW\r\n"
  42. "Q7BYGGOkVFiZ7ANOwviDg5SUhxRDWCcW8dS6/p1vfdQ1C3qj2OwJjkpg0aDBIzJn\r\n"
  43. "FzgguT3MF3ama77vxv0S3kOfmCj62MLqPGpj5pQ0/1hefRFbL8oAX8bXUN7/rmGM\r\n"
  44. "Zc0QyzFZv2iQ04dY/6TNclwKPB4H0On4K+8BMs3PRkWA0clCaQaFO2+iwnk3XZfe\r\n"
  45. "+MsKUEbLCpAQeYspYv1cw38dCdWq1KTP5aJk+oXgwjfX5cAaPTz74NTqTIsCcaTD\r\n"
  46. "3vy7ukJYFlDR9Kyo7z8rMazYrKJslhnuRH0BhK9st9McwL957j5tZmrKyraCcmCx\r\n"
  47. "dMAGcsis1va3ayYZpIpFqA4EhYrTM+6N8ZRfUap20+b5IQwHfTQDejUhL6rBwy7j\r\n"
  48. "Ti5yD83/itoOMyXq2sV/XWfVD5zk/P5iv22O1EAQMhhnPB9K/I/JhuSGQJfn3cNh\r\n"
  49. "ykOUYT0+vDeSeEVa+FVEP1W35G0alTbKbNs5Tb8KxJ3iDJUxokM//SvPXZy9hOVX\r\n"
  50. "Y05imB04J15DaGbAHlNzunhuJi7121WV/JRXZRW9diE6hwpD8rwqi3FMuRUmy7U9\r\n"
  51. "aFA5poKRAYlo9YtZ3YpFyjGKB6MfCQcB2opuSnQ/gbugV41m67uQ4CDwWLaNRkTb\r\n"
  52. "GlsMBNcHnidg15Bsat5HaB7l250ukrI13Uw1MYdDUzaS3gPfw9aC4F2w0p3U+DPH\r\n"
  53. "80/zePxtroR7T4/+rI136Rl+aMXDMOEGCX1TVP8rjuZzuRyUSUKC8Q==\r\n"
  54. "-----END RSA PRIVATE KEY-----\r\n"
  55. "-----BEGIN CERTIFICATE-----\r\n"
  56. "MIICXTCCAcYCCQC1Vk/N8qR4AjANBgkqhkiG9w0BAQUFADBzMQswCQYDVQQGEwJB\r\n"
  57. "VDESMBAGA1UECBMJQ2FyaW50aGlhMRIwEAYDVQQHEwlTdC4gSmFrb2IxDzANBgNV\r\n"
  58. "BAoTBkFwcEluZjEPMA0GA1UEAxMGQXBwSW5mMRowGAYJKoZIhvcNAQkBFgthcHBA\r\n"
  59. "aW5mLmNvbTAeFw0wNjAyMjcxMzI3MThaFw0wNjAzMjkxMzI3MThaMHMxCzAJBgNV\r\n"
  60. "BAYTAkFUMRIwEAYDVQQIEwlDYXJpbnRoaWExEjAQBgNVBAcTCVN0LiBKYWtvYjEP\r\n"
  61. "MA0GA1UEChMGQXBwSW5mMQ8wDQYDVQQDEwZBcHBJbmYxGjAYBgkqhkiG9w0BCQEW\r\n"
  62. "C2FwcEBpbmYuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsFXiPuicN\r\n"
  63. "Im4oJwF8NuaFN+lgYwcZ6dAO3ILIR3kLA2PxF8HSQLfF8J8a4odZhLhctIMAKTxm\r\n"
  64. "k0w8TW5qhL8QLdGzY9vzvkgdKOkan2t3sMeXJAfrM1AphTsmgntAQazGZjOj5p4W\r\n"
  65. "jDnxQ+VXAylqwjHh49eSBxM3wgoscF4iLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GB\r\n"
  66. "AIpfLdXiKchPvFMhQS8xTtXvrw5dVL3yImUMYs4GQi8RrjGmfGB3yMAR7B/b8v4a\r\n"
  67. "+ztfusgWAWiUKuSGTk4S8YB0fsFlmOv0WDr+PyZ4Lui/a8opbyzGE7rqpnF/s0GO\r\n"
  68. "M7uLCNNwIN7WhmxcWV0KZU1wTppoSWPJda1yTbBzF9XP\r\n"
  69. "-----END CERTIFICATE-----\r\n"
  70. );
  71. RSATest::RSATest(const std::string& name): CppUnit::TestCase(name)
  72. {
  73. }
  74. RSATest::~RSATest()
  75. {
  76. }
  77. void RSATest::testNewKeys()
  78. {
  79. RSAKey key(RSAKey::KL_1024, RSAKey::EXP_SMALL);
  80. std::ostringstream strPub;
  81. std::ostringstream strPriv;
  82. key.save(&strPub, &strPriv, "testpwd");
  83. std::string pubKey = strPub.str();
  84. std::string privKey = strPriv.str();
  85. // now do the round trip
  86. std::istringstream iPub(pubKey);
  87. std::istringstream iPriv(privKey);
  88. RSAKey key2(&iPub, &iPriv, "testpwd");
  89. std::istringstream iPriv2(privKey);
  90. RSAKey key3(0, &iPriv2, "testpwd");
  91. std::ostringstream strPub3;
  92. key3.save(&strPub3);
  93. std::string pubFromPrivate = strPub3.str();
  94. assertTrue (pubFromPrivate == pubKey);
  95. }
  96. void RSATest::testNewKeysNoPassphrase()
  97. {
  98. RSAKey key(RSAKey::KL_1024, RSAKey::EXP_SMALL);
  99. std::ostringstream strPub;
  100. std::ostringstream strPriv;
  101. key.save(&strPub, &strPriv);
  102. std::string pubKey = strPub.str();
  103. std::string privKey = strPriv.str();
  104. // now do the round trip
  105. std::istringstream iPub(pubKey);
  106. std::istringstream iPriv(privKey);
  107. RSAKey key2(&iPub, &iPriv);
  108. std::istringstream iPriv2(privKey);
  109. RSAKey key3(0, &iPriv2);
  110. std::ostringstream strPub3;
  111. key3.save(&strPub3);
  112. std::string pubFromPrivate = strPub3.str();
  113. assertTrue (pubFromPrivate == pubKey);
  114. }
  115. void RSATest::testSign()
  116. {
  117. std::string msg("Test this sign message");
  118. RSAKey key(RSAKey::KL_2048, RSAKey::EXP_LARGE);
  119. RSADigestEngine eng(key);
  120. eng.update(msg.c_str(), static_cast<unsigned>(msg.length()));
  121. const Poco::DigestEngine::Digest& sig = eng.signature();
  122. std::string hexDig = Poco::DigestEngine::digestToHex(sig);
  123. // verify
  124. std::ostringstream strPub;
  125. key.save(&strPub);
  126. std::string pubKey = strPub.str();
  127. std::istringstream iPub(pubKey);
  128. RSAKey keyPub(&iPub);
  129. RSADigestEngine eng2(keyPub);
  130. eng2.update(msg.c_str(), static_cast<unsigned>(msg.length()));
  131. assertTrue (eng2.verify(sig));
  132. }
  133. void RSATest::testSignSha256()
  134. {
  135. std::string msg("Test this sign message");
  136. RSAKey key(RSAKey::KL_2048, RSAKey::EXP_LARGE);
  137. RSADigestEngine eng(key, "SHA256");
  138. eng.update(msg.c_str(), static_cast<unsigned>(msg.length()));
  139. const Poco::DigestEngine::Digest& sig = eng.signature();
  140. std::string hexDig = Poco::DigestEngine::digestToHex(sig);
  141. // verify
  142. std::ostringstream strPub;
  143. key.save(&strPub);
  144. std::string pubKey = strPub.str();
  145. std::istringstream iPub(pubKey);
  146. RSAKey keyPub(&iPub);
  147. RSADigestEngine eng2(keyPub, "SHA256");
  148. eng2.update(msg.c_str(), static_cast<unsigned>(msg.length()));
  149. assertTrue (eng2.verify(sig));
  150. }
  151. void RSATest::testSignManipulated()
  152. {
  153. std::string msg("Test this sign message");
  154. std::string msgManip("Test that sign message");
  155. RSAKey key(RSAKey::KL_2048, RSAKey::EXP_LARGE);
  156. RSADigestEngine eng(key);
  157. eng.update(msg.c_str(), static_cast<unsigned>(msg.length()));
  158. const Poco::DigestEngine::Digest& sig = eng.signature();
  159. std::string hexDig = Poco::DigestEngine::digestToHex(sig);
  160. // verify
  161. std::ostringstream strPub;
  162. key.save(&strPub);
  163. std::string pubKey = strPub.str();
  164. std::istringstream iPub(pubKey);
  165. RSAKey keyPub(&iPub);
  166. RSADigestEngine eng2(keyPub);
  167. eng2.update(msgManip.c_str(), static_cast<unsigned>(msgManip.length()));
  168. assertTrue (!eng2.verify(sig));
  169. }
  170. void RSATest::testRSACipher()
  171. {
  172. Cipher::Ptr pCipher = CipherFactory::defaultFactory().createCipher(RSAKey(RSAKey::KL_1024, RSAKey::EXP_SMALL));
  173. for (std::size_t n = 1; n <= 1200; n++)
  174. {
  175. std::string val(n, 'x');
  176. std::string enc = pCipher->encryptString(val);
  177. std::string dec = pCipher->decryptString(enc);
  178. assertTrue (dec == val);
  179. }
  180. RSAKey key(RSAKey::KL_1024, RSAKey::EXP_SMALL);
  181. std::string pubKeyFile = Poco::Path::temp() + "poco.key.pub";
  182. std::string privKeyFile = Poco::Path::temp() + "poco.key.priv";
  183. if (Poco::File(pubKeyFile).exists()) Poco::File(pubKeyFile).remove();
  184. if (Poco::File(privKeyFile).exists()) Poco::File(privKeyFile).remove();
  185. std::ofstream strPub(pubKeyFile);
  186. std::ofstream strPriv(privKeyFile);
  187. key.save(&strPub, &strPriv);
  188. strPub.close();
  189. strPriv.close();
  190. Poco::Crypto::RSAKey encryptKey(pubKeyFile);
  191. Poco::Crypto::RSAKey decryptKey(pubKeyFile, privKeyFile);
  192. Poco::Crypto::CipherFactory factory;
  193. auto iengine = factory.createCipher(encryptKey);
  194. auto oengine = factory.createCipher(decryptKey);
  195. std::string ss = "test_str";
  196. auto enc = iengine->encryptString(ss);
  197. auto dec = oengine->decryptString(enc);
  198. assertEqual (ss, dec);
  199. delete iengine;
  200. delete oengine;
  201. }
  202. void RSATest::testRSACipherLarge()
  203. {
  204. std::vector<std::size_t> sizes;
  205. sizes.push_back (2047);
  206. sizes.push_back (2048);
  207. sizes.push_back (2049);
  208. sizes.push_back (4095);
  209. sizes.push_back (4096);
  210. sizes.push_back (4097);
  211. sizes.push_back (8191);
  212. sizes.push_back (8192);
  213. sizes.push_back (8193);
  214. sizes.push_back (16383);
  215. sizes.push_back (16384);
  216. sizes.push_back (16385);
  217. Cipher::Ptr pCipher = CipherFactory::defaultFactory().createCipher(RSAKey(RSAKey::KL_1024, RSAKey::EXP_SMALL));
  218. for (std::vector<std::size_t>::const_iterator it = sizes.begin(); it != sizes.end(); ++it)
  219. {
  220. std::string val(*it, 'x');
  221. std::string enc = pCipher->encryptString(val);
  222. std::string dec = pCipher->decryptString(enc);
  223. assertTrue (dec == val);
  224. }
  225. }
  226. void RSATest::testCertificate()
  227. {
  228. std::istringstream str(anyPem);
  229. X509Certificate cert(str);
  230. RSAKey publicKey(cert);
  231. std::istringstream str2(anyPem);
  232. RSAKey privateKey(0, &str2, "test");
  233. Cipher::Ptr pCipher = CipherFactory::defaultFactory().createCipher(publicKey);
  234. Cipher::Ptr pCipher2 = CipherFactory::defaultFactory().createCipher(privateKey);
  235. std::string val("lets do some encryption");
  236. std::string enc = pCipher->encryptString(val);
  237. std::string dec = pCipher2->decryptString(enc);
  238. assertTrue (dec == val);
  239. }
  240. void RSATest::setUp()
  241. {
  242. }
  243. void RSATest::tearDown()
  244. {
  245. }
  246. CppUnit::Test* RSATest::suite()
  247. {
  248. CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("RSATest");
  249. CppUnit_addTest(pSuite, RSATest, testNewKeys);
  250. CppUnit_addTest(pSuite, RSATest, testNewKeysNoPassphrase);
  251. CppUnit_addTest(pSuite, RSATest, testSign);
  252. CppUnit_addTest(pSuite, RSATest, testSignSha256);
  253. CppUnit_addTest(pSuite, RSATest, testSignManipulated);
  254. CppUnit_addTest(pSuite, RSATest, testRSACipher);
  255. CppUnit_addTest(pSuite, RSATest, testRSACipherLarge);
  256. CppUnit_addTest(pSuite, RSATest, testCertificate);
  257. return pSuite;
  258. }