diff options
Diffstat (limited to 'python/rsa/tests')
-rw-r--r-- | python/rsa/tests/__init__.py | 0 | ||||
-rw-r--r-- | python/rsa/tests/constants.py | 9 | ||||
-rw-r--r-- | python/rsa/tests/py2kconstants.py | 3 | ||||
-rw-r--r-- | python/rsa/tests/py3kconstants.py | 3 | ||||
-rw-r--r-- | python/rsa/tests/test_bigfile.py | 60 | ||||
-rw-r--r-- | python/rsa/tests/test_common.py | 61 | ||||
-rw-r--r-- | python/rsa/tests/test_compat.py | 17 | ||||
-rw-r--r-- | python/rsa/tests/test_integers.py | 36 | ||||
-rw-r--r-- | python/rsa/tests/test_load_save_keys.py | 127 | ||||
-rw-r--r-- | python/rsa/tests/test_pem.py | 14 | ||||
-rw-r--r-- | python/rsa/tests/test_pkcs1.py | 94 | ||||
-rw-r--r-- | python/rsa/tests/test_strings.py | 28 | ||||
-rw-r--r-- | python/rsa/tests/test_transform.py | 67 | ||||
-rw-r--r-- | python/rsa/tests/test_varblock.py | 82 |
14 files changed, 601 insertions, 0 deletions
diff --git a/python/rsa/tests/__init__.py b/python/rsa/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/python/rsa/tests/__init__.py diff --git a/python/rsa/tests/constants.py b/python/rsa/tests/constants.py new file mode 100644 index 000000000..6a0d08183 --- /dev/null +++ b/python/rsa/tests/constants.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- + +from rsa._compat import have_python3 + +if have_python3: + from py3kconstants import * +else: + from py2kconstants import * + diff --git a/python/rsa/tests/py2kconstants.py b/python/rsa/tests/py2kconstants.py new file mode 100644 index 000000000..5f695dd22 --- /dev/null +++ b/python/rsa/tests/py2kconstants.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +unicode_string = u"Euro=\u20ac ABCDEFGHIJKLMNOPQRSTUVWXYZ" diff --git a/python/rsa/tests/py3kconstants.py b/python/rsa/tests/py3kconstants.py new file mode 100644 index 000000000..83b67129c --- /dev/null +++ b/python/rsa/tests/py3kconstants.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +unicode_string = "Euro=\u20ac ABCDEFGHIJKLMNOPQRSTUVWXYZ" diff --git a/python/rsa/tests/test_bigfile.py b/python/rsa/tests/test_bigfile.py new file mode 100644 index 000000000..86bcbbac6 --- /dev/null +++ b/python/rsa/tests/test_bigfile.py @@ -0,0 +1,60 @@ +'''Tests block operations.''' +from rsa._compat import b + +try: + from StringIO import StringIO as BytesIO +except ImportError: + from io import BytesIO +import unittest2 + +import rsa +from rsa import bigfile, varblock, pkcs1 + +class BigfileTest(unittest2.TestCase): + + def test_encrypt_decrypt_bigfile(self): + + # Expected block size + 11 bytes padding + pub_key, priv_key = rsa.newkeys((6 + 11) * 8) + + # Encrypt the file + message = b('123456Sybren') + infile = BytesIO(message) + outfile = BytesIO() + + bigfile.encrypt_bigfile(infile, outfile, pub_key) + + # Test + crypto = outfile.getvalue() + + cryptfile = BytesIO(crypto) + clearfile = BytesIO() + + bigfile.decrypt_bigfile(cryptfile, clearfile, priv_key) + self.assertEquals(clearfile.getvalue(), message) + + # We have 2x6 bytes in the message, so that should result in two + # bigfile. + cryptfile.seek(0) + varblocks = list(varblock.yield_varblocks(cryptfile)) + self.assertEqual(2, len(varblocks)) + + + def test_sign_verify_bigfile(self): + + # Large enough to store MD5-sum and ASN.1 code for MD5 + pub_key, priv_key = rsa.newkeys((34 + 11) * 8) + + # Sign the file + msgfile = BytesIO(b('123456Sybren')) + signature = pkcs1.sign(msgfile, priv_key, 'MD5') + + # Check the signature + msgfile.seek(0) + self.assertTrue(pkcs1.verify(msgfile, signature, pub_key)) + + # Alter the message, re-check + msgfile = BytesIO(b('123456sybren')) + self.assertRaises(pkcs1.VerificationError, + pkcs1.verify, msgfile, signature, pub_key) + diff --git a/python/rsa/tests/test_common.py b/python/rsa/tests/test_common.py new file mode 100644 index 000000000..d105dc020 --- /dev/null +++ b/python/rsa/tests/test_common.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import unittest2 +import struct +from rsa._compat import byte, b +from rsa.common import byte_size, bit_size, _bit_size + + +class Test_byte(unittest2.TestCase): + def test_values(self): + self.assertEqual(byte(0), b('\x00')) + self.assertEqual(byte(255), b('\xff')) + + def test_struct_error_when_out_of_bounds(self): + self.assertRaises(struct.error, byte, 256) + self.assertRaises(struct.error, byte, -1) + +class Test_byte_size(unittest2.TestCase): + def test_values(self): + self.assertEqual(byte_size(1 << 1023), 128) + self.assertEqual(byte_size((1 << 1024) - 1), 128) + self.assertEqual(byte_size(1 << 1024), 129) + self.assertEqual(byte_size(255), 1) + self.assertEqual(byte_size(256), 2) + self.assertEqual(byte_size(0xffff), 2) + self.assertEqual(byte_size(0xffffff), 3) + self.assertEqual(byte_size(0xffffffff), 4) + self.assertEqual(byte_size(0xffffffffff), 5) + self.assertEqual(byte_size(0xffffffffffff), 6) + self.assertEqual(byte_size(0xffffffffffffff), 7) + self.assertEqual(byte_size(0xffffffffffffffff), 8) + + def test_zero(self): + self.assertEqual(byte_size(0), 1) + + def test_bad_type(self): + self.assertRaises(TypeError, byte_size, []) + self.assertRaises(TypeError, byte_size, ()) + self.assertRaises(TypeError, byte_size, dict()) + self.assertRaises(TypeError, byte_size, "") + self.assertRaises(TypeError, byte_size, None) + +class Test_bit_size(unittest2.TestCase): + def test_zero(self): + self.assertEqual(bit_size(0), 0) + + def test_values(self): + self.assertEqual(bit_size(1023), 10) + self.assertEqual(bit_size(1024), 11) + self.assertEqual(bit_size(1025), 11) + self.assertEqual(bit_size(1 << 1024), 1025) + self.assertEqual(bit_size((1 << 1024) + 1), 1025) + self.assertEqual(bit_size((1 << 1024) - 1), 1024) + + self.assertEqual(_bit_size(1023), 10) + self.assertEqual(_bit_size(1024), 11) + self.assertEqual(_bit_size(1025), 11) + self.assertEqual(_bit_size(1 << 1024), 1025) + self.assertEqual(_bit_size((1 << 1024) + 1), 1025) + self.assertEqual(_bit_size((1 << 1024) - 1), 1024) diff --git a/python/rsa/tests/test_compat.py b/python/rsa/tests/test_compat.py new file mode 100644 index 000000000..3652c82d5 --- /dev/null +++ b/python/rsa/tests/test_compat.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +import unittest2 +import struct + +from rsa._compat import is_bytes, byte + +class Test_byte(unittest2.TestCase): + def test_byte(self): + for i in range(256): + byt = byte(i) + self.assertTrue(is_bytes(byt)) + self.assertEqual(ord(byt), i) + + def test_raises_StructError_on_overflow(self): + self.assertRaises(struct.error, byte, 256) + self.assertRaises(struct.error, byte, -1) diff --git a/python/rsa/tests/test_integers.py b/python/rsa/tests/test_integers.py new file mode 100644 index 000000000..0a712aa0f --- /dev/null +++ b/python/rsa/tests/test_integers.py @@ -0,0 +1,36 @@ +'''Tests integer operations.''' + +import unittest2 + +import rsa.core + +class IntegerTest(unittest2.TestCase): + + def setUp(self): + (self.pub, self.priv) = rsa.newkeys(64) + + def test_enc_dec(self): + + message = 42 + print("\tMessage: %d" % message) + + encrypted = rsa.core.encrypt_int(message, self.pub.e, self.pub.n) + print("\tEncrypted: %d" % encrypted) + + decrypted = rsa.core.decrypt_int(encrypted, self.priv.d, self.pub.n) + print("\tDecrypted: %d" % decrypted) + + self.assertEqual(message, decrypted) + + def test_sign_verify(self): + + message = 42 + + signed = rsa.core.encrypt_int(message,self.priv.d, self.pub.n) + print("\tSigned: %d" % signed) + + verified = rsa.core.decrypt_int(signed, self.pub.e,self.pub.n) + print("\tVerified: %d" % verified) + + self.assertEqual(message, verified) + diff --git a/python/rsa/tests/test_load_save_keys.py b/python/rsa/tests/test_load_save_keys.py new file mode 100644 index 000000000..fc1a1aaae --- /dev/null +++ b/python/rsa/tests/test_load_save_keys.py @@ -0,0 +1,127 @@ +'''Unittest for saving and loading keys.''' + +import base64 +import unittest2 +from rsa._compat import b + +import rsa.key + +B64PRIV_DER = b('MC4CAQACBQDeKYlRAgMBAAECBQDHn4npAgMA/icCAwDfxwIDANcXAgInbwIDAMZt') +PRIVATE_DER = base64.decodestring(B64PRIV_DER) + +B64PUB_DER = b('MAwCBQDeKYlRAgMBAAE=') +PUBLIC_DER = base64.decodestring(B64PUB_DER) + +PRIVATE_PEM = b(''' +-----BEGIN CONFUSING STUFF----- +Cruft before the key + +-----BEGIN RSA PRIVATE KEY----- +Comment: something blah + +%s +-----END RSA PRIVATE KEY----- + +Stuff after the key +-----END CONFUSING STUFF----- +''' % B64PRIV_DER.decode("utf-8")) + +CLEAN_PRIVATE_PEM = b('''\ +-----BEGIN RSA PRIVATE KEY----- +%s +-----END RSA PRIVATE KEY----- +''' % B64PRIV_DER.decode("utf-8")) + +PUBLIC_PEM = b(''' +-----BEGIN CONFUSING STUFF----- +Cruft before the key + +-----BEGIN RSA PUBLIC KEY----- +Comment: something blah + +%s +-----END RSA PUBLIC KEY----- + +Stuff after the key +-----END CONFUSING STUFF----- +''' % B64PUB_DER.decode("utf-8")) + +CLEAN_PUBLIC_PEM = b('''\ +-----BEGIN RSA PUBLIC KEY----- +%s +-----END RSA PUBLIC KEY----- +''' % B64PUB_DER.decode("utf-8")) + + +class DerTest(unittest2.TestCase): + '''Test saving and loading DER keys.''' + + def test_load_private_key(self): + '''Test loading private DER keys.''' + + key = rsa.key.PrivateKey.load_pkcs1(PRIVATE_DER, 'DER') + expected = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287) + + self.assertEqual(expected, key) + + def test_save_private_key(self): + '''Test saving private DER keys.''' + + key = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287) + der = key.save_pkcs1('DER') + + self.assertEqual(PRIVATE_DER, der) + + def test_load_public_key(self): + '''Test loading public DER keys.''' + + key = rsa.key.PublicKey.load_pkcs1(PUBLIC_DER, 'DER') + expected = rsa.key.PublicKey(3727264081, 65537) + + self.assertEqual(expected, key) + + def test_save_public_key(self): + '''Test saving public DER keys.''' + + key = rsa.key.PublicKey(3727264081, 65537) + der = key.save_pkcs1('DER') + + self.assertEqual(PUBLIC_DER, der) + +class PemTest(unittest2.TestCase): + '''Test saving and loading PEM keys.''' + + + def test_load_private_key(self): + '''Test loading private PEM files.''' + + key = rsa.key.PrivateKey.load_pkcs1(PRIVATE_PEM, 'PEM') + expected = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287) + + self.assertEqual(expected, key) + + def test_save_private_key(self): + '''Test saving private PEM files.''' + + key = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287) + pem = key.save_pkcs1('PEM') + + self.assertEqual(CLEAN_PRIVATE_PEM, pem) + + def test_load_public_key(self): + '''Test loading public PEM files.''' + + key = rsa.key.PublicKey.load_pkcs1(PUBLIC_PEM, 'PEM') + expected = rsa.key.PublicKey(3727264081, 65537) + + self.assertEqual(expected, key) + + def test_save_public_key(self): + '''Test saving public PEM files.''' + + key = rsa.key.PublicKey(3727264081, 65537) + pem = key.save_pkcs1('PEM') + + self.assertEqual(CLEAN_PUBLIC_PEM, pem) + + diff --git a/python/rsa/tests/test_pem.py b/python/rsa/tests/test_pem.py new file mode 100644 index 000000000..867f678a0 --- /dev/null +++ b/python/rsa/tests/test_pem.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +import unittest2 +from rsa._compat import b +from rsa.pem import _markers + + +class Test__markers(unittest2.TestCase): + def test_values(self): + self.assertEqual(_markers('RSA PRIVATE KEY'), + (b('-----BEGIN RSA PRIVATE KEY-----'), + b('-----END RSA PRIVATE KEY-----'))) diff --git a/python/rsa/tests/test_pkcs1.py b/python/rsa/tests/test_pkcs1.py new file mode 100644 index 000000000..d5882dfd1 --- /dev/null +++ b/python/rsa/tests/test_pkcs1.py @@ -0,0 +1,94 @@ +'''Tests string operations.''' + +import struct +import unittest2 + +import rsa +from rsa import pkcs1 +from rsa._compat import byte, is_integer, b, is_bytes + +class BinaryTest(unittest2.TestCase): + + def setUp(self): + (self.pub, self.priv) = rsa.newkeys(256) + + def test_enc_dec(self): + + message = struct.pack('>IIII', 0, 0, 0, 1) + print("\tMessage: %r" % message) + + encrypted = pkcs1.encrypt(message, self.pub) + print("\tEncrypted: %r" % encrypted) + + decrypted = pkcs1.decrypt(encrypted, self.priv) + print("\tDecrypted: %r" % decrypted) + + self.assertEqual(message, decrypted) + + def test_decoding_failure(self): + + message = struct.pack('>IIII', 0, 0, 0, 1) + encrypted = pkcs1.encrypt(message, self.pub) + + # Alter the encrypted stream + a = encrypted[5] + if is_bytes(a): + a = ord(a) + encrypted = encrypted[:5] + byte(a + 1) + encrypted[6:] + + self.assertRaises(pkcs1.DecryptionError, pkcs1.decrypt, encrypted, + self.priv) + + def test_randomness(self): + '''Encrypting the same message twice should result in different + cryptos. + ''' + + message = struct.pack('>IIII', 0, 0, 0, 1) + encrypted1 = pkcs1.encrypt(message, self.pub) + encrypted2 = pkcs1.encrypt(message, self.pub) + + self.assertNotEqual(encrypted1, encrypted2) + +class SignatureTest(unittest2.TestCase): + + def setUp(self): + (self.pub, self.priv) = rsa.newkeys(512) + + def test_sign_verify(self): + '''Test happy flow of sign and verify''' + + message = b('je moeder') + print("\tMessage: %r" % message) + + signature = pkcs1.sign(message, self.priv, 'SHA-256') + print("\tSignature: %r" % signature) + + self.assertTrue(pkcs1.verify(message, signature, self.pub)) + + def test_alter_message(self): + '''Altering the message should let the verification fail.''' + + signature = pkcs1.sign(b('je moeder'), self.priv, 'SHA-256') + self.assertRaises(pkcs1.VerificationError, pkcs1.verify, + b('mijn moeder'), signature, self.pub) + + def test_sign_different_key(self): + '''Signing with another key should let the verification fail.''' + + (otherpub, _) = rsa.newkeys(512) + + message = b('je moeder') + signature = pkcs1.sign(message, self.priv, 'SHA-256') + self.assertRaises(pkcs1.VerificationError, pkcs1.verify, + message, signature, otherpub) + + def test_multiple_signings(self): + '''Signing the same message twice should return the same signatures.''' + + message = struct.pack('>IIII', 0, 0, 0, 1) + signature1 = pkcs1.sign(message, self.priv, 'SHA-1') + signature2 = pkcs1.sign(message, self.priv, 'SHA-1') + + self.assertEqual(signature1, signature2) + diff --git a/python/rsa/tests/test_strings.py b/python/rsa/tests/test_strings.py new file mode 100644 index 000000000..4af06291d --- /dev/null +++ b/python/rsa/tests/test_strings.py @@ -0,0 +1,28 @@ +'''Tests string operations.''' + +from __future__ import absolute_import + +import unittest2 + +import rsa + +from constants import unicode_string + +class StringTest(unittest2.TestCase): + + def setUp(self): + (self.pub, self.priv) = rsa.newkeys(384) + + def test_enc_dec(self): + + message = unicode_string.encode('utf-8') + print("\tMessage: %s" % message) + + encrypted = rsa.encrypt(message, self.pub) + print("\tEncrypted: %s" % encrypted) + + decrypted = rsa.decrypt(encrypted, self.priv) + print("\tDecrypted: %s" % decrypted) + + self.assertEqual(message, decrypted) + diff --git a/python/rsa/tests/test_transform.py b/python/rsa/tests/test_transform.py new file mode 100644 index 000000000..ffd9ec892 --- /dev/null +++ b/python/rsa/tests/test_transform.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- + + +import unittest2 +from rsa._compat import b +from rsa.transform import int2bytes, bytes2int, _int2bytes + + +class Test_int2bytes(unittest2.TestCase): + def test_accuracy(self): + self.assertEqual(int2bytes(123456789), b('\x07[\xcd\x15')) + self.assertEqual(_int2bytes(123456789), b('\x07[\xcd\x15')) + + def test_codec_identity(self): + self.assertEqual(bytes2int(int2bytes(123456789, 128)), 123456789) + self.assertEqual(bytes2int(_int2bytes(123456789, 128)), 123456789) + + def test_chunk_size(self): + self.assertEqual(int2bytes(123456789, 6), b('\x00\x00\x07[\xcd\x15')) + self.assertEqual(int2bytes(123456789, 7), + b('\x00\x00\x00\x07[\xcd\x15')) + + self.assertEqual(_int2bytes(123456789, 6), + b('\x00\x00\x07[\xcd\x15')) + self.assertEqual(_int2bytes(123456789, 7), + b('\x00\x00\x00\x07[\xcd\x15')) + + def test_zero(self): + self.assertEqual(int2bytes(0, 4), b('\x00') * 4) + self.assertEqual(int2bytes(0, 7), b('\x00') * 7) + self.assertEqual(int2bytes(0), b('\x00')) + + self.assertEqual(_int2bytes(0, 4), b('\x00') * 4) + self.assertEqual(_int2bytes(0, 7), b('\x00') * 7) + self.assertEqual(_int2bytes(0), b('\x00')) + + def test_correctness_against_base_implementation(self): + # Slow test. + values = [ + 1 << 512, + 1 << 8192, + 1 << 77, + ] + for value in values: + self.assertEqual(int2bytes(value), _int2bytes(value), + "Boom %d" % value) + self.assertEqual(bytes2int(int2bytes(value)), + value, + "Boom %d" % value) + self.assertEqual(bytes2int(_int2bytes(value)), + value, + "Boom %d" % value) + + def test_raises_OverflowError_when_chunk_size_is_insufficient(self): + self.assertRaises(OverflowError, int2bytes, 123456789, 3) + self.assertRaises(OverflowError, int2bytes, 299999999999, 4) + + self.assertRaises(OverflowError, _int2bytes, 123456789, 3) + self.assertRaises(OverflowError, _int2bytes, 299999999999, 4) + + def test_raises_ValueError_when_negative_integer(self): + self.assertRaises(ValueError, int2bytes, -1) + self.assertRaises(ValueError, _int2bytes, -1) + + def test_raises_TypeError_when_not_integer(self): + self.assertRaises(TypeError, int2bytes, None) + self.assertRaises(TypeError, _int2bytes, None) diff --git a/python/rsa/tests/test_varblock.py b/python/rsa/tests/test_varblock.py new file mode 100644 index 000000000..24ea50f1f --- /dev/null +++ b/python/rsa/tests/test_varblock.py @@ -0,0 +1,82 @@ +'''Tests varblock operations.''' + + +try: + from StringIO import StringIO as BytesIO +except ImportError: + from io import BytesIO +import unittest + +import rsa +from rsa._compat import b +from rsa import varblock + +class VarintTest(unittest.TestCase): + + def test_read_varint(self): + + encoded = b('\xac\x02crummy') + infile = BytesIO(encoded) + + (decoded, read) = varblock.read_varint(infile) + + # Test the returned values + self.assertEqual(300, decoded) + self.assertEqual(2, read) + + # The rest of the file should be untouched + self.assertEqual(b('crummy'), infile.read()) + + def test_read_zero(self): + + encoded = b('\x00crummy') + infile = BytesIO(encoded) + + (decoded, read) = varblock.read_varint(infile) + + # Test the returned values + self.assertEqual(0, decoded) + self.assertEqual(1, read) + + # The rest of the file should be untouched + self.assertEqual(b('crummy'), infile.read()) + + def test_write_varint(self): + + expected = b('\xac\x02') + outfile = BytesIO() + + written = varblock.write_varint(outfile, 300) + + # Test the returned values + self.assertEqual(expected, outfile.getvalue()) + self.assertEqual(2, written) + + + def test_write_zero(self): + + outfile = BytesIO() + written = varblock.write_varint(outfile, 0) + + # Test the returned values + self.assertEqual(b('\x00'), outfile.getvalue()) + self.assertEqual(1, written) + + +class VarblockTest(unittest.TestCase): + + def test_yield_varblock(self): + infile = BytesIO(b('\x01\x0512345\x06Sybren')) + + varblocks = list(varblock.yield_varblocks(infile)) + self.assertEqual([b('12345'), b('Sybren')], varblocks) + +class FixedblockTest(unittest.TestCase): + + def test_yield_fixedblock(self): + + infile = BytesIO(b('123456Sybren')) + + fixedblocks = list(varblock.yield_fixedblocks(infile, 6)) + self.assertEqual([b('123456'), b('Sybren')], fixedblocks) + |