Skip to content

Commit 789cb13

Browse files
authored
Adjust SecurityAccess parameter boundaries (#221)
Reduces SecurityAccess level boundaries to 01-7E Fixes #220
1 parent 7411eda commit 789cb13

File tree

2 files changed

+46
-37
lines changed

2 files changed

+46
-37
lines changed

test/client/test_security_access.py

+43-34
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33

44
from test.ClientServerTest import ClientServerTest
55

6+
67
class TestRequestSeed(ClientServerTest):
78
def __init__(self, *args, **kwargs):
89
ClientServerTest.__init__(self, *args, **kwargs)
910

1011
def test_request_seed_success(self):
1112
request = self.conn.touserqueue.get(timeout=0.2)
1213
self.assertEqual(request, b"\x27\x05")
13-
self.conn.fromuserqueue.put(b"\x67\x05\x99\x88\x77\x66") # Positive response
14+
self.conn.fromuserqueue.put(b"\x67\x05\x99\x88\x77\x66") # Positive response
1415

1516
def _test_request_seed_success(self):
1617
response = self.udsclient.request_seed(0x05)
@@ -19,16 +20,16 @@ def _test_request_seed_success(self):
1920
def test_request_seed_success_spr(self):
2021
request = self.conn.touserqueue.get(timeout=0.2)
2122
self.assertEqual(request, b"\x27\x85")
22-
self.conn.fromuserqueue.put('wait') # Synchronize
23+
self.conn.fromuserqueue.put('wait') # Synchronize
2324

2425
def _test_request_seed_success_spr(self):
2526
with self.udsclient.suppress_positive_response:
2627
response = self.udsclient.request_seed(0x05)
2728
self.assertEqual(response, None)
28-
self.conn.fromuserqueue.get(timeout=0.2) #Avoid closing connection prematurely
29+
self.conn.fromuserqueue.get(timeout=0.2) # Avoid closing connection prematurely
2930

3031
def test_request_seed_denied_exception(self):
31-
self.wait_request_and_respond(b"\x7F\x27\x22") # Conditions Not Correct
32+
self.wait_request_and_respond(b"\x7F\x27\x22") # Conditions Not Correct
3233

3334
def _test_request_seed_denied_exception(self):
3435
with self.assertRaises(NegativeResponseException) as handle:
@@ -41,7 +42,7 @@ def _test_request_seed_denied_exception(self):
4142
self.assertEqual(response.code, 0x22)
4243

4344
def test_request_seed_denied_no_exception(self):
44-
self.wait_request_and_respond(b"\x7F\x27\x22") # Conditions Not Correct
45+
self.wait_request_and_respond(b"\x7F\x27\x22") # Conditions Not Correct
4546

4647
def _test_request_seed_denied_no_exception(self):
4748
self.udsclient.config['exception_on_negative_response'] = False
@@ -53,14 +54,14 @@ def _test_request_seed_denied_no_exception(self):
5354
self.assertEqual(response.code, 0x22)
5455

5556
def test_request_seed_bad_subfn_exception(self):
56-
self.wait_request_and_respond(b"\x67\x06\x99\x88\x77\x66") # Positive response with wrong subfunction
57+
self.wait_request_and_respond(b"\x67\x06\x99\x88\x77\x66") # Positive response with wrong subfunction
5758

5859
def _test_request_seed_bad_subfn_exception(self):
5960
with self.assertRaises(UnexpectedResponseException) as handle:
6061
self.udsclient.request_seed(0x05)
6162

6263
def test_request_seed_bad_subfn_no_exception(self):
63-
self.wait_request_and_respond(b"\x67\x06\x99\x88\x77\x66") # Positive response with wrong subfunction
64+
self.wait_request_and_respond(b"\x67\x06\x99\x88\x77\x66") # Positive response with wrong subfunction
6465

6566
def _test_request_seed_bad_subfn_no_exception(self):
6667
self.udsclient.config['exception_on_unexpected_response'] = False
@@ -69,44 +70,44 @@ def _test_request_seed_bad_subfn_no_exception(self):
6970
self.assertTrue(response.unexpected)
7071

7172
def test_request_seed_incomplete_response_exception(self):
72-
self.wait_request_and_respond(b"\x67\x05") # Positive response with no seed
73+
self.wait_request_and_respond(b"\x67\x05") # Positive response with no seed
7374

7475
def _test_request_seed_incomplete_response_exception(self):
7576
with self.assertRaises(InvalidResponseException) as handle:
7677
self.udsclient.request_seed(0x05)
7778

7879
def test_request_seed_incomplete_response_no_exception(self):
79-
self.wait_request_and_respond(b"\x67\x05") # Positive response with no seed
80+
self.wait_request_and_respond(b"\x67\x05") # Positive response with no seed
8081

8182
def _test_request_seed_incomplete_response_no_exception(self):
8283
self.udsclient.config['exception_on_invalid_response'] = False
8384
response = self.udsclient.request_seed(0x05)
8485
self.assertFalse(response.valid)
8586

8687
def test_request_seed_invalidservice_exception(self):
87-
self.wait_request_and_respond(b"\x00\x05") #Inexistent Service
88+
self.wait_request_and_respond(b"\x00\x05") # Inexistent Service
8889

8990
def _test_request_seed_invalidservice_exception(self):
9091
with self.assertRaises(InvalidResponseException) as handle:
9192
self.udsclient.request_seed(0x05)
9293

9394
def test_request_seed_invalidservice_no_exception(self):
94-
self.wait_request_and_respond(b"\x00\x05") #Inexistent Service
95+
self.wait_request_and_respond(b"\x00\x05") # Inexistent Service
9596

9697
def _test_request_seed_invalidservice_no_exception(self):
9798
self.udsclient.config['exception_on_invalid_response'] = False
9899
response = self.udsclient.request_seed(0x05)
99100
self.assertFalse(response.valid)
100101

101102
def test_request_seed_wrongservice_exception(self):
102-
self.wait_request_and_respond(b"\x7E\x00") # Valid but wrong service (Tester Present)
103+
self.wait_request_and_respond(b"\x7E\x00") # Valid but wrong service (Tester Present)
103104

104105
def _test_request_seed_wrongservice_exception(self):
105106
with self.assertRaises(UnexpectedResponseException) as handle:
106107
self.udsclient.request_seed(0x05)
107108

108109
def test_request_seed_wrongservice_no_exception(self):
109-
self.wait_request_and_respond(b"\x7E\x00") # Valid but wrong service (Tester Present)
110+
self.wait_request_and_respond(b"\x7E\x00") # Valid but wrong service (Tester Present)
110111

111112
def _test_request_seed_wrongservice_no_exception(self):
112113
self.udsclient.config['exception_on_unexpected_response'] = False
@@ -119,7 +120,10 @@ def test_request_seed_bad_param(self):
119120

120121
def _test_request_seed_bad_param(self):
121122
with self.assertRaises(ValueError):
122-
self.udsclient.request_seed(0x80)
123+
self.udsclient.request_seed(0) # issue #220
124+
125+
with self.assertRaises(ValueError):
126+
self.udsclient.request_seed(0x7f) # issue #220
123127

124128
with self.assertRaises(ValueError):
125129
self.udsclient.request_seed(-1)
@@ -132,14 +136,14 @@ def __init__(self, *args, **kwargs):
132136
def test_send_key_success(self):
133137
request = self.conn.touserqueue.get(timeout=0.2)
134138
self.assertEqual(request, b"\x27\x06\x11\x22\x33\x44")
135-
self.conn.fromuserqueue.put(b"\x67\x06") # Positive response
139+
self.conn.fromuserqueue.put(b"\x67\x06") # Positive response
136140

137141
def _test_send_key_success(self):
138-
response = self.udsclient.send_key(0x06,b"\x11\x22\x33\x44")
142+
response = self.udsclient.send_key(0x06, b"\x11\x22\x33\x44")
139143
self.assertTrue(response.positive)
140144

141145
def test_send_key_denied_exception(self):
142-
self.wait_request_and_respond(b"\x7F\x27\x35") # InvalidKey
146+
self.wait_request_and_respond(b"\x7F\x27\x35") # InvalidKey
143147

144148
def _test_send_key_denied_exception(self):
145149
with self.assertRaises(NegativeResponseException) as handle:
@@ -152,7 +156,7 @@ def _test_send_key_denied_exception(self):
152156
self.assertEqual(response.code, 0x35)
153157

154158
def test_send_key_denied_no_exception(self):
155-
self.wait_request_and_respond(b"\x7F\x27\x35") # InvalidKey
159+
self.wait_request_and_respond(b"\x7F\x27\x35") # InvalidKey
156160

157161
def _test_send_key_denied_no_exception(self):
158162
self.udsclient.config['exception_on_negative_response'] = False
@@ -164,14 +168,14 @@ def _test_send_key_denied_no_exception(self):
164168
self.assertEqual(response.code, 0x35)
165169

166170
def test_send_key_bad_subfn_exception(self):
167-
self.wait_request_and_respond(b"\x67\x08\x99\x88\x77\x66") # Positive response with wrong subfunction
171+
self.wait_request_and_respond(b"\x67\x08\x99\x88\x77\x66") # Positive response with wrong subfunction
168172

169173
def _test_send_key_bad_subfn_exception(self):
170174
with self.assertRaises(UnexpectedResponseException) as handle:
171175
self.udsclient.send_key(0x06, b"\x11\x22\x33\x44")
172176

173177
def test_send_key_bad_subfn_no_exception(self):
174-
self.wait_request_and_respond(b"\x67\x08\x99\x88\x77\x66") # Positive response with wrong subfunction
178+
self.wait_request_and_respond(b"\x67\x08\x99\x88\x77\x66") # Positive response with wrong subfunction
175179

176180
def _test_send_key_bad_subfn_no_exception(self):
177181
self.udsclient.config['exception_on_unexpected_response'] = False
@@ -180,29 +184,29 @@ def _test_send_key_bad_subfn_no_exception(self):
180184
self.assertTrue(response.unexpected)
181185

182186
def test_send_key_invalidservice_exception(self):
183-
self.wait_request_and_respond(b"\x00\x06") #Inexistent Service
187+
self.wait_request_and_respond(b"\x00\x06") # Inexistent Service
184188

185189
def _test_send_key_invalidservice_exception(self):
186190
with self.assertRaises(InvalidResponseException) as handle:
187191
self.udsclient.send_key(0x06, b"\x11\x22\x33\x44")
188192

189193
def test_send_key_invalidservice_no_exception(self):
190-
self.wait_request_and_respond(b"\x00\x06") #Inexistent Service
194+
self.wait_request_and_respond(b"\x00\x06") # Inexistent Service
191195

192196
def _test_send_key_invalidservice_no_exception(self):
193197
self.udsclient.config['exception_on_invalid_response'] = False
194198
response = self.udsclient.send_key(0x06, b"\x11\x22\x33\x44")
195199
self.assertFalse(response.valid)
196200

197201
def test_send_key_wrongservice_exception(self):
198-
self.wait_request_and_respond(b"\x7E\x00") # Valid but wrong service (Tester Present)
202+
self.wait_request_and_respond(b"\x7E\x00") # Valid but wrong service (Tester Present)
199203

200204
def _test_send_key_wrongservice_exception(self):
201205
with self.assertRaises(UnexpectedResponseException) as handle:
202206
self.udsclient.send_key(0x06, b"\x11\x22\x33\x44")
203207

204208
def test_send_key_wrongservice_no_exception(self):
205-
self.wait_request_and_respond(b"\x7E\x00") # Valid but wrong service (Tester Present)
209+
self.wait_request_and_respond(b"\x7E\x00") # Valid but wrong service (Tester Present)
206210

207211
def _test_send_key_wrongservice_no_exception(self):
208212
self.udsclient.config['exception_on_unexpected_response'] = False
@@ -217,6 +221,12 @@ def _test_send_key_bad_param(self):
217221
with self.assertRaises(ValueError):
218222
self.udsclient.send_key(0x80, b"\x11\x22\x33\x44")
219223

224+
with self.assertRaises(ValueError):
225+
self.udsclient.send_key(0x7F, b"\x11\x22\x33\x44") # issue #220
226+
227+
with self.assertRaises(ValueError):
228+
self.udsclient.send_key(0, b"\x11\x22\x33\x44") # issue #220
229+
220230
with self.assertRaises(ValueError):
221231
self.udsclient.send_key(-1, b"\x11\x22\x33\x44")
222232

@@ -249,15 +259,15 @@ def test_unlock_success(self):
249259
self.assertEqual(request, b"\x27\x07") # Request seed
250260
self.conn.fromuserqueue.put(b"\x67\x07\x11\x22\x33\x44") # Positive response
251261
request = self.conn.touserqueue.get(timeout=0.2)
252-
key = bytearray([(0x10 + 0x07+i + 0 + 0x11), (0x10 + 0x07+i + 1 + 0x22), (0x10 + 0x07+i + 2 + 0x33), (0x10 + 0x07+i + 3 + 0x44)])
262+
key = bytearray([(0x10 + 0x07 + i + 0 + 0x11), (0x10 + 0x07 + i + 1 + 0x22), (0x10 + 0x07 + i + 2 + 0x33), (0x10 + 0x07 + i + 3 + 0x44)])
253263
self.assertEqual(request, b"\x27\x08" + bytes(key))
254264
self.conn.fromuserqueue.put(b"\x67\x08") # Positive response
255265

256266
def _test_unlock_success(self):
257267
self.udsclient.config['security_algo'] = self.dummy_algo
258268
self.udsclient.config['security_algo_params'] = 0x10
259-
response = self.udsclient.unlock_security_access(0x07)
260-
response = self.udsclient.unlock_security_access(0x08)
269+
response = self.udsclient.unlock_security_access(0x07)
270+
response = self.udsclient.unlock_security_access(0x08)
261271
self.assertTrue(response.positive)
262272

263273
def test_unlock_already_unlocked(self):
@@ -267,7 +277,7 @@ def test_unlock_already_unlocked(self):
267277
def _test_unlock_already_unlocked(self):
268278
self.udsclient.config['security_algo'] = self.dummy_algo
269279
self.udsclient.config['security_algo_params'] = 0x10
270-
response = self.udsclient.unlock_security_access(0x07)
280+
response = self.udsclient.unlock_security_access(0x07)
271281
self.assertTrue(response.positive)
272282

273283
def test_unlock_success_backward_compatibility(self):
@@ -282,22 +292,21 @@ def test_unlock_success_backward_compatibility(self):
282292
def _test_unlock_success_backward_compatibility(self):
283293
self.udsclient.config['security_algo'] = self.dummy_algo_backward_compatible
284294
self.udsclient.config['security_algo_params'] = 0xFF
285-
response = self.udsclient.unlock_security_access(0x07)
286-
response = self.udsclient.unlock_security_access(0x08)
295+
response = self.udsclient.unlock_security_access(0x07)
296+
response = self.udsclient.unlock_security_access(0x08)
287297
self.assertTrue(response.positive)
288298

289-
290299
def test_unlock_seed_fail_exception(self):
291-
self.wait_request_and_respond(b"\x7F\x27\x11")
300+
self.wait_request_and_respond(b"\x7F\x27\x11")
292301

293302
def _test_unlock_seed_fail_exception(self):
294303
self.udsclient.config['security_algo'] = self.dummy_algo
295304
self.udsclient.config['security_algo_params'] = 0xFF
296305
with self.assertRaises(NegativeResponseException):
297-
response = self.udsclient.unlock_security_access(0x07)
306+
response = self.udsclient.unlock_security_access(0x07)
298307

299308
def test_unlock_seed_fail_no_exception(self):
300-
self.wait_request_and_respond(b"\x7F\x27\x11")
309+
self.wait_request_and_respond(b"\x7F\x27\x11")
301310

302311
def _test_unlock_seed_fail_no_exception(self):
303312
self.udsclient.config['security_algo'] = self.dummy_algo

udsoncan/services/SecurityAccess.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class InterpretedResponse(Response):
5151
@classmethod
5252
def normalize_level(cls, mode: int, level: int) -> int:
5353
cls.validate_mode(mode)
54-
tools.validate_int(level, min=0, max=0x7F, name='Security level')
54+
tools.validate_int(level, min=1, max=0x7E, name='Security level')
5555

5656
if mode == cls.Mode.RequestSeed:
5757
return level if level % 2 == 1 else level - 1
@@ -122,5 +122,5 @@ def interpret_response(cls, response: Response, mode: int) -> InterpretedRespons
122122

123123
@classmethod
124124
def validate_mode(cls, mode: int):
125-
if mode not in [cls.Mode.RequestSeed, cls.Mode.SendKey]:
126-
raise ValueError('Given mode must be either be RequestSeed (0) or SendKey (1).')
125+
if mode not in (cls.Mode.RequestSeed, cls.Mode.SendKey):
126+
raise ValueError('Given mode must be either be RequestSeed (%d) or SendKey (%d).' % (cls.Mode.RequestSeed, cls.Mode.SendKey))

0 commit comments

Comments
 (0)