Coverage for tests/admin/test_certificate_v1_element.py: 100%

77 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2025-07-10 13:43 +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. 

22 

23import hashlib 

24import hmac 

25import os 

26from parameterized import parameterized 

27import secp256k1 as ec 

28 

29from unittest import TestCase 

30from unittest.mock import Mock 

31from admin.certificate import HSMCertificateRoot, HSMCertificateElement 

32 

33 

34class TestHSMCertificateRoot(TestCase): 

35 def test_ok(self): 

36 pubkey = ec.PrivateKey().pubkey 

37 root = HSMCertificateRoot(pubkey.serialize(compressed=False).hex()) 

38 self.assertEqual( 

39 pubkey.serialize(compressed=True), 

40 root.get_pubkey().serialize(compressed=True)) 

41 

42 def test_invalid_pubkey(self): 

43 with self.assertRaises(ValueError): 

44 HSMCertificateRoot("invalid-pubkey") 

45 

46 

47class TestHSMCertificateElement(TestCase): 

48 def test_create_certificate_element_ok(self): 

49 element = HSMCertificateElement({ 

50 "name": "device", 

51 "message": 'cc', 

52 "signature": 'dd', 

53 "signed_by": "root", 

54 "tweak": 'ee' 

55 }) 

56 self.assertEqual({ 

57 "name": "device", 

58 "message": 'cc', 

59 "signature": 'dd', 

60 "signed_by": "root", 

61 "tweak": 'ee' 

62 }, element.to_dict()) 

63 

64 def test_create_certificate_element_invalid_name(self): 

65 with self.assertRaises(ValueError): 

66 HSMCertificateElement({ 

67 "name": "invalid-name", 

68 "message": 'cc', 

69 "signature": 'dd', 

70 "signed_by": "root", 

71 "tweak": 'ee' 

72 }) 

73 

74 def test_create_certificate_element_missing_certifier(self): 

75 with self.assertRaises(ValueError): 

76 HSMCertificateElement({ 

77 "name": "device", 

78 "message": 'cc', 

79 "signature": 'dd', 

80 "tweak": 'ee' 

81 }) 

82 

83 def test_create_certificate_element_invalid_tweak(self): 

84 with self.assertRaises(ValueError): 

85 HSMCertificateElement({ 

86 "name": "device", 

87 "message": 'cc', 

88 "signature": 'dd', 

89 "signed_by": "root", 

90 "tweak": 'invalid-tweak' 

91 }) 

92 

93 def test_create_certificate_element_invalid_message(self): 

94 with self.assertRaises(ValueError): 

95 HSMCertificateElement({ 

96 "name": "device", 

97 "message": 'invalid-message', 

98 "signature": 'dd', 

99 "signed_by": "root", 

100 "tweak": 'ee' 

101 }) 

102 

103 def test_create_certificate_element_invalid_signature(self): 

104 with self.assertRaises(ValueError): 

105 HSMCertificateElement({ 

106 "name": "device", 

107 "message": 'cc', 

108 "signature": 'invalid-signature', 

109 "signed_by": "root", 

110 "tweak": 'ee' 

111 }) 

112 

113 def test_certificate_element_is_valid_ok(self): 

114 privkey = ec.PrivateKey() 

115 msg = 'aa' * 65 

116 signature = privkey.ecdsa_serialize(privkey.ecdsa_sign(bytes.fromhex(msg))).hex() 

117 mock_certifier = Mock(get_pubkey=lambda: privkey.pubkey) 

118 

119 element = HSMCertificateElement({ 

120 "name": "device", 

121 "message": msg, 

122 "signature": signature, 

123 "signed_by": "root" 

124 }) 

125 self.assertEqual({ 

126 "name": "device", 

127 "message": msg, 

128 "signature": signature, 

129 "signed_by": "root" 

130 }, element.to_dict()) 

131 self.assertTrue(element.is_valid(mock_certifier)) 

132 

133 def test_certificate_element_is_valid_with_tweak_ok(self): 

134 privkey = ec.PrivateKey() 

135 pubkey = privkey.pubkey 

136 raw_tweak = os.urandom(32).hex() 

137 tweak = hmac.new( 

138 bytes.fromhex(raw_tweak), 

139 pubkey.serialize(compressed=False), 

140 hashlib.sha256, 

141 ).digest() 

142 mock_certifier = Mock(get_pubkey=lambda: pubkey) 

143 

144 tweak_privkey = ec.PrivateKey(privkey.tweak_add(tweak), raw=True) 

145 msg = os.urandom(66).hex() 

146 signature = tweak_privkey.ecdsa_serialize( 

147 tweak_privkey.ecdsa_sign(bytes.fromhex(msg))).hex() 

148 

149 element = HSMCertificateElement({ 

150 "name": "device", 

151 "message": msg, 

152 "signature": signature, 

153 "signed_by": "root", 

154 "tweak": raw_tweak 

155 }) 

156 self.assertEqual({ 

157 "name": "device", 

158 "message": msg, 

159 "signature": signature, 

160 "signed_by": "root", 

161 "tweak": raw_tweak 

162 }, element.to_dict()) 

163 self.assertTrue(element.is_valid(mock_certifier)) 

164 

165 def test_certificate_element_is_valid_wrong_signature(self): 

166 privkey = ec.PrivateKey() 

167 msg = 'aa' * 65 

168 

169 element = HSMCertificateElement({ 

170 "name": "device", 

171 "message": msg, 

172 "signature": 'bb' * 65, 

173 "signed_by": "root" 

174 }) 

175 self.assertEqual({ 

176 "name": "device", 

177 "message": msg, 

178 "signature": 'bb' * 65, 

179 "signed_by": "root" 

180 }, element.to_dict()) 

181 self.assertFalse(element.is_valid(privkey.pubkey)) 

182 

183 def test_certificate_element_is_valid_wrong_tweak(self): 

184 privkey = ec.PrivateKey() 

185 pubkey = privkey.pubkey 

186 raw_tweak = os.urandom(32).hex() 

187 tweak = hmac.new( 

188 bytes.fromhex(raw_tweak), 

189 pubkey.serialize(compressed=False), 

190 hashlib.sha256, 

191 ).digest() 

192 

193 tweak_privkey = ec.PrivateKey(privkey.tweak_add(tweak), raw=True) 

194 msg = os.urandom(66).hex() 

195 signature = tweak_privkey.ecdsa_serialize( 

196 tweak_privkey.ecdsa_sign(bytes.fromhex(msg))).hex() 

197 

198 element = HSMCertificateElement({ 

199 "name": "device", 

200 "message": msg, 

201 "signature": signature, 

202 "signed_by": "root", 

203 "tweak": 'bb' * 32 

204 }) 

205 self.assertEqual({ 

206 "name": "device", 

207 "message": msg, 

208 "signature": signature, 

209 "signed_by": "root", 

210 "tweak": 'bb' * 32 

211 }, element.to_dict()) 

212 self.assertFalse(element.is_valid(pubkey)) 

213 

214 @parameterized.expand([ 

215 ("device", lambda b: b[-65:]), 

216 ("attestation", lambda b: b[1:]), 

217 ("ui", lambda b: b[:]), 

218 ("signer", lambda b: b[:]) 

219 ]) 

220 def test_certificate_element_get_value(self, name, extractor): 

221 msg = os.urandom(66).hex() 

222 element = HSMCertificateElement({ 

223 "name": name, 

224 "message": msg, 

225 "signature": 'aa' * 70, 

226 "signed_by": "root", 

227 "tweak": 'bb' * 32 

228 }) 

229 self.assertEqual(extractor(bytes.fromhex(msg)).hex(), element.get_value())