diff options
author | herbertxue <herbertxue@google.com> | 2018-06-12 10:44:13 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2018-06-12 10:44:13 -0700 |
commit | bb1c2dedecd5abed776627728e9f7a02d0665727 (patch) | |
tree | 75545e9a8e9a5fce6df78d519c65628720ec47b5 /tests | |
parent | dbe61a7ce8c6b3a1ffbf632590ea05c61231b687 (diff) | |
parent | d8ac8301abc7ccb1a099ceb7e4d435ea55bf4a46 (diff) | |
download | rsa-bb1c2dedecd5abed776627728e9f7a02d0665727.tar.gz |
Merge commit 'fd70d79' into rsa_3.4.2 Inital commit of rsa 3.4.2 with historymaster-cuttlefish-testing-release
am: d8ac8301ab
Change-Id: Id2b3352d050725b82e9284bd126949cacfdd5a36
Diffstat (limited to 'tests')
-rw-r--r-- | tests/__init__.py | 0 | ||||
-rw-r--r-- | tests/private.pem | 5 | ||||
-rw-r--r-- | tests/test_bigfile.py | 73 | ||||
-rw-r--r-- | tests/test_common.py | 77 | ||||
-rw-r--r-- | tests/test_compat.py | 32 | ||||
-rw-r--r-- | tests/test_integers.py | 50 | ||||
-rw-r--r-- | tests/test_key.py | 42 | ||||
-rw-r--r-- | tests/test_load_save_keys.py | 174 | ||||
-rw-r--r-- | tests/test_parallel.py | 20 | ||||
-rw-r--r-- | tests/test_pem.py | 74 | ||||
-rw-r--r-- | tests/test_pkcs1.py | 107 | ||||
-rw-r--r-- | tests/test_prime.py | 44 | ||||
-rw-r--r-- | tests/test_strings.py | 42 | ||||
-rw-r--r-- | tests/test_transform.py | 80 | ||||
-rw-r--r-- | tests/test_varblock.py | 88 |
15 files changed, 908 insertions, 0 deletions
diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/__init__.py diff --git a/tests/private.pem b/tests/private.pem new file mode 100644 index 0000000..1a17279 --- /dev/null +++ b/tests/private.pem @@ -0,0 +1,5 @@ +-----BEGIN RSA PRIVATE KEY----- +MGECAQACEQCvWovlXBvfEeOMZPEleO9NAgMBAAECEA20Y+6fDkaWvC24horBzQEC +CQDdS2PAL/tK4QIJAMratZuNnT3tAghs7iNYA0ZrgQIIQQ5nU93U4fkCCHR55el6 +/K+2 +-----END RSA PRIVATE KEY----- diff --git a/tests/test_bigfile.py b/tests/test_bigfile.py new file mode 100644 index 0000000..70278dc --- /dev/null +++ b/tests/test_bigfile.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests block operations.""" + +from rsa._compat import b + +try: + from StringIO import StringIO as BytesIO +except ImportError: + from io import BytesIO +import unittest + +import rsa +from rsa import bigfile, varblock, pkcs1 + + +class BigfileTest(unittest.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/tests/test_common.py b/tests/test_common.py new file mode 100644 index 0000000..453dcc8 --- /dev/null +++ b/tests/test_common.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest +import struct +from rsa._compat import byte, b +from rsa.common import byte_size, bit_size, _bit_size + + +class TestByte(unittest.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 TestByteSize(unittest.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 TestBitSize(unittest.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/tests/test_compat.py b/tests/test_compat.py new file mode 100644 index 0000000..8cbf101 --- /dev/null +++ b/tests/test_compat.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest +import struct + +from rsa._compat import is_bytes, byte + + +class TestByte(unittest.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/tests/test_integers.py b/tests/test_integers.py new file mode 100644 index 0000000..fb29ba4 --- /dev/null +++ b/tests/test_integers.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests integer operations.""" + +import unittest + +import rsa +import rsa.core + + +class IntegerTest(unittest.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/tests/test_key.py b/tests/test_key.py new file mode 100644 index 0000000..0e62f55 --- /dev/null +++ b/tests/test_key.py @@ -0,0 +1,42 @@ +""" +Some tests for the rsa/key.py file. +""" + +import unittest + +import rsa.key +import rsa.core + + +class BlindingTest(unittest.TestCase): + def test_blinding(self): + """Test blinding and unblinding. + + This is basically the doctest of the PrivateKey.blind method, but then + implemented as unittest to allow running on different Python versions. + """ + + pk = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287) + + message = 12345 + encrypted = rsa.core.encrypt_int(message, pk.e, pk.n) + + blinded = pk.blind(encrypted, 4134431) # blind before decrypting + decrypted = rsa.core.decrypt_int(blinded, pk.d, pk.n) + unblinded = pk.unblind(decrypted, 4134431) + + self.assertEqual(unblinded, message) + + +class KeyGenTest(unittest.TestCase): + def test_custom_exponent(self): + priv, pub = rsa.key.newkeys(16, exponent=3) + + self.assertEqual(3, priv.e) + self.assertEqual(3, pub.e) + + def test_default_exponent(self): + priv, pub = rsa.key.newkeys(16) + + self.assertEqual(0x10001, priv.e) + self.assertEqual(0x10001, pub.e) diff --git a/tests/test_load_save_keys.py b/tests/test_load_save_keys.py new file mode 100644 index 0000000..6f374cf --- /dev/null +++ b/tests/test_load_save_keys.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +'''Unittest for saving and loading keys.''' + +import base64 +import unittest +import os.path +import pickle + +from rsa._compat import b + +import rsa.key + +B64PRIV_DER = b('MC4CAQACBQDeKYlRAgMBAAECBQDHn4npAgMA/icCAwDfxwIDANcXAgInbwIDAMZt') +PRIVATE_DER = base64.standard_b64decode(B64PRIV_DER) + +B64PUB_DER = b('MAwCBQDeKYlRAgMBAAE=') +PUBLIC_DER = base64.standard_b64decode(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(unittest.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(unittest.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) + + def test_load_from_disk(self): + """Test loading a PEM file from disk.""" + + fname = os.path.join(os.path.dirname(__file__), 'private.pem') + with open(fname, mode='rb') as privatefile: + keydata = privatefile.read() + privkey = rsa.key.PrivateKey.load_pkcs1(keydata) + + self.assertEqual(15945948582725241569, privkey.p) + self.assertEqual(14617195220284816877, privkey.q) + + +class PickleTest(unittest.TestCase): + """Test saving and loading keys by pickling.""" + + def test_private_key(self): + pk = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287) + + pickled = pickle.dumps(pk) + unpickled = pickle.loads(pickled) + self.assertEqual(pk, unpickled) + + def test_public_key(self): + pk = rsa.key.PublicKey(3727264081, 65537) + + pickled = pickle.dumps(pk) + unpickled = pickle.loads(pickled) + + self.assertEqual(pk, unpickled) diff --git a/tests/test_parallel.py b/tests/test_parallel.py new file mode 100644 index 0000000..1a69e9e --- /dev/null +++ b/tests/test_parallel.py @@ -0,0 +1,20 @@ +"""Test for multiprocess prime generation.""" + +import unittest + +import rsa.prime +import rsa.parallel +import rsa.common + + +class ParallelTest(unittest.TestCase): + """Tests for multiprocess prime generation.""" + + def test_parallel_primegen(self): + p = rsa.parallel.getprime(1024, 3) + + self.assertFalse(rsa.prime.is_prime(p - 1)) + self.assertTrue(rsa.prime.is_prime(p)) + self.assertFalse(rsa.prime.is_prime(p + 1)) + + self.assertEqual(1024, rsa.common.bit_size(p)) diff --git a/tests/test_pem.py b/tests/test_pem.py new file mode 100644 index 0000000..952ec79 --- /dev/null +++ b/tests/test_pem.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from rsa._compat import b +from rsa.pem import _markers +import rsa.key + +# 512-bit key. Too small for practical purposes, but good enough for testing with. +public_key_pem = ''' +-----BEGIN PUBLIC KEY----- +MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKH0aYP9ZFuctlPnXhEyHjgc8ltKKx9M +0c+h4sKMXwjhjbQAZdtWIw8RRghpUJnKj+6bN2XzZDazyULxgPhtax0CAwEAAQ== +-----END PUBLIC KEY----- +''' + +private_key_pem = ''' +-----BEGIN RSA PRIVATE KEY----- +MIIBOwIBAAJBAKH0aYP9ZFuctlPnXhEyHjgc8ltKKx9M0c+h4sKMXwjhjbQAZdtW +Iw8RRghpUJnKj+6bN2XzZDazyULxgPhtax0CAwEAAQJADwR36EpNzQTqDzusCFIq +ZS+h9X8aIovgBK3RNhMIGO2ThpsnhiDTcqIvgQ56knbl6B2W4iOl54tJ6CNtf6l6 +zQIhANTaNLFGsJfOvZHcI0WL1r89+1A4JVxR+lpslJJwAvgDAiEAwsjqqZ2wY2F0 +F8p1J98BEbtjU2mEZIVCMn6vQuhWdl8CIDRL4IJl4eGKlB0QP0JJF1wpeGO/R76l +DaPF5cMM7k3NAiEAss28m/ck9BWBfFVdNjx/vsdFZkx2O9AX9EJWoBSnSgECIQCa ++sVQMUVJFGsdE/31C7wCIbE3IpB7ziABZ7mN+V3Dhg== +-----END RSA PRIVATE KEY----- +''' + +# Private key components +prime1 = 96275860229939261876671084930484419185939191875438854026071315955024109172739 +prime2 = 88103681619592083641803383393198542599284510949756076218404908654323473741407 + + +class TestMarkers(unittest.TestCase): + def test_values(self): + self.assertEqual(_markers('RSA PRIVATE KEY'), + (b('-----BEGIN RSA PRIVATE KEY-----'), + b('-----END RSA PRIVATE KEY-----'))) + + +class TestBytesAndStrings(unittest.TestCase): + """Test that we can use PEM in both Unicode strings and bytes.""" + + def test_unicode_public(self): + key = rsa.key.PublicKey.load_pkcs1_openssl_pem(public_key_pem) + self.assertEqual(prime1 * prime2, key.n) + + def test_bytes_public(self): + key = rsa.key.PublicKey.load_pkcs1_openssl_pem(public_key_pem.encode('ascii')) + self.assertEqual(prime1 * prime2, key.n) + + def test_unicode_private(self): + key = rsa.key.PrivateKey.load_pkcs1(private_key_pem) + self.assertEqual(prime1 * prime2, key.n) + + def test_bytes_private(self): + key = rsa.key.PrivateKey.load_pkcs1(private_key_pem.encode('ascii')) + self.assertEqual(prime1, key.p) + self.assertEqual(prime2, key.q) diff --git a/tests/test_pkcs1.py b/tests/test_pkcs1.py new file mode 100644 index 0000000..39555f6 --- /dev/null +++ b/tests/test_pkcs1.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests string operations.""" + +import struct +import unittest + +import rsa +from rsa import pkcs1 +from rsa._compat import byte, b, is_bytes + + +class BinaryTest(unittest.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(unittest.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/tests/test_prime.py b/tests/test_prime.py new file mode 100644 index 0000000..a47c3f2 --- /dev/null +++ b/tests/test_prime.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests prime functions.""" + +import unittest + +import rsa.prime + + +class PrimeTest(unittest.TestCase): + def test_is_prime(self): + """Test some common primes.""" + + # Test some trivial numbers + self.assertFalse(rsa.prime.is_prime(-1)) + self.assertFalse(rsa.prime.is_prime(0)) + self.assertFalse(rsa.prime.is_prime(1)) + self.assertTrue(rsa.prime.is_prime(2)) + self.assertFalse(rsa.prime.is_prime(42)) + self.assertTrue(rsa.prime.is_prime(41)) + + # Test some slightly larger numbers + self.assertEqual( + [907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997], + [x for x in range(901, 1000) if rsa.prime.is_prime(x)] + ) + + # Test around the 50th millionth known prime. + self.assertTrue(rsa.prime.is_prime(982451653)) + self.assertFalse(rsa.prime.is_prime(982451653 * 961748941)) diff --git a/tests/test_strings.py b/tests/test_strings.py new file mode 100644 index 0000000..28fa091 --- /dev/null +++ b/tests/test_strings.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests string operations.""" + +from __future__ import absolute_import + +import unittest + +import rsa + +unicode_string = u"Euro=\u20ac ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + +class StringTest(unittest.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/tests/test_transform.py b/tests/test_transform.py new file mode 100644 index 0000000..7fe121b --- /dev/null +++ b/tests/test_transform.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest +from rsa._compat import b +from rsa.transform import int2bytes, bytes2int, _int2bytes + + +class Test_int2bytes(unittest.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/tests/test_varblock.py b/tests/test_varblock.py new file mode 100644 index 0000000..d1c3730 --- /dev/null +++ b/tests/test_varblock.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests varblock operations.""" + +try: + from StringIO import StringIO as BytesIO +except ImportError: + from io import BytesIO +import unittest + +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) |