blob: d881d20ed9212c14e117e64d599e69f0d3f959b8 [file] [log] [blame]
Roy Kokkelkoren0659aac2015-10-25 15:12:111# Copyright 2011 Sybren A. Stüvel <[email protected]>
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
Sybren A. Stüvel3934ab42016-02-05 15:01:207# https://www.apache.org/licenses/LICENSE-2.0
Roy Kokkelkoren0659aac2015-10-25 15:12:118#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
Sybren A. Stüvelf0627be2016-03-17 14:52:2315"""Unittest for saving and loading keys."""
Sybren A. Stüvelfa346792011-07-19 21:53:5916
17import base64
Sybren A. Stüvelf68c52a2016-01-18 14:39:5018import os.path
Sybren A. Stüvel4bc97332016-01-22 14:41:4019import pickle
Michael Manganiello0c906332017-01-05 12:51:1220import unittest
21import warnings
Sybren A. Stüvelded036c2019-08-04 13:02:2022from unittest import mock
Sybren A. Stüvelf68c52a2016-01-18 14:39:5023
Sybren A. Stüvelfa346792011-07-19 21:53:5924import rsa.key
25
adamantike9f577402016-05-08 18:36:5726B64PRIV_DER = b'MC4CAQACBQDeKYlRAgMBAAECBQDHn4npAgMA/icCAwDfxwIDANcXAgInbwIDAMZt'
Sybren A. Stüvele798a6e2016-01-18 14:39:0027PRIVATE_DER = base64.standard_b64decode(B64PRIV_DER)
Sybren A. Stüvelfa346792011-07-19 21:53:5928
adamantike9f577402016-05-08 18:36:5729B64PUB_DER = b'MAwCBQDeKYlRAgMBAAE='
Sybren A. Stüvele798a6e2016-01-18 14:39:0030PUBLIC_DER = base64.standard_b64decode(B64PUB_DER)
Sybren A. Stüvel74023dc2011-07-24 16:29:1731
adamantike9f577402016-05-08 18:36:5732PRIVATE_PEM = b'''\
Sybren A. Stüvelfa346792011-07-19 21:53:5933-----BEGIN CONFUSING STUFF-----
34Cruft before the key
35
36-----BEGIN RSA PRIVATE KEY-----
Sybren A. Stüvel70bc1a52011-07-30 18:13:0937Comment: something blah
38
adamantike9f577402016-05-08 18:36:5739''' + B64PRIV_DER + b'''
Sybren A. Stüvelfa346792011-07-19 21:53:5940-----END RSA PRIVATE KEY-----
41
42Stuff after the key
43-----END CONFUSING STUFF-----
adamantike9f577402016-05-08 18:36:5744'''
Sybren A. Stüvelfa346792011-07-19 21:53:5945
adamantike9f577402016-05-08 18:36:5746CLEAN_PRIVATE_PEM = b'''\
Sybren A. Stüvelf6a10732011-07-19 23:11:3447-----BEGIN RSA PRIVATE KEY-----
adamantike9f577402016-05-08 18:36:5748''' + B64PRIV_DER + b'''
Sybren A. Stüvelf6a10732011-07-19 23:11:3449-----END RSA PRIVATE KEY-----
adamantike9f577402016-05-08 18:36:5750'''
Sybren A. Stüvelf6a10732011-07-19 23:11:3451
adamantike9f577402016-05-08 18:36:5752PUBLIC_PEM = b'''\
Sybren A. Stüvel74023dc2011-07-24 16:29:1753-----BEGIN CONFUSING STUFF-----
54Cruft before the key
55
56-----BEGIN RSA PUBLIC KEY-----
Sybren A. Stüvel70bc1a52011-07-30 18:13:0957Comment: something blah
58
adamantike9f577402016-05-08 18:36:5759''' + B64PUB_DER + b'''
Sybren A. Stüvel74023dc2011-07-24 16:29:1760-----END RSA PUBLIC KEY-----
61
62Stuff after the key
63-----END CONFUSING STUFF-----
adamantike9f577402016-05-08 18:36:5764'''
Sybren A. Stüvel74023dc2011-07-24 16:29:1765
adamantike9f577402016-05-08 18:36:5766CLEAN_PUBLIC_PEM = b'''\
Sybren A. Stüvel74023dc2011-07-24 16:29:1767-----BEGIN RSA PUBLIC KEY-----
adamantike9f577402016-05-08 18:36:5768''' + B64PUB_DER + b'''
Sybren A. Stüvel74023dc2011-07-24 16:29:1769-----END RSA PUBLIC KEY-----
adamantike9f577402016-05-08 18:36:5770'''
Sybren A. Stüvel74023dc2011-07-24 16:29:1771
Sybren A. Stüvelfa346792011-07-19 21:53:5972
Sybren A. Stüveled1c81d2016-01-14 11:23:3273class DerTest(unittest.TestCase):
Sybren A. Stüveld3d10342016-01-22 10:36:0674 """Test saving and loading DER keys."""
Sybren A. Stüvelfa346792011-07-19 21:53:5975
76 def test_load_private_key(self):
Sybren A. Stüveld3d10342016-01-22 10:36:0677 """Test loading private DER keys."""
Sybren A. Stüvelfa346792011-07-19 21:53:5978
Sybren A. Stüvelaa5a7fd2011-07-24 17:06:3279 key = rsa.key.PrivateKey.load_pkcs1(PRIVATE_DER, 'DER')
Sybren A. Stüvelfa346792011-07-19 21:53:5980 expected = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
81
82 self.assertEqual(expected, key)
Michael Manganiello0c906332017-01-05 12:51:1283 self.assertEqual(key.exp1, 55063)
84 self.assertEqual(key.exp2, 10095)
85 self.assertEqual(key.coef, 50797)
86
87 @mock.patch('pyasn1.codec.der.decoder.decode')
88 def test_load_malformed_private_key(self, der_decode):
89 """Test loading malformed private DER keys."""
90
91 # Decode returns an invalid exp2 value.
92 der_decode.return_value = (
93 [0, 3727264081, 65537, 3349121513, 65063, 57287, 55063, 0, 50797],
94 0,
95 )
96
97 with warnings.catch_warnings(record=True) as w:
98 # Always print warnings
99 warnings.simplefilter('always')
100
101 # Load 3 keys
102 for _ in range(3):
103 key = rsa.key.PrivateKey.load_pkcs1(PRIVATE_DER, 'DER')
104
105 # Check that 3 warnings were generated.
106 self.assertEqual(3, len(w))
107
108 for warning in w:
109 self.assertTrue(issubclass(warning.category, UserWarning))
110 self.assertIn('malformed', str(warning.message))
111
112 # Check that we are creating the key with correct values
113 self.assertEqual(key.exp1, 55063)
114 self.assertEqual(key.exp2, 10095)
115 self.assertEqual(key.coef, 50797)
Sybren A. Stüvelfa346792011-07-19 21:53:59116
Sybren A. Stüvelf6a10732011-07-19 23:11:34117 def test_save_private_key(self):
Sybren A. Stüveld3d10342016-01-22 10:36:06118 """Test saving private DER keys."""
Sybren A. Stüvelf6a10732011-07-19 23:11:34119
120 key = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
Sybren A. Stüvelaa5a7fd2011-07-24 17:06:32121 der = key.save_pkcs1('DER')
Sybren A. Stüvelf6a10732011-07-19 23:11:34122
Sybren A. Stüvelf0627be2016-03-17 14:52:23123 self.assertIsInstance(der, bytes)
Sybren A. Stüvelf6a10732011-07-19 23:11:34124 self.assertEqual(PRIVATE_DER, der)
Sybren A. Stüvelfa346792011-07-19 21:53:59125
Sybren A. Stüvel74023dc2011-07-24 16:29:17126 def test_load_public_key(self):
Sybren A. Stüveld3d10342016-01-22 10:36:06127 """Test loading public DER keys."""
Sybren A. Stüvel74023dc2011-07-24 16:29:17128
Sybren A. Stüvelaa5a7fd2011-07-24 17:06:32129 key = rsa.key.PublicKey.load_pkcs1(PUBLIC_DER, 'DER')
Sybren A. Stüvel74023dc2011-07-24 16:29:17130 expected = rsa.key.PublicKey(3727264081, 65537)
131
132 self.assertEqual(expected, key)
133
134 def test_save_public_key(self):
Sybren A. Stüveld3d10342016-01-22 10:36:06135 """Test saving public DER keys."""
Sybren A. Stüvel74023dc2011-07-24 16:29:17136
137 key = rsa.key.PublicKey(3727264081, 65537)
Sybren A. Stüvelaa5a7fd2011-07-24 17:06:32138 der = key.save_pkcs1('DER')
Sybren A. Stüvel74023dc2011-07-24 16:29:17139
Sybren A. Stüvelf0627be2016-03-17 14:52:23140 self.assertIsInstance(der, bytes)
Sybren A. Stüvel74023dc2011-07-24 16:29:17141 self.assertEqual(PUBLIC_DER, der)
142
Sybren A. Stüvelfa346792011-07-19 21:53:59143
Sybren A. Stüveld3d10342016-01-22 10:36:06144class PemTest(unittest.TestCase):
145 """Test saving and loading PEM keys."""
Sybren A. Stüvelfa346792011-07-19 21:53:59146
147 def test_load_private_key(self):
Sybren A. Stüveld3d10342016-01-22 10:36:06148 """Test loading private PEM files."""
Sybren A. Stüvelfa346792011-07-19 21:53:59149
Sybren A. Stüvelaa5a7fd2011-07-24 17:06:32150 key = rsa.key.PrivateKey.load_pkcs1(PRIVATE_PEM, 'PEM')
Sybren A. Stüvelfa346792011-07-19 21:53:59151 expected = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
152
153 self.assertEqual(expected, key)
Michael Manganiello0c906332017-01-05 12:51:12154 self.assertEqual(key.exp1, 55063)
155 self.assertEqual(key.exp2, 10095)
156 self.assertEqual(key.coef, 50797)
Sybren A. Stüvelfa346792011-07-19 21:53:59157
Sybren A. Stüvelf6a10732011-07-19 23:11:34158 def test_save_private_key(self):
Sybren A. Stüveld3d10342016-01-22 10:36:06159 """Test saving private PEM files."""
Sybren A. Stüvelf6a10732011-07-19 23:11:34160
161 key = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
Sybren A. Stüvelaa5a7fd2011-07-24 17:06:32162 pem = key.save_pkcs1('PEM')
Sybren A. Stüvelf6a10732011-07-19 23:11:34163
Sybren A. Stüvelf0627be2016-03-17 14:52:23164 self.assertIsInstance(pem, bytes)
Sybren A. Stüvelf6a10732011-07-19 23:11:34165 self.assertEqual(CLEAN_PRIVATE_PEM, pem)
166
Sybren A. Stüvel74023dc2011-07-24 16:29:17167 def test_load_public_key(self):
Sybren A. Stüveld3d10342016-01-22 10:36:06168 """Test loading public PEM files."""
Sybren A. Stüvel74023dc2011-07-24 16:29:17169
Sybren A. Stüvelaa5a7fd2011-07-24 17:06:32170 key = rsa.key.PublicKey.load_pkcs1(PUBLIC_PEM, 'PEM')
Sybren A. Stüvel74023dc2011-07-24 16:29:17171 expected = rsa.key.PublicKey(3727264081, 65537)
172
173 self.assertEqual(expected, key)
174
175 def test_save_public_key(self):
Sybren A. Stüveld3d10342016-01-22 10:36:06176 """Test saving public PEM files."""
Sybren A. Stüvel74023dc2011-07-24 16:29:17177
178 key = rsa.key.PublicKey(3727264081, 65537)
Sybren A. Stüvelaa5a7fd2011-07-24 17:06:32179 pem = key.save_pkcs1('PEM')
Sybren A. Stüvel74023dc2011-07-24 16:29:17180
Sybren A. Stüvelf0627be2016-03-17 14:52:23181 self.assertIsInstance(pem, bytes)
Sybren A. Stüvel74023dc2011-07-24 16:29:17182 self.assertEqual(CLEAN_PUBLIC_PEM, pem)
183
Sybren A. Stüvelf68c52a2016-01-18 14:39:50184 def test_load_from_disk(self):
185 """Test loading a PEM file from disk."""
186
187 fname = os.path.join(os.path.dirname(__file__), 'private.pem')
188 with open(fname, mode='rb') as privatefile:
189 keydata = privatefile.read()
190 privkey = rsa.key.PrivateKey.load_pkcs1(keydata)
191
192 self.assertEqual(15945948582725241569, privkey.p)
193 self.assertEqual(14617195220284816877, privkey.q)
Sybren A. Stüvel4bc97332016-01-22 14:41:40194
195
196class PickleTest(unittest.TestCase):
197 """Test saving and loading keys by pickling."""
198
199 def test_private_key(self):
200 pk = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
201
202 pickled = pickle.dumps(pk)
203 unpickled = pickle.loads(pickled)
204 self.assertEqual(pk, unpickled)
205
Bu Sun Kimeb6ddb62021-02-19 01:05:54206 for attr in rsa.key.AbstractKey.__slots__:
207 self.assertTrue(hasattr(unpickled, attr))
208
Sybren A. Stüvel4bc97332016-01-22 14:41:40209 def test_public_key(self):
210 pk = rsa.key.PublicKey(3727264081, 65537)
211
212 pickled = pickle.dumps(pk)
213 unpickled = pickle.loads(pickled)
214
215 self.assertEqual(pk, unpickled)
Bu Sun Kimeb6ddb62021-02-19 01:05:54216 for attr in rsa.key.AbstractKey.__slots__:
217 self.assertTrue(hasattr(unpickled, attr))