Added example for RIOT-OS using lwIP POSIX sockets

pull/252/head
Daniele Lacamera 2021-03-26 17:37:20 +01:00
parent e5a77b2872
commit 115e7bbca2
5 changed files with 699 additions and 0 deletions

View File

@ -0,0 +1,89 @@
APPLICATION = posix-tls
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../RIOT
# If no BOARD is found in the environment, use this default:
BOARD ?= native
# lwIP's memory management doesn't seem to work on non 32-bit platforms at the
# moment.
BOARD_BLACKLIST := arduino-duemilanove arduino-leonardo \
arduino-mega2560 arduino-nano \
arduino-uno chronos esp8266-esp-12x esp8266-olimex-mod \
esp8266-sparkfun-thing jiminy-mega256rfr2 mega-xplained \
msb-430 msb-430h telosb waspmote-pro \
wsn430-v1_3b wsn430-v1_4 z1
BOARD_INSUFFICIENT_MEMORY = blackpill bluepill i-nucleo-lrwan1 \
nucleo-f031k6 nucleo-f042k6 \
nucleo-l031k6 nucleo-f030r8 nucleo-f302r8 \
nucleo-f303k8 nucleo-f334r8 nucleo-l053r8 \
saml10-xpro saml11-xpro stm32f0discovery
LWIP_IPV4 ?= 1
CFLAGS += -DTHREAD_STACKSIZE_MAIN=20000
ifneq (0, $(LWIP_IPV4))
USEMODULE += ipv4_addr
USEMODULE += lwip_arp
USEMODULE += lwip_ipv4
CFLAGS += -DETHARP_SUPPORT_STATIC_ENTRIES=1
LWIP_IPV6 ?= 0
else
LWIP_IPV6 ?= 1
endif
ifneq (0, $(LWIP_IPV6))
USEMODULE += ipv6_addr
USEMODULE += lwip_ipv6_autoconfig
endif
USEMODULE += inet_csum
USEMODULE += lwip_netdev
USEMODULE += netdev_eth
USEMODULE += netdev_default
USEMODULE += ps
USEMODULE += sock_tcp
USEPKG += wolfssl
USEMODULE+=wolfssl_socket
USEMODULE+=wolfcrypt_rsa
USEMODULE+=wolfcrypt_ecc
USEMODULE+=wolfcrypt_aes
USEMODULE+=wolfcrypt_asn
USEMODULE+=wolfcrypt_hmac
USEMODULE+=wolfcrypt_md5
USEMODULE+=wolfcrypt_sha
USEMODULE+=wolfcrypt_random
USEMODULE+=wolfssl_internal
USEMODULE+=wolfssl_wolfio
USEMODULE+=wolfssl_keys
USEMODULE+=wolfssl_ssl
USEMODULE+=wolfssl_tls
USEMODULE+=wolfcrypt_aes_gcm
CFLAGS+=-DHAVE_AESGCM -DWC_RSA_PSS -DHAVE_HKDF
USEMODULE += posix_sockets
DISABLE_MODULE += auto_init_lwip
CFLAGS += -DSO_REUSE
CFLAGS += -DLWIP_SO_RCVTIMEO
CFLAGS += -DLWIP_SOCK_TCP_ACCEPT_TIMEOUT=500
CFLAGS += -DLWIP_NETIF_LOOPBACK=1
CFLAGS += -DLWIP_HAVE_LOOPIF=1
# Add also the shell, some shell commands
USEMODULE += shell
USEMODULE += shell_commands
# Uncomment next line to enable debug symbols
CFLAGS+=-g -ggdb3
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,95 @@
# Posix sockets: TLS client/server example
This example shows how to use wolfSSL TLS sockets over RIOT-OS POSIX sockets
## License
This example is distributed under the terms of GNU GPLv2.
## SOCK vs. Socket
This example is configured to use wolfSSL on RIOT-OS over POSIX sockets (LWIP).
## Fast configuration (Between RIOT instances)
### Prepare the bridge interface linking two tuntap
```bash
./../../dist/tools/tapsetup/tapsetup --create 2
```
## Testing
### Prerequisite
Clone RIOT-OS in a directory on your filesystem.
### Run the server
```bash
$ make all RIOTBASE=/path/to/riot-os; PORT=tap1 make term
> ip
```
*copy the server address*
```bash
> tlss
```
### Run the client
The default IP address assigned to all nodes is 192.168.7.2. Modify the default address in main.c and re-compile the client application after starting the server.
```bash
$ PORT=tap0 make term
> tlsc <IPv6's server address[%netif]>
```
### Testing against host endpoints
Riot-to-host can be tested against wolfSSL client/server. The default IP address assigned to the
RIOT node in native mode is "192.168.7.2".
#### Testing TLS server on node
```bash
$ make term
```
From another console, assign address to the tap0 device on the host:
```bash
$ ifconfig tap0 192.168.7.1/24 up
```
From the RIOT native node, start the server:
```bash
> tlss
```
On the host, connect using wolfSSL example client
```bash
$ wolfssl/examples/client/client -h 192.168.7.2
```
#### Testing TLS client on node
```bash
$ make term
```
From another console, assign address to the tap0 device on the host:
```bash
$ ifconfig tap0 192.168.7.1/24 up
```
Start the wolfSSL example server (-b is to listen on all interfaces, -d disables client certificate verification)
```bash
$ wolfssl/examples/server/server -b -d
```
From the RIOT native node, start the client:
```bash
> tlsc 192.168.7.1
```

View File

@ -0,0 +1,180 @@
/*
* Copyright (C) 2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*
* This file is subject to the terms and conditions of the GNU
* General Public License v2. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup examples
* @{
*
* @file
* @brief wolfSSL server example
*
* @author Daniele Lacamera <daniele@wolfssl.com>, Kaleb J. Himes <kaleb@wolfssl.com>
*
* @}
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* socket includes */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include "wolfssl/ssl.h"
#include "wolfssl/certs_test.h"
#define SERVER_PORT 11111
int tls_client(int argc, char *argv[])
{
int sockfd;
char buff[] = "Hello, TLS Server!\0";
char *server_ip;
size_t len;
#ifdef LWIP_IPV6
struct sockaddr_in6 servAddr;
#else
struct sockaddr_in servAddr;
#endif
/* declare wolfSSL objects */
WOLFSSL_CTX* ctx;
WOLFSSL* ssl;
puts("This is a TLS Client!");
if (argc != 2) {
fprintf(stderr, "Usage: %s IP_ADDR_SERVER\n", argv[0]);
return -1;
}
printf("Client is connecting to server at address %s port 11111...\n", argv[1]);
server_ip = argv[1];
#ifdef LWIP_IPV6
/* Create a socket that uses an internet IPv6 address,
* Sets the socket to be stream based (TCP),
* 0 means choose the default protocol. */
if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "ERROR: failed to create the socket\n");
return -1;
}
/* Initialize the server address struct with zeros */
memset(&servAddr, 0, sizeof(servAddr));
/* Fill in the server address */
servAddr.sin6_family = AF_INET6; /* using IPv6 */
servAddr.sin6_port = htons(SERVER_PORT); /* on SERVER_PORT */
/* Get the server IPv6 address from the compile-time string parameter */
if (inet_pton(AF_INET6, server_ip, &servAddr.sin6_addr.s6_addr) != 1) {
fprintf(stderr, "ERROR: invalid address\n");
return -1;
}
#else
/* Create a socket that uses an internet IPv4 address,
* Sets the socket to be stream based (TCP),
* 0 means choose the default protocol. */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "ERROR: failed to create the socket\n");
return -1;
}
/* Initialize the server address struct with zeros */
memset(&servAddr, 0, sizeof(servAddr));
/* Fill in the server address */
servAddr.sin_family = AF_INET; /* using IPv4 */
servAddr.sin_port = htons(SERVER_PORT); /* on SERVER_PORT */
/* Get the server IPv4 address from the compile-time string parameter */
if (inet_pton(AF_INET, server_ip, &servAddr.sin_addr.s_addr) != 1) {
fprintf(stderr, "ERROR: invalid address\n");
return -1;
}
#endif
/* Connect to the server */
if (connect(sockfd, (struct sockaddr*) &servAddr, sizeof(servAddr)) == -1) {
fprintf(stderr, "ERROR: failed to connect\n");
return -1;
}
/* Initialize wolfSSL */
wolfSSL_Init();
/* Create and initialize WOLFSSL_CTX */
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method())) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
exit(-1);
}
/* Load client certificates into WOLFSSL_CTX */
if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048,
sizeof_ca_cert_der_2048,
SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load ca buffer\n");
exit(-1);
}
/* Create a WOLFSSL object */
if ((ssl = wolfSSL_new(ctx)) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL object\n");
exit(-1);
}
/* Attach wolfSSL to the socket */
wolfSSL_set_fd(ssl, sockfd);
/* Connect to wolfSSL on the server side */
if (wolfSSL_connect(ssl) != SSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to connect to wolfSSL: %d\n", wolfSSL_state(ssl));
exit(-1);
}
printf("Message for server: %s\n", buff);
len = strlen(buff);
/* Send the message to the server */
if (wolfSSL_write(ssl, buff, len) != (int) len) {
fprintf(stderr, "ERROR: failed to write\n");
return -1;
}
/* Read the server data into our buff array */
memset(buff, 0, sizeof(buff));
if (wolfSSL_read(ssl, buff, sizeof(buff)-1) == -1) {
fprintf(stderr, "ERROR: failed to read\n");
return -1;
}
/* Print to stdout any data the server sends */
printf("Server sent a reply!\n");
printf("Server Response was: %s\n", buff);
/* Cleanup and exit */
close(sockfd); /* Close the connection to the server */
return 0; /* Return reporting a success */
}

View File

@ -0,0 +1,137 @@
/*
* Copyright (C) 2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*
* This file is subject to the terms and conditions of the GNU
* General Public License v2. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup examples
* @{
*
* @file
* @brief Example wolfSSL application using Posix sockets
*
* @author Daniele Lacamera <daniele@wolfssl.com>, Kaleb J. Himes <kaleb@wolfssl.com>
*
* @}
*/
#include <stdio.h>
#include "lwip.h"
#include "lwip/opt.h"
#include "lwip/netif.h"
#include "net/ipv6/addr.h"
#include "shell.h"
#include "msg.h"
#include "net/sock/tcp.h"
#include "xtimer.h"
#include "lwip/sockets.h"
static int ifconfig(int argc, char **argv)
{
(void)argc;
(void)argv;
for (struct netif *iface = netif_list; iface != NULL; iface = iface->next) {
printf("%s_%02u: ", iface->name, iface->num);
#ifdef MODULE_LWIP_IPV6
char addrstr[IPV6_ADDR_MAX_STR_LEN];
for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (!ipv6_addr_is_unspecified((ipv6_addr_t *)&iface->ip6_addr[i])) {
printf(" inet6 %s\n", ipv6_addr_to_str(addrstr, (ipv6_addr_t *)&iface->ip6_addr[i],
sizeof(addrstr)));
}
}
#endif
puts("");
}
return 0;
}
#ifndef MODULE_POSIX_SOCKETS
# error RIOT-OS lacks support for posix sockets, and this TLS app is configured to use them. Please ensure that MODULE_POSIX_SOCKETS is enabled in your configuration.
#endif
#define MAIN_QUEUE_SIZE (8)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
extern int tls_client(int argc, char **argv);
extern int tls_server(int argc, char **argv);
static const shell_command_t shell_commands[] = {
{ "tlsc", "Start a TLS client", tls_client },
{ "tlss", "Start and stop a TLS server", tls_server },
{ "ifconfig", "Shows assigned IP addresses", ifconfig },
{ NULL, NULL, NULL }
};
static void add_site_local_address(struct netif *iface)
{
(void)iface;
#ifdef MODULE_LWIP_IPV6
#define SITE_LOCAL_PREFIX 0xBBAAC0FE
ip6_addr_t sl_addr;
memcpy(&sl_addr, &iface->ip6_addr[0], sizeof(ip6_addr_t));
sl_addr.addr[0] = SITE_LOCAL_PREFIX;
netif_add_ip6_address(iface, &sl_addr, NULL);
#endif
}
static void manual_eth_address(struct netif *iface)
{
ip4_addr_t ipaddr, netmask, gw;
IP4_ADDR(&ipaddr, 192, 168, 7, 2);
IP4_ADDR(&netmask, 255, 255, 255, 0);
IP4_ADDR(&gw, 192, 168, 7, 1);
netif_set_addr(iface, &ipaddr, &netmask, &gw);
}
int main(void)
{
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
puts("RIOT TLS testing implementation");
/* Initialize TCP/IP stack */
xtimer_init();
lwip_bootstrap();
for (struct netif *iface = netif_list; iface != NULL; iface = iface->next) {
if (strncmp(iface->name, "lo", 2) != 0)
/* Add site-local address */
add_site_local_address(iface);
if (strncmp(iface->name, "ET", 2) == 0)
manual_eth_address(iface);
/* IPv4: eth address */
}
/* start shell */
puts("All up, running the shell now");
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
/* should be never reached */
return 0;
}

View File

@ -0,0 +1,198 @@
/*
* Copyright (C) 2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*
* This file is subject to the terms and conditions of the GNU
* General Public License v2. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup examples
* @{
*
* @file
* @brief wolfSSL server example
*
* @author Daniele Lacamera <daniele@wolfssl.com>, Kaleb J. Himes <kaleb@wolfssl.com>
*
* @}
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* socket includes */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include "wolfssl/ssl.h"
#include "wolfssl/certs_test.h"
#define DEFAULT_PORT 11111
int tls_server(int argc, char *argv[])
{
int sockfd;
char buff[256];
int shutdown = 0;
/* declare wolfSSL objects */
WOLFSSL_CTX* ctx;
WOLFSSL* ssl;
#ifdef LWIP_IPV6
struct sockaddr_in6 servAddr;
struct sockaddr_in6 clientAddr;
socklen_t size = sizeof(clientAddr);
/* Create a socket that uses an internet IPv6 address,
* Sets the socket to be stream based (TCP),
* 0 means choose the default protocol. */
if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "ERROR: failed to create the socket\n");
return -1;
}
/* Initialize the server address struct with zeros */
memset(&servAddr, 0, sizeof(servAddr));
/* Fill in the server address */
servAddr.sin6_family = AF_INET6; /* using IPv6 */
servAddr.sin6_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */
#else
struct sockaddr_in servAddr;
struct sockaddr_in clientAddr;
socklen_t size = sizeof(clientAddr);
/* Create a socket that uses an internet IPv4 address,
* Sets the socket to be stream based (TCP),
* 0 means choose the default protocol. */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "ERROR: failed to create the socket\n");
return -1;
}
/* Initialize the server address struct with zeros */
memset(&servAddr, 0, sizeof(servAddr));
/* Fill in the server address */
servAddr.sin_family = AF_INET; /* using IPv6 */
servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */
#endif
(void)argc;
(void)argv;
/* Bind the server socket to local port */
if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) {
fprintf(stderr, "ERROR: failed to bind\n");
return -1;
}
/* Listen for a new connection, allow 5 pending connections */
if (listen(sockfd, 5) == -1) {
fprintf(stderr, "ERROR: failed to listen\n");
return -1;
}
puts("This is the TLS Server!");
puts("Server is listening on port 11111");
wolfSSL_Init();
/* Create and initialize WOLFSSL_CTX */
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method())) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
return -1;
}
/* Load server certificates into WOLFSSL_CTX */
if (wolfSSL_CTX_use_certificate_buffer(ctx, server_cert_der_2048,
sizeof_server_cert_der_2048,
SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load server_cert_der_2048\n");
return -1;
}
/* Load server key into WOLFSSL_CTX */
if (wolfSSL_CTX_use_PrivateKey_buffer(ctx, server_key_der_2048,
sizeof_server_key_der_2048,
SSL_FILETYPE_ASN1) != SSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load server_key_der_2048\n");
return -1;
}
/* Continue to accept clients until shutdown is issued */
while (!shutdown) {
int connd;
size_t len;
printf("Waiting for a connection...\n");
/* Accept client connections */
connd = accept(sockfd, (struct sockaddr *)&clientAddr, &size);
if (connd < 0) {
fprintf(stderr, "ERROR: failed to accept the connection\n\n");
continue;
}
/* Create a WOLFSSL object */
if ((ssl = wolfSSL_new(ctx)) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL object\n");
return -1;
}
/* Attach wolfSSL to the socket */
wolfSSL_set_fd(ssl, connd);
printf("Client connected successfully\n");
/* Read the client data into our buff array */
memset(buff, 0, sizeof(buff));
if (wolfSSL_read(ssl, buff, sizeof(buff)-1) == -1) {
fprintf(stderr, "ERROR: failed to read, state: %d\n", wolfSSL_state(ssl));
return -1;
}
/* Print to stdout any data the client sends */
printf("Client sent a message!\n");
printf("Client said: %s\n", buff);
/* Check for server shutdown command */
if (strncmp(buff, "shutdown", 8) == 0) {
printf("Shutdown command issued!\n");
shutdown = 1;
}
/* Write our reply into buff */
strncpy(buff, "I hear ya fa shizzle!\n", sizeof(buff) - 1);
len = strnlen(buff, sizeof(buff));
printf("Sending reply to client, reply reads: %s\n", buff);
/* Reply back to the client */
if (wolfSSL_write(ssl, buff, len) != (int) len) {
fprintf(stderr, "ERROR: failed to write\n");
return -1;
}
/* Cleanup after this connection */
close(connd); /* Close the connection to the client */
}
printf("Shutdown complete\n");
/* Cleanup and return */
close(sockfd); /* Close the socket listening for clients */
return 0; /* Return reporting a success */
}