From 47e5dd74e2dcfc19b318579671bce493231aac35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=20Lepp=C3=A4nen?= Date: Fri, 20 Sep 2019 11:55:17 +0300 Subject: [PATCH] Enabled DER coded certificate support to Wi-SUN mesh API Wi-SUN mesh API uses now nanostack certificate interface with length parameters. This enables that either PEM or DER formatted certificates can be used. Using the length configuration for certificates and keys is optional, so existing applications using the PEM certificates do not require changes. --- .../nanostack/mbed-mesh-api/mbed_lib.json | 20 +++++++-- .../mbed-mesh-api/source/wisun_tasklet.c | 39 +++++++++++++---- .../source/6LoWPAN/ws/ws_pae_controller.c | 43 +++++++++++++++++++ .../source/6LoWPAN/ws/ws_pae_controller.h | 29 +++++++++++++ .../source/libNET/src/ns_net.c | 12 ++++++ 5 files changed, 130 insertions(+), 13 deletions(-) diff --git a/features/nanostack/mbed-mesh-api/mbed_lib.json b/features/nanostack/mbed-mesh-api/mbed_lib.json index 5bf9046682..8af1e2e24e 100644 --- a/features/nanostack/mbed-mesh-api/mbed_lib.json +++ b/features/nanostack/mbed-mesh-api/mbed_lib.json @@ -159,17 +159,29 @@ "value": null }, "root-certificate": { - "help": "Root certificate in PEM format (must be a null terminated c-string)", + "help": "Root certificate; in PEM format must be a null terminated c-string, in DER format the root-certificate-len must be set", "value": null }, + "root-certificate-len": { + "help": "Root certificate length; optional for PEM format, must be defined for DER format", + "value": null + }, "own-certificate": { - "help": "Own certificate in PEM format (must be a null terminated c-string)", + "help": "Own certificate; in PEM format must be a null terminated c-string, in DER format the own-certificate-len must be set", + "value": null + }, + "own-certificate-len": { + "help": "Own certificate length; optional for PEM format, must be defined for DER format", "value": null }, "own-certificate-key": { - "help": "Own certificate's key in PEM format (must be a null terminated c-string)", + "help": "Own certificate's key; in PEM format must be a null terminated c-string, in DER format the own-certificate-key-len must be set", "value": null - } + }, + "own-certificate-key-len": { + "help": "Own certificate's key length; optional for PEM format, must be defined for DER format", + "value": null + } }, "target_overrides": { "KW24D": { diff --git a/features/nanostack/mbed-mesh-api/source/wisun_tasklet.c b/features/nanostack/mbed-mesh-api/source/wisun_tasklet.c index f75e13b565..1079bcf67e 100644 --- a/features/nanostack/mbed-mesh-api/source/wisun_tasklet.c +++ b/features/nanostack/mbed-mesh-api/source/wisun_tasklet.c @@ -269,15 +269,36 @@ static void wisun_tasklet_configure_and_connect_to_network(void) } #if defined(MBED_CONF_MBED_MESH_API_CERTIFICATE_HEADER) - arm_certificate_chain_entry_s chain_info; - memset(&chain_info, 0, sizeof(arm_certificate_chain_entry_s)); - chain_info.cert_chain[0] = (const uint8_t *) MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE; - chain_info.cert_len[0] = strlen((const char *) MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE) + 1; - chain_info.cert_chain[1] = (const uint8_t *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE; - chain_info.cert_len[1] = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE) + 1; - chain_info.key_chain[1] = (const uint8_t *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY; - chain_info.chain_length = 2; - arm_network_certificate_chain_set((const arm_certificate_chain_entry_s *) &chain_info); + arm_certificate_entry_s trusted_cert = { + .cert = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE, + .key = NULL, + .cert_len = 0, + .key_len = 0 + }; +#ifdef MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE_LEN + trusted_cert.cert_len = MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE_LEN; +#else + trusted_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_ROOT_CERTIFICATE) + 1; +#endif + arm_network_trusted_certificate_add((const arm_certificate_entry_s *)&trusted_cert); + + arm_certificate_entry_s own_cert = { + .cert = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE, + .key = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY, + .cert_len = 0, + .key_len = 0 + }; +#ifdef MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_LEN + own_cert.cert_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_LEN; +#else + own_cert.cert_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE) + 1; +#endif +#ifdef MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY_LEN + own_cert.key_len = MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY_LEN; +#else + own_cert.key_len = strlen((const char *) MBED_CONF_MBED_MESH_API_OWN_CERTIFICATE_KEY) + 1; +#endif + arm_network_own_certificate_add((const arm_certificate_entry_s *)&own_cert); #endif status = arm_nwk_interface_up(wisun_tasklet_data_ptr->network_interface_id); diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.c b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.c index 086ec06393..1789cc01c6 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.c +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.c @@ -769,6 +769,40 @@ int8_t ws_pae_controller_certificate_chain_set(const arm_certificate_chain_entry return 0; } +int8_t ws_pae_controller_own_certificate_add(const arm_certificate_entry_s *cert) +{ + if (!cert) { + return -1; + } + + int8_t ret = -1; + + ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { + for (uint8_t i = 0; i < SEC_PROT_CERT_CHAIN_DEPTH; i++) { + if (entry->certs.own_cert_chain.cert[i] == NULL) { + sec_prot_certs_cert_set(&entry->certs.own_cert_chain, i, (uint8_t *) cert->cert, cert->cert_len); + // Set private key if set for the certificate that is added + if (cert->key && cert->key_len > 0) { + sec_prot_certs_priv_key_set(&entry->certs.own_cert_chain, (uint8_t *) cert->key, cert->key_len); + } + ret = 0; + break; + } + } + } + + return ret; +} + +int8_t ws_pae_controller_own_certificates_remove(void) +{ + ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { + sec_prot_certs_chain_entry_init(&entry->certs.own_cert_chain); + } + + return 0; +} + int8_t ws_pae_controller_trusted_certificate_add(const arm_certificate_entry_s *cert) { if (!cert) { @@ -816,6 +850,15 @@ int8_t ws_pae_controller_trusted_certificate_remove(const arm_certificate_entry_ return ret; } +int8_t ws_pae_controller_trusted_certificates_remove(void) +{ + ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { + sec_prot_certs_chain_list_delete(&entry->certs.trusted_cert_chain_list); + } + + return 0; +} + int8_t ws_pae_controller_certificate_revocation_list_add(const arm_cert_revocation_list_entry_s *crl) { if (!crl) { diff --git a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.h b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.h index b34a61ae37..3b9c8c61ff 100644 --- a/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.h +++ b/features/nanostack/sal-stack-nanostack/source/6LoWPAN/ws/ws_pae_controller.h @@ -158,6 +158,26 @@ int8_t ws_pae_controller_timing_adjust(uint8_t timing); */ int8_t ws_pae_controller_certificate_chain_set(const arm_certificate_chain_entry_s *chain); +/** + * ws_pae_controller_own_certificate_add add own certificate to certificate chain + * + * \param cert own certificate + * + * \return < 0 failure + * \return >= 0 success + * + */ +int8_t ws_pae_controller_own_certificate_add(const arm_certificate_entry_s *cert); + +/** + * ws_pae_controller_own_certificates_remove removes own certificates + * + * \return < 0 failure + * \return >= 0 success + * + */ +int8_t ws_pae_controller_own_certificates_remove(void); + /** * ws_pae_controller_trusted_certificate_add add trusted certificate * @@ -180,6 +200,15 @@ int8_t ws_pae_controller_trusted_certificate_add(const arm_certificate_entry_s * */ int8_t ws_pae_controller_trusted_certificate_remove(const arm_certificate_entry_s *cert); +/** + * ws_pae_controller_trusted_certificates_remove removes trusted certificates + * + * \return < 0 failure + * \return >= 0 success + * + */ +int8_t ws_pae_controller_trusted_certificates_remove(void); + /** * ws_pae_controller_certificate_revocation_list_add add certification revocation list * diff --git a/features/nanostack/sal-stack-nanostack/source/libNET/src/ns_net.c b/features/nanostack/sal-stack-nanostack/source/libNET/src/ns_net.c index da7e31b98e..5ee8a60dc6 100644 --- a/features/nanostack/sal-stack-nanostack/source/libNET/src/ns_net.c +++ b/features/nanostack/sal-stack-nanostack/source/libNET/src/ns_net.c @@ -988,18 +988,30 @@ int8_t arm_network_trusted_certificate_remove(const arm_certificate_entry_s *cer int8_t arm_network_trusted_certificates_remove(void) { +#ifdef HAVE_WS + return ws_pae_controller_trusted_certificates_remove(); +#else return -1; +#endif } int8_t arm_network_own_certificate_add(const arm_certificate_entry_s *cert) { +#ifdef HAVE_WS + return ws_pae_controller_own_certificate_add(cert); +#else (void) cert; return -1; +#endif } extern int8_t arm_network_own_certificates_remove(void) { +#ifdef HAVE_WS + return ws_pae_controller_own_certificates_remove(); +#else return -1; +#endif } int8_t arm_network_certificate_revocation_list_add(const arm_cert_revocation_list_entry_s *crl)