Skip to content

Commit 4e855b6

Browse files
joerchanrlubos
authored andcommitted
lib: modem_key_mgmt: Add function to get digest and list entries
Add two new functions to modem key management interface. A function to retrieve the SHA1 digest of the credential in persistent storage. A function that iterates over all entries in persistent storage and calls a callback with the security tag and the credential type. Signed-off-by: Joakim Andersson <[email protected]>
1 parent c477d1f commit 4e855b6

File tree

2 files changed

+143
-1
lines changed

2 files changed

+143
-1
lines changed

include/modem/modem_key_mgmt.h

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ extern "C" {
2323
* @{
2424
*/
2525

26-
/**@brief Credential types. */
26+
/** @brief The digest is 32 bytes long. */
27+
#define MODEM_KEY_MGMT_DIGEST_SIZE (32)
28+
29+
/** @brief Credential types. */
2730
enum modem_key_mgmt_cred_type {
2831
MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN,
2932
MODEM_KEY_MGMT_CRED_TYPE_PUBLIC_CERT,
@@ -32,6 +35,15 @@ enum modem_key_mgmt_cred_type {
3235
MODEM_KEY_MGMT_CRED_TYPE_IDENTITY
3336
};
3437

38+
/**
39+
* @brief Credential list entry handler function prototype.
40+
*
41+
* @param[in] sec_tag The security tag.
42+
* @param[in] cred_type The credential type.
43+
*/
44+
typedef void (*modem_key_mgmt_list_cb_t)(
45+
nrf_sec_tag_t sec_tag, enum modem_key_mgmt_cred_type cred_type);
46+
3547
/**
3648
* @brief Write or update a credential in persistent storage.
3749
*
@@ -136,6 +148,23 @@ int modem_key_mgmt_cmp(nrf_sec_tag_t sec_tag,
136148
enum modem_key_mgmt_cred_type cred_type,
137149
const void *buf, size_t len);
138150

151+
/**
152+
* @brief Read the SHA1 digest of a credential from persistent storage.
153+
*
154+
* @param[in] sec_tag The security tag of the credential.
155+
* @param[in] cred_type The credential type.
156+
* @param[out] buf Buffer to read the credential into.
157+
* @param[in] len Length of the buffer.
158+
*
159+
* @retval 0 On success.
160+
* @retval -ENOMEM Credential does not fit in @p buf. See @ref MODEM_KEY_MGMT_DIGEST_SIZE
161+
* @retval -ENOENT No credential associated with the given
162+
* @p sec_tag and @p cred_type.
163+
*/
164+
int modem_key_mgmt_digest(nrf_sec_tag_t sec_tag,
165+
enum modem_key_mgmt_cred_type cred_type,
166+
void *buf, size_t len);
167+
139168
/**
140169
* @brief Check if a credential exists in persistent storage.
141170
*
@@ -152,6 +181,17 @@ int modem_key_mgmt_exists(nrf_sec_tag_t sec_tag,
152181
enum modem_key_mgmt_cred_type cred_type,
153182
bool *exists);
154183

184+
/**
185+
* @brief List all the available credentials in persistent storage.
186+
*
187+
* @param[in] list_cb Callback called for each available
188+
* credential in persistent storage.
189+
*
190+
* @retval 0 On success.
191+
* @retval -ENOBUFS Internal buffer is too small.
192+
*/
193+
int modem_key_mgmt_list(modem_key_mgmt_list_cb_t list_cb);
194+
155195
/**@} */
156196

157197
#ifdef __cplusplus

lib/modem_key_mgmt/modem_key_mgmt.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,68 @@ int modem_key_mgmt_cmp(nrf_sec_tag_t sec_tag,
267267
return err;
268268
}
269269

270+
#define MODEM_KEY_MGMT_DIGEST_STR_SIZE_WITHOUT_NULL_TERM 64
271+
272+
int modem_key_mgmt_digest(nrf_sec_tag_t sec_tag,
273+
enum modem_key_mgmt_cred_type cred_type,
274+
void *buf, size_t len)
275+
{
276+
char cmd[sizeof("AT%CMNG=1,##########,##")];
277+
bool cmee_was_enabled;
278+
int ret;
279+
280+
if (buf == NULL) {
281+
return -EINVAL;
282+
}
283+
284+
if (len < MODEM_KEY_MGMT_DIGEST_SIZE) {
285+
return -ENOMEM;
286+
}
287+
288+
cmee_enable(&cmee_was_enabled);
289+
290+
snprintk(cmd, sizeof(cmd), "AT%%CMNG=1,%u,%u", sec_tag, cred_type);
291+
292+
k_mutex_lock(&key_mgmt_mutex, K_FOREVER);
293+
294+
ret = nrf_modem_at_scanf(
295+
cmd,
296+
"%%CMNG: "
297+
"%*u," /* Ignore tag. */
298+
"%*u," /* Ignore type. */
299+
"\"%" STRINGIFY(MODEM_KEY_MGMT_DIGEST_STR_SIZE_WITHOUT_NULL_TERM) "s\"",
300+
scratch_buf);
301+
302+
if (!cmee_was_enabled) {
303+
cmee_disable();
304+
}
305+
306+
switch (ret) {
307+
case 1:
308+
len = hex2bin(scratch_buf, strlen(scratch_buf), buf, len);
309+
310+
if (len != MODEM_KEY_MGMT_DIGEST_SIZE) {
311+
ret = -EINVAL;
312+
break;
313+
}
314+
315+
ret = 0;
316+
break;
317+
case 0:
318+
ret = -ENOENT;
319+
default:
320+
break;
321+
}
322+
323+
k_mutex_unlock(&key_mgmt_mutex);
324+
if (ret) {
325+
return translate_error(ret);
326+
}
327+
328+
return 0;
329+
330+
}
331+
270332
int modem_key_mgmt_delete(nrf_sec_tag_t sec_tag,
271333
enum modem_key_mgmt_cred_type cred_type)
272334
{
@@ -366,3 +428,43 @@ int modem_key_mgmt_exists(nrf_sec_tag_t sec_tag,
366428
k_mutex_unlock(&key_mgmt_mutex);
367429
return err;
368430
}
431+
432+
int modem_key_mgmt_list(modem_key_mgmt_list_cb_t list_cb)
433+
{
434+
int err;
435+
char *token;
436+
uint32_t tag, type;
437+
bool cmee_was_enabled;
438+
439+
k_mutex_lock(&key_mgmt_mutex, K_FOREVER);
440+
441+
cmee_enable(&cmee_was_enabled);
442+
443+
scratch_buf[0] = '\0';
444+
err = nrf_modem_at_cmd(scratch_buf, sizeof(scratch_buf),
445+
"AT%%CMNG=1");
446+
447+
if (!cmee_was_enabled) {
448+
cmee_disable();
449+
}
450+
451+
if (err) {
452+
err = translate_error(err);
453+
goto out;
454+
}
455+
456+
token = strtok(scratch_buf, "\n");
457+
while (token != NULL) {
458+
int match = sscanf(token, "%%CMNG: %u,%u,\"", &tag, &type);
459+
460+
if (match == 2 && tag < NRF_SEC_TAG_TLS_DECRYPT_BASE) {
461+
list_cb(tag, type);
462+
}
463+
464+
token = strtok(NULL, "\n");
465+
}
466+
467+
out:
468+
k_mutex_unlock(&key_mgmt_mutex);
469+
return err;
470+
}

0 commit comments

Comments
 (0)