From 0a8eaea8892f387b73b0aa1a1f6f1537c34ed064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1nos=20Brodbeck?= Date: Thu, 28 Jan 2021 10:21:55 +0100 Subject: [PATCH] example/gcoap: add DTLS support --- examples/gcoap/gcoap_cli.c | 47 +++++++++++++++- examples/gcoap_dtls/Makefile | 85 +++++++++++++++++++++++++++++ examples/gcoap_dtls/Makefile.ci | 53 ++++++++++++++++++ examples/gcoap_dtls/Makefile.slip | 1 + examples/gcoap_dtls/README.md | 12 ++++ examples/gcoap_dtls/gcoap_cli.c | 1 + examples/gcoap_dtls/main.c | 1 + examples/gcoap_dtls/tinydtls_keys.h | 63 +++++++++++++++++++++ 8 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 examples/gcoap_dtls/Makefile create mode 100644 examples/gcoap_dtls/Makefile.ci create mode 120000 examples/gcoap_dtls/Makefile.slip create mode 100644 examples/gcoap_dtls/README.md create mode 120000 examples/gcoap_dtls/gcoap_cli.c create mode 120000 examples/gcoap_dtls/main.c create mode 100644 examples/gcoap_dtls/tinydtls_keys.h diff --git a/examples/gcoap/gcoap_cli.c b/examples/gcoap/gcoap_cli.c index b9c7a5546f..c38a7f90c7 100644 --- a/examples/gcoap/gcoap_cli.c +++ b/examples/gcoap/gcoap_cli.c @@ -30,6 +30,28 @@ #define ENABLE_DEBUG 0 #include "debug.h" +#if IS_USED(MODULE_GCOAP_DTLS) +#include "net/credman.h" +#include "net/dsm.h" +#include "tinydtls_keys.h" + +/* Example credential tag for credman. Tag together with the credential type needs to be unique. */ +#define GCOAP_DTLS_CREDENTIAL_TAG 10 + +static const uint8_t psk_id_0[] = PSK_DEFAULT_IDENTITY; +static const uint8_t psk_key_0[] = PSK_DEFAULT_KEY; +static const credman_credential_t credential = { + .type = CREDMAN_TYPE_PSK, + .tag = GCOAP_DTLS_CREDENTIAL_TAG, + .params = { + .psk = { + .key = { .s = psk_key_0, .len = sizeof(psk_key_0) - 1, }, + .id = { .s = psk_id_0, .len = sizeof(psk_id_0) - 1, }, + } + }, +}; +#endif + static bool _proxied = false; static sock_udp_ep_t _proxy_remote; static char proxy_uri[64]; @@ -316,7 +338,16 @@ int gcoap_cli_cmd(int argc, char **argv) if (strcmp(argv[1], "info") == 0) { uint8_t open_reqs = gcoap_op_state(); - printf("CoAP server is listening on port %u\n", CONFIG_GCOAP_PORT); + if (IS_USED(MODULE_GCOAP_DTLS)) { + printf("CoAP server is listening on port %u\n", CONFIG_GCOAPS_PORT); + } else { + printf("CoAP server is listening on port %u\n", CONFIG_GCOAP_PORT); + } +#if IS_USED(MODULE_GCOAP_DTLS) + printf("Connection secured with DTLS\n"); + printf("Free DTLS session slots: %d/%d\n", dsm_get_num_available_slots(), + dsm_get_num_maximum_slots()); +#endif printf(" CLI requests sent: %u\n", req_count); printf("CoAP open requests: %u\n", open_reqs); printf("Configured Proxy: "); @@ -466,5 +497,19 @@ int gcoap_cli_cmd(int argc, char **argv) void gcoap_cli_init(void) { +#if IS_USED(MODULE_GCOAP_DTLS) + int res = credman_add(&credential); + if (res < 0 && res != CREDMAN_EXIST) { + /* ignore duplicate credentials */ + printf("gcoap: cannot add credential to system: %d\n", res); + return; + } + sock_dtls_t *gcoap_sock_dtls = gcoap_get_sock_dtls(); + res = sock_dtls_add_credential(gcoap_sock_dtls, GCOAP_DTLS_CREDENTIAL_TAG); + if (res < 0) { + printf("gcoap: cannot add credential to DTLS sock: %d\n", res); + } +#endif + gcoap_register_listener(&_listener); } diff --git a/examples/gcoap_dtls/Makefile b/examples/gcoap_dtls/Makefile new file mode 100644 index 0000000000..8d5cfdc916 --- /dev/null +++ b/examples/gcoap_dtls/Makefile @@ -0,0 +1,85 @@ +# Default Makefile, for host native GNRC-based networking + +# name of your application +APPLICATION = gcoap_example + +# If no BOARD is found in the environment, use this default: +BOARD ?= native + +# This has to be the absolute path to the RIOT base directory: +RIOTBASE ?= $(CURDIR)/../.. + +# Include packages that pull up and auto-init the link layer. +# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present +USEMODULE += gnrc_netdev_default +USEMODULE += auto_init_gnrc_netif +# Specify the mandatory networking modules +USEMODULE += gnrc_ipv6_default +USEMODULE += gcoap +# Additional networking modules that can be dropped if not needed +USEMODULE += gnrc_icmpv6_echo + +# Required by gcoap example +USEMODULE += od +USEMODULE += fmt +# Add also the shell, some shell commands +USEMODULE += shell +USEMODULE += shell_commands +USEMODULE += ps + +# Comment this out to disable code in RIOT that does safety checking +# which is not needed in a production environment but helps in the +# development process: +DEVELHELP ?= 1 + +# Change this to 0 show compiler invocation lines by default: +QUIET ?= 1 + +# Enables DTLS-secured CoAP messaging +GCOAP_ENABLE_DTLS ?= 1 +ifeq (1,$(GCOAP_ENABLE_DTLS)) + # Required by DTLS. Currently, only tinyDTLS is supported by sock_dtls. + USEPKG += tinydtls + USEMODULE += sock_dtls + USEMODULE += tinydtls_sock_dtls + USEMODULE += gcoap_dtls + # tinydtls needs crypto secure PRNG + USEMODULE += prng_sha1prng + + # Maximum number of DTLS sessions + CFLAGS += -DDTLS_PEER_MAX=1 +endif + +# Instead of simulating an Ethernet connection, we can also simulate +# an IEEE 802.15.4 radio using ZEP +USE_ZEP ?= 0 + +# set the ZEP port for native +ZEP_PORT_BASE ?= 17754 +ifeq (1,$(USE_ZEP)) + TERMFLAGS += -z [::1]:$(ZEP_PORT_BASE) + USEMODULE += socket_zep + + ifneq (,$(ZEP_MAC)) + TERMFLAGS += --eui64=$(ZEP_MAC) + endif +endif + +include $(RIOTBASE)/Makefile.include + +# For now this goes after the inclusion of Makefile.include so Kconfig symbols +# are available. Only set configuration via CFLAGS if Kconfig is not being used +# for this module. +ifndef CONFIG_KCONFIG_MODULE_GCOAP +## Uncomment to redefine port, for example use 61616 for RFC 6282 UDP compression. +#GCOAP_PORT = 5683 +#CFLAGS += -DCONFIG_GCOAP_PORT=$(GCOAP_PORT) + +## Uncomment to redefine request token length, max 8. +#GCOAP_TOKENLEN = 2 +#CFLAGS += -DCONFIG_GCOAP_TOKENLEN=$(GCOAP_TOKENLEN) + +# Increase from default for confirmable block2 follow-on requests +GCOAP_RESEND_BUFS_MAX ?= 2 +CFLAGS += -DCONFIG_GCOAP_RESEND_BUFS_MAX=$(GCOAP_RESEND_BUFS_MAX) +endif diff --git a/examples/gcoap_dtls/Makefile.ci b/examples/gcoap_dtls/Makefile.ci new file mode 100644 index 0000000000..7d33d0fe3b --- /dev/null +++ b/examples/gcoap_dtls/Makefile.ci @@ -0,0 +1,53 @@ +BOARD_INSUFFICIENT_MEMORY := \ + airfy-beacon \ + blackpill \ + bluepill \ + hifive1 \ + hifive1b \ + im880b \ + microbit \ + nrf51dongle \ + nrf6310 \ + nucleo-f070rb \ + nucleo-f072rb \ + nucleo-f302r8 \ + saml10-xpro \ + saml11-xpro \ + stm32mp157c-dk2 \ + yunjia-nrf51822 \ + arduino-duemilanove \ + arduino-leonardo \ + arduino-mega2560 \ + arduino-nano \ + arduino-uno \ + atmega1284p \ + atmega328p \ + atmega328p-xplained-mini \ + atxmega-a1u-xpro \ + atxmega-a3bu-xplained \ + bluepill-stm32f030c8 \ + derfmega128 \ + i-nucleo-lrwan1 \ + mega-xplained \ + microduino-corerf \ + msb-430 \ + msb-430h \ + nucleo-f030r8 \ + nucleo-f031k6 \ + nucleo-f042k6 \ + nucleo-f303k8 \ + nucleo-f334r8 \ + nucleo-l011k4 \ + nucleo-l031k6 \ + nucleo-l053r8 \ + samd10-xmini \ + slstk3400a \ + stk3200 \ + stm32f030f4-demo \ + stm32f0discovery \ + stm32l0538-disco \ + telosb \ + waspmote-pro \ + z1 \ + zigduino \ + # diff --git a/examples/gcoap_dtls/Makefile.slip b/examples/gcoap_dtls/Makefile.slip new file mode 120000 index 0000000000..4caf7a08c3 --- /dev/null +++ b/examples/gcoap_dtls/Makefile.slip @@ -0,0 +1 @@ +../gcoap/Makefile.slip \ No newline at end of file diff --git a/examples/gcoap_dtls/README.md b/examples/gcoap_dtls/README.md new file mode 100644 index 0000000000..6b4ef436ff --- /dev/null +++ b/examples/gcoap_dtls/README.md @@ -0,0 +1,12 @@ +## About + +This is an additional gcoap example, but with enabled DTLS. It only provides a +custom configured makefile, while the code is a symlink to the original gcoap +example. Therefore, the infos and usage notes of the other README also applies to this +example. + +Please note, that with DTLS the default port is 5684 and not 5683, thus CoAP requests +must be sent to this port. + +Since DTLS has higher memory and and ROM requirements, more boards are blacklisted +for this example compared to the non-DTLS gcoap example. diff --git a/examples/gcoap_dtls/gcoap_cli.c b/examples/gcoap_dtls/gcoap_cli.c new file mode 120000 index 0000000000..22f3ebcab1 --- /dev/null +++ b/examples/gcoap_dtls/gcoap_cli.c @@ -0,0 +1 @@ +../gcoap/gcoap_cli.c \ No newline at end of file diff --git a/examples/gcoap_dtls/main.c b/examples/gcoap_dtls/main.c new file mode 120000 index 0000000000..2710302f57 --- /dev/null +++ b/examples/gcoap_dtls/main.c @@ -0,0 +1 @@ +../gcoap/main.c \ No newline at end of file diff --git a/examples/gcoap_dtls/tinydtls_keys.h b/examples/gcoap_dtls/tinydtls_keys.h new file mode 100644 index 0000000000..cc741865ed --- /dev/null +++ b/examples/gcoap_dtls/tinydtls_keys.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2018 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup examples + * @{ + * + * @file + * @brief PSK and RPK keys for the dtls-sock example. + * + * @author Raul Fuentes + * + * @} + */ + +#ifndef TINYDTLS_KEYS_H +#define TINYDTLS_KEYS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Default keys examples for tinyDTLS (for RIOT, Linux and Contiki) + */ +#define PSK_DEFAULT_IDENTITY "Client_identity" +#define PSK_DEFAULT_KEY "secretPSK" +#define PSK_OPTIONS "i:k:" +#define PSK_ID_MAXLEN 32 +#define PSK_MAXLEN 32 + +#ifdef CONFIG_DTLS_ECC +static const unsigned char ecdsa_priv_key[] = { + 0x41, 0xC1, 0xCB, 0x6B, 0x51, 0x24, 0x7A, 0x14, + 0x43, 0x21, 0x43, 0x5B, 0x7A, 0x80, 0xE7, 0x14, + 0x89, 0x6A, 0x33, 0xBB, 0xAD, 0x72, 0x94, 0xCA, + 0x40, 0x14, 0x55, 0xA1, 0x94, 0xA9, 0x49, 0xFA +}; + +static const unsigned char ecdsa_pub_key_x[] = { + 0x36, 0xDF, 0xE2, 0xC6, 0xF9, 0xF2, 0xED, 0x29, + 0xDA, 0x0A, 0x9A, 0x8F, 0x62, 0x68, 0x4E, 0x91, + 0x63, 0x75, 0xBA, 0x10, 0x30, 0x0C, 0x28, 0xC5, + 0xE4, 0x7C, 0xFB, 0xF2, 0x5F, 0xA5, 0x8F, 0x52 +}; + +static const unsigned char ecdsa_pub_key_y[] = { + 0x71, 0xA0, 0xD4, 0xFC, 0xDE, 0x1A, 0xB8, 0x78, + 0x5A, 0x3C, 0x78, 0x69, 0x35, 0xA7, 0xCF, 0xAB, + 0xE9, 0x3F, 0x98, 0x72, 0x09, 0xDA, 0xED, 0x0B, + 0x4F, 0xAB, 0xC3, 0x6F, 0xC7, 0x72, 0xF8, 0x29 +}; +#endif /* CONFIG_DTLS_ECC */ +#ifdef __cplusplus +} +#endif + +#endif /* TINYDTLS_KEYS_H */