Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions include/net/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,45 @@ struct zsock_pollfd {
#define ZSOCK_MSG_PEEK 0x02
#define ZSOCK_MSG_DONTWAIT 0x40

/* Protocol level for TLS.
* Here, the same socket protocol level for TLS as in Linux was used.
*/
#define SOL_TLS 282

/* Socket options for TLS */

/* Socket option to select TLS credentials to use. It accepts and returns an
* array of sec_tag_t that indicate which TLS credentials should be used with
* specific socket
*/
#define TLS_SEC_TAG_LIST 1
/* Write-only socket option to set hostname. It accepts a string containing
* the hostname (may be NULL to disable hostname verification). By default,
* hostname check is enforced for TLS clients.
*/
#define TLS_HOSTNAME 2
/* Socket option to select ciphersuites to use. It accepts and returns an array
* of integers with IANA assigned ciphersuite identifiers.
* If not set, socket will allow all ciphersuites available in the system
* (mebdTLS default behavior).
*/
#define TLS_CIPHERSUITE_LIST 3
/* Read-only socket option to read a ciphersuite chosen during TLS handshake.
* It returns an integer containing an IANA assigned ciphersuite identifier
* of chosen ciphersuite.
*/
#define TLS_CIPHERSUITE_USED 4
/* Write-only socket option to set peer verification level for TLS connection.
* This option accepts an integer with a peer verification level, compatible
* with mbedTLS values:
* 0 - none,
* 1 - optional
* 2 - required.
* If not set, socket will use mbedTLS defaults (none for servers, required
* for clients).
*/
#define TLS_PEER_VERIFY 5

struct zsock_addrinfo {
struct zsock_addrinfo *ai_next;
int ai_flags;
Expand Down Expand Up @@ -71,6 +110,10 @@ ssize_t zsock_recvfrom(int sock, void *buf, size_t max_len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
int zsock_fcntl(int sock, int cmd, int flags);
int zsock_poll(struct zsock_pollfd *fds, int nfds, int timeout);
int zsock_getsockopt(int sock, int level, int optname,
void *optval, socklen_t *optlen);
int zsock_setsockopt(int sock, int level, int optname,
const void *optval, socklen_t optlen);
int zsock_inet_pton(sa_family_t family, const char *src, void *dst);
int zsock_getaddrinfo(const char *host, const char *service,
const struct zsock_addrinfo *hints,
Expand All @@ -92,6 +135,10 @@ ssize_t ztls_recvfrom(int sock, void *buf, size_t max_len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
int ztls_fcntl(int sock, int cmd, int flags);
int ztls_poll(struct zsock_pollfd *fds, int nfds, int timeout);
int ztls_getsockopt(int sock, int level, int optname,
void *optval, socklen_t *optlen);
int ztls_setsockopt(int sock, int level, int optname,
const void *optval, socklen_t optlen);

#endif /* defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) */

Expand Down Expand Up @@ -213,6 +260,26 @@ static inline int poll(struct zsock_pollfd *fds, int nfds, int timeout)
#define MSG_PEEK ZSOCK_MSG_PEEK
#define MSG_DONTWAIT ZSOCK_MSG_DONTWAIT

static inline int getsockopt(int sock, int level, int optname,
void *optval, socklen_t *optlen)
{
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
return ztls_getsockopt(sock, level, optname, optval, optlen);
#else
return zsock_getsockopt(sock, level, optname, optval, optlen);
#endif
}

static inline int setsockopt(int sock, int level, int optname,
const void *optval, socklen_t optlen)
{
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
return ztls_setsockopt(sock, level, optname, optval, optlen);
#else
return zsock_setsockopt(sock, level, optname, optval, optlen);
#endif
}

static inline char *inet_ntop(sa_family_t family, const void *src, char *dst,
size_t size)
{
Expand Down
111 changes: 111 additions & 0 deletions include/net/tls_credentials.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rlubos , so this would be the commit whose message can be updated with the description of 2-stage credential management as suggested in #9007 (comment)

* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

/** @file
* @brief TLS credentials management
*
* An API for applications to configure TLS credentials.
*/

#ifndef __TLS_CREDENTIAL_H
#define __TLS_CREDENTIAL_H

/**
* @brief TLS credentials management
* @defgroup tls_credentials TLS credentials management
* @ingroup networking
* @{
*/

#ifdef __cplusplus
extern "C" {
#endif

/** TLS credential types */
enum tls_credential_type {
TLS_CREDENTIAL_NONE,
TLS_CREDENTIAL_CA_CERTIFICATE,
TLS_CREDENTIAL_SERVER_CERTIFICATE,
TLS_CREDENTIAL_PRIVATE_KEY,
TLS_CREDENTIAL_PSK,
TLS_CREDENTIAL_PSK_ID
};

/** Secure tag, a reference to TLS credential
*
* Secure tag can be used to reference credential after it was registered
* in the system.
*
* @note Some TLS credentials come in pairs:
* - TLS_CREDENTIAL_SERVER_CERTIFICATE with TLS_CREDENTIAL_PRIVATE_KEY,
* - TLS_CREDENTIAL_PSK with TLS_CREDENTIAL_PSK_ID.
* Such pairs of credentials must be assigned the same secure tag to be
* correctly handled in the system.
*/
typedef int sec_tag_t;

/**
* @brief Add a TLS credential.
*
* @details This function adds a TLS credential, that can be used
* by TLS/DTLS for authentication.
*
* @param tag A security tag that credential will be referenced with.
* @param type A TLS/DTLS credential type.
* @param cred A TLS/DTLS credential.
* @param credlen A TLS/DTLS credential length.
*
* @retval 0 TLS credential successfully added.
* @retval -EACCES Access to the TLS credential subsystem was denied.
* @retval -ENOMEM Not enough memory to add new TLS credential.
* @retval -EEXIST TLS credential of specific tag and type already exists.
*/
int tls_credential_add(sec_tag_t tag, enum tls_credential_type type,
const void *cred, size_t credlen);

/**
* @brief Get a TLS credential.
*
* @details This function gets an already registered TLS credential,
* referenced by @p tag secure tag of @p type.
*
* @param tag A security tag of requested credential.
* @param type A TLS/DTLS credential type of requested credential.
* @param cred A buffer for TLS/DTLS credential.
* @param credlen A buffer size on input. TLS/DTLS credential length on output.
*
* @retval 0 TLS credential successfully obtained.
* @retval -EACCES Access to the TLS credential subsystem was denied.
* @retval -ENOENT Requested TLS credential was not found.
* @retval -EFBIG Requested TLS credential does not fit in the buffer provided.
*/
int tls_credential_get(sec_tag_t tag, enum tls_credential_type type,
void *cred, size_t *credlen);

/**
* @brief Delete a TLS credential.
*
* @details This function removes a TLS credential, referenced by @p tag
* secure tag of @p type.
*
* @param tag A security tag corresponding to removed credential.
* @param type A TLS/DTLS credential type of removed credential.
*
* @retval 0 TLS credential successfully deleted.
* @retval -EACCES Access to the TLS credential subsystem was denied.
* @retval -ENOENT Requested TLS credential was not found.
*/
int tls_credential_delete(sec_tag_t tag, enum tls_credential_type type);

#ifdef __cplusplus
}
#endif

/**
* @}
*/

#endif /* __TLS_CREDENTIAL_H */
8 changes: 8 additions & 0 deletions samples/net/sockets/big_http_download/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

include($ENV{ZEPHYR_BASE}/samples/net/common/common.cmake)

set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/)

generate_inc_file_for_target(
app
src/lets_encrypt_x3.der
${gen_dir}/lets_encrypt_x3.der.inc
)
23 changes: 23 additions & 0 deletions samples/net/sockets/big_http_download/src/big_http_download.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
#include <kernel.h>
#include <net/net_app.h>

#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
#include <net/tls_credentials.h>
#include "ca_certificate.h"
#endif

#define sleep(x) k_sleep(x * 1000)

#endif
Expand Down Expand Up @@ -144,6 +149,19 @@ void download(struct addrinfo *ai, bool is_tls)
CHECK(sock);
printf("sock = %d\n", sock);

#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
if (is_tls) {
sec_tag_t sec_tag_opt[] = {
CA_CERTIFICATE_TAG,
};
CHECK(setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST,
sec_tag_opt, sizeof(sec_tag_opt)));

CHECK(setsockopt(sock, SOL_TLS, TLS_HOSTNAME,
host, strlen(host) + 1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This strlen() + 1 looks a bit weird, I'm sure will be source of common mistake ;-)

}
#endif

CHECK(connect(sock, ai->ai_addr, ai->ai_addrlen));
sendall(sock, "GET /", SSTRLEN("GET /"));
sendall(sock, uri_path, strlen(uri_path));
Expand Down Expand Up @@ -207,6 +225,11 @@ int main(void)
int resolve_attempts = 10;
bool is_tls = false;

#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
tls_credential_add(CA_CERTIFICATE_TAG, TLS_CREDENTIAL_CA_CERTIFICATE,
ca_certificate, sizeof(ca_certificate));
#endif

setbuf(stdout, NULL);

if (strncmp(download_url, "http://", SSTRLEN("http://")) == 0) {
Expand Down
21 changes: 21 additions & 0 deletions samples/net/sockets/big_http_download/src/ca_certificate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef __CA_CERTIFICATE_H__
#define __CA_CERTIFICATE_H__

#define CA_CERTIFICATE_TAG 1

/* By default only certificates in DER format are supported. If you want to use
* certificate in PEM format, you can enable support for it in Kconfig.
*/

/* Let's Encrypt Authority X3 for https://www.7-zip.org */
static const unsigned char ca_certificate[] = {
#include "lets_encrypt_x3.der.inc"
};

#endif /* __CA_CERTIFICATE_H__ */
Binary file not shown.
8 changes: 8 additions & 0 deletions samples/net/sockets/echo_client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@ target_sources_ifdef(CONFIG_NET_UDP app PRIVATE src/udp.c)
target_sources_ifdef(CONFIG_NET_TCP app PRIVATE src/tcp.c)

include($ENV{ZEPHYR_BASE}/samples/net/common/common.cmake)

set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/)

generate_inc_file_for_target(
app
src/echo-apps-cert.der
${gen_dir}/echo-apps-cert.der.inc
)
16 changes: 16 additions & 0 deletions samples/net/sockets/echo_client/boards/qemu_x86_tls.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
CONFIG_NET_UDP=n
CONFIG_NET_TCP=y
CONFIG_NET_IPV6=y
CONFIG_NET_IPV4=y

CONFIG_MAIN_STACK_SIZE=4096

# 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=4096

CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=2
20 changes: 20 additions & 0 deletions samples/net/sockets/echo_client/src/ca_certificate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef __CA_CERTIFICATE_H__
#define __CA_CERTIFICATE_H__

#define CA_CERTIFICATE_TAG 1

#define TLS_PEER_HOSTNAME "localhost"

/* This is the same cert as what is found in net-tools/echo-apps-cert.pem file
*/
static const unsigned char ca_certificate[] = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have the pem file as a file and just emded it here by including it. So similar way as what is done for example in rpl_border_router sample.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable, I can give a try. I guess you ment der file though? We've agreed in review of #7118 to use DER cert format to save some code size.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you ment der file though? We've agreed in review of #7118 to use DER cert format to save some code size.

Yes, I meant the DER file.

#include "echo-apps-cert.der.inc"
};

#endif /* __CA_CERTIFICATE_H__ */
Binary file not shown.
Loading