Browse Source

samples: net: sockets: coap_server: Add CoAP secure support

Update the CoAP server sample to demonstrate using DTLS for secure
sockets.

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
pull/88358/head
Pieter De Gendt 2 months ago committed by Anas Nashif
parent
commit
51a4e4c858
  1. 29
      samples/net/sockets/coap_server/CMakeLists.txt
  2. 36
      samples/net/sockets/coap_server/Kconfig
  3. 15
      samples/net/sockets/coap_server/README.rst
  4. 18
      samples/net/sockets/coap_server/overlay-dtls.conf
  5. 5
      samples/net/sockets/coap_server/prj.conf
  6. 10
      samples/net/sockets/coap_server/sample.yaml
  7. 43
      samples/net/sockets/coap_server/src/certificate.h
  8. BIN
      samples/net/sockets/coap_server/src/certs/ca.der
  9. BIN
      samples/net/sockets/coap_server/src/certs/coaps-server-cert.der
  10. BIN
      samples/net/sockets/coap_server/src/certs/coaps-server-key.der
  11. BIN
      samples/net/sockets/coap_server/src/certs/server.der
  12. BIN
      samples/net/sockets/coap_server/src/certs/server_privkey.der
  13. 14
      samples/net/sockets/coap_server/src/dummy_psk.h
  14. 128
      samples/net/sockets/coap_server/src/main.c

29
samples/net/sockets/coap_server/CMakeLists.txt

@ -4,6 +4,19 @@ cmake_minimum_required(VERSION 3.20.0) @@ -4,6 +4,19 @@ cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(coap_server)
if(CONFIG_NET_SOCKETS_ENABLE_DTLS AND
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED AND
(CONFIG_NET_SAMPLE_PSK_HEADER_FILE STREQUAL "dummy_psk.h"))
add_custom_target(development_psk
COMMAND ${CMAKE_COMMAND} -E echo "----------------------------------------------------------"
COMMAND ${CMAKE_COMMAND} -E echo "--- WARNING: Using dummy PSK! Only suitable for ---"
COMMAND ${CMAKE_COMMAND} -E echo "--- development. Set NET_SAMPLE_PSK_HEADER_FILE to use ---"
COMMAND ${CMAKE_COMMAND} -E echo "--- own pre-shared key. ---"
COMMAND ${CMAKE_COMMAND} -E echo "----------------------------------------------------------"
)
add_dependencies(app development_psk)
endif()
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/ip)
@ -18,3 +31,19 @@ zephyr_iterable_section( @@ -18,3 +31,19 @@ zephyr_iterable_section(
SUBALIGN ${CONFIG_LINKER_ITERABLE_SUBALIGN})
include(${ZEPHYR_BASE}/samples/net/common/common.cmake)
set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/)
foreach(inc_file
ca.der
server.der
server_privkey.der
coaps-server-cert.der
coaps-server-key.der
)
generate_inc_file_for_target(
app
src/certs/${inc_file}
${gen_dir}/${inc_file}.inc
)
endforeach()

36
samples/net/sockets/coap_server/Kconfig

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
# Copyright (c) 2023, Emna Rekik
# Copyright (c) 2025, Basalte bv
# SPDX-License-Identifier: Apache-2.0
# Config options for CoAP server sample application
mainmenu "CoAP server sample application"
config NET_SAMPLE_COAPS_SERVICE
bool "Enable CoAP secure service"
depends on NET_SOCKETS_ENABLE_DTLS || TLS_CREDENTIALS
config NET_SAMPLE_COAP_SERVER_SERVICE_PORT
int "Port number for CoAP service"
default 5684 if NET_SAMPLE_COAPS_SERVICE
default 5683
if NET_SAMPLE_COAPS_SERVICE
config NET_SAMPLE_PSK_HEADER_FILE
string "Header file containing PSK"
default "dummy_psk.h"
depends on MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
help
Name of a header file containing a pre-shared key.
config NET_SAMPLE_CERTS_WITH_SC
bool "Signed Certificates"
depends on NET_SOCKETS_SOCKOPT_TLS
help
Enable this flag, if you are interested to run this
application with certificates.
endif
source "Kconfig.zephyr"

15
samples/net/sockets/coap_server/README.rst

@ -17,8 +17,9 @@ service's name. A linker file is required, see ``sections-ram.ld`` for an exampl @@ -17,8 +17,9 @@ service's name. A linker file is required, see ``sections-ram.ld`` for an exampl
This demo assumes that the platform of choice has networking support,
some adjustments to the configuration may be needed.
The sample will listen for requests in the CoAP UDP port (5683) in the
site-local IPv6 multicast address reserved for CoAP nodes.
The sample will listen for requests on the default CoAP UDP port
(5683 or 5684 for secure CoAP) in the site-local IPv6 multicast address reserved
for CoAP nodes.
The sample exports the following resources:
@ -37,6 +38,16 @@ against coap-server. @@ -37,6 +38,16 @@ against coap-server.
Building And Running
********************
Build the CoAP server sample application like this:
.. zephyr-app-commands::
:zephyr-app: samples/net/sockets/coap_server
:board: <board to use>
:goals: build
:compact:
Use :zephyr_file:`overlay-dtls.conf <samples/net/sockets/coap_server/overlay-dtls.conf>`
to build the sample with CoAP secure resources instead.
This project has no output in case of success, the correct
functionality can be verified by using some external tool such as tcpdump

18
samples/net/sockets/coap_server/overlay-dtls.conf

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
CONFIG_NET_SAMPLE_COAPS_SERVICE=y
# Secure Socket
CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
CONFIG_NET_SOCKETS_ENABLE_DTLS=y
CONFIG_NET_SOCKETS_TLS_MAX_CLIENT_SESSION_COUNT=6
CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=6
CONFIG_NET_SOCKETS_DTLS_TIMEOUT=30000
# TLS configuration
CONFIG_MBEDTLS_DEBUG=y
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_BUILTIN=y
CONFIG_MBEDTLS_ENABLE_HEAP=y
CONFIG_MBEDTLS_HEAP_SIZE=60000
CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID=y
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=2048
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED=y

5
samples/net/sockets/coap_server/prj.conf

@ -6,7 +6,7 @@ CONFIG_NET_UDP=y @@ -6,7 +6,7 @@ CONFIG_NET_UDP=y
# Socket
CONFIG_NET_SOCKETS=y
CONFIG_POSIX_API=y
CONFIG_ZVFS_POLL_MAX=4
CONFIG_ZVFS_POLL_MAX=10
# CoAP
CONFIG_COAP=y
@ -48,3 +48,6 @@ CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=5 @@ -48,3 +48,6 @@ CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=5
CONFIG_NET_IPV4=n
CONFIG_NET_CONFIG_NEED_IPV4=n
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1"
# Enable v4-mapped-on-v6
CONFIG_NET_IPV4_MAPPING_TO_IPV6=y

10
samples/net/sockets/coap_server/sample.yaml

@ -12,6 +12,16 @@ tests: @@ -12,6 +12,16 @@ tests:
platform_allow:
- native_sim
- qemu_x86
sample.net.sockets.coaps_server:
harness: net
extra_args: EXTRA_CONF_FILE="overlay-dtls.conf"
tags:
- net
- socket
- tls
platform_allow:
- native_sim
- qemu_x86
sample.net.sockets.coap_server.wifi.nrf70dk:
extra_args:
- SNIPPET=wifi-ipv4

43
samples/net/sockets/coap_server/src/certificate.h

@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __CERTIFICATE_H__
#define __CERTIFICATE_H__
#define SERVER_CERTIFICATE_TAG 1
#define PSK_TAG 2
#if !defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC)
static const unsigned char server_certificate[] = {
#include "coaps-server-cert.der.inc"
};
/* This is the private key in pkcs#8 format. */
static const unsigned char private_key[] = {
#include "coaps-server-key.der.inc"
};
#else
static const unsigned char ca_certificate[] = {
#include "ca.der.inc"
};
static const unsigned char server_certificate[] = {
#include "server.der.inc"
};
/* This is the private key in pkcs#8 format. */
static const unsigned char private_key[] = {
#include "server_privkey.der.inc"
};
#endif
#if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
#include CONFIG_NET_SAMPLE_PSK_HEADER_FILE
#endif
#endif /* __CERTIFICATE_H__ */

BIN
samples/net/sockets/coap_server/src/certs/ca.der

Binary file not shown.

BIN
samples/net/sockets/coap_server/src/certs/coaps-server-cert.der

Binary file not shown.

BIN
samples/net/sockets/coap_server/src/certs/coaps-server-key.der

Binary file not shown.

BIN
samples/net/sockets/coap_server/src/certs/server.der

Binary file not shown.

BIN
samples/net/sockets/coap_server/src/certs/server_privkey.der

Binary file not shown.

14
samples/net/sockets/coap_server/src/dummy_psk.h

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DUMMY_PSK_H__
#define __DUMMY_PSK_H__
static const unsigned char psk[] = {0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
static const char psk_id[] = "PSK_identity";
#endif /* __DUMMY_PSK_H__ */

128
samples/net/sockets/coap_server/src/main.c

@ -8,18 +8,98 @@ @@ -8,18 +8,98 @@
LOG_MODULE_REGISTER(net_coap_service_sample, LOG_LEVEL_DBG);
#include <zephyr/net/coap_service.h>
#include <zephyr/net/mld.h>
#include "net_sample_common.h"
#ifdef CONFIG_NET_IPV6
#include <zephyr/net/mld.h>
#include "net_private.h"
#include "ipv6.h"
#endif
#include "net_sample_common.h"
static uint16_t coap_port = CONFIG_NET_SAMPLE_COAP_SERVER_SERVICE_PORT;
static const uint16_t coap_port = 5683;
#ifndef CONFIG_NET_SAMPLE_COAPS_SERVICE
#ifdef CONFIG_NET_IPV6
COAP_SERVICE_DEFINE(coap_server, NULL, &coap_port, COAP_SERVICE_AUTOSTART);
#else /* CONFIG_NET_SAMPLE_COAPS_SERVICE */
#include "certificate.h"
static const sec_tag_t sec_tag_list_verify_none[] = {
SERVER_CERTIFICATE_TAG,
#if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
PSK_TAG,
#endif
};
COAPS_SERVICE_DEFINE(coap_server, NULL, &coap_port, 0,
sec_tag_list_verify_none, sizeof(sec_tag_list_verify_none));
#endif /* CONFIG_NET_SAMPLE_COAPS_SERVICE */
static int setup_dtls(void)
{
#if defined(CONFIG_NET_SAMPLE_COAPS_SERVICE)
#if defined(CONFIG_NET_SOCKETS_ENABLE_DTLS)
int err;
#if defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC)
err = tls_credential_add(SERVER_CERTIFICATE_TAG,
TLS_CREDENTIAL_CA_CERTIFICATE,
ca_certificate,
sizeof(ca_certificate));
if (err < 0) {
LOG_ERR("Failed to register CA certificate: %d", err);
return err;
}
#endif /* defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC) */
err = tls_credential_add(SERVER_CERTIFICATE_TAG,
TLS_CREDENTIAL_SERVER_CERTIFICATE,
server_certificate,
sizeof(server_certificate));
if (err < 0) {
LOG_ERR("Failed to register public certificate: %d", err);
return err;
}
err = tls_credential_add(SERVER_CERTIFICATE_TAG,
TLS_CREDENTIAL_PRIVATE_KEY,
private_key, sizeof(private_key));
if (err < 0) {
LOG_ERR("Failed to register private key: %d", err);
return err;
}
#if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
err = tls_credential_add(PSK_TAG,
TLS_CREDENTIAL_PSK,
psk,
sizeof(psk));
if (err < 0) {
LOG_ERR("Failed to register PSK: %d", err);
return err;
}
err = tls_credential_add(PSK_TAG,
TLS_CREDENTIAL_PSK_ID,
psk_id,
sizeof(psk_id) - 1);
if (err < 0) {
LOG_ERR("Failed to register PSK ID: %d", err);
return err;
}
#endif /* defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) */
#endif /* defined(CONFIG_NET_SOCKETS_ENABLE_DTLS) */
#endif /* defined(CONFIG_NET_SAMPLE_COAPS_SERVICE) */
return 0;
}
#if !defined(CONFIG_NET_SAMPLE_COAPS_SERVICE) && defined(CONFIG_NET_IPV6)
#define ALL_NODES_LOCAL_COAP_MCAST \
{ { { 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xfd } } }
@ -27,13 +107,13 @@ static const uint16_t coap_port = 5683; @@ -27,13 +107,13 @@ static const uint16_t coap_port = 5683;
#define MY_IP6ADDR \
{ { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } }
static int join_coap_multicast_group(void)
static int join_coap_multicast_group(uint16_t port)
{
static struct in6_addr my_addr = MY_IP6ADDR;
static struct sockaddr_in6 mcast_addr = {
struct sockaddr_in6 mcast_addr = {
.sin6_family = AF_INET6,
.sin6_addr = ALL_NODES_LOCAL_COAP_MCAST,
.sin6_port = htons(coap_port) };
.sin6_port = htons(port) };
struct net_if_addr *ifaddr;
struct net_if *iface;
int ret;
@ -71,22 +151,36 @@ static int join_coap_multicast_group(void) @@ -71,22 +151,36 @@ static int join_coap_multicast_group(void)
return 0;
}
#endif /* CONFIG_NET_IPV6 */
int main(void)
{
int ret;
wait_for_network();
return join_coap_multicast_group();
ret = setup_dtls();
if (ret < 0) {
LOG_ERR("Failed to setup DTLS (%d)", ret);
return ret;
}
#else /* CONFIG_NET_IPV6 */
int main(void)
{
wait_for_network();
return 0;
#if !defined(CONFIG_NET_SAMPLE_COAPS_SERVICE) && defined(CONFIG_NET_IPV6)
ret = join_coap_multicast_group(coap_port);
if (ret < 0) {
LOG_ERR("Failed to join CoAP all-nodes multicast (%d)", ret);
return ret;
}
#endif
#endif /* CONFIG_NET_IPV6 */
#ifdef CONFIG_NET_SAMPLE_COAPS_SERVICE
/* CoAP secure server has to be started manually after DTLS setup */
ret = coap_service_start(&coap_server);
if (ret < 0) {
LOG_ERR("Failed to start CoAP secure server (%d)", ret);
return ret;
}
#endif
COAP_SERVICE_DEFINE(coap_server, NULL, &coap_port, COAP_SERVICE_AUTOSTART);
return ret;
}

Loading…
Cancel
Save