2009-01-03 22:22:43 +01:00
/*
* SSL client with certificate authentication
*
2015-07-27 11:11:48 +02:00
* Copyright ( C ) 2006 - 2015 , ARM Limited , All Rights Reserved
2015-09-04 14:21:07 +02:00
* SPDX - License - Identifier : Apache - 2.0
2010-07-18 22:36:00 +02:00
*
2015-09-04 14:21:07 +02:00
* Licensed under the Apache License , Version 2.0 ( the " License " ) ; you may
* not use this file except in compliance with the License .
* You may obtain a copy of the License at
2009-01-04 17:27:10 +01:00
*
2015-09-04 14:21:07 +02:00
* http : //www.apache.org/licenses/LICENSE-2.0
2009-01-03 22:22:43 +01:00
*
2015-09-04 14:21:07 +02:00
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS , WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
2009-01-03 22:22:43 +01:00
*
2015-09-04 14:21:07 +02:00
* This file is part of mbed TLS ( https : //tls.mbed.org)
2009-01-03 22:22:43 +01:00
*/
2015-04-08 12:49:31 +02:00
# if !defined(MBEDTLS_CONFIG_FILE)
2015-03-09 18:05:11 +01:00
# include "mbedtls/config.h"
2014-04-29 12:39:06 +02:00
# else
2015-04-08 12:49:31 +02:00
# include MBEDTLS_CONFIG_FILE
2014-04-29 12:39:06 +02:00
# endif
2009-01-03 22:22:43 +01:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_PLATFORM_C)
2015-03-09 18:05:11 +01:00
# include "mbedtls/platform.h"
2015-01-19 15:26:37 +01:00
# else
2015-02-11 15:06:19 +01:00
# include <stdio.h>
2016-04-27 02:26:50 +02:00
# include <stdlib.h>
# define mbedtls_time time
# define mbedtls_time_t time_t
2015-04-08 12:49:31 +02:00
# define mbedtls_printf printf
# define mbedtls_fprintf fprintf
# define mbedtls_snprintf snprintf
2019-03-30 07:27:43 +01:00
# define mbedtls_calloc calloc
# define mbedtls_free free
2019-01-31 14:20:20 +01:00
# define mbedtls_exit exit
# define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
# define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
2015-01-19 15:26:37 +01:00
# endif
2015-05-13 10:04:32 +02:00
# if !defined(MBEDTLS_ENTROPY_C) || \
! defined ( MBEDTLS_SSL_TLS_C ) | | ! defined ( MBEDTLS_SSL_CLI_C ) | | \
2015-05-13 13:58:56 +02:00
! defined ( MBEDTLS_NET_C ) | | ! defined ( MBEDTLS_CTR_DRBG_C )
2015-05-13 10:04:32 +02:00
int main ( void )
{
mbedtls_printf ( " MBEDTLS_ENTROPY_C and/or "
" MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
2015-05-13 13:58:56 +02:00
" MBEDTLS_NET_C and/or MBEDTLS_CTR_DRBG_C and/or not defined. \n " ) ;
2015-05-13 10:04:32 +02:00
return ( 0 ) ;
}
# else
2019-11-20 15:00:17 +01:00
# if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
# include "mbedtls/memory_buffer_alloc.h"
# endif
2016-09-14 15:32:09 +02:00
# include "mbedtls/net_sockets.h"
2015-03-09 18:05:11 +01:00
# include "mbedtls/ssl.h"
# include "mbedtls/entropy.h"
# include "mbedtls/ctr_drbg.h"
# include "mbedtls/certs.h"
# include "mbedtls/x509.h"
# include "mbedtls/error.h"
# include "mbedtls/debug.h"
2015-05-13 10:04:32 +02:00
# include "mbedtls/timing.h"
2020-04-16 14:35:19 +02:00
# include "mbedtls/base64.h"
2009-01-03 22:22:43 +01:00
2018-11-12 18:46:59 +01:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
# include "psa/crypto.h"
2018-11-15 14:06:09 +01:00
# include "mbedtls/psa_util.h"
2018-11-12 18:46:59 +01:00
# endif
2015-02-11 15:06:19 +01:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
2014-02-20 22:50:56 +01:00
2019-11-20 15:00:17 +01:00
/* Size of memory to be allocated for the heap, when using the library's memory
* management and MBEDTLS_MEMORY_BUFFER_ALLOC_C is enabled . */
# define MEMORY_HEAP_SIZE 120000
2017-09-18 16:05:46 +02:00
# define MAX_REQUEST_SIZE 20000
# define MAX_REQUEST_SIZE_STR "20000"
2010-02-18 20:37:19 +01:00
# define DFL_SERVER_NAME "localhost"
2014-02-25 11:11:26 +01:00
# define DFL_SERVER_ADDR NULL
2015-06-23 12:30:57 +02:00
# define DFL_SERVER_PORT "4433"
2010-02-18 20:37:19 +01:00
# define DFL_REQUEST_PAGE " / "
2014-06-18 13:07:56 +02:00
# define DFL_REQUEST_SIZE -1
2010-02-18 20:37:19 +01:00
# define DFL_DEBUG_LEVEL 0
2019-04-03 13:59:58 +02:00
# define DFL_CONTEXT_CRT_CB 0
2014-02-26 13:47:08 +01:00
# define DFL_NBIO 0
2017-10-10 16:56:37 +02:00
# define DFL_EVENT 0
2014-10-01 18:29:03 +02:00
# define DFL_READ_TIMEOUT 0
2014-10-02 14:02:32 +02:00
# define DFL_MAX_RESEND 0
2011-05-26 15:16:06 +02:00
# define DFL_CA_FILE ""
2012-06-04 14:46:42 +02:00
# define DFL_CA_PATH ""
2010-07-18 10:28:20 +02:00
# define DFL_CRT_FILE ""
# define DFL_KEY_FILE ""
2018-11-07 09:42:35 +01:00
# define DFL_KEY_OPAQUE 0
2013-04-16 18:05:29 +02:00
# define DFL_PSK ""
2018-11-15 14:06:09 +01:00
# define DFL_PSK_OPAQUE 0
2013-04-16 18:05:29 +02:00
# define DFL_PSK_IDENTITY "Client_identity"
2015-09-16 11:08:34 +02:00
# define DFL_ECJPAKE_PW NULL
2017-05-16 08:50:24 +02:00
# define DFL_EC_MAX_OPS -1
2011-02-20 17:05:58 +01:00
# define DFL_FORCE_CIPHER 0
2015-04-08 12:49:31 +02:00
# define DFL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION_DISABLED
2014-11-03 20:10:36 +01:00
# define DFL_ALLOW_LEGACY -2
2014-02-20 17:19:59 +01:00
# define DFL_RENEGOTIATE 0
2014-08-15 12:07:38 +02:00
# define DFL_EXCHANGES 1
2015-03-31 14:21:11 +02:00
# define DFL_MIN_VERSION -1
2012-09-28 15:28:45 +02:00
# define DFL_MAX_VERSION -1
2015-03-20 20:44:04 +01:00
# define DFL_ARC4 -1
2017-05-09 15:59:24 +02:00
# define DFL_SHA1 -1
2015-03-27 17:52:25 +01:00
# define DFL_AUTH_MODE -1
2015-04-08 12:49:31 +02:00
# define DFL_MFL_CODE MBEDTLS_SSL_MAX_FRAG_LEN_NONE
2015-01-09 12:43:35 +01:00
# define DFL_TRUNC_HMAC -1
2015-01-07 16:35:25 +01:00
# define DFL_RECSPLIT -1
2015-06-11 17:02:29 +02:00
# define DFL_DHMLEN -1
2013-07-30 13:43:43 +02:00
# define DFL_RECONNECT 0
2014-02-20 22:50:56 +01:00
# define DFL_RECO_DELAY 0
2019-05-20 12:46:26 +02:00
# define DFL_RECO_MODE 1
2019-04-09 18:24:19 +02:00
# define DFL_CID_ENABLED 0
# define DFL_CID_VALUE ""
2019-05-03 18:30:59 +02:00
# define DFL_CID_ENABLED_RENEGO -1
# define DFL_CID_VALUE_RENEGO NULL
2015-09-04 10:20:17 +02:00
# define DFL_RECONNECT_HARD 0
2015-04-08 12:49:31 +02:00
# define DFL_TICKETS MBEDTLS_SSL_SESSION_TICKETS_ENABLED
2014-04-05 14:34:07 +02:00
# define DFL_ALPN_STRING NULL
2017-05-15 17:05:15 +02:00
# define DFL_CURVES NULL
2015-04-08 12:49:31 +02:00
# define DFL_TRANSPORT MBEDTLS_SSL_TRANSPORT_STREAM
2014-10-01 14:40:56 +02:00
# define DFL_HS_TO_MIN 0
# define DFL_HS_TO_MAX 0
2018-08-12 13:28:53 +02:00
# define DFL_DTLS_MTU -1
2018-08-14 14:33:30 +02:00
# define DFL_DGRAM_PACKING 1
2014-10-20 13:34:59 +02:00
# define DFL_FALLBACK -1
2014-10-20 18:40:56 +02:00
# define DFL_EXTENDED_MS -1
2014-10-27 13:57:03 +01:00
# define DFL_ETM -1
2019-05-29 12:33:32 +02:00
# define DFL_SERIALIZE 0
2020-04-16 14:35:19 +02:00
# define DFL_CONTEXT_FILE ""
2019-05-29 12:33:32 +02:00
# define DFL_EXTENDED_MS_ENFORCE -1
2019-03-27 16:55:27 +01:00
# define DFL_CA_CALLBACK 0
2019-05-12 10:03:32 +02:00
# define DFL_EAP_TLS 0
2019-06-06 21:24:31 +02:00
# define DFL_REPRODUCIBLE 0
2019-08-29 07:31:22 +02:00
# define DFL_NSS_KEYLOG 0
# define DFL_NSS_KEYLOG_FILE NULL
Fix possible close_notify/ClientHello confusion
The ssl-opt.sh test cases using session resumption tend to fail occasionally
on the CI due to a race condition in how ssl_server2 and ssl_client2 handle
the reconnection cycle.
The server does the following in order:
- S1 send application data
- S2 send a close_notify alert
- S3 close the client socket
- S4 wait for a "new connection" (actually a new datagram)
- S5 start a handshake
The client does the following in order:
- C1 wait for and read application data from the server
- C2 send a close_notify alert
- C3 close the server socket
- C4 reset session data and re-open a server socket
- C5 start a handshake
If the client has been able to send the close_notify (C2) and if has been
delivered to the server before if closes the client socket (S3), when the
server reaches S4, the datagram that we start the new connection will be the
ClientHello and everything will be fine.
However if S3 wins the race and happens before the close_notify is delivered,
in S4 the close_notify is what will be seen as the first datagram in a new
connection, and then in S5 this will rightfully be rejected as not being a
valid ClientHello and the server will close the connection (and go wait for
another one). The client will then fail to read from the socket and exit
non-zero and the ssl-opt.sh harness will correctly report this as a failure.
In order to avoid this race condition in test using ssl_client2 and
ssl_server2, this commits introduces a new command-line option
skip_close_notify to ssl_client2 and uses it in all ssl-opt.sh tests that use
session resumption with DTLS and ssl_server2.
This works because ssl_server2 knows how many messages it expects in each
direction and in what order, and closes the connection after that rather than
relying on close_notify (which is also why there was a race in the first
place).
Tests that use another server (in practice there are two of them, using
OpenSSL as a server) wouldn't work with skip_close_notify, as the server won't
close the connection until the client sends a close_notify, but for the same
reason they don't need it (there is no race between receiving close_notify and
closing as the former is the cause of the later).
An alternative approach would be to make ssl_server2 keep the connection open
until it receives a close_notify. Unfortunately it creates problems for tests
where we simulate a lossy network, as the close_notify could be lost (and the
client can't retransmit it). We could modify udp_proxy with an option to never
drop alert messages, but when TLS 1.3 comes that would no longer work as the
type of messages will be encrypted.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2020-02-17 11:04:33 +01:00
# define DFL_SKIP_CLOSE_NOTIFY 0
2009-02-10 23:19:10 +01:00
2014-04-25 13:40:05 +02:00
# define GET_REQUEST "GET %s HTTP / 1.0\r\nExtra-header: "
# define GET_REQUEST_END "\r\n\r\n"
2009-01-03 22:22:43 +01:00
2019-04-03 13:59:58 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
2019-04-05 15:06:58 +02:00
# define USAGE_CONTEXT_CRT_CB \
2019-04-03 13:59:58 +02:00
" context_crt_cb=%%d This determines whether the CRT verification callback is bound \n " \
" to the SSL configuration of the SSL context. \n " \
" Possible values: \n " \
" - 0 (default): Use CRT callback bound to configuration \n " \
" - 1: Use CRT callback bound to SSL context \n "
# else
2019-04-05 15:06:58 +02:00
# define USAGE_CONTEXT_CRT_CB ""
2019-04-03 13:59:58 +02:00
# endif /* MBEDTLS_X509_CRT_PARSE_C */
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
# if defined(MBEDTLS_FS_IO)
2011-05-26 15:16:06 +02:00
# define USAGE_IO \
2012-11-20 10:30:55 +01:00
" ca_file=%%s The single file containing the top-level CA(s) you fully trust \n " \
" default: \" \" (pre-loaded) \n " \
2019-05-01 12:16:28 +02:00
" use \" none \" to skip loading any top-level CAs. \n " \
2012-11-20 10:30:55 +01:00
" ca_path=%%s The path containing the top-level CA(s) you fully trust \n " \
" default: \" \" (pre-loaded) (overrides ca_file) \n " \
2019-05-01 12:16:28 +02:00
" use \" none \" to skip loading any top-level CAs. \n " \
2012-11-20 10:30:55 +01:00
" crt_file=%%s Your own cert and chain (in bottom to top order, top may be omitted) \n " \
" default: \" \" (pre-loaded) \n " \
2011-05-26 15:16:06 +02:00
" key_file=%%s default: \" \" (pre-loaded) \n "
# else
# define USAGE_IO \
2015-04-08 12:49:31 +02:00
" No file operations available (MBEDTLS_FS_IO not defined) \n "
# endif /* MBEDTLS_FS_IO */
2018-11-07 09:42:35 +01:00
# else /* MBEDTLS_X509_CRT_PARSE_C */
2013-04-18 22:46:23 +02:00
# define USAGE_IO ""
2015-04-08 12:49:31 +02:00
# endif /* MBEDTLS_X509_CRT_PARSE_C */
2018-11-07 09:42:35 +01:00
# if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_X509_CRT_PARSE_C)
# define USAGE_KEY_OPAQUE \
" key_opaque=%%d Handle your private key as if it were opaque \n " \
" default: 0 (disabled) \n "
# else
# define USAGE_KEY_OPAQUE ""
# endif
2013-04-18 22:46:23 +02:00
2019-05-15 15:03:01 +02:00
# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2019-04-09 18:24:19 +02:00
# define USAGE_CID \
" cid=%%d Disable (0) or enable (1) the use of the DTLS Connection ID extension. \n " \
" default: 0 (disabled) \n " \
2019-05-03 18:30:59 +02:00
" cid_renego=%%d Disable (0) or enable (1) the use of the DTLS Connection ID extension during renegotiation. \n " \
2019-05-23 18:01:06 +02:00
" default: same as 'cid' parameter \n " \
2019-04-09 18:24:19 +02:00
" cid_val=%%s The CID to use for incoming messages (in hex, without 0x). \n " \
2019-05-03 18:30:59 +02:00
" default: \" \" \n " \
" cid_val_renego=%%s The CID to use for incoming messages (in hex, without 0x) after renegotiation. \n " \
2019-05-23 18:01:06 +02:00
" default: same as 'cid_val' parameter \n "
2019-05-15 15:03:01 +02:00
# else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2019-04-09 18:24:19 +02:00
# define USAGE_CID ""
2019-05-15 15:03:01 +02:00
# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2019-04-09 18:24:19 +02:00
2020-03-10 12:19:08 +01:00
# if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
2018-10-23 12:37:50 +02:00
# define USAGE_PSK_RAW \
2019-11-20 14:54:36 +01:00
" psk=%%s default: \" \" (disabled) \n " \
" The PSK values are in hex, without 0x. \n " \
2013-04-18 22:46:23 +02:00
" psk_identity=%%s default: \" Client_identity \" \n "
2018-10-23 12:37:50 +02:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
# define USAGE_PSK_SLOT \
2018-11-15 14:06:09 +01:00
" psk_opaque=%%d default: 0 (don't use opaque static PSK) \n " \
" Enable this to store the PSK configured through command line \n " \
" parameter `psk` in a PSA-based key slot. \n " \
2018-10-23 12:37:50 +02:00
" Note: Currently only supported in conjunction with \n " \
" the use of min_version to force TLS 1.2 and force_ciphersuite \n " \
" to force a particular PSK-only ciphersuite. \n " \
" Note: This is to test integration of PSA-based opaque PSKs with \n " \
" Mbed TLS only. Production systems are likely to configure Mbed TLS \n " \
" with prepopulated key slots instead of importing raw key material. \n "
# else
# define USAGE_PSK_SLOT ""
# endif /* MBEDTLS_USE_PSA_CRYPTO */
2019-03-29 13:02:26 +01:00
# define USAGE_PSK USAGE_PSK_RAW USAGE_PSK_SLOT
# else
# define USAGE_PSK ""
2020-03-10 12:19:08 +01:00
# endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
2019-03-29 13:02:26 +01:00
2019-03-27 16:55:27 +01:00
# if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
# define USAGE_CA_CALLBACK \
" ca_callback=%%d default: 0 (disabled) \n " \
" Enable this to use the trusted certificate callback function \n "
# else
# define USAGE_CA_CALLBACK ""
# endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
2011-05-26 15:16:06 +02:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_SESSION_TICKETS)
2013-08-14 13:48:06 +02:00
# define USAGE_TICKETS \
" tickets=%%d default: 1 (enabled) \n "
# else
# define USAGE_TICKETS ""
2015-04-08 12:49:31 +02:00
# endif /* MBEDTLS_SSL_SESSION_TICKETS */
2013-08-14 13:48:06 +02:00
2019-05-12 10:03:32 +02:00
# if defined(MBEDTLS_SSL_EXPORT_KEYS)
# define USAGE_EAP_TLS \
" eap_tls=%%d default: 0 (disabled) \n "
2019-08-29 07:31:22 +02:00
# define USAGE_NSS_KEYLOG \
2019-09-09 12:38:51 +02:00
" nss_keylog=%%d default: 0 (disabled) \n " \
" This cannot be used with eap_tls=1 \n "
2019-08-29 07:31:22 +02:00
# define USAGE_NSS_KEYLOG_FILE \
" nss_keylog_file=%%s \n "
2019-05-12 10:03:32 +02:00
# else
# define USAGE_EAP_TLS ""
2019-08-29 07:31:22 +02:00
# define USAGE_NSS_KEYLOG ""
# define USAGE_NSS_KEYLOG_FILE ""
2019-05-12 10:03:32 +02:00
# endif /* MBEDTLS_SSL_EXPORT_KEYS */
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
2013-08-15 13:45:55 +02:00
# define USAGE_TRUNC_HMAC \
2015-01-09 12:43:35 +01:00
" trunc_hmac=%%d default: library default \n "
2013-08-15 13:45:55 +02:00
# else
# define USAGE_TRUNC_HMAC ""
2015-04-08 12:49:31 +02:00
# endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
2013-08-15 13:45:55 +02:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
2013-08-15 13:33:48 +02:00
# define USAGE_MAX_FRAG_LEN \
" max_frag_len=%%d default: 16384 (tls default) \n " \
" options: 512, 1024, 2048, 4096 \n "
# else
# define USAGE_MAX_FRAG_LEN ""
2015-04-08 12:49:31 +02:00
# endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
2013-08-15 13:33:48 +02:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
2015-01-07 16:35:25 +01:00
# define USAGE_RECSPLIT \
2015-06-11 17:02:10 +02:00
" recsplit=0/1 default: (library default: on) \n "
2015-01-07 16:35:25 +01:00
# else
# define USAGE_RECSPLIT
# endif
2015-06-11 17:02:29 +02:00
# if defined(MBEDTLS_DHM_C)
# define USAGE_DHMLEN \
" dhmlen=%%d default: (library default: 1024 bits) \n "
# else
# define USAGE_DHMLEN
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_ALPN)
2014-04-05 14:34:07 +02:00
# define USAGE_ALPN \
" alpn=%%s default: \" \" (disabled) \n " \
" example: spdy/1,http/1.1 \n "
# else
# define USAGE_ALPN ""
2015-04-08 12:49:31 +02:00
# endif /* MBEDTLS_SSL_ALPN */
2014-04-05 14:34:07 +02:00
2017-05-15 17:05:15 +02:00
# if defined(MBEDTLS_ECP_C)
# define USAGE_CURVES \
" curves=a,b,c,d default: \" default \" (library default) \n " \
" example: \" secp521r1,brainpoolP512r1 \" \n " \
" - use \" none \" for empty list \n " \
" - see mbedtls_ecp_curve_list() \n " \
" for acceptable curve names \n "
# else
# define USAGE_CURVES ""
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_PROTO_DTLS)
2014-10-01 14:40:56 +02:00
# define USAGE_DTLS \
" dtls=%%d default: 0 (TLS) \n " \
" hs_timeout=%%d-%%d default: (library default: 1000-60000) \n " \
2018-08-12 13:28:53 +02:00
" range of DTLS handshake timeouts in millisecs \n " \
2018-08-14 14:33:30 +02:00
" mtu=%%d default: (library default: unlimited) \n " \
" dgram_packing=%%d default: 1 (allowed) \n " \
" allow or forbid packing of multiple \n " \
" records within a single datgram. \n "
2014-10-01 14:40:56 +02:00
# else
# define USAGE_DTLS ""
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_FALLBACK_SCSV)
2014-10-20 13:34:59 +02:00
# define USAGE_FALLBACK \
" fallback=0/1 default: (library default: off) \n "
# else
# define USAGE_FALLBACK ""
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
2014-10-20 18:40:56 +02:00
# define USAGE_EMS \
" extended_ms=0/1 default: (library default: on) \n "
# else
# define USAGE_EMS ""
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
2014-10-27 13:57:03 +01:00
# define USAGE_ETM \
" etm=0/1 default: (library default: on) \n "
# else
# define USAGE_ETM ""
# endif
2019-06-18 20:16:43 +02:00
# define USAGE_REPRODUCIBLE \
" reproducible=0/1 default: 0 (disabled) \n "
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_RENEGOTIATION)
2014-11-03 08:23:14 +01:00
# define USAGE_RENEGO \
" renegotiation=%%d default: 0 (disabled) \n " \
" renegotiate=%%d default: 0 (disabled) \n "
# else
# define USAGE_RENEGO ""
# endif
2015-09-16 11:08:34 +02:00
# if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
# define USAGE_ECJPAKE \
" ecjpake_pw=%%s default: none (disabled) \n "
# else
# define USAGE_ECJPAKE ""
# endif
2017-05-16 08:50:24 +02:00
# if defined(MBEDTLS_ECP_RESTARTABLE)
# define USAGE_ECRESTART \
" ec_max_ops=%%s default: library default (restart disabled) \n "
# else
# define USAGE_ECRESTART ""
# endif
2019-06-04 10:06:31 +02:00
# if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
# define USAGE_SERIALIZATION \
2020-04-16 14:35:19 +02:00
" serialize=%%d default: 0 (do not serialize/deserialize) \n " \
" options: 1 (serialize) \n " \
" 2 (serialize with re-initialization) \n " \
" context_file=%%s The file path to write a serialized connection \n " \
" in the form of base64 code (serialize option \n " \
" must be set) \n " \
" default: \" \" (do nothing) \n " \
" option: a file path \n "
2019-06-04 10:06:31 +02:00
# else
# define USAGE_SERIALIZATION ""
# endif
2010-02-18 20:37:19 +01:00
# define USAGE \
2010-07-18 10:28:20 +02:00
" \n usage: ssl_client2 param=<>... \n " \
" \n acceptable parameters: \n " \
" server_name=%%s default: localhost \n " \
2014-02-25 11:11:26 +01:00
" server_addr=%%s default: given by name \n " \
2010-07-18 10:28:20 +02:00
" server_port=%%d default: 4433 \n " \
2014-02-19 18:22:59 +01:00
" request_page=%%s default: \" . \" \n " \
2018-07-04 10:29:34 +02:00
" request_size=%%d default: about 34 (basic request) \n " \
" (minimum: 0, max: " MAX_REQUEST_SIZE_STR " ) \n " \
" If 0, in the first exchange only an empty \n " \
" application data message is sent followed by \n " \
" a second non-empty message before attempting \n " \
" to read a response from the server \n " \
2017-10-10 16:56:37 +02:00
" debug_level=%%d default: 0 (disabled) \n " \
" nbio=%%d default: 0 (blocking I/O) \n " \
" options: 1 (non-blocking), 2 (added delays) \n " \
" event=%%d default: 0 (loop) \n " \
" options: 1 (level-triggered, implies nbio=1), \n " \
" read_timeout=%%d default: 0 ms (no timeout) \n " \
2014-10-02 14:02:32 +02:00
" max_resend=%%d default: 0 (no resend on timeout) \n " \
Fix possible close_notify/ClientHello confusion
The ssl-opt.sh test cases using session resumption tend to fail occasionally
on the CI due to a race condition in how ssl_server2 and ssl_client2 handle
the reconnection cycle.
The server does the following in order:
- S1 send application data
- S2 send a close_notify alert
- S3 close the client socket
- S4 wait for a "new connection" (actually a new datagram)
- S5 start a handshake
The client does the following in order:
- C1 wait for and read application data from the server
- C2 send a close_notify alert
- C3 close the server socket
- C4 reset session data and re-open a server socket
- C5 start a handshake
If the client has been able to send the close_notify (C2) and if has been
delivered to the server before if closes the client socket (S3), when the
server reaches S4, the datagram that we start the new connection will be the
ClientHello and everything will be fine.
However if S3 wins the race and happens before the close_notify is delivered,
in S4 the close_notify is what will be seen as the first datagram in a new
connection, and then in S5 this will rightfully be rejected as not being a
valid ClientHello and the server will close the connection (and go wait for
another one). The client will then fail to read from the socket and exit
non-zero and the ssl-opt.sh harness will correctly report this as a failure.
In order to avoid this race condition in test using ssl_client2 and
ssl_server2, this commits introduces a new command-line option
skip_close_notify to ssl_client2 and uses it in all ssl-opt.sh tests that use
session resumption with DTLS and ssl_server2.
This works because ssl_server2 knows how many messages it expects in each
direction and in what order, and closes the connection after that rather than
relying on close_notify (which is also why there was a race in the first
place).
Tests that use another server (in practice there are two of them, using
OpenSSL as a server) wouldn't work with skip_close_notify, as the server won't
close the connection until the client sends a close_notify, but for the same
reason they don't need it (there is no race between receiving close_notify and
closing as the former is the cause of the later).
An alternative approach would be to make ssl_server2 keep the connection open
until it receives a close_notify. Unfortunately it creates problems for tests
where we simulate a lossy network, as the close_notify could be lost (and the
client can't retransmit it). We could modify udp_proxy with an option to never
drop alert messages, but when TLS 1.3 comes that would no longer work as the
type of messages will be encrypted.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2020-02-17 11:04:33 +01:00
" skip_close_notify=%%d default: 0 (send close_notify) \n " \
2014-02-19 18:22:59 +01:00
" \n " \
2014-10-01 14:40:56 +02:00
USAGE_DTLS \
2019-04-09 18:24:19 +02:00
USAGE_CID \
2014-10-01 14:40:56 +02:00
" \n " \
2017-10-10 16:56:37 +02:00
" auth_mode=%%s default: (library default: none) \n " \
2014-02-19 18:22:59 +01:00
" options: none, optional, required \n " \
2011-05-26 15:16:06 +02:00
USAGE_IO \
2018-11-07 09:42:35 +01:00
USAGE_KEY_OPAQUE \
2019-03-27 16:55:27 +01:00
USAGE_CA_CALLBACK \
2014-02-19 18:22:59 +01:00
" \n " \
USAGE_PSK \
2015-09-16 11:08:34 +02:00
USAGE_ECJPAKE \
2017-05-16 08:50:24 +02:00
USAGE_ECRESTART \
2014-02-19 18:22:59 +01:00
" \n " \
2017-10-10 16:56:37 +02:00
" allow_legacy=%%d default: (library default: no) \n " \
2014-11-03 08:23:14 +01:00
USAGE_RENEGO \
2014-08-15 12:07:38 +02:00
" exchanges=%%d default: 1 \n " \
2019-05-20 12:46:26 +02:00
" reconnect=%%d number of reconnections using session resumption \n " \
" default: 0 (disabled) \n " \
2015-05-13 10:04:32 +02:00
" reco_delay=%%d default: 0 seconds \n " \
2019-06-03 09:55:16 +02:00
" reco_mode=%%d 0: copy session, 1: serialize session \n " \
2019-05-20 12:46:26 +02:00
" default: 1 \n " \
2015-09-04 10:20:17 +02:00
" reconnect_hard=%%d default: 0 (disabled) \n " \
2013-08-14 13:48:06 +02:00
USAGE_TICKETS \
2019-05-12 10:03:32 +02:00
USAGE_EAP_TLS \
2014-02-19 18:22:59 +01:00
USAGE_MAX_FRAG_LEN \
USAGE_TRUNC_HMAC \
2019-04-05 15:06:58 +02:00
USAGE_CONTEXT_CRT_CB \
2014-04-05 14:34:07 +02:00
USAGE_ALPN \
2014-10-20 13:34:59 +02:00
USAGE_FALLBACK \
2014-10-20 18:40:56 +02:00
USAGE_EMS \
2014-10-27 13:57:03 +01:00
USAGE_ETM \
2019-06-18 20:16:43 +02:00
USAGE_REPRODUCIBLE \
2017-05-15 17:05:15 +02:00
USAGE_CURVES \
2015-01-07 16:35:25 +01:00
USAGE_RECSPLIT \
2015-06-11 17:02:29 +02:00
USAGE_DHMLEN \
2012-09-28 15:28:45 +02:00
" \n " \
2015-03-27 17:52:25 +01:00
" arc4=%%d default: (library default: 0) \n " \
2017-05-09 15:59:24 +02:00
" allow_sha1=%%d default: 0 \n " \
2015-03-31 14:21:11 +02:00
" min_version=%%s default: (library default: tls1) \n " \
" max_version=%%s default: (library default: tls1_2) \n " \
2012-09-28 15:28:45 +02:00
" force_version=%%s default: \" \" (none) \n " \
2014-02-12 11:11:12 +01:00
" options: ssl3, tls1, tls1_1, tls1_2, dtls1, dtls1_2 \n " \
2012-09-28 15:28:45 +02:00
" \n " \
2011-02-20 17:05:58 +01:00
" force_ciphersuite=<name> default: all enabled \n " \
2018-10-16 22:08:38 +02:00
" query_config=<name> return 0 if the specified \n " \
" configuration macro is defined and 1 \n " \
" otherwise. The expansion of the macro \n " \
" is printed if it is defined \n " \
2019-06-04 10:06:31 +02:00
USAGE_SERIALIZATION \
2011-02-20 17:05:58 +01:00
" acceptable ciphersuite names: \n "
2010-02-18 20:37:19 +01:00
2017-06-09 17:13:22 +02:00
# define ALPN_LIST_SIZE 10
# define CURVE_LIST_SIZE 20
2019-01-31 14:20:20 +01:00
2015-02-12 12:37:29 +01:00
/*
* global options
*/
struct options
{
const char * server_name ; /* hostname of the server (client only) */
const char * server_addr ; /* address of the server (client only) */
2015-06-23 12:30:57 +02:00
const char * server_port ; /* port on which the ssl service runs */
2015-02-12 12:37:29 +01:00
int debug_level ; /* level of debugging */
int nbio ; /* should I/O be blocking? */
2017-10-10 16:56:37 +02:00
int event ; /* loop or event-driven IO? level or edge triggered? */
uint32_t read_timeout ; /* timeout on mbedtls_ssl_read() in milliseconds */
2015-02-16 19:37:53 +01:00
int max_resend ; /* DTLS times to resend on read timeout */
2015-02-12 12:37:29 +01:00
const char * request_page ; /* page on server to request */
int request_size ; /* pad request with header to requested size */
const char * ca_file ; /* the file with the CA certificate(s) */
const char * ca_path ; /* the path with the CA certificate(s) reside */
const char * crt_file ; /* the file with the client certificate */
const char * key_file ; /* the file with the client key */
2018-11-07 09:42:35 +01:00
int key_opaque ; /* handle private key as if it were opaque */
2018-10-23 12:37:50 +02:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
2018-11-15 14:06:09 +01:00
int psk_opaque ;
2019-03-27 16:55:27 +01:00
# endif
# if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
2019-03-28 15:14:22 +01:00
int ca_callback ; /* Use callback for trusted certificate list */
2018-10-23 12:37:50 +02:00
# endif
2015-02-12 12:37:29 +01:00
const char * psk ; /* the pre-shared key */
const char * psk_identity ; /* the pre-shared key identity */
2015-09-16 11:08:34 +02:00
const char * ecjpake_pw ; /* the EC J-PAKE password */
2017-05-16 08:50:24 +02:00
int ec_max_ops ; /* EC consecutive operations limit */
2015-02-12 12:37:29 +01:00
int force_ciphersuite [ 2 ] ; /* protocol/ciphersuite to use, or all */
int renegotiation ; /* enable / disable renegotiation */
int allow_legacy ; /* allow legacy renegotiation */
int renegotiate ; /* attempt renegotiation? */
int renego_delay ; /* delay before enforcing renegotiation */
int exchanges ; /* number of data exchanges */
int min_version ; /* minimum protocol version accepted */
int max_version ; /* maximum protocol version accepted */
int arc4 ; /* flag for arc4 suites support */
2017-05-09 15:59:24 +02:00
int allow_sha1 ; /* flag for SHA-1 support */
2015-02-12 12:37:29 +01:00
int auth_mode ; /* verify mode for connection */
unsigned char mfl_code ; /* code for maximum fragment length */
int trunc_hmac ; /* negotiate truncated hmac or not */
int recsplit ; /* enable record splitting? */
2015-06-11 17:02:29 +02:00
int dhmlen ; /* minimum DHM params len in bits */
2015-02-12 12:37:29 +01:00
int reconnect ; /* attempt to resume session */
int reco_delay ; /* delay in seconds before resuming session */
2019-05-20 12:46:26 +02:00
int reco_mode ; /* how to keep the session around */
2015-09-04 10:20:17 +02:00
int reconnect_hard ; /* unexpectedly reconnect from the same port */
2015-02-12 12:37:29 +01:00
int tickets ; /* enable / disable session tickets */
2017-05-15 17:05:15 +02:00
const char * curves ; /* list of supported elliptic curves */
2015-02-12 12:37:29 +01:00
const char * alpn_string ; /* ALPN supported protocols */
2015-02-16 19:37:53 +01:00
int transport ; /* TLS or DTLS? */
uint32_t hs_to_min ; /* Initial value of DTLS handshake timer */
uint32_t hs_to_max ; /* Max value of DTLS handshake timer */
2018-08-12 13:28:53 +02:00
int dtls_mtu ; /* UDP Maximum tranport unit for DTLS */
2015-02-12 12:37:29 +01:00
int fallback ; /* is this a fallback connection? */
2018-08-14 14:33:30 +02:00
int dgram_packing ; /* allow/forbid datagram packing */
2015-02-12 12:37:29 +01:00
int extended_ms ; /* negotiate extended master secret? */
int etm ; /* negotiate encrypt then mac? */
2019-04-03 13:59:58 +02:00
int context_crt_cb ; /* use context-specific CRT verify callback */
2019-05-12 10:03:32 +02:00
int eap_tls ; /* derive EAP-TLS keying material? */
2019-08-29 07:31:22 +02:00
int nss_keylog ; /* export NSS key log material */
const char * nss_keylog_file ; /* NSS key log file */
2019-04-09 18:24:19 +02:00
int cid_enabled ; /* whether to use the CID extension or not */
2019-05-03 18:30:59 +02:00
int cid_enabled_renego ; /* whether to use the CID extension or not
* during renegotiation */
2019-04-09 18:24:19 +02:00
const char * cid_val ; /* the CID to use for incoming messages */
2019-05-29 12:33:32 +02:00
int serialize ; /* serialize/deserialize connection */
2020-04-16 14:35:19 +02:00
const char * context_file ; /* the file to write a serialized connection
* in the form of base64 code ( serialize
* option must be set ) */
2019-05-03 18:30:59 +02:00
const char * cid_val_renego ; /* the CID to use for incoming messages
* after renegotiation */
2019-06-11 17:50:23 +02:00
int reproducible ; /* make communication reproducible */
Fix possible close_notify/ClientHello confusion
The ssl-opt.sh test cases using session resumption tend to fail occasionally
on the CI due to a race condition in how ssl_server2 and ssl_client2 handle
the reconnection cycle.
The server does the following in order:
- S1 send application data
- S2 send a close_notify alert
- S3 close the client socket
- S4 wait for a "new connection" (actually a new datagram)
- S5 start a handshake
The client does the following in order:
- C1 wait for and read application data from the server
- C2 send a close_notify alert
- C3 close the server socket
- C4 reset session data and re-open a server socket
- C5 start a handshake
If the client has been able to send the close_notify (C2) and if has been
delivered to the server before if closes the client socket (S3), when the
server reaches S4, the datagram that we start the new connection will be the
ClientHello and everything will be fine.
However if S3 wins the race and happens before the close_notify is delivered,
in S4 the close_notify is what will be seen as the first datagram in a new
connection, and then in S5 this will rightfully be rejected as not being a
valid ClientHello and the server will close the connection (and go wait for
another one). The client will then fail to read from the socket and exit
non-zero and the ssl-opt.sh harness will correctly report this as a failure.
In order to avoid this race condition in test using ssl_client2 and
ssl_server2, this commits introduces a new command-line option
skip_close_notify to ssl_client2 and uses it in all ssl-opt.sh tests that use
session resumption with DTLS and ssl_server2.
This works because ssl_server2 knows how many messages it expects in each
direction and in what order, and closes the connection after that rather than
relying on close_notify (which is also why there was a race in the first
place).
Tests that use another server (in practice there are two of them, using
OpenSSL as a server) wouldn't work with skip_close_notify, as the server won't
close the connection until the client sends a close_notify, but for the same
reason they don't need it (there is no race between receiving close_notify and
closing as the former is the cause of the later).
An alternative approach would be to make ssl_server2 keep the connection open
until it receives a close_notify. Unfortunately it creates problems for tests
where we simulate a lossy network, as the close_notify could be lost (and the
client can't retransmit it). We could modify udp_proxy with an option to never
drop alert messages, but when TLS 1.3 comes that would no longer work as the
type of messages will be encrypted.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2020-02-17 11:04:33 +01:00
int skip_close_notify ; /* skip sending the close_notify alert */
2015-02-12 12:37:29 +01:00
} opt ;
2018-10-16 22:08:38 +02:00
int query_config ( const char * config ) ;
2019-05-12 10:03:32 +02:00
# if defined(MBEDTLS_SSL_EXPORT_KEYS)
typedef struct eap_tls_keys
{
unsigned char master_secret [ 48 ] ;
unsigned char randbytes [ 64 ] ;
2019-05-12 13:54:30 +02:00
mbedtls_tls_prf_types tls_prf_type ;
2019-05-12 10:03:32 +02:00
} eap_tls_keys ;
static int eap_tls_key_derivation ( void * p_expkey ,
const unsigned char * ms ,
const unsigned char * kb ,
size_t maclen ,
size_t keylen ,
size_t ivlen ,
2019-09-12 11:09:57 +02:00
const unsigned char client_random [ 32 ] ,
const unsigned char server_random [ 32 ] ,
2019-05-12 13:54:30 +02:00
mbedtls_tls_prf_types tls_prf_type )
2019-05-12 10:03:32 +02:00
{
eap_tls_keys * keys = ( eap_tls_keys * ) p_expkey ;
( ( void ) kb ) ;
memcpy ( keys - > master_secret , ms , sizeof ( keys - > master_secret ) ) ;
memcpy ( keys - > randbytes , client_random , 32 ) ;
memcpy ( keys - > randbytes + 32 , server_random , 32 ) ;
2019-05-12 13:54:30 +02:00
keys - > tls_prf_type = tls_prf_type ;
2019-05-12 10:03:32 +02:00
2019-05-14 19:38:49 +02:00
if ( opt . debug_level > 2 )
{
2019-05-15 16:45:24 +02:00
mbedtls_printf ( " exported maclen is %u \n " , ( unsigned ) maclen ) ;
mbedtls_printf ( " exported keylen is %u \n " , ( unsigned ) keylen ) ;
mbedtls_printf ( " exported ivlen is %u \n " , ( unsigned ) ivlen ) ;
2019-05-14 19:38:49 +02:00
}
2019-05-12 10:03:32 +02:00
return ( 0 ) ;
}
2019-08-29 07:31:22 +02:00
static int nss_keylog_export ( void * p_expkey ,
const unsigned char * ms ,
const unsigned char * kb ,
size_t maclen ,
size_t keylen ,
size_t ivlen ,
2019-09-12 11:09:57 +02:00
const unsigned char client_random [ 32 ] ,
const unsigned char server_random [ 32 ] ,
2019-08-29 07:31:22 +02:00
mbedtls_tls_prf_types tls_prf_type )
{
char nss_keylog_line [ 200 ] ;
size_t const client_random_len = 32 ;
size_t const master_secret_len = 48 ;
size_t len = 0 ;
size_t j ;
int ret = 0 ;
( ( void ) p_expkey ) ;
( ( void ) kb ) ;
( ( void ) maclen ) ;
( ( void ) keylen ) ;
( ( void ) ivlen ) ;
( ( void ) server_random ) ;
( ( void ) tls_prf_type ) ;
len + = sprintf ( nss_keylog_line + len ,
" %s " , " CLIENT_RANDOM " ) ;
for ( j = 0 ; j < client_random_len ; j + + )
{
len + = sprintf ( nss_keylog_line + len ,
" %02x " , client_random [ j ] ) ;
}
len + = sprintf ( nss_keylog_line + len , " " ) ;
for ( j = 0 ; j < master_secret_len ; j + + )
{
len + = sprintf ( nss_keylog_line + len ,
" %02x " , ms [ j ] ) ;
}
len + = sprintf ( nss_keylog_line + len , " \n " ) ;
nss_keylog_line [ len ] = ' \0 ' ;
mbedtls_printf ( " \n " ) ;
mbedtls_printf ( " ---------------- NSS KEYLOG ----------------- \n " ) ;
mbedtls_printf ( " %s " , nss_keylog_line ) ;
mbedtls_printf ( " --------------------------------------------- \n " ) ;
if ( opt . nss_keylog_file ! = NULL )
{
FILE * f ;
if ( ( f = fopen ( opt . nss_keylog_file , " a " ) ) = = NULL )
{
ret = - 1 ;
goto exit ;
}
if ( fwrite ( nss_keylog_line , 1 , len , f ) ! = len )
{
ret = - 1 ;
2020-01-21 17:39:52 +01:00
fclose ( f ) ;
2019-08-29 07:31:22 +02:00
goto exit ;
}
fclose ( f ) ;
}
exit :
mbedtls_platform_zeroize ( nss_keylog_line ,
sizeof ( nss_keylog_line ) ) ;
return ( ret ) ;
}
2019-05-12 10:03:32 +02:00
# endif
2015-06-23 17:35:03 +02:00
static void my_debug ( void * ctx , int level ,
const char * file , int line ,
const char * str )
2015-02-12 12:37:29 +01:00
{
2015-07-01 11:50:23 +02:00
const char * p , * basename ;
2015-02-12 12:37:29 +01:00
2015-07-01 11:50:23 +02:00
/* Extract basename from file */
for ( p = basename = file ; * p ! = ' \0 ' ; p + + )
if ( * p = = ' / ' | | * p = = ' \\ ' )
basename = p + 1 ;
2017-10-10 16:59:57 +02:00
mbedtls_fprintf ( ( FILE * ) ctx , " %s:%04d: |%d| %s " ,
basename , line , level , str ) ;
2015-02-12 12:37:29 +01:00
fflush ( ( FILE * ) ctx ) ;
}
2019-06-06 21:24:31 +02:00
mbedtls_time_t dummy_constant_time ( mbedtls_time_t * time )
{
( void ) time ;
return 0x5af2a056 ;
}
int dummy_entropy ( void * data , unsigned char * output , size_t len )
{
size_t i ;
2019-06-11 16:07:53 +02:00
int ret ;
2019-06-11 16:29:28 +02:00
( void ) data ;
2019-06-06 21:24:31 +02:00
2019-06-07 22:31:59 +02:00
ret = mbedtls_entropy_func ( data , output , len ) ;
2019-06-07 15:04:32 +02:00
for ( i = 0 ; i < len ; i + + )
{
2019-06-06 21:24:31 +02:00
//replace result with pseudo random
output [ i ] = ( unsigned char ) rand ( ) ;
}
2019-06-07 22:31:59 +02:00
return ( ret ) ;
2019-06-06 21:24:31 +02:00
}
2019-03-27 16:55:27 +01:00
# if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
2019-03-28 15:14:22 +01:00
int ca_callback ( void * data , mbedtls_x509_crt const * child ,
2019-04-05 15:52:17 +02:00
mbedtls_x509_crt * * candidates )
2019-03-27 16:55:27 +01:00
{
2019-03-28 15:14:22 +01:00
int ret = 0 ;
2019-03-27 16:55:27 +01:00
mbedtls_x509_crt * ca = ( mbedtls_x509_crt * ) data ;
2019-03-28 15:14:22 +01:00
mbedtls_x509_crt * first ;
/* This is a test-only implementation of the CA callback
* which always returns the entire list of trusted certificates .
* Production implementations managing a large number of CAs
* should use an efficient presentation and lookup for the
* set of trusted certificates ( such as a hashtable ) and only
* return those trusted certificates which satisfy basic
* parental checks , such as the matching of child ` Issuer `
2019-04-01 14:11:54 +02:00
* and parent ` Subject ` field or matching key identifiers . */
2019-03-28 15:14:22 +01:00
( ( void ) child ) ;
first = mbedtls_calloc ( 1 , sizeof ( mbedtls_x509_crt ) ) ;
if ( first = = NULL )
{
ret = - 1 ;
goto exit ;
}
mbedtls_x509_crt_init ( first ) ;
if ( mbedtls_x509_crt_parse_der ( first , ca - > raw . p , ca - > raw . len ) ! = 0 )
{
ret = - 1 ;
goto exit ;
}
2019-03-27 16:55:27 +01:00
while ( ca - > next ! = NULL )
{
ca = ca - > next ;
2019-03-28 15:14:22 +01:00
if ( mbedtls_x509_crt_parse_der ( first , ca - > raw . p , ca - > raw . len ) ! = 0 )
{
ret = - 1 ;
goto exit ;
}
2019-03-27 16:55:27 +01:00
}
2019-03-28 15:14:22 +01:00
exit :
if ( ret ! = 0 )
{
mbedtls_x509_crt_free ( first ) ;
mbedtls_free ( first ) ;
first = NULL ;
}
2019-03-27 16:55:27 +01:00
* candidates = first ;
2019-03-28 15:14:22 +01:00
return ( ret ) ;
2019-03-27 16:55:27 +01:00
}
# endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
2015-02-12 12:37:29 +01:00
/*
* Test recv / send functions that make sure each try returns
* WANT_READ / WANT_WRITE at least once before sucesseding
*/
2019-07-03 18:02:43 +02:00
static int delayed_recv ( void * ctx , unsigned char * buf , size_t len )
2015-02-12 12:37:29 +01:00
{
static int first_try = 1 ;
int ret ;
if ( first_try )
{
first_try = 0 ;
2015-05-06 17:19:31 +02:00
return ( MBEDTLS_ERR_SSL_WANT_READ ) ;
2015-02-12 12:37:29 +01:00
}
2015-04-08 12:49:31 +02:00
ret = mbedtls_net_recv ( ctx , buf , len ) ;
2015-05-06 17:19:31 +02:00
if ( ret ! = MBEDTLS_ERR_SSL_WANT_READ )
2015-02-12 12:37:29 +01:00
first_try = 1 ; /* Next call will be a new operation */
return ( ret ) ;
}
2019-07-03 18:02:43 +02:00
static int delayed_send ( void * ctx , const unsigned char * buf , size_t len )
2015-02-12 12:37:29 +01:00
{
static int first_try = 1 ;
int ret ;
if ( first_try )
{
first_try = 0 ;
2015-05-06 17:19:31 +02:00
return ( MBEDTLS_ERR_SSL_WANT_WRITE ) ;
2015-02-12 12:37:29 +01:00
}
2015-04-08 12:49:31 +02:00
ret = mbedtls_net_send ( ctx , buf , len ) ;
2015-05-06 17:19:31 +02:00
if ( ret ! = MBEDTLS_ERR_SSL_WANT_WRITE )
2015-02-12 12:37:29 +01:00
first_try = 1 ; /* Next call will be a new operation */
return ( ret ) ;
}
2019-07-03 18:02:43 +02:00
typedef struct
{
mbedtls_ssl_context * ssl ;
mbedtls_net_context * net ;
} io_ctx_t ;
2019-07-03 18:14:41 +02:00
# if defined(MBEDTLS_SSL_RECORD_CHECKING)
static int ssl_check_record ( mbedtls_ssl_context const * ssl ,
unsigned char const * buf , size_t len )
{
int ret ;
unsigned char * tmp_buf ;
tmp_buf = mbedtls_calloc ( 1 , len ) ;
if ( tmp_buf = = NULL )
return ( MBEDTLS_ERR_SSL_ALLOC_FAILED ) ;
memcpy ( tmp_buf , buf , len ) ;
ret = mbedtls_ssl_check_record ( ssl , tmp_buf , len ) ;
if ( ret ! = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE )
{
int ret_repeated ;
/* Test-only: Make sure that mbedtls_ssl_check_record()
* doesn ' t alter state . */
memcpy ( tmp_buf , buf , len ) ; /* Restore buffer */
ret_repeated = mbedtls_ssl_check_record ( ssl , tmp_buf , len ) ;
if ( ret ! = ret_repeated )
{
2019-07-24 14:59:07 +02:00
mbedtls_printf ( " mbedtls_ssl_check_record() returned inconsistent results. \n " ) ;
return ( - 1 ) ;
2019-07-03 18:14:41 +02:00
}
switch ( ret )
{
case 0 :
break ;
case MBEDTLS_ERR_SSL_INVALID_RECORD :
if ( opt . debug_level > 1 )
mbedtls_printf ( " mbedtls_ssl_check_record() detected invalid record. \n " ) ;
break ;
case MBEDTLS_ERR_SSL_INVALID_MAC :
if ( opt . debug_level > 1 )
mbedtls_printf ( " mbedtls_ssl_check_record() detected unauthentic record. \n " ) ;
break ;
case MBEDTLS_ERR_SSL_UNEXPECTED_RECORD :
if ( opt . debug_level > 1 )
mbedtls_printf ( " mbedtls_ssl_check_record() detected unexpected record. \n " ) ;
break ;
default :
mbedtls_printf ( " mbedtls_ssl_check_record() failed fatally with -%#04x. \n " , - ret ) ;
return ( - 1 ) ;
}
/* Regardless of the outcome, forward the record to the stack. */
}
mbedtls_free ( tmp_buf ) ;
return ( 0 ) ;
}
# endif /* MBEDTLS_SSL_RECORD_CHECKING */
2019-07-03 18:02:43 +02:00
static int recv_cb ( void * ctx , unsigned char * buf , size_t len )
{
io_ctx_t * io_ctx = ( io_ctx_t * ) ctx ;
size_t recv_len ;
int ret ;
if ( opt . nbio = = 2 )
ret = delayed_recv ( io_ctx - > net , buf , len ) ;
else
ret = mbedtls_net_recv ( io_ctx - > net , buf , len ) ;
if ( ret < 0 )
return ( ret ) ;
recv_len = ( size_t ) ret ;
if ( opt . transport = = MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
/* Here's the place to do any datagram/record checking
* in between receiving the packet from the underlying
* transport and passing it on to the TLS stack . */
2019-07-03 18:14:41 +02:00
# if defined(MBEDTLS_SSL_RECORD_CHECKING)
if ( ssl_check_record ( io_ctx - > ssl , buf , recv_len ) ! = 0 )
return ( - 1 ) ;
# endif /* MBEDTLS_SSL_RECORD_CHECKING */
2019-07-03 18:02:43 +02:00
}
return ( ( int ) recv_len ) ;
}
static int recv_timeout_cb ( void * ctx , unsigned char * buf , size_t len ,
uint32_t timeout )
{
io_ctx_t * io_ctx = ( io_ctx_t * ) ctx ;
int ret ;
size_t recv_len ;
ret = mbedtls_net_recv_timeout ( io_ctx - > net , buf , len , timeout ) ;
if ( ret < 0 )
return ( ret ) ;
recv_len = ( size_t ) ret ;
if ( opt . transport = = MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
/* Here's the place to do any datagram/record checking
* in between receiving the packet from the underlying
* transport and passing it on to the TLS stack . */
2019-07-03 18:14:41 +02:00
# if defined(MBEDTLS_SSL_RECORD_CHECKING)
if ( ssl_check_record ( io_ctx - > ssl , buf , recv_len ) ! = 0 )
return ( - 1 ) ;
# endif /* MBEDTLS_SSL_RECORD_CHECKING */
2019-07-03 18:02:43 +02:00
}
return ( ( int ) recv_len ) ;
}
static int send_cb ( void * ctx , unsigned char const * buf , size_t len )
{
io_ctx_t * io_ctx = ( io_ctx_t * ) ctx ;
if ( opt . nbio = = 2 )
return ( delayed_send ( io_ctx - > net , buf , len ) ) ;
return ( mbedtls_net_send ( io_ctx - > net , buf , len ) ) ;
}
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
2019-02-26 12:38:29 +01:00
static unsigned char peer_crt_info [ 1024 ] ;
2019-02-25 18:43:18 +01:00
2015-02-12 12:37:29 +01:00
/*
* Enabled if debug_level > 1 in code below
*/
2017-10-10 16:59:57 +02:00
static int my_verify ( void * data , mbedtls_x509_crt * crt ,
int depth , uint32_t * flags )
2015-02-12 12:37:29 +01:00
{
char buf [ 1024 ] ;
( ( void ) data ) ;
2015-04-08 12:49:31 +02:00
mbedtls_x509_crt_info ( buf , sizeof ( buf ) - 1 , " " , crt ) ;
2019-02-25 18:43:18 +01:00
if ( depth = = 0 )
memcpy ( peer_crt_info , buf , sizeof ( buf ) ) ;
if ( opt . debug_level = = 0 )
return ( 0 ) ;
mbedtls_printf ( " \n Verify requested for (Depth %d): \n " , depth ) ;
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " %s " , buf ) ;
2015-02-12 12:37:29 +01:00
if ( ( * flags ) = = 0 )
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " This certificate has no flags \n " ) ;
2015-04-20 11:56:18 +02:00
else
{
mbedtls_x509_crt_verify_info ( buf , sizeof ( buf ) , " ! " , * flags ) ;
mbedtls_printf ( " %s \n " , buf ) ;
}
2015-02-12 12:37:29 +01:00
return ( 0 ) ;
}
2017-05-09 14:57:45 +02:00
static int ssl_sig_hashes_for_test [ ] = {
# if defined(MBEDTLS_SHA512_C)
MBEDTLS_MD_SHA512 ,
MBEDTLS_MD_SHA384 ,
# endif
# if defined(MBEDTLS_SHA256_C)
MBEDTLS_MD_SHA256 ,
MBEDTLS_MD_SHA224 ,
# endif
# if defined(MBEDTLS_SHA1_C)
/* Allow SHA-1 as we use it extensively in tests. */
MBEDTLS_MD_SHA1 ,
# endif
MBEDTLS_MD_NONE
} ;
2015-04-08 12:49:31 +02:00
# endif /* MBEDTLS_X509_CRT_PARSE_C */
2015-02-12 12:37:29 +01:00
2017-10-10 16:56:37 +02:00
/*
* Wait for an event from the underlying transport or the timer
* ( Used in event - driven IO mode ) .
*/
# if !defined(MBEDTLS_TIMING_C)
2018-03-15 12:35:07 +01:00
int idle ( mbedtls_net_context * fd ,
2018-03-15 13:21:15 +01:00
int idle_reason )
2017-10-10 16:56:37 +02:00
# else
2018-03-15 12:35:07 +01:00
int idle ( mbedtls_net_context * fd ,
2018-03-15 13:21:15 +01:00
mbedtls_timing_delay_context * timer ,
int idle_reason )
2017-10-10 16:56:37 +02:00
# endif
2018-03-15 13:21:15 +01:00
{
2017-10-10 16:56:37 +02:00
2018-03-15 12:35:07 +01:00
int ret ;
2017-10-10 16:56:37 +02:00
int poll_type = 0 ;
if ( idle_reason = = MBEDTLS_ERR_SSL_WANT_WRITE )
poll_type = MBEDTLS_NET_POLL_WRITE ;
else if ( idle_reason = = MBEDTLS_ERR_SSL_WANT_READ )
poll_type = MBEDTLS_NET_POLL_READ ;
# if !defined(MBEDTLS_TIMING_C)
else
2018-03-15 16:49:24 +01:00
return ( 0 ) ;
2017-10-10 16:56:37 +02:00
# endif
while ( 1 )
{
2017-10-31 11:58:53 +01:00
/* Check if timer has expired */
2017-10-10 16:56:37 +02:00
# if defined(MBEDTLS_TIMING_C)
2017-10-31 11:58:53 +01:00
if ( timer ! = NULL & &
mbedtls_timing_get_delay ( timer ) = = 2 )
2017-10-10 16:56:37 +02:00
{
break ;
}
2017-10-31 11:58:53 +01:00
# endif /* MBEDTLS_TIMING_C */
2017-10-10 16:56:37 +02:00
2017-10-31 11:58:53 +01:00
/* Check if underlying transport became available */
2018-03-15 12:35:07 +01:00
if ( poll_type ! = 0 )
2017-10-10 16:56:37 +02:00
{
2018-03-15 12:35:07 +01:00
ret = mbedtls_net_poll ( fd , poll_type , 0 ) ;
if ( ret < 0 )
return ( ret ) ;
if ( ret = = poll_type )
break ;
2017-10-10 16:56:37 +02:00
}
}
2018-03-15 12:35:07 +01:00
return ( 0 ) ;
2017-10-10 16:56:37 +02:00
}
2019-04-09 18:12:56 +02:00
/* Unhexify `hex` into `dst`. `dst` must have
* size at least ` strlen ( hex ) / 2 ` . */
2019-04-09 18:24:19 +02:00
int unhexify ( char const * hex , unsigned char * dst )
2019-04-09 18:12:56 +02:00
{
unsigned char c ;
size_t j ;
size_t len = strlen ( hex ) ;
if ( len % 2 ! = 0 )
return ( - 1 ) ;
for ( j = 0 ; j < len ; j + = 2 )
{
c = hex [ j ] ;
if ( c > = ' 0 ' & & c < = ' 9 ' )
c - = ' 0 ' ;
else if ( c > = ' a ' & & c < = ' f ' )
c - = ' a ' - 10 ;
else if ( c > = ' A ' & & c < = ' F ' )
c - = ' A ' - 10 ;
else
return ( - 1 ) ;
dst [ j / 2 ] = c < < 4 ;
c = hex [ j + 1 ] ;
if ( c > = ' 0 ' & & c < = ' 9 ' )
c - = ' 0 ' ;
else if ( c > = ' a ' & & c < = ' f ' )
c - = ' a ' - 10 ;
else if ( c > = ' A ' & & c < = ' F ' )
c - = ' A ' - 10 ;
else
return ( - 1 ) ;
dst [ j / 2 ] | = c ;
}
return ( 0 ) ;
}
2019-05-15 15:03:01 +02:00
# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2019-05-03 18:30:59 +02:00
int report_cid_usage ( mbedtls_ssl_context * ssl ,
const char * additional_description )
{
int ret ;
unsigned char peer_cid [ MBEDTLS_SSL_CID_OUT_LEN_MAX ] ;
size_t peer_cid_len ;
int cid_negotiated ;
if ( opt . transport ! = MBEDTLS_SSL_TRANSPORT_DATAGRAM )
return ( 0 ) ;
2019-05-22 17:59:25 +02:00
/* Check if the use of a CID has been negotiated,
* but don ' t ask for the CID value and length .
*
* Note : Here and below , we ' re demonstrating the various ways
* in which mbedtls_ssl_get_peer_cid ( ) can be called ,
* depending on whether or not the length / value of the
* peer ' s CID is needed .
*
* An actual application , however , should use
* just one call to mbedtls_ssl_get_peer_cid ( ) . */
2019-05-03 18:30:59 +02:00
ret = mbedtls_ssl_get_peer_cid ( ssl , & cid_negotiated ,
2019-05-22 17:59:25 +02:00
NULL , NULL ) ;
2019-05-03 18:30:59 +02:00
if ( ret ! = 0 )
{
mbedtls_printf ( " failed \n ! mbedtls_ssl_get_peer_cid returned -0x%x \n \n " ,
- ret ) ;
return ( ret ) ;
}
if ( cid_negotiated = = MBEDTLS_SSL_CID_DISABLED )
{
if ( opt . cid_enabled = = MBEDTLS_SSL_CID_ENABLED )
{
mbedtls_printf ( " (%s) Use of Connection ID was rejected by the server. \n " ,
additional_description ) ;
}
}
else
{
size_t idx = 0 ;
mbedtls_printf ( " (%s) Use of Connection ID has been negotiated. \n " ,
additional_description ) ;
2019-05-22 17:59:25 +02:00
/* Ask for just the length of the peer's CID. */
ret = mbedtls_ssl_get_peer_cid ( ssl , & cid_negotiated ,
NULL , & peer_cid_len ) ;
if ( ret ! = 0 )
{
mbedtls_printf ( " failed \n ! mbedtls_ssl_get_peer_cid returned -0x%x \n \n " ,
- ret ) ;
return ( ret ) ;
}
/* Ask for just length + value of the peer's CID. */
ret = mbedtls_ssl_get_peer_cid ( ssl , & cid_negotiated ,
peer_cid , & peer_cid_len ) ;
if ( ret ! = 0 )
{
mbedtls_printf ( " failed \n ! mbedtls_ssl_get_peer_cid returned -0x%x \n \n " ,
- ret ) ;
return ( ret ) ;
}
2019-05-03 18:30:59 +02:00
mbedtls_printf ( " (%s) Peer CID (length %u Bytes): " ,
additional_description ,
( unsigned ) peer_cid_len ) ;
while ( idx < peer_cid_len )
{
mbedtls_printf ( " %02x " , peer_cid [ idx ] ) ;
idx + + ;
}
mbedtls_printf ( " \n " ) ;
}
return ( 0 ) ;
}
2019-05-15 15:03:01 +02:00
# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2019-05-03 18:30:59 +02:00
2010-02-18 20:37:19 +01:00
int main ( int argc , char * argv [ ] )
2009-01-03 22:22:43 +01:00
{
2015-06-30 15:40:39 +02:00
int ret = 0 , len , tail_len , i , written , frags , retry_left ;
mbedtls_net_context server_fd ;
2019-07-03 18:02:43 +02:00
io_ctx_t io_ctx ;
2017-09-18 16:05:46 +02:00
unsigned char buf [ MAX_REQUEST_SIZE + 1 ] ;
2020-03-10 12:19:08 +01:00
# if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
2015-04-08 12:49:31 +02:00
unsigned char psk [ MBEDTLS_PSK_MAX_LEN ] ;
2013-04-16 18:05:29 +02:00
size_t psk_len = 0 ;
2014-04-05 14:34:07 +02:00
# endif
2019-04-09 18:24:19 +02:00
2019-05-15 15:03:01 +02:00
# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2019-04-09 18:24:19 +02:00
unsigned char cid [ MBEDTLS_SSL_CID_IN_LEN_MAX ] ;
2019-05-03 18:30:59 +02:00
unsigned char cid_renego [ MBEDTLS_SSL_CID_IN_LEN_MAX ] ;
2019-04-09 18:24:19 +02:00
size_t cid_len = 0 ;
2019-05-03 18:30:59 +02:00
size_t cid_renego_len = 0 ;
2019-04-09 18:24:19 +02:00
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_ALPN)
2017-06-09 17:13:22 +02:00
const char * alpn_list [ ALPN_LIST_SIZE ] ;
2013-04-18 22:46:23 +02:00
# endif
2019-11-20 15:00:17 +01:00
# if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
unsigned char alloc_buf [ MEMORY_HEAP_SIZE ] ;
# endif
2017-05-15 17:05:15 +02:00
# if defined(MBEDTLS_ECP_C)
2017-06-09 17:13:22 +02:00
mbedtls_ecp_group_id curve_list [ CURVE_LIST_SIZE ] ;
2017-05-15 17:05:15 +02:00
const mbedtls_ecp_curve_info * curve_cur ;
# endif
2013-06-24 13:01:08 +02:00
const char * pers = " ssl_client2 " ;
2011-12-04 18:09:26 +01:00
2018-10-23 12:37:50 +02:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
2019-01-08 15:36:01 +01:00
psa_key_handle_t slot = 0 ;
2018-10-23 12:37:50 +02:00
psa_algorithm_t alg = 0 ;
2019-08-08 12:38:18 +02:00
psa_key_attributes_t key_attributes ;
2018-10-23 12:37:50 +02:00
psa_status_t status ;
# endif
2017-05-05 18:59:02 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default ;
# endif
2015-04-08 12:49:31 +02:00
mbedtls_entropy_context entropy ;
mbedtls_ctr_drbg_context ctr_drbg ;
mbedtls_ssl_context ssl ;
2015-05-04 14:56:36 +02:00
mbedtls_ssl_config conf ;
2015-04-08 12:49:31 +02:00
mbedtls_ssl_session saved_session ;
2019-05-21 11:01:32 +02:00
unsigned char * session_data = NULL ;
size_t session_data_len = 0 ;
2015-05-13 13:58:56 +02:00
# if defined(MBEDTLS_TIMING_C)
2015-05-13 10:04:32 +02:00
mbedtls_timing_delay_context timer ;
2015-05-13 13:58:56 +02:00
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
2015-05-12 11:27:25 +02:00
uint32_t flags ;
2015-04-08 12:49:31 +02:00
mbedtls_x509_crt cacert ;
mbedtls_x509_crt clicert ;
mbedtls_pk_context pkey ;
2018-11-08 09:52:25 +01:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
2019-01-08 15:36:01 +01:00
psa_key_handle_t key_slot = 0 ; /* invalid key slot */
2018-11-08 09:52:25 +01:00
# endif
2013-04-18 22:46:23 +02:00
# endif
2010-02-18 20:37:19 +01:00
char * p , * q ;
2011-02-20 17:05:58 +01:00
const int * list ;
2019-07-15 10:31:11 +02:00
# if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
unsigned char * context_buf = NULL ;
size_t context_buf_len ;
# endif
2019-05-12 10:03:32 +02:00
# if defined(MBEDTLS_SSL_EXPORT_KEYS)
unsigned char eap_tls_keymaterial [ 16 ] ;
unsigned char eap_tls_iv [ 8 ] ;
const char * eap_tls_label = " client EAP encryption " ;
eap_tls_keys eap_tls_keying ;
# endif
2010-02-18 20:37:19 +01:00
2019-11-20 15:00:17 +01:00
# if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
mbedtls_memory_buffer_alloc_init ( alloc_buf , sizeof ( alloc_buf ) ) ;
# endif
2011-02-06 14:22:40 +01:00
/*
* Make sure memory references are valid .
*/
2015-06-30 15:40:39 +02:00
mbedtls_net_init ( & server_fd ) ;
2015-04-29 00:48:22 +02:00
mbedtls_ssl_init ( & ssl ) ;
2015-05-04 14:56:36 +02:00
mbedtls_ssl_config_init ( & conf ) ;
2015-04-08 12:49:31 +02:00
memset ( & saved_session , 0 , sizeof ( mbedtls_ssl_session ) ) ;
2015-04-28 22:52:30 +02:00
mbedtls_ctr_drbg_init ( & ctr_drbg ) ;
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_init ( & cacert ) ;
mbedtls_x509_crt_init ( & clicert ) ;
mbedtls_pk_init ( & pkey ) ;
2013-04-18 22:46:23 +02:00
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_ALPN)
2014-05-01 10:58:57 +02:00
memset ( ( void * ) alpn_list , 0 , sizeof ( alpn_list ) ) ;
2014-04-05 14:34:07 +02:00
# endif
2011-02-06 14:22:40 +01:00
2018-11-12 18:46:59 +01:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
status = psa_crypto_init ( ) ;
if ( status ! = PSA_SUCCESS )
{
mbedtls_fprintf ( stderr , " Failed to initialize PSA Crypto implementation: %d \n " ,
( int ) status ) ;
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ;
goto exit ;
}
# endif
2010-02-18 20:37:19 +01:00
if ( argc = = 0 )
{
usage :
2012-02-06 17:45:10 +01:00
if ( ret = = 0 )
ret = 1 ;
2015-04-08 12:49:31 +02:00
mbedtls_printf ( USAGE ) ;
2011-02-20 17:05:58 +01:00
2015-04-08 12:49:31 +02:00
list = mbedtls_ssl_list_ciphersuites ( ) ;
2011-02-20 17:05:58 +01:00
while ( * list )
{
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " %-42s " , mbedtls_ssl_get_ciphersuite_name ( * list ) ) ;
2013-04-18 22:46:23 +02:00
list + + ;
if ( ! * list )
break ;
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " %s \n " , mbedtls_ssl_get_ciphersuite_name ( * list ) ) ;
2011-02-20 17:05:58 +01:00
list + + ;
}
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " \n " ) ;
2010-02-18 20:37:19 +01:00
goto exit ;
}
opt . server_name = DFL_SERVER_NAME ;
2014-02-25 11:11:26 +01:00
opt . server_addr = DFL_SERVER_ADDR ;
2010-02-18 20:37:19 +01:00
opt . server_port = DFL_SERVER_PORT ;
opt . debug_level = DFL_DEBUG_LEVEL ;
2019-04-09 18:24:19 +02:00
opt . cid_enabled = DFL_CID_ENABLED ;
opt . cid_val = DFL_CID_VALUE ;
2019-05-03 18:30:59 +02:00
opt . cid_enabled_renego = DFL_CID_ENABLED_RENEGO ;
opt . cid_val_renego = DFL_CID_VALUE_RENEGO ;
2014-02-26 13:47:08 +01:00
opt . nbio = DFL_NBIO ;
2017-10-10 16:56:37 +02:00
opt . event = DFL_EVENT ;
2019-04-03 13:59:58 +02:00
opt . context_crt_cb = DFL_CONTEXT_CRT_CB ;
2014-10-01 18:29:03 +02:00
opt . read_timeout = DFL_READ_TIMEOUT ;
2014-10-02 14:02:32 +02:00
opt . max_resend = DFL_MAX_RESEND ;
2010-02-18 20:37:19 +01:00
opt . request_page = DFL_REQUEST_PAGE ;
2014-04-25 13:40:05 +02:00
opt . request_size = DFL_REQUEST_SIZE ;
2011-05-26 15:16:06 +02:00
opt . ca_file = DFL_CA_FILE ;
2012-06-04 14:46:42 +02:00
opt . ca_path = DFL_CA_PATH ;
2010-07-18 10:28:20 +02:00
opt . crt_file = DFL_CRT_FILE ;
opt . key_file = DFL_KEY_FILE ;
2018-11-07 09:42:35 +01:00
opt . key_opaque = DFL_KEY_OPAQUE ;
2013-04-16 18:05:29 +02:00
opt . psk = DFL_PSK ;
2018-10-23 12:37:50 +02:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
2018-11-15 14:06:09 +01:00
opt . psk_opaque = DFL_PSK_OPAQUE ;
2019-03-27 16:55:27 +01:00
# endif
# if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
opt . ca_callback = DFL_CA_CALLBACK ;
2018-10-23 12:37:50 +02:00
# endif
2013-04-16 18:05:29 +02:00
opt . psk_identity = DFL_PSK_IDENTITY ;
2015-09-16 11:08:34 +02:00
opt . ecjpake_pw = DFL_ECJPAKE_PW ;
2017-05-16 08:50:24 +02:00
opt . ec_max_ops = DFL_EC_MAX_OPS ;
2011-02-20 17:05:58 +01:00
opt . force_ciphersuite [ 0 ] = DFL_FORCE_CIPHER ;
2012-09-16 21:57:18 +02:00
opt . renegotiation = DFL_RENEGOTIATION ;
opt . allow_legacy = DFL_ALLOW_LEGACY ;
2014-02-20 17:19:59 +01:00
opt . renegotiate = DFL_RENEGOTIATE ;
2014-08-15 12:07:38 +02:00
opt . exchanges = DFL_EXCHANGES ;
2012-09-28 15:28:45 +02:00
opt . min_version = DFL_MIN_VERSION ;
opt . max_version = DFL_MAX_VERSION ;
2015-01-12 13:43:29 +01:00
opt . arc4 = DFL_ARC4 ;
2017-05-09 15:59:24 +02:00
opt . allow_sha1 = DFL_SHA1 ;
2012-11-23 14:04:08 +01:00
opt . auth_mode = DFL_AUTH_MODE ;
2013-07-16 13:39:57 +02:00
opt . mfl_code = DFL_MFL_CODE ;
2013-07-19 11:08:52 +02:00
opt . trunc_hmac = DFL_TRUNC_HMAC ;
2015-01-07 16:35:25 +01:00
opt . recsplit = DFL_RECSPLIT ;
2015-06-11 17:02:29 +02:00
opt . dhmlen = DFL_DHMLEN ;
2013-07-30 13:43:43 +02:00
opt . reconnect = DFL_RECONNECT ;
2014-02-20 22:50:56 +01:00
opt . reco_delay = DFL_RECO_DELAY ;
2019-05-20 12:46:26 +02:00
opt . reco_mode = DFL_RECO_MODE ;
2015-09-04 10:20:17 +02:00
opt . reconnect_hard = DFL_RECONNECT_HARD ;
2013-08-03 13:02:31 +02:00
opt . tickets = DFL_TICKETS ;
2014-04-05 14:34:07 +02:00
opt . alpn_string = DFL_ALPN_STRING ;
2017-05-15 17:05:15 +02:00
opt . curves = DFL_CURVES ;
2014-10-01 14:40:56 +02:00
opt . transport = DFL_TRANSPORT ;
opt . hs_to_min = DFL_HS_TO_MIN ;
opt . hs_to_max = DFL_HS_TO_MAX ;
2018-08-12 13:28:53 +02:00
opt . dtls_mtu = DFL_DTLS_MTU ;
2014-10-20 13:34:59 +02:00
opt . fallback = DFL_FALLBACK ;
2014-10-20 18:40:56 +02:00
opt . extended_ms = DFL_EXTENDED_MS ;
2014-10-27 13:57:03 +01:00
opt . etm = DFL_ETM ;
2018-08-14 14:33:30 +02:00
opt . dgram_packing = DFL_DGRAM_PACKING ;
2019-05-29 12:33:32 +02:00
opt . serialize = DFL_SERIALIZE ;
2020-04-16 14:35:19 +02:00
opt . context_file = DFL_CONTEXT_FILE ;
2019-05-12 10:03:32 +02:00
opt . eap_tls = DFL_EAP_TLS ;
2019-06-06 21:24:31 +02:00
opt . reproducible = DFL_REPRODUCIBLE ;
2019-08-29 07:31:22 +02:00
opt . nss_keylog = DFL_NSS_KEYLOG ;
opt . nss_keylog_file = DFL_NSS_KEYLOG_FILE ;
Fix possible close_notify/ClientHello confusion
The ssl-opt.sh test cases using session resumption tend to fail occasionally
on the CI due to a race condition in how ssl_server2 and ssl_client2 handle
the reconnection cycle.
The server does the following in order:
- S1 send application data
- S2 send a close_notify alert
- S3 close the client socket
- S4 wait for a "new connection" (actually a new datagram)
- S5 start a handshake
The client does the following in order:
- C1 wait for and read application data from the server
- C2 send a close_notify alert
- C3 close the server socket
- C4 reset session data and re-open a server socket
- C5 start a handshake
If the client has been able to send the close_notify (C2) and if has been
delivered to the server before if closes the client socket (S3), when the
server reaches S4, the datagram that we start the new connection will be the
ClientHello and everything will be fine.
However if S3 wins the race and happens before the close_notify is delivered,
in S4 the close_notify is what will be seen as the first datagram in a new
connection, and then in S5 this will rightfully be rejected as not being a
valid ClientHello and the server will close the connection (and go wait for
another one). The client will then fail to read from the socket and exit
non-zero and the ssl-opt.sh harness will correctly report this as a failure.
In order to avoid this race condition in test using ssl_client2 and
ssl_server2, this commits introduces a new command-line option
skip_close_notify to ssl_client2 and uses it in all ssl-opt.sh tests that use
session resumption with DTLS and ssl_server2.
This works because ssl_server2 knows how many messages it expects in each
direction and in what order, and closes the connection after that rather than
relying on close_notify (which is also why there was a race in the first
place).
Tests that use another server (in practice there are two of them, using
OpenSSL as a server) wouldn't work with skip_close_notify, as the server won't
close the connection until the client sends a close_notify, but for the same
reason they don't need it (there is no race between receiving close_notify and
closing as the former is the cause of the later).
An alternative approach would be to make ssl_server2 keep the connection open
until it receives a close_notify. Unfortunately it creates problems for tests
where we simulate a lossy network, as the close_notify could be lost (and the
client can't retransmit it). We could modify udp_proxy with an option to never
drop alert messages, but when TLS 1.3 comes that would no longer work as the
type of messages will be encrypted.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2020-02-17 11:04:33 +01:00
opt . skip_close_notify = DFL_SKIP_CLOSE_NOTIFY ;
2010-02-18 20:37:19 +01:00
for ( i = 1 ; i < argc ; i + + )
{
p = argv [ i ] ;
if ( ( q = strchr ( p , ' = ' ) ) = = NULL )
goto usage ;
* q + + = ' \0 ' ;
if ( strcmp ( p , " server_name " ) = = 0 )
opt . server_name = q ;
2014-02-25 11:11:26 +01:00
else if ( strcmp ( p , " server_addr " ) = = 0 )
opt . server_addr = q ;
2010-02-18 20:37:19 +01:00
else if ( strcmp ( p , " server_port " ) = = 0 )
2015-06-23 12:30:57 +02:00
opt . server_port = q ;
2014-02-06 14:02:55 +01:00
else if ( strcmp ( p , " dtls " ) = = 0 )
{
int t = atoi ( q ) ;
if ( t = = 0 )
2015-04-08 12:49:31 +02:00
opt . transport = MBEDTLS_SSL_TRANSPORT_STREAM ;
2014-02-06 14:02:55 +01:00
else if ( t = = 1 )
2015-04-08 12:49:31 +02:00
opt . transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM ;
2014-02-06 14:02:55 +01:00
else
goto usage ;
}
2010-02-18 20:37:19 +01:00
else if ( strcmp ( p , " debug_level " ) = = 0 )
{
opt . debug_level = atoi ( q ) ;
if ( opt . debug_level < 0 | | opt . debug_level > 65535 )
goto usage ;
}
2019-04-03 13:59:58 +02:00
else if ( strcmp ( p , " context_crt_cb " ) = = 0 )
{
opt . context_crt_cb = atoi ( q ) ;
if ( opt . context_crt_cb ! = 0 & & opt . context_crt_cb ! = 1 )
goto usage ;
}
2014-02-26 13:47:08 +01:00
else if ( strcmp ( p , " nbio " ) = = 0 )
{
opt . nbio = atoi ( q ) ;
if ( opt . nbio < 0 | | opt . nbio > 2 )
goto usage ;
}
2017-10-10 16:56:37 +02:00
else if ( strcmp ( p , " event " ) = = 0 )
{
opt . event = atoi ( q ) ;
if ( opt . event < 0 | | opt . event > 2 )
goto usage ;
}
2014-10-01 18:29:03 +02:00
else if ( strcmp ( p , " read_timeout " ) = = 0 )
opt . read_timeout = atoi ( q ) ;
2014-10-02 14:02:32 +02:00
else if ( strcmp ( p , " max_resend " ) = = 0 )
{
opt . max_resend = atoi ( q ) ;
if ( opt . max_resend < 0 )
goto usage ;
}
2010-02-18 20:37:19 +01:00
else if ( strcmp ( p , " request_page " ) = = 0 )
opt . request_page = q ;
2014-04-25 13:40:05 +02:00
else if ( strcmp ( p , " request_size " ) = = 0 )
{
opt . request_size = atoi ( q ) ;
2017-09-18 16:05:46 +02:00
if ( opt . request_size < 0 | |
opt . request_size > MAX_REQUEST_SIZE )
2014-04-25 13:40:05 +02:00
goto usage ;
}
2011-05-26 15:16:06 +02:00
else if ( strcmp ( p , " ca_file " ) = = 0 )
opt . ca_file = q ;
2012-06-04 14:46:42 +02:00
else if ( strcmp ( p , " ca_path " ) = = 0 )
opt . ca_path = q ;
2010-07-18 10:28:20 +02:00
else if ( strcmp ( p , " crt_file " ) = = 0 )
opt . crt_file = q ;
else if ( strcmp ( p , " key_file " ) = = 0 )
opt . key_file = q ;
2018-11-07 09:42:35 +01:00
# if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_X509_CRT_PARSE_C)
else if ( strcmp ( p , " key_opaque " ) = = 0 )
opt . key_opaque = atoi ( q ) ;
# endif
2019-05-15 15:03:01 +02:00
# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2019-04-09 18:24:19 +02:00
else if ( strcmp ( p , " cid " ) = = 0 )
{
opt . cid_enabled = atoi ( q ) ;
if ( opt . cid_enabled ! = 0 & & opt . cid_enabled ! = 1 )
goto usage ;
}
2019-05-03 18:30:59 +02:00
else if ( strcmp ( p , " cid_renego " ) = = 0 )
{
opt . cid_enabled_renego = atoi ( q ) ;
if ( opt . cid_enabled_renego ! = 0 & & opt . cid_enabled_renego ! = 1 )
goto usage ;
}
2019-04-09 18:24:19 +02:00
else if ( strcmp ( p , " cid_val " ) = = 0 )
{
opt . cid_val = q ;
}
2019-05-03 18:30:59 +02:00
else if ( strcmp ( p , " cid_val_renego " ) = = 0 )
{
opt . cid_val_renego = q ;
}
2019-05-15 15:03:01 +02:00
# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2013-04-16 18:05:29 +02:00
else if ( strcmp ( p , " psk " ) = = 0 )
opt . psk = q ;
2018-10-23 12:37:50 +02:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
2018-11-15 14:06:09 +01:00
else if ( strcmp ( p , " psk_opaque " ) = = 0 )
opt . psk_opaque = atoi ( q ) ;
2019-03-27 16:55:27 +01:00
# endif
# if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
else if ( strcmp ( p , " ca_callback " ) = = 0 )
opt . ca_callback = atoi ( q ) ;
2018-10-23 12:37:50 +02:00
# endif
2013-04-16 18:05:29 +02:00
else if ( strcmp ( p , " psk_identity " ) = = 0 )
opt . psk_identity = q ;
2015-09-16 11:08:34 +02:00
else if ( strcmp ( p , " ecjpake_pw " ) = = 0 )
opt . ecjpake_pw = q ;
2017-05-16 08:50:24 +02:00
else if ( strcmp ( p , " ec_max_ops " ) = = 0 )
opt . ec_max_ops = atoi ( q ) ;
2011-02-20 17:05:58 +01:00
else if ( strcmp ( p , " force_ciphersuite " ) = = 0 )
{
2015-04-08 12:49:31 +02:00
opt . force_ciphersuite [ 0 ] = mbedtls_ssl_get_ciphersuite_id ( q ) ;
2011-02-20 17:05:58 +01:00
2014-06-11 14:19:06 +02:00
if ( opt . force_ciphersuite [ 0 ] = = 0 )
2012-02-06 17:45:10 +01:00
{
ret = 2 ;
2011-02-20 17:05:58 +01:00
goto usage ;
2012-02-06 17:45:10 +01:00
}
2011-02-20 17:05:58 +01:00
opt . force_ciphersuite [ 1 ] = 0 ;
}
2012-09-16 21:57:18 +02:00
else if ( strcmp ( p , " renegotiation " ) = = 0 )
{
2017-10-10 16:59:57 +02:00
opt . renegotiation = ( atoi ( q ) ) ?
MBEDTLS_SSL_RENEGOTIATION_ENABLED :
MBEDTLS_SSL_RENEGOTIATION_DISABLED ;
2012-09-16 21:57:18 +02:00
}
else if ( strcmp ( p , " allow_legacy " ) = = 0 )
{
2014-11-03 20:10:36 +01:00
switch ( atoi ( q ) )
{
2017-10-10 16:59:57 +02:00
case - 1 :
opt . allow_legacy = MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ;
break ;
case 0 :
opt . allow_legacy = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ;
break ;
case 1 :
opt . allow_legacy = MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION ;
break ;
2014-11-03 20:10:36 +01:00
default : goto usage ;
}
2012-09-16 21:57:18 +02:00
}
2014-02-20 17:19:59 +01:00
else if ( strcmp ( p , " renegotiate " ) = = 0 )
{
opt . renegotiate = atoi ( q ) ;
if ( opt . renegotiate < 0 | | opt . renegotiate > 1 )
goto usage ;
}
2014-08-15 12:07:38 +02:00
else if ( strcmp ( p , " exchanges " ) = = 0 )
{
opt . exchanges = atoi ( q ) ;
if ( opt . exchanges < 1 )
goto usage ;
}
2013-07-30 13:43:43 +02:00
else if ( strcmp ( p , " reconnect " ) = = 0 )
{
opt . reconnect = atoi ( q ) ;
2013-08-02 15:04:36 +02:00
if ( opt . reconnect < 0 | | opt . reconnect > 2 )
2013-07-30 13:43:43 +02:00
goto usage ;
}
2014-02-20 22:50:56 +01:00
else if ( strcmp ( p , " reco_delay " ) = = 0 )
{
opt . reco_delay = atoi ( q ) ;
if ( opt . reco_delay < 0 )
goto usage ;
}
2019-05-20 12:46:26 +02:00
else if ( strcmp ( p , " reco_mode " ) = = 0 )
{
opt . reco_mode = atoi ( q ) ;
if ( opt . reco_mode < 0 )
goto usage ;
}
2015-09-04 10:20:17 +02:00
else if ( strcmp ( p , " reconnect_hard " ) = = 0 )
{
opt . reconnect_hard = atoi ( q ) ;
if ( opt . reconnect_hard < 0 | | opt . reconnect_hard > 1 )
goto usage ;
}
2013-08-03 13:02:31 +02:00
else if ( strcmp ( p , " tickets " ) = = 0 )
{
opt . tickets = atoi ( q ) ;
if ( opt . tickets < 0 | | opt . tickets > 2 )
goto usage ;
}
2014-04-05 14:34:07 +02:00
else if ( strcmp ( p , " alpn " ) = = 0 )
{
opt . alpn_string = q ;
}
2014-10-20 13:34:59 +02:00
else if ( strcmp ( p , " fallback " ) = = 0 )
{
switch ( atoi ( q ) )
{
2015-04-08 12:49:31 +02:00
case 0 : opt . fallback = MBEDTLS_SSL_IS_NOT_FALLBACK ; break ;
case 1 : opt . fallback = MBEDTLS_SSL_IS_FALLBACK ; break ;
2014-10-20 13:34:59 +02:00
default : goto usage ;
}
}
2014-10-20 18:40:56 +02:00
else if ( strcmp ( p , " extended_ms " ) = = 0 )
{
switch ( atoi ( q ) )
{
2017-10-10 16:59:57 +02:00
case 0 :
opt . extended_ms = MBEDTLS_SSL_EXTENDED_MS_DISABLED ;
break ;
case 1 :
opt . extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED ;
break ;
2014-10-20 18:40:56 +02:00
default : goto usage ;
}
}
2017-05-15 17:05:15 +02:00
else if ( strcmp ( p , " curves " ) = = 0 )
opt . curves = q ;
2014-10-27 13:57:03 +01:00
else if ( strcmp ( p , " etm " ) = = 0 )
{
switch ( atoi ( q ) )
{
2015-04-08 12:49:31 +02:00
case 0 : opt . etm = MBEDTLS_SSL_ETM_DISABLED ; break ;
case 1 : opt . etm = MBEDTLS_SSL_ETM_ENABLED ; break ;
2014-10-27 13:57:03 +01:00
default : goto usage ;
}
}
2012-09-28 15:28:45 +02:00
else if ( strcmp ( p , " min_version " ) = = 0 )
{
if ( strcmp ( q , " ssl3 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . min_version = MBEDTLS_SSL_MINOR_VERSION_0 ;
2012-09-28 15:28:45 +02:00
else if ( strcmp ( q , " tls1 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . min_version = MBEDTLS_SSL_MINOR_VERSION_1 ;
2014-02-12 11:11:12 +01:00
else if ( strcmp ( q , " tls1_1 " ) = = 0 | |
strcmp ( q , " dtls1 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . min_version = MBEDTLS_SSL_MINOR_VERSION_2 ;
2014-02-12 11:11:12 +01:00
else if ( strcmp ( q , " tls1_2 " ) = = 0 | |
strcmp ( q , " dtls1_2 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . min_version = MBEDTLS_SSL_MINOR_VERSION_3 ;
2012-09-28 15:28:45 +02:00
else
goto usage ;
}
else if ( strcmp ( p , " max_version " ) = = 0 )
{
if ( strcmp ( q , " ssl3 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . max_version = MBEDTLS_SSL_MINOR_VERSION_0 ;
2012-09-28 15:28:45 +02:00
else if ( strcmp ( q , " tls1 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . max_version = MBEDTLS_SSL_MINOR_VERSION_1 ;
2014-02-12 11:11:12 +01:00
else if ( strcmp ( q , " tls1_1 " ) = = 0 | |
strcmp ( q , " dtls1 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . max_version = MBEDTLS_SSL_MINOR_VERSION_2 ;
2014-02-12 11:11:12 +01:00
else if ( strcmp ( q , " tls1_2 " ) = = 0 | |
strcmp ( q , " dtls1_2 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . max_version = MBEDTLS_SSL_MINOR_VERSION_3 ;
2012-09-28 15:28:45 +02:00
else
goto usage ;
}
2015-01-12 13:43:29 +01:00
else if ( strcmp ( p , " arc4 " ) = = 0 )
{
switch ( atoi ( q ) )
{
2015-04-08 12:49:31 +02:00
case 0 : opt . arc4 = MBEDTLS_SSL_ARC4_DISABLED ; break ;
case 1 : opt . arc4 = MBEDTLS_SSL_ARC4_ENABLED ; break ;
2015-01-12 13:43:29 +01:00
default : goto usage ;
}
}
2017-05-09 15:59:24 +02:00
else if ( strcmp ( p , " allow_sha1 " ) = = 0 )
{
switch ( atoi ( q ) )
{
case 0 : opt . allow_sha1 = 0 ; break ;
case 1 : opt . allow_sha1 = 1 ; break ;
default : goto usage ;
}
}
2012-09-28 15:28:45 +02:00
else if ( strcmp ( p , " force_version " ) = = 0 )
{
if ( strcmp ( q , " ssl3 " ) = = 0 )
{
2015-04-08 12:49:31 +02:00
opt . min_version = MBEDTLS_SSL_MINOR_VERSION_0 ;
opt . max_version = MBEDTLS_SSL_MINOR_VERSION_0 ;
2012-09-28 15:28:45 +02:00
}
else if ( strcmp ( q , " tls1 " ) = = 0 )
{
2015-04-08 12:49:31 +02:00
opt . min_version = MBEDTLS_SSL_MINOR_VERSION_1 ;
opt . max_version = MBEDTLS_SSL_MINOR_VERSION_1 ;
2012-09-28 15:28:45 +02:00
}
2014-03-26 12:16:44 +01:00
else if ( strcmp ( q , " tls1_1 " ) = = 0 )
2012-09-28 15:28:45 +02:00
{
2015-04-08 12:49:31 +02:00
opt . min_version = MBEDTLS_SSL_MINOR_VERSION_2 ;
opt . max_version = MBEDTLS_SSL_MINOR_VERSION_2 ;
2012-09-28 15:28:45 +02:00
}
2014-03-26 12:16:44 +01:00
else if ( strcmp ( q , " tls1_2 " ) = = 0 )
{
2015-04-08 12:49:31 +02:00
opt . min_version = MBEDTLS_SSL_MINOR_VERSION_3 ;
opt . max_version = MBEDTLS_SSL_MINOR_VERSION_3 ;
2014-03-26 12:16:44 +01:00
}
else if ( strcmp ( q , " dtls1 " ) = = 0 )
{
2015-04-08 12:49:31 +02:00
opt . min_version = MBEDTLS_SSL_MINOR_VERSION_2 ;
opt . max_version = MBEDTLS_SSL_MINOR_VERSION_2 ;
opt . transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM ;
2014-03-26 12:16:44 +01:00
}
else if ( strcmp ( q , " dtls1_2 " ) = = 0 )
2012-09-28 15:28:45 +02:00
{
2015-04-08 12:49:31 +02:00
opt . min_version = MBEDTLS_SSL_MINOR_VERSION_3 ;
opt . max_version = MBEDTLS_SSL_MINOR_VERSION_3 ;
opt . transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM ;
2012-09-28 15:28:45 +02:00
}
else
goto usage ;
}
2012-11-23 14:04:08 +01:00
else if ( strcmp ( p , " auth_mode " ) = = 0 )
{
if ( strcmp ( q , " none " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . auth_mode = MBEDTLS_SSL_VERIFY_NONE ;
2012-11-23 14:04:08 +01:00
else if ( strcmp ( q , " optional " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . auth_mode = MBEDTLS_SSL_VERIFY_OPTIONAL ;
2012-11-23 14:04:08 +01:00
else if ( strcmp ( q , " required " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . auth_mode = MBEDTLS_SSL_VERIFY_REQUIRED ;
2012-11-23 14:04:08 +01:00
else
goto usage ;
}
2013-07-16 13:39:57 +02:00
else if ( strcmp ( p , " max_frag_len " ) = = 0 )
{
if ( strcmp ( q , " 512 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_512 ;
2013-07-16 13:39:57 +02:00
else if ( strcmp ( q , " 1024 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_1024 ;
2013-07-16 13:39:57 +02:00
else if ( strcmp ( q , " 2048 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_2048 ;
2013-07-16 13:39:57 +02:00
else if ( strcmp ( q , " 4096 " ) = = 0 )
2015-04-08 12:49:31 +02:00
opt . mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_4096 ;
2013-07-16 13:39:57 +02:00
else
goto usage ;
}
2013-07-19 11:08:52 +02:00
else if ( strcmp ( p , " trunc_hmac " ) = = 0 )
{
2015-01-09 12:43:35 +01:00
switch ( atoi ( q ) )
{
2015-04-08 12:49:31 +02:00
case 0 : opt . trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_DISABLED ; break ;
case 1 : opt . trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED ; break ;
2015-01-09 12:43:35 +01:00
default : goto usage ;
}
2013-07-19 11:08:52 +02:00
}
2014-10-01 14:40:56 +02:00
else if ( strcmp ( p , " hs_timeout " ) = = 0 )
{
if ( ( p = strchr ( q , ' - ' ) ) = = NULL )
goto usage ;
* p + + = ' \0 ' ;
opt . hs_to_min = atoi ( q ) ;
opt . hs_to_max = atoi ( p ) ;
if ( opt . hs_to_min = = 0 | | opt . hs_to_max < opt . hs_to_min )
goto usage ;
}
2018-08-12 13:28:53 +02:00
else if ( strcmp ( p , " mtu " ) = = 0 )
{
opt . dtls_mtu = atoi ( q ) ;
if ( opt . dtls_mtu < 0 )
goto usage ;
}
2018-08-14 14:33:30 +02:00
else if ( strcmp ( p , " dgram_packing " ) = = 0 )
{
opt . dgram_packing = atoi ( q ) ;
if ( opt . dgram_packing ! = 0 & &
opt . dgram_packing ! = 1 )
{
goto usage ;
}
}
2015-01-07 16:35:25 +01:00
else if ( strcmp ( p , " recsplit " ) = = 0 )
{
opt . recsplit = atoi ( q ) ;
if ( opt . recsplit < 0 | | opt . recsplit > 1 )
goto usage ;
}
2015-06-11 17:02:29 +02:00
else if ( strcmp ( p , " dhmlen " ) = = 0 )
{
opt . dhmlen = atoi ( q ) ;
if ( opt . dhmlen < 0 )
goto usage ;
}
2018-10-16 22:08:38 +02:00
else if ( strcmp ( p , " query_config " ) = = 0 )
{
return query_config ( q ) ;
}
2019-05-29 12:33:32 +02:00
else if ( strcmp ( p , " serialize " ) = = 0 )
{
opt . serialize = atoi ( q ) ;
2019-06-06 09:40:52 +02:00
if ( opt . serialize < 0 | | opt . serialize > 2 )
2019-05-29 12:33:32 +02:00
goto usage ;
}
2020-04-16 14:35:19 +02:00
else if ( strcmp ( p , " context_file " ) = = 0 )
{
opt . context_file = q ;
}
2019-05-12 10:03:32 +02:00
else if ( strcmp ( p , " eap_tls " ) = = 0 )
{
opt . eap_tls = atoi ( q ) ;
if ( opt . eap_tls < 0 | | opt . eap_tls > 1 )
goto usage ;
}
2019-06-06 21:24:31 +02:00
else if ( strcmp ( p , " reproducible " ) = = 0 )
{
opt . reproducible = 1 ;
}
2019-08-29 07:31:22 +02:00
else if ( strcmp ( p , " nss_keylog " ) = = 0 )
{
opt . nss_keylog = atoi ( q ) ;
if ( opt . nss_keylog < 0 | | opt . nss_keylog > 1 )
goto usage ;
}
else if ( strcmp ( p , " nss_keylog_file " ) = = 0 )
{
opt . nss_keylog_file = q ;
}
Fix possible close_notify/ClientHello confusion
The ssl-opt.sh test cases using session resumption tend to fail occasionally
on the CI due to a race condition in how ssl_server2 and ssl_client2 handle
the reconnection cycle.
The server does the following in order:
- S1 send application data
- S2 send a close_notify alert
- S3 close the client socket
- S4 wait for a "new connection" (actually a new datagram)
- S5 start a handshake
The client does the following in order:
- C1 wait for and read application data from the server
- C2 send a close_notify alert
- C3 close the server socket
- C4 reset session data and re-open a server socket
- C5 start a handshake
If the client has been able to send the close_notify (C2) and if has been
delivered to the server before if closes the client socket (S3), when the
server reaches S4, the datagram that we start the new connection will be the
ClientHello and everything will be fine.
However if S3 wins the race and happens before the close_notify is delivered,
in S4 the close_notify is what will be seen as the first datagram in a new
connection, and then in S5 this will rightfully be rejected as not being a
valid ClientHello and the server will close the connection (and go wait for
another one). The client will then fail to read from the socket and exit
non-zero and the ssl-opt.sh harness will correctly report this as a failure.
In order to avoid this race condition in test using ssl_client2 and
ssl_server2, this commits introduces a new command-line option
skip_close_notify to ssl_client2 and uses it in all ssl-opt.sh tests that use
session resumption with DTLS and ssl_server2.
This works because ssl_server2 knows how many messages it expects in each
direction and in what order, and closes the connection after that rather than
relying on close_notify (which is also why there was a race in the first
place).
Tests that use another server (in practice there are two of them, using
OpenSSL as a server) wouldn't work with skip_close_notify, as the server won't
close the connection until the client sends a close_notify, but for the same
reason they don't need it (there is no race between receiving close_notify and
closing as the former is the cause of the later).
An alternative approach would be to make ssl_server2 keep the connection open
until it receives a close_notify. Unfortunately it creates problems for tests
where we simulate a lossy network, as the close_notify could be lost (and the
client can't retransmit it). We could modify udp_proxy with an option to never
drop alert messages, but when TLS 1.3 comes that would no longer work as the
type of messages will be encrypted.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2020-02-17 11:04:33 +01:00
else if ( strcmp ( p , " skip_close_notify " ) = = 0 )
{
opt . skip_close_notify = atoi ( q ) ;
if ( opt . skip_close_notify < 0 | | opt . skip_close_notify > 1 )
goto usage ;
}
2010-02-18 20:37:19 +01:00
else
goto usage ;
}
2009-01-03 22:22:43 +01:00
2019-09-09 12:38:51 +02:00
if ( opt . nss_keylog ! = 0 & & opt . eap_tls ! = 0 )
{
mbedtls_printf ( " Error: eap_tls and nss_keylog options cannot be used together. \n " ) ;
goto usage ;
}
2017-10-10 16:56:37 +02:00
/* Event-driven IO is incompatible with the above custom
* receive and send functions , as the polling builds on
* refers to the underlying net_context . */
if ( opt . event = = 1 & & opt . nbio ! = 1 )
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " Warning: event-driven IO mandates nbio=1 - overwrite \n " ) ;
2017-10-10 16:56:37 +02:00
opt . nbio = 1 ;
}
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_DEBUG_C)
mbedtls_debug_set_threshold ( opt . debug_level ) ;
2014-04-25 16:34:30 +02:00
# endif
2020-03-10 12:19:08 +01:00
# if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
2018-10-23 12:37:50 +02:00
/*
* Unhexify the pre - shared key if any is given
*/
if ( strlen ( opt . psk ) )
{
2019-04-09 18:12:56 +02:00
psk_len = strlen ( opt . psk ) / 2 ;
if ( psk_len > sizeof ( psk ) )
2018-10-23 12:37:50 +02:00
{
2019-04-09 18:12:56 +02:00
mbedtls_printf ( " pre-shared key too long \n " ) ;
2018-10-23 12:37:50 +02:00
goto exit ;
}
2019-04-09 18:12:56 +02:00
if ( unhexify ( opt . psk , psk ) ! = 0 )
2018-10-23 12:37:50 +02:00
{
2019-04-09 18:12:56 +02:00
mbedtls_printf ( " pre-shared key not valid hex \n " ) ;
goto exit ;
2018-10-23 12:37:50 +02:00
}
}
2020-03-10 12:19:08 +01:00
# endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
2018-10-23 12:37:50 +02:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
2018-11-15 14:06:09 +01:00
if ( opt . psk_opaque ! = 0 )
2018-10-23 12:37:50 +02:00
{
if ( opt . psk = = NULL )
{
2018-11-15 14:06:09 +01:00
mbedtls_printf ( " psk_opaque set but no psk to be imported specified. \n " ) ;
2018-10-23 12:37:50 +02:00
ret = 2 ;
goto usage ;
}
if ( opt . force_ciphersuite [ 0 ] < = 0 )
{
mbedtls_printf ( " opaque PSKs are only supported in conjunction with forcing TLS 1.2 and a PSK-only ciphersuite through the 'force_ciphersuite' option. \n " ) ;
ret = 2 ;
goto usage ;
}
}
# endif /* MBEDTLS_USE_PSA_CRYPTO */
2013-06-29 16:01:32 +02:00
if ( opt . force_ciphersuite [ 0 ] > 0 )
{
2015-04-08 12:49:31 +02:00
const mbedtls_ssl_ciphersuite_t * ciphersuite_info ;
2017-10-10 16:59:57 +02:00
ciphersuite_info =
mbedtls_ssl_ciphersuite_from_id ( opt . force_ciphersuite [ 0 ] ) ;
2013-06-29 16:01:32 +02:00
2013-07-26 14:05:32 +02:00
if ( opt . max_version ! = - 1 & &
ciphersuite_info - > min_minor_ver > opt . max_version )
{
2017-10-10 16:59:57 +02:00
mbedtls_printf ( " forced ciphersuite not allowed with this protocol version \n " ) ;
2013-07-26 14:05:32 +02:00
ret = 2 ;
goto usage ;
}
if ( opt . min_version ! = - 1 & &
2013-06-29 16:01:32 +02:00
ciphersuite_info - > max_minor_ver < opt . min_version )
{
2017-10-10 16:59:57 +02:00
mbedtls_printf ( " forced ciphersuite not allowed with this protocol version \n " ) ;
2013-06-29 16:01:32 +02:00
ret = 2 ;
goto usage ;
}
2014-03-26 18:12:04 +01:00
/* If the server selects a version that's not supported by
* this suite , then there will be no common ciphersuite . . . */
if ( opt . max_version = = - 1 | |
opt . max_version > ciphersuite_info - > max_minor_ver )
{
2013-07-26 14:05:32 +02:00
opt . max_version = ciphersuite_info - > max_minor_ver ;
2014-03-26 18:12:04 +01:00
}
2013-07-26 14:05:32 +02:00
if ( opt . min_version < ciphersuite_info - > min_minor_ver )
2014-03-26 18:12:04 +01:00
{
2013-07-26 14:05:32 +02:00
opt . min_version = ciphersuite_info - > min_minor_ver ;
2014-03-26 18:12:04 +01:00
/* DTLS starts with TLS 1.1 */
2015-04-08 12:49:31 +02:00
if ( opt . transport = = MBEDTLS_SSL_TRANSPORT_DATAGRAM & &
opt . min_version < MBEDTLS_SSL_MINOR_VERSION_2 )
opt . min_version = MBEDTLS_SSL_MINOR_VERSION_2 ;
2014-03-26 18:12:04 +01:00
}
2015-03-20 20:44:04 +01:00
/* Enable RC4 if needed and not explicitly disabled */
2015-04-08 12:49:31 +02:00
if ( ciphersuite_info - > cipher = = MBEDTLS_CIPHER_ARC4_128 )
2015-03-20 20:44:04 +01:00
{
2015-04-08 12:49:31 +02:00
if ( opt . arc4 = = MBEDTLS_SSL_ARC4_DISABLED )
2015-03-20 20:44:04 +01:00
{
2017-10-10 16:59:57 +02:00
mbedtls_printf ( " forced RC4 ciphersuite with RC4 disabled \n " ) ;
2015-03-20 20:44:04 +01:00
ret = 2 ;
goto usage ;
}
2015-04-08 12:49:31 +02:00
opt . arc4 = MBEDTLS_SSL_ARC4_ENABLED ;
2015-03-20 20:44:04 +01:00
}
2013-04-16 18:05:29 +02:00
2019-04-09 18:24:19 +02:00
2018-10-23 12:37:50 +02:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
2018-11-15 14:06:09 +01:00
if ( opt . psk_opaque ! = 0 )
2013-04-16 18:05:29 +02:00
{
2018-10-23 12:37:50 +02:00
/* Ensure that the chosen ciphersuite is PSK-only; we must know
* the ciphersuite in advance to set the correct policy for the
* PSK key slot . This limitation might go away in the future . */
if ( ciphersuite_info - > key_exchange ! = MBEDTLS_KEY_EXCHANGE_PSK | |
opt . min_version ! = MBEDTLS_SSL_MINOR_VERSION_3 )
2013-04-16 18:05:29 +02:00
{
2018-10-23 12:37:50 +02:00
mbedtls_printf ( " opaque PSKs are only supported in conjunction with forcing TLS 1.2 and a PSK-only ciphersuite through the 'force_ciphersuite' option. \n " ) ;
ret = 2 ;
goto usage ;
2013-04-16 18:05:29 +02:00
}
2018-10-23 12:37:50 +02:00
/* Determine KDF algorithm the opaque PSK will be used in. */
# if defined(MBEDTLS_SHA512_C)
if ( ciphersuite_info - > mac = = MBEDTLS_MD_SHA384 )
alg = PSA_ALG_TLS12_PSK_TO_MS ( PSA_ALG_SHA_384 ) ;
2013-04-16 18:05:29 +02:00
else
2018-10-23 12:37:50 +02:00
# endif /* MBEDTLS_SHA512_C */
alg = PSA_ALG_TLS12_PSK_TO_MS ( PSA_ALG_SHA_256 ) ;
2013-04-16 18:05:29 +02:00
}
2018-10-23 12:37:50 +02:00
# endif /* MBEDTLS_USE_PSA_CRYPTO */
2013-04-16 18:05:29 +02:00
}
2019-05-15 15:03:01 +02:00
# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2019-05-03 18:30:59 +02:00
cid_len = strlen ( opt . cid_val ) / 2 ;
if ( cid_len > sizeof ( cid ) )
{
mbedtls_printf ( " CID too long \n " ) ;
goto exit ;
}
if ( unhexify ( opt . cid_val , cid ) ! = 0 )
{
mbedtls_printf ( " CID not valid hex \n " ) ;
goto exit ;
}
/* Keep CID settings for renegotiation unless
* specified otherwise . */
if ( opt . cid_enabled_renego = = DFL_CID_ENABLED_RENEGO )
opt . cid_enabled_renego = opt . cid_enabled ;
if ( opt . cid_val_renego = = DFL_CID_VALUE_RENEGO )
opt . cid_val_renego = opt . cid_val ;
cid_renego_len = strlen ( opt . cid_val_renego ) / 2 ;
if ( cid_renego_len > sizeof ( cid_renego ) )
{
mbedtls_printf ( " CID too long \n " ) ;
goto exit ;
}
if ( unhexify ( opt . cid_val_renego , cid_renego ) ! = 0 )
{
mbedtls_printf ( " CID not valid hex \n " ) ;
goto exit ;
}
2019-05-15 15:03:01 +02:00
# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2019-04-09 18:24:19 +02:00
2017-05-15 17:05:15 +02:00
# if defined(MBEDTLS_ECP_C)
if ( opt . curves ! = NULL )
{
p = ( char * ) opt . curves ;
i = 0 ;
if ( strcmp ( p , " none " ) = = 0 )
{
curve_list [ 0 ] = MBEDTLS_ECP_DP_NONE ;
}
else if ( strcmp ( p , " default " ) ! = 0 )
{
/* Leave room for a final NULL in curve list */
2017-06-09 17:13:22 +02:00
while ( i < CURVE_LIST_SIZE - 1 & & * p ! = ' \0 ' )
2017-05-15 17:05:15 +02:00
{
q = p ;
/* Terminate the current string */
while ( * p ! = ' , ' & & * p ! = ' \0 ' )
p + + ;
if ( * p = = ' , ' )
* p + + = ' \0 ' ;
if ( ( curve_cur = mbedtls_ecp_curve_info_from_name ( q ) ) ! = NULL )
{
curve_list [ i + + ] = curve_cur - > grp_id ;
}
else
{
mbedtls_printf ( " unknown curve %s \n " , q ) ;
mbedtls_printf ( " supported curves: " ) ;
for ( curve_cur = mbedtls_ecp_curve_list ( ) ;
curve_cur - > grp_id ! = MBEDTLS_ECP_DP_NONE ;
curve_cur + + )
{
mbedtls_printf ( " %s " , curve_cur - > name ) ;
}
mbedtls_printf ( " \n " ) ;
goto exit ;
}
}
mbedtls_printf ( " Number of curves: %d \n " , i ) ;
2017-06-09 17:13:22 +02:00
if ( i = = CURVE_LIST_SIZE - 1 & & * p ! = ' \0 ' )
2017-05-15 17:05:15 +02:00
{
2017-06-09 17:13:22 +02:00
mbedtls_printf ( " curves list too long, maximum %d " ,
CURVE_LIST_SIZE - 1 ) ;
2017-05-15 17:05:15 +02:00
goto exit ;
}
curve_list [ i ] = MBEDTLS_ECP_DP_NONE ;
}
}
# endif /* MBEDTLS_ECP_C */
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_ALPN)
2014-04-05 14:34:07 +02:00
if ( opt . alpn_string ! = NULL )
{
p = ( char * ) opt . alpn_string ;
i = 0 ;
/* Leave room for a final NULL in alpn_list */
2017-06-09 17:13:22 +02:00
while ( i < ALPN_LIST_SIZE - 1 & & * p ! = ' \0 ' )
2014-04-05 14:34:07 +02:00
{
alpn_list [ i + + ] = p ;
/* Terminate the current string and move on to next one */
while ( * p ! = ' , ' & & * p ! = ' \0 ' )
p + + ;
if ( * p = = ' , ' )
* p + + = ' \0 ' ;
}
}
2015-04-08 12:49:31 +02:00
# endif /* MBEDTLS_SSL_ALPN */
2014-04-05 14:34:07 +02:00
2009-01-03 22:22:43 +01:00
/*
* 0. Initialize the RNG and the session data
*/
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " \n . Seeding the random number generator... " ) ;
2011-12-04 18:09:26 +01:00
fflush ( stdout ) ;
2015-04-08 12:49:31 +02:00
mbedtls_entropy_init ( & entropy ) ;
2019-06-07 15:04:32 +02:00
if ( opt . reproducible )
2011-12-04 18:09:26 +01:00
{
2019-06-18 20:16:43 +02:00
srand ( 1 ) ;
2019-06-06 21:24:31 +02:00
if ( ( ret = mbedtls_ctr_drbg_seed ( & ctr_drbg , dummy_entropy ,
2019-06-07 15:04:32 +02:00
& entropy , ( const unsigned char * ) pers ,
strlen ( pers ) ) ) ! = 0 )
2019-06-06 21:24:31 +02:00
{
mbedtls_printf ( " failed \n ! mbedtls_ctr_drbg_seed returned -0x%x \n " ,
2019-06-07 15:04:32 +02:00
- ret ) ;
2019-06-06 21:24:31 +02:00
goto exit ;
}
2019-06-07 15:04:32 +02:00
}
else
{
2019-06-06 21:24:31 +02:00
if ( ( ret = mbedtls_ctr_drbg_seed ( & ctr_drbg , mbedtls_entropy_func ,
2019-06-07 15:04:32 +02:00
& entropy , ( const unsigned char * ) pers ,
strlen ( pers ) ) ) ! = 0 )
2019-06-06 21:24:31 +02:00
{
mbedtls_printf ( " failed \n ! mbedtls_ctr_drbg_seed returned -0x%x \n " ,
2019-06-07 15:04:32 +02:00
- ret ) ;
2019-06-06 21:24:31 +02:00
goto exit ;
}
2011-12-04 18:09:26 +01:00
}
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " ok \n " ) ;
2009-01-03 22:22:43 +01:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
2009-01-03 22:22:43 +01:00
/*
* 1.1 . Load the trusted CA
*/
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " . Loading the CA root certificate ... " ) ;
2009-01-03 22:22:43 +01:00
fflush ( stdout ) ;
2019-03-05 17:02:15 +01:00
if ( strcmp ( opt . ca_path , " none " ) = = 0 | |
strcmp ( opt . ca_file , " none " ) = = 0 )
{
ret = 0 ;
}
else
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_FS_IO)
2012-06-04 14:46:42 +02:00
if ( strlen ( opt . ca_path ) )
2019-03-05 17:02:15 +01:00
ret = mbedtls_x509_crt_parse_path ( & cacert , opt . ca_path ) ;
2012-06-04 14:46:42 +02:00
else if ( strlen ( opt . ca_file ) )
2019-03-05 17:02:15 +01:00
ret = mbedtls_x509_crt_parse_file ( & cacert , opt . ca_file ) ;
2013-04-18 22:46:23 +02:00
else
2011-05-26 15:16:06 +02:00
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_CERTS_C)
2019-02-01 09:15:06 +01:00
{
# if defined(MBEDTLS_PEM_PARSE_C)
2015-04-08 12:49:31 +02:00
for ( i = 0 ; mbedtls_test_cas [ i ] ! = NULL ; i + + )
2015-03-27 10:20:26 +01:00
{
2015-04-08 12:49:31 +02:00
ret = mbedtls_x509_crt_parse ( & cacert ,
( const unsigned char * ) mbedtls_test_cas [ i ] ,
mbedtls_test_cas_len [ i ] ) ;
2015-03-27 10:20:26 +01:00
if ( ret ! = 0 )
break ;
}
2019-02-01 09:15:06 +01:00
if ( ret = = 0 )
# endif /* MBEDTLS_PEM_PARSE_C */
for ( i = 0 ; mbedtls_test_cas_der [ i ] ! = NULL ; i + + )
{
ret = mbedtls_x509_crt_parse_der ( & cacert ,
( const unsigned char * ) mbedtls_test_cas_der [ i ] ,
mbedtls_test_cas_der_len [ i ] ) ;
if ( ret ! = 0 )
break ;
}
}
2011-05-26 15:16:06 +02:00
# else
{
ret = 1 ;
2017-10-10 16:59:57 +02:00
mbedtls_printf ( " MBEDTLS_CERTS_C not defined. " ) ;
2011-05-26 15:16:06 +02:00
}
2019-02-01 09:15:06 +01:00
# endif /* MBEDTLS_CERTS_C */
2012-05-16 10:21:05 +02:00
if ( ret < 0 )
2009-01-03 22:22:43 +01:00
{
2017-10-10 16:59:57 +02:00
mbedtls_printf ( " failed \n ! mbedtls_x509_crt_parse returned -0x%x \n \n " ,
- ret ) ;
2009-01-03 22:22:43 +01:00
goto exit ;
}
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " ok (%d skipped) \n " , ret ) ;
2009-01-03 22:22:43 +01:00
/*
* 1.2 . Load own certificate and private key
*
* ( can be skipped if client authentication is not required )
*/
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " . Loading the client cert. and key... " ) ;
2009-01-03 22:22:43 +01:00
fflush ( stdout ) ;
2019-03-05 17:02:15 +01:00
if ( strcmp ( opt . crt_file , " none " ) = = 0 )
ret = 0 ;
else
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_FS_IO)
2010-07-18 10:28:20 +02:00
if ( strlen ( opt . crt_file ) )
2019-03-05 17:02:15 +01:00
ret = mbedtls_x509_crt_parse_file ( & clicert , opt . crt_file ) ;
2013-04-18 22:46:23 +02:00
else
2011-05-26 15:16:06 +02:00
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_CERTS_C)
2017-10-10 16:56:37 +02:00
ret = mbedtls_x509_crt_parse ( & clicert ,
( const unsigned char * ) mbedtls_test_cli_crt ,
2015-04-08 12:49:31 +02:00
mbedtls_test_cli_crt_len ) ;
2011-05-26 15:16:06 +02:00
# else
{
ret = 1 ;
2018-12-05 17:49:42 +01:00
mbedtls_printf ( " MBEDTLS_CERTS_C not defined. " ) ;
2011-05-26 15:16:06 +02:00
}
# endif
2009-01-03 22:22:43 +01:00
if ( ret ! = 0 )
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_x509_crt_parse returned -0x%x \n \n " ,
- ret ) ;
2009-01-03 22:22:43 +01:00
goto exit ;
}
2019-03-05 17:02:15 +01:00
if ( strcmp ( opt . key_file , " none " ) = = 0 )
ret = 0 ;
else
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_FS_IO)
2010-07-18 10:28:20 +02:00
if ( strlen ( opt . key_file ) )
2019-03-05 17:02:15 +01:00
ret = mbedtls_pk_parse_keyfile ( & pkey , opt . key_file , " " ) ;
2010-07-18 10:28:20 +02:00
else
2011-05-26 15:16:06 +02:00
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_CERTS_C)
2017-10-10 16:56:37 +02:00
ret = mbedtls_pk_parse_key ( & pkey ,
( const unsigned char * ) mbedtls_test_cli_key ,
2015-04-08 12:49:31 +02:00
mbedtls_test_cli_key_len , NULL , 0 ) ;
2011-05-26 15:16:06 +02:00
# else
{
ret = 1 ;
2018-12-05 17:49:42 +01:00
mbedtls_printf ( " MBEDTLS_CERTS_C not defined. " ) ;
2011-05-26 15:16:06 +02:00
}
# endif
2009-01-03 22:22:43 +01:00
if ( ret ! = 0 )
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_pk_parse_key returned -0x%x \n \n " ,
- ret ) ;
2009-01-03 22:22:43 +01:00
goto exit ;
}
2018-11-07 09:42:35 +01:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
if ( opt . key_opaque ! = 0 )
{
2018-11-08 09:52:25 +01:00
if ( ( ret = mbedtls_pk_wrap_as_opaque ( & pkey , & key_slot ,
PSA_ALG_SHA_256 ) ) ! = 0 )
{
mbedtls_printf ( " failed \n ! "
" mbedtls_pk_wrap_as_opaque returned -0x%x \n \n " , - ret ) ;
goto exit ;
}
2018-11-07 09:42:35 +01:00
}
# endif /* MBEDTLS_USE_PSA_CRYPTO */
2018-11-08 09:52:25 +01:00
mbedtls_printf ( " ok (key type: %s) \n " , mbedtls_pk_get_name ( & pkey ) ) ;
2015-04-08 12:49:31 +02:00
# endif /* MBEDTLS_X509_CRT_PARSE_C */
2009-01-03 22:22:43 +01:00
/*
* 2. Start the connection
*/
2014-02-25 11:11:26 +01:00
if ( opt . server_addr = = NULL )
opt . server_addr = opt . server_name ;
2015-06-23 12:30:57 +02:00
mbedtls_printf ( " . Connecting to %s/%s/%s... " ,
2015-04-08 12:49:31 +02:00
opt . transport = = MBEDTLS_SSL_TRANSPORT_STREAM ? " tcp " : " udp " ,
2014-03-23 18:23:41 +01:00
opt . server_addr , opt . server_port ) ;
2009-01-03 22:22:43 +01:00
fflush ( stdout ) ;
2017-10-10 16:56:37 +02:00
if ( ( ret = mbedtls_net_connect ( & server_fd ,
opt . server_addr , opt . server_port ,
opt . transport = = MBEDTLS_SSL_TRANSPORT_STREAM ?
MBEDTLS_NET_PROTO_TCP : MBEDTLS_NET_PROTO_UDP ) ) ! = 0 )
2009-01-03 22:22:43 +01:00
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_net_connect returned -0x%x \n \n " ,
- ret ) ;
2009-01-03 22:22:43 +01:00
goto exit ;
}
2014-02-26 13:47:08 +01:00
if ( opt . nbio > 0 )
2015-06-30 15:40:39 +02:00
ret = mbedtls_net_set_nonblock ( & server_fd ) ;
2014-02-26 13:47:08 +01:00
else
2015-06-30 15:40:39 +02:00
ret = mbedtls_net_set_block ( & server_fd ) ;
2014-02-26 13:47:08 +01:00
if ( ret ! = 0 )
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! net_set_(non)block() returned -0x%x \n \n " ,
- ret ) ;
2014-02-26 13:47:08 +01:00
goto exit ;
}
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " ok \n " ) ;
2009-01-03 22:22:43 +01:00
/*
* 3. Setup stuff
*/
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " . Setting up the SSL/TLS structure... " ) ;
2009-01-03 22:22:43 +01:00
fflush ( stdout ) ;
2015-05-04 19:32:36 +02:00
if ( ( ret = mbedtls_ssl_config_defaults ( & conf ,
MBEDTLS_SSL_IS_CLIENT ,
2015-06-17 13:53:47 +02:00
opt . transport ,
MBEDTLS_SSL_PRESET_DEFAULT ) ) ! = 0 )
2015-05-04 14:56:36 +02:00
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_config_defaults returned -0x%x \n \n " ,
- ret ) ;
2015-05-04 14:56:36 +02:00
goto exit ;
}
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
2017-05-05 18:59:02 +02:00
/* The default algorithms profile disables SHA-1, but our tests still
rely on it heavily . */
2017-05-09 15:59:24 +02:00
if ( opt . allow_sha1 > 0 )
{
crt_profile_for_test . allowed_mds | = MBEDTLS_X509_ID_FLAG ( MBEDTLS_MD_SHA1 ) ;
mbedtls_ssl_conf_cert_profile ( & conf , & crt_profile_for_test ) ;
mbedtls_ssl_conf_sig_hashes ( & conf , ssl_sig_hashes_for_test ) ;
}
2017-05-05 18:59:02 +02:00
2019-04-03 13:59:58 +02:00
if ( opt . context_crt_cb = = 0 )
mbedtls_ssl_conf_verify ( & conf , my_verify , NULL ) ;
2019-02-26 12:38:29 +01:00
memset ( peer_crt_info , 0 , sizeof ( peer_crt_info ) ) ;
2017-05-05 18:59:02 +02:00
# endif /* MBEDTLS_X509_CRT_PARSE_C */
2012-09-28 09:10:55 +02:00
2019-05-15 15:03:01 +02:00
# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2019-05-03 18:30:59 +02:00
if ( opt . cid_enabled = = 1 | | opt . cid_enabled_renego = = 1 )
Add CID configuration API
Context:
The CID draft does not require that the length of CIDs used for incoming
records must not change in the course of a connection. Since the record
header does not contain a length field for the CID, this means that if
CIDs of varying lengths are used, the CID length must be inferred from
other aspects of the record header (such as the epoch) and/or by means
outside of the protocol, e.g. by coding its length in the CID itself.
Inferring the CID length from the record's epoch is theoretically possible
in DTLS 1.2, but it requires the information about the epoch to be present
even if the epoch is no longer used: That's because one should silently drop
records from old epochs, but not the entire datagrams to which they belong
(there might be entire flights in a single datagram, including a change of
epoch); however, in order to do so, one needs to parse the record's content
length, the position of which is only known once the CID length for the epoch
is known. In conclusion, it puts a significant burden on the implementation
to infer the CID length from the record epoch, which moreover mangles record
processing with the high-level logic of the protocol (determining which epochs
are in use in which flights, when they are changed, etc. -- this would normally
determine when we drop epochs).
Moreover, with DTLS 1.3, CIDs are no longer uniquely associated to epochs,
but every epoch may use a set of CIDs of varying lengths -- in that case,
it's even theoretically impossible to do record header parsing based on
the epoch configuration only.
We must therefore seek a way for standalone record header parsing, which
means that we must either (a) fix the CID lengths for incoming records,
or (b) allow the application-code to configure a callback to implement
an application-specific CID parsing which would somehow infer the length
of the CID from the CID itself.
Supporting multiple lengths for incoming CIDs significantly increases
complexity while, on the other hand, the restriction to a fixed CID length
for incoming CIDs (which the application controls - in contrast to the
lengths of the CIDs used when writing messages to the peer) doesn't
appear to severely limit the usefulness of the CID extension.
Therefore, the initial implementation of the CID feature will require
a fixed length for incoming CIDs, which is what this commit enforces,
in the following way:
In order to avoid a change of API in case support for variable lengths
CIDs shall be added at some point, we keep mbedtls_ssl_set_cid(), which
includes a CID length parameter, but add a new API mbedtls_ssl_conf_cid_len()
which applies to an SSL configuration, and which fixes the CID length that
any call to mbetls_ssl_set_cid() which applies to an SSL context that is bound
to the given SSL configuration must use.
While this creates a slight redundancy of parameters, it allows to
potentially add an API like mbedtls_ssl_conf_cid_len_cb() later which
could allow users to register a callback which dynamically infers the
length of a CID at record header parsing time, without changing the
rest of the API.
2019-05-03 14:06:44 +02:00
{
2019-05-03 18:30:59 +02:00
if ( opt . cid_enabled = = 1 & &
opt . cid_enabled_renego = = 1 & &
cid_len ! = cid_renego_len )
{
mbedtls_printf ( " CID length must not change during renegotiation \n " ) ;
goto usage ;
}
if ( opt . cid_enabled = = 1 )
2019-05-14 12:30:10 +02:00
ret = mbedtls_ssl_conf_cid ( & conf , cid_len ,
MBEDTLS_SSL_UNEXPECTED_CID_IGNORE ) ;
2019-05-03 18:30:59 +02:00
else
2019-05-14 12:30:10 +02:00
ret = mbedtls_ssl_conf_cid ( & conf , cid_renego_len ,
MBEDTLS_SSL_UNEXPECTED_CID_IGNORE ) ;
2019-05-03 18:30:59 +02:00
Add CID configuration API
Context:
The CID draft does not require that the length of CIDs used for incoming
records must not change in the course of a connection. Since the record
header does not contain a length field for the CID, this means that if
CIDs of varying lengths are used, the CID length must be inferred from
other aspects of the record header (such as the epoch) and/or by means
outside of the protocol, e.g. by coding its length in the CID itself.
Inferring the CID length from the record's epoch is theoretically possible
in DTLS 1.2, but it requires the information about the epoch to be present
even if the epoch is no longer used: That's because one should silently drop
records from old epochs, but not the entire datagrams to which they belong
(there might be entire flights in a single datagram, including a change of
epoch); however, in order to do so, one needs to parse the record's content
length, the position of which is only known once the CID length for the epoch
is known. In conclusion, it puts a significant burden on the implementation
to infer the CID length from the record epoch, which moreover mangles record
processing with the high-level logic of the protocol (determining which epochs
are in use in which flights, when they are changed, etc. -- this would normally
determine when we drop epochs).
Moreover, with DTLS 1.3, CIDs are no longer uniquely associated to epochs,
but every epoch may use a set of CIDs of varying lengths -- in that case,
it's even theoretically impossible to do record header parsing based on
the epoch configuration only.
We must therefore seek a way for standalone record header parsing, which
means that we must either (a) fix the CID lengths for incoming records,
or (b) allow the application-code to configure a callback to implement
an application-specific CID parsing which would somehow infer the length
of the CID from the CID itself.
Supporting multiple lengths for incoming CIDs significantly increases
complexity while, on the other hand, the restriction to a fixed CID length
for incoming CIDs (which the application controls - in contrast to the
lengths of the CIDs used when writing messages to the peer) doesn't
appear to severely limit the usefulness of the CID extension.
Therefore, the initial implementation of the CID feature will require
a fixed length for incoming CIDs, which is what this commit enforces,
in the following way:
In order to avoid a change of API in case support for variable lengths
CIDs shall be added at some point, we keep mbedtls_ssl_set_cid(), which
includes a CID length parameter, but add a new API mbedtls_ssl_conf_cid_len()
which applies to an SSL configuration, and which fixes the CID length that
any call to mbetls_ssl_set_cid() which applies to an SSL context that is bound
to the given SSL configuration must use.
While this creates a slight redundancy of parameters, it allows to
potentially add an API like mbedtls_ssl_conf_cid_len_cb() later which
could allow users to register a callback which dynamically infers the
length of a CID at record header parsing time, without changing the
rest of the API.
2019-05-03 14:06:44 +02:00
if ( ret ! = 0 )
{
2019-05-23 17:58:22 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_conf_cid_len returned -%#04x \n \n " ,
- ret ) ;
Add CID configuration API
Context:
The CID draft does not require that the length of CIDs used for incoming
records must not change in the course of a connection. Since the record
header does not contain a length field for the CID, this means that if
CIDs of varying lengths are used, the CID length must be inferred from
other aspects of the record header (such as the epoch) and/or by means
outside of the protocol, e.g. by coding its length in the CID itself.
Inferring the CID length from the record's epoch is theoretically possible
in DTLS 1.2, but it requires the information about the epoch to be present
even if the epoch is no longer used: That's because one should silently drop
records from old epochs, but not the entire datagrams to which they belong
(there might be entire flights in a single datagram, including a change of
epoch); however, in order to do so, one needs to parse the record's content
length, the position of which is only known once the CID length for the epoch
is known. In conclusion, it puts a significant burden on the implementation
to infer the CID length from the record epoch, which moreover mangles record
processing with the high-level logic of the protocol (determining which epochs
are in use in which flights, when they are changed, etc. -- this would normally
determine when we drop epochs).
Moreover, with DTLS 1.3, CIDs are no longer uniquely associated to epochs,
but every epoch may use a set of CIDs of varying lengths -- in that case,
it's even theoretically impossible to do record header parsing based on
the epoch configuration only.
We must therefore seek a way for standalone record header parsing, which
means that we must either (a) fix the CID lengths for incoming records,
or (b) allow the application-code to configure a callback to implement
an application-specific CID parsing which would somehow infer the length
of the CID from the CID itself.
Supporting multiple lengths for incoming CIDs significantly increases
complexity while, on the other hand, the restriction to a fixed CID length
for incoming CIDs (which the application controls - in contrast to the
lengths of the CIDs used when writing messages to the peer) doesn't
appear to severely limit the usefulness of the CID extension.
Therefore, the initial implementation of the CID feature will require
a fixed length for incoming CIDs, which is what this commit enforces,
in the following way:
In order to avoid a change of API in case support for variable lengths
CIDs shall be added at some point, we keep mbedtls_ssl_set_cid(), which
includes a CID length parameter, but add a new API mbedtls_ssl_conf_cid_len()
which applies to an SSL configuration, and which fixes the CID length that
any call to mbetls_ssl_set_cid() which applies to an SSL context that is bound
to the given SSL configuration must use.
While this creates a slight redundancy of parameters, it allows to
potentially add an API like mbedtls_ssl_conf_cid_len_cb() later which
could allow users to register a callback which dynamically infers the
length of a CID at record header parsing time, without changing the
rest of the API.
2019-05-03 14:06:44 +02:00
goto exit ;
}
}
2019-05-15 15:03:01 +02:00
# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Add CID configuration API
Context:
The CID draft does not require that the length of CIDs used for incoming
records must not change in the course of a connection. Since the record
header does not contain a length field for the CID, this means that if
CIDs of varying lengths are used, the CID length must be inferred from
other aspects of the record header (such as the epoch) and/or by means
outside of the protocol, e.g. by coding its length in the CID itself.
Inferring the CID length from the record's epoch is theoretically possible
in DTLS 1.2, but it requires the information about the epoch to be present
even if the epoch is no longer used: That's because one should silently drop
records from old epochs, but not the entire datagrams to which they belong
(there might be entire flights in a single datagram, including a change of
epoch); however, in order to do so, one needs to parse the record's content
length, the position of which is only known once the CID length for the epoch
is known. In conclusion, it puts a significant burden on the implementation
to infer the CID length from the record epoch, which moreover mangles record
processing with the high-level logic of the protocol (determining which epochs
are in use in which flights, when they are changed, etc. -- this would normally
determine when we drop epochs).
Moreover, with DTLS 1.3, CIDs are no longer uniquely associated to epochs,
but every epoch may use a set of CIDs of varying lengths -- in that case,
it's even theoretically impossible to do record header parsing based on
the epoch configuration only.
We must therefore seek a way for standalone record header parsing, which
means that we must either (a) fix the CID lengths for incoming records,
or (b) allow the application-code to configure a callback to implement
an application-specific CID parsing which would somehow infer the length
of the CID from the CID itself.
Supporting multiple lengths for incoming CIDs significantly increases
complexity while, on the other hand, the restriction to a fixed CID length
for incoming CIDs (which the application controls - in contrast to the
lengths of the CIDs used when writing messages to the peer) doesn't
appear to severely limit the usefulness of the CID extension.
Therefore, the initial implementation of the CID feature will require
a fixed length for incoming CIDs, which is what this commit enforces,
in the following way:
In order to avoid a change of API in case support for variable lengths
CIDs shall be added at some point, we keep mbedtls_ssl_set_cid(), which
includes a CID length parameter, but add a new API mbedtls_ssl_conf_cid_len()
which applies to an SSL configuration, and which fixes the CID length that
any call to mbetls_ssl_set_cid() which applies to an SSL context that is bound
to the given SSL configuration must use.
While this creates a slight redundancy of parameters, it allows to
potentially add an API like mbedtls_ssl_conf_cid_len_cb() later which
could allow users to register a callback which dynamically infers the
length of a CID at record header parsing time, without changing the
rest of the API.
2019-05-03 14:06:44 +02:00
2015-03-27 17:52:25 +01:00
if ( opt . auth_mode ! = DFL_AUTH_MODE )
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_authmode ( & conf , opt . auth_mode ) ;
2009-01-03 22:22:43 +01:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_PROTO_DTLS)
2014-10-01 14:40:56 +02:00
if ( opt . hs_to_min ! = DFL_HS_TO_MIN | | opt . hs_to_max ! = DFL_HS_TO_MAX )
2017-10-10 16:56:37 +02:00
mbedtls_ssl_conf_handshake_timeout ( & conf , opt . hs_to_min ,
opt . hs_to_max ) ;
2018-08-12 13:28:53 +02:00
2018-08-14 14:33:30 +02:00
if ( opt . dgram_packing ! = DFL_DGRAM_PACKING )
2018-08-24 12:13:57 +02:00
mbedtls_ssl_set_datagram_packing ( & ssl , opt . dgram_packing ) ;
2015-04-08 12:49:31 +02:00
# endif /* MBEDTLS_SSL_PROTO_DTLS */
2014-10-01 14:40:56 +02:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
2015-05-11 09:50:24 +02:00
if ( ( ret = mbedtls_ssl_conf_max_frag_len ( & conf , opt . mfl_code ) ) ! = 0 )
2014-07-08 14:05:52 +02:00
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_conf_max_frag_len returned %d \n \n " ,
ret ) ;
2014-07-08 14:05:52 +02:00
goto exit ;
}
2013-08-15 13:33:48 +02:00
# endif
2013-07-16 13:39:57 +02:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
2015-01-09 12:43:35 +01:00
if ( opt . trunc_hmac ! = DFL_TRUNC_HMAC )
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_truncated_hmac ( & conf , opt . trunc_hmac ) ;
2013-08-15 13:45:55 +02:00
# endif
2013-07-19 11:08:52 +02:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
2014-10-20 18:40:56 +02:00
if ( opt . extended_ms ! = DFL_EXTENDED_MS )
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_extended_master_secret ( & conf , opt . extended_ms ) ;
2014-10-20 18:40:56 +02:00
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
2014-10-27 13:57:03 +01:00
if ( opt . etm ! = DFL_ETM )
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_encrypt_then_mac ( & conf , opt . etm ) ;
2014-10-27 13:57:03 +01:00
# endif
2019-05-12 10:03:32 +02:00
# if defined(MBEDTLS_SSL_EXPORT_KEYS)
if ( opt . eap_tls ! = 0 )
2019-08-29 07:31:22 +02:00
{
2019-05-12 10:03:32 +02:00
mbedtls_ssl_conf_export_keys_ext_cb ( & conf , eap_tls_key_derivation ,
& eap_tls_keying ) ;
2019-08-29 07:31:22 +02:00
}
else if ( opt . nss_keylog ! = 0 )
{
mbedtls_ssl_conf_export_keys_ext_cb ( & conf ,
nss_keylog_export ,
NULL ) ;
}
2019-05-12 10:03:32 +02:00
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
2015-01-07 16:35:25 +01:00
if ( opt . recsplit ! = DFL_RECSPLIT )
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_cbc_record_splitting ( & conf , opt . recsplit
2017-10-10 16:56:37 +02:00
? MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED
: MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ) ;
2015-01-07 16:35:25 +01:00
# endif
2015-06-11 17:02:29 +02:00
# if defined(MBEDTLS_DHM_C)
if ( opt . dhmlen ! = DFL_DHMLEN )
mbedtls_ssl_conf_dhm_min_bitlen ( & conf , opt . dhmlen ) ;
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_ALPN)
2014-04-05 14:34:07 +02:00
if ( opt . alpn_string ! = NULL )
2015-05-11 09:50:24 +02:00
if ( ( ret = mbedtls_ssl_conf_alpn_protocols ( & conf , alpn_list ) ) ! = 0 )
2014-07-08 14:05:52 +02:00
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_conf_alpn_protocols returned %d \n \n " ,
ret ) ;
2014-07-08 14:05:52 +02:00
goto exit ;
}
2014-04-05 14:34:07 +02:00
# endif
2019-06-07 15:04:32 +02:00
if ( opt . reproducible )
{
2019-06-11 16:02:43 +02:00
# if defined(MBEDTLS_HAVE_TIME)
2019-06-06 21:24:31 +02:00
# if defined(MBEDTLS_PLATFORM_TIME_ALT)
mbedtls_platform_set_time ( dummy_constant_time ) ;
# else
2019-06-11 12:11:36 +02:00
fprintf ( stderr , " Warning: reproducible option used without constant time \n " ) ;
2019-06-11 12:15:17 +02:00
# endif
2019-06-06 21:24:31 +02:00
# endif
2019-06-07 15:04:32 +02:00
}
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_rng ( & conf , mbedtls_ctr_drbg_random , & ctr_drbg ) ;
mbedtls_ssl_conf_dbg ( & conf , my_debug , stdout ) ;
2014-02-26 13:47:08 +01:00
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_read_timeout ( & conf , opt . read_timeout ) ;
2009-01-03 22:22:43 +01:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_SESSION_TICKETS)
2015-05-20 10:45:29 +02:00
mbedtls_ssl_conf_session_tickets ( & conf , opt . tickets ) ;
2013-08-14 13:48:06 +02:00
# endif
2013-08-03 13:02:31 +02:00
2012-10-31 13:32:41 +01:00
if ( opt . force_ciphersuite [ 0 ] ! = DFL_FORCE_CIPHER )
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_ciphersuites ( & conf , opt . force_ciphersuite ) ;
2015-03-20 20:44:04 +01:00
2015-05-14 12:28:21 +02:00
# if defined(MBEDTLS_ARC4_C)
2015-03-20 20:44:04 +01:00
if ( opt . arc4 ! = DFL_ARC4 )
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_arc4_support ( & conf , opt . arc4 ) ;
2015-05-14 12:28:21 +02:00
# endif
2011-02-20 17:05:58 +01:00
2014-11-03 20:10:36 +01:00
if ( opt . allow_legacy ! = DFL_ALLOW_LEGACY )
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_legacy_renegotiation ( & conf , opt . allow_legacy ) ;
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_RENEGOTIATION)
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_renegotiation ( & conf , opt . renegotiation ) ;
2014-11-03 08:23:14 +01:00
# endif
2012-09-16 21:57:18 +02:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
2014-02-27 13:35:00 +01:00
if ( strcmp ( opt . ca_path , " none " ) ! = 0 & &
strcmp ( opt . ca_file , " none " ) ! = 0 )
{
2019-03-27 16:55:27 +01:00
# if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
if ( opt . ca_callback ! = 0 )
2019-03-28 15:14:22 +01:00
mbedtls_ssl_conf_ca_cb ( & conf , ca_callback , & cacert ) ;
2019-03-27 16:55:27 +01:00
else
# endif
mbedtls_ssl_conf_ca_chain ( & conf , & cacert , NULL ) ;
2014-02-27 13:35:00 +01:00
}
if ( strcmp ( opt . crt_file , " none " ) ! = 0 & &
strcmp ( opt . key_file , " none " ) ! = 0 )
{
2015-05-11 09:50:24 +02:00
if ( ( ret = mbedtls_ssl_conf_own_cert ( & conf , & clicert , & pkey ) ) ! = 0 )
2014-07-08 14:05:52 +02:00
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_conf_own_cert returned %d \n \n " ,
ret ) ;
2014-07-08 14:05:52 +02:00
goto exit ;
}
2014-02-27 13:35:00 +01:00
}
2013-04-18 22:46:23 +02:00
# endif
2017-05-15 17:05:15 +02:00
# if defined(MBEDTLS_ECP_C)
if ( opt . curves ! = NULL & &
strcmp ( opt . curves , " default " ) ! = 0 )
{
mbedtls_ssl_conf_curves ( & conf , curve_list ) ;
}
# endif
2020-03-10 12:19:08 +01:00
# if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
2018-10-23 12:37:50 +02:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
2018-11-15 14:06:09 +01:00
if ( opt . psk_opaque ! = 0 )
2018-10-23 12:37:50 +02:00
{
2019-08-08 12:38:18 +02:00
key_attributes = psa_key_attributes_init ( ) ;
psa_set_key_usage_flags ( & key_attributes , PSA_KEY_USAGE_DERIVE ) ;
psa_set_key_algorithm ( & key_attributes , alg ) ;
psa_set_key_type ( & key_attributes , PSA_KEY_TYPE_DERIVE ) ;
2018-10-23 12:37:50 +02:00
2019-08-08 12:38:18 +02:00
status = psa_import_key ( & key_attributes , psk , psk_len , & slot ) ;
2018-10-23 12:37:50 +02:00
if ( status ! = PSA_SUCCESS )
{
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ;
goto exit ;
}
if ( ( ret = mbedtls_ssl_conf_psk_opaque ( & conf , slot ,
( const unsigned char * ) opt . psk_identity ,
2018-11-05 13:52:42 +01:00
strlen ( opt . psk_identity ) ) ) ! = 0 )
2018-10-23 12:37:50 +02:00
{
mbedtls_printf ( " failed \n ! mbedtls_ssl_conf_psk_opaque returned %d \n \n " ,
ret ) ;
goto exit ;
}
}
else
# endif /* MBEDTLS_USE_PSA_CRYPTO */
2019-11-20 14:54:36 +01:00
if ( psk_len > 0 )
2014-07-08 14:05:52 +02:00
{
2019-11-20 14:54:36 +01:00
ret = mbedtls_ssl_conf_psk ( & conf , psk , psk_len ,
( const unsigned char * ) opt . psk_identity ,
strlen ( opt . psk_identity ) ) ;
if ( ret ! = 0 )
{
mbedtls_printf ( " failed \n ! mbedtls_ssl_conf_psk returned %d \n \n " , ret ) ;
goto exit ;
}
2014-07-08 14:05:52 +02:00
}
2020-03-10 12:19:08 +01:00
# endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
2013-04-18 22:46:23 +02:00
2015-03-31 14:21:11 +02:00
if ( opt . min_version ! = DFL_MIN_VERSION )
2017-10-10 16:56:37 +02:00
mbedtls_ssl_conf_min_version ( & conf , MBEDTLS_SSL_MAJOR_VERSION_3 ,
opt . min_version ) ;
2014-02-10 14:25:10 +01:00
2015-03-31 14:21:11 +02:00
if ( opt . max_version ! = DFL_MAX_VERSION )
2017-10-10 16:56:37 +02:00
mbedtls_ssl_conf_max_version ( & conf , MBEDTLS_SSL_MAJOR_VERSION_3 ,
opt . max_version ) ;
2012-09-28 15:28:45 +02:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_FALLBACK_SCSV)
2014-10-20 13:34:59 +02:00
if ( opt . fallback ! = DFL_FALLBACK )
2015-05-11 09:50:24 +02:00
mbedtls_ssl_conf_fallback ( & conf , opt . fallback ) ;
2014-10-20 13:34:59 +02:00
# endif
2012-09-28 15:28:45 +02:00
2015-05-11 11:25:46 +02:00
if ( ( ret = mbedtls_ssl_setup ( & ssl , & conf ) ) ! = 0 )
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_setup returned -0x%x \n \n " ,
- ret ) ;
2015-05-11 11:25:46 +02:00
goto exit ;
}
# if defined(MBEDTLS_X509_CRT_PARSE_C)
if ( ( ret = mbedtls_ssl_set_hostname ( & ssl , opt . server_name ) ) ! = 0 )
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_set_hostname returned %d \n \n " ,
ret ) ;
2015-05-11 11:25:46 +02:00
goto exit ;
}
# endif
2015-09-16 11:08:34 +02:00
# if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if ( opt . ecjpake_pw ! = DFL_ECJPAKE_PW )
{
if ( ( ret = mbedtls_ssl_set_hs_ecjpake_password ( & ssl ,
( const unsigned char * ) opt . ecjpake_pw ,
strlen ( opt . ecjpake_pw ) ) ) ! = 0 )
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_set_hs_ecjpake_password returned %d \n \n " ,
ret ) ;
2015-09-16 11:08:34 +02:00
goto exit ;
}
}
# endif
2019-04-03 13:59:58 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
if ( opt . context_crt_cb = = 1 )
mbedtls_ssl_set_verify ( & ssl , my_verify , NULL ) ;
# endif /* MBEDTLS_X509_CRT_PARSE_C */
2019-07-03 18:02:43 +02:00
io_ctx . ssl = & ssl ;
io_ctx . net = & server_fd ;
mbedtls_ssl_set_bio ( & ssl , & io_ctx , send_cb , recv_cb ,
opt . nbio = = 0 ? recv_timeout_cb : NULL ) ;
2015-05-11 11:25:46 +02:00
2019-05-15 15:03:01 +02:00
# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2019-04-09 18:24:19 +02:00
if ( opt . transport = = MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
if ( ( ret = mbedtls_ssl_set_cid ( & ssl , opt . cid_enabled ,
cid , cid_len ) ) ! = 0 )
{
mbedtls_printf ( " failed \n ! mbedtls_ssl_set_cid returned %d \n \n " ,
ret ) ;
goto exit ;
}
}
2019-05-15 15:03:01 +02:00
# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2019-04-09 18:24:19 +02:00
2018-08-20 10:37:23 +02:00
# if defined(MBEDTLS_SSL_PROTO_DTLS)
if ( opt . dtls_mtu ! = DFL_DTLS_MTU )
mbedtls_ssl_set_mtu ( & ssl , opt . dtls_mtu ) ;
# endif
2015-05-13 13:58:56 +02:00
# if defined(MBEDTLS_TIMING_C)
2015-05-13 10:04:32 +02:00
mbedtls_ssl_set_timer_cb ( & ssl , & timer , mbedtls_timing_set_delay ,
mbedtls_timing_get_delay ) ;
2015-05-13 13:58:56 +02:00
# endif
2015-05-13 10:04:32 +02:00
2017-05-16 08:50:24 +02:00
# if defined(MBEDTLS_ECP_RESTARTABLE)
if ( opt . ec_max_ops ! = DFL_EC_MAX_OPS )
mbedtls_ecp_set_max_ops ( opt . ec_max_ops ) ;
# endif
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " ok \n " ) ;
2014-03-26 18:12:04 +01:00
2009-01-03 22:22:43 +01:00
/*
* 4. Handshake
*/
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " . Performing the SSL/TLS handshake... " ) ;
2009-01-03 22:22:43 +01:00
fflush ( stdout ) ;
2015-04-08 12:49:31 +02:00
while ( ( ret = mbedtls_ssl_handshake ( & ssl ) ) ! = 0 )
2009-01-03 22:22:43 +01:00
{
2017-05-16 08:50:24 +02:00
if ( ret ! = MBEDTLS_ERR_SSL_WANT_READ & &
ret ! = MBEDTLS_ERR_SSL_WANT_WRITE & &
2018-06-13 12:02:12 +02:00
ret ! = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
2009-01-03 22:22:43 +01:00
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_handshake returned -0x%x \n " ,
- ret ) ;
2015-04-08 12:49:31 +02:00
if ( ret = = MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
mbedtls_printf (
2014-03-11 11:10:27 +01:00
" Unable to verify the server's certificate. "
" Either it is invalid, \n "
" or you didn't set ca_file or ca_path "
" to an appropriate value. \n "
" Alternatively, you may want to use "
" auth_mode=optional for testing purposes. \n " ) ;
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " \n " ) ;
2009-01-03 22:22:43 +01:00
goto exit ;
}
2017-10-10 16:56:37 +02:00
2018-06-12 12:40:54 +02:00
# if defined(MBEDTLS_ECP_RESTARTABLE)
2018-10-15 15:28:16 +02:00
if ( ret = = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
continue ;
2018-06-12 12:40:54 +02:00
# endif
2017-10-10 16:56:37 +02:00
/* For event-driven IO, wait for socket to become available */
if ( opt . event = = 1 /* level triggered IO */ )
{
# if defined(MBEDTLS_TIMING_C)
2018-03-15 12:35:07 +01:00
ret = idle ( & server_fd , & timer , ret ) ;
2017-10-10 16:56:37 +02:00
# else
2018-03-15 12:35:07 +01:00
ret = idle ( & server_fd , ret ) ;
2017-10-10 16:56:37 +02:00
# endif
2018-03-15 12:35:07 +01:00
if ( ret ! = 0 )
goto exit ;
2017-10-10 16:56:37 +02:00
}
2009-01-03 22:22:43 +01:00
}
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " ok \n [ Protocol is %s ] \n [ Ciphersuite is %s ] \n " ,
2017-10-10 16:56:37 +02:00
mbedtls_ssl_get_version ( & ssl ) ,
mbedtls_ssl_get_ciphersuite ( & ssl ) ) ;
2009-01-03 22:22:43 +01:00
2015-04-08 12:49:31 +02:00
if ( ( ret = mbedtls_ssl_get_record_expansion ( & ssl ) ) > = 0 )
mbedtls_printf ( " [ Record expansion is %d ] \n " , ret ) ;
2014-10-14 17:47:31 +02:00
else
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " [ Record expansion is unknown (compression) ] \n " ) ;
2014-10-14 17:47:31 +02:00
2015-08-31 18:30:52 +02:00
# if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
2020-04-03 11:25:29 +02:00
mbedtls_printf ( " [ Maximum input fragment length is %u ] \n " ,
( unsigned int ) mbedtls_ssl_get_input_max_frag_len ( & ssl ) ) ;
mbedtls_printf ( " [ Maximum output fragment length is %u ] \n " ,
( unsigned int ) mbedtls_ssl_get_output_max_frag_len ( & ssl ) ) ;
2015-08-31 18:30:52 +02:00
# endif
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_ALPN)
2014-04-05 14:34:07 +02:00
if ( opt . alpn_string ! = NULL )
{
2015-04-08 12:49:31 +02:00
const char * alp = mbedtls_ssl_get_alpn_protocol ( & ssl ) ;
mbedtls_printf ( " [ Application Layer Protocol is %s ] \n " ,
2014-04-05 14:34:07 +02:00
alp ? alp : " (none) " ) ;
}
# endif
2019-05-12 10:03:32 +02:00
# if defined(MBEDTLS_SSL_EXPORT_KEYS)
2019-05-12 13:54:30 +02:00
if ( opt . eap_tls ! = 0 )
2019-05-12 10:03:32 +02:00
{
size_t j = 0 ;
2019-05-12 13:54:30 +02:00
if ( ( ret = mbedtls_ssl_tls_prf ( eap_tls_keying . tls_prf_type ,
eap_tls_keying . master_secret ,
sizeof ( eap_tls_keying . master_secret ) ,
eap_tls_label ,
eap_tls_keying . randbytes ,
sizeof ( eap_tls_keying . randbytes ) ,
eap_tls_keymaterial ,
sizeof ( eap_tls_keymaterial ) ) )
! = 0 )
{
mbedtls_printf ( " failed \n ! mbedtls_ssl_tls_prf returned -0x%x \n \n " ,
- ret ) ;
goto exit ;
}
2019-05-12 10:03:32 +02:00
mbedtls_printf ( " EAP-TLS key material is: " ) ;
for ( j = 0 ; j < sizeof ( eap_tls_keymaterial ) ; j + + )
{
if ( j % 8 = = 0 )
mbedtls_printf ( " \n " ) ;
mbedtls_printf ( " %02x " , eap_tls_keymaterial [ j ] ) ;
}
mbedtls_printf ( " \n " ) ;
2019-05-12 13:54:30 +02:00
if ( ( ret = mbedtls_ssl_tls_prf ( eap_tls_keying . tls_prf_type , NULL , 0 ,
2019-05-15 16:49:54 +02:00
eap_tls_label ,
eap_tls_keying . randbytes ,
sizeof ( eap_tls_keying . randbytes ) ,
eap_tls_iv ,
sizeof ( eap_tls_iv ) ) ) ! = 0 )
2019-05-12 13:54:30 +02:00
{
mbedtls_printf ( " failed \n ! mbedtls_ssl_tls_prf returned -0x%x \n \n " ,
- ret ) ;
goto exit ;
}
2019-05-12 10:03:32 +02:00
mbedtls_printf ( " EAP-TLS IV is: " ) ;
for ( j = 0 ; j < sizeof ( eap_tls_iv ) ; j + + )
{
if ( j % 8 = = 0 )
mbedtls_printf ( " \n " ) ;
mbedtls_printf ( " %02x " , eap_tls_iv [ j ] ) ;
}
mbedtls_printf ( " \n " ) ;
}
# endif
2013-07-30 13:43:43 +02:00
if ( opt . reconnect ! = 0 )
{
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " . Saving session for reuse... " ) ;
2013-07-30 13:43:43 +02:00
fflush ( stdout ) ;
2019-05-20 12:46:26 +02:00
if ( opt . reco_mode = = 1 )
2019-05-16 11:39:42 +02:00
{
2019-05-21 11:01:32 +02:00
/* free any previously saved data */
2019-05-24 10:26:41 +02:00
if ( session_data ! = NULL )
{
mbedtls_platform_zeroize ( session_data , session_data_len ) ;
mbedtls_free ( session_data ) ;
session_data = NULL ;
}
2019-05-21 11:01:32 +02:00
/* get size of the buffer needed */
mbedtls_ssl_session_save ( mbedtls_ssl_get_session_pointer ( & ssl ) ,
NULL , 0 , & session_data_len ) ;
session_data = mbedtls_calloc ( 1 , session_data_len ) ;
if ( session_data = = NULL )
{
mbedtls_printf ( " failed \n ! alloc %u bytes for session data \n " ,
( unsigned ) session_data_len ) ;
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED ;
goto exit ;
}
/* actually save session data */
2019-05-20 12:46:26 +02:00
if ( ( ret = mbedtls_ssl_session_save ( mbedtls_ssl_get_session_pointer ( & ssl ) ,
2019-05-21 11:01:32 +02:00
session_data , session_data_len ,
2019-05-20 12:46:26 +02:00
& session_data_len ) ) ! = 0 )
{
mbedtls_printf ( " failed \n ! mbedtls_ssl_session_saved returned -0x%04x \n \n " ,
- ret ) ;
goto exit ;
}
}
else
{
if ( ( ret = mbedtls_ssl_get_session ( & ssl , & saved_session ) ) ! = 0 )
{
mbedtls_printf ( " failed \n ! mbedtls_ssl_get_session returned -0x%x \n \n " ,
- ret ) ;
goto exit ;
}
2019-05-16 11:39:42 +02:00
}
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " ok \n " ) ;
2019-05-21 11:01:32 +02:00
if ( opt . reco_mode = = 1 )
{
mbedtls_printf ( " [ Saved %u bytes of session data] \n " ,
( unsigned ) session_data_len ) ;
}
2013-07-30 13:43:43 +02:00
}
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
2009-01-03 22:22:43 +01:00
/*
* 5. Verify the server certificate
*/
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " . Verifying peer X.509 certificate... " ) ;
2009-01-03 22:22:43 +01:00
2015-05-11 19:54:43 +02:00
if ( ( flags = mbedtls_ssl_get_verify_result ( & ssl ) ) ! = 0 )
2009-01-03 22:22:43 +01:00
{
2015-04-20 11:56:18 +02:00
char vrfy_buf [ 512 ] ;
2009-01-03 22:22:43 +01:00
2015-04-20 11:56:18 +02:00
mbedtls_printf ( " failed \n " ) ;
2009-01-03 22:22:43 +01:00
2017-10-10 16:56:37 +02:00
mbedtls_x509_crt_verify_info ( vrfy_buf , sizeof ( vrfy_buf ) ,
" ! " , flags ) ;
2009-01-03 22:22:43 +01:00
2015-04-20 11:56:18 +02:00
mbedtls_printf ( " %s \n " , vrfy_buf ) ;
2009-01-03 22:22:43 +01:00
}
else
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " ok \n " ) ;
2009-01-03 22:22:43 +01:00
2019-02-25 18:43:18 +01:00
mbedtls_printf ( " . Peer certificate information ... \n " ) ;
mbedtls_printf ( " %s \n " , peer_crt_info ) ;
2015-04-08 12:49:31 +02:00
# endif /* MBEDTLS_X509_CRT_PARSE_C */
2009-01-03 22:22:43 +01:00
2019-05-15 15:03:01 +02:00
# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2019-05-03 18:30:59 +02:00
ret = report_cid_usage ( & ssl , " initial handshake " ) ;
if ( ret ! = 0 )
goto exit ;
2019-04-09 18:24:19 +02:00
if ( opt . transport = = MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
2019-05-03 18:30:59 +02:00
if ( ( ret = mbedtls_ssl_set_cid ( & ssl , opt . cid_enabled_renego ,
cid_renego ,
cid_renego_len ) ) ! = 0 )
2019-04-09 18:24:19 +02:00
{
2019-05-03 18:30:59 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_set_cid returned %d \n \n " ,
ret ) ;
return ( ret ) ;
2019-04-09 18:24:19 +02:00
}
}
2019-05-15 15:03:01 +02:00
# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2019-04-09 18:24:19 +02:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_SSL_RENEGOTIATION)
2014-02-20 17:19:59 +01:00
if ( opt . renegotiate )
2013-10-29 18:16:38 +01:00
{
2014-02-20 17:19:59 +01:00
/*
* Perform renegotiation ( this must be done when the server is waiting
* for input from our side ) .
*/
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " . Performing renegotiation... " ) ;
2014-02-20 17:19:59 +01:00
fflush ( stdout ) ;
2015-04-08 12:49:31 +02:00
while ( ( ret = mbedtls_ssl_renegotiate ( & ssl ) ) ! = 0 )
2013-10-29 18:16:38 +01:00
{
2015-05-06 17:19:31 +02:00
if ( ret ! = MBEDTLS_ERR_SSL_WANT_READ & &
2017-05-16 08:50:24 +02:00
ret ! = MBEDTLS_ERR_SSL_WANT_WRITE & &
2018-06-13 12:02:12 +02:00
ret ! = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
2014-02-20 17:19:59 +01:00
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_renegotiate returned %d \n \n " ,
ret ) ;
2014-02-20 17:19:59 +01:00
goto exit ;
}
2017-10-10 16:56:37 +02:00
2018-10-15 15:28:16 +02:00
# if defined(MBEDTLS_ECP_RESTARTABLE)
if ( ret = = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
continue ;
# endif
2017-10-10 16:56:37 +02:00
/* For event-driven IO, wait for socket to become available */
if ( opt . event = = 1 /* level triggered IO */ )
{
# if defined(MBEDTLS_TIMING_C)
2017-10-31 11:58:53 +01:00
idle ( & server_fd , & timer , ret ) ;
2017-10-10 16:56:37 +02:00
# else
2017-10-31 11:58:53 +01:00
idle ( & server_fd , ret ) ;
2017-10-10 16:56:37 +02:00
# endif
}
2013-10-29 18:16:38 +01:00
}
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " ok \n " ) ;
2013-10-29 18:16:38 +01:00
}
2015-04-08 12:49:31 +02:00
# endif /* MBEDTLS_SSL_RENEGOTIATION */
2013-10-29 18:16:38 +01:00
2019-05-15 15:03:01 +02:00
# if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2019-05-03 18:30:59 +02:00
ret = report_cid_usage ( & ssl , " after renegotiation " ) ;
if ( ret ! = 0 )
goto exit ;
2019-05-15 15:03:01 +02:00
# endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2019-05-03 18:30:59 +02:00
2009-01-03 22:22:43 +01:00
/*
* 6. Write the GET request
*/
2014-10-14 11:47:21 +02:00
retry_left = opt . max_resend ;
2013-07-30 13:43:43 +02:00
send_request :
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " > Write to server: " ) ;
2009-01-03 22:22:43 +01:00
fflush ( stdout ) ;
2017-09-18 16:05:46 +02:00
len = mbedtls_snprintf ( ( char * ) buf , sizeof ( buf ) - 1 , GET_REQUEST ,
opt . request_page ) ;
2015-07-01 15:51:43 +02:00
tail_len = ( int ) strlen ( GET_REQUEST_END ) ;
2014-04-25 13:40:05 +02:00
2014-08-14 17:47:17 +02:00
/* Add padding to GET request to reach opt.request_size in length */
if ( opt . request_size ! = DFL_REQUEST_SIZE & &
len + tail_len < opt . request_size )
{
memset ( buf + len , ' A ' , opt . request_size - len - tail_len ) ;
len + = opt . request_size - len - tail_len ;
2014-04-25 13:40:05 +02:00
}
2009-01-03 22:22:43 +01:00
2017-09-18 16:05:46 +02:00
strncpy ( ( char * ) buf + len , GET_REQUEST_END , sizeof ( buf ) - len - 1 ) ;
2014-08-14 17:47:17 +02:00
len + = tail_len ;
2014-06-18 13:07:56 +02:00
/* Truncate if request size is smaller than the "natural" size */
if ( opt . request_size ! = DFL_REQUEST_SIZE & &
len > opt . request_size )
{
len = opt . request_size ;
/* Still end with \r\n unless that's really not possible */
if ( len > = 2 ) buf [ len - 2 ] = ' \r ' ;
if ( len > = 1 ) buf [ len - 1 ] = ' \n ' ;
}
2015-04-08 12:49:31 +02:00
if ( opt . transport = = MBEDTLS_SSL_TRANSPORT_STREAM )
2009-01-03 22:22:43 +01:00
{
2018-07-04 10:29:34 +02:00
written = 0 ;
frags = 0 ;
do
2009-01-03 22:22:43 +01:00
{
2017-10-10 16:56:37 +02:00
while ( ( ret = mbedtls_ssl_write ( & ssl , buf + written ,
2018-07-04 10:29:34 +02:00
len - written ) ) < 0 )
2013-07-16 15:43:17 +02:00
{
2015-05-06 17:19:31 +02:00
if ( ret ! = MBEDTLS_ERR_SSL_WANT_READ & &
2017-05-16 08:50:24 +02:00
ret ! = MBEDTLS_ERR_SSL_WANT_WRITE & &
2018-06-13 12:02:12 +02:00
ret ! = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
2014-10-13 18:38:36 +02:00
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_write returned -0x%x \n \n " ,
- ret ) ;
2014-10-13 18:38:36 +02:00
goto exit ;
}
2017-10-10 16:56:37 +02:00
/* For event-driven IO, wait for socket to become available */
if ( opt . event = = 1 /* level triggered IO */ )
{
# if defined(MBEDTLS_TIMING_C)
2017-10-31 11:58:53 +01:00
idle ( & server_fd , & timer , ret ) ;
2017-10-10 16:56:37 +02:00
# else
2017-10-31 11:58:53 +01:00
idle ( & server_fd , ret ) ;
2017-10-10 16:56:37 +02:00
# endif
}
2013-07-16 15:43:17 +02:00
}
2018-07-04 10:29:34 +02:00
frags + + ;
written + = ret ;
2009-01-03 22:22:43 +01:00
}
2018-07-04 10:29:34 +02:00
while ( written < len ) ;
2009-01-03 22:22:43 +01:00
}
2014-10-13 18:38:36 +02:00
else /* Not stream, so datagram */
{
2017-10-10 16:56:37 +02:00
while ( 1 )
{
ret = mbedtls_ssl_write ( & ssl , buf , len ) ;
2018-06-12 12:40:54 +02:00
# if defined(MBEDTLS_ECP_RESTARTABLE)
2018-06-13 12:02:12 +02:00
if ( ret = = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
2018-06-12 12:40:54 +02:00
continue ;
# endif
2017-10-10 16:56:37 +02:00
if ( ret ! = MBEDTLS_ERR_SSL_WANT_READ & &
ret ! = MBEDTLS_ERR_SSL_WANT_WRITE )
break ;
/* For event-driven IO, wait for socket to become available */
if ( opt . event = = 1 /* level triggered IO */ )
{
# if defined(MBEDTLS_TIMING_C)
2017-10-31 11:58:53 +01:00
idle ( & server_fd , & timer , ret ) ;
2017-10-10 16:56:37 +02:00
# else
2017-10-31 11:58:53 +01:00
idle ( & server_fd , ret ) ;
2017-10-10 16:56:37 +02:00
# endif
}
}
2014-10-13 18:38:36 +02:00
if ( ret < 0 )
{
2017-10-27 14:43:58 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_write returned %d \n \n " ,
ret ) ;
2014-10-13 18:38:36 +02:00
goto exit ;
}
frags = 1 ;
written = ret ;
2017-09-18 16:05:46 +02:00
if ( written < len )
{
mbedtls_printf ( " warning \n ! request didn't fit into single datagram and "
" was truncated to size %u " , ( unsigned ) written ) ;
}
2014-10-13 18:38:36 +02:00
}
2009-01-03 22:22:43 +01:00
2013-07-16 15:43:17 +02:00
buf [ written ] = ' \0 ' ;
2017-10-10 16:56:37 +02:00
mbedtls_printf ( " %d bytes written in %d fragments \n \n %s \n " ,
written , frags , ( char * ) buf ) ;
2009-01-03 22:22:43 +01:00
2018-07-04 10:29:34 +02:00
/* Send a non-empty request if request_size == 0 */
if ( len = = 0 )
{
opt . request_size = DFL_REQUEST_SIZE ;
goto send_request ;
}
2009-01-03 22:22:43 +01:00
/*
* 7. Read the HTTP response
*/
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " < Read from server: " ) ;
2009-01-03 22:22:43 +01:00
fflush ( stdout ) ;
2014-07-11 14:14:15 +02:00
/*
* TLS and DTLS need different reading styles ( stream vs datagram )
*/
2015-04-08 12:49:31 +02:00
if ( opt . transport = = MBEDTLS_SSL_TRANSPORT_STREAM )
2014-07-11 14:14:15 +02:00
{
do
{
len = sizeof ( buf ) - 1 ;
memset ( buf , 0 , sizeof ( buf ) ) ;
2015-04-08 12:49:31 +02:00
ret = mbedtls_ssl_read ( & ssl , buf , len ) ;
2014-07-11 14:14:15 +02:00
2018-06-12 12:40:54 +02:00
# if defined(MBEDTLS_ECP_RESTARTABLE)
2018-06-13 12:02:12 +02:00
if ( ret = = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
2018-06-12 12:40:54 +02:00
continue ;
# endif
2015-05-06 17:19:31 +02:00
if ( ret = = MBEDTLS_ERR_SSL_WANT_READ | |
ret = = MBEDTLS_ERR_SSL_WANT_WRITE )
2017-10-10 16:56:37 +02:00
{
/* For event-driven IO, wait for socket to become available */
if ( opt . event = = 1 /* level triggered IO */ )
{
# if defined(MBEDTLS_TIMING_C)
2017-10-31 11:58:53 +01:00
idle ( & server_fd , & timer , ret ) ;
2017-10-10 16:56:37 +02:00
# else
2017-10-31 11:58:53 +01:00
idle ( & server_fd , ret ) ;
2017-10-10 16:56:37 +02:00
# endif
}
2014-07-11 14:14:15 +02:00
continue ;
2017-10-10 16:56:37 +02:00
}
2014-07-11 14:14:15 +02:00
if ( ret < = 0 )
{
switch ( ret )
{
2015-04-08 12:49:31 +02:00
case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY :
mbedtls_printf ( " connection was closed gracefully \n " ) ;
2014-07-11 14:14:15 +02:00
ret = 0 ;
goto close_notify ;
case 0 :
2015-04-08 12:49:31 +02:00
case MBEDTLS_ERR_NET_CONN_RESET :
mbedtls_printf ( " connection was reset by peer \n " ) ;
2014-07-11 14:14:15 +02:00
ret = 0 ;
goto reconnect ;
default :
2017-10-10 16:59:57 +02:00
mbedtls_printf ( " mbedtls_ssl_read returned -0x%x \n " ,
- ret ) ;
2014-07-11 14:14:15 +02:00
goto exit ;
}
}
len = ret ;
buf [ len ] = ' \0 ' ;
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " %d bytes read \n \n %s " , len , ( char * ) buf ) ;
2014-07-11 14:14:15 +02:00
/* End of message should be detected according to the syntax of the
* application protocol ( eg HTTP ) , just use a dummy test here . */
if ( ret > 0 & & buf [ len - 1 ] = = ' \n ' )
{
ret = 0 ;
break ;
}
}
while ( 1 ) ;
}
else /* Not stream, so datagram */
2009-01-03 22:22:43 +01:00
{
len = sizeof ( buf ) - 1 ;
memset ( buf , 0 , sizeof ( buf ) ) ;
2017-10-10 16:56:37 +02:00
while ( 1 )
{
ret = mbedtls_ssl_read ( & ssl , buf , len ) ;
2018-06-12 12:40:54 +02:00
# if defined(MBEDTLS_ECP_RESTARTABLE)
2018-06-13 12:02:12 +02:00
if ( ret = = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
2018-06-12 12:40:54 +02:00
continue ;
# endif
2017-10-10 16:56:37 +02:00
if ( ret ! = MBEDTLS_ERR_SSL_WANT_READ & &
ret ! = MBEDTLS_ERR_SSL_WANT_WRITE )
break ;
/* For event-driven IO, wait for socket to become available */
if ( opt . event = = 1 /* level triggered IO */ )
{
# if defined(MBEDTLS_TIMING_C)
2017-10-31 11:58:53 +01:00
idle ( & server_fd , & timer , ret ) ;
2017-10-10 16:56:37 +02:00
# else
2017-10-31 11:58:53 +01:00
idle ( & server_fd , ret ) ;
2017-10-10 16:56:37 +02:00
# endif
}
}
2009-01-03 22:22:43 +01:00
2014-08-16 11:28:40 +02:00
if ( ret < = 0 )
2009-01-03 22:22:43 +01:00
{
2014-08-16 11:28:40 +02:00
switch ( ret )
{
2015-05-06 17:19:31 +02:00
case MBEDTLS_ERR_SSL_TIMEOUT :
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " timeout \n " ) ;
2014-10-14 11:47:21 +02:00
if ( retry_left - - > 0 )
2014-10-02 14:02:32 +02:00
goto send_request ;
goto exit ;
2015-04-08 12:49:31 +02:00
case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY :
mbedtls_printf ( " connection was closed gracefully \n " ) ;
2014-08-16 11:28:40 +02:00
ret = 0 ;
2014-08-19 16:14:36 +02:00
goto close_notify ;
2014-08-16 11:28:40 +02:00
default :
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " mbedtls_ssl_read returned -0x%x \n " , - ret ) ;
2014-08-16 11:28:40 +02:00
goto exit ;
}
2011-05-26 15:16:06 +02:00
}
2009-01-03 22:22:43 +01:00
len = ret ;
2014-04-25 13:40:05 +02:00
buf [ len ] = ' \0 ' ;
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " %d bytes read \n \n %s " , len , ( char * ) buf ) ;
2014-07-11 14:14:15 +02:00
ret = 0 ;
2009-01-03 22:22:43 +01:00
}
2014-08-16 11:28:40 +02:00
/*
2015-09-04 10:20:17 +02:00
* 7 b . Simulate hard reset and reconnect from same port ?
*/
if ( opt . reconnect_hard ! = 0 )
{
opt . reconnect_hard = 0 ;
mbedtls_printf ( " . Restarting connection from same port... " ) ;
fflush ( stdout ) ;
2019-02-27 09:34:31 +01:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
2019-02-26 13:36:53 +01:00
memset ( peer_crt_info , 0 , sizeof ( peer_crt_info ) ) ;
2019-02-27 09:34:31 +01:00
# endif /* MBEDTLS_X509_CRT_PARSE_C */
2019-02-26 13:36:53 +01:00
2015-09-04 10:20:17 +02:00
if ( ( ret = mbedtls_ssl_session_reset ( & ssl ) ) ! = 0 )
{
2017-10-10 16:59:57 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_session_reset returned -0x%x \n \n " ,
- ret ) ;
2015-09-04 10:20:17 +02:00
goto exit ;
}
while ( ( ret = mbedtls_ssl_handshake ( & ssl ) ) ! = 0 )
{
if ( ret ! = MBEDTLS_ERR_SSL_WANT_READ & &
2017-05-16 08:50:24 +02:00
ret ! = MBEDTLS_ERR_SSL_WANT_WRITE & &
2018-06-13 12:02:12 +02:00
ret ! = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
2015-09-04 10:20:17 +02:00
{
2017-10-10 16:59:57 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_handshake returned -0x%x \n \n " ,
- ret ) ;
2015-09-04 10:20:17 +02:00
goto exit ;
}
2017-10-10 16:56:37 +02:00
/* For event-driven IO, wait for socket to become available */
if ( opt . event = = 1 /* level triggered IO */ )
{
# if defined(MBEDTLS_TIMING_C)
2017-10-31 11:58:53 +01:00
idle ( & server_fd , & timer , ret ) ;
2017-10-10 16:56:37 +02:00
# else
2017-10-31 11:58:53 +01:00
idle ( & server_fd , ret ) ;
2017-10-10 16:56:37 +02:00
# endif
}
2015-09-04 10:20:17 +02:00
}
mbedtls_printf ( " ok \n " ) ;
goto send_request ;
}
/*
2019-05-29 14:15:08 +02:00
* 7 c . Simulate serialize / deserialize and go back to data exchange
*/
2019-06-04 10:06:31 +02:00
# if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
2019-06-06 09:40:52 +02:00
if ( opt . serialize ! = 0 )
2019-05-29 14:15:08 +02:00
{
2019-06-06 14:10:07 +02:00
size_t buf_len ;
2019-05-29 14:15:08 +02:00
2019-07-12 10:41:55 +02:00
mbedtls_printf ( " . Serializing live connection... " ) ;
2019-05-29 14:15:08 +02:00
2019-06-06 14:10:07 +02:00
ret = mbedtls_ssl_context_save ( & ssl , NULL , 0 , & buf_len ) ;
2019-07-12 10:41:55 +02:00
if ( ret ! = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL )
2019-05-29 14:15:08 +02:00
{
2019-06-04 14:36:18 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_context_save returned "
" -0x%x \n \n " , - ret ) ;
2019-05-29 14:15:08 +02:00
goto exit ;
}
2019-06-06 14:10:07 +02:00
if ( ( context_buf = mbedtls_calloc ( 1 , buf_len ) ) = = NULL )
2019-05-29 14:15:08 +02:00
{
2019-06-04 14:36:18 +02:00
mbedtls_printf ( " failed \n ! Couldn't allocate buffer for "
" serialized context " ) ;
2019-05-29 14:15:08 +02:00
goto exit ;
}
2019-07-15 10:31:11 +02:00
context_buf_len = buf_len ;
2019-05-29 14:15:08 +02:00
2019-06-13 11:22:50 +02:00
if ( ( ret = mbedtls_ssl_context_save ( & ssl , context_buf ,
buf_len , & buf_len ) ) ! = 0 )
2019-05-29 14:15:08 +02:00
{
2019-07-12 10:41:55 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_context_save returned "
2019-06-04 14:36:18 +02:00
" -0x%x \n \n " , - ret ) ;
2019-05-29 14:15:08 +02:00
goto exit ;
}
2019-07-12 10:41:55 +02:00
mbedtls_printf ( " ok \n " ) ;
2020-04-16 14:35:19 +02:00
/* Save serialized context to the 'opt.context_file' as a base64 code */
if ( 0 < strlen ( opt . context_file ) )
{
FILE * b64_file ;
uint8_t * b64_buf ;
size_t b64_len ;
mbedtls_printf ( " . Save serialized context to a file... " ) ;
mbedtls_base64_encode ( NULL , 0 , & b64_len , context_buf , buf_len ) ;
if ( ( b64_buf = mbedtls_calloc ( 1 , b64_len ) ) = = NULL )
{
mbedtls_printf ( " failed \n ! Couldn't allocate buffer for "
" the base64 code \n " ) ;
goto exit ;
}
if ( ( ret = mbedtls_base64_encode ( b64_buf , b64_len , & b64_len ,
context_buf , buf_len ) ) ! = 0 )
{
mbedtls_printf ( " failed \n ! mbedtls_base64_encode returned "
" -0x%x \n " , - ret ) ;
mbedtls_free ( b64_buf ) ;
goto exit ;
}
if ( ( b64_file = fopen ( opt . context_file , " w " ) ) = = NULL )
{
mbedtls_printf ( " failed \n ! Cannot open '%s' for writing. \n " ,
opt . context_file ) ;
mbedtls_free ( b64_buf ) ;
goto exit ;
}
if ( b64_len ! = fwrite ( b64_buf , 1 , b64_len , b64_file ) )
{
mbedtls_printf ( " failed \n ! fwrite(%ld bytes) failed \n " ,
( long ) b64_len ) ;
mbedtls_free ( b64_buf ) ;
fclose ( b64_file ) ;
goto exit ;
}
mbedtls_free ( b64_buf ) ;
fclose ( b64_file ) ;
mbedtls_printf ( " ok \n " ) ;
}
2019-07-12 10:41:55 +02:00
if ( opt . serialize = = 1 )
{
2019-07-23 14:51:09 +02:00
/* nothing to do here, done by context_save() already */
2020-04-17 14:37:00 +02:00
mbedtls_printf ( " . Context has been reset... ok \n " ) ;
2019-07-12 10:41:55 +02:00
}
2019-06-06 09:40:52 +02:00
if ( opt . serialize = = 2 )
{
2019-07-12 10:41:55 +02:00
mbedtls_printf ( " . Freeing and reinitializing context... " ) ;
2019-06-06 09:40:52 +02:00
mbedtls_ssl_free ( & ssl ) ;
mbedtls_ssl_init ( & ssl ) ;
if ( ( ret = mbedtls_ssl_setup ( & ssl , & conf ) ) ! = 0 )
{
2019-06-13 11:22:50 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_setup returned "
2019-07-12 10:41:55 +02:00
" -0x%x \n \n " , - ret ) ;
2019-06-06 09:40:52 +02:00
goto exit ;
}
if ( opt . nbio = = 2 )
2019-06-13 11:22:50 +02:00
mbedtls_ssl_set_bio ( & ssl , & server_fd , delayed_send ,
delayed_recv , NULL ) ;
2019-06-06 09:40:52 +02:00
else
2019-07-12 10:41:55 +02:00
mbedtls_ssl_set_bio ( & ssl , & server_fd , mbedtls_net_send ,
mbedtls_net_recv ,
2019-06-13 11:22:50 +02:00
opt . nbio = = 0 ? mbedtls_net_recv_timeout : NULL ) ;
2019-06-06 09:40:52 +02:00
2019-06-13 10:45:06 +02:00
# if defined(MBEDTLS_TIMING_C)
2019-06-13 11:22:50 +02:00
mbedtls_ssl_set_timer_cb ( & ssl , & timer ,
mbedtls_timing_set_delay ,
mbedtls_timing_get_delay ) ;
2019-06-13 10:45:06 +02:00
# endif /* MBEDTLS_TIMING_C */
2019-07-12 10:41:55 +02:00
mbedtls_printf ( " ok \n " ) ;
2019-06-06 09:40:52 +02:00
}
2019-07-12 10:41:55 +02:00
mbedtls_printf ( " . Deserializing connection... " ) ;
2019-05-29 14:15:08 +02:00
2019-06-13 11:22:50 +02:00
if ( ( ret = mbedtls_ssl_context_load ( & ssl , context_buf ,
buf_len ) ) ! = 0 )
2019-05-29 14:15:08 +02:00
{
2019-06-04 14:36:18 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_context_load returned "
" -0x%x \n \n " , - ret ) ;
2019-05-29 14:15:08 +02:00
goto exit ;
}
2019-07-12 10:41:55 +02:00
2019-07-15 10:31:11 +02:00
mbedtls_free ( context_buf ) ;
context_buf = NULL ;
context_buf_len = 0 ;
2019-07-12 10:41:55 +02:00
mbedtls_printf ( " ok \n " ) ;
2019-05-29 14:15:08 +02:00
}
2019-06-04 14:36:18 +02:00
# endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
2019-05-29 14:15:08 +02:00
/*
* 7 d . Continue doing data exchanges ?
2014-08-15 12:07:38 +02:00
*/
if ( - - opt . exchanges > 0 )
goto send_request ;
/*
2014-08-19 16:14:36 +02:00
* 8. Done , cleanly close the connection
*/
close_notify :
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " . Closing the connection... " ) ;
2015-09-04 10:20:17 +02:00
fflush ( stdout ) ;
2014-08-19 16:14:36 +02:00
Fix possible close_notify/ClientHello confusion
The ssl-opt.sh test cases using session resumption tend to fail occasionally
on the CI due to a race condition in how ssl_server2 and ssl_client2 handle
the reconnection cycle.
The server does the following in order:
- S1 send application data
- S2 send a close_notify alert
- S3 close the client socket
- S4 wait for a "new connection" (actually a new datagram)
- S5 start a handshake
The client does the following in order:
- C1 wait for and read application data from the server
- C2 send a close_notify alert
- C3 close the server socket
- C4 reset session data and re-open a server socket
- C5 start a handshake
If the client has been able to send the close_notify (C2) and if has been
delivered to the server before if closes the client socket (S3), when the
server reaches S4, the datagram that we start the new connection will be the
ClientHello and everything will be fine.
However if S3 wins the race and happens before the close_notify is delivered,
in S4 the close_notify is what will be seen as the first datagram in a new
connection, and then in S5 this will rightfully be rejected as not being a
valid ClientHello and the server will close the connection (and go wait for
another one). The client will then fail to read from the socket and exit
non-zero and the ssl-opt.sh harness will correctly report this as a failure.
In order to avoid this race condition in test using ssl_client2 and
ssl_server2, this commits introduces a new command-line option
skip_close_notify to ssl_client2 and uses it in all ssl-opt.sh tests that use
session resumption with DTLS and ssl_server2.
This works because ssl_server2 knows how many messages it expects in each
direction and in what order, and closes the connection after that rather than
relying on close_notify (which is also why there was a race in the first
place).
Tests that use another server (in practice there are two of them, using
OpenSSL as a server) wouldn't work with skip_close_notify, as the server won't
close the connection until the client sends a close_notify, but for the same
reason they don't need it (there is no race between receiving close_notify and
closing as the former is the cause of the later).
An alternative approach would be to make ssl_server2 keep the connection open
until it receives a close_notify. Unfortunately it creates problems for tests
where we simulate a lossy network, as the close_notify could be lost (and the
client can't retransmit it). We could modify udp_proxy with an option to never
drop alert messages, but when TLS 1.3 comes that would no longer work as the
type of messages will be encrypted.
Signed-off-by: Manuel Pégourié-Gonnard <manuel.pegourie-gonnard@arm.com>
2020-02-17 11:04:33 +01:00
/*
* Most of the time sending a close_notify before closing is the right
* thing to do . However , when the server already knows how many messages
* are expected and closes the connection by itself , this alert becomes
* redundant . Sometimes with DTLS this redundancy becomes a problem by
* leading to a race condition where the server might close the connection
* before seeing the alert , and since UDP is connection - less when the
* alert arrives it will be seen as a new connection , which will fail as
* the alert is clearly not a valid ClientHello . This may cause spurious
* failures in tests that use DTLS and resumption with ssl_server2 in
* ssl - opt . sh , avoided by enabling skip_close_notify client - side .
*/
if ( opt . skip_close_notify = = 0 )
{
/* No error checking, the connection might be closed already */
do ret = mbedtls_ssl_close_notify ( & ssl ) ;
while ( ret = = MBEDTLS_ERR_SSL_WANT_WRITE ) ;
ret = 0 ;
}
2014-08-19 16:14:36 +02:00
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " done \n " ) ;
2014-08-19 16:14:36 +02:00
/*
* 9. Reconnect ?
2014-08-16 11:28:40 +02:00
*/
reconnect :
2013-07-30 13:43:43 +02:00
if ( opt . reconnect ! = 0 )
{
2013-08-02 15:04:36 +02:00
- - opt . reconnect ;
2013-07-30 13:43:43 +02:00
2015-06-30 15:55:03 +02:00
mbedtls_net_free ( & server_fd ) ;
2014-03-25 11:24:43 +01:00
2015-05-13 13:58:56 +02:00
# if defined(MBEDTLS_TIMING_C)
2014-02-20 22:50:56 +01:00
if ( opt . reco_delay > 0 )
2015-05-14 18:22:47 +02:00
mbedtls_net_usleep ( 1000000 * opt . reco_delay ) ;
2015-05-13 13:58:56 +02:00
# endif
2013-08-23 10:44:29 +02:00
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " . Reconnecting with saved session... " ) ;
2013-07-30 13:43:43 +02:00
2019-02-27 09:34:31 +01:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
2019-02-26 12:38:29 +01:00
memset ( peer_crt_info , 0 , sizeof ( peer_crt_info ) ) ;
2019-02-27 09:34:31 +01:00
# endif /* MBEDTLS_X509_CRT_PARSE_C */
2019-02-26 12:38:29 +01:00
2015-04-08 12:49:31 +02:00
if ( ( ret = mbedtls_ssl_session_reset ( & ssl ) ) ! = 0 )
2013-07-30 13:43:43 +02:00
{
2017-10-10 16:59:57 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_session_reset returned -0x%x \n \n " ,
- ret ) ;
2013-07-30 13:43:43 +02:00
goto exit ;
}
2019-05-20 12:46:26 +02:00
if ( opt . reco_mode = = 1 )
2019-05-16 11:39:42 +02:00
{
2019-05-20 12:46:26 +02:00
if ( ( ret = mbedtls_ssl_session_load ( & saved_session ,
session_data ,
session_data_len ) ) ! = 0 )
{
mbedtls_printf ( " failed \n ! mbedtls_ssl_session_load returned -0x%x \n \n " ,
- ret ) ;
goto exit ;
}
2019-05-16 11:39:42 +02:00
}
2015-04-08 12:49:31 +02:00
if ( ( ret = mbedtls_ssl_set_session ( & ssl , & saved_session ) ) ! = 0 )
2014-07-08 14:05:52 +02:00
{
2019-05-16 11:39:42 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_set_session returned -0x%x \n \n " ,
- ret ) ;
2014-07-08 14:05:52 +02:00
goto exit ;
}
2013-07-30 13:43:43 +02:00
2017-10-10 16:59:57 +02:00
if ( ( ret = mbedtls_net_connect ( & server_fd ,
opt . server_addr , opt . server_port ,
opt . transport = = MBEDTLS_SSL_TRANSPORT_STREAM ?
MBEDTLS_NET_PROTO_TCP : MBEDTLS_NET_PROTO_UDP ) ) ! = 0 )
2013-07-30 13:43:43 +02:00
{
2017-10-10 16:59:57 +02:00
mbedtls_printf ( " failed \n ! mbedtls_net_connect returned -0x%x \n \n " ,
- ret ) ;
2013-07-30 13:43:43 +02:00
goto exit ;
}
2014-10-02 17:59:19 +02:00
if ( opt . nbio > 0 )
2015-06-30 15:40:39 +02:00
ret = mbedtls_net_set_nonblock ( & server_fd ) ;
2014-10-02 17:59:19 +02:00
else
2015-06-30 15:40:39 +02:00
ret = mbedtls_net_set_block ( & server_fd ) ;
2014-10-02 17:59:19 +02:00
if ( ret ! = 0 )
{
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " failed \n ! net_set_(non)block() returned -0x%x \n \n " ,
2017-10-10 16:59:57 +02:00
- ret ) ;
2014-10-02 17:59:19 +02:00
goto exit ;
}
2015-04-08 12:49:31 +02:00
while ( ( ret = mbedtls_ssl_handshake ( & ssl ) ) ! = 0 )
2013-07-30 13:43:43 +02:00
{
2015-05-06 17:19:31 +02:00
if ( ret ! = MBEDTLS_ERR_SSL_WANT_READ & &
2017-05-16 08:50:24 +02:00
ret ! = MBEDTLS_ERR_SSL_WANT_WRITE & &
2018-06-13 12:02:12 +02:00
ret ! = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
2013-07-30 13:43:43 +02:00
{
2017-10-10 16:59:57 +02:00
mbedtls_printf ( " failed \n ! mbedtls_ssl_handshake returned -0x%x \n \n " ,
- ret ) ;
2013-07-30 13:43:43 +02:00
goto exit ;
}
}
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " ok \n " ) ;
2013-07-30 13:43:43 +02:00
goto send_request ;
}
2014-08-16 11:28:40 +02:00
/*
* Cleanup and exit
*/
2009-01-03 22:22:43 +01:00
exit :
2015-04-08 12:49:31 +02:00
# ifdef MBEDTLS_ERROR_C
2011-11-27 22:07:34 +01:00
if ( ret ! = 0 )
{
char error_buf [ 100 ] ;
2015-04-08 12:49:31 +02:00
mbedtls_strerror ( ret , error_buf , 100 ) ;
mbedtls_printf ( " Last error was: -0x%X - %s \n \n " , - ret , error_buf ) ;
2011-11-27 22:07:34 +01:00
}
# endif
2015-06-30 15:55:03 +02:00
mbedtls_net_free ( & server_fd ) ;
2014-08-16 11:28:40 +02:00
2015-04-08 12:49:31 +02:00
# if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt_free ( & clicert ) ;
mbedtls_x509_crt_free ( & cacert ) ;
mbedtls_pk_free ( & pkey ) ;
2018-11-08 09:52:25 +01:00
# if defined(MBEDTLS_USE_PSA_CRYPTO)
psa_destroy_key ( key_slot ) ;
# endif
2013-04-18 22:46:23 +02:00
# endif
2015-04-08 12:49:31 +02:00
mbedtls_ssl_session_free ( & saved_session ) ;
mbedtls_ssl_free ( & ssl ) ;
2015-05-04 14:56:36 +02:00
mbedtls_ssl_config_free ( & conf ) ;
2015-04-08 12:49:31 +02:00
mbedtls_ctr_drbg_free ( & ctr_drbg ) ;
mbedtls_entropy_free ( & entropy ) ;
2019-05-24 10:26:41 +02:00
if ( session_data ! = NULL )
mbedtls_platform_zeroize ( session_data , session_data_len ) ;
2019-05-21 11:01:32 +02:00
mbedtls_free ( session_data ) ;
2019-07-15 10:31:11 +02:00
# if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
if ( context_buf ! = NULL )
mbedtls_platform_zeroize ( context_buf , context_buf_len ) ;
mbedtls_free ( context_buf ) ;
# endif
2009-01-03 22:22:43 +01:00
2020-03-10 12:19:08 +01:00
# if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) && \
2018-11-05 14:25:17 +01:00
defined ( MBEDTLS_USE_PSA_CRYPTO )
2018-11-15 14:06:09 +01:00
if ( opt . psk_opaque ! = 0 )
2018-11-05 14:25:17 +01:00
{
/* This is ok even if the slot hasn't been
* initialized ( we might have jumed here
* immediately because of bad cmd line params ,
* for example ) . */
2018-11-15 14:06:09 +01:00
status = psa_destroy_key ( slot ) ;
2018-11-05 14:25:17 +01:00
if ( status ! = PSA_SUCCESS )
{
mbedtls_printf ( " Failed to destroy key slot %u - error was %d " ,
2018-11-15 14:06:09 +01:00
( unsigned ) slot , ( int ) status ) ;
2018-11-05 14:25:17 +01:00
if ( ret = = 0 )
ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ;
}
}
2020-03-10 12:19:08 +01:00
# endif / * MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED &&
2018-11-05 14:25:17 +01:00
MBEDTLS_USE_PSA_CRYPTO */
2019-11-20 15:00:17 +01:00
# if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
# if defined(MBEDTLS_MEMORY_DEBUG)
mbedtls_memory_buffer_alloc_status ( ) ;
# endif
mbedtls_memory_buffer_alloc_free ( ) ;
# endif
2011-11-18 15:26:47 +01:00
# if defined(_WIN32)
2015-04-08 12:49:31 +02:00
mbedtls_printf ( " + Press Enter to exit this program. \n " ) ;
2009-01-03 22:22:43 +01:00
fflush ( stdout ) ; getchar ( ) ;
# endif
2013-07-24 16:28:35 +02:00
// Shell can not handle large exit numbers -> 1 for errors
if ( ret < 0 )
ret = 1 ;
2009-01-03 22:22:43 +01:00
return ( ret ) ;
}
2015-04-08 12:49:31 +02:00
# endif / * MBEDTLS_BIGNUM_C && MBEDTLS_ENTROPY_C && MBEDTLS_SSL_TLS_C &&
MBEDTLS_SSL_CLI_C & & MBEDTLS_NET_C & & MBEDTLS_RSA_C & &
2015-05-13 13:58:56 +02:00
MBEDTLS_CTR_DRBG_C MBEDTLS_TIMING_C */