blob: 0d3dfd8c27960122305888e5e1559f4067762abb [file] [log] [blame]
David Brown5e7c6dd2017-11-16 14:47:16 -07001"""
2Tests for RSA keys
3"""
4
5import io
6import os
7import sys
8import tempfile
9import unittest
10
11from cryptography.exceptions import InvalidSignature
12from cryptography.hazmat.primitives.asymmetric.padding import PSS, MGF1
13from cryptography.hazmat.primitives.hashes import SHA256
14
15# Setup sys path so 'imgtool' is in it.
16sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
17
18from imgtool.keys import load, RSA2048, RSAUsageError
19
20class KeyGeneration(unittest.TestCase):
21
22 def setUp(self):
23 self.test_dir = tempfile.TemporaryDirectory()
24
25 def tname(self, base):
26 return os.path.join(self.test_dir.name, base)
27
28 def tearDown(self):
29 self.test_dir.cleanup()
30
31 def test_keygen(self):
32 name1 = self.tname("keygen.pem")
33 k = RSA2048.generate()
34 k.export_private(name1, b'secret')
35
36 # Try loading the key without a password.
37 self.assertIsNone(load(name1))
38
39 k2 = load(name1, b'secret')
40
41 pubname = self.tname('keygen-pub.pem')
42 k2.export_public(pubname)
43 pk2 = load(pubname)
44
45 # We should be able to export the public key from the loaded
46 # public key, but not the private key.
47 pk2.export_public(self.tname('keygen-pub2.pem'))
48 self.assertRaises(RSAUsageError, pk2.export_private, self.tname('keygen-priv2.pem'))
49
50 def test_emit(self):
51 """Basic sanity check on the code emitters."""
52 k = RSA2048.generate()
53
54 ccode = io.StringIO()
55 k.emit_c(ccode)
56 self.assertIn("rsa_pub_key", ccode.getvalue())
57 self.assertIn("rsa_pub_key_len", ccode.getvalue())
58
59 rustcode = io.StringIO()
60 k.emit_rust(rustcode)
61 self.assertIn("RSA_PUB_KEY", rustcode.getvalue())
62
63 def test_emit_pub(self):
64 """Basic sanity check on the code emitters, from public key."""
65 pubname = self.tname("public.pem")
66 k = RSA2048.generate()
67 k.export_public(pubname)
68
69 k2 = load(pubname)
70
71 ccode = io.StringIO()
72 k2.emit_c(ccode)
73 self.assertIn("rsa_pub_key", ccode.getvalue())
74 self.assertIn("rsa_pub_key_len", ccode.getvalue())
75
76 rustcode = io.StringIO()
77 k2.emit_rust(rustcode)
78 self.assertIn("RSA_PUB_KEY", rustcode.getvalue())
79
80 def test_sig(self):
81 k = RSA2048.generate()
82 buf = b'This is the message'
83 sig = k.sign(buf)
84
85 # The code doesn't have any verification, so verify this
86 # manually.
87 k.key.public_key().verify(
88 signature=sig,
89 data=buf,
90 padding=PSS(mgf=MGF1(SHA256()), salt_length=PSS.MAX_LENGTH),
91 algorithm=SHA256())
92
93 # Modify the message to make sure the signature fails.
94 self.assertRaises(InvalidSignature,
95 k.key.public_key().verify,
96 signature=sig,
97 data=b'This is thE message',
98 padding=PSS(mgf=MGF1(SHA256()), salt_length=PSS.MAX_LENGTH),
99 algorithm=SHA256())
100
101if __name__ == '__main__':
102 unittest.main()