Skip to content

Commit 88b46cc

Browse files
author
Mika Leppänen
committed
Corrected Wi-SUN certificate add and remove functions on Wi-SUN interface
Corrected Wi-SUN certificate add and remove functions to work properly with .json certificates. .json certificates are used only if certificates added by add functions are not set. Corrected certificate add and remove functions to work properly and improved function descriptions.
1 parent d6784c3 commit 88b46cc

File tree

2 files changed

+110
-66
lines changed

2 files changed

+110
-66
lines changed

connectivity/nanostack/mbed-mesh-api/mbed-mesh-api/WisunInterface.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,16 @@ class WisunInterface final : public MeshInterfaceNanostack {
415415
* \brief Set own certificate and private key reference to the Wi-SUN network.
416416
*
417417
* Function can be called several times if intermediate certificates are used. Then each call to the function
418-
* adds a certificate reference to own certificate chain. Certificates are in bottom up order i.e. the top certificate is given last.
418+
* adds a certificate reference to own certificate chain. Certificates are in bottom up order i.e. own certificate
419+
* is given first and the top certificate is given last.
420+
*
421+
* PEM formatted certificates must use either "\n" or "\r\n" as line separator. PEM formatted certificates
422+
* must be NUL terminated and the NUL terminator is counted to certificate length.
423+
*
424+
* It is possible to add multiple PEM certificates concatenated together in one call set_own_certificate(). In that
425+
* case certificates are in bottom up order i.e. own certificate is given first and the top certificate is given
426+
* last. NUL terminator is added after the last concatenated certificate and the NUL terminator is counted to
427+
* total concatenated certificate length.
419428
*
420429
* Function must be called before connecting the device i.e before call to connect() method.
421430
* Function will not copy certificate or key, therefore addresses must remain valid.
@@ -443,7 +452,14 @@ class WisunInterface final : public MeshInterfaceNanostack {
443452
/**
444453
* \brief Set trusted certificate reference to the Wi-SUN network.
445454
*
446-
* Function can be called several times. Certificates are in bottom up order i.e. the top certificate is given last.
455+
* Function can be called several times. Each call to the function adds a trusted certificate to Wi-SUN.
456+
*
457+
* PEM formatted certificates must use either "\n" or "\r\n" as line separator. PEM formatted certificates
458+
* must be NUL terminated and the NUL terminator is counted to certificate length.
459+
*
460+
* It is possible to add multiple PEM certificates concatenated together in one call set_trusted_certificate().
461+
* NUL terminator is added after the last concatenated certificate and the NUL terminator is counted to
462+
* total concatenated certificate length.
447463
*
448464
* Function must be called before connecting the device i.e before call to connect() method.
449465
* Function will not copy certificate, therefore addresses must remain valid.

connectivity/nanostack/mbed-mesh-api/source/wisun_tasklet.c

Lines changed: 92 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ typedef struct {
7070
net_6lowpan_mode_e operating_mode;
7171
net_6lowpan_mode_extension_e operating_mode_extension;
7272
int8_t network_interface_id;
73+
bool configured_and_connected;
7374
} wisun_tasklet_data_str_t;
7475

7576
typedef struct {
@@ -81,8 +82,6 @@ typedef NS_LIST_HEAD(wisun_certificate_entry_t, link) cert_list_t;
8182
typedef struct {
8283
cert_list_t own_certificates_list;
8384
cert_list_t trusted_certificates_list;
84-
bool remove_own_certificates: 1;
85-
bool remove_trusted_certificates: 1;
8685
} wisun_certificates_t;
8786

8887
/* Tasklet data */
@@ -106,9 +105,9 @@ static void wisun_tasklet_main(arm_event_s *event);
106105
static void wisun_tasklet_network_state_changed(mesh_connection_status_t status);
107106
static void wisun_tasklet_parse_network_event(arm_event_s *event);
108107
static void wisun_tasklet_configure_and_connect_to_network(void);
109-
static void wisun_tasklet_clear_stored_certificates(void) ;
110-
static int wisun_tasklet_store_certificate_data(const uint8_t *cert, uint16_t cert_len, const uint8_t *cert_key, uint16_t cert_key_len, bool remove_own, bool remove_trusted, bool trusted_cert);
111-
static int wisun_tasklet_add_stored_certificates(void) ;
108+
static void wisun_tasklet_clear_stored_certificates(int8_t clear_trusted, int8_t clear_own);
109+
static int wisun_tasklet_store_certificate_data(const uint8_t *cert, uint16_t cert_len, const uint8_t *cert_key, uint16_t cert_key_len, bool trusted_cert);
110+
static int wisun_tasklet_add_stored_certificates(int8_t *trusted_set, int8_t *own_set);
112111
static void wisun_tasklet_statistics_do_start(void);
113112

114113
/*
@@ -231,6 +230,11 @@ static void wisun_tasklet_parse_network_event(arm_event_s *event)
231230
static void wisun_tasklet_configure_and_connect_to_network(void)
232231
{
233232
int status;
233+
234+
if (wisun_tasklet_data_ptr->configured_and_connected) {
235+
return;
236+
}
237+
234238
fhss_timer_t *fhss_timer_ptr = &fhss_functions;
235239

236240
if (MBED_CONF_MBED_MESH_API_WISUN_DEVICE_TYPE == MESH_DEVICE_TYPE_WISUN_BORDER_ROUTER) {
@@ -246,7 +250,9 @@ static void wisun_tasklet_configure_and_connect_to_network(void)
246250
wisun_tasklet_data_ptr->operating_mode,
247251
wisun_tasklet_data_ptr->operating_mode_extension);
248252

249-
if (wisun_tasklet_add_stored_certificates() != 0) {
253+
int8_t trusted_set = false;
254+
int8_t own_set = false;
255+
if (wisun_tasklet_add_stored_certificates(&trusted_set, &own_set) != 0) {
250256
tr_error("Can't set Wi-SUN certificates");
251257
return;
252258
}
@@ -278,38 +284,41 @@ static void wisun_tasklet_configure_and_connect_to_network(void)
278284
}
279285

280286
#if defined(MBED_CONF_MBED_MESH_API_CERTIFICATE_HEADER)
281-
arm_certificate_entry_s trusted_cert = {
282-
.cert = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE,
283-
.key = NULL,
284-
.cert_len = 0,
285-
.key_len = 0
286-
};
287+
if (!trusted_set) {
288+
arm_certificate_entry_s trusted_cert = {
289+
.cert = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE,
290+
.key = NULL,
291+
.cert_len = 0,
292+
.key_len = 0
293+
};
287294
#ifdef MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE_LEN
288-
trusted_cert.cert_len = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE_LEN;
295+
trusted_cert.cert_len = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE_LEN;
289296
#else
290-
trusted_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE) + 1;
297+
trusted_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE) + 1;
291298
#endif
292-
arm_network_trusted_certificates_remove();
293-
arm_network_trusted_certificate_add((const arm_certificate_entry_s *)&trusted_cert);
294-
295-
arm_certificate_entry_s own_cert = {
296-
.cert = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE,
297-
.key = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY,
298-
.cert_len = 0,
299-
.key_len = 0
300-
};
299+
arm_network_trusted_certificates_remove();
300+
arm_network_trusted_certificate_add((const arm_certificate_entry_s *)&trusted_cert);
301+
}
302+
if (!own_set) {
303+
arm_certificate_entry_s own_cert = {
304+
.cert = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE,
305+
.key = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY,
306+
.cert_len = 0,
307+
.key_len = 0
308+
};
301309
#ifdef MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_LEN
302-
own_cert.cert_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_LEN;
310+
own_cert.cert_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_LEN;
303311
#else
304-
own_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE) + 1;
312+
own_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE) + 1;
305313
#endif
306314
#ifdef MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY_LEN
307-
own_cert.key_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY_LEN;
315+
own_cert.key_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY_LEN;
308316
#else
309-
own_cert.key_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY) + 1;
317+
own_cert.key_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY) + 1;
310318
#endif
311-
arm_network_own_certificates_remove();
312-
arm_network_own_certificate_add((const arm_certificate_entry_s *)&own_cert);
319+
arm_network_own_certificates_remove();
320+
arm_network_own_certificate_add((const arm_certificate_entry_s *)&own_cert);
321+
}
313322
#endif
314323

315324
if (statistics_started) {
@@ -318,6 +327,7 @@ static void wisun_tasklet_configure_and_connect_to_network(void)
318327

319328
status = arm_nwk_interface_up(wisun_tasklet_data_ptr->network_interface_id);
320329
if (status >= 0) {
330+
wisun_tasklet_data_ptr->configured_and_connected = true;
321331
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED;
322332
tr_info("Start Wi-SUN Bootstrap");
323333
wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED);
@@ -326,6 +336,7 @@ static void wisun_tasklet_configure_and_connect_to_network(void)
326336
tr_err("Bootstrap start failed, %d", status);
327337
wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_START_FAILED);
328338
}
339+
329340
}
330341

331342
/*
@@ -338,7 +349,7 @@ static void wisun_tasklet_network_state_changed(mesh_connection_status_t status)
338349
}
339350
}
340351

341-
static int wisun_tasklet_store_certificate_data(const uint8_t *cert, uint16_t cert_len, const uint8_t *cert_key, uint16_t cert_key_len, bool remove_own, bool remove_trusted, bool trusted_cert)
352+
static int wisun_tasklet_store_certificate_data(const uint8_t *cert, uint16_t cert_len, const uint8_t *cert_key, uint16_t cert_key_len, bool trusted_cert)
342353
{
343354
if (wisun_certificates_ptr == NULL) {
344355
wisun_certificates_ptr = (wisun_certificates_t *)ns_dyn_mem_alloc(sizeof(wisun_certificates_t));
@@ -347,23 +358,11 @@ static int wisun_tasklet_store_certificate_data(const uint8_t *cert, uint16_t ce
347358
}
348359
ns_list_init(&wisun_certificates_ptr->own_certificates_list);
349360
ns_list_init(&wisun_certificates_ptr->trusted_certificates_list);
350-
wisun_certificates_ptr->remove_own_certificates = false;
351-
wisun_certificates_ptr->remove_trusted_certificates = false;
352-
}
353-
354-
if (remove_own) {
355-
wisun_certificates_ptr->remove_own_certificates = true;
356-
return 0;
357-
}
358-
359-
if (remove_trusted) {
360-
wisun_certificates_ptr->remove_trusted_certificates = true;
361-
return 0;
362361
}
363362

364363
wisun_certificate_entry_t *ws_cert_entry_store = (wisun_certificate_entry_t *)ns_dyn_mem_alloc(sizeof(wisun_certificate_entry_t));
365364
if (!ws_cert_entry_store) {
366-
wisun_tasklet_clear_stored_certificates();
365+
wisun_tasklet_clear_stored_certificates(true, true);
367366
return -1;
368367
}
369368

@@ -387,27 +386,33 @@ static int wisun_tasklet_store_certificate_data(const uint8_t *cert, uint16_t ce
387386
return 0;
388387
}
389388

390-
static void wisun_tasklet_clear_stored_certificates(void)
389+
static void wisun_tasklet_clear_stored_certificates(int8_t clear_trusted, int8_t clear_own)
391390
{
392391
if (!wisun_certificates_ptr) {
393392
return;
394393
}
395394

396-
ns_list_foreach_safe(wisun_certificate_entry_t, trusted_cert_entry, &wisun_certificates_ptr->trusted_certificates_list) {
397-
ns_list_remove(&wisun_certificates_ptr->trusted_certificates_list, trusted_cert_entry);
398-
ns_dyn_mem_free(trusted_cert_entry);
395+
if (clear_trusted) {
396+
ns_list_foreach_safe(wisun_certificate_entry_t, trusted_cert_entry, &wisun_certificates_ptr->trusted_certificates_list) {
397+
ns_list_remove(&wisun_certificates_ptr->trusted_certificates_list, trusted_cert_entry);
398+
ns_dyn_mem_free(trusted_cert_entry);
399+
}
399400
}
400401

401-
ns_list_foreach_safe(wisun_certificate_entry_t, own_cert_entry, &wisun_certificates_ptr->own_certificates_list) {
402-
ns_list_remove(&wisun_certificates_ptr->own_certificates_list, own_cert_entry);
403-
ns_dyn_mem_free(own_cert_entry);
402+
if (clear_own) {
403+
ns_list_foreach_safe(wisun_certificate_entry_t, own_cert_entry, &wisun_certificates_ptr->own_certificates_list) {
404+
ns_list_remove(&wisun_certificates_ptr->own_certificates_list, own_cert_entry);
405+
ns_dyn_mem_free(own_cert_entry);
406+
}
404407
}
405408

406-
ns_dyn_mem_free(wisun_certificates_ptr);
407-
wisun_certificates_ptr = NULL;
409+
if (ns_list_is_empty(&wisun_certificates_ptr->trusted_certificates_list) && ns_list_is_empty(&wisun_certificates_ptr->own_certificates_list)) {
410+
ns_dyn_mem_free(wisun_certificates_ptr);
411+
wisun_certificates_ptr = NULL;
412+
}
408413
}
409414

410-
static int wisun_tasklet_add_stored_certificates(void)
415+
static int wisun_tasklet_add_stored_certificates(int8_t *trusted_set, int8_t *own_set)
411416
{
412417
int8_t status = 0;
413418

@@ -416,15 +421,15 @@ static int wisun_tasklet_add_stored_certificates(void)
416421
return 0;
417422
}
418423

419-
if (wisun_certificates_ptr->remove_own_certificates) {
420-
status = arm_network_own_certificates_remove();
424+
if (!ns_list_is_empty(&wisun_certificates_ptr->trusted_certificates_list)) {
425+
status = arm_network_trusted_certificates_remove();
421426
if (status != 0) {
422427
goto CERTIFICATE_SET_END;
423428
}
424429
}
425430

426-
if (wisun_certificates_ptr->remove_trusted_certificates) {
427-
status = arm_network_trusted_certificates_remove();
431+
if (!ns_list_is_empty(&wisun_certificates_ptr->own_certificates_list)) {
432+
status = arm_network_own_certificates_remove();
428433
if (status != 0) {
429434
goto CERTIFICATE_SET_END;
430435
}
@@ -435,17 +440,19 @@ static int wisun_tasklet_add_stored_certificates(void)
435440
if (status != 0) {
436441
goto CERTIFICATE_SET_END;
437442
}
443+
*trusted_set = true;
438444
}
439445

440446
ns_list_foreach(wisun_certificate_entry_t, cert_entry, &wisun_certificates_ptr->own_certificates_list) {
441447
status = arm_network_own_certificate_add(&cert_entry->arm_cert_entry);
442448
if (status != 0) {
443449
goto CERTIFICATE_SET_END;
444450
}
451+
*own_set = true;
445452
}
446453

447454
CERTIFICATE_SET_END:
448-
wisun_tasklet_clear_stored_certificates();
455+
wisun_tasklet_clear_stored_certificates(true, true);
449456

450457
return status;
451458
}
@@ -481,6 +488,7 @@ int8_t wisun_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_id
481488
wisun_tasklet_data_ptr->mesh_api_cb = callback;
482489
wisun_tasklet_data_ptr->network_interface_id = nwk_interface_id;
483490
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_INITIALIZED;
491+
wisun_tasklet_data_ptr->configured_and_connected = false;
484492

485493
if (re_connecting == false) {
486494
wisun_tasklet_data_ptr->tasklet = eventOS_event_handler_create(&wisun_tasklet_main,
@@ -509,6 +517,7 @@ int8_t wisun_tasklet_disconnect(bool send_cb)
509517
wisun_tasklet_network_state_changed(MESH_DISCONNECTED);
510518
}
511519
}
520+
wisun_tasklet_data_ptr->configured_and_connected = false;
512521
wisun_tasklet_data_ptr->mesh_api_cb = NULL;
513522
}
514523
return status;
@@ -522,6 +531,7 @@ void wisun_tasklet_init(void)
522531
memset(wisun_tasklet_data_ptr, 0, sizeof(wisun_tasklet_data_str_t));
523532
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_CREATED;
524533
wisun_tasklet_data_ptr->network_interface_id = INVALID_INTERFACE_ID;
534+
wisun_tasklet_data_ptr->configured_and_connected = false;
525535
}
526536
}
527537

@@ -542,7 +552,7 @@ int8_t wisun_tasklet_network_init(int8_t device_id)
542552

543553
int wisun_tasklet_set_own_certificate(uint8_t *cert, uint16_t cert_len, uint8_t *cert_key, uint16_t cert_key_len)
544554
{
545-
if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID) {
555+
if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID && wisun_tasklet_data_ptr->configured_and_connected) {
546556
// interface already active write certificates to stack.
547557
arm_certificate_entry_s arm_cert_entry;
548558
arm_cert_entry.cert = cert;
@@ -552,22 +562,40 @@ int wisun_tasklet_set_own_certificate(uint8_t *cert, uint16_t cert_len, uint8_t
552562
return arm_network_own_certificate_add(&arm_cert_entry);
553563
}
554564
// Stack is inactive store the certificates and activate when connect() called
555-
return wisun_tasklet_store_certificate_data(cert, cert_len, cert_key, cert_key_len, false, false, false);
565+
return wisun_tasklet_store_certificate_data(cert, cert_len, cert_key, cert_key_len, false);
556566
}
557567

558568
int wisun_tasklet_remove_own_certificates(void)
559569
{
560-
return wisun_tasklet_store_certificate_data(NULL, 0, NULL, 0, true, false, false);
570+
if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID && wisun_tasklet_data_ptr->configured_and_connected) {
571+
int8_t status = arm_network_own_certificates_remove();
572+
if (status != 0) {
573+
return -1;
574+
}
575+
return 0;
576+
}
577+
578+
wisun_tasklet_clear_stored_certificates(false, true);
579+
return 0;
561580
}
562581

563582
int wisun_tasklet_remove_trusted_certificates(void)
564583
{
565-
return wisun_tasklet_store_certificate_data(NULL, 0, NULL, 0, false, true, false);
584+
if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID && wisun_tasklet_data_ptr->configured_and_connected) {
585+
int8_t status = arm_network_trusted_certificates_remove();
586+
if (status != 0) {
587+
return -1;
588+
}
589+
return 0;
590+
}
591+
592+
wisun_tasklet_clear_stored_certificates(true, false);
593+
return 0;
566594
}
567595

568596
int wisun_tasklet_set_trusted_certificate(uint8_t *cert, uint16_t cert_len)
569597
{
570-
if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID) {
598+
if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID && wisun_tasklet_data_ptr->configured_and_connected) {
571599
// interface already active write certificates to stack.
572600
arm_certificate_entry_s arm_cert_entry;
573601
arm_cert_entry.cert = cert;
@@ -577,7 +605,7 @@ int wisun_tasklet_set_trusted_certificate(uint8_t *cert, uint16_t cert_len)
577605
return arm_network_trusted_certificate_add(&arm_cert_entry);
578606
}
579607
// Stack is inactive store the certificates and activate when connect() called
580-
return wisun_tasklet_store_certificate_data(cert, cert_len, NULL, 0, false, false, true);
608+
return wisun_tasklet_store_certificate_data(cert, cert_len, NULL, 0, true);
581609
}
582610

583611
int wisun_tasklet_statistics_start(void)

0 commit comments

Comments
 (0)