Skip to content

Commit b8611bd

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 06e29c4 commit b8611bd

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)