Skip to content

Commit e304e18

Browse files
joerchanrlubos
authored andcommitted
tests: tls_credentials_nrf_modem: Test the nrf_modem credential backend
Test the functionality of the nrf_modem TLS credential backend. Signed-off-by: Joakim Andersson <joerchan@gmail.com>
1 parent 98be383 commit e304e18

File tree

5 files changed

+300
-0
lines changed

5 files changed

+300
-0
lines changed

CODEOWNERS

+1
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@
874874
/tests/subsys/net/lib/nrf_cloud/ @nrfconnect/ncs-nrf-cloud
875875
/tests/subsys/net/lib/nrf_provisioning/ @nrfconnect/ncs-iot-oulu
876876
/tests/subsys/net/lib/wifi_credentials*/ @nrfconnect/ncs-cia
877+
/tests/subsys/net/lib/tls_credentials*/ @nrfconnect/ncs-co-networking
877878
/tests/subsys/net/openthread/rpc/ @nrfconnect/ncs-protocols-serialization
878879
/tests/subsys/nfc/rpc/ @nrfconnect/ncs-protocols-serialization
879880
/tests/subsys/nrf_compress/ @nordicjm
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#
2+
# Copyright (c) 2022 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
cmake_minimum_required(VERSION 3.20.0)
8+
9+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
10+
project(tls_credentials_test)
11+
12+
target_include_directories(app PRIVATE
13+
${ZEPHYR_NRFXLIB_MODULE_DIR}/nrf_modem/include/
14+
${ZEPHYR_BASE}/subsys/net/lib/tls_credentials
15+
)
16+
17+
target_compile_definitions(app PRIVATE
18+
CONFIG_TLS_MAX_CREDENTIALS_NUMBER=10
19+
CONFIG_TLS_CREDENTIALS_LOG_LEVEL=3
20+
)
21+
22+
target_sources(app PRIVATE
23+
${ZEPHYR_NRF_MODULE_DIR}/subsys/net/lib/tls_credentials/tls_credentials_nrf_modem.c
24+
main.c
25+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#include <zephyr/ztest.h>
8+
#include <zephyr/fff.h>
9+
10+
#include <zephyr/net/tls_credentials.h>
11+
#include "tls_internal.h"
12+
13+
#include <modem/modem_key_mgmt.h>
14+
15+
DEFINE_FFF_GLOBALS;
16+
17+
FAKE_VALUE_FUNC(int, modem_key_mgmt_write, nrf_sec_tag_t, enum modem_key_mgmt_cred_type,
18+
const void *, size_t);
19+
FAKE_VALUE_FUNC(int, modem_key_mgmt_read, nrf_sec_tag_t, enum modem_key_mgmt_cred_type,
20+
void *, size_t *);
21+
FAKE_VALUE_FUNC(int, modem_key_mgmt_delete, nrf_sec_tag_t, enum modem_key_mgmt_cred_type);
22+
FAKE_VALUE_FUNC(int, modem_key_mgmt_clear, nrf_sec_tag_t);
23+
FAKE_VALUE_FUNC(int, modem_key_mgmt_cmp, nrf_sec_tag_t, enum modem_key_mgmt_cred_type,
24+
const void *, size_t);
25+
FAKE_VALUE_FUNC(int, modem_key_mgmt_digest, nrf_sec_tag_t, enum modem_key_mgmt_cred_type,
26+
void *, size_t);
27+
FAKE_VALUE_FUNC(int, modem_key_mgmt_exists, nrf_sec_tag_t, enum modem_key_mgmt_cred_type,
28+
bool *);
29+
FAKE_VALUE_FUNC(int, modem_key_mgmt_list, modem_key_mgmt_list_cb_t);
30+
31+
static const char pem_buf[] = "--- begin --- base64-encode(some-bytes) --- end ----";
32+
33+
/* These tests should be run first, to verify the credentials loaded on modem init. */
34+
ZTEST(tls_credentials, test_00_init_import_list_public_api)
35+
{
36+
uint8_t cred[1];
37+
size_t len = sizeof(cred);
38+
39+
/* The CA chain can be accessed. */
40+
modem_key_mgmt_read_fake.return_val = 0;
41+
42+
zassert_equal(tls_credential_get(100, TLS_CREDENTIAL_CA_CERTIFICATE, cred, &len), 0);
43+
zassert_equal(tls_credential_get(101, TLS_CREDENTIAL_CA_CERTIFICATE, cred, &len), 0);
44+
zassert_equal(tls_credential_get(103, TLS_CREDENTIAL_CA_CERTIFICATE, cred, &len), 0);
45+
46+
/* The server certificate and private key cannot be accessed, instead returning EACCESS. */
47+
modem_key_mgmt_read_fake.return_val = -EACCES;
48+
49+
zassert_equal(tls_credential_get(1, TLS_CREDENTIAL_SERVER_CERTIFICATE, cred, &len),
50+
-EACCES);
51+
zassert_equal(tls_credential_get(1, TLS_CREDENTIAL_PRIVATE_KEY, cred, &len), -EACCES);
52+
53+
zassert_equal(tls_credential_get(2, TLS_CREDENTIAL_SERVER_CERTIFICATE, cred, &len),
54+
-EACCES);
55+
zassert_equal(tls_credential_get(2, TLS_CREDENTIAL_PRIVATE_KEY, cred, &len), -EACCES);
56+
}
57+
58+
ZTEST(tls_credentials, test_00_init_import_list_internal_api)
59+
{
60+
zassert_not_null(credential_get(100, TLS_CREDENTIAL_CA_CERTIFICATE));
61+
zassert_not_null(credential_get(101, TLS_CREDENTIAL_CA_CERTIFICATE));
62+
zassert_not_null(credential_get(103, TLS_CREDENTIAL_CA_CERTIFICATE));
63+
64+
zassert_not_null(credential_get(1, TLS_CREDENTIAL_SERVER_CERTIFICATE));
65+
zassert_not_null(credential_get(1, TLS_CREDENTIAL_PRIVATE_KEY));
66+
67+
zassert_not_null(credential_get(2, TLS_CREDENTIAL_SERVER_CERTIFICATE));
68+
zassert_not_null(credential_get(2, TLS_CREDENTIAL_PRIVATE_KEY));
69+
}
70+
71+
ZTEST(tls_credentials, test_00_init_import_list_internal_api_iterator)
72+
{
73+
struct tls_credential *cred;
74+
75+
cred = credential_next_get(100, NULL);
76+
zassert_not_null(cred);
77+
zassert_equal(cred->tag, 100);
78+
zassert_equal(cred->type, TLS_CREDENTIAL_CA_CERTIFICATE);
79+
zassert_is_null(credential_next_get(100, cred));
80+
81+
cred = credential_next_get(101, NULL);
82+
zassert_not_null(cred);
83+
zassert_equal(cred->tag, 101);
84+
zassert_equal(cred->type, TLS_CREDENTIAL_CA_CERTIFICATE);
85+
zassert_is_null(credential_next_get(100, cred));
86+
87+
cred = credential_next_get(103, NULL);
88+
zassert_not_null(cred);
89+
zassert_equal(cred->tag, 103);
90+
zassert_equal(cred->type, TLS_CREDENTIAL_CA_CERTIFICATE);
91+
zassert_is_null(credential_next_get(100, cred));
92+
93+
/* We assert the type of the iterator based on the order they were added by the callback. */
94+
cred = credential_next_get(1, NULL);
95+
zassert_not_null(cred);
96+
zassert_equal(cred->tag, 1);
97+
zassert_equal(cred->type, TLS_CREDENTIAL_SERVER_CERTIFICATE);
98+
cred = credential_next_get(1, cred);
99+
zassert_not_null(cred);
100+
zassert_equal(cred->tag, 1);
101+
zassert_equal(cred->type, TLS_CREDENTIAL_PRIVATE_KEY);
102+
zassert_is_null(credential_next_get(1, cred));
103+
104+
cred = credential_next_get(2, NULL);
105+
zassert_not_null(cred);
106+
zassert_equal(cred->tag, 2);
107+
zassert_equal(cred->type, TLS_CREDENTIAL_PRIVATE_KEY);
108+
cred = credential_next_get(2, cred);
109+
zassert_not_null(cred);
110+
zassert_equal(cred->tag, 2);
111+
zassert_equal(cred->type, TLS_CREDENTIAL_SERVER_CERTIFICATE);
112+
}
113+
114+
/* base64(bin("B9BAC15641653CAE2B5151DCBD0C40DDCDF19125950FA2475977437EA35F7A45")) */
115+
const char expected_digest_str[] =
116+
"ubrBVkFlPK4rUVHcvQxA3c3xkSWVD6JHWXdDfqNfekU=";
117+
118+
static const uint8_t digest[] = {
119+
0xB9, 0xBA, 0xC1, 0x56, 0x41, 0x65, 0x3C, 0xAE,
120+
0x2B, 0x51, 0x51, 0xDC, 0xBD, 0x0C, 0x40, 0xDD,
121+
0xCD, 0xF1, 0x91, 0x25, 0x95, 0x0F, 0xA2, 0x47,
122+
0x59, 0x77, 0x43, 0x7E, 0xA3, 0x5F, 0x7A, 0x45
123+
};
124+
125+
int modem_key_mgmt_digest_custom(nrf_sec_tag_t sec_tag,
126+
enum modem_key_mgmt_cred_type cred_type,
127+
void *buf, size_t len)
128+
{
129+
zassert_equal(sec_tag, 100);
130+
zassert_equal(cred_type, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN);
131+
132+
memcpy(buf, digest, sizeof(digest));
133+
return 0;
134+
}
135+
136+
ZTEST(tls_credentials, test_credential_digest)
137+
{
138+
struct tls_credential *cred;
139+
uint8_t digest_base64_buf[49];
140+
size_t digest_base64_len = sizeof(digest_base64_buf);
141+
142+
modem_key_mgmt_digest_fake.custom_fake = modem_key_mgmt_digest_custom;
143+
144+
cred = credential_next_get(100, NULL);
145+
146+
zassert_ok(credential_digest(cred, digest_base64_buf, &digest_base64_len));
147+
zassert_mem_equal(digest_base64_buf, expected_digest_str, sizeof(expected_digest_str));
148+
}
149+
150+
ZTEST(tls_credentials, test_tls_credential_add)
151+
{
152+
size_t len = strlen(pem_buf);
153+
154+
modem_key_mgmt_write_fake.return_val = 0;
155+
156+
zassert_ok(tls_credential_add(10, TLS_CREDENTIAL_CA_CERTIFICATE, (uint8_t *)pem_buf, len));
157+
158+
zassert_equal(modem_key_mgmt_write_fake.call_count, 1);
159+
160+
zassert_equal(modem_key_mgmt_write_fake.arg0_val, 10);
161+
zassert_equal(modem_key_mgmt_write_fake.arg1_val, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN);
162+
zassert_equal(modem_key_mgmt_write_fake.arg2_val, (uint8_t *)pem_buf);
163+
zassert_equal(modem_key_mgmt_write_fake.arg3_val, len);
164+
165+
zassert_ok(tls_credential_delete(10, TLS_CREDENTIAL_CA_CERTIFICATE));
166+
167+
zassert_equal(modem_key_mgmt_delete_fake.call_count, 1);
168+
169+
zassert_equal(modem_key_mgmt_delete_fake.arg0_val, 10);
170+
zassert_equal(modem_key_mgmt_delete_fake.arg1_val, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN);
171+
}
172+
173+
ZTEST(tls_credentials, test_tls_credential_add_existing_equal)
174+
{
175+
size_t len = strlen(pem_buf);
176+
177+
modem_key_mgmt_cmp_fake.return_val = 0;
178+
179+
zassert_ok(tls_credential_add(101, TLS_CREDENTIAL_CA_CERTIFICATE, (uint8_t *)pem_buf, len));
180+
181+
zassert_equal(modem_key_mgmt_cmp_fake.call_count, 1);
182+
zassert_equal(modem_key_mgmt_cmp_fake.arg0_val, 101);
183+
zassert_equal(modem_key_mgmt_cmp_fake.arg1_val, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN);
184+
zassert_equal(modem_key_mgmt_cmp_fake.arg2_val, (uint8_t *)pem_buf);
185+
zassert_equal(modem_key_mgmt_cmp_fake.arg3_val, len);
186+
}
187+
188+
ZTEST(tls_credentials, test_tls_credential_add_existing_not_equal)
189+
{
190+
size_t len = strlen(pem_buf);
191+
192+
modem_key_mgmt_cmp_fake.return_val = 1;
193+
194+
zassert_equal(tls_credential_add(101, TLS_CREDENTIAL_CA_CERTIFICATE,
195+
(uint8_t *)pem_buf, len),
196+
-EEXIST);
197+
198+
zassert_equal(modem_key_mgmt_cmp_fake.call_count, 1);
199+
zassert_equal(modem_key_mgmt_cmp_fake.arg0_val, 101);
200+
zassert_equal(modem_key_mgmt_cmp_fake.arg1_val, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN);
201+
zassert_equal(modem_key_mgmt_cmp_fake.arg2_val, (uint8_t *)pem_buf);
202+
zassert_equal(modem_key_mgmt_cmp_fake.arg3_val, len);
203+
204+
/* Should not have been written */
205+
zassert_equal(modem_key_mgmt_write_fake.call_count, 0);
206+
}
207+
208+
/* Verify that if we have an entry, but the modem for some reason has lost it, we write it. */
209+
ZTEST(tls_credentials, test_tls_credential_add_existing_but_not_existing)
210+
{
211+
size_t len = strlen(pem_buf);
212+
213+
modem_key_mgmt_cmp_fake.return_val = -ENOENT;
214+
modem_key_mgmt_write_fake.return_val = 0;
215+
216+
zassert_ok(tls_credential_add(101, TLS_CREDENTIAL_CA_CERTIFICATE, (uint8_t *)pem_buf, len));
217+
218+
zassert_equal(modem_key_mgmt_cmp_fake.call_count, 1);
219+
220+
/* Write it if it does not exist. */
221+
zassert_equal(modem_key_mgmt_write_fake.call_count, 1);
222+
zassert_equal(modem_key_mgmt_write_fake.arg0_val, 101);
223+
zassert_equal(modem_key_mgmt_write_fake.arg1_val, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN);
224+
zassert_equal(modem_key_mgmt_write_fake.arg2_val, (uint8_t *)pem_buf);
225+
zassert_equal(modem_key_mgmt_write_fake.arg3_val, len);
226+
}
227+
228+
229+
static void _reset_fake(const struct ztest_unit_test *test, void *fixture)
230+
{
231+
RESET_FAKE(modem_key_mgmt_write);
232+
RESET_FAKE(modem_key_mgmt_read);
233+
RESET_FAKE(modem_key_mgmt_cmp);
234+
RESET_FAKE(modem_key_mgmt_exists);
235+
RESET_FAKE(modem_key_mgmt_delete);
236+
RESET_FAKE(modem_key_mgmt_list);
237+
}
238+
239+
ZTEST_RULE(reset_fake_rule, _reset_fake, NULL);
240+
241+
/* NRF_MODEM_LIB_ON_INIT handler. */
242+
extern void credentials_on_modem_init(int ret, void *ctx);
243+
244+
int modem_key_mgmt_list_setup(modem_key_mgmt_list_cb_t list_cb)
245+
{
246+
list_cb(100, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN);
247+
list_cb(101, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN);
248+
list_cb(103, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN);
249+
250+
list_cb(1, MODEM_KEY_MGMT_CRED_TYPE_PUBLIC_CERT);
251+
list_cb(1, MODEM_KEY_MGMT_CRED_TYPE_PRIVATE_CERT);
252+
253+
list_cb(2, MODEM_KEY_MGMT_CRED_TYPE_PRIVATE_CERT);
254+
list_cb(2, MODEM_KEY_MGMT_CRED_TYPE_PUBLIC_CERT);
255+
256+
return 0;
257+
}
258+
259+
static void *tls_credentials_setup(void)
260+
{
261+
modem_key_mgmt_list_fake.custom_fake = modem_key_mgmt_list_setup;
262+
263+
credentials_on_modem_init(0, NULL);
264+
return NULL;
265+
}
266+
267+
ZTEST_SUITE(tls_credentials, NULL, tls_credentials_setup, NULL, NULL, NULL);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
CONFIG_ZTEST=y
2+
CONFIG_BASE64=y
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
tests:
2+
net.lib.tls_credentials:
3+
platform_allow: native_sim
4+
integration_platforms:
5+
- native_sim

0 commit comments

Comments
 (0)