Skip to content

Commit 46a045b

Browse files
authored
Merge pull request #14046 from mikaleppanen/mbedos_5_15_corr_cert_add
[mbed-os-5.15] Corrected Wi-SUN certificate add and remove functions on Wi-SUN interface
2 parents 01495a7 + b8611bd commit 46a045b

File tree

2 files changed

+110
-66
lines changed

2 files changed

+110
-66
lines changed

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,16 @@ class WisunInterface : public MeshInterfaceNanostack {
424424
* \brief Set own certificate and private key reference to the Wi-SUN network.
425425
*
426426
* Function can be called several times if intermediate certificates are used. Then each call to the function
427-
* adds a certificate reference to own certificate chain. Certificates are in bottom up order i.e. the top certificate is given last.
427+
* adds a certificate reference to own certificate chain. Certificates are in bottom up order i.e. own certificate
428+
* is given first and the top certificate is given last.
429+
*
430+
* PEM formatted certificates must use either "\n" or "\r\n" as line separator. PEM formatted certificates
431+
* must be NUL terminated and the NUL terminator is counted to certificate length.
432+
*
433+
* It is possible to add multiple PEM certificates concatenated together in one call set_own_certificate(). In that
434+
* case certificates are in bottom up order i.e. own certificate is given first and the top certificate is given
435+
* last. NUL terminator is added after the last concatenated certificate and the NUL terminator is counted to
436+
* total concatenated certificate length.
428437
*
429438
* Function must be called before connecting the device i.e before call to connect() method.
430439
* Function will not copy certificate or key, therefore addresses must remain valid.
@@ -452,7 +461,14 @@ class WisunInterface : public MeshInterfaceNanostack {
452461
/**
453462
* \brief Set trusted certificate reference to the Wi-SUN network.
454463
*
455-
* Function can be called several times. Certificates are in bottom up order i.e. the top certificate is given last.
464+
* Function can be called several times. Each call to the function adds a trusted certificate to Wi-SUN.
465+
*
466+
* PEM formatted certificates must use either "\n" or "\r\n" as line separator. PEM formatted certificates
467+
* must be NUL terminated and the NUL terminator is counted to certificate length.
468+
*
469+
* It is possible to add multiple PEM certificates concatenated together in one call set_trusted_certificate().
470+
* NUL terminator is added after the last concatenated certificate and the NUL terminator is counted to
471+
* total concatenated certificate length.
456472
*
457473
* Function must be called before connecting the device i.e before call to connect() method.
458474
* Function will not copy certificate, therefore addresses must remain valid.

features/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
/*
@@ -230,6 +229,11 @@ static void wisun_tasklet_parse_network_event(arm_event_s *event)
230229
static void wisun_tasklet_configure_and_connect_to_network(void)
231230
{
232231
int status;
232+
233+
if (wisun_tasklet_data_ptr->configured_and_connected) {
234+
return;
235+
}
236+
233237
fhss_timer_t *fhss_timer_ptr = &fhss_functions;
234238

235239
if (MBED_CONF_MBED_MESH_API_WISUN_DEVICE_TYPE == MESH_DEVICE_TYPE_WISUN_BORDER_ROUTER) {
@@ -245,7 +249,9 @@ static void wisun_tasklet_configure_and_connect_to_network(void)
245249
wisun_tasklet_data_ptr->operating_mode,
246250
wisun_tasklet_data_ptr->operating_mode_extension);
247251

248-
if (wisun_tasklet_add_stored_certificates() != 0) {
252+
int8_t trusted_set = false;
253+
int8_t own_set = false;
254+
if (wisun_tasklet_add_stored_certificates(&trusted_set, &own_set) != 0) {
249255
tr_error("Can't set Wi-SUN certificates");
250256
return;
251257
}
@@ -277,38 +283,41 @@ static void wisun_tasklet_configure_and_connect_to_network(void)
277283
}
278284

279285
#if defined(MBED_CONF_MBED_MESH_API_CERTIFICATE_HEADER)
280-
arm_certificate_entry_s trusted_cert = {
281-
.cert = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE,
282-
.key = NULL,
283-
.cert_len = 0,
284-
.key_len = 0
285-
};
286+
if (!trusted_set) {
287+
arm_certificate_entry_s trusted_cert = {
288+
.cert = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE,
289+
.key = NULL,
290+
.cert_len = 0,
291+
.key_len = 0
292+
};
286293
#ifdef MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE_LEN
287-
trusted_cert.cert_len = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE_LEN;
294+
trusted_cert.cert_len = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE_LEN;
288295
#else
289-
trusted_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE) + 1;
296+
trusted_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE) + 1;
290297
#endif
291-
arm_network_trusted_certificates_remove();
292-
arm_network_trusted_certificate_add((const arm_certificate_entry_s *)&trusted_cert);
293-
294-
arm_certificate_entry_s own_cert = {
295-
.cert = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE,
296-
.key = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY,
297-
.cert_len = 0,
298-
.key_len = 0
299-
};
298+
arm_network_trusted_certificates_remove();
299+
arm_network_trusted_certificate_add((const arm_certificate_entry_s *)&trusted_cert);
300+
}
301+
if (!own_set) {
302+
arm_certificate_entry_s own_cert = {
303+
.cert = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE,
304+
.key = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY,
305+
.cert_len = 0,
306+
.key_len = 0
307+
};
300308
#ifdef MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_LEN
301-
own_cert.cert_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_LEN;
309+
own_cert.cert_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_LEN;
302310
#else
303-
own_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE) + 1;
311+
own_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE) + 1;
304312
#endif
305313
#ifdef MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY_LEN
306-
own_cert.key_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY_LEN;
314+
own_cert.key_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY_LEN;
307315
#else
308-
own_cert.key_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY) + 1;
316+
own_cert.key_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY) + 1;
309317
#endif
310-
arm_network_own_certificates_remove();
311-
arm_network_own_certificate_add((const arm_certificate_entry_s *)&own_cert);
318+
arm_network_own_certificates_remove();
319+
arm_network_own_certificate_add((const arm_certificate_entry_s *)&own_cert);
320+
}
312321
#endif
313322

314323
if (statistics_started) {
@@ -317,6 +326,7 @@ static void wisun_tasklet_configure_and_connect_to_network(void)
317326

318327
status = arm_nwk_interface_up(wisun_tasklet_data_ptr->network_interface_id);
319328
if (status >= 0) {
329+
wisun_tasklet_data_ptr->configured_and_connected = true;
320330
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_BOOTSTRAP_STARTED;
321331
tr_info("Start Wi-SUN Bootstrap");
322332
wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_STARTED);
@@ -325,6 +335,7 @@ static void wisun_tasklet_configure_and_connect_to_network(void)
325335
tr_err("Bootstrap start failed, %d", status);
326336
wisun_tasklet_network_state_changed(MESH_BOOTSTRAP_START_FAILED);
327337
}
338+
328339
}
329340

330341
/*
@@ -337,7 +348,7 @@ static void wisun_tasklet_network_state_changed(mesh_connection_status_t status)
337348
}
338349
}
339350

340-
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)
351+
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)
341352
{
342353
if (wisun_certificates_ptr == NULL) {
343354
wisun_certificates_ptr = (wisun_certificates_t *)ns_dyn_mem_alloc(sizeof(wisun_certificates_t));
@@ -346,23 +357,11 @@ static int wisun_tasklet_store_certificate_data(const uint8_t *cert, uint16_t ce
346357
}
347358
ns_list_init(&wisun_certificates_ptr->own_certificates_list);
348359
ns_list_init(&wisun_certificates_ptr->trusted_certificates_list);
349-
wisun_certificates_ptr->remove_own_certificates = false;
350-
wisun_certificates_ptr->remove_trusted_certificates = false;
351-
}
352-
353-
if (remove_own) {
354-
wisun_certificates_ptr->remove_own_certificates = true;
355-
return 0;
356-
}
357-
358-
if (remove_trusted) {
359-
wisun_certificates_ptr->remove_trusted_certificates = true;
360-
return 0;
361360
}
362361

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

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

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

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

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

405-
ns_dyn_mem_free(wisun_certificates_ptr);
406-
wisun_certificates_ptr = NULL;
408+
if (ns_list_is_empty(&wisun_certificates_ptr->trusted_certificates_list) && ns_list_is_empty(&wisun_certificates_ptr->own_certificates_list)) {
409+
ns_dyn_mem_free(wisun_certificates_ptr);
410+
wisun_certificates_ptr = NULL;
411+
}
407412
}
408413

409-
static int wisun_tasklet_add_stored_certificates(void)
414+
static int wisun_tasklet_add_stored_certificates(int8_t *trusted_set, int8_t *own_set)
410415
{
411416
int8_t status = 0;
412417

@@ -415,15 +420,15 @@ static int wisun_tasklet_add_stored_certificates(void)
415420
return 0;
416421
}
417422

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

425-
if (wisun_certificates_ptr->remove_trusted_certificates) {
426-
status = arm_network_trusted_certificates_remove();
430+
if (!ns_list_is_empty(&wisun_certificates_ptr->own_certificates_list)) {
431+
status = arm_network_own_certificates_remove();
427432
if (status != 0) {
428433
goto CERTIFICATE_SET_END;
429434
}
@@ -434,17 +439,19 @@ static int wisun_tasklet_add_stored_certificates(void)
434439
if (status != 0) {
435440
goto CERTIFICATE_SET_END;
436441
}
442+
*trusted_set = true;
437443
}
438444

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

446453
CERTIFICATE_SET_END:
447-
wisun_tasklet_clear_stored_certificates();
454+
wisun_tasklet_clear_stored_certificates(true, true);
448455

449456
return status;
450457
}
@@ -480,6 +487,7 @@ int8_t wisun_tasklet_connect(mesh_interface_cb callback, int8_t nwk_interface_id
480487
wisun_tasklet_data_ptr->mesh_api_cb = callback;
481488
wisun_tasklet_data_ptr->network_interface_id = nwk_interface_id;
482489
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_INITIALIZED;
490+
wisun_tasklet_data_ptr->configured_and_connected = false;
483491

484492
if (re_connecting == false) {
485493
wisun_tasklet_data_ptr->tasklet = eventOS_event_handler_create(&wisun_tasklet_main,
@@ -508,6 +516,7 @@ int8_t wisun_tasklet_disconnect(bool send_cb)
508516
wisun_tasklet_network_state_changed(MESH_DISCONNECTED);
509517
}
510518
}
519+
wisun_tasklet_data_ptr->configured_and_connected = false;
511520
wisun_tasklet_data_ptr->mesh_api_cb = NULL;
512521
}
513522
return status;
@@ -521,6 +530,7 @@ void wisun_tasklet_init(void)
521530
memset(wisun_tasklet_data_ptr, 0, sizeof(wisun_tasklet_data_str_t));
522531
wisun_tasklet_data_ptr->tasklet_state = TASKLET_STATE_CREATED;
523532
wisun_tasklet_data_ptr->network_interface_id = INVALID_INTERFACE_ID;
533+
wisun_tasklet_data_ptr->configured_and_connected = false;
524534
}
525535
}
526536

@@ -541,7 +551,7 @@ int8_t wisun_tasklet_network_init(int8_t device_id)
541551

542552
int wisun_tasklet_set_own_certificate(uint8_t *cert, uint16_t cert_len, uint8_t *cert_key, uint16_t cert_key_len)
543553
{
544-
if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID) {
554+
if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID && wisun_tasklet_data_ptr->configured_and_connected) {
545555
// interface already active write certificates to stack.
546556
arm_certificate_entry_s arm_cert_entry;
547557
arm_cert_entry.cert = cert;
@@ -551,22 +561,40 @@ int wisun_tasklet_set_own_certificate(uint8_t *cert, uint16_t cert_len, uint8_t
551561
return arm_network_own_certificate_add(&arm_cert_entry);
552562
}
553563
// Stack is inactive store the certificates and activate when connect() called
554-
return wisun_tasklet_store_certificate_data(cert, cert_len, cert_key, cert_key_len, false, false, false);
564+
return wisun_tasklet_store_certificate_data(cert, cert_len, cert_key, cert_key_len, false);
555565
}
556566

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

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

567595
int wisun_tasklet_set_trusted_certificate(uint8_t *cert, uint16_t cert_len)
568596
{
569-
if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID) {
597+
if (wisun_tasklet_data_ptr && wisun_tasklet_data_ptr->network_interface_id != INVALID_INTERFACE_ID && wisun_tasklet_data_ptr->configured_and_connected) {
570598
// interface already active write certificates to stack.
571599
arm_certificate_entry_s arm_cert_entry;
572600
arm_cert_entry.cert = cert;
@@ -576,7 +604,7 @@ int wisun_tasklet_set_trusted_certificate(uint8_t *cert, uint16_t cert_len)
576604
return arm_network_trusted_certificate_add(&arm_cert_entry);
577605
}
578606
// Stack is inactive store the certificates and activate when connect() called
579-
return wisun_tasklet_store_certificate_data(cert, cert_len, NULL, 0, false, false, true);
607+
return wisun_tasklet_store_certificate_data(cert, cert_len, NULL, 0, true);
580608
}
581609

582610
int wisun_tasklet_statistics_start(void)

0 commit comments

Comments
 (0)