Skip to content

Commit a124bca

Browse files
authored
Merge pull request #14048 from mikaleppanen/corr_cert_add
Corrected Wi-SUN certificate add and remove functions on Wi-SUN interface
2 parents e917282 + 88b46cc commit a124bca

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)