diff --git a/samples/net/sockets/http_server/CMakeLists.txt b/samples/net/sockets/http_server/CMakeLists.txt index f39e7edfa5071ca..4b538193ab76f18 100644 --- a/samples/net/sockets/http_server/CMakeLists.txt +++ b/samples/net/sockets/http_server/CMakeLists.txt @@ -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) @@ -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() diff --git a/samples/net/sockets/http_server/Kconfig b/samples/net/sockets/http_server/Kconfig index 5e949bfc1531a1a..90104be01fa19ab 100644 --- a/samples/net/sockets/http_server/Kconfig +++ b/samples/net/sockets/http_server/Kconfig @@ -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" diff --git a/samples/net/sockets/http_server/prj.conf b/samples/net/sockets/http_server/prj.conf index f5ccce4ab4ed9a4..0c0553bd90d66c3 100644 --- a/samples/net/sockets/http_server/prj.conf +++ b/samples/net/sockets/http_server/prj.conf @@ -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 @@ -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 @@ -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, diff --git a/samples/net/sockets/http_server/sections-rom.ld b/samples/net/sockets/http_server/sections-rom.ld index 512251641b2ad2b..09a6b9398f6706a 100644 --- a/samples/net/sockets/http_server/sections-rom.ld +++ b/samples/net/sockets/http_server/sections-rom.ld @@ -1,3 +1,4 @@ #include ITERABLE_SECTION_ROM(http_resource_desc_test_http_service, 4) +ITERABLE_SECTION_ROM(http_resource_desc_test_https_service, 4) diff --git a/samples/net/sockets/http_server/src/ca.der b/samples/net/sockets/http_server/src/ca.der new file mode 100644 index 000000000000000..b1d3e097cadcea3 Binary files /dev/null and b/samples/net/sockets/http_server/src/ca.der differ diff --git a/samples/net/sockets/http_server/src/certificate.h b/samples/net/sockets/http_server/src/certificate.h new file mode 100644 index 000000000000000..52a3fa9c8ea18f8 --- /dev/null +++ b/samples/net/sockets/http_server/src/certificate.h @@ -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__ */ diff --git a/samples/net/sockets/http_server/src/dummy_psk.h b/samples/net/sockets/http_server/src/dummy_psk.h new file mode 100644 index 000000000000000..e67107266fda45c --- /dev/null +++ b/samples/net/sockets/http_server/src/dummy_psk.h @@ -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__ */ diff --git a/samples/net/sockets/http_server/src/https-server-cert.der b/samples/net/sockets/http_server/src/https-server-cert.der new file mode 100644 index 000000000000000..bfcb335e31c8c37 Binary files /dev/null and b/samples/net/sockets/http_server/src/https-server-cert.der differ diff --git a/samples/net/sockets/http_server/src/https-server-key.der b/samples/net/sockets/http_server/src/https-server-key.der new file mode 100644 index 000000000000000..5a4d67372ea4187 Binary files /dev/null and b/samples/net/sockets/http_server/src/https-server-key.der differ diff --git a/samples/net/sockets/http_server/src/main.c b/samples/net/sockets/http_server/src/main.c index 55ed96a491e0402..8bda30c32bb3f22 100644 --- a/samples/net/sockets/http_server/src/main.c +++ b/samples/net/sockets/http_server/src/main.c @@ -7,18 +7,24 @@ #include #include +#include #include #include #include +#include -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 +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, @@ -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, \ + &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); diff --git a/samples/net/sockets/http_server/src/server.der b/samples/net/sockets/http_server/src/server.der new file mode 100644 index 000000000000000..2b664a4bdb2ce64 Binary files /dev/null and b/samples/net/sockets/http_server/src/server.der differ diff --git a/samples/net/sockets/http_server/src/server_privkey.der b/samples/net/sockets/http_server/src/server_privkey.der new file mode 100644 index 000000000000000..2269293fe790f22 Binary files /dev/null and b/samples/net/sockets/http_server/src/server_privkey.der differ