test_pkcs1_15.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. # -*- coding: utf-8 -*-
  2. #
  3. # SelfTest/Signature/test_pkcs1_15.py: Self-test for PKCS#1 v1.5 signatures
  4. #
  5. # ===================================================================
  6. # The contents of this file are dedicated to the public domain. To
  7. # the extent that dedication to the public domain is not available,
  8. # everyone is granted a worldwide, perpetual, royalty-free,
  9. # non-exclusive license to exercise all rights associated with the
  10. # contents of this file for any purpose whatsoever.
  11. # No rights are reserved.
  12. #
  13. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  17. # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  18. # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. # SOFTWARE.
  21. # ===================================================================
  22. __revision__ = "$Id$"
  23. import unittest
  24. from Crypto.PublicKey import RSA
  25. from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
  26. from Crypto.Hash import *
  27. from Crypto import Random
  28. from Crypto.Signature import PKCS1_v1_5 as PKCS
  29. from Crypto.Util.py3compat import *
  30. def isStr(s):
  31. t = ''
  32. try:
  33. t += s
  34. except TypeError:
  35. return 0
  36. return 1
  37. def rws(t):
  38. """Remove white spaces, tabs, and new lines from a string"""
  39. for c in ['\n', '\t', ' ']:
  40. t = t.replace(c,'')
  41. return t
  42. def t2b(t):
  43. """Convert a text string with bytes in hex form to a byte string"""
  44. clean = b(rws(t))
  45. if len(clean)%2 == 1:
  46. raise ValueError("Even number of characters expected")
  47. return a2b_hex(clean)
  48. class PKCS1_15_Tests(unittest.TestCase):
  49. # List of tuples with test data for PKCS#1 v1.5.
  50. # Each tuple is made up by:
  51. # Item #0: dictionary with RSA key component, or key to import
  52. # Item #1: data to hash and sign
  53. # Item #2: signature of the data #1, done with the key #0, after
  54. # hashing it with #3
  55. # Item #3: hash object generator
  56. _testData = (
  57. #
  58. # Taken from ftp://ftp.rsa.com/pub/pkcs/ascii/examples.asc
  59. # "Some Examples of the PKCS Standards", 1999
  60. #
  61. (
  62. # Private key, from 2.1
  63. {
  64. 'n':'''0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0 c0 01 c6
  65. 27 10 27 00 75 14 29 42 e1 9a 8d 8c 51 d0 53 b3 e3 78 2a 1d
  66. e5 dc 5a f4 eb e9 94 68 17 01 14 a1 df e6 7c dc 9a 9a f5 5d
  67. 65 56 20 bb ab''',
  68. 'e':'''01 00
  69. 01''',
  70. 'd':'''01 23 c5 b6 1b a3 6e db 1d 36 79 90 41 99 a8 9e a8 0c 09
  71. b9 12 2e 14 00 c0 9a dc f7 78 46 76 d0 1d 23 35 6a 7d 44 d6
  72. bd 8b d5 0e 94 bf c7 23 fa 87 d8 86 2b 75 17 76 91 c1 1d 75
  73. 76 92 df 88 81'''
  74. },
  75. # Data to sign, from 3.1
  76. '''30 81 a4 02 01 00 30 42 31 0b 30 09 06
  77. 03 55 04 06 13 02 55 53 31 1d 30 1b 06 03 55 04 0a 13 14
  78. 45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61 74 69 6f
  79. 6e 31 14 30 12 06 03 55 04 03 13 0b 54 65 73 74 20 55 73
  80. 65 72 20 31 30 5b 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01
  81. 05 00 03 4a 00 30 47 02 40
  82. 0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0
  83. c0 01 c6 27 10 27 00 75 14 29 42 e1 9a 8d 8c 51
  84. d0 53 b3 e3 78 2a 1d e5 dc 5a f4 eb e9 94 68 17
  85. 01 14 a1 df e6 7c dc 9a 9a f5 5d 65 56 20 bb ab
  86. 02 03 01 00 01''',
  87. # Signature, from 3.2 (at the very end)
  88. '''06 db 36 cb 18 d3 47 5b 9c 01 db 3c 78 95 28 08
  89. 02 79 bb ae ff 2b 7d 55 8e d6 61 59 87 c8 51 86
  90. 3f 8a 6c 2c ff bc 89 c3 f7 5a 18 d9 6b 12 7c 71
  91. 7d 54 d0 d8 04 8d a8 a0 54 46 26 d1 7a 2a 8f be''',
  92. MD2
  93. ),
  94. #
  95. # RSA keypair generated with openssl
  96. #
  97. (
  98. """-----BEGIN RSA PRIVATE KEY-----
  99. MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII
  100. q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8
  101. Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI
  102. OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr
  103. +rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK
  104. JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9
  105. n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ==
  106. -----END RSA PRIVATE KEY-----""",
  107. "This is a test\x0a",
  108. #
  109. # PKCS#1 signature computed with openssl
  110. #
  111. '''4a700a16432a291a3194646952687d5316458b8b86fb0a25aa30e0dcecdb
  112. 442676759ac63d56ec1499c3ae4c0013c2053cabd5b5804848994541ac16
  113. fa243a4d''',
  114. SHA
  115. ),
  116. #
  117. # Test vector from http://www.di-mgt.com.au/rsa_alg.html#signpkcs1
  118. #
  119. (
  120. {
  121. 'n':'''E08973398DD8F5F5E88776397F4EB005BB5383DE0FB7ABDC7DC775290D052E6D
  122. 12DFA68626D4D26FAA5829FC97ECFA82510F3080BEB1509E4644F12CBBD832CF
  123. C6686F07D9B060ACBEEE34096A13F5F7050593DF5EBA3556D961FF197FC981E6
  124. F86CEA874070EFAC6D2C749F2DFA553AB9997702A648528C4EF357385774575F''',
  125. 'e':'''010001''',
  126. 'd':'''00A403C327477634346CA686B57949014B2E8AD2C862B2C7D748096A8B91F736
  127. F275D6E8CD15906027314735644D95CD6763CEB49F56AC2F376E1CEE0EBF282D
  128. F439906F34D86E085BD5656AD841F313D72D395EFE33CBFF29E4030B3D05A28F
  129. B7F18EA27637B07957D32F2BDE8706227D04665EC91BAF8B1AC3EC9144AB7F21'''
  130. },
  131. "abc",
  132. '''60AD5A78FB4A4030EC542C8974CD15F55384E836554CEDD9A322D5F4135C6267
  133. A9D20970C54E6651070B0144D43844C899320DD8FA7819F7EBC6A7715287332E
  134. C8675C136183B3F8A1F81EF969418267130A756FDBB2C71D9A667446E34E0EAD
  135. 9CF31BFB66F816F319D0B7E430A5F2891553986E003720261C7E9022C0D9F11F''',
  136. SHA
  137. )
  138. )
  139. def testSign1(self):
  140. for i in range(len(self._testData)):
  141. row = self._testData[i]
  142. # Build the key
  143. if isStr(row[0]):
  144. key = RSA.importKey(row[0])
  145. else:
  146. comps = [ long(rws(row[0][x]),16) for x in ('n','e','d') ]
  147. key = RSA.construct(comps)
  148. h = row[3].new()
  149. # Data to sign can either be in hex form or not
  150. try:
  151. h.update(t2b(row[1]))
  152. except:
  153. h.update(b(row[1]))
  154. # The real test
  155. signer = PKCS.new(key)
  156. self.failUnless(signer.can_sign())
  157. s = signer.sign(h)
  158. self.assertEqual(s, t2b(row[2]))
  159. def testVerify1(self):
  160. for i in range(len(self._testData)):
  161. row = self._testData[i]
  162. # Build the key
  163. if isStr(row[0]):
  164. key = RSA.importKey(row[0]).publickey()
  165. else:
  166. comps = [ long(rws(row[0][x]),16) for x in ('n','e') ]
  167. key = RSA.construct(comps)
  168. h = row[3].new()
  169. # Data to sign can either be in hex form or not
  170. try:
  171. h.update(t2b(row[1]))
  172. except:
  173. h.update(b(row[1]))
  174. # The real test
  175. verifier = PKCS.new(key)
  176. self.failIf(verifier.can_sign())
  177. result = verifier.verify(h, t2b(row[2]))
  178. self.failUnless(result)
  179. def testSignVerify(self):
  180. rng = Random.new().read
  181. key = RSA.generate(1024, rng)
  182. for hashmod in (MD2,MD5,SHA,SHA224,SHA256,SHA384,SHA512,RIPEMD):
  183. h = hashmod.new()
  184. h.update(b('blah blah blah'))
  185. signer = PKCS.new(key)
  186. s = signer.sign(h)
  187. result = signer.verify(h, s)
  188. self.failUnless(result)
  189. def get_tests(config={}):
  190. tests = []
  191. tests += list_test_cases(PKCS1_15_Tests)
  192. return tests
  193. if __name__ == '__main__':
  194. suite = lambda: unittest.TestSuite(get_tests())
  195. unittest.main(defaultTest='suite')
  196. # vim:set ts=4 sw=4 sts=4 expandtab: