Coverage for tests/admin/test_certificate_element.py: 100%
65 statements
« prev ^ index » next coverage.py v7.2.7, created at 2024-04-05 20:41 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2024-04-05 20:41 +0000
1# The MIT License (MIT)
2#
3# Copyright (c) 2021 RSK Labs Ltd
4#
5# Permission is hereby granted, free of charge, to any person obtaining a copy of
6# this software and associated documentation files (the "Software"), to deal in
7# the Software without restriction, including without limitation the rights to
8# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9# of the Software, and to permit persons to whom the Software is furnished to do
10# so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice shall be included in all
13# copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21# SOFTWARE.
23import hashlib
24import hmac
25import os
26from parameterized import parameterized
27import secp256k1 as ec
29from unittest import TestCase
30from admin.certificate import HSMCertificateElement
33class TestCertificateElement(TestCase):
34 def test_create_certificate_element_ok(self):
35 element = HSMCertificateElement({
36 "name": "device",
37 "message": 'cc',
38 "signature": 'dd',
39 "signed_by": "root",
40 "tweak": 'ee'
41 })
42 self.assertEqual({
43 "name": "device",
44 "message": 'cc',
45 "signature": 'dd',
46 "signed_by": "root",
47 "tweak": 'ee'
48 }, element.to_dict())
50 def test_create_certificate_element_invalid_name(self):
51 with self.assertRaises(ValueError):
52 HSMCertificateElement({
53 "name": "invalid-name",
54 "message": 'cc',
55 "signature": 'dd',
56 "signed_by": "root",
57 "tweak": 'ee'
58 })
60 def test_create_certificate_element_missing_certifier(self):
61 with self.assertRaises(ValueError):
62 HSMCertificateElement({
63 "name": "device",
64 "message": 'cc',
65 "signature": 'dd',
66 "tweak": 'ee'
67 })
69 def test_create_certificate_element_invalid_tweak(self):
70 with self.assertRaises(ValueError):
71 HSMCertificateElement({
72 "name": "device",
73 "message": 'cc',
74 "signature": 'dd',
75 "signed_by": "root",
76 "tweak": 'invalid-tweak'
77 })
79 def test_create_certificate_element_invalid_message(self):
80 with self.assertRaises(ValueError):
81 HSMCertificateElement({
82 "name": "device",
83 "message": 'invalid-message',
84 "signature": 'dd',
85 "signed_by": "root",
86 "tweak": 'ee'
87 })
89 def test_create_certificate_element_invalid_signature(self):
90 with self.assertRaises(ValueError):
91 HSMCertificateElement({
92 "name": "device",
93 "message": 'cc',
94 "signature": 'invalid-signature',
95 "signed_by": "root",
96 "tweak": 'ee'
97 })
99 def test_certificate_element_is_valid_ok(self):
100 privkey = ec.PrivateKey()
101 msg = 'aa' * 65
102 signature = privkey.ecdsa_serialize(privkey.ecdsa_sign(bytes.fromhex(msg))).hex()
104 element = HSMCertificateElement({
105 "name": "device",
106 "message": msg,
107 "signature": signature,
108 "signed_by": "root"
109 })
110 self.assertEqual({
111 "name": "device",
112 "message": msg,
113 "signature": signature,
114 "signed_by": "root"
115 }, element.to_dict())
116 self.assertTrue(element.is_valid(privkey.pubkey))
118 def test_certificate_element_is_valid_with_tweak_ok(self):
119 privkey = ec.PrivateKey()
120 pubkey = privkey.pubkey
121 raw_tweak = os.urandom(32).hex()
122 tweak = hmac.new(
123 bytes.fromhex(raw_tweak),
124 pubkey.serialize(compressed=False),
125 hashlib.sha256,
126 ).digest()
128 tweak_privkey = ec.PrivateKey(privkey.tweak_add(tweak), raw=True)
129 msg = os.urandom(66).hex()
130 signature = tweak_privkey.ecdsa_serialize(
131 tweak_privkey.ecdsa_sign(bytes.fromhex(msg))).hex()
133 element = HSMCertificateElement({
134 "name": "device",
135 "message": msg,
136 "signature": signature,
137 "signed_by": "root",
138 "tweak": raw_tweak
139 })
140 self.assertEqual({
141 "name": "device",
142 "message": msg,
143 "signature": signature,
144 "signed_by": "root",
145 "tweak": raw_tweak
146 }, element.to_dict())
147 self.assertTrue(element.is_valid(pubkey))
149 def test_certificate_element_is_valid_wrong_signature(self):
150 privkey = ec.PrivateKey()
151 msg = 'aa' * 65
153 element = HSMCertificateElement({
154 "name": "device",
155 "message": msg,
156 "signature": 'bb' * 65,
157 "signed_by": "root"
158 })
159 self.assertEqual({
160 "name": "device",
161 "message": msg,
162 "signature": 'bb' * 65,
163 "signed_by": "root"
164 }, element.to_dict())
165 self.assertFalse(element.is_valid(privkey.pubkey))
167 def test_certificate_element_is_valid_wrong_tweak(self):
168 privkey = ec.PrivateKey()
169 pubkey = privkey.pubkey
170 raw_tweak = os.urandom(32).hex()
171 tweak = hmac.new(
172 bytes.fromhex(raw_tweak),
173 pubkey.serialize(compressed=False),
174 hashlib.sha256,
175 ).digest()
177 tweak_privkey = ec.PrivateKey(privkey.tweak_add(tweak), raw=True)
178 msg = os.urandom(66).hex()
179 signature = tweak_privkey.ecdsa_serialize(
180 tweak_privkey.ecdsa_sign(bytes.fromhex(msg))).hex()
182 element = HSMCertificateElement({
183 "name": "device",
184 "message": msg,
185 "signature": signature,
186 "signed_by": "root",
187 "tweak": 'bb' * 32
188 })
189 self.assertEqual({
190 "name": "device",
191 "message": msg,
192 "signature": signature,
193 "signed_by": "root",
194 "tweak": 'bb' * 32
195 }, element.to_dict())
196 self.assertFalse(element.is_valid(pubkey))
198 @parameterized.expand([
199 ("device", lambda b: b[-65:]),
200 ("attestation", lambda b: b[1:]),
201 ("ui", lambda b: b[:]),
202 ("signer", lambda b: b[:])
203 ])
204 def test_certificate_element_get_value(self, name, extractor):
205 msg = os.urandom(66).hex()
206 element = HSMCertificateElement({
207 "name": name,
208 "message": msg,
209 "signature": 'aa' * 70,
210 "signed_by": "root",
211 "tweak": 'bb' * 32
212 })
213 self.assertEqual(extractor(bytes.fromhex(msg)).hex(), element.get_value())