sample: net: Add https-client sample application

This https-client sample starts to send HTTP GET/HEAD/POST
requests same way as http-client, to https server that can
be found in net-tools repository.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2017-06-05 14:00:20 +03:00
commit e90f4e1486
9 changed files with 797 additions and 0 deletions

View file

@ -0,0 +1,11 @@
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
BOARD ?= qemu_x86
CONF_FILE ?= prj_$(BOARD).conf
include $(ZEPHYR_BASE)/Makefile.inc
include $(ZEPHYR_BASE)/samples/net/common/Makefile.ipstack

View file

@ -0,0 +1,123 @@
.. _https-client-sample:
HTTPS Client
############
Overview
********
This sample application shows how to create encrypted HTTP 1.1 requests
to an HTTPS server and how to parse the incoming responses.
Supported HTTP 1.1 methods are: GET, HEAD, OPTIONS and POST.
The source code for this sample application can be found at:
:file:`samples/net/https_client`.
Requirements
************
- :ref:`networking_with_qemu`
- Terminal emulator software
- HTTPS Server
- DNS server (optional)
Building and Running
********************
Open the project configuration file for your platform, for example:
:file:`prj_qemu_x86.conf` is the configuration file for QEMU.
To use QEMU for testing, follow the :ref:`networking_with_qemu` guide.
For IPv4 networks, set the following variables:
.. code-block:: console
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=n
IPv6 is the preferred routing technology for this sample application,
In this sample application, both static IP addresses and DHCPv4 are supported.
Static IP addresses are specified in the project configuration file,
for example:
.. code-block:: console
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
CONFIG_NET_APP_PEER_IPV6_ADDR="2001:db8::2"
are the IPv6 addresses for the HTTPS client running Zephyr and the
HTTPS server, respectively. The application also supports DNS resolving so the
peer address is resolved automatically if host name is given, so you
can also write the HTTPS server name like this:
.. code-block:: console
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
CONFIG_NET_APP_PEER_IPV6_ADDR="6.zephyr.test"
Open the :file:`src/config.h` file and set the server port
to match the HTTP server setup, for example:
.. code-block:: c
#define SERVER_PORT 443
assumes that the HTTPS server is listening at the TCP port 443.
If the default example HTTPS server is used (described in the next section),
then the default port is 4443.
HTTPS Server
============
Sample code for a very simple HTTPS server can be downloaded from the
zephyrproject-rtos/net-tools project area:
https://github.com/zephyrproject-rtos/net-tools
Open a terminal window and type:
.. code-block:: console
$ cd net-tools
$ ./https-server.sh
DNS setup
=========
The net-tools project provides a simple DNS resolver. You can activate
it like this if you want to test DNS resolving with the HTTP client.
Open a terminal window and type:
.. code-block:: console
$ cd net-tools
$ ./dnsmasq.sh
Sample Output
=============
This sample application loops a specified number of times doing several
HTTP 1.1 requests and printing some output. The requests are:
- GET "/index.html"
- HEAD "/"
- OPTIONS "/index.html"
- POST "/post_test.php"
The terminal window where QEMU is running will show something similar
to the following:
.. code-block:: console
[https-client] [INF] response: Received 364 bytes piece of data
[https-client] [INF] response: HTTP server response status: OK
[https-client] [INF] response: HTTP body: 178 bytes, expected: 178 bytes
[https-client] [INF] response: HTTP server response status: OK
[https-client] [INF] response: HTTP server response status: Unsupported method ('OPTIONS')
[https-client] [INF] response: Received 163 bytes piece of data
[https-client] [INF] response: HTTP server response status: OK
[https-client] [INF] response: HTTP body: 24 bytes, expected: 24 bytes

View file

@ -0,0 +1,44 @@
CONFIG_RANDOM_GENERATOR=y
CONFIG_NETWORKING=y
CONFIG_NET_TCP=y
CONFIG_NET_ARP=y
CONFIG_NET_L2_ETHERNET=y
CONFIG_NET_LOG=y
CONFIG_NET_SHELL=y
CONFIG_NET_IFACE_UNICAST_IPV4_ADDR_COUNT=2
CONFIG_NET_IFACE_UNICAST_IPV6_ADDR_COUNT=2
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=5
CONFIG_INIT_STACKS=y
CONFIG_NET_PKT_RX_COUNT=64
CONFIG_NET_PKT_TX_COUNT=64
CONFIG_NET_BUF_RX_COUNT=64
CONFIG_NET_BUF_TX_COUNT=64
CONFIG_NET_IPV4=y
CONFIG_NET_DHCPV4=y
CONFIG_NET_IPV6=y
CONFIG_HTTP_CLIENT=y
CONFIG_HTTPS=y
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_BUILTIN=y
CONFIG_MBEDTLS_CFG_FILE="config-mini-tls1_2.h"
CONFIG_STDOUT_CONSOLE=y
CONFIG_NET_SHELL=y
# Set the IP addresses here or in the
# src/config.h file
#
CONFIG_NET_APP_SETTINGS=y
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
CONFIG_NET_APP_PEER_IPV6_ADDR="2001:db8::2"
CONFIG_NET_APP_MY_IPV4_ADDR="192.0.2.1"
CONFIG_NET_APP_PEER_IPV4_ADDR="192.0.2.2"
CONFIG_NET_MGMT=y
CONFIG_NET_MGMT_EVENT=y

View file

@ -0,0 +1,54 @@
CONFIG_NETWORKING=y
CONFIG_NET_TCP=y
CONFIG_RANDOM_GENERATOR=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NET_LOG=y
CONFIG_NET_SLIP_TAP=y
CONFIG_INIT_STACKS=y
CONFIG_NET_PKT_RX_COUNT=64
CONFIG_NET_PKT_TX_COUNT=64
CONFIG_NET_BUF_RX_COUNT=64
CONFIG_NET_BUF_TX_COUNT=64
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=2
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=5
CONFIG_INIT_STACKS=y
CONFIG_SYS_LOG_SHOW_COLOR=y
CONFIG_SYS_LOG_NET_LEVEL=4
#CONFIG_NET_DEBUG_HTTP=y
CONFIG_HTTP_CLIENT=y
CONFIG_HTTPS=y
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_BUILTIN=y
CONFIG_MBEDTLS_CFG_FILE="config-mini-tls1_2.h"
CONFIG_NET_IPV6=y
CONFIG_NET_IPV4=y
CONFIG_NET_DHCPV4=y
CONFIG_NET_APP_SETTINGS=y
CONFIG_NET_APP_MY_IPV6_ADDR="2001:db8::1"
CONFIG_NET_APP_PEER_IPV6_ADDR="2001:db8::2"
CONFIG_NET_APP_MY_IPV4_ADDR="192.0.2.1"
CONFIG_NET_APP_PEER_IPV4_ADDR="192.0.2.2"
CONFIG_NET_SHELL=y
CONFIG_DNS_RESOLVER=y
CONFIG_DNS_RESOLVER_ADDITIONAL_BUF_CTR=2
CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES=2
CONFIG_DNS_RESOLVER_MAX_SERVERS=2
CONFIG_DNS_SERVER_IP_ADDRESSES=y
CONFIG_DNS_NUM_CONCUR_QUERIES=2
CONFIG_NET_MGMT=y
CONFIG_NET_MGMT_EVENT=y
# Example DNS servers running in linux using dnsmasq
CONFIG_DNS_SERVER1="192.0.2.2:5353"
CONFIG_DNS_SERVER2="[2001:db8::2]:5353"

View file

@ -0,0 +1,9 @@
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
include $(ZEPHYR_BASE)/samples/net/common/Makefile.common
obj-y += main.o

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#define APP_REQ_TIMEOUT K_SECONDS(5)
/* The startup time needs to be longish if DHCP is enabled as setting
* DHCP up takes some time.
*/
#define APP_STARTUP_TIME K_SECONDS(20)
#define POST_CONTENT_TYPE "application/x-www-form-urlencoded"
#define POST_PAYLOAD "os=ZephyrRTOS&arch=" CONFIG_ARCH
#define SERVER_PORT 4443
#define HOSTNAME "localhost" /* for cert verification if that is enabled */
#if defined(CONFIG_NET_IPV6)
#define SERVER_ADDR CONFIG_NET_APP_PEER_IPV6_ADDR
#else
#define SERVER_ADDR CONFIG_NET_APP_PEER_IPV4_ADDR
#endif

View file

@ -0,0 +1,406 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#if 1
#define SYS_LOG_DOMAIN "https-client"
#define NET_SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG
#define NET_LOG_ENABLED 1
#endif
#include <zephyr.h>
#include <errno.h>
#include <net/net_core.h>
#include <net/net_ip.h>
#include <net/http.h>
#include <net_sample_app.h>
#include "config.h"
#define INSTANCE_INFO "Zephyr HTTPS example client #1"
#define MAX_ITERATIONS 20
#define WAIT_TIME (APP_REQ_TIMEOUT * 2)
#define RESULT_BUF_SIZE 2048
static u8_t result[RESULT_BUF_SIZE];
/* Note that each HTTPS context needs its own stack as there will be
* a separate thread for each HTTPS context.
*/
NET_STACK_DEFINE(HTTPS_CLIENT, https_stack,
CONFIG_HTTPS_STACK_SIZE, CONFIG_HTTPS_STACK_SIZE);
#define RX_FIFO_DEPTH 4
K_MEM_POOL_DEFINE(ssl_rx_pool, 4, 64, RX_FIFO_DEPTH, 4);
/*
* Note that the http_client_ctx is quite large so be careful if that is
* allocated from stack.
*/
static struct http_client_ctx https_ctx;
struct waiter {
struct http_client_ctx *ctx;
struct k_sem wait;
size_t total_len;
size_t header_len;
};
#include "test_certs.h"
void panic(const char *msg)
{
if (msg) {
NET_ERR("%s", msg);
}
for (;;) {
k_sleep(K_FOREVER);
}
}
/* Load the certificates etc. In this sample app, we verify that
* the server is the test server we are communicating against to.
*/
static int setup_cert(struct http_client_ctx *ctx, void *cert)
{
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
mbedtls_ssl_conf_psk(&ctx->https.mbedtls.conf,
client_psk, sizeof(client_psk),
(const unsigned char *)client_psk_id,
sizeof(client_psk_id) - 1);
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C)
{
mbedtls_x509_crt *ca_cert = cert;
int ret;
ret = mbedtls_x509_crt_parse_der(ca_cert,
ca_certificate,
sizeof(ca_certificate));
if (ret != 0) {
NET_ERR("mbedtls_x509_crt_parse_der failed "
"(-0x%x)", -ret);
return ret;
}
mbedtls_ssl_conf_ca_chain(&ctx->https.mbedtls.conf,
ca_cert, NULL);
mbedtls_ssl_conf_authmode(&ctx->https.mbedtls.conf,
MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_cert_profile(&ctx->https.mbedtls.conf,
&mbedtls_x509_crt_profile_default);
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
return 0;
}
static int do_sync_http_req(struct http_client_ctx *ctx,
enum http_method method,
const char *url,
const char *content_type,
const char *payload)
{
struct http_client_request req = {};
int ret;
req.method = method;
req.url = url;
req.protocol = " " HTTP_PROTOCOL HTTP_CRLF;
ret = http_client_send_req(ctx, &req, NULL, result, sizeof(result),
NULL, APP_REQ_TIMEOUT);
if (ret < 0) {
NET_ERR("Cannot send %s request (%d)", http_method_str(method),
ret);
goto out;
}
if (ctx->rsp.data_len > sizeof(result)) {
NET_ERR("Result buffer overflow by %zd bytes",
ctx->rsp.data_len - sizeof(result));
ret = -E2BIG;
} else {
NET_INFO("HTTP server response status: %s",
ctx->rsp.http_status);
if (ctx->parser.http_errno) {
if (method == HTTP_OPTIONS) {
/* Ignore error if OPTIONS is not found */
goto out;
}
NET_INFO("HTTP parser status: %s",
http_errno_description(ctx->parser.http_errno));
ret = -EINVAL;
goto out;
}
/* Our example server does not support OPTIONS so check that
* here too.
*/
if (method != HTTP_HEAD && method != HTTP_OPTIONS) {
if (ctx->rsp.body_found) {
NET_INFO("HTTP body: %zd bytes, "
"expected: %zd bytes",
ctx->rsp.processed,
ctx->rsp.content_length);
} else {
NET_ERR("Error detected during HTTP msg "
"processing");
}
}
}
out:
return ret;
}
void response(struct http_client_ctx *ctx,
u8_t *data, size_t buflen,
size_t datalen,
enum http_final_call data_end,
void *user_data)
{
struct waiter *waiter = user_data;
int ret;
if (data_end == HTTP_DATA_MORE) {
NET_INFO("Received %zd bytes piece of data", datalen);
/* Do something with the data here. For this example
* we just ignore the received data.
*/
waiter->total_len += datalen;
if (ctx->rsp.body_start) {
/* This fragment contains the start of the body
* Note that the header length is not proper if
* the header is spanning over multiple recv
* fragments.
*/
waiter->header_len = ctx->rsp.body_start -
ctx->rsp.response_buf;
}
return;
}
waiter->total_len += datalen;
NET_INFO("HTTP server response status: %s", ctx->rsp.http_status);
if (ctx->parser.http_errno) {
if (ctx->req.method == HTTP_OPTIONS) {
/* Ignore error if OPTIONS is not found */
goto out;
}
NET_INFO("HTTP parser status: %s",
http_errno_description(ctx->parser.http_errno));
ret = -EINVAL;
goto out;
}
if (ctx->req.method != HTTP_HEAD && ctx->req.method != HTTP_OPTIONS) {
if (ctx->rsp.body_found) {
NET_INFO("HTTP body: %zd bytes, expected: %zd bytes",
ctx->rsp.processed, ctx->rsp.content_length);
} else {
NET_ERR("Error detected during HTTP msg processing");
}
if (waiter->total_len !=
waiter->header_len + ctx->rsp.content_length) {
NET_ERR("Error while receiving data, "
"received %zd expected %zd bytes",
waiter->total_len, waiter->header_len +
ctx->rsp.content_length);
}
}
out:
k_sem_give(&waiter->wait);
}
static int do_async_http_req(struct http_client_ctx *ctx,
enum http_method method,
const char *url,
const char *content_type,
const char *payload)
{
struct http_client_request req = {};
struct waiter waiter;
int ret;
req.method = method;
req.url = url;
req.protocol = " " HTTP_PROTOCOL HTTP_CRLF;
k_sem_init(&waiter.wait, 0, 1);
waiter.total_len = 0;
ret = http_client_send_req(ctx, &req, response, result, sizeof(result),
&waiter, APP_REQ_TIMEOUT);
if (ret < 0 && ret != -EINPROGRESS) {
NET_ERR("Cannot send %s request (%d)", http_method_str(method),
ret);
goto out;
}
if (k_sem_take(&waiter.wait, WAIT_TIME)) {
NET_ERR("Timeout while waiting HTTP response");
http_client_release(ctx);
ret = -ETIMEDOUT;
goto out;
}
ret = 0;
out:
return ret;
}
static inline int do_sync_reqs(struct http_client_ctx *ctx, int count)
{
int ret;
/* These examples use the HTTP client API synchronously so they
* do not set the callback parameter.
*/
while (count--) {
ret = do_sync_http_req(ctx, HTTP_GET, "/index.html",
NULL, NULL);
if (ret < 0) {
goto out;
}
ret = do_sync_http_req(ctx, HTTP_HEAD, "/",
NULL, NULL);
if (ret < 0) {
goto out;
}
ret = do_sync_http_req(ctx, HTTP_OPTIONS, "/index.html",
NULL, NULL);
if (ret < 0) {
goto out;
}
ret = do_sync_http_req(ctx, HTTP_POST, "/post_test.php",
POST_CONTENT_TYPE, POST_PAYLOAD);
if (ret < 0) {
goto out;
}
/* Note that we cannot receive data bigger than RESULT_BUF_SIZE
* if we wait the buffer synchronously. If you want to receive
* bigger data, then you need to set the callback when sending
* the HTTP request using http_client_send_req()
*/
}
out:
return ret;
}
static inline int do_async_reqs(struct http_client_ctx *ctx, int count)
{
int ret;
/* These examples use the HTTP client API asynchronously so they
* do set the callback parameter.
*/
while (count--) {
ret = do_async_http_req(ctx, HTTP_GET, "/index.html",
NULL, NULL);
if (ret < 0) {
goto out;
}
ret = do_async_http_req(ctx, HTTP_HEAD, "/",
NULL, NULL);
if (ret < 0) {
goto out;
}
ret = do_async_http_req(ctx, HTTP_OPTIONS, "/index.html",
NULL, NULL);
if (ret < 0) {
goto out;
}
ret = do_async_http_req(ctx, HTTP_POST, "/post_test.php",
POST_CONTENT_TYPE, POST_PAYLOAD);
if (ret < 0) {
goto out;
}
/* FIXME: There is a mbedtls SSL buffer size issue if we try to
* receive large amount of data. So disable the big-file.html
* fetch for time being.
*/
if (0) {
ret = do_async_http_req(ctx, HTTP_GET,
"/big-file.html",
NULL, NULL);
if (ret < 0) {
goto out;
}
}
}
out:
return ret;
}
void main(void)
{
bool failure = false;
int ret;
ret = net_sample_app_init("Run HTTPS client", 0, APP_STARTUP_TIME);
if (ret < 0) {
panic("Application init failed");
}
ret = https_client_init(&https_ctx, SERVER_ADDR, SERVER_PORT,
(u8_t *)INSTANCE_INFO, strlen(INSTANCE_INFO),
setup_cert, HOSTNAME, NULL, &ssl_rx_pool,
https_stack, sizeof(https_stack));
if (ret < 0) {
NET_ERR("HTTPS init failed (%d)", ret);
panic(NULL);
}
ret = do_sync_reqs(&https_ctx, MAX_ITERATIONS);
if (ret < 0) {
failure = true;
}
ret = do_async_reqs(&https_ctx, MAX_ITERATIONS);
if (ret < 0) {
failure = true;
}
if (failure) {
NET_ERR("Some of the tests failed.");
goto out;
}
out:
http_client_release(&https_ctx);
NET_INFO("Done!");
}

View file

@ -0,0 +1,121 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __TEST_CERTS_H__
#define __TEST_CERTS_H__
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/* This is the same cert as what is found in net-tools/https-server.pem file */
static const unsigned char ca_certificate[767] = {
0x30, 0x82, 0x02, 0xFB, 0x30, 0x82, 0x01, 0xE3,
0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
0xEC, 0x70, 0x51, 0xE3, 0xF9, 0x77, 0x0E, 0x3A,
0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86,
0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x30,
0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
0x04, 0x03, 0x0C, 0x09, 0x6C, 0x6F, 0x63, 0x61,
0x6C, 0x68, 0x6F, 0x73, 0x74, 0x30, 0x1E, 0x17,
0x0D, 0x31, 0x37, 0x30, 0x35, 0x33, 0x31, 0x31,
0x34, 0x31, 0x31, 0x35, 0x33, 0x5A, 0x17, 0x0D,
0x34, 0x34, 0x31, 0x30, 0x31, 0x36, 0x31, 0x34,
0x31, 0x31, 0x35, 0x33, 0x5A, 0x30, 0x14, 0x31,
0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03,
0x0C, 0x09, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x68,
0x6F, 0x73, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30,
0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
0x01, 0x0F, 0x00, 0x30, 0x82, 0x01, 0x0A, 0x02,
0x82, 0x01, 0x01, 0x00, 0xB1, 0x0F, 0x3F, 0x6F,
0x4B, 0xFF, 0xA7, 0xC6, 0xBE, 0xB0, 0x3A, 0xC1,
0x50, 0xF5, 0x91, 0xA3, 0xCC, 0x4B, 0x9A, 0x36,
0x3B, 0xC8, 0x7B, 0x03, 0x02, 0x20, 0x9D, 0x5F,
0x05, 0x9D, 0xEE, 0xF8, 0xAB, 0xFE, 0x4D, 0xC8,
0xC5, 0xAB, 0x77, 0xFB, 0x39, 0x8C, 0x0C, 0xEE,
0x83, 0xEC, 0x8C, 0x46, 0xA2, 0xC3, 0xF1, 0x46,
0xEB, 0x03, 0x6B, 0x3D, 0xBF, 0x02, 0xB0, 0x91,
0xF9, 0x4A, 0xC4, 0x71, 0x59, 0x78, 0x88, 0x75,
0x06, 0xDB, 0x6D, 0x4D, 0xDD, 0xF5, 0x1E, 0x6C,
0x8F, 0x88, 0x4E, 0x6D, 0xAA, 0x9D, 0xBF, 0x37,
0x64, 0xAA, 0x22, 0x6E, 0x9B, 0x55, 0xBF, 0xFC,
0x47, 0x8F, 0xA2, 0xE8, 0x29, 0x16, 0xF8, 0xAF,
0x12, 0x5A, 0x4E, 0x3E, 0x85, 0x06, 0xC4, 0x78,
0x06, 0x80, 0xCC, 0xDC, 0x6A, 0xD6, 0x81, 0xFF,
0x40, 0xAA, 0xA4, 0xAB, 0x50, 0xB3, 0x56, 0xC4,
0xE3, 0xA0, 0xB8, 0x94, 0x5B, 0x6F, 0x9D, 0x5B,
0x0D, 0x62, 0x0B, 0x46, 0x46, 0x79, 0xFA, 0x1A,
0x6E, 0x5C, 0x88, 0x0A, 0xE2, 0x1F, 0x04, 0x11,
0xF8, 0x39, 0x22, 0xB9, 0x28, 0xE2, 0x80, 0xF2,
0x82, 0x9D, 0x38, 0x7A, 0x2E, 0x71, 0x83, 0x0E,
0x1D, 0x76, 0xD7, 0xBE, 0xC2, 0x55, 0x68, 0xD3,
0xFE, 0xC0, 0x96, 0xBC, 0xFA, 0xA6, 0x83, 0xA2,
0xDE, 0x39, 0xB3, 0x6B, 0x65, 0x88, 0x39, 0x63,
0x5F, 0x4E, 0xB1, 0x37, 0x33, 0xB0, 0x49, 0x64,
0x86, 0xCC, 0x56, 0xE3, 0x8B, 0x21, 0x26, 0xE5,
0x8B, 0xA1, 0x3B, 0x55, 0x44, 0x22, 0x88, 0xD0,
0xF9, 0xF7, 0xB8, 0x11, 0xF4, 0xE8, 0x0F, 0x4D,
0x0E, 0xAC, 0x2E, 0x5E, 0x4D, 0x42, 0x36, 0x05,
0x0E, 0x5E, 0x27, 0xB1, 0x40, 0xF2, 0xE7, 0x63,
0xA8, 0x01, 0x3C, 0xEB, 0x19, 0xA3, 0xF5, 0xFE,
0xB7, 0x1B, 0x14, 0xDB, 0x1E, 0xF5, 0x32, 0x5F,
0x1D, 0xEF, 0x7B, 0xC3, 0x02, 0x03, 0x01, 0x00,
0x01, 0xA3, 0x50, 0x30, 0x4E, 0x30, 0x1D, 0x06,
0x03, 0x55, 0x1D, 0x0E, 0x04, 0x16, 0x04, 0x14,
0xB5, 0xBC, 0xDD, 0xB0, 0xC6, 0xED, 0x95, 0xB0,
0x96, 0xEC, 0x96, 0x72, 0xE7, 0x92, 0x93, 0x90,
0x3F, 0x84, 0x29, 0x3A, 0x30, 0x1F, 0x06, 0x03,
0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
0x14, 0xB5, 0xBC, 0xDD, 0xB0, 0xC6, 0xED, 0x95,
0xB0, 0x96, 0xEC, 0x96, 0x72, 0xE7, 0x92, 0x93,
0x90, 0x3F, 0x84, 0x29, 0x3A, 0x30, 0x0C, 0x06,
0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03,
0x01, 0x01, 0xFF, 0x30, 0x0D, 0x06, 0x09, 0x2A,
0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B,
0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x87,
0xD5, 0xB4, 0x03, 0xBA, 0x54, 0xEC, 0x14, 0x43,
0x6C, 0xE9, 0xE1, 0x02, 0x3A, 0xF7, 0xCB, 0x95,
0xDC, 0x44, 0xB1, 0x60, 0x88, 0x35, 0x2B, 0xA9,
0x13, 0x4D, 0x69, 0x2F, 0x5E, 0x4B, 0xD8, 0x32,
0x51, 0xB9, 0x5A, 0xEB, 0xEC, 0x6A, 0x7F, 0x37,
0x57, 0x8C, 0xC2, 0x4E, 0x97, 0x25, 0x29, 0x2A,
0x9E, 0x3C, 0xFA, 0xFB, 0xDD, 0xE3, 0x7D, 0x1E,
0x47, 0x06, 0x10, 0xE1, 0x17, 0x53, 0xEC, 0xCC,
0xD5, 0xE4, 0xB8, 0x45, 0xF5, 0xBC, 0x4C, 0x38,
0xFD, 0x78, 0xB6, 0xC6, 0xB7, 0x47, 0x01, 0x1B,
0x35, 0x82, 0xE2, 0x05, 0xC9, 0x88, 0xC1, 0x31,
0xE9, 0x1A, 0xF4, 0x56, 0x97, 0x27, 0x8C, 0x5E,
0x6E, 0xF4, 0x8A, 0xAD, 0xCB, 0xE6, 0x16, 0x43,
0xFF, 0x0C, 0x1F, 0x5D, 0x24, 0x4D, 0xE3, 0xA8,
0x8E, 0xE0, 0x2D, 0x3A, 0x67, 0x2B, 0x55, 0xED,
0xD5, 0xC0, 0x1F, 0x1B, 0x0F, 0x1F, 0x8F, 0xC0,
0x77, 0x74, 0x65, 0x90, 0x93, 0x5B, 0x18, 0xBE,
0xA9, 0x4F, 0xD2, 0x4F, 0x98, 0xCE, 0x12, 0x89,
0x22, 0x8A, 0x16, 0x96, 0xEB, 0xC6, 0x87, 0x39,
0xCE, 0x88, 0x5E, 0x03, 0x51, 0x0A, 0x13, 0xE9,
0x23, 0x4D, 0x60, 0x65, 0x55, 0x05, 0x45, 0xEB,
0xDA, 0x24, 0xFE, 0x60, 0xD5, 0x89, 0x38, 0xD5,
0xC4, 0x9E, 0x80, 0x61, 0x0F, 0x92, 0x63, 0x4E,
0xD5, 0x7F, 0x29, 0xB3, 0x6C, 0x2B, 0x23, 0x35,
0x76, 0xF0, 0x88, 0x79, 0xBB, 0xB1, 0xA2, 0x5B,
0x51, 0x9C, 0x6B, 0xE3, 0x30, 0x00, 0x01, 0x2B,
0xCD, 0xFF, 0x07, 0xB1, 0xB1, 0xB0, 0x65, 0xCE,
0x7A, 0x01, 0x79, 0xE9, 0xA8, 0xAA, 0x4C, 0xE7,
0x94, 0xF5, 0x72, 0x67, 0xF0, 0x3D, 0x07, 0xB7,
0xEA, 0x5C, 0x94, 0x93, 0xC0, 0xB3, 0xFD, 0x6C,
0xE2, 0xBE, 0x6C, 0x2C, 0x7D, 0xB2, 0x25, 0x19,
0x1A, 0xDE, 0x2B, 0xC9, 0x30, 0x0A, 0x97
};
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
const unsigned char client_psk[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
const char client_psk_id[] = "Client_identity";
#endif
#endif

View file

@ -0,0 +1,4 @@
[test]
tags = net http
build_only = true
platform_whitelist = frdm_k64f qemu_x86