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

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 admin.certificate import HSMCertificateElement 

31 

32 

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()) 

49 

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 }) 

59 

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 }) 

68 

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 }) 

78 

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 }) 

88 

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 }) 

98 

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() 

103 

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)) 

117 

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() 

127 

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() 

132 

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)) 

148 

149 def test_certificate_element_is_valid_wrong_signature(self): 

150 privkey = ec.PrivateKey() 

151 msg = 'aa' * 65 

152 

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)) 

166 

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() 

176 

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() 

181 

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)) 

197 

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())