Skip to content

Commit

Permalink
Merge pull request RIOT-OS#11943 from pokgak/sock_dtls_impl
Browse files Browse the repository at this point in the history
pkg/tinydtls: add DTLS sock API implementation
  • Loading branch information
smlng authored Dec 5, 2019
2 parents 35ed8a8 + 57533a7 commit 6e53e28
Show file tree
Hide file tree
Showing 12 changed files with 1,169 additions and 0 deletions.
54 changes: 54 additions & 0 deletions examples/dtls-sock/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# name of your application
APPLICATION = dtls_sock

# 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)/../..

# TinyDTLS only has support for 32-bit architectures ATM
FEATURES_REQUIRED += arch_32bit

# 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 for IPv6 and UDP
USEMODULE += gnrc_ipv6_default
USEMODULE += gnrc_sock_udp

# Use tinydtls for sock_dtls
USEMODULE += tinydtls_sock_dtls

# Add also the shell, some shell commands
USEMODULE += shell
USEMODULE += shell_commands

# UDP Port to use (20220 is default for DTLS).
DTLS_PORT ?= 20220
CFLAGS += -DDTLS_DEFAULT_PORT=$(DTLS_PORT)

# NOTE: If no cipher suite is selected, DTLS_PSK is used by default.
# This adds support for TLS_PSK_WITH_AES_128_CCM_8
CFLAGS += -DDTLS_PSK
# This adds support for TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
# CFLAGS += -DDTLS_ECC

# Uncomment to enable debug logs
# CFLAGS += -DDTLS_DEBUG
# When DTLS_DEBUG is set and using tinydtls, verbosity of debug log can be set with
# Values: 0:EMERG (Default), 1:ALERT 2:CRIT 3:WARN 4:NOTICE 5:INFO 6:DEBUG
# TINYDTLS_LOG=3

# FIXME: This is a temporary patch
CFLAGS += -DTHREAD_STACKSIZE_MAIN=\(2*THREAD_STACKSIZE_LARGE\)

# 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

include $(RIOTBASE)/Makefile.include
41 changes: 41 additions & 0 deletions examples/dtls-sock/Makefile.ci
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
BOARD_INSUFFICIENT_MEMORY := \
airfy-beacon \
b-l072z-lrwan1 \
blackpill \
blackpill-128kib \
bluepill \
bluepill-128kib \
calliope-mini \
cc1352-launchpad \
cc2650-launchpad \
cc2650stk \
hifive1 \
hifive1b \
i-nucleo-lrwan1 \
lsn50 \
maple-mini \
microbit \
nrf51dongle \
nrf6310 \
nucleo-f030r8 \
nucleo-f031k6 \
nucleo-f042k6 \
nucleo-f070rb \
nucleo-f072rb \
nucleo-f103rb \
nucleo-f302r8 \
nucleo-f303k8 \
nucleo-f334r8 \
nucleo-l031k6 \
nucleo-l053r8 \
nucleo-l073rz \
opencm904 \
saml10-xpro \
saml11-xpro \
spark-core \
stm32f0discovery \
stm32f030f4-demo \
stm32l0538-disco \
stm32mindev \
yunjia-nrf51822
#
42 changes: 42 additions & 0 deletions examples/dtls-sock/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# DTLS sock example

This example shows how to use DTLS sock `sock_dtls_t`.

## Testing using RIOT `native`

For testing, we can use two RIOT `native` RIOT instances. For that first we
need to prepare the network interfaces:

```bash
$ ./../../dist/tools/tapsetup/tapsetup --create 2
```

For the server instance:

```
$ PORT=tap0 make all term
[...]
> dtlss start
ifconfig
```

For the client:

```
$ PORT=tap1 make all term
[...]
> dtlsc <server ip address> "DATA to send"
```

## Debug logs

To enable debug logs uncomment `CFLAGS += -DDTLS_DEBUG` in the Makefile.
Tinydtls supports setting the log level. See Makefile for more info.

## Configs and constraints

DTLS sock acts as a wrapper for the underlying DTLS stack and as such, the
constraints that applies specifically to the stack are also applied here.
For tinydtls, please refer to [dtls-echo README][1].

[1]: https://github.com/RIOT-OS/RIOT/blob/master/examples/dtls-echo/README.md
163 changes: 163 additions & 0 deletions examples/dtls-sock/dtls-client.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* Copyright (C) 2019 HAW Hamburg
*
* 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 DTLS sock client example
*
* @author Aiman Ismail <muhammadaimanbin.ismail@haw-hamburg.de>
*/

#include <stdio.h>

#include "net/sock/udp.h"
#include "net/sock/dtls.h"
#include "net/ipv6/addr.h"
#include "net/credman.h"

#include "tinydtls_keys.h"

#ifndef DTLS_DEFAULT_PORT
#define DTLS_DEFAULT_PORT 20220 /* DTLS default port */
#endif

#define SOCK_DTLS_CLIENT_TAG (2)

#ifdef DTLS_ECC
static const ecdsa_public_key_t other_pubkeys[] = {
{ .x = ecdsa_pub_key_x, .y = ecdsa_pub_key_y },
};

static const credman_credential_t credential = {
.type = CREDMAN_TYPE_ECDSA,
.tag = SOCK_DTLS_CLIENT_TAG,
.params = {
.ecdsa = {
.private_key = ecdsa_priv_key,
.public_key = {
.x = ecdsa_pub_key_x,
.y = ecdsa_pub_key_y,
},
.client_keys = (ecdsa_public_key_t *)other_pubkeys,
.client_keys_size = ARRAY_SIZE(other_pubkeys),
}
},
};

#else /* ifdef DTLS_PSK */
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 = SOCK_DTLS_CLIENT_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 int client_send(char *addr_str, char *data, size_t datalen)
{
ssize_t res;
sock_udp_t udp_sock;
sock_dtls_t dtls_sock;
sock_dtls_session_t session;
sock_udp_ep_t remote;
sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
local.port = 12345;
remote.port = DTLS_DEFAULT_PORT;

/* get interface */
char* iface = ipv6_addr_split_iface(addr_str);
if (iface) {
int pid = atoi(iface);
if (gnrc_netif_get_by_pid(pid) == NULL) {
puts("Invalid network interface");
return -1;
}
remote.netif = pid;
} else if (gnrc_netif_numof() == 1) {
/* assign the single interface found in gnrc_netif_numof() */
remote.netif = gnrc_netif_iter(NULL)->pid;
} else {
/* no interface is given, or given interface is invalid */
/* FIXME This probably is not valid with multiple interfaces */
remote.netif = SOCK_ADDR_ANY_NETIF;
}

if (!ipv6_addr_from_str((ipv6_addr_t *)remote.addr.ipv6, addr_str)) {
puts("Error parsing destination address");
return -1;
}

if (sock_udp_create(&udp_sock, &local, NULL, 0) < 0) {
puts("Error creating UDP sock");
return -1;
}

if (sock_dtls_create(&dtls_sock, &udp_sock,
SOCK_DTLS_CLIENT_TAG,
SOCK_DTLS_1_2, SOCK_DTLS_CLIENT) < 0) {
puts("Error creating DTLS sock");
sock_udp_close(&udp_sock);
return -1;
}

res = credman_add(&credential);
if (res < 0 && res != CREDMAN_EXIST) {
/* ignore duplicate credentials */
printf("Error cannot add credential to system: %zd\n", res);
return -1;
}

res = sock_dtls_session_create(&dtls_sock, &remote, &session);
if (res < 0) {
printf("Error creating session: %zd\n", res);
sock_dtls_close(&dtls_sock);
sock_udp_close(&udp_sock);
return -1;
}

if (sock_dtls_send(&dtls_sock, &session, data, datalen) < 0) {
puts("Error sending data");
}
else {
printf("Sent DTLS message\n");

uint8_t rcv[512];
if (sock_dtls_recv(&dtls_sock, &session, rcv, sizeof(rcv), SOCK_NO_TIMEOUT) < 0) {
printf("Error receiving DTLS message\n");
}
else {
printf("Received DTLS message\n");
}
}

puts("Terminating");
sock_dtls_session_destroy(&dtls_sock, &session);
sock_dtls_close(&dtls_sock);
sock_udp_close(&udp_sock);
return 0;
}

int dtls_client_cmd(int argc, char **argv)
{
if (argc != 3) {
printf("usage %s <addr> <data>\n", argv[0]);
return 1;
}

return client_send(argv[1], argv[2], strlen(argv[2]));
}
Loading

0 comments on commit 6e53e28

Please sign in to comment.