OLD | NEW |
(Empty) | |
| 1 # -*- coding: utf-8 -*- |
| 2 # |
| 3 # SelfTest/Cipher/test_pkcs1_15.py: Self-test for PKCS#1 v1.5 encryption |
| 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 |
| 23 __revision__ = "$Id$" |
| 24 |
| 25 import unittest |
| 26 import sys |
| 27 |
| 28 from Crypto.PublicKey import RSA |
| 29 from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex |
| 30 from Crypto import Random |
| 31 from Crypto.Cipher import PKCS1_v1_5 as PKCS |
| 32 from Crypto.Util.py3compat import * |
| 33 |
| 34 def rws(t): |
| 35 """Remove white spaces, tabs, and new lines from a string""" |
| 36 for c in ['\n', '\t', ' ']: |
| 37 t = t.replace(c,'') |
| 38 return t |
| 39 |
| 40 def t2b(t): |
| 41 """Convert a text string with bytes in hex form to a byte string""" |
| 42 clean = b(rws(t)) |
| 43 if len(clean)%2 == 1: |
| 44 print clean |
| 45 raise ValueError("Even number of characters expected") |
| 46 return a2b_hex(clean) |
| 47 |
| 48 class PKCS1_15_Tests(unittest.TestCase): |
| 49 |
| 50 def setUp(self): |
| 51 self.rng = Random.new().read |
| 52 self.key1024 = RSA.generate(1024, self.rng) |
| 53 |
| 54 # List of tuples with test data for PKCS#1 v1.5. |
| 55 # Each tuple is made up by: |
| 56 # Item #0: dictionary with RSA key component, or key to import |
| 57 # Item #1: plaintext |
| 58 # Item #2: ciphertext |
| 59 # Item #3: random data |
| 60 |
| 61 _testData = ( |
| 62 |
| 63 # |
| 64 # Generated with openssl 0.9.8o |
| 65 # |
| 66 ( |
| 67 # Private key |
| 68 '''-----BEGIN RSA PRIVATE KEY----- |
| 69 MIICXAIBAAKBgQDAiAnvIAOvqVwJTaYzsKnefZftgtXGE2hPJppGsWl78yz9jeXY |
| 70 W/FxX/gTPURArNhdnhP6n3p2ZaDIBrO2zizbgIXs0IsljTTcr4vnI8fMXzyNUOjA |
| 71 zP3nzMqZDZK6757XQAobOssMkBFqRWwilT/3DsBhRpl3iMUhF+wvpTSHewIDAQAB |
| 72 AoGAC4HV/inOrpgTvSab8Wj0riyZgQOZ3U3ZpSlsfR8ra9Ib9Uee3jCYnKscu6Gk |
| 73 y6zI/cdt8EPJ4PuwAWSNJzbpbVaDvUq25OD+CX8/uRT08yBS4J8TzBitZJTD4lS7 |
| 74 atdTnKT0Wmwk+u8tDbhvMKwnUHdJLcuIsycts9rwJVapUtkCQQDvDpx2JMun0YKG |
| 75 uUttjmL8oJ3U0m3ZvMdVwBecA0eebZb1l2J5PvI3EJD97eKe91Nsw8T3lwpoN40k |
| 76 IocSVDklAkEAzi1HLHE6EzVPOe5+Y0kGvrIYRRhncOb72vCvBZvD6wLZpQgqo6c4 |
| 77 d3XHFBBQWA6xcvQb5w+VVEJZzw64y25sHwJBAMYReRl6SzL0qA0wIYrYWrOt8JeQ |
| 78 8mthulcWHXmqTgC6FEXP9Es5GD7/fuKl4wqLKZgIbH4nqvvGay7xXLCXD/ECQH9a |
| 79 1JYNMtRen5unSAbIOxRcKkWz92F0LKpm9ZW/S9vFHO+mBcClMGoKJHiuQxLBsLbT |
| 80 NtEZfSJZAeS2sUtn3/0CQDb2M2zNBTF8LlM0nxmh0k9VGm5TVIyBEMcipmvOgqIs |
| 81 HKukWBcq9f/UOmS0oEhai/6g+Uf7VHJdWaeO5LzuvwU= |
| 82 -----END RSA PRIVATE KEY-----''', |
| 83 # Plaintext |
| 84 '''THIS IS PLAINTEXT\x0A''', |
| 85 # Ciphertext |
| 86 '''3f dc fd 3c cd 5c 9b 12 af 65 32 e3 f7 d0 da 36 |
| 87 8f 8f d9 e3 13 1c 7f c8 b3 f9 c1 08 e4 eb 79 9c |
| 88 91 89 1f 96 3b 94 77 61 99 a4 b1 ee 5d e6 17 c9 |
| 89 5d 0a b5 63 52 0a eb 00 45 38 2a fb b0 71 3d 11 |
| 90 f7 a1 9e a7 69 b3 af 61 c0 bb 04 5b 5d 4b 27 44 |
| 91 1f 5b 97 89 ba 6a 08 95 ee 4f a2 eb 56 64 e5 0f |
| 92 da 7c f9 9a 61 61 06 62 ed a0 bc 5f aa 6c 31 78 |
| 93 70 28 1a bb 98 3c e3 6a 60 3c d1 0b 0f 5a f4 75''', |
| 94 # Random data |
| 95 '''eb d7 7d 86 a4 35 23 a3 54 7e 02 0b 42 1d |
| 96 61 6c af 67 b8 4e 17 56 80 66 36 04 64 34 26 8a |
| 97 47 dd 44 b3 1a b2 17 60 f4 91 2e e2 b5 95 64 cc |
| 98 f9 da c8 70 94 54 86 4c ef 5b 08 7d 18 c4 ab 8d |
| 99 04 06 33 8f ca 15 5f 52 60 8a a1 0c f5 08 b5 4c |
| 100 bb 99 b8 94 25 04 9c e6 01 75 e6 f9 63 7a 65 61 |
| 101 13 8a a7 47 77 81 ae 0d b8 2c 4d 50 a5''' |
| 102 ), |
| 103 ) |
| 104 |
| 105 def testEncrypt1(self): |
| 106 for test in self._testData: |
| 107 # Build the key |
| 108 key = RSA.importKey(test[0]) |
| 109 # RNG that takes its random numbers from a pool given |
| 110 # at initialization |
| 111 class randGen: |
| 112 def __init__(self, data): |
| 113 self.data = data |
| 114 self.idx = 0 |
| 115 def __call__(self, N): |
| 116 r = self.data[self.idx:N] |
| 117 self.idx += N |
| 118 return r |
| 119 # The real test |
| 120 key._randfunc = randGen(t2b(test[3])) |
| 121 cipher = PKCS.new(key) |
| 122 ct = cipher.encrypt(b(test[1])) |
| 123 self.assertEqual(ct, t2b(test[2])) |
| 124 |
| 125 def testEncrypt2(self): |
| 126 # Verify that encryption fail if plaintext is too long |
| 127 pt = '\x00'*(128-11+1) |
| 128 cipher = PKCS.new(self.key1024) |
| 129 self.assertRaises(ValueError, cipher.encrypt, pt) |
| 130 |
| 131 def testVerify1(self): |
| 132 for test in self._testData: |
| 133 # Build the key |
| 134 key = RSA.importKey(test[0]) |
| 135 # The real test |
| 136 cipher = PKCS.new(key) |
| 137 pt = cipher.decrypt(t2b(test[2]), "---") |
| 138 self.assertEqual(pt, b(test[1])) |
| 139 |
| 140 def testVerify2(self): |
| 141 # Verify that decryption fails if ciphertext is not as long as |
| 142 # RSA modulus |
| 143 cipher = PKCS.new(self.key1024) |
| 144 self.assertRaises(ValueError, cipher.decrypt, '\x00'*127, "---") |
| 145 self.assertRaises(ValueError, cipher.decrypt, '\x00'*129, "---") |
| 146 |
| 147 # Verify that decryption fails if there are less then 8 non-zero
padding |
| 148 # bytes |
| 149 pt = b('\x00\x02' + '\xFF'*7 + '\x00' + '\x45'*118) |
| 150 ct = self.key1024.encrypt(pt, 0)[0] |
| 151 ct = b('\x00'*(128-len(ct))) + ct |
| 152 self.assertEqual("---", cipher.decrypt(ct, "---")) |
| 153 |
| 154 def testEncryptVerify1(self): |
| 155 # Encrypt/Verify messages of length [0..RSAlen-11] |
| 156 # and therefore padding [8..117] |
| 157 for pt_len in xrange(0,128-11+1): |
| 158 pt = self.rng(pt_len) |
| 159 cipher = PKCS.new(self.key1024) |
| 160 ct = cipher.encrypt(pt) |
| 161 pt2 = cipher.decrypt(ct, "---") |
| 162 self.assertEqual(pt,pt2) |
| 163 |
| 164 |
| 165 def get_tests(config={}): |
| 166 tests = [] |
| 167 tests += list_test_cases(PKCS1_15_Tests) |
| 168 return tests |
| 169 |
| 170 if __name__ == '__main__': |
| 171 suite = lambda: unittest.TestSuite(get_tests()) |
| 172 unittest.main(defaultTest='suite') |
| 173 |
| 174 # vim:set ts=4 sw=4 sts=4 expandtab: |
OLD | NEW |