diff options
Diffstat (limited to 'samples')
-rw-r--r-- | samples/net/http_server/README.rst | 57 | ||||
-rw-r--r-- | samples/net/http_server/prj_qemu_x86.conf | 4 | ||||
-rw-r--r-- | samples/net/http_server/src/Makefile | 5 | ||||
-rw-r--r-- | samples/net/http_server/src/config.h | 4 | ||||
-rw-r--r-- | samples/net/http_server/src/https_server.c | 406 | ||||
-rw-r--r-- | samples/net/http_server/src/main.c | 7 | ||||
-rw-r--r-- | samples/net/http_server/src/ssl_utils.c | 295 | ||||
-rw-r--r-- | samples/net/http_server/src/ssl_utils.h | 37 | ||||
-rw-r--r-- | samples/net/http_server/src/test_certs.h | 92 |
9 files changed, 906 insertions, 1 deletions
diff --git a/samples/net/http_server/README.rst b/samples/net/http_server/README.rst index 27b77829c..792bbdaa1 100644 --- a/samples/net/http_server/README.rst +++ b/samples/net/http_server/README.rst @@ -109,7 +109,6 @@ Refer to the board documentation in Zephyr, :ref:`frdm_k64f`, for more information about this board and how to access the FRDM serial console under other operating systems. - Sample Output ============= @@ -223,6 +222,60 @@ and this is the HTML message that wget will save: <body><h1><center>404 Not Found</center></h1></body> </html> +HTTPS Server +============ + +The sample code also includes a HTTPS (HTTP over TLS) server example +running side by side with the HTTP server, this server runs on qemu. +In order to compile and run the code execute: + +.. code-block:: console + + make BOARD=qemu_x86 run + +The sample code supports only one hard-coded valid URL (index.html) and +will return 404 code for other requests. + +Sample Output +============= + +The app will show the following on the screen: + +.. code-block:: console + + Zephyr HTTP Server + Address: 192.0.2.1, port: 80 + Zephyr HTTPS Server + Address: 192.0.2.1, port: 443 + failed + ! mbedtls_ssl_handshake returned -29312 + +Now execute the following command on a different terminal window + +.. code-block:: console + + wget https://192.0.2.1 --no-check-certificate + +This will be shown on the screen + +.. code-block:: console + + Connecting to 192.0.2.1:443... connected. + WARNING: cannot verify 192.0.2.1's certificate + Unable to locally verify the issuer's authority. + HTTP request sent, awaiting response... 200 OK + Length: unspecified [text/html] + Saving to: ‘index.html’ + + index.html [ <=> ] + +The inspection of the file index.html will show + +.. code-block:: console + + <h2>Zephyr TLS Test Server</h2> + <p>Successful connection</p> + Known Issues and Limitations ============================ @@ -230,3 +283,5 @@ Known Issues and Limitations chunk transfer mode. - Clients must close the connection to allow the HTTP server to release the network context and accept another connection. +- The use of mbedTLS and IPv6 takes more than the available ram for the + emulation platform, so only IPv4 works for now in QEMU. diff --git a/samples/net/http_server/prj_qemu_x86.conf b/samples/net/http_server/prj_qemu_x86.conf index 8e869d43e..88ba68d55 100644 --- a/samples/net/http_server/prj_qemu_x86.conf +++ b/samples/net/http_server/prj_qemu_x86.conf @@ -28,3 +28,7 @@ CONFIG_NET_SAMPLES_MY_IPV6_ADDR="2001:db8::1" CONFIG_NET_SAMPLES_MY_IPV4_ADDR="192.0.2.1" CONFIG_NET_MAX_CONTEXTS=16 + +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_BUILTIN=y +CONFIG_MBEDTLS_CFG_FILE="config-mini-tls1_2.h" diff --git a/samples/net/http_server/src/Makefile b/samples/net/http_server/src/Makefile index 11d9be117..5219783b9 100644 --- a/samples/net/http_server/src/Makefile +++ b/samples/net/http_server/src/Makefile @@ -8,3 +8,8 @@ obj-y += main.o obj-y += http_utils.o obj-y += http_server.o obj-y += http_write_utils.o +ifdef CONFIG_MBEDTLS +obj-y += https_server.o ssl_utils.o +endif + + diff --git a/samples/net/http_server/src/config.h b/samples/net/http_server/src/config.h index 672b66363..054a4c4e3 100644 --- a/samples/net/http_server/src/config.h +++ b/samples/net/http_server/src/config.h @@ -25,4 +25,8 @@ #define APP_SLEEP_MSECS 500 +#ifdef CONFIG_MBEDTLS +#define SERVER_PORT 443 +#endif + #endif diff --git a/samples/net/http_server/src/https_server.c b/samples/net/http_server/src/https_server.c new file mode 100644 index 000000000..6173c7ec2 --- /dev/null +++ b/samples/net/http_server/src/https_server.c @@ -0,0 +1,406 @@ +/* Minimal TLS server. + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * + * SPDX-License-Identifier: Apache-2.0 + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#include <zephyr.h> +#include <stdio.h> + +#include <errno.h> +#include <misc/printk.h> + +#if !defined(CONFIG_MBEDTLS_CFG_FILE) +#include "mbedtls/config.h" +#else +#include CONFIG_MBEDTLS_CFG_FILE +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include <stdlib.h> +#define mbedtls_time_t time_t +#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS +#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE +#endif + +#include <string.h> +#include <net/net_context.h> +#include <net/net_if.h> +#include "config.h" +#include "ssl_utils.h" +#include "test_certs.h" + +#include "mbedtls/ssl_cookie.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/net_sockets.h" +#include "mbedtls/x509.h" +#include "mbedtls/ssl.h" +#include "mbedtls/error.h" +#include "mbedtls/debug.h" + +#if defined(MBEDTLS_DEBUG_C) +#include "mbedtls/debug.h" +#define DEBUG_THRESHOLD 0 +#endif + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) +#include "mbedtls/memory_buffer_alloc.h" +static unsigned char heap[12000]; +#endif + +/* + * Hardcoded values for server host and port + */ + +static const char *pers = "tls_server"; + +#if defined(CONFIG_NET_IPV6) +static struct in6_addr server_addr; +#else +static struct in_addr server_addr; +#endif + +struct parsed_url { + const char *url; + uint16_t url_len; +}; + +#define HTTP_RESPONSE \ + "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \ + "<h2>Zephyr TLS Test Server</h2>\r\n" \ + "<p>Successful connection</p>\r\n" + +#define HTTP_NOT_FOUND \ + "HTTP/1.0 404 NOT FOUND\r\nContent-Type: text/html\r\n\r\n" \ + "<h2>Zephyr TLS page not found </h2>\r\n" \ + "<p>Successful connection</p>\r\n" + +static void my_debug(void *ctx, int level, + const char *file, int line, const char *str) +{ + const char *p, *basename; + + ARG_UNUSED(ctx); + + /* Extract basename from file */ + for (p = basename = file; *p != '\0'; p++) { + if (*p == '/' || *p == '\\') { + basename = p + 1; + } + + } + + mbedtls_printf("%s:%04d: |%d| %s", basename, line, level, str); +} + +static int entropy_source(void *data, unsigned char *output, size_t len, + size_t *olen) +{ + uint32_t seed; + + ARG_UNUSED(data); + + seed = sys_rand32_get(); + + if (len > sizeof(seed)) { + len = sizeof(seed); + } + + memcpy(output, &seed, len); + + *olen = len; + return 0; +} + +static +int on_url(struct http_parser *parser, const char *at, size_t length) +{ + struct parsed_url *req = (struct parsed_url *)parser->data; + + req->url = at; + req->url_len = length; + + return 0; +} + +static unsigned char payload[256]; + +void https_server(void) +{ + struct ssl_context ctx; + struct parsed_url request; + int ret, len = 0; + + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ssl_context ssl; + mbedtls_ssl_config conf; + mbedtls_x509_crt srvcert; + mbedtls_pk_context pkey; + + mbedtls_platform_set_printf(printk); + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) + mbedtls_memory_buffer_alloc_init(heap, sizeof(heap)); +#endif + +#if defined(MBEDTLS_DEBUG_C) + mbedtls_debug_set_threshold(DEBUG_THRESHOLD); + mbedtls_ssl_conf_dbg(&conf, my_debug, NULL); +#endif + mbedtls_x509_crt_init(&srvcert); + mbedtls_pk_init(&pkey); + mbedtls_ssl_init(&ssl); + mbedtls_ssl_config_init(&conf); + mbedtls_entropy_init(&entropy); + mbedtls_ctr_drbg_init(&ctr_drbg); + + /* + * 1. Load the certificates and private RSA key + */ + + ret = mbedtls_x509_crt_parse(&srvcert, rsa_example_cert_der, + rsa_example_cert_der_len); + if (ret != 0) { + mbedtls_printf(" failed\n !" + " mbedtls_x509_crt_parse returned %d\n\n", ret); + goto exit; + } + + ret = mbedtls_pk_parse_key(&pkey, rsa_example_keypair_der, + rsa_example_keypair_der_len, NULL, 0); + if (ret != 0) { + mbedtls_printf(" failed\n !" + " mbedtls_pk_parse_key returned %d\n\n", ret); + goto exit; + } + + /* + * 3. Seed the RNG + */ + + mbedtls_entropy_add_source(&entropy, entropy_source, NULL, + MBEDTLS_ENTROPY_MAX_GATHER, + MBEDTLS_ENTROPY_SOURCE_STRONG); + + ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, + (const unsigned char *)pers, strlen(pers)); + if (ret != 0) { + mbedtls_printf(" failed\n !" + " mbedtls_ctr_drbg_seed returned %d\n", ret); + goto exit; + } + + /* + * 4. Setup stuff + */ + ret = mbedtls_ssl_config_defaults(&conf, + MBEDTLS_SSL_IS_SERVER, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT); + if (ret != 0) { + mbedtls_printf(" failed\n !" + " mbedtls_ssl_config_defaults returned %d\n\n", + ret); + goto exit; + } + + mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); + mbedtls_ssl_conf_dbg(&conf, my_debug, NULL); + + mbedtls_ssl_conf_ca_chain(&conf, srvcert.next, NULL); + ret = mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey); + if (ret != 0) { + mbedtls_printf(" failed\n !" + " mbedtls_ssl_conf_own_cert returned %d\n\n", + ret); + goto exit; + } + + ret = mbedtls_ssl_setup(&ssl, &conf); + if (ret != 0) { + mbedtls_printf(" failed\n !" + " mbedtls_ssl_setup returned %d\n\n", ret); + goto exit; + } + + /* + * 3. Wait until a client connects + */ + ret = ssl_init(&ctx, &server_addr); + if (ret != 0) { + mbedtls_printf(" failed\n ! ssl_init returned %d\n\n", ret); + goto exit; + + } + + /* + * 4. Prepare http parser + */ + http_parser_init(&ctx.parser, HTTP_REQUEST); + http_parser_settings_init(&ctx.parser_settings); + ctx.parser.data = &request; + ctx.parser_settings.on_url = on_url; + + mbedtls_printf("Zephyr HTTPS Server\n"); + mbedtls_printf("Address: %s, port: %d\n", ZEPHYR_ADDR, SERVER_PORT); +reset: + mbedtls_ssl_session_reset(&ssl); + mbedtls_ssl_set_bio(&ssl, &ctx, ssl_tx, ssl_rx, NULL); + /* + * 5. Handshake + */ + do { + ret = mbedtls_ssl_handshake(&ssl); + if (ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + if (ret < 0) { + mbedtls_printf(" failed\n !" + " mbedtls_ssl_handshake returned %d\n\n", + ret); + goto reset; + } + } + } while (ret != 0); + + /* + * 6. Read the HTTPS Request + */ + mbedtls_printf("Read HTTPS request\n"); + do { + len = sizeof(payload) - 1; + memset(payload, 0, sizeof(payload)); + ret = mbedtls_ssl_read(&ssl, payload, len); + + if (ret == MBEDTLS_ERR_SSL_WANT_READ || + ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + continue; + } + + if (ret <= 0) { + switch (ret) { + case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: + mbedtls_printf(" connection was" + " closed gracefully\n"); + goto close; + + case MBEDTLS_ERR_NET_CONN_RESET: + mbedtls_printf(" connection was" + " reset by peer\n"); + break; + + default: + mbedtls_printf + (" mbedtls_ssl_read returned -0x%x\n", + -ret); + break; + } + + break; + } + + len = ret; + ret = http_parser_execute(&ctx.parser, &ctx.parser_settings, + payload, len); + if (ret < 0) { + } + } while (ret < 0); + + /* + * 7. Write the Response + */ + mbedtls_printf("Write HTTPS response\n"); + + if (!strncmp("/index.html", request.url, request.url_len)) { + len = snprintf((char *)payload, sizeof(payload), + HTTP_RESPONSE); + } else { + + len = snprintf((char *)payload, sizeof(payload), + HTTP_NOT_FOUND); + } + + do { + ret = mbedtls_ssl_write(&ssl, payload, len); + if (ret == MBEDTLS_ERR_NET_CONN_RESET) { + mbedtls_printf(" failed\n !" + " peer closed the connection\n"); + goto reset; + } + + if (ret != MBEDTLS_ERR_SSL_WANT_READ && + ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + if (ret < 0) { + mbedtls_printf(" failed\n !" + " mbedtls_ssl_write" + " returned %d\n", ret); + goto exit; + } + } + } while (ret <= 0); + +close: + + mbedtls_ssl_close_notify(&ssl); + ret = 0; + goto reset; + +exit: +#ifdef MBEDTLS_ERROR_C + if (ret != 0) { + mbedtls_strerror(ret, payload, 100); + mbedtls_printf("Last error was: %d - %s\n", ret, payload); + } +#endif + + mbedtls_ssl_free(&ssl); + mbedtls_ssl_config_free(&conf); + mbedtls_ctr_drbg_free(&ctr_drbg); + mbedtls_entropy_free(&entropy); +} + +#define STACK_SIZE 8192 +uint8_t stack[STACK_SIZE]; + +static inline int init_app(void) +{ +#if defined(CONFIG_NET_IPV6) + if (net_addr_pton(AF_INET6, ZEPHYR_ADDR, &server_addr) < 0) { + mbedtls_printf("Invalid IPv6 address %s", ZEPHYR_ADDR); + } + + if (!net_if_ipv6_addr_add(net_if_get_default(), &server_addr, + NET_ADDR_MANUAL, 0)) { + return -EIO; + } +#else + if (net_addr_pton(AF_INET, ZEPHYR_ADDR, &server_addr) < 0) { + mbedtls_printf("Invalid IPv4 address %s", ZEPHYR_ADDR); + } + + if (!net_if_ipv4_addr_add(net_if_get_default(), &server_addr, + NET_ADDR_MANUAL, 0)) { + return -EIO; + } +#endif + + return 0; +} + +void https_server_start(void) +{ + if (init_app() != 0) { + printk("Cannot initialize network\n"); + return; + } + + k_thread_spawn(stack, STACK_SIZE, (k_thread_entry_t) https_server, + NULL, NULL, NULL, K_PRIO_COOP(7), 0, 0); + +} diff --git a/samples/net/http_server/src/main.c b/samples/net/http_server/src/main.c index e5ebd16e8..d71f897ad 100644 --- a/samples/net/http_server/src/main.c +++ b/samples/net/http_server/src/main.c @@ -20,6 +20,10 @@ static int network_setup(struct net_context **net_ctx, net_tcp_accept_cb_t accept_cb, const char *addr, uint16_t port); +#if defined(CONFIG_MBEDTLS) +#include "ssl_utils.h" +#endif + void main(void) { struct net_context *net_ctx = NULL; @@ -101,6 +105,9 @@ int network_setup(struct net_context **net_ctx, net_tcp_accept_cb_t accept_cb, print_server_banner(&local_sock); +#if defined(CONFIG_MBEDTLS) + https_server_start(); +#endif return 0; lb_error: diff --git a/samples/net/http_server/src/ssl_utils.c b/samples/net/http_server/src/ssl_utils.c new file mode 100644 index 000000000..ac75aadd0 --- /dev/null +++ b/samples/net/http_server/src/ssl_utils.c @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <zephyr.h> +#include <net/net_core.h> +#include <net/net_context.h> +#include <net/nbuf.h> +#include <net/net_if.h> +#include <string.h> +#include <errno.h> +#include <misc/printk.h> + +#if !defined(CONFIG_MBEDTLS_CFG_FILE) +#include "mbedtls/config.h" +#else +#include CONFIG_MBEDTLS_CFG_FILE +#endif + +#include "mbedtls/ssl.h" + +#include "config.h" +#include "ssl_utils.h" + +#define RX_FIFO_DEPTH 4 + +K_MEM_POOL_DEFINE(rx_pkts, 4, 64, RX_FIFO_DEPTH, 4); + +static void ssl_received(struct net_context *context, + struct net_buf *buf, int status, void *user_data) +{ + struct ssl_context *ctx = user_data; + struct rx_fifo_block *rx_data = NULL; + struct k_mem_block block; + + ARG_UNUSED(context); + ARG_UNUSED(status); + + if (!net_nbuf_appdatalen(buf)) { + net_nbuf_unref(buf); + return; + } + + k_mem_pool_alloc(&rx_pkts, &block, + sizeof(struct rx_fifo_block), K_FOREVER); + rx_data = block.data; + rx_data->buf = buf; + + /* For freeing memory later */ + memcpy(&rx_data->block, &block, sizeof(struct k_mem_block)); + k_fifo_put(&ctx->rx_fifo, (void *)rx_data); +} + +static inline void ssl_sent(struct net_context *context, + int status, void *token, void *user_data) +{ + struct ssl_context *ctx = user_data; + + k_sem_give(&ctx->tx_sem); +} + +int ssl_tx(void *context, const unsigned char *buf, size_t size) +{ + struct ssl_context *ctx = context; + struct net_context *net_ctx; + struct net_buf *send_buf; + + int rc, len; + + net_ctx = ctx->net_ctx; + + send_buf = net_nbuf_get_tx(net_ctx, K_NO_WAIT); + if (!send_buf) { + return MBEDTLS_ERR_SSL_ALLOC_FAILED; + } + + rc = net_nbuf_append(send_buf, size, (uint8_t *) buf, K_FOREVER); + if (!rc) { + net_nbuf_unref(send_buf); + return MBEDTLS_ERR_SSL_INTERNAL_ERROR; + } + + len = net_buf_frags_len(send_buf); + + rc = net_context_send(send_buf, ssl_sent, K_NO_WAIT, NULL, ctx); + + if (rc < 0) { + net_nbuf_unref(send_buf); + return MBEDTLS_ERR_SSL_INTERNAL_ERROR; + } + + k_sem_take(&ctx->tx_sem, K_FOREVER); + return len; +} + +int ssl_rx(void *context, unsigned char *buf, size_t size) +{ + struct ssl_context *ctx = context; + uint16_t read_bytes; + struct rx_fifo_block *rx_data; + uint8_t *ptr; + int pos; + int len; + int rc = 0; + + if (ctx->frag == NULL) { + rx_data = k_fifo_get(&ctx->rx_fifo, K_FOREVER); + ctx->rx_nbuf = rx_data->buf; + k_mem_pool_free(&rx_data->block); + + read_bytes = net_nbuf_appdatalen(ctx->rx_nbuf); + + ctx->remaining = read_bytes; + ctx->frag = ctx->rx_nbuf->frags; + ptr = net_nbuf_appdata(ctx->rx_nbuf); + + len = ptr - ctx->frag->data; + net_buf_pull(ctx->frag, len); + } else { + read_bytes = ctx->remaining; + ptr = ctx->frag->data; + } + + len = ctx->frag->len; + pos = 0; + if (read_bytes > size) { + while (ctx->frag) { + read_bytes = len < (size - pos) ? len : (size - pos); + memcpy(buf + pos, ptr, read_bytes); + pos += read_bytes; + if (pos < size) { + ctx->frag = ctx->frag->frags; + ptr = ctx->frag->data; + len = ctx->frag->len; + } else { + if (read_bytes == len) { + ctx->frag = ctx->frag->frags; + } else { + net_buf_pull(ctx->frag, read_bytes); + } + + ctx->remaining -= size; + return size; + } + } + } else { + while (ctx->frag) { + memcpy(buf + pos, ptr, len); + pos += len; + ctx->frag = ctx->frag->frags; + if (!ctx->frag) { + break; + } + + ptr = ctx->frag->data; + len = ctx->frag->len; + } + + net_nbuf_unref(ctx->rx_nbuf); + ctx->rx_nbuf = NULL; + ctx->frag = NULL; + ctx->remaining = 0; + + if (read_bytes != pos) { + return -EIO; + } + + rc = read_bytes; + } + + return rc; +} + +static void ssl_accepted(struct net_context *context, + struct sockaddr *addr, + socklen_t addrlen, int error, void *user_data) +{ + int ret; + struct ssl_context *ctx = user_data; + + ctx->net_ctx = context; + ret = net_context_recv(context, ssl_received, 0, user_data); + if (ret < 0) { + printk("Cannot receive TCP packet (family %d)", + net_context_get_family(context)); + } + +} + +#if defined(CONFIG_NET_IPV6) +int ssl_init(struct ssl_context *ctx, void *addr) +{ + struct net_context *tcp_ctx = { 0 }; + struct sockaddr_in6 my_addr = { 0 }; + struct in6_addr *server_addr = addr; + int rc; + + k_sem_init(&ctx->tx_sem, 0, UINT_MAX); + k_fifo_init(&ctx->rx_fifo); + + my_mcast_addr.sin6_family = AF_INET6; + + net_ipaddr_copy(&my_addr.sin6_addr, server_addr); + my_addr.sin6_family = AF_INET6; + my_addr.sin6_port = htons(SERVER_PORT); + + rc = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP, &tcp_ctx); + if (rc < 0) { + printk("Cannot get network context for IPv6 TCP (%d)", rc); + return -EIO; + } + + rc = net_context_bind(tcp_ctx, (struct sockaddr *)&my_addr, + sizeof(struct sockaddr_in6)); + if (rc < 0) { + printk("Cannot bind IPv6 TCP port %d (%d)", SERVER_PORT, rc); + goto error; + } + + ctx->rx_nbuf = NULL; + ctx->remaining = 0; + ctx->net_ctx = tcp_ctx; + + rc = net_context_listen(ctx->net_ctx, 0); + if (rc < 0) { + printk("Cannot listen IPv6 TCP (%d)", rc); + return -EIO; + } + + rc = net_context_accept(ctx->net_ctx, ssl_accepted, 0, ctx); + if (rc < 0) { + printk("Cannot accept IPv4 (%d)", rc); + return -EIO; + } + + return 0; + +error: + net_context_put(tcp_ctx); + return -EINVAL; +} + +#else +int ssl_init(struct ssl_context *ctx, void *addr) +{ + struct net_context *tcp_ctx = { 0 }; + struct sockaddr_in my_addr4 = { 0 }; + struct in_addr *server_addr = addr; + int rc; + + k_sem_init(&ctx->tx_sem, 0, UINT_MAX); + k_fifo_init(&ctx->rx_fifo); + + net_ipaddr_copy(&my_addr4.sin_addr, server_addr); + my_addr4.sin_family = AF_INET; + my_addr4.sin_port = htons(SERVER_PORT); + + rc = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP, &tcp_ctx); + if (rc < 0) { + printk("Cannot get network context for IPv4 TCP (%d)", rc); + return -EIO; + } + + rc = net_context_bind(tcp_ctx, (struct sockaddr *)&my_addr4, + sizeof(struct sockaddr_in)); + if (rc < 0) { + printk("Cannot bind IPv4 TCP port %d (%d)", SERVER_PORT, rc); + goto error; + } + + ctx->rx_nbuf = NULL; + ctx->remaining = 0; + ctx->net_ctx = tcp_ctx; + + rc = net_context_listen(ctx->net_ctx, 0); + if (rc < 0) { + printk("Cannot listen IPv4 (%d)", rc); + return -EIO; + } + + rc = net_context_accept(ctx->net_ctx, ssl_accepted, 0, ctx); + if (rc < 0) { + printk("Cannot accept IPv4 (%d)", rc); + return -EIO; + } + + return 0; + +error: + net_context_put(tcp_ctx); + return -EINVAL; +} +#endif diff --git a/samples/net/http_server/src/ssl_utils.h b/samples/net/http_server/src/ssl_utils.h new file mode 100644 index 000000000..a0ef50eff --- /dev/null +++ b/samples/net/http_server/src/ssl_utils.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _SSL_UTILS_H_ +#define _SSL_UTILS_H_ + +#include <net/net_core.h> +#include <net/http_parser.h> + +struct rx_fifo_block { + sys_snode_t snode; + struct k_mem_block block; + struct net_buf *buf; +}; + +struct ssl_context { + struct net_context *net_ctx; + struct net_buf *rx_nbuf; + struct net_buf *frag; + struct k_sem tx_sem; + struct k_fifo rx_fifo; + struct http_parser_settings parser_settings; + struct http_parser parser; + + int remaining; +}; + +int ssl_init(struct ssl_context *ctx, void *addr); +int ssl_tx(void *ctx, const unsigned char *buf, size_t size); +int ssl_rx(void *ctx, unsigned char *buf, size_t size); + +void https_server_start(void); + +#endif diff --git a/samples/net/http_server/src/test_certs.h b/samples/net/http_server/src/test_certs.h new file mode 100644 index 000000000..5b6326110 --- /dev/null +++ b/samples/net/http_server/src/test_certs.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __TEST_CERTS_H__ +#define __TEST_CERTS_H__ + +static const unsigned char rsa_example_keypair_der[] = { + 0x30, 0x82, 0x01, 0x3b, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0x9b, 0xfc, + 0x66, 0x90, 0x79, 0x84, 0x42, 0xbb, 0xab, 0x13, 0xfd, 0x2b, 0x7b, 0xf8, + 0xde, 0x15, 0x12, 0xe5, 0xf1, 0x93, 0xe3, 0x06, 0x8a, 0x7b, 0xb8, 0xb1, + 0xe1, 0x9e, 0x26, 0xbb, 0x95, 0x01, 0xbf, 0xe7, 0x30, 0xed, 0x64, 0x85, + 0x02, 0xdd, 0x15, 0x69, 0xa8, 0x34, 0xb0, 0x06, 0xec, 0x3f, 0x35, 0x3c, + 0x1e, 0x1b, 0x2b, 0x8f, 0xfa, 0x8f, 0x00, 0x1b, 0xdf, 0x07, 0xc6, 0xac, + 0x53, 0x07, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x1b, 0x4a, 0xf7, + 0x7b, 0x31, 0xf7, 0xe5, 0x61, 0x46, 0xd6, 0xd1, 0x86, 0x69, 0x43, 0xab, + 0x40, 0x0e, 0xb5, 0x73, 0x26, 0x88, 0x23, 0x9d, 0xd9, 0x76, 0x00, 0x91, + 0xd4, 0x85, 0x3c, 0x6f, 0x1e, 0xc0, 0x51, 0xeb, 0xe6, 0x90, 0x5b, 0x41, + 0x7f, 0xe6, 0xaa, 0x31, 0x6b, 0xac, 0x59, 0x53, 0x96, 0x26, 0xf1, 0xae, + 0xda, 0xbe, 0x55, 0xa4, 0x75, 0x40, 0x22, 0x5f, 0x27, 0x17, 0xa0, 0xd2, + 0x91, 0x02, 0x21, 0x00, 0xc8, 0xc4, 0x27, 0x7c, 0xd5, 0x61, 0xad, 0xbf, + 0x32, 0x8e, 0x1e, 0xcb, 0xe8, 0x94, 0xf4, 0x9f, 0x55, 0x77, 0xe5, 0xa8, + 0xc9, 0x70, 0xd0, 0x0f, 0x81, 0x04, 0xb7, 0x09, 0xb2, 0x1b, 0x53, 0xe9, + 0x02, 0x21, 0x00, 0xc6, 0xe6, 0x65, 0xbe, 0x10, 0xc8, 0x6d, 0xb7, 0x1e, + 0xee, 0x8e, 0x41, 0xbc, 0xe8, 0x67, 0x09, 0x9d, 0x8d, 0xee, 0x46, 0x1b, + 0xd5, 0x90, 0xb9, 0xee, 0x0d, 0xc5, 0xf9, 0xc6, 0xc9, 0xc9, 0x6f, 0x02, + 0x21, 0x00, 0x9b, 0xb0, 0x31, 0x87, 0x06, 0xda, 0x36, 0xa8, 0x9c, 0x85, + 0xc5, 0xb0, 0x0e, 0xee, 0xe4, 0x3c, 0x63, 0x45, 0x15, 0x1d, 0xad, 0x09, + 0x04, 0xef, 0xe0, 0xf7, 0x4d, 0x12, 0x01, 0xc2, 0x5b, 0x71, 0x02, 0x20, + 0x46, 0xd1, 0x25, 0x8c, 0x84, 0xa1, 0x38, 0x1f, 0x29, 0x0e, 0x3a, 0xec, + 0x40, 0xfc, 0x66, 0x23, 0x50, 0x4b, 0x86, 0x78, 0xc3, 0xd4, 0x48, 0x51, + 0x4a, 0xe6, 0xf0, 0x84, 0x3c, 0x39, 0x00, 0x55, 0x02, 0x21, 0x00, 0x8d, + 0x03, 0x6e, 0x29, 0x0e, 0xd7, 0x4e, 0x1f, 0x27, 0x70, 0xb5, 0x20, 0x79, + 0xfb, 0x31, 0x6a, 0x14, 0xb7, 0xe6, 0x55, 0x9a, 0x65, 0x40, 0xcf, 0xe0, + 0xe6, 0x46, 0xf8, 0xb2, 0x8e, 0xf4, 0x63, 0x0a +}; + +static const unsigned int rsa_example_keypair_der_len = 320; + +static const unsigned char rsa_example_cert_der[] = { + 0x30, 0x82, 0x02, 0x12, 0x30, 0x82, 0x01, 0x7b, 0x02, 0x02, 0x0d, 0xfa, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 0x30, 0x81, 0x9b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x4a, 0x50, 0x31, 0x0e, 0x30, 0x0c, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x13, 0x05, 0x54, 0x6f, 0x6b, 0x79, 0x6f, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x43, 0x68, + 0x75, 0x6f, 0x2d, 0x6b, 0x75, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x08, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x34, 0x44, 0x44, + 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0f, 0x57, + 0x65, 0x62, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x0f, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x34, 0x44, 0x44, 0x20, 0x57, 0x65, + 0x62, 0x20, 0x43, 0x41, 0x31, 0x23, 0x30, 0x21, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x14, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x40, 0x66, 0x72, 0x61, 0x6e, 0x6b, 0x34, 0x64, + 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, + 0x38, 0x32, 0x32, 0x30, 0x35, 0x32, 0x36, 0x35, 0x34, 0x5a, 0x17, 0x0d, + 0x31, 0x37, 0x30, 0x38, 0x32, 0x31, 0x30, 0x35, 0x32, 0x36, 0x35, 0x34, + 0x5a, 0x30, 0x4a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x4a, 0x50, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, + 0x08, 0x0c, 0x05, 0x54, 0x6f, 0x6b, 0x79, 0x6f, 0x31, 0x11, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x46, 0x72, 0x61, 0x6e, 0x6b, + 0x34, 0x44, 0x44, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x0c, 0x0f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, + 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0x9b, 0xfc, 0x66, 0x90, 0x79, 0x84, + 0x42, 0xbb, 0xab, 0x13, 0xfd, 0x2b, 0x7b, 0xf8, 0xde, 0x15, 0x12, 0xe5, + 0xf1, 0x93, 0xe3, 0x06, 0x8a, 0x7b, 0xb8, 0xb1, 0xe1, 0x9e, 0x26, 0xbb, + 0x95, 0x01, 0xbf, 0xe7, 0x30, 0xed, 0x64, 0x85, 0x02, 0xdd, 0x15, 0x69, + 0xa8, 0x34, 0xb0, 0x06, 0xec, 0x3f, 0x35, 0x3c, 0x1e, 0x1b, 0x2b, 0x8f, + 0xfa, 0x8f, 0x00, 0x1b, 0xdf, 0x07, 0xc6, 0xac, 0x53, 0x07, 0x02, 0x03, + 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x14, 0xb6, + 0x4c, 0xbb, 0x81, 0x79, 0x33, 0xe6, 0x71, 0xa4, 0xda, 0x51, 0x6f, 0xcb, + 0x08, 0x1d, 0x8d, 0x60, 0xec, 0xbc, 0x18, 0xc7, 0x73, 0x47, 0x59, 0xb1, + 0xf2, 0x20, 0x48, 0xbb, 0x61, 0xfa, 0xfc, 0x4d, 0xad, 0x89, 0x8d, 0xd1, + 0x21, 0xeb, 0xd5, 0xd8, 0xe5, 0xba, 0xd6, 0xa6, 0x36, 0xfd, 0x74, 0x50, + 0x83, 0xb6, 0x0f, 0xc7, 0x1d, 0xdf, 0x7d, 0xe5, 0x2e, 0x81, 0x7f, 0x45, + 0xe0, 0x9f, 0xe2, 0x3e, 0x79, 0xee, 0xd7, 0x30, 0x31, 0xc7, 0x20, 0x72, + 0xd9, 0x58, 0x2e, 0x2a, 0xfe, 0x12, 0x5a, 0x34, 0x45, 0xa1, 0x19, 0x08, + 0x7c, 0x89, 0x47, 0x5f, 0x4a, 0x95, 0xbe, 0x23, 0x21, 0x4a, 0x53, 0x72, + 0xda, 0x2a, 0x05, 0x2f, 0x2e, 0xc9, 0x70, 0xf6, 0x5b, 0xfa, 0xfd, 0xdf, + 0xb4, 0x31, 0xb2, 0xc1, 0x4a, 0x9c, 0x06, 0x25, 0x43, 0xa1, 0xe6, 0xb4, + 0x1e, 0x7f, 0x86, 0x9b, 0x16, 0x40, 0x0a +}; + +static const unsigned int rsa_example_cert_der_len = 535; + +#endif |