From cf0dfc52f0528ee76829ae89b51aebbc7e29003d Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Tue, 2 Jan 2024 12:48:55 +0000 Subject: [PATCH] feat(coap): Support both PKI and PSK being configured concurrently --- coap/Kconfig | 28 +++++++----- coap/examples/coap_client/README.md | 18 ++++++-- .../main/coap_client_example_main.c | 45 +++++++++++++++++-- coap/examples/coap_server/README.md | 6 ++- coap/idf_component.yml | 2 +- coap/port/include/coap3/coap.h | 2 +- coap/port/include/coap_config.h | 2 +- coap/port/include/coap_config_posix.h | 2 +- 8 files changed, 82 insertions(+), 23 deletions(-) diff --git a/coap/Kconfig b/coap/Kconfig index ff8bca9e4a..f8bdd224f9 100644 --- a/coap/Kconfig +++ b/coap/Kconfig @@ -1,21 +1,27 @@ menu "CoAP Configuration" - choice COAP_MBEDTLS_ENCRYPTION_MODE - prompt "CoAP Encryption method" - default COAP_MBEDTLS_PSK + config COAP_MBEDTLS_PSK + bool "Pre-Shared Keys" + default y help If the CoAP information is to be encrypted, the encryption environment - can be set up in one of two ways (default being Pre-Shared key mode) + can be set up using Pre-Shared keys (PSK) mode. - Encrypt using defined Pre-Shared Keys (PSK if uri includes coaps://) - - Encrypt using defined Public Key Infrastructure (PKI if uri includes coaps://) + - Note: If PKI is set as well, a server will decide which method to use + based on the incoming encryption request. It is up to the client + logic to decide which one to use. - config COAP_MBEDTLS_PSK - bool "Pre-Shared Keys" - - config COAP_MBEDTLS_PKI - bool "PKI Certificates" + config COAP_MBEDTLS_PKI + bool "PKI Certificates" + default n + help + If the CoAP information is to be encrypted, the encryption environment + can be set up using Public Key Infrastructure (PKI) mode. - endchoice #COAP_MBEDTLS_ENCRYPTION_MODE + - Encrypt using defined Public Key Infrastructure (PKI if uri includes coaps://) + - Note: If PSK is set as well, a server will decide which method to use + based on the incoming encryption request. It is up to the client + logic to decide which one to use. config COAP_DEBUGGING bool "Enable CoAP debugging" diff --git a/coap/examples/coap_client/README.md b/coap/examples/coap_client/README.md index cc5f65c7ac..d2daa0843d 100644 --- a/coap/examples/coap_client/README.md +++ b/coap/examples/coap_client/README.md @@ -16,13 +16,23 @@ as well as supporting the Observer extensions [RFC7641](https://tools.ietf.org/h If the URI is prefixed with coaps:// instead of coap://, then the CoAP client will attempt to use the DTLS protocol using the defined Pre-Shared Keys(PSK) or Public Key Infrastructure (PKI) which the -CoAP server needs to know about. +CoAP server needs to know about. If both PSK and PKI are defined, then it is the responsibility +of the client code to decide (PSK or PKI) which to use. If the URI is prefixed with coap+tcp://, then the CoAP will try to use TCP for the communication. +If the URI is prefixed with coaps+tcp://, then the CoAP will try to use TLS for the communication. +If both PSK and PKI are defined, then it is the responsibility of the client code to decide (PSK +or PKI) which to use. + If the URI is prefixed with coap+ws://, then the CoAP will try to use WebSockets (over TCP) for the communication, which assumes that CoAP WebSockets is enabled in the build. +If the URI is prefixed with coaps+ws://, then the CoAP will try to use WebSockets (over TLS) for +the communication, which assumes that CoAP WebSockets is enabled in the build. +If both PSK and PKI are defined, then it is the responsibility of the client code to decide (PSK +or PKI) which to use. + The Constrained Application Protocol (CoAP) is a specialized web transfer protocol for use with constrained nodes and constrained networks in the Internet of Things. The protocol is designed for machine-to-machine (M2M) applications such as smart energy and @@ -43,10 +53,12 @@ Example Connection Configuration ---> * Set WiFi Password Component config ---> CoAP Configuration ---> - * Set encryption method definition, PSK (default) or PKI + * Set encryption method definition, PSK (default) and/or PKI * Enable CoAP debugging if required - * Disable CoAP using TCP if this is not required (TCP needed for TLS) + * Disable CoAP using TCP if this is not required (TCP needed for TLS or WebSockets) * Disable CoAP server functionality to reduce code size + * Enable OSCORE (RFC8613) support if required + * Enable WebSockets (RFC8323) support if required Example CoAP Client Configuration ---> * Set CoAP Target Uri * If PSK, Set CoAP Preshared Key to use in connection to the server diff --git a/coap/examples/coap_client/main/coap_client_example_main.c b/coap/examples/coap_client/main/coap_client_example_main.c index fbc6314a56..82febde1d4 100644 --- a/coap/examples/coap_client/main/coap_client_example_main.c +++ b/coap/examples/coap_client/main/coap_client_example_main.c @@ -271,6 +271,35 @@ coap_start_pki_session(coap_context_t *ctx, coap_address_t *dst_addr, coap_uri_t } #endif /* CONFIG_COAP_MBEDTLS_PKI */ +static coap_session_t * +coap_start_anon_pki_session(coap_context_t *ctx, coap_address_t *dst_addr, coap_uri_t *uri, coap_proto_t proto) +{ + static coap_dtls_pki_t dtls_pki; + static char client_sni[256]; + + memset (&dtls_pki, 0, sizeof(dtls_pki)); + dtls_pki.version = COAP_DTLS_PKI_SETUP_VERSION; + memset(client_sni, 0, sizeof(client_sni)); + if (uri->host.length) { + memcpy(client_sni, uri->host.s, MIN(uri->host.length, sizeof(client_sni))); + } else { + memcpy(client_sni, "localhost", 9); + } + dtls_pki.client_sni = client_sni; + dtls_pki.pki_key.key_type = COAP_PKI_KEY_PEM; + dtls_pki.pki_key.key.pem.public_cert = NULL; + dtls_pki.pki_key.key.pem.private_key = NULL; + dtls_pki.pki_key.key.pem.ca_file = NULL; + +#ifdef CONFIG_COAP_OSCORE_SUPPORT + return coap_new_client_session_oscore_pki(ctx, NULL, dst_addr, proto, + &dtls_pki, oscore_conf); +#else /* ! CONFIG_COAP_OSCORE_SUPPORT */ + return coap_new_client_session_pki(ctx, NULL, dst_addr, proto, + &dtls_pki); +#endif /* ! CONFIG_COAP_OSCORE_SUPPORT */ +} + static void coap_example_client(void *p) { coap_address_t dst_addr; @@ -355,13 +384,23 @@ static void coap_example_client(void *p) goto clean_up; #endif /* CONFIG_MBEDTLS_TLS_CLIENT */ + /* + * Encrypted request. Client needs to choose whether using PSK (if configured) + * or PKI (if configured) or anonymous PKI (where certificates are not defined locally). + * This code chooses PSK (if configured), then PKI (if configured) then anonymous + * PKI where certificates are not defined locally. + */ #ifdef CONFIG_COAP_MBEDTLS_PSK session = coap_start_psk_session(ctx, &dst_addr, &uri, proto); #endif /* CONFIG_COAP_MBEDTLS_PSK */ - #ifdef CONFIG_COAP_MBEDTLS_PKI - session = coap_start_pki_session(ctx, &dst_addr, &uri, proto); -#endif /* CONFIG_COAP_MBEDTLS_PKI */ + if (!session) { + session = coap_start_pki_session(ctx, &dst_addr, &uri, proto); + } +#endif /* CONFIG_COAP_MBEDTLS_PKI */ + if (!session) { + session = coap_start_anon_pki_session(ctx, &dst_addr, &uri, proto); + } } else { #ifdef CONFIG_COAP_OSCORE_SUPPORT session = coap_new_client_session_oscore(ctx, NULL, &dst_addr, proto, oscore_conf); diff --git a/coap/examples/coap_server/README.md b/coap/examples/coap_server/README.md index ef31ce06fe..445526b069 100644 --- a/coap/examples/coap_server/README.md +++ b/coap/examples/coap_server/README.md @@ -38,10 +38,12 @@ Example Connection Configuration ---> * Set WiFi Password Component config ---> CoAP Configuration ---> - * Set encryption method definition, PSK (default) or PKI + * Set encryption method definition, PSK (default) and/or PKI * Enable CoAP debugging if required - * Disable CoAP using TCP if this is not required (TCP needed for TLS) + * Disable CoAP using TCP if this is not required (TCP needed for TLS or WebSockets) * Disable CoAP client functionality to reduce code size unless this server is a proxy + * Enable OSCORE (RFC8613) support if required + * Enable WebSockets (RFC8323) support if required Example CoAP Server Configuration ---> * If PSK, Set CoAP Preshared Key to use for connections to the server diff --git a/coap/idf_component.yml b/coap/idf_component.yml index df88cf06a0..58ac63fa57 100644 --- a/coap/idf_component.yml +++ b/coap/idf_component.yml @@ -1,4 +1,4 @@ -version: "4.3.4" +version: "4.3.4~1" description: Constrained Application Protocol (CoAP) C Library url: https://github.com/espressif/idf-extra-components/tree/master/coap dependencies: diff --git a/coap/port/include/coap3/coap.h b/coap/port/include/coap3/coap.h index b056f0bc5a..25ff972935 100644 --- a/coap/port/include/coap3/coap.h +++ b/coap/port/include/coap3/coap.h @@ -5,7 +5,7 @@ * * coap.h -- main header file for CoAP stack of libcoap * - * Copyright (C) 2010-2012,2015-2016 Olaf Bergmann + * Copyright (C) 2010-2012,2015-2024 Olaf Bergmann * 2015 Carsten Schoenert * * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD diff --git a/coap/port/include/coap_config.h b/coap/port/include/coap_config.h index 165ce174ba..38a01f668c 100644 --- a/coap/port/include/coap_config.h +++ b/coap/port/include/coap_config.h @@ -6,7 +6,7 @@ * * coap.h -- main header file for CoAP stack of libcoap * - * Copyright (C) 2010-2012,2015-2016 Olaf Bergmann + * Copyright (C) 2010-2012,2015-2024 Olaf Bergmann * 2015 Carsten Schoenert * * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD diff --git a/coap/port/include/coap_config_posix.h b/coap/port/include/coap_config_posix.h index 2d4d023f06..479360362b 100644 --- a/coap/port/include/coap_config_posix.h +++ b/coap/port/include/coap_config_posix.h @@ -6,7 +6,7 @@ * * coap.h -- main header file for CoAP stack of libcoap * - * Copyright (C) 2010-2012,2015-2016 Olaf Bergmann + * Copyright (C) 2010-2012,2015-2024 Olaf Bergmann * 2015 Carsten Schoenert * * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD