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
|
Update license headers to Apache-2.0 OR GPL-2.0-or-later
This will allow us to ship the LTS branches in a single archive
This commit was generated using the following script:
# ========================
#!/bin/sh
header1='\ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later\
*\
* This file is provided under the Apache License 2.0, or the\
* GNU General Public License v2.0 or later.\
*\
* **********\
* Apache License 2.0:\
*\
* 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\
*\
* http://www.apache.org/licenses/LICENSE-2.0\
*\
* 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.\
*\
* **********\
*\
* **********\
* GNU General Public License v2.0 or later:\
*\
* This program is free software; you can redistribute it and/or modify\
* it under the terms of the GNU General Public License as published by\
* the Free Software Foundation; either version 2 of the License, or\
* (at your option) any later version.\
*\
* This program is distributed in the hope that it will be useful,\
* but WITHOUT ANY WARRANTY; without even the implied warranty of\
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\
* GNU General Public License for more details.\
*\
* You should have received a copy of the GNU General Public License along\
* with this program; if not, write to the Free Software Foundation, Inc.,\
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\
*\
* **********'
find -path './.git' -prune -o '(' -name '*.c' -o -name '*.cpp' -o -name '*.fmt' -o -name '*.h' ')' -print | xargs sed -i "
# Normalize the first line of the copyright headers (no text on the first line of a block comment)
/^\/\*.*Copyright.*Arm/I s/\/\*/&\n */
# Insert new copyright header
/SPDX-License-Identifier/ i\
$header1
# Delete old copyright header
/SPDX-License-Identifier/,$ {
# Delete lines until the one preceding the mbedtls declaration
N
1,/This file is part of/ {
/This file is part of/! D
}
}
"
# Format copyright header for inclusion into scripts
header2=$(echo "$header1" | sed 's/^\\\? \* \?/#/')
find -path './.git' -prune -o '(' -name '*.gdb' -o -name '*.pl' -o -name '*.py' -o -name '*.sh' ')' -print | xargs sed -i "
# Insert new copyright header
/SPDX-License-Identifier/ i\
$header2
# Delete old copyright header
/SPDX-License-Identifier/,$ {
# Delete lines until the one preceding the mbedtls declaration
N
1,/This file is part of/ {
/This file is part of/! D
}
}
"
# ========================
Signed-off-by: Bence Szépkúti <bence.szepkuti@arm.com>
2020-06-05 13:02:18 +02:00
|
|
|
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
|
|
|
*
|
|
|
|
* This file is provided under the Apache License 2.0, or the
|
|
|
|
* GNU General Public License v2.0 or later.
|
|
|
|
*
|
|
|
|
* **********
|
|
|
|
* Apache License 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
|
|
|
*
|
Update license headers to Apache-2.0 OR GPL-2.0-or-later
This will allow us to ship the LTS branches in a single archive
This commit was generated using the following script:
# ========================
#!/bin/sh
header1='\ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later\
*\
* This file is provided under the Apache License 2.0, or the\
* GNU General Public License v2.0 or later.\
*\
* **********\
* Apache License 2.0:\
*\
* 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\
*\
* http://www.apache.org/licenses/LICENSE-2.0\
*\
* 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.\
*\
* **********\
*\
* **********\
* GNU General Public License v2.0 or later:\
*\
* This program is free software; you can redistribute it and/or modify\
* it under the terms of the GNU General Public License as published by\
* the Free Software Foundation; either version 2 of the License, or\
* (at your option) any later version.\
*\
* This program is distributed in the hope that it will be useful,\
* but WITHOUT ANY WARRANTY; without even the implied warranty of\
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\
* GNU General Public License for more details.\
*\
* You should have received a copy of the GNU General Public License along\
* with this program; if not, write to the Free Software Foundation, Inc.,\
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\
*\
* **********'
find -path './.git' -prune -o '(' -name '*.c' -o -name '*.cpp' -o -name '*.fmt' -o -name '*.h' ')' -print | xargs sed -i "
# Normalize the first line of the copyright headers (no text on the first line of a block comment)
/^\/\*.*Copyright.*Arm/I s/\/\*/&\n */
# Insert new copyright header
/SPDX-License-Identifier/ i\
$header1
# Delete old copyright header
/SPDX-License-Identifier/,$ {
# Delete lines until the one preceding the mbedtls declaration
N
1,/This file is part of/ {
/This file is part of/! D
}
}
"
# Format copyright header for inclusion into scripts
header2=$(echo "$header1" | sed 's/^\\\? \* \?/#/')
find -path './.git' -prune -o '(' -name '*.gdb' -o -name '*.pl' -o -name '*.py' -o -name '*.sh' ')' -print | xargs sed -i "
# Insert new copyright header
/SPDX-License-Identifier/ i\
$header2
# Delete old copyright header
/SPDX-License-Identifier/,$ {
# Delete lines until the one preceding the mbedtls declaration
N
1,/This file is part of/ {
/This file is part of/! D
}
}
"
# ========================
Signed-off-by: Bence Szépkúti <bence.szepkuti@arm.com>
2020-06-05 13:02:18 +02:00
|
|
|
* **********
|
|
|
|
*
|
|
|
|
* **********
|
|
|
|
* GNU General Public License v2.0 or later:
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
* **********
|
|
|
|
*
|
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-04-24 14:24:46 +02:00
|
|
|
#define mbedtls_exit exit
|
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");
|
2019-04-24 14:24:46 +02:00
|
|
|
mbedtls_exit( 0 );
|
2015-05-13 10:04:32 +02:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
|
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"
|
2009-01-03 22:22:43 +01:00
|
|
|
|
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
|
|
|
|
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
|
2014-02-26 13:47:08 +01:00
|
|
|
#define DFL_NBIO 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 ""
|
2013-04-16 18:05:29 +02:00
|
|
|
#define DFL_PSK ""
|
|
|
|
#define DFL_PSK_IDENTITY "Client_identity"
|
2015-09-16 11:08:34 +02:00
|
|
|
#define DFL_ECJPAKE_PW NULL
|
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
|
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
|
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
|
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
|
|
|
|
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" \
|
|
|
|
" ca_path=%%s The path containing the top-level CA(s) you fully trust\n" \
|
|
|
|
" default: \"\" (pre-loaded) (overrides ca_file)\n" \
|
|
|
|
" 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 */
|
2013-04-18 22:46:23 +02:00
|
|
|
#else
|
|
|
|
#define USAGE_IO ""
|
2015-04-08 12:49:31 +02:00
|
|
|
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
2013-04-18 22:46:23 +02:00
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
|
2013-04-18 22:46:23 +02:00
|
|
|
#define USAGE_PSK \
|
|
|
|
" psk=%%s default: \"\" (in hex, without 0x)\n" \
|
|
|
|
" psk_identity=%%s default: \"Client_identity\"\n"
|
|
|
|
#else
|
|
|
|
#define USAGE_PSK ""
|
2015-04-08 12:49:31 +02:00
|
|
|
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
|
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
|
|
|
|
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" \
|
|
|
|
" range of DTLS handshake timeouts in millisecs\n"
|
|
|
|
#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
|
|
|
|
|
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
|
|
|
|
|
2020-04-14 19:41:01 +02:00
|
|
|
/* USAGE is arbitrarily split to stay under the portable string literal
|
|
|
|
* length limit: 4095 bytes in C99. */
|
|
|
|
#define USAGE1 \
|
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" \
|
2017-09-18 16:05:46 +02:00
|
|
|
" request_size=%%d default: about 34 (basic request)\n" \
|
2018-07-04 10:29:34 +02:00
|
|
|
" (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" \
|
2010-07-18 10:28:20 +02:00
|
|
|
" debug_level=%%d default: 0 (disabled)\n" \
|
2014-02-26 13:47:08 +01:00
|
|
|
" nbio=%%d default: 0 (blocking I/O)\n" \
|
|
|
|
" options: 1 (non-blocking), 2 (added delays)\n" \
|
2015-09-09 11:22:58 +02:00
|
|
|
" 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 \
|
2020-04-14 19:41:01 +02:00
|
|
|
"\n"
|
|
|
|
#define USAGE2 \
|
|
|
|
" 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 \
|
2014-02-19 18:22:59 +01:00
|
|
|
"\n" \
|
|
|
|
USAGE_PSK \
|
2015-09-16 11:08:34 +02:00
|
|
|
USAGE_ECJPAKE \
|
2020-04-14 19:41:01 +02:00
|
|
|
"\n"
|
|
|
|
#define USAGE3 \
|
|
|
|
" 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" \
|
2013-07-30 13:43:43 +02:00
|
|
|
" reconnect=%%d default: 0 (disabled)\n" \
|
2015-05-13 10:04:32 +02:00
|
|
|
" reco_delay=%%d default: 0 seconds\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 \
|
2014-02-19 18:22:59 +01:00
|
|
|
USAGE_MAX_FRAG_LEN \
|
|
|
|
USAGE_TRUNC_HMAC \
|
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 \
|
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 \
|
2020-04-14 19:41:01 +02:00
|
|
|
"\n"
|
|
|
|
#define USAGE4 \
|
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"\
|
|
|
|
" 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
|
|
|
|
|
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? */
|
2015-04-08 12:49:31 +02:00
|
|
|
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 */
|
|
|
|
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 */
|
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 */
|
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 */
|
2015-02-12 12:37:29 +01:00
|
|
|
int fallback; /* is this a fallback connection? */
|
|
|
|
int extended_ms; /* negotiate extended master secret? */
|
|
|
|
int etm; /* negotiate encrypt then mac? */
|
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;
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s", basename, line, level, str );
|
2015-02-12 12:37:29 +01:00
|
|
|
fflush( (FILE *) ctx );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Test recv/send functions that make sure each try returns
|
|
|
|
* WANT_READ/WANT_WRITE at least once before sucesseding
|
|
|
|
*/
|
|
|
|
static int my_recv( void *ctx, unsigned char *buf, size_t len )
|
|
|
|
{
|
|
|
|
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 );
|
|
|
|
}
|
|
|
|
|
|
|
|
static int my_send( void *ctx, const unsigned char *buf, size_t len )
|
|
|
|
{
|
|
|
|
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 );
|
|
|
|
}
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
2015-02-12 12:37:29 +01:00
|
|
|
/*
|
|
|
|
* Enabled if debug_level > 1 in code below
|
|
|
|
*/
|
2015-05-11 19:54:43 +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_printf( "\nVerify requested for (Depth %d):\n", depth );
|
|
|
|
mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
|
|
|
|
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
|
|
|
|
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;
|
2017-09-18 16:05:46 +02:00
|
|
|
|
|
|
|
unsigned char buf[MAX_REQUEST_SIZE + 1];
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
|
|
|
|
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
|
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
|
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
|
|
|
|
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;
|
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;
|
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;
|
2010-02-18 20:37:19 +01:00
|
|
|
|
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
|
|
|
|
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;
|
|
|
|
|
2020-04-14 19:41:01 +02:00
|
|
|
mbedtls_printf( USAGE1 );
|
|
|
|
mbedtls_printf( USAGE2 );
|
|
|
|
mbedtls_printf( USAGE3 );
|
|
|
|
mbedtls_printf( USAGE4 );
|
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;
|
2014-02-26 13:47:08 +01:00
|
|
|
opt.nbio = DFL_NBIO;
|
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;
|
2013-04-16 18:05:29 +02:00
|
|
|
opt.psk = DFL_PSK;
|
|
|
|
opt.psk_identity = DFL_PSK_IDENTITY;
|
2015-09-16 11:08:34 +02:00
|
|
|
opt.ecjpake_pw = DFL_ECJPAKE_PW;
|
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;
|
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;
|
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;
|
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;
|
|
|
|
}
|
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;
|
|
|
|
}
|
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;
|
2013-04-16 18:05:29 +02:00
|
|
|
else if( strcmp( p, "psk" ) == 0 )
|
|
|
|
opt.psk = q;
|
|
|
|
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;
|
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 )
|
|
|
|
{
|
2015-04-08 12:49:31 +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 ) )
|
|
|
|
{
|
2015-04-08 12:49:31 +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;
|
|
|
|
}
|
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 ) )
|
|
|
|
{
|
2015-04-08 12:49:31 +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;
|
|
|
|
}
|
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;
|
|
|
|
}
|
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
|
|
|
|
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
|
|
|
|
|
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;
|
|
|
|
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 )
|
|
|
|
{
|
2015-04-08 12:49:31 +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 )
|
|
|
|
{
|
2015-04-08 12:49:31 +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
|
|
|
{
|
2015-04-08 12:49:31 +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-06-29 16:01:32 +02:00
|
|
|
}
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
|
2013-04-16 18:05:29 +02:00
|
|
|
/*
|
|
|
|
* Unhexify the pre-shared key if any is given
|
|
|
|
*/
|
|
|
|
if( strlen( opt.psk ) )
|
|
|
|
{
|
|
|
|
unsigned char c;
|
|
|
|
size_t j;
|
|
|
|
|
|
|
|
if( strlen( opt.psk ) % 2 != 0 )
|
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_printf("pre-shared key not valid hex\n");
|
2013-04-16 18:05:29 +02:00
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
psk_len = strlen( opt.psk ) / 2;
|
|
|
|
|
|
|
|
for( j = 0; j < strlen( opt.psk ); j += 2 )
|
|
|
|
{
|
|
|
|
c = opt.psk[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
|
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_printf("pre-shared key not valid hex\n");
|
2013-04-16 18:05:29 +02:00
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
psk[ j / 2 ] = c << 4;
|
|
|
|
|
|
|
|
c = opt.psk[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
|
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_printf("pre-shared key not valid hex\n");
|
2013-04-16 18:05:29 +02:00
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
psk[ j / 2 ] |= c;
|
|
|
|
}
|
|
|
|
}
|
2015-04-08 12:49:31 +02:00
|
|
|
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
|
2013-04-16 18:05:29 +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 );
|
2015-04-28 22:52:30 +02:00
|
|
|
if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
|
2013-06-24 13:01:08 +02:00
|
|
|
(const unsigned char *) pers,
|
|
|
|
strlen( pers ) ) ) != 0 )
|
2011-12-04 18:09:26 +01:00
|
|
|
{
|
2015-04-28 22:52:30 +02:00
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret );
|
2011-12-04 18:09:26 +01:00
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
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
|
2019-03-05 17:10:27 +01:00
|
|
|
#if defined(MBEDTLS_CERTS_C) && 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;
|
|
|
|
}
|
2011-05-26 15:16:06 +02:00
|
|
|
#else
|
|
|
|
{
|
|
|
|
ret = 1;
|
2019-03-05 17:10:27 +01:00
|
|
|
#if !defined(MBEDTLS_CERTS_C)
|
|
|
|
mbedtls_printf( "MBEDTLS_CERTS_C not defined." );
|
|
|
|
#else
|
|
|
|
mbedtls_printf( "All test CRTs loaded via MBEDTLS_CERTS_C are PEM-encoded, but MBEDTLS_PEM_PARSE_C is disabled." );
|
2011-05-26 15:16:06 +02:00
|
|
|
}
|
2019-03-05 17:10:27 +01:00
|
|
|
#endif /* MBEDTLS_CERTS_C */
|
|
|
|
#endif /* MBEDTLS_CERTS_C && MBEDTLS_PEM_PARSE_C */
|
2012-05-16 10:21:05 +02:00
|
|
|
if( ret < 0 )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2015-04-08 12:49:31 +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
|
2019-03-05 17:10:27 +01:00
|
|
|
#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_PEM_PARSE_C)
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt,
|
|
|
|
mbedtls_test_cli_crt_len );
|
2011-05-26 15:16:06 +02:00
|
|
|
#else
|
|
|
|
{
|
|
|
|
ret = 1;
|
2019-03-05 17:10:27 +01:00
|
|
|
#if !defined(MBEDTLS_CERTS_C)
|
|
|
|
mbedtls_printf( "MBEDTLS_CERTS_C not defined." );
|
|
|
|
#else
|
|
|
|
mbedtls_printf( "All test CRTs loaded via MBEDTLS_CERTS_C are PEM-encoded, but MBEDTLS_PEM_PARSE_C is disabled." );
|
2011-05-26 15:16:06 +02:00
|
|
|
}
|
2019-03-05 17:10:27 +01:00
|
|
|
#endif /* MBEDTLS_CERTS_C */
|
|
|
|
#endif /* MBEDTLS_CERTS_C && MBEDTLS_PEM_PARSE_C */
|
2009-01-03 22:22:43 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
{
|
2015-04-08 12:49:31 +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
|
2019-03-05 17:10:27 +01:00
|
|
|
#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_PEM_PARSE_C)
|
2015-04-08 12:49:31 +02:00
|
|
|
ret = mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_cli_key,
|
|
|
|
mbedtls_test_cli_key_len, NULL, 0 );
|
2011-05-26 15:16:06 +02:00
|
|
|
#else
|
|
|
|
{
|
|
|
|
ret = 1;
|
2019-03-05 17:10:27 +01:00
|
|
|
#if !defined(MBEDTLS_CERTS_C)
|
|
|
|
mbedtls_printf( "MBEDTLS_CERTS_C not defined." );
|
|
|
|
#else
|
|
|
|
mbedtls_printf( "All test keys loaded via MBEDTLS_CERTS_C are PEM-encoded, but MBEDTLS_PEM_PARSE_C is disabled." );
|
2011-05-26 15:16:06 +02:00
|
|
|
}
|
2019-03-05 17:10:27 +01:00
|
|
|
#endif /* MBEDTLS_CERTS_C */
|
|
|
|
#endif /* MBEDTLS_CERTS_C && MBEDTLS_PEM_PARSE_C */
|
2009-01-03 22:22:43 +01:00
|
|
|
if( ret != 0 )
|
|
|
|
{
|
2015-04-08 12:49:31 +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;
|
|
|
|
}
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_printf( " ok\n" );
|
|
|
|
#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 );
|
|
|
|
|
2015-04-08 12:49:31 +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
|
|
|
{
|
2015-04-08 12:49:31 +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 )
|
|
|
|
{
|
2015-04-08 12:49:31 +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
|
|
|
{
|
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret );
|
|
|
|
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
|
|
|
|
2012-09-28 09:10:55 +02:00
|
|
|
if( opt.debug_level > 0 )
|
2015-05-11 09:50:24 +02:00
|
|
|
mbedtls_ssl_conf_verify( &conf, my_verify, NULL );
|
2017-05-05 18:59:02 +02:00
|
|
|
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
2012-09-28 09:10:55 +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 )
|
2015-05-11 09:50:24 +02:00
|
|
|
mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max );
|
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
|
|
|
{
|
2015-05-11 09:50:24 +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
|
|
|
|
|
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
|
2015-04-08 12:49:31 +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
|
|
|
{
|
2015-05-11 09:50:24 +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
|
|
|
|
|
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 )
|
|
|
|
{
|
2015-05-11 09:50:24 +02:00
|
|
|
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
|
|
|
{
|
2015-05-11 09:50:24 +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
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
|
2015-05-11 09:50:24 +02:00
|
|
|
if( ( ret = mbedtls_ssl_conf_psk( &conf, psk, psk_len,
|
2014-07-08 14:05:52 +02:00
|
|
|
(const unsigned char *) opt.psk_identity,
|
|
|
|
strlen( opt.psk_identity ) ) ) != 0 )
|
|
|
|
{
|
2015-05-11 09:50:24 +02:00
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_psk returned %d\n\n", ret );
|
2014-07-08 14:05:52 +02:00
|
|
|
goto exit;
|
|
|
|
}
|
2013-04-18 22:46:23 +02:00
|
|
|
#endif
|
|
|
|
|
2015-03-31 14:21:11 +02:00
|
|
|
if( opt.min_version != DFL_MIN_VERSION )
|
2015-05-11 10:11:56 +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 )
|
2015-05-11 10:11:56 +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 )
|
|
|
|
{
|
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ssl_setup returned -0x%x\n\n", -ret );
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
|
|
|
if( ( ret = mbedtls_ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
|
|
|
|
{
|
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
|
|
|
|
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 )
|
|
|
|
{
|
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n", ret );
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-05-11 11:25:46 +02:00
|
|
|
if( opt.nbio == 2 )
|
|
|
|
mbedtls_ssl_set_bio( &ssl, &server_fd, my_send, my_recv, NULL );
|
|
|
|
else
|
|
|
|
mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv,
|
2015-05-14 18:58:17 +02:00
|
|
|
opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
|
2015-05-11 11:25:46 +02:00
|
|
|
|
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
|
|
|
|
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
|
|
|
{
|
2015-05-06 17:19:31 +02:00
|
|
|
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
2009-01-03 22:22:43 +01:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n", -ret );
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_printf( " ok\n [ Protocol is %s ]\n [ Ciphersuite is %s ]\n",
|
|
|
|
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)
|
|
|
|
mbedtls_printf( " [ Maximum fragment length is %u ]\n",
|
|
|
|
(unsigned int) mbedtls_ssl_get_max_frag_len( &ssl ) );
|
|
|
|
#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
|
|
|
|
|
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 );
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_ssl_get_session( &ssl, &saved_session ) ) != 0 )
|
2013-07-30 13:43:43 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ssl_get_session 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
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2015-05-11 19:54:43 +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
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( mbedtls_ssl_get_peer_cert( &ssl ) != NULL )
|
2013-04-16 18:05:29 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_printf( " . Peer certificate information ...\n" );
|
|
|
|
mbedtls_x509_crt_info( (char *) buf, sizeof( buf ) - 1, " ",
|
|
|
|
mbedtls_ssl_get_peer_cert( &ssl ) );
|
|
|
|
mbedtls_printf( "%s\n", buf );
|
2013-04-16 18:05:29 +02:00
|
|
|
}
|
2015-04-08 12:49:31 +02:00
|
|
|
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
2009-01-03 22:22:43 +01: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 &&
|
|
|
|
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
2014-02-20 17:19:59 +01:00
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ssl_renegotiate returned %d\n\n", ret );
|
2014-02-20 17:19:59 +01:00
|
|
|
goto exit;
|
|
|
|
}
|
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
|
|
|
|
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
|
|
|
{
|
2018-07-04 10:29:34 +02:00
|
|
|
while( ( ret = mbedtls_ssl_write( &ssl, buf + written,
|
|
|
|
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 &&
|
|
|
|
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
2014-10-13 18:38:36 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +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;
|
|
|
|
}
|
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 */
|
|
|
|
{
|
2015-04-08 12:49:31 +02:00
|
|
|
do ret = mbedtls_ssl_write( &ssl, buf, len );
|
2015-05-06 17:19:31 +02:00
|
|
|
while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
|
|
|
|
ret == MBEDTLS_ERR_SSL_WANT_WRITE );
|
2014-10-13 18:38:36 +02:00
|
|
|
|
|
|
|
if( ret < 0 )
|
|
|
|
{
|
2015-04-08 12:49:31 +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';
|
2015-04-08 12:49:31 +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
|
|
|
|
2015-05-06 17:19:31 +02:00
|
|
|
if( ret == MBEDTLS_ERR_SSL_WANT_READ ||
|
|
|
|
ret == MBEDTLS_ERR_SSL_WANT_WRITE )
|
2014-07-11 14:14:15 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
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:
|
2015-04-08 12:49:31 +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 ) );
|
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
do ret = mbedtls_ssl_read( &ssl, buf, len );
|
2015-05-06 17:19:31 +02:00
|
|
|
while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
|
|
|
|
ret == MBEDTLS_ERR_SSL_WANT_WRITE );
|
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
|
|
|
* 7b. 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 );
|
|
|
|
|
|
|
|
if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 )
|
|
|
|
{
|
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ssl_session_reset returned -0x%x\n\n", -ret );
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
|
|
|
|
{
|
|
|
|
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
|
|
|
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
|
|
|
{
|
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret );
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mbedtls_printf( " ok\n" );
|
|
|
|
|
|
|
|
goto send_request;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 7c. 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
|
|
|
|
2015-04-08 12:49:31 +02:00
|
|
|
if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 )
|
2013-07-30 13:43:43 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +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;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2015-05-11 09:50:24 +02:00
|
|
|
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_session returned %d\n\n", ret );
|
2014-07-08 14:05:52 +02:00
|
|
|
goto exit;
|
|
|
|
}
|
2013-07-30 13:43:43 +02:00
|
|
|
|
2015-04-08 12:49:31 +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
|
|
|
{
|
2015-04-08 12:49:31 +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",
|
2014-10-02 17:59:19 +02:00
|
|
|
-ret );
|
|
|
|
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 &&
|
|
|
|
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
2013-07-30 13:43:43 +02:00
|
|
|
{
|
2015-04-08 12:49:31 +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 );
|
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 );
|
2009-01-03 22:22:43 +01:00
|
|
|
|
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;
|
|
|
|
|
2019-04-24 14:24:46 +02:00
|
|
|
mbedtls_exit( ret );
|
2009-01-03 22:22:43 +01:00
|
|
|
}
|
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 */
|