tests: net: socket_tls: test different TLS configurations with sockets
This commit adds a test to showcase how to configure TLS 1.2 and 1.3 socket connections against an OpenSSL server. Only a limited number of combinations are available for now: - TLS 1.2 - RSA certificate and key exchange. - ECDSA certificate and ECDHE key exchange. - TLS 1.3 only supports ephemeral (ECDHE) key exchange with/without session tickets. Since the goal is to test TLS connection and not low level ethernet functionalities or similar, the only supported platform is "native_sim" where Linux sockets are used to connect to the OpenSSL server locally. The idea is that the Zephyr application acts a client and tries to connect to the OpenSSL server running on the same PC. For sake of simplificity a bash script is provided to start the OpenSSL server properly. For completeness a bash script is also provided to re-generate certificates and keys. Signed-off-by: Valerio Setti <vsetti@baylibre.com>
This commit is contained in:
parent
6be57aaedf
commit
91fa8a2b63
27
tests/net/socket/tls_configurations/CMakeLists.txt
Normal file
27
tests/net/socket/tls_configurations/CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(tls_configurations)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
||||
|
||||
set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/)
|
||||
|
||||
# Helper function to convert the content of a PEM file (generated by OpenSSL)
|
||||
# to a C string that can be parsed by Mbed TLS. The format is unchanged, it's
|
||||
# still PEM, but new lines are replaced by "\n", so that both C compiler and
|
||||
# Mbed TLS parser are happy.
|
||||
function(pem_to_mbedtls target input_file)
|
||||
file(READ credentials/${input_file} input_file_content)
|
||||
string(REGEX REPLACE "\n" "\\\\n" input_file_content ${input_file_content})
|
||||
set(GENERATED_FILE ${gen_dir}/${input_file}.inc)
|
||||
file(WRITE ${GENERATED_FILE} "\"${input_file_content}\"\n")
|
||||
generate_unique_target_name_from_filename(${input_file} generated_target_name)
|
||||
add_custom_target(${generated_target_name} DEPENDS ${GENERATED_FILE})
|
||||
add_dependencies(${target} ${generated_target_name})
|
||||
endfunction()
|
||||
|
||||
pem_to_mbedtls(app ec.crt)
|
||||
pem_to_mbedtls(app rsa.crt)
|
||||
8
tests/net/socket/tls_configurations/Kconfig
Normal file
8
tests/net/socket/tls_configurations/Kconfig
Normal file
@ -0,0 +1,8 @@
|
||||
# Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config SERVER_PORT
|
||||
int "Server port to connect to"
|
||||
default 4242
|
||||
|
||||
source "Kconfig.zephyr"
|
||||
@ -0,0 +1,5 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgwecn6Plv8ONZs2cF
|
||||
IIlr4B4xaoPYEMHm9mSG4esgQ2uhRANCAARVR4/COFJhHmmGdERod/1DhM5hBcq/
|
||||
xQHuUtxC1a977tMFCzINWTy155+/E8uj35FUhsLeFMoyGtgvKHKIBpgt
|
||||
-----END PRIVATE KEY-----
|
||||
10
tests/net/socket/tls_configurations/credentials/ec.crt
Normal file
10
tests/net/socket/tls_configurations/credentials/ec.crt
Normal file
@ -0,0 +1,10 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBfDCCASOgAwIBAgIUW0crZnSm9CwlYmnYdDSohFSG5UwwCgYIKoZIzj0EAwIw
|
||||
FDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MDgyNzA5NDcxN1oXDTM0MDgyNTA5
|
||||
NDcxN1owFDESMBAGA1UEAwwJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0D
|
||||
AQcDQgAEVUePwjhSYR5phnREaHf9Q4TOYQXKv8UB7lLcQtWve+7TBQsyDVk8teef
|
||||
vxPLo9+RVIbC3hTKMhrYLyhyiAaYLaNTMFEwHQYDVR0OBBYEFDi6b5XH5Z5d4cSe
|
||||
S5OVBHaWjB8SMB8GA1UdIwQYMBaAFDi6b5XH5Z5d4cSeS5OVBHaWjB8SMA8GA1Ud
|
||||
EwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgMEnVFWqIHRphQtWn5CbXomkH
|
||||
H/mDhf4ux5k55dmRRH8CIFwL0gYBrp26n0AsRSpVN1RroAt7M1MpCgEycVr3QNMQ
|
||||
-----END CERTIFICATE-----
|
||||
28
tests/net/socket/tls_configurations/credentials/rsa-priv.key
Normal file
28
tests/net/socket/tls_configurations/credentials/rsa-priv.key
Normal file
@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRaXhTWuxKafRh
|
||||
fsewYRSRjpeOQJPqY1u38eTFFgcb4oAZOguoubEpJHui3olEWdcyfREx+GsDUo1n
|
||||
5G6az6m65tCSAKEoFumREhDngt3crdw91hnrnBPjnpCNzeGQ1EqBFbW9mwjp1xQY
|
||||
pBG0pCwdGIxlzW9ufVrtTbmLp1xcz3U7/RJBwDTX1o+u1oV5mJ9+oYtMQ1b8mOcr
|
||||
f8Wdg01CWk0ag/C2os07XmRNOCUdO1kh1BHQuPV5K+tgdgHOZdYBBHv8LCgT+FO9
|
||||
8r3lhuzVsWTyJLGYYTFnT5b8EtpilnsTDZykmTqzTF3tFejY4OgWS8kmUgEG6QLn
|
||||
+Q+ewaKxAgMBAAECggEAdA3fgVKCYTsXFHEOedFTdNdxZoSjdOJbkjWccx0iE3IT
|
||||
S+e/TmKarBJr8nch259ug6yMOwVRSSYW99zA70rm5Y3FSSTQK0eHab55X9RG4GX6
|
||||
CMr+0nRNEXhu5CeVOo5sO92sOsgQyIdJu94xccsKJ5XTORgBCVqvaZQJoDvAFC5j
|
||||
ErZpwYYl0P9Dx/jRSrqC0llOBASj0EMfPVSoImxuiGIKrT+flD2GR0IBJ6BjD+k8
|
||||
wgWNdqv8pq4MGs/lodqA8DPnealcCVaCwobIzUWHjjW06m++iFL9d3LDr9rHMDG8
|
||||
rp6pE9D2fn8wb43wiTe++n6zFNLnzVfNQS/P33jCAQKBgQD/Gj9+ypciFMuWedDl
|
||||
9qgmttjzUcEyyAViD4FWSsef98MLgcxDdz9o/BxS4xJUbxPj/lAaakEFVIStoFo5
|
||||
Meu5cHGYA35Wm5193g9i7YQI/wLyS/SnHV3O8GixqIwI5Mci/MXbvKb5TwQBRS3+
|
||||
3MXqBewL7OTXmkqXmpF9BSE3PQKBgQDSJhJocS8cheIAmWp94SLmTrCuxy1HeDFL
|
||||
0PiIMlWbxvpdO0RUd1hg1IOk21z/7llwxh8JPtFYcQogJA4/WfBHy4Vqh483SYj8
|
||||
8aOrkxbRNE3j3+VSCTZReX6ACRsReHJTktEsI07iU3Bnmpwg2x3d6D4JUqVZA4PX
|
||||
nbimkP6whQKBgQCCLT/HkNQstRXq9MCwCP1nvBjbmZWQN1ff4W+rvD9AF2u1nIfC
|
||||
ycBW74f4mB1Lbt9kkesIf74sXSPTgidoVlwm5gVhgC7hPUnR6BZL8k5VVOSJBk+T
|
||||
U74CEtYqCotjInOoG/tPlWZThInTqBy/mKN6N4lr0Hg6uWZlFKA3fv2jNQKBgGvw
|
||||
fjgDGs2tvt3L7zTk9MYS2RGM4Kb7B2cH2QArymkPFP3aOUihXFWwEkYVHnmedXZF
|
||||
bR+Ukna46RiFLIRBr/dQhCCprFgbfy9c9lJkZK3kDbXkBKfUb3/9xYoCI1Mf6Kkg
|
||||
mivvns8FSJEOiu8dXQPkDClBuAg2k/ul2XhEtWz5AoGBAN8LRCutUDkBT7kr072O
|
||||
m0fGQFzKq3jN8otsSfdBb40pqZqBCNAn/ojBAc2wcqLMUMHU9cHvEntsXZCbDmmO
|
||||
5Mx3UF3mUCYAqcl6YCP9qiL6etBqD0q8TGngAT2MoMweh3xaHpSOcT4qISunW5ZG
|
||||
6LTYdd5z+ab+sHB0pUTrsFER
|
||||
-----END PRIVATE KEY-----
|
||||
19
tests/net/socket/tls_configurations/credentials/rsa.crt
Normal file
19
tests/net/socket/tls_configurations/credentials/rsa.crt
Normal file
@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDCTCCAfGgAwIBAgIUQxMu5/uGKh0/cmqChP7kIeSFm5wwDQYJKoZIhvcNAQEL
|
||||
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MDgyNzA5NDcxN1oXDTM0MDgy
|
||||
NTA5NDcxN1owFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEA0Wl4U1rsSmn0YX7HsGEUkY6XjkCT6mNbt/HkxRYHG+KA
|
||||
GToLqLmxKSR7ot6JRFnXMn0RMfhrA1KNZ+Rums+puubQkgChKBbpkRIQ54Ld3K3c
|
||||
PdYZ65wT456Qjc3hkNRKgRW1vZsI6dcUGKQRtKQsHRiMZc1vbn1a7U25i6dcXM91
|
||||
O/0SQcA019aPrtaFeZiffqGLTENW/JjnK3/FnYNNQlpNGoPwtqLNO15kTTglHTtZ
|
||||
IdQR0Lj1eSvrYHYBzmXWAQR7/CwoE/hTvfK95Ybs1bFk8iSxmGExZ0+W/BLaYpZ7
|
||||
Ew2cpJk6s0xd7RXo2ODoFkvJJlIBBukC5/kPnsGisQIDAQABo1MwUTAdBgNVHQ4E
|
||||
FgQU76/m3HsYiudPteCzusB4UmGFb5UwHwYDVR0jBBgwFoAU76/m3HsYiudPteCz
|
||||
usB4UmGFb5UwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXhaB
|
||||
lnyVhD5NSAEx4K6jCB3qTkk4QX90C2m2WVPP+8CXVcvbGWeSWpRUS4Xh1Cv3Ic1g
|
||||
Zb+QZL5d+KWwC+u2Ih44bVuO0xNqhya+SBDzF8h/hmeR4dWerwrWUE5NCHzByxDM
|
||||
tcyKRzINIOta9fSuiacD+k/3I4ns9UcXWLRwAD2g/M03dYir5GjJySW7q9pRxKdy
|
||||
SvkhZOXdPsDjJveJJztMurox8rsXANsWsMrjJ3EEkhxCZRjdjq0CrCtryHHIJSTf
|
||||
Cu9MFtWpV1xvJQeIoCKBed076T1XPYUG5q1TO96GZgv+1o6+Mbd8j4myyt2KkuP4
|
||||
6tvuNznVD1ykZK3OdQ==
|
||||
-----END CERTIFICATE-----
|
||||
5
tests/net/socket/tls_configurations/overlay-ec.conf
Normal file
5
tests/net/socket/tls_configurations/overlay-ec.conf
Normal file
@ -0,0 +1,5 @@
|
||||
CONFIG_PSA_WANT_ALG_ECDH=y
|
||||
CONFIG_PSA_WANT_ALG_ECDSA=y
|
||||
CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC=y
|
||||
CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE=y
|
||||
CONFIG_PSA_WANT_ECC_SECP_R1_256=y
|
||||
4
tests/net/socket/tls_configurations/overlay-rsa.conf
Normal file
4
tests/net/socket/tls_configurations/overlay-rsa.conf
Normal file
@ -0,0 +1,4 @@
|
||||
CONFIG_PSA_WANT_ALG_RSA_OAEP=y
|
||||
CONFIG_PSA_WANT_ALG_RSA_PKCS1V15_CRYPT=y
|
||||
CONFIG_PSA_WANT_ALG_RSA_PKCS1V15_SIGN=y
|
||||
CONFIG_PSA_WANT_ALG_RSA_PSS=y
|
||||
8
tests/net/socket/tls_configurations/overlay-tls12.conf
Normal file
8
tests/net/socket/tls_configurations/overlay-tls12.conf
Normal file
@ -0,0 +1,8 @@
|
||||
CONFIG_MBEDTLS_TLS_VERSION_1_2=y
|
||||
CONFIG_PSA_WANT_ALG_TLS12_PRF=y
|
||||
CONFIG_PSA_WANT_KEY_TYPE_AES=y
|
||||
CONFIG_PSA_WANT_ALG_CBC_NO_PADDING=y
|
||||
CONFIG_PSA_WANT_ALG_SHA_256=y
|
||||
CONFIG_PSA_WANT_ALG_SHA_384=y
|
||||
CONFIG_PSA_WANT_KEY_TYPE_HMAC=y
|
||||
CONFIG_PSA_WANT_ALG_HMAC=y
|
||||
8
tests/net/socket/tls_configurations/overlay-tls13.conf
Normal file
8
tests/net/socket/tls_configurations/overlay-tls13.conf
Normal file
@ -0,0 +1,8 @@
|
||||
CONFIG_MBEDTLS_TLS_VERSION_1_3=y
|
||||
CONFIG_PSA_WANT_ALG_HKDF_EXTRACT=y
|
||||
CONFIG_PSA_WANT_ALG_HKDF_EXPAND=y
|
||||
|
||||
CONFIG_PSA_WANT_ALG_GCM=y
|
||||
CONFIG_PSA_WANT_KEY_TYPE_AES=y
|
||||
CONFIG_PSA_WANT_ALG_CBC_NO_PADDING=y
|
||||
CONFIG_PSA_WANT_ALG_SHA_256=y
|
||||
52
tests/net/socket/tls_configurations/prj.conf
Normal file
52
tests/net/socket/tls_configurations/prj.conf
Normal file
@ -0,0 +1,52 @@
|
||||
# Kernel options
|
||||
CONFIG_MAIN_STACK_SIZE=4096
|
||||
CONFIG_POSIX_API=y
|
||||
CONFIG_HEAP_MEM_POOL_SIZE=2048
|
||||
|
||||
# Generic networking options
|
||||
CONFIG_NETWORKING=y
|
||||
|
||||
# Socket
|
||||
CONFIG_NET_SOCKETS=y
|
||||
CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
|
||||
|
||||
# Disable native ethernet driver (using native sockets instead)
|
||||
CONFIG_ETH_NATIVE_POSIX=n
|
||||
|
||||
# Use native sockets
|
||||
CONFIG_NET_SOCKETS=y
|
||||
CONFIG_NET_SOCKETS_OFFLOAD=y
|
||||
CONFIG_NET_DRIVERS=y
|
||||
CONFIG_NET_NATIVE_OFFLOADED_SOCKETS=y
|
||||
|
||||
# Mbed 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_MBEDTLS_PEM_CERTIFICATE_FORMAT=y
|
||||
# Build the PSA Crypto core so that the TLS stack uses the PSA crypto API.
|
||||
CONFIG_MBEDTLS_PSA_CRYPTO_C=y
|
||||
CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG=y
|
||||
CONFIG_ENTROPY_GENERATOR=y
|
||||
|
||||
# Disable some Kconfigs that are implied by CONFIG_NET_SOCKETS_SOCKOPT_TLS.
|
||||
# These are not wrong in general, but specific to a certain case (TLS 1.2 + RSA
|
||||
# key exchange/certificate + AES encryption). What we want here instead is to
|
||||
# have a basic configuration in this "prj.conf" file and then add algorithm
|
||||
# support in overlay files.
|
||||
CONFIG_MBEDTLS_TLS_VERSION_1_2=n
|
||||
CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=n
|
||||
CONFIG_MBEDTLS_CIPHER_AES_ENABLED=n
|
||||
CONFIG_PSA_WANT_KEY_TYPE_AES=n
|
||||
CONFIG_PSA_WANT_ALG_CBC_NO_PADDING=n
|
||||
|
||||
# Logging
|
||||
CONFIG_LOG=y
|
||||
CONFIG_PRINTK=y
|
||||
|
||||
# Debug log options (optional)
|
||||
# CONFIG_NET_LOG=y
|
||||
# CONFIG_MBEDTLS_LOG_LEVEL_DBG=y
|
||||
# CONFIG_MBEDTLS_DEBUG=y
|
||||
17
tests/net/socket/tls_configurations/pytest/conftest.py
Normal file
17
tests/net/socket/tls_configurations/pytest/conftest.py
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import pytest
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption('--server-type')
|
||||
parser.addoption('--port')
|
||||
|
||||
@pytest.fixture()
|
||||
def server_type(request):
|
||||
return request.config.getoption('--server-type')
|
||||
|
||||
@pytest.fixture()
|
||||
def port(request):
|
||||
return request.config.getoption('--port')
|
||||
80
tests/net/socket/tls_configurations/pytest/test_app_vs_openssl.py
Executable file
80
tests/net/socket/tls_configurations/pytest/test_app_vs_openssl.py
Executable file
@ -0,0 +1,80 @@
|
||||
# Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
from twister_harness import DeviceAdapter
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def get_arguments_from_server_type(server_type, port):
|
||||
this_path = os.path.dirname(os.path.abspath(__file__))
|
||||
certs_path = os.path.join(this_path, "..", "credentials")
|
||||
|
||||
args = ["openssl", "s_server"]
|
||||
if server_type == "1.2-rsa":
|
||||
args.extend(["-cert", "{}/rsa.crt".format(certs_path),
|
||||
"-key", "{}/rsa-priv.key".format(certs_path),
|
||||
"-certform", "PEM",
|
||||
"-tls1_2",
|
||||
"-cipher", "AES128-SHA256,AES256-SHA256"])
|
||||
elif server_type == "1.2-ec":
|
||||
args.extend(["-cert", "{}/ec.crt".format(certs_path),
|
||||
"-key", "{}/ec-priv.key".format(certs_path),
|
||||
"-certform", "PEM",
|
||||
"-tls1_2",
|
||||
"-cipher", "ECDHE-ECDSA-AES128-SHA256"])
|
||||
elif server_type == "1.3-ephemeral":
|
||||
args.extend(["-cert", "{}/ec.crt".format(certs_path),
|
||||
"-key", "{}/ec-priv.key".format(certs_path),
|
||||
"-certform", "PEM",
|
||||
"-tls1_3",
|
||||
"-ciphersuites", "TLS_AES_128_GCM_SHA256",
|
||||
"-num_tickets", "0"])
|
||||
elif server_type == "1.3-ephemeral-tickets":
|
||||
args.extend(["-cert", "{}/ec.crt".format(certs_path),
|
||||
"-key", "{}/ec-priv.key".format(certs_path),
|
||||
"-certform", "PEM",
|
||||
"-tls1_3",
|
||||
"-ciphersuites", "TLS_AES_128_GCM_SHA256"])
|
||||
elif server_type == "1.3-psk-tickets":
|
||||
args.extend(["-tls1_3",
|
||||
"-ciphersuites", "TLS_AES_128_GCM_SHA256",
|
||||
"-psk_identity", "PSK_identity", "-psk", "0102030405",
|
||||
"-allow_no_dhe_kex", "-nocert"])
|
||||
else:
|
||||
raise Exception("Wrong server type")
|
||||
|
||||
args.extend(["-serverpref", "-state", "-debug", "-status_verbose", "-rev",
|
||||
"-accept", "{}".format(port)])
|
||||
return args
|
||||
|
||||
def start_server(server_type, port):
|
||||
logger.info("Server type: " + server_type)
|
||||
args = get_arguments_from_server_type(server_type, port)
|
||||
logger.info("Launch command:")
|
||||
print(" ".join(args))
|
||||
openssl = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
try:
|
||||
openssl.wait(1)
|
||||
logger.error("Server startup failed. Here's the logs from OpenSSL:")
|
||||
for line in openssl.stdout.readlines():
|
||||
logger.error(line)
|
||||
raise Exception("Server startup failed")
|
||||
except subprocess.TimeoutExpired:
|
||||
logger.info("Server is up")
|
||||
|
||||
return openssl
|
||||
|
||||
def test_app_vs_openssl(dut: DeviceAdapter, server_type, port):
|
||||
server = start_server(server_type, port)
|
||||
|
||||
logger.info("Launch Zephyr application")
|
||||
dut.launch()
|
||||
dut.readlines_until("Test PASSED", timeout=3.0)
|
||||
|
||||
logger.info("Kill server")
|
||||
server.kill()
|
||||
254
tests/net/socket/tls_configurations/src/main.c
Normal file
254
tests/net/socket/tls_configurations/src/main.c
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*/
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(tls_configuration_sample, LOG_LEVEL_INF);
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <zephyr/posix/sys/eventfd.h>
|
||||
|
||||
#include <zephyr/net/socket.h>
|
||||
#include <zephyr/net/tls_credentials.h>
|
||||
#include <zephyr/net/net_if.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
|
||||
/* This include is required for the definition of the Mbed TLS internal symbol
|
||||
* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED.
|
||||
*/
|
||||
#include <mbedtls/ssl_ciphersuites.h>
|
||||
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
|
||||
static const unsigned char psk[] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
|
||||
static const char psk_id[] = "PSK_identity";
|
||||
#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
|
||||
|
||||
/* Following certificates (*.inc files) are:
|
||||
* - generated from "create-certs.sh" script
|
||||
* - converted in C array shape in the CMakeList file
|
||||
*/
|
||||
#if defined(CONFIG_PSA_WANT_ALG_RSA_PKCS1V15_SIGN) || defined(CONFIG_PSA_WANT_ALG_RSA_PSS)
|
||||
#define USE_CERTIFICATE
|
||||
static const unsigned char certificate[] = {
|
||||
#include "rsa.crt.inc"
|
||||
};
|
||||
#elif defined(CONFIG_PSA_WANT_ALG_ECDSA)
|
||||
#define USE_CERTIFICATE
|
||||
static const unsigned char certificate[] = {
|
||||
#include "ec.crt.inc"
|
||||
};
|
||||
#endif
|
||||
|
||||
#define APP_BANNER "TLS socket configuration sample"
|
||||
|
||||
#define INVALID_SOCKET (-1)
|
||||
|
||||
enum {
|
||||
_PLACEHOLDER_TAG_ = 0,
|
||||
#if defined(USE_CERTIFICATE)
|
||||
CA_CERTIFICATE_TAG,
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
|
||||
PSK_TAG,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int socket_fd = INVALID_SOCKET;
|
||||
static struct pollfd fds[1];
|
||||
|
||||
/* Keep the new line because openssl uses that to start processing the incoming data */
|
||||
#define TEST_STRING "hello world\n"
|
||||
static uint8_t test_buf[sizeof(TEST_STRING)];
|
||||
|
||||
static int wait_for_event(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Wait for event on any socket used. Once event occurs,
|
||||
* we'll check them all.
|
||||
*/
|
||||
ret = poll(fds, ARRAY_SIZE(fds), -1);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Error in poll (%d)", errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create_socket(void)
|
||||
{
|
||||
int ret = 0;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(CONFIG_SERVER_PORT);
|
||||
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
|
||||
|
||||
#if defined(CONFIG_MBEDTLS_TLS_VERSION_1_3)
|
||||
socket_fd = socket(addr.sin_family, SOCK_STREAM, IPPROTO_TLS_1_3);
|
||||
#else
|
||||
socket_fd = socket(addr.sin_family, SOCK_STREAM, IPPROTO_TLS_1_2);
|
||||
#endif
|
||||
if (socket_fd < 0) {
|
||||
LOG_ERR("Failed to create TLS socket (%d)", errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
sec_tag_t sec_tag_list[] = {
|
||||
#if defined(USE_CERTIFICATE)
|
||||
CA_CERTIFICATE_TAG,
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
|
||||
PSK_TAG,
|
||||
#endif
|
||||
};
|
||||
|
||||
ret = setsockopt(socket_fd, SOL_TLS, TLS_SEC_TAG_LIST,
|
||||
sec_tag_list, sizeof(sec_tag_list));
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to set TLS_SEC_TAG_LIST option (%d)", errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* HOSTNAME is only required for key exchanges that use a certificate. */
|
||||
#if defined(USE_CERTIFICATE)
|
||||
ret = setsockopt(socket_fd, SOL_TLS, TLS_HOSTNAME,
|
||||
"localhost", sizeof("localhost"));
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to set TLS_HOSTNAME option (%d)", errno);
|
||||
return -errno;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = connect(socket_fd, (struct sockaddr *) &addr, sizeof(addr));
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Cannot connect to TCP remote (%d)", errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* Prepare file descriptor for polling */
|
||||
fds[0].fd = socket_fd;
|
||||
fds[0].events = POLLIN;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void close_socket(void)
|
||||
{
|
||||
if (socket_fd != INVALID_SOCKET) {
|
||||
close(socket_fd);
|
||||
}
|
||||
}
|
||||
|
||||
static int setup_credentials(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
#if defined(USE_CERTIFICATE)
|
||||
err = tls_credential_add(CA_CERTIFICATE_TAG,
|
||||
TLS_CREDENTIAL_CA_CERTIFICATE,
|
||||
certificate,
|
||||
sizeof(certificate));
|
||||
if (err < 0) {
|
||||
LOG_ERR("Failed to register certificate: %d", err);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_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
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ret;
|
||||
size_t data_len;
|
||||
|
||||
LOG_INF(APP_BANNER);
|
||||
|
||||
setup_credentials();
|
||||
|
||||
ret = create_socket();
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Socket creation failed (%d)", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memcpy(test_buf, TEST_STRING, sizeof(TEST_STRING));
|
||||
/* The -1 here is because sizeof() accounts for "\0" but that's not
|
||||
* needed for socket functions send/recv.
|
||||
*/
|
||||
data_len = sizeof(TEST_STRING) - 1;
|
||||
|
||||
/* OpenSSL s_server has only the "-rev" option as echo-like behavior
|
||||
* which echoes back the data that we send it in reversed order. So
|
||||
* in the following we send the test buffer twice (in the 1st iteration
|
||||
* it will contain the original TEST_STRING, whereas in the 2nd one
|
||||
* it will contain TEST_STRING reversed) so that in the end we can
|
||||
* just memcmp() it against the original TEST_STRING.
|
||||
*/
|
||||
for (int i = 0; i < 2; i++) {
|
||||
LOG_DBG("Send: %s", test_buf);
|
||||
ret = send(socket_fd, test_buf, data_len, 0);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Error sending test string (%d)", errno);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memset(test_buf, 0, sizeof(test_buf));
|
||||
|
||||
wait_for_event();
|
||||
|
||||
ret = recv(socket_fd, test_buf, data_len, MSG_WAITALL);
|
||||
if (ret == 0) {
|
||||
LOG_ERR("Server terminated unexpectedly");
|
||||
ret = -EIO;
|
||||
goto exit;
|
||||
} else if (ret < 0) {
|
||||
LOG_ERR("Error receiving data (%d)", errno);
|
||||
goto exit;
|
||||
}
|
||||
if (ret != data_len) {
|
||||
LOG_ERR("Sent %d bytes, but received %d", data_len, ret);
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
LOG_DBG("Received: %s", test_buf);
|
||||
}
|
||||
|
||||
ret = memcmp(TEST_STRING, test_buf, data_len);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Received data does not match with TEST_STRING");
|
||||
LOG_HEXDUMP_ERR(test_buf, data_len, "Received:");
|
||||
LOG_HEXDUMP_ERR(TEST_STRING, data_len, "Expected:");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
exit:
|
||||
LOG_INF("Test %s", (ret < 0) ? "FAILED" : "PASSED");
|
||||
|
||||
close_socket();
|
||||
|
||||
return 0;
|
||||
}
|
||||
53
tests/net/socket/tls_configurations/testcase.yaml
Normal file
53
tests/net/socket/tls_configurations/testcase.yaml
Normal file
@ -0,0 +1,53 @@
|
||||
common:
|
||||
tags:
|
||||
- crypto.mbedtls
|
||||
- net.socket
|
||||
platform_allow:
|
||||
- native_sim
|
||||
- native_sim/native/64
|
||||
integration_platforms:
|
||||
- native_sim
|
||||
harness: pytest
|
||||
tests:
|
||||
net.sockets.tls12.rsa_kex:
|
||||
extra_args:
|
||||
- EXTRA_CONF_FILE=overlay-tls12.conf;overlay-rsa.conf
|
||||
extra_configs:
|
||||
- CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=y
|
||||
- CONFIG_SERVER_PORT=4000
|
||||
harness_config:
|
||||
pytest_args: ["--server-type", "1.2-rsa", "--port", "4000"]
|
||||
net.sockets.tls12.ec_kex:
|
||||
extra_args:
|
||||
- EXTRA_CONF_FILE=overlay-tls12.conf;overlay-ec.conf
|
||||
extra_configs:
|
||||
- CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=y
|
||||
- CONFIG_SERVER_PORT=4001
|
||||
harness_config:
|
||||
pytest_args: ["--server-type", "1.2-ec", "--port", "4001"]
|
||||
net.sockets.tls13.ephemeral_kex:
|
||||
extra_args:
|
||||
- EXTRA_CONF_FILE=overlay-tls13.conf;overlay-ec.conf
|
||||
extra_configs:
|
||||
- CONFIG_MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED=y
|
||||
- CONFIG_SERVER_PORT=4002
|
||||
harness_config:
|
||||
pytest_args: ["--server-type", "1.3-ephemeral", "--port", "4002"]
|
||||
net.sockets.tls13.ephemeral_kex.tickets:
|
||||
extra_args:
|
||||
- EXTRA_CONF_FILE=overlay-tls13.conf;overlay-ec.conf
|
||||
extra_configs:
|
||||
- CONFIG_MBEDTLS_TLS_SESSION_TICKETS=y
|
||||
- CONFIG_MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED=y
|
||||
- CONFIG_SERVER_PORT=4003
|
||||
harness_config:
|
||||
pytest_args: ["--server-type", "1.3-ephemeral-tickets", "--port", "4003"]
|
||||
net.sockets.tls13.psk_kex.tickets:
|
||||
extra_args:
|
||||
- EXTRA_CONF_FILE=overlay-tls13.conf
|
||||
extra_configs:
|
||||
- CONFIG_MBEDTLS_TLS_SESSION_TICKETS=y
|
||||
- CONFIG_MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED=y
|
||||
- CONFIG_SERVER_PORT=4004
|
||||
harness_config:
|
||||
pytest_args: ["--server-type", "1.3-psk-tickets", "--port", "4004"]
|
||||
Loading…
Reference in New Issue
Block a user