Skip to content

Commit

Permalink
samples: net: sockets: http_server: Add HTTPS support
Browse files Browse the repository at this point in the history
The example certs are copied from echo-server sample application.

Signed-off-by: Jukka Rissanen <[email protected]>
  • Loading branch information
jukkar committed Nov 9, 2023
1 parent c8d282f commit 643c66a
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 17 deletions.
34 changes: 33 additions & 1 deletion samples/net/sockets/http_server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ find_package(Python REQUIRED COMPONENTS Interpreter)

project(http_server)

if(CONFIG_NET_SOCKETS_SOCKOPT_TLS AND
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED AND
(CONFIG_NET_SAMPLE_PSK_HEADER_FILE STREQUAL "dummy_psk.h"))
add_custom_target(development_psk
COMMAND ${CMAKE_COMMAND} -E echo "----------------------------------------------------------"
COMMAND ${CMAKE_COMMAND} -E echo "--- WARNING: Using dummy PSK! Only suitable for ---"
COMMAND ${CMAKE_COMMAND} -E echo "--- development. Set NET_SAMPLE_PSK_HEADER_FILE to use ---"
COMMAND ${CMAKE_COMMAND} -E echo "--- own pre-shared key. ---"
COMMAND ${CMAKE_COMMAND} -E echo "----------------------------------------------------------"
)
add_dependencies(app development_psk)
endif()

option(INCLUDE_HTML_CONTENT "Include the HTML content" ON)

target_sources(app PRIVATE src/main.c)
Expand All @@ -22,4 +35,23 @@ generate_inc_file_for_target(app ${source_file_not_found} ${gen_dir}/not_found_p
target_link_libraries(app PRIVATE zephyr_interface zephyr)

zephyr_linker_sources(SECTIONS sections-rom.ld)
zephyr_iterable_section(NAME http_resource_desc_test_http_service KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
zephyr_linker_section_ifdef(CONFIG_NET_SAMPLE_HTTPS_SERVICE NAME
http_resource_desc_test_https_service
KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
zephyr_linker_section_ifdef(CONFIG_NET_SAMPLE_HTTP_SERVICE NAME
http_resource_desc_test_http_service
KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)

foreach(inc_file
ca.der
server.der
server_privkey.der
https-server-cert.der
https-server-key.der
)
generate_inc_file_for_target(
app
src/${inc_file}
${gen_dir}/${inc_file}.inc
)
endforeach()
33 changes: 31 additions & 2 deletions samples/net/sockets/http_server/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,37 @@

mainmenu "HTTP2 server sample application"

config NET_HTTP_SERVER_SERVICE_PORT
config NET_SAMPLE_HTTP_SERVICE
bool "Enable http service"
default y

config NET_SAMPLE_HTTP_SERVER_SERVICE_PORT
int "Port number for http service"
default 8080
default 80
depends on NET_SAMPLE_HTTP_SERVICE

config NET_SAMPLE_HTTPS_SERVICE
bool "Enable https service"
depends on NET_SOCKETS_SOCKOPT_TLS || TLS_CREDENTIALS

config NET_SAMPLE_HTTPS_SERVER_SERVICE_PORT
int "Port number for https service"
default 443
depends on NET_SAMPLE_HTTPS_SERVICE

config NET_SAMPLE_PSK_HEADER_FILE
string "Header file containing PSK"
default "dummy_psk.h"
depends on MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
help
Name of a header file containing a
pre-shared key.

config NET_SAMPLE_CERTS_WITH_SC
bool "Signed certificates"
depends on NET_SOCKETS_SOCKOPT_TLS
help
Enable this flag, if you are interested to run this
application with signed certificates and keys.

source "Kconfig.zephyr"
23 changes: 14 additions & 9 deletions samples/net/sockets/http_server/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ CONFIG_INIT_STACKS=y
CONFIG_POSIX_MAX_FDS=32
CONFIG_POSIX_API=y
CONFIG_FDTABLE=y
CONFIG_NET_SOCKETS_POLL_MAX=32

# Eventfd
CONFIG_EVENTFD=y
Expand All @@ -34,14 +35,15 @@ CONFIG_HTTP_SERVER=y
# Network buffers
CONFIG_NET_PKT_RX_COUNT=16
CONFIG_NET_PKT_TX_COUNT=16
CONFIG_NET_BUF_RX_COUNT=64
CONFIG_NET_BUF_TX_COUNT=64
CONFIG_NET_BUF_RX_COUNT=128
CONFIG_NET_BUF_TX_COUNT=128
CONFIG_NET_CONTEXT_NET_PKT_POOL=y

# IP address options
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=4
CONFIG_NET_MAX_CONTEXTS=32
CONFIG_NET_MAX_CONN=32

# Network address config
CONFIG_NET_CONFIG_SETTINGS=y
Expand All @@ -53,13 +55,16 @@ CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2"
CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1"
CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2"

# TLS Options (commented-out for regular TCP)
#CONFIG_TLS_CREDENTIALS=y
#CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
#CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=3
#CONFIG_TLS_MAX_CREDENTIALS_NUMBER=5
#CONFIG_MBEDTLS_ENABLE_HEAP=y
#CONFIG_MBEDTLS_HEAP_SIZE=44000
# 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=2048
CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=6
CONFIG_TLS_CREDENTIALS=y
CONFIG_TLS_MAX_CREDENTIALS_NUMBER=5

# Networking tweaks
# Required to handle large number of consecutive connections,
Expand Down
1 change: 1 addition & 0 deletions samples/net/sockets/http_server/sections-rom.ld
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <zephyr/linker/iterable_sections.h>

ITERABLE_SECTION_ROM(http_resource_desc_test_http_service, 4)
ITERABLE_SECTION_ROM(http_resource_desc_test_https_service, 4)
Binary file added samples/net/sockets/http_server/src/ca.der
Binary file not shown.
50 changes: 50 additions & 0 deletions samples/net/sockets/http_server/src/certificate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef __CERTIFICATE_H__
#define __CERTIFICATE_H__

enum tls_tag {
/** The Certificate Authority public key */
HTTP_SERVER_CA_CERTIFICATE_TAG,
/** Used for both the public and private server keys */
HTTP_SERVER_CERTIFICATE_TAG,
/** Used for both the public and private client keys */
HTTP_SERVER_CLIENT_CERTIFICATE_TAG,
PSK_TAG,
};

#if !defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC)
static const unsigned char server_certificate[] = {
#include "https-server-cert.der.inc"
};

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

#else

static const unsigned char ca_certificate[] = {
#include "ca.der.inc"
};

static const unsigned char server_certificate[] = {
#include "server.der.inc"
};

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

#if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
#include CONFIG_NET_SAMPLE_PSK_HEADER_FILE
#endif

#endif /* __CERTIFICATE_H__ */
14 changes: 14 additions & 0 deletions samples/net/sockets/http_server/src/dummy_psk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef __DUMMY_PSK_H__
#define __DUMMY_PSK_H__

static const unsigned char psk[] = {0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
static const char psk_id[] = "PSK_identity";

#endif /* __DUMMY_PSK_H__ */
Binary file not shown.
Binary file not shown.
100 changes: 95 additions & 5 deletions samples/net/sockets/http_server/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,24 @@
#include <stdio.h>

#include <zephyr/kernel.h>
#include <zephyr/net/tls_credentials.h>
#include <zephyr/net/http/server.h>
#include <zephyr/net/http/service.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/socket.h>

static uint16_t test_http_service_port = htons(CONFIG_NET_HTTP_SERVER_SERVICE_PORT);
HTTP_SERVICE_DEFINE(test_http_service, CONFIG_NET_CONFIG_MY_IPV4_ADDR, &test_http_service_port, 1,
10, NULL);
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_http_server_sample, LOG_LEVEL_DBG);

static uint8_t index_html_gz[] = {
#include "index.html.gz.inc"
};

#if defined(CONFIG_NET_SAMPLE_HTTP_SERVICE)
static uint16_t test_http_service_port = CONFIG_NET_SAMPLE_HTTP_SERVER_SERVICE_PORT;
HTTP_SERVICE_DEFINE(test_http_service, CONFIG_NET_CONFIG_MY_IPV4_ADDR, &test_http_service_port, 1,
10, NULL);

struct http_resource_detail_static index_html_gz_resource_detail = {
.common = {
.type = HTTP_RESOURCE_TYPE_STATIC,
Expand All @@ -39,16 +45,100 @@ struct http_resource_detail_rest add_two_numbers_detail = {
};

HTTP_RESOURCE_DEFINE(add_two_numbers, test_http_service, "/add", &add_two_numbers_detail);
#endif /* CONFIG_NET_SAMPLE_HTTP_SERVICE */

#if defined(CONFIG_NET_SAMPLE_HTTPS_SERVICE)
#include "certificate.h"

static const sec_tag_t sec_tag_list_verify_none[] = {
HTTP_SERVER_CERTIFICATE_TAG,
#if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
PSK_TAG,
#endif
};

static uint16_t test_https_service_port = CONFIG_NET_SAMPLE_HTTPS_SERVER_SERVICE_PORT;
HTTPS_SERVICE_DEFINE(test_https_service, CONFIG_NET_CONFIG_MY_IPV4_ADDR, \

Check warning on line 61 in samples/net/sockets/http_server/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

LINE_CONTINUATIONS

samples/net/sockets/http_server/src/main.c:61 Avoid unnecessary line continuations
&test_https_service_port, 1, 10, NULL, \
sec_tag_list_verify_none, sizeof(sec_tag_list_verify_none));

static struct http_resource_detail_static index_html_gz_resource_detail_https = {
.common = {
.type = HTTP_RESOURCE_TYPE_STATIC,
.bitmask_of_supported_http_methods = BIT(HTTP_GET),
},
.static_data = index_html_gz,
.static_data_len = sizeof(index_html_gz),
};

HTTP_RESOURCE_DEFINE(index_html_gz_resource_https, test_https_service, "/",
&index_html_gz_resource_detail_https);

#endif /* CONFIG_NET_SAMPLE_HTTPS_SERVICE */

static void setup_tls(void)
{
#if defined(CONFIG_NET_SAMPLE_HTTPS_SERVICE)
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
int err;

#if defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC)
err = tls_credential_add(HTTP_SERVER_CERTIFICATE_TAG,
TLS_CREDENTIAL_CA_CERTIFICATE,
ca_certificate,
sizeof(ca_certificate));
if (err < 0) {
LOG_ERR("Failed to register CA certificate: %d", err);
}
#endif /* defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC) */

err = tls_credential_add(HTTP_SERVER_CERTIFICATE_TAG,
TLS_CREDENTIAL_SERVER_CERTIFICATE,
server_certificate,
sizeof(server_certificate));
if (err < 0) {
LOG_ERR("Failed to register public certificate: %d", err);
}

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

#if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
err = tls_credential_add(PSK_TAG,
TLS_CREDENTIAL_PSK,
psk,
sizeof(psk));
if (err < 0) {
LOG_ERR("Failed to register PSK: %d", err);
}

err = tls_credential_add(PSK_TAG,
TLS_CREDENTIAL_PSK_ID,
psk_id,
sizeof(psk_id) - 1);
if (err < 0) {
LOG_ERR("Failed to register PSK ID: %d", err);
}
#endif /* defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) */
#endif /* defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) */
#endif /* defined(CONFIG_NET_SAMPLE_HTTPS_SERVICE) */
}

int main(void)
{
struct http_server_ctx ctx;
int server_fd;

int server_fd = http_server_init(&ctx);
setup_tls();

server_fd = http_server_init(&ctx);
if (server_fd < 0) {
printf("Failed to initialize HTTP2 server\n");
return -1;
return server_fd;
}

http_server_start(&ctx);
Expand Down
Binary file added samples/net/sockets/http_server/src/server.der
Binary file not shown.
Binary file not shown.

0 comments on commit 643c66a

Please sign in to comment.