Skip to content

Commit ec5a48c

Browse files
committed
fix TLS credentials IF
Signed-off-by: Maximilian Deubel <maximilian.deubel@nordicsemi.no>
1 parent 307ba0c commit ec5a48c

File tree

4 files changed

+75
-10
lines changed

4 files changed

+75
-10
lines changed

src/nrfcredstore/command_interface.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -235,29 +235,27 @@ def write_credential(self, sectag, cred_type, cred_text):
235235
for c in range(chunks):
236236
chunk = encoded[c*TLS_CRED_CHUNK_SIZE:(c+1)*TLS_CRED_CHUNK_SIZE]
237237
self.write_raw(f"cred buf {chunk}")
238-
self.comms.expect_response("Stored")
238+
self.comms.expect_response(ok_pattern="Stored")
239239

240240
# Store the buffered credential
241241
self.write_raw(f"cred add {sectag} {TLS_CRED_TYPES[cred_type]} DEFAULT bint")
242-
result, _ = self.comms.expect_response("Added TLS credential")
243-
time.sleep(1)
242+
result, _ = self.comms.expect_response(ok_pattern="Added TLS credential")
244243
return result
245244

246245
def delete_credential(self, sectag: int, cred_type: int):
247246
self.write_raw(f'cred del {sectag} {TLS_CRED_TYPES[cred_type]}')
248-
result, _ = self.comms.expect_response("Deleted TLS credential", "There is no TLS credential")
249-
time.sleep(2)
247+
result, _ = self.comms.expect_response(ok_pattern="Deleted TLS credential", error_pattern="There is no TLS credential")
250248
return result
251249

252250
def check_credential_exists(self, sectag: int, cred_type: int, get_hash=True):
253251
self.write_raw(f'cred list {sectag} {TLS_CRED_TYPES[cred_type]}')
254252

255253
# This will capture the list dump for the credential if it exists.
256-
result, output = self.comms.expect_response("1 credentials found.",
257-
"0 credentials found.",
258-
f"{sectag},{TLS_CRED_TYPES[cred_type]}")
254+
result, output = self.comms.expect_response(ok_pattern="1 credentials found.",
255+
error_pattern="0 credentials found.",
256+
store_str=f"{sectag},{TLS_CRED_TYPES[cred_type]}")
259257

260-
if not output:
258+
if not result:
261259
return False, None
262260

263261
if not get_hash:

src/nrfcredstore/comms.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ def close(self):
322322
self.serial_api.close()
323323
self.serial_api = None
324324

325-
def expect_response(self, ok_str=None, error_str=None, store_str=None, timeout=15, suppress_errors=False):
325+
def expect_response(self, ok_str=None, error_str=None, store_str=None, timeout=15, suppress_errors=False, error_pattern=None, ok_pattern=None):
326326
'''
327327
Read lines until either ok_str or error_str is found or timeout (seconds) is reached.
328328
If store_str is in one of the lines, it will be returned as the output.
@@ -339,8 +339,12 @@ def expect_response(self, ok_str=None, error_str=None, store_str=None, timeout=1
339339
line = ansi_escape.sub('', line)
340340
if ok_str and ok_str == line:
341341
return (True, output)
342+
if ok_pattern and ok_pattern in line:
343+
return (True, output)
342344
if error_str and error_str == line:
343345
return (False, output)
346+
if error_pattern and error_pattern in line:
347+
return (False, output)
344348
if line.startswith('+CME ERROR'):
345349
code = int(line.replace('+CME ERROR: ', ''))
346350
if not suppress_errors:

tests/test_command_interface.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,50 @@ def test_delete_credential_at(at_command_interface):
4949
at_command_interface.delete_credential(sectag=42, cred_type=CredType.CLIENT_CERT.value)
5050
at_command_interface.comms.write_line.assert_called_once_with('AT%CMNG=3,42,1')
5151

52+
def test_delete_credential_tls(tls_cred_shell_interface):
53+
"""Test deleting a credential that exists in TLS shell"""
54+
tls_cred_shell_interface.comms.write_line = Mock()
55+
tls_cred_shell_interface.comms.expect_response.return_value = (True, '')
56+
tls_cred_shell_interface.delete_credential(sectag=42, cred_type=CredType.ROOT_CA_CERT.value)
57+
tls_cred_shell_interface.comms.write_line.assert_called_once_with('cred del 42 CA')
58+
59+
def test_delete_credential_tls_not_found(tls_cred_shell_interface):
60+
"""Test deleting a credential that does not exist in TLS shell"""
61+
tls_cred_shell_interface.comms.write_line = Mock()
62+
tls_cred_shell_interface.comms.expect_response.return_value = (False, '')
63+
tls_cred_shell_interface.delete_credential(sectag=42, cred_type=CredType.ROOT_CA_CERT.value)
64+
tls_cred_shell_interface.comms.write_line.assert_called_once_with('cred del 42 CA')
65+
66+
def test_check_credential_exists_tls(tls_cred_shell_interface):
67+
"""Test checking a credential that exists in TLS shell"""
68+
tls_cred_shell_interface.comms.write_line = Mock()
69+
tls_cred_shell_interface.comms.expect_response.return_value = (True, '42,CA,qLqL2kIyuj7FF9aFXQuhmc8kbMOHNYsM451gElqNyVQ=,0\r\n')
70+
result, hash = tls_cred_shell_interface.check_credential_exists(sectag=42, cred_type=CredType.ROOT_CA_CERT.value, get_hash=True)
71+
tls_cred_shell_interface.comms.write_line.assert_called_once_with('cred list 42 CA')
72+
assert hash == 'qLqL2kIyuj7FF9aFXQuhmc8kbMOHNYsM451gElqNyVQ='
73+
assert result == True
74+
75+
def test_check_credential_exists_tls_not_found(tls_cred_shell_interface):
76+
"""Test checking a credential that does not exist in TLS shell"""
77+
tls_cred_shell_interface.comms.write_line = Mock()
78+
tls_cred_shell_interface.comms.expect_response.return_value = (False, '')
79+
result, hash = tls_cred_shell_interface.check_credential_exists(sectag=42, cred_type=CredType.ROOT_CA_CERT.value, get_hash=True)
80+
tls_cred_shell_interface.comms.write_line.assert_called_once_with('cred list 42 CA')
81+
assert hash == None
82+
assert result == False
83+
84+
def test_write_credential_tls(tls_cred_shell_interface):
85+
"""Test writing a credential using TLSCredShellInterface"""
86+
tls_cred_shell_interface.comms.write_line = Mock()
87+
tls_cred_shell_interface.comms.expect_response.side_effect = [
88+
(True, ""),
89+
(True, "")
90+
]
91+
result = tls_cred_shell_interface.write_credential(sectag=42, cred_type=CredType.CLIENT_CERT.value, cred_text='test_value')
92+
assert result == True
93+
assert tls_cred_shell_interface.comms.write_line.call_count >= 3
94+
95+
5296
def test_check_credential_exists_at(at_command_interface):
5397
"""Test checking if a credential exists using ATCommandInterface"""
5498
at_command_interface.comms.write_line = Mock()

tests/test_comms.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,3 +457,22 @@ def test_expect_response_store(mock_serial):
457457
mock_select.assert_called_once()
458458
assert result is True
459459
assert output.strip() == '%ATTESTTOKEN: "foo.bar"'
460+
461+
def test_expect_response_pattern(mock_serial):
462+
with patch("nrfcredstore.comms.select_device", return_value=(Mock(), "123456789")) as mock_select:
463+
comms = Comms()
464+
comms.read_line = Mock(side_effect=[
465+
"Stored 48 bytes.",
466+
"16842753,CA,qLqL2kIyuj7FF9aFXQuhmc8kbMOHNYsM451gElqNyVQ=,0",
467+
"1 credentials found.",
468+
"0 credentials found."
469+
])
470+
assert comms.expect_response(ok_pattern="Stored") == (True, '')
471+
assert comms.expect_response(
472+
ok_pattern="1 credentials found.",
473+
error_pattern="0 credentials found.",
474+
store_str="16842753,CA") == (True, "16842753,CA,qLqL2kIyuj7FF9aFXQuhmc8kbMOHNYsM451gElqNyVQ=,0\r\n")
475+
assert comms.expect_response(
476+
ok_pattern="1 credentials found.",
477+
error_pattern="0 credentials found.",
478+
store_str="16842753,CA") == (False, '')

0 commit comments

Comments
 (0)