aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorherbertxue <herbertxue@google.com>2018-06-12 10:44:13 -0700
committerandroid-build-merger <android-build-merger@google.com>2018-06-12 10:44:13 -0700
commitbb1c2dedecd5abed776627728e9f7a02d0665727 (patch)
tree75545e9a8e9a5fce6df78d519c65628720ec47b5 /tests
parentdbe61a7ce8c6b3a1ffbf632590ea05c61231b687 (diff)
parentd8ac8301abc7ccb1a099ceb7e4d435ea55bf4a46 (diff)
downloadrsa-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__.py0
-rw-r--r--tests/private.pem5
-rw-r--r--tests/test_bigfile.py73
-rw-r--r--tests/test_common.py77
-rw-r--r--tests/test_compat.py32
-rw-r--r--tests/test_integers.py50
-rw-r--r--tests/test_key.py42
-rw-r--r--tests/test_load_save_keys.py174
-rw-r--r--tests/test_parallel.py20
-rw-r--r--tests/test_pem.py74
-rw-r--r--tests/test_pkcs1.py107
-rw-r--r--tests/test_prime.py44
-rw-r--r--tests/test_strings.py42
-rw-r--r--tests/test_transform.py80
-rw-r--r--tests/test_varblock.py88
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)