Skip to content

Commit

Permalink
Merge pull request #10308 from danielinux/master
Browse files Browse the repository at this point in the history
wolfSSL pkg addition with examples
  • Loading branch information
MichelRottleuthner committed Sep 11, 2019
2 parents 5ec0e9d + 8bb1ee1 commit 3d0e3b0
Show file tree
Hide file tree
Showing 26 changed files with 2,290 additions and 0 deletions.
63 changes: 63 additions & 0 deletions examples/dtls-wolfssl/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# name of your application
APPLICATION = dtls_wolfssl

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

# wolfSSL supports 32-bit architectures only
BOARD_BLACKLIST := arduino-duemilanove arduino-leonardo arduino-mega2560 arduino-nano arduino-uno \
chronos jiminy-mega256rfr2 mega-xplained msb-430 msb-430h telosb \
waspmote-pro wsn430-v1_3b wsn430-v1_4 z1

BOARD_INSUFFICIENT_MEMORY := airfy-beacon b-l072z-lrwan1 bluepill \
calliope-mini cc2650-launchpad cc2650stk hifive1 i-nucleo-lrwan1 \
maple-mini microbit nrf51dongle nrf6310 nucleo-f031k6 \
nucleo-f042k6 nucleo-f303k8 nucleo-f303k8 nucleo-l031k6 nucleo-f030r8 \
nucleo-f070rb nucleo-f072rb nucleo-f103rb nucleo-f302r8 nucleo-f334r8 \
nucleo-l031k6 nucleo-l053r8 nucleo-l073rz opencm904 \
saml11-xpro bluepill blackpill saml10-xpro \
stm32l0538-disco \
spark-core stm32f0discovery stm32mindev yunjia-nrf51822

# 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

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

USEPKG += wolfssl
USEMODULE += wolfcrypt
USEMODULE += wolfssl
USEMODULE += wolfssl_dtls

# Select public key algorithm (or PSK) support fot ciphersuite(s):
#USEMODULE += wolfcrypt_ecc
#USEMODULE += wolfcrypt_rsa wolfcrypt_dh
USEMODULE += wolfssl_psk

# Uncomment the following line to add debug symbols
#CFLAGS+=-g -ggdb3

CFLAGS += -DDTLS_DEFAULT_PORT=$(DTLS_PORT) -DDTLS_WOLFSSL -Wno-unused-parameter -Wno-unused-variable

# A larger stack size is required if using ECC or RSA
CFLAGS += -DTHREAD_STACKSIZE_MAIN=\(3*THREAD_STACKSIZE_DEFAULT\)

# 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:
CFLAGS += -DDEVELHELP

# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1

include $(RIOTBASE)/Makefile.include
49 changes: 49 additions & 0 deletions examples/dtls-wolfssl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# dtls_wolfssl example

This example shows how to use DTLS with wolfSSL

## SOCK vs. Socket

This example is configured to use socks instead of sockets (over GNRC).
It's possible to use POSIX sockets, which give a more similar approach to the
UNIX version of wolfSSL. POSIX sockets are supported by RIOT-OS via lwIP, but
no example is available at this time.

## Fast configuration (Between RIOT instances)

### Prepare the bridge interface linking two tuntap

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

## Testing

### Run the server
```bash
$ make all; PORT=tap1 make term
> ifconfig
```
*copy the server address*

```bash
> dtlss
```
### Run the client
```bash
$ PORT=tap0 make term
> dtlsc <IPv6's server address[%netif]>
```
### Certificate/key
Test certificate and key arrays are provided in `cert.c`. You can generate your own arrays starting from existing certificate and key in .der format using `xxd -i`.
### Testing against host endpoints
Riot-to-host can be tested against the DTLS examples provided in the [wolfSSL-examples](https://github.com/wolfSSL/wolfssl-examples/tree/master/dtls) repository.
## Boards
Boards that due to insufficient memory are not able to support GNRC are included
in the `BOARD_INSUFFICIENT_MEMORY`.
307 changes: 307 additions & 0 deletions examples/dtls-wolfssl/cert.c

Large diffs are not rendered by default.

191 changes: 191 additions & 0 deletions examples/dtls-wolfssl/dtls-client.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
/*
* Copyright (C) 2019 Daniele Lacamera
*
* 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 Demonstrating DTLS 1.2 client using wolfSSL
*
* @author Daniele Lacamera <daniele@wolfssl.com>
* @}
*/

#include <wolfssl/ssl.h>
#include <wolfssl/error-ssl.h>
#include <sock_tls.h>
#include <net/sock.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "log.h"

#define SERVER_PORT 11111
#define APP_DTLS_BUF_SIZE 64

extern const unsigned char server_cert[];
extern const unsigned long server_cert_len;

static sock_tls_t skv;
static sock_tls_t *sk = &skv;

static void usage(const char *cmd_name)
{
LOG(LOG_ERROR, "Usage: %s <server-address>\n", cmd_name);
}

#ifdef MODULE_WOLFSSL_PSK
/* identity is OpenSSL testing default for openssl s_client, keep same */
static const char* kIdentityStr = "Client_identity";

static inline unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint,
char* identity, unsigned int id_max_len, unsigned char* key,
unsigned int key_max_len)
{
(void)ssl;
(void)hint;
(void)key_max_len;

/* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
strncpy(identity, kIdentityStr, id_max_len);

if (wolfSSL_GetVersion(ssl) < WOLFSSL_TLSV1_3) {
/* test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
unsigned binary */
key[0] = 0x1a;
key[1] = 0x2b;
key[2] = 0x3c;
key[3] = 0x4d;

return 4; /* length of key in octets or 0 for error */
}
else {
int i;
int b = 0x01;

for (i = 0; i < 32; i++, b += 0x22) {
if (b >= 0x100)
b = 0x01;
key[i] = b;
}

return 32; /* length of key in octets or 0 for error */
}
}
#endif

int dtls_client(int argc, char **argv)
{
int ret = 0;
char buf[APP_DTLS_BUF_SIZE] = "Hello from DTLS client!";
int iface;
char *addr_str;
int connect_timeout = 0;
const int max_connect_timeouts = 5;

if (argc != 2) {
usage(argv[0]);
return -1;
}

addr_str = argv[1];
sock_udp_ep_t local = SOCK_IPV6_EP_ANY;
sock_udp_ep_t remote = SOCK_IPV6_EP_ANY;

/* Parsing <address> */
iface = ipv6_addr_split_iface(addr_str);
if (iface == -1) {
if (gnrc_netif_numof() == 1) {
/* assign the single interface found in gnrc_netif_numof() */
remote.netif = (uint16_t)gnrc_netif_iter(NULL)->pid;
}
}
else {
if (gnrc_netif_get_by_pid(iface) == NULL) {
LOG(LOG_ERROR, "ERROR: interface not valid");
usage(argv[0]);
return -1;
}
remote.netif = (uint16_t)gnrc_netif_iter(NULL)->pid;
}
if (ipv6_addr_from_str((ipv6_addr_t *)remote.addr.ipv6, addr_str) == NULL) {
LOG(LOG_ERROR, "ERROR: unable to parse destination address");
usage(argv[0]);
return -1;
}
remote.port = SERVER_PORT;
if (sock_dtls_create(sk, &local, &remote, 0, wolfDTLSv1_2_client_method()) != 0) {
LOG(LOG_ERROR, "ERROR: Unable to create DTLS sock");
return -1;
}

#ifndef MODULE_WOLFSSL_PSK
/* Disable certificate validation from the client side */
wolfSSL_CTX_set_verify(sk->ctx, SSL_VERIFY_NONE, 0);

/* Load certificate file for the DTLS client */
if (wolfSSL_CTX_use_certificate_buffer(sk->ctx, server_cert,
server_cert_len, SSL_FILETYPE_ASN1 ) != SSL_SUCCESS)
{
LOG(LOG_ERROR, "Error loading cert buffer\n");
return -1;
}

#else /* !def MODULE_WOLFSSL_PSK */
wolfSSL_CTX_set_psk_client_callback(sk->ctx, my_psk_client_cb);
#endif

if (sock_dtls_session_create(sk) < 0)
return -1;
wolfSSL_dtls_set_timeout_init(sk->ssl, 5);
LOG(LOG_INFO, "connecting to server...");
/* attempt to connect until the connection is successful */
do {
ret = wolfSSL_connect(sk->ssl);
if ((ret != SSL_SUCCESS)) {
if(wolfSSL_get_error(sk->ssl, ret) == SOCKET_ERROR_E) {
LOG(LOG_WARNING, "Socket error: reconnecting...\n");
sock_dtls_session_destroy(sk);
connect_timeout = 0;
if (sock_dtls_session_create(sk) < 0)
return -1;
}
if ((wolfSSL_get_error(sk->ssl, ret) == WOLFSSL_ERROR_WANT_READ) &&
(connect_timeout++ >= max_connect_timeouts)) {
LOG(LOG_WARNING, "Server not responding: reconnecting...\n");
sock_dtls_session_destroy(sk);
connect_timeout = 0;
if (sock_dtls_session_create(sk) < 0)
return -1;
}
}
} while(ret != SSL_SUCCESS);

/* set remote endpoint */
sock_dtls_set_endpoint(sk, &remote);

/* send the hello message */
wolfSSL_write(sk->ssl, buf, strlen(buf));

/* wait for a reply, indefinitely */
do {
ret = wolfSSL_read(sk->ssl, buf, APP_DTLS_BUF_SIZE - 1);
LOG(LOG_INFO, "wolfSSL_read returned %d\r\n", ret);
} while (ret <= 0);
buf[ret] = (char)0;
LOG(LOG_INFO, "Received: '%s'\r\n", buf);

/* Clean up and exit. */
LOG(LOG_INFO, "Closing connection.\r\n");
sock_dtls_session_destroy(sk);
sock_dtls_close(sk);
return 0;
}
Loading

0 comments on commit 3d0e3b0

Please sign in to comment.