Skip to content

Commit

Permalink
WIP: 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.

This is not yet working, so is WIP.

Signed-off-by: Jukka Rissanen <[email protected]>
  • Loading branch information
jukkar committed Nov 4, 2023
1 parent 570b889 commit ffd7b7d
Show file tree
Hide file tree
Showing 12 changed files with 240 additions and 17 deletions.
36 changes: 35 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,25 @@ 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)

if(CONFIG_NET_SAMPLE_HTTPS_SERVICE)
zephyr_iterable_section(NAME http_resource_desc_test_https_service KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
endif()

if(CONFIG_NET_SAMPLE_HTTP_SERVICE)
zephyr_iterable_section(NAME http_resource_desc_test_http_service KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4)
endif()

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"
22 changes: 13 additions & 9 deletions samples/net/sockets/http_server/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ 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
Expand All @@ -53,13 +53,17 @@ 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_POSIX_MAX_FDS=16
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.
101 changes: 96 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,101 @@ 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_CA_CERTIFICATE_TAG,
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 62 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:62 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 = HTTP_SUPPORT_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 ffd7b7d

Please sign in to comment.