Skip to content
Permalink
Browse files

net: samples: Add TLS support to socket echo_client/echo_server

This commit adds TLS support to socket echo_client/echo_server samples.

Credentials used are the same as in the non-socket versions of these
samples, therefore they can be easily tested with net-tools utils.

Maximum payload size for the client was sligtly reduced to fit the
encrypted data within 1280 bytes.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
  • Loading branch information...
rlubos authored and nashif committed Jul 18, 2018
1 parent 50631b3 commit 29b65859b158fd24122ecf6e7ac077ef9e423406
@@ -14,3 +14,11 @@ target_sources_ifdef(CONFIG_NET_UDP app PRIVATE src/udp.c)
target_sources_ifdef(CONFIG_NET_TCP app PRIVATE src/tcp.c)

include($ENV{ZEPHYR_BASE}/samples/net/common/common.cmake)

set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/)

generate_inc_file_for_target(
app
src/echo-apps-cert.der
${gen_dir}/echo-apps-cert.der.inc
)
@@ -0,0 +1,16 @@
CONFIG_NET_UDP=n
CONFIG_NET_TCP=y
CONFIG_NET_IPV6=y
CONFIG_NET_IPV4=y

CONFIG_MAIN_STACK_SIZE=4096

# TLS configuration
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_BUILTIN=y
CONFIG_MBEDTLS_ENABLE_HEAP=y
CONFIG_MBEDTLS_HEAP_SIZE=60000
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=4096

CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=2
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef __CA_CERTIFICATE_H__
#define __CA_CERTIFICATE_H__

#define CA_CERTIFICATE_TAG 1

#define TLS_PEER_HOSTNAME "localhost"

/* This is the same cert as what is found in net-tools/echo-apps-cert.pem file
*/
static const unsigned char ca_certificate[] = {
#include "echo-apps-cert.der.inc"
};

#endif /* __CA_CERTIFICATE_H__ */
Binary file not shown.
@@ -28,38 +28,37 @@
#include <stdio.h>

#include <net/socket.h>
#include <net/tls_credentials.h>

#include "common.h"
#include "ca_certificate.h"

#define APP_BANNER "Run echo client"

/* Generated by http://www.lipsum.com/
* 3 paragraphs, 176 words, 1230 bytes of Lorem Ipsum
* 2 paragraphs, 171 words, 1210 bytes of Lorem Ipsum
*/
const char lorem_ipsum[] =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
"Vestibulum id cursus felis, sit amet suscipit velit. Integer "
"facilisis malesuada porta. Nunc at accumsan mauris. Etiam vehicula, "
"arcu consequat feugiat venenatis, tellus velit gravida ligula, quis "
"posuere sem leo eget urna. Curabitur condimentum leo nec orci "
"mattis, nec faucibus dui rutrum. Ut mollis orci in iaculis "
"consequat. Nulla volutpat nibh eu velit sagittis, a iaculis dui "
"aliquam."
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse "
"eleifend odio sit amet scelerisque tincidunt. In orci ligula, egestas "
"ut neque sit amet, fringilla malesuada dolor. Fusce rhoncus nunc in "
"lacus tincidunt lobortis. Donec aliquam lectus gravida fermentum "
"egestas. Curabitur eu ex pretium, dapibus massa in, pretium tellus. "
"Suspendisse ac efficitur magna, ut convallis nisl. Duis sed sapien "
"odio. Aliquam efficitur sed tellus sit amet eleifend. Sed facilisis "
"ligula aliquam erat ornare hendrerit. Aenean tincidunt nunc a nulla "
"vestibulum mollis. Vivamus fringilla euismod nisi sit amet malesuada. "
"Vivamus consequat ultricies metus sed feugiat. Aenean malesuada "
"cursus sem."
"\n"
"Quisque interdum consequat eros a eleifend. Fusce dapibus nisl "
"sit amet velit posuere imperdiet. Quisque accumsan tempor massa "
"sit amet tincidunt. Integer sollicitudin vehicula tristique. Nulla "
"sagittis massa turpis, ac ultricies neque posuere eu. Nulla et "
"imperdiet ex. Etiam venenatis sed lacus tincidunt hendrerit. In "
"libero nisl, congue id tellus vitae, tincidunt tristique mauris. "
"Nullam sed porta massa. Sed condimentum sem eu convallis euismod. "
"Suspendisse lobortis purus faucibus, gravida turpis id, mattis "
"velit. Maecenas eleifend sapien eu tincidunt lobortis. Sed elementum "
"sapien id enim laoreet consequat."
"\n"
"Aenean et neque aliquam, lobortis lectus in, consequat leo. Sed "
"quis egestas nulla. Quisque ac risus quis elit mollis finibus. "
"Phasellus efficitur imperdiet metus."
"Vestibulum tempor diam et aliquam tristique. Nullam condimentum felis "
"et convallis finibus. Aliquam erat volutpat. Nam et blandit tortor. "
"Nullam pharetra arcu aliquam, suscipit mi eu, faucibus lacus. "
"Pellentesque eleifend nulla sit amet purus maximus, et elementum "
"lectus fringilla. Praesent consectetur diam eget tellus molestie "
"tempor. Class aptent taciti sociosqu ad litora torquent per conubia "
"nostra, per inceptos himenaeos. Nam tincidunt urna augue, nec cursus "
"arcu eleifend nec. Donec semper tellus in leo nullam."
"\n";

const int ipsum_len = sizeof(lorem_ipsum) - 1;
@@ -113,11 +112,26 @@ static void wait(void)
}
}

static void init_app(void)
{
NET_INFO(APP_BANNER);

#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
int err = tls_credential_add(CA_CERTIFICATE_TAG,
TLS_CREDENTIAL_CA_CERTIFICATE,
ca_certificate,
sizeof(ca_certificate));
if (err < 0) {
NET_ERR("Failed to register public certificate: %d", err);
}
#endif
}

void main(void)
{
int ret;

NET_INFO(APP_BANNER);
init_app();

if (IS_ENABLED(CONFIG_NET_TCP)) {
ret = start_tcp();
@@ -18,8 +18,10 @@
#include <stdio.h>

#include <net/socket.h>
#include <net/tls_credentials.h>

#include "common.h"
#include "ca_certificate.h"

#define RECV_BUF_SIZE 128

@@ -81,13 +83,39 @@ static int start_tcp_proto(struct data *data, struct sockaddr *addr,
{
int ret;

#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
data->tcp.sock = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TLS_1_2);
#else
data->tcp.sock = socket(addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
#endif
if (data->tcp.sock < 0) {
NET_ERR("Failed to create TCP socket (%s): %d", data->proto,
errno);
return -errno;
}

#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
sec_tag_t sec_tag_list[] = {
CA_CERTIFICATE_TAG,
};

ret = setsockopt(data->tcp.sock, SOL_TLS, TLS_SEC_TAG_LIST,
sec_tag_list, sizeof(sec_tag_list));
if (ret < 0) {
NET_ERR("Failed to set TLS_SEC_TAG_LIST option (%s): %d",
data->proto, errno);
ret = -errno;
}

ret = setsockopt(data->tcp.sock, SOL_TLS, TLS_HOSTNAME,
TLS_PEER_HOSTNAME, sizeof(TLS_PEER_HOSTNAME));
if (ret < 0) {
NET_ERR("Failed to set TLS_HOSTNAME option (%s): %d",
data->proto, errno);
ret = -errno;
}
#endif

ret = connect(data->tcp.sock, addr, addrlen);
if (ret < 0) {
NET_ERR("Cannot connect to TCP remote (%s): %d", data->proto,
@@ -14,3 +14,16 @@ target_sources_ifdef(CONFIG_NET_UDP app PRIVATE src/udp.c)
target_sources_ifdef(CONFIG_NET_TCP app PRIVATE src/tcp.c)

include($ENV{ZEPHYR_BASE}/samples/net/common/common.cmake)

set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/)

foreach(inc_file
echo-apps-cert.der
echo-apps-key.der
)
generate_inc_file_for_target(
app
src/${inc_file}
${gen_dir}/${inc_file}.inc
)
endforeach()
@@ -0,0 +1,16 @@
CONFIG_NET_UDP=n
CONFIG_NET_TCP=y
CONFIG_NET_IPV6=y
CONFIG_NET_IPV4=y

CONFIG_MAIN_STACK_SIZE=3072

# TLS configuration
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_BUILTIN=y
CONFIG_MBEDTLS_ENABLE_HEAP=y
CONFIG_MBEDTLS_HEAP_SIZE=60000
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=4096

CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=4
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef __CERTIFICATE_H__
#define __CERTIFICATE_H__

#define SERVER_CERTIFICATE_TAG 1

static const unsigned char server_certificate[] = {
#include "echo-apps-cert.der.inc"
};

/* This is the private key in pkcs#8 format. */
static const unsigned char private_key[] = {
#include "echo-apps-key.der.inc"
};

#endif /* __CERTIFICATE_H__ */
@@ -5,8 +5,13 @@
* SPDX-License-Identifier: Apache-2.0
*/


#define MY_PORT 4242
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
#define STACK_SIZE 4096
#else
#define STACK_SIZE 1024
#endif
#define THREAD_PRIORITY K_PRIO_COOP(8)
#define RECV_BUFFER_SIZE 1280

Binary file not shown.
Binary file not shown.
@@ -18,8 +18,10 @@
#include <errno.h>

#include <net/net_core.h>
#include <net/tls_credentials.h>

#include "common.h"
#include "certificate.h"

#define APP_BANNER "Run echo server"

@@ -44,6 +46,24 @@ static void init_app(void)
k_sem_init(&quit_lock, 0, UINT_MAX);

NET_INFO(APP_BANNER);

#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
int err = tls_credential_add(SERVER_CERTIFICATE_TAG,
TLS_CREDENTIAL_SERVER_CERTIFICATE,
server_certificate,
sizeof(server_certificate));
if (err < 0) {
NET_ERR("Failed to register public certificate: %d", err);
}


err = tls_credential_add(SERVER_CERTIFICATE_TAG,
TLS_CREDENTIAL_PRIVATE_KEY,
private_key, sizeof(private_key));
if (err < 0) {
NET_ERR("Failed to register private key: %d", err);
}
#endif
}

void main(void)
@@ -18,8 +18,10 @@
#include <stdio.h>

#include <net/socket.h>
#include <net/tls_credentials.h>

#include "common.h"
#include "certificate.h"

#define MAX_CLIENT_QUEUE 1

@@ -54,13 +56,32 @@ static int start_tcp_proto(struct data *data, struct sockaddr *bind_addr,
{
int ret;

#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
data->tcp.sock = socket(bind_addr->sa_family, SOCK_STREAM,
IPPROTO_TLS_1_2);
#else
data->tcp.sock = socket(bind_addr->sa_family, SOCK_STREAM, IPPROTO_TCP);
#endif
if (data->tcp.sock < 0) {
NET_ERR("Failed to create TCP socket (%s): %d", data->proto,
errno);
return -errno;
}

#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
sec_tag_t sec_tag_list[] = {
SERVER_CERTIFICATE_TAG,
};

ret = setsockopt(data->tcp.sock, SOL_TLS, TLS_SEC_TAG_LIST,
sec_tag_list, sizeof(sec_tag_list));
if (ret < 0) {
NET_ERR("Failed to set TCP secure option (%s): %d", data->proto,
errno);
ret = -errno;
}
#endif

ret = bind(data->tcp.sock, bind_addr, bind_addrlen);
if (ret < 0) {
NET_ERR("Failed to bind TCP socket (%s): %d", data->proto,
@@ -118,6 +139,7 @@ static int process_tcp(struct data *data)

offset += received;

#if !defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
/* To prevent fragmentation of the response, reply only if
* buffer is full or there is no more data to read
*/
@@ -126,6 +148,7 @@ static int process_tcp(struct data *data)
sizeof(data->tcp.recv_buffer) - offset,
MSG_PEEK | MSG_DONTWAIT) < 0 &&
(errno == EAGAIN || errno == EWOULDBLOCK))) {
#endif
ret = sendall(client, data->tcp.recv_buffer, offset);
if (ret < 0) {
NET_ERR("TCP (%s): Failed to send, "
@@ -143,7 +166,9 @@ static int process_tcp(struct data *data)
}

offset = 0;
#if !defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
}
#endif
} while (true);

close(client);

0 comments on commit 29b6585

Please sign in to comment.
You can’t perform that action at this time.