1a8e1175bSopenharmony_ci/*
2a8e1175bSopenharmony_ci *  SSL client with options
3a8e1175bSopenharmony_ci *
4a8e1175bSopenharmony_ci *  Copyright The Mbed TLS Contributors
5a8e1175bSopenharmony_ci *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6a8e1175bSopenharmony_ci */
7a8e1175bSopenharmony_ci
8a8e1175bSopenharmony_ci#define MBEDTLS_ALLOW_PRIVATE_ACCESS
9a8e1175bSopenharmony_ci
10a8e1175bSopenharmony_ci#include "ssl_test_lib.h"
11a8e1175bSopenharmony_ci
12a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TEST_IMPOSSIBLE)
13a8e1175bSopenharmony_ciint main(void)
14a8e1175bSopenharmony_ci{
15a8e1175bSopenharmony_ci    mbedtls_printf(MBEDTLS_SSL_TEST_IMPOSSIBLE);
16a8e1175bSopenharmony_ci    mbedtls_exit(0);
17a8e1175bSopenharmony_ci}
18a8e1175bSopenharmony_ci#elif !defined(MBEDTLS_SSL_SRV_C)
19a8e1175bSopenharmony_ciint main(void)
20a8e1175bSopenharmony_ci{
21a8e1175bSopenharmony_ci    mbedtls_printf("MBEDTLS_SSL_SRV_C not defined.\n");
22a8e1175bSopenharmony_ci    mbedtls_exit(0);
23a8e1175bSopenharmony_ci}
24a8e1175bSopenharmony_ci#else /* !MBEDTLS_SSL_TEST_IMPOSSIBLE && MBEDTLS_SSL_SRV_C */
25a8e1175bSopenharmony_ci
26a8e1175bSopenharmony_ci#include <stdint.h>
27a8e1175bSopenharmony_ci
28a8e1175bSopenharmony_ci#if !defined(_MSC_VER)
29a8e1175bSopenharmony_ci#include <inttypes.h>
30a8e1175bSopenharmony_ci#endif
31a8e1175bSopenharmony_ci
32a8e1175bSopenharmony_ci#if !defined(_WIN32)
33a8e1175bSopenharmony_ci#include <signal.h>
34a8e1175bSopenharmony_ci#endif
35a8e1175bSopenharmony_ci
36a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C)
37a8e1175bSopenharmony_ci#include "mbedtls/ssl_cache.h"
38a8e1175bSopenharmony_ci#endif
39a8e1175bSopenharmony_ci
40a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C)
41a8e1175bSopenharmony_ci#include "mbedtls/ssl_ticket.h"
42a8e1175bSopenharmony_ci#endif
43a8e1175bSopenharmony_ci
44a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_COOKIE_C)
45a8e1175bSopenharmony_ci#include "mbedtls/ssl_cookie.h"
46a8e1175bSopenharmony_ci#endif
47a8e1175bSopenharmony_ci
48a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) && defined(MBEDTLS_FS_IO)
49a8e1175bSopenharmony_ci#define SNI_OPTION
50a8e1175bSopenharmony_ci#endif
51a8e1175bSopenharmony_ci
52a8e1175bSopenharmony_ci#if defined(_WIN32)
53a8e1175bSopenharmony_ci#include <windows.h>
54a8e1175bSopenharmony_ci#endif
55a8e1175bSopenharmony_ci
56a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
57a8e1175bSopenharmony_ci#include "test/psa_crypto_helpers.h"
58a8e1175bSopenharmony_ci#endif
59a8e1175bSopenharmony_ci
60a8e1175bSopenharmony_ci#include "mbedtls/pk.h"
61a8e1175bSopenharmony_ci#include "mbedtls/dhm.h"
62a8e1175bSopenharmony_ci
63a8e1175bSopenharmony_ci/* Size of memory to be allocated for the heap, when using the library's memory
64a8e1175bSopenharmony_ci * management and MBEDTLS_MEMORY_BUFFER_ALLOC_C is enabled. */
65a8e1175bSopenharmony_ci#define MEMORY_HEAP_SIZE        180000
66a8e1175bSopenharmony_ci
67a8e1175bSopenharmony_ci#define DFL_SERVER_ADDR         NULL
68a8e1175bSopenharmony_ci#define DFL_SERVER_PORT         "4433"
69a8e1175bSopenharmony_ci#define DFL_RESPONSE_SIZE       -1
70a8e1175bSopenharmony_ci#define DFL_DEBUG_LEVEL         0
71a8e1175bSopenharmony_ci#define DFL_NBIO                0
72a8e1175bSopenharmony_ci#define DFL_EVENT               0
73a8e1175bSopenharmony_ci#define DFL_READ_TIMEOUT        0
74a8e1175bSopenharmony_ci#define DFL_CA_FILE             ""
75a8e1175bSopenharmony_ci#define DFL_CA_PATH             ""
76a8e1175bSopenharmony_ci#define DFL_CRT_FILE            ""
77a8e1175bSopenharmony_ci#define DFL_KEY_FILE            ""
78a8e1175bSopenharmony_ci#define DFL_KEY_OPAQUE          0
79a8e1175bSopenharmony_ci#define DFL_KEY_PWD             ""
80a8e1175bSopenharmony_ci#define DFL_CRT_FILE2           ""
81a8e1175bSopenharmony_ci#define DFL_KEY_FILE2           ""
82a8e1175bSopenharmony_ci#define DFL_KEY_PWD2            ""
83a8e1175bSopenharmony_ci#define DFL_ASYNC_OPERATIONS    "-"
84a8e1175bSopenharmony_ci#define DFL_ASYNC_PRIVATE_DELAY1 (-1)
85a8e1175bSopenharmony_ci#define DFL_ASYNC_PRIVATE_DELAY2 (-1)
86a8e1175bSopenharmony_ci#define DFL_ASYNC_PRIVATE_ERROR  (0)
87a8e1175bSopenharmony_ci#define DFL_PSK                 ""
88a8e1175bSopenharmony_ci#define DFL_PSK_OPAQUE          0
89a8e1175bSopenharmony_ci#define DFL_PSK_LIST_OPAQUE     0
90a8e1175bSopenharmony_ci#define DFL_PSK_IDENTITY        "Client_identity"
91a8e1175bSopenharmony_ci#define DFL_ECJPAKE_PW          NULL
92a8e1175bSopenharmony_ci#define DFL_ECJPAKE_PW_OPAQUE   0
93a8e1175bSopenharmony_ci#define DFL_PSK_LIST            NULL
94a8e1175bSopenharmony_ci#define DFL_FORCE_CIPHER        0
95a8e1175bSopenharmony_ci#define DFL_TLS1_3_KEX_MODES    MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL
96a8e1175bSopenharmony_ci#define DFL_RENEGOTIATION       MBEDTLS_SSL_RENEGOTIATION_DISABLED
97a8e1175bSopenharmony_ci#define DFL_ALLOW_LEGACY        -2
98a8e1175bSopenharmony_ci#define DFL_RENEGOTIATE         0
99a8e1175bSopenharmony_ci#define DFL_RENEGO_DELAY        -2
100a8e1175bSopenharmony_ci#define DFL_RENEGO_PERIOD       ((uint64_t) -1)
101a8e1175bSopenharmony_ci#define DFL_EXCHANGES           1
102a8e1175bSopenharmony_ci#define DFL_MIN_VERSION         -1
103a8e1175bSopenharmony_ci#define DFL_MAX_VERSION         -1
104a8e1175bSopenharmony_ci#define DFL_SHA1                -1
105a8e1175bSopenharmony_ci#define DFL_CID_ENABLED         0
106a8e1175bSopenharmony_ci#define DFL_CID_VALUE           ""
107a8e1175bSopenharmony_ci#define DFL_CID_ENABLED_RENEGO  -1
108a8e1175bSopenharmony_ci#define DFL_CID_VALUE_RENEGO    NULL
109a8e1175bSopenharmony_ci#define DFL_AUTH_MODE           -1
110a8e1175bSopenharmony_ci#define DFL_CERT_REQ_CA_LIST    MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED
111a8e1175bSopenharmony_ci#define DFL_CERT_REQ_DN_HINT    0
112a8e1175bSopenharmony_ci#define DFL_MFL_CODE            MBEDTLS_SSL_MAX_FRAG_LEN_NONE
113a8e1175bSopenharmony_ci#define DFL_TRUNC_HMAC          -1
114a8e1175bSopenharmony_ci#define DFL_TICKETS             MBEDTLS_SSL_SESSION_TICKETS_ENABLED
115a8e1175bSopenharmony_ci#define DFL_DUMMY_TICKET        0
116a8e1175bSopenharmony_ci#define DFL_TICKET_ROTATE       0
117a8e1175bSopenharmony_ci#define DFL_TICKET_TIMEOUT      86400
118a8e1175bSopenharmony_ci#define DFL_TICKET_AEAD         MBEDTLS_CIPHER_AES_256_GCM
119a8e1175bSopenharmony_ci#define DFL_CACHE_MAX           -1
120a8e1175bSopenharmony_ci#define DFL_CACHE_TIMEOUT       -1
121a8e1175bSopenharmony_ci#define DFL_CACHE_REMOVE        0
122a8e1175bSopenharmony_ci#define DFL_SNI                 NULL
123a8e1175bSopenharmony_ci#define DFL_ALPN_STRING         NULL
124a8e1175bSopenharmony_ci#define DFL_GROUPS              NULL
125a8e1175bSopenharmony_ci#define DFL_EARLY_DATA          -1
126a8e1175bSopenharmony_ci#define DFL_MAX_EARLY_DATA_SIZE ((uint32_t) -1)
127a8e1175bSopenharmony_ci#define DFL_SIG_ALGS            NULL
128a8e1175bSopenharmony_ci#define DFL_DHM_FILE            NULL
129a8e1175bSopenharmony_ci#define DFL_TRANSPORT           MBEDTLS_SSL_TRANSPORT_STREAM
130a8e1175bSopenharmony_ci#define DFL_COOKIES             1
131a8e1175bSopenharmony_ci#define DFL_ANTI_REPLAY         -1
132a8e1175bSopenharmony_ci#define DFL_HS_TO_MIN           0
133a8e1175bSopenharmony_ci#define DFL_HS_TO_MAX           0
134a8e1175bSopenharmony_ci#define DFL_DTLS_MTU            -1
135a8e1175bSopenharmony_ci#define DFL_BADMAC_LIMIT        -1
136a8e1175bSopenharmony_ci#define DFL_DGRAM_PACKING        1
137a8e1175bSopenharmony_ci#define DFL_EXTENDED_MS         -1
138a8e1175bSopenharmony_ci#define DFL_ETM                 -1
139a8e1175bSopenharmony_ci#define DFL_SERIALIZE           0
140a8e1175bSopenharmony_ci#define DFL_CONTEXT_FILE        ""
141a8e1175bSopenharmony_ci#define DFL_EXTENDED_MS_ENFORCE -1
142a8e1175bSopenharmony_ci#define DFL_CA_CALLBACK         0
143a8e1175bSopenharmony_ci#define DFL_EAP_TLS             0
144a8e1175bSopenharmony_ci#define DFL_REPRODUCIBLE        0
145a8e1175bSopenharmony_ci#define DFL_NSS_KEYLOG          0
146a8e1175bSopenharmony_ci#define DFL_NSS_KEYLOG_FILE     NULL
147a8e1175bSopenharmony_ci#define DFL_QUERY_CONFIG_MODE   0
148a8e1175bSopenharmony_ci#define DFL_USE_SRTP            0
149a8e1175bSopenharmony_ci#define DFL_SRTP_FORCE_PROFILE  0
150a8e1175bSopenharmony_ci#define DFL_SRTP_SUPPORT_MKI    0
151a8e1175bSopenharmony_ci#define DFL_KEY_OPAQUE_ALG      "none"
152a8e1175bSopenharmony_ci
153a8e1175bSopenharmony_ci#define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
154a8e1175bSopenharmony_ci                      "02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n"  \
155a8e1175bSopenharmony_ci                      "03-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n"  \
156a8e1175bSopenharmony_ci                      "04-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n"  \
157a8e1175bSopenharmony_ci                      "05-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n"  \
158a8e1175bSopenharmony_ci                      "06-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n"  \
159a8e1175bSopenharmony_ci                      "07-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah</p>\r\n"
160a8e1175bSopenharmony_ci
161a8e1175bSopenharmony_ci/* Uncomment LONG_RESPONSE at the end of HTTP_RESPONSE to test sending longer
162a8e1175bSopenharmony_ci * packets (for fragmentation purposes) */
163a8e1175bSopenharmony_ci#define HTTP_RESPONSE \
164a8e1175bSopenharmony_ci    "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \
165a8e1175bSopenharmony_ci    "<h2>Mbed TLS Test Server</h2>\r\n" \
166a8e1175bSopenharmony_ci    "<p>Successful connection using: %s</p>\r\n" // LONG_RESPONSE
167a8e1175bSopenharmony_ci
168a8e1175bSopenharmony_ci/*
169a8e1175bSopenharmony_ci * Size of the basic I/O buffer. Able to hold our default response.
170a8e1175bSopenharmony_ci */
171a8e1175bSopenharmony_ci#define DFL_IO_BUF_LEN      200
172a8e1175bSopenharmony_ci
173a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
174a8e1175bSopenharmony_ci#if defined(MBEDTLS_FS_IO)
175a8e1175bSopenharmony_ci#define USAGE_IO \
176a8e1175bSopenharmony_ci    "    ca_file=%%s          The single file containing the top-level CA(s) you fully trust\n" \
177a8e1175bSopenharmony_ci    "                        default: \"\" (pre-loaded)\n" \
178a8e1175bSopenharmony_ci    "                        use \"none\" to skip loading any top-level CAs.\n" \
179a8e1175bSopenharmony_ci    "    ca_path=%%s          The path containing the top-level CA(s) you fully trust\n" \
180a8e1175bSopenharmony_ci    "                        default: \"\" (pre-loaded) (overrides ca_file)\n" \
181a8e1175bSopenharmony_ci    "                        use \"none\" to skip loading any top-level CAs.\n" \
182a8e1175bSopenharmony_ci    "    crt_file=%%s         Your own cert and chain (in bottom to top order, top may be omitted)\n" \
183a8e1175bSopenharmony_ci    "                        default: see note after key_file2\n" \
184a8e1175bSopenharmony_ci    "    key_file=%%s         default: see note after key_file2\n" \
185a8e1175bSopenharmony_ci    "    key_pwd=%%s          Password for key specified by key_file argument\n" \
186a8e1175bSopenharmony_ci    "                        default: none\n" \
187a8e1175bSopenharmony_ci    "    crt_file2=%%s        Your second cert and chain (in bottom to top order, top may be omitted)\n" \
188a8e1175bSopenharmony_ci    "                        default: see note after key_file2\n" \
189a8e1175bSopenharmony_ci    "    key_file2=%%s        default: see note below\n" \
190a8e1175bSopenharmony_ci    "                        note: if neither crt_file/key_file nor crt_file2/key_file2 are used,\n" \
191a8e1175bSopenharmony_ci    "                              preloaded certificate(s) and key(s) are used if available\n" \
192a8e1175bSopenharmony_ci    "    key_pwd2=%%s         Password for key specified by key_file2 argument\n" \
193a8e1175bSopenharmony_ci    "                        default: none\n" \
194a8e1175bSopenharmony_ci    "    dhm_file=%%s        File containing Diffie-Hellman parameters\n" \
195a8e1175bSopenharmony_ci    "                       default: preloaded parameters\n"
196a8e1175bSopenharmony_ci#else
197a8e1175bSopenharmony_ci#define USAGE_IO \
198a8e1175bSopenharmony_ci    "\n"                                                    \
199a8e1175bSopenharmony_ci    "    No file operations available (MBEDTLS_FS_IO not defined)\n" \
200a8e1175bSopenharmony_ci    "\n"
201a8e1175bSopenharmony_ci#endif /* MBEDTLS_FS_IO */
202a8e1175bSopenharmony_ci#else
203a8e1175bSopenharmony_ci#define USAGE_IO ""
204a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
205a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
206a8e1175bSopenharmony_ci#define USAGE_KEY_OPAQUE \
207a8e1175bSopenharmony_ci    "    key_opaque=%%d       Handle your private keys as if they were opaque\n" \
208a8e1175bSopenharmony_ci    "                        default: 0 (disabled)\n"
209a8e1175bSopenharmony_ci#else
210a8e1175bSopenharmony_ci#define USAGE_KEY_OPAQUE ""
211a8e1175bSopenharmony_ci#endif
212a8e1175bSopenharmony_ci
213a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
214a8e1175bSopenharmony_ci#define USAGE_SSL_ASYNC \
215a8e1175bSopenharmony_ci    "    async_operations=%%c...   d=decrypt, s=sign (default: -=off)\n" \
216a8e1175bSopenharmony_ci    "    async_private_delay1=%%d  Asynchronous delay for key_file or preloaded key\n" \
217a8e1175bSopenharmony_ci    "    async_private_delay2=%%d  Asynchronous delay for key_file2 and sni\n" \
218a8e1175bSopenharmony_ci    "                              default: -1 (not asynchronous)\n" \
219a8e1175bSopenharmony_ci    "    async_private_error=%%d   Async callback error injection (default=0=none,\n" \
220a8e1175bSopenharmony_ci    "                              1=start, 2=cancel, 3=resume, negative=first time only)"
221a8e1175bSopenharmony_ci#else
222a8e1175bSopenharmony_ci#define USAGE_SSL_ASYNC ""
223a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
224a8e1175bSopenharmony_ci
225a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
226a8e1175bSopenharmony_ci#define USAGE_CID \
227a8e1175bSopenharmony_ci    "    cid=%%d             Disable (0) or enable (1) the use of the DTLS Connection ID extension.\n" \
228a8e1175bSopenharmony_ci    "                       default: 0 (disabled)\n"     \
229a8e1175bSopenharmony_ci    "    cid_renego=%%d      Disable (0) or enable (1) the use of the DTLS Connection ID extension during renegotiation.\n" \
230a8e1175bSopenharmony_ci    "                       default: same as 'cid' parameter\n"     \
231a8e1175bSopenharmony_ci    "    cid_val=%%s          The CID to use for incoming messages (in hex, without 0x).\n"  \
232a8e1175bSopenharmony_ci    "                        default: \"\"\n" \
233a8e1175bSopenharmony_ci    "    cid_val_renego=%%s   The CID to use for incoming messages (in hex, without 0x) after renegotiation.\n"  \
234a8e1175bSopenharmony_ci    "                        default: same as 'cid_val' parameter\n"
235a8e1175bSopenharmony_ci#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
236a8e1175bSopenharmony_ci#define USAGE_CID ""
237a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
238a8e1175bSopenharmony_ci
239a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
240a8e1175bSopenharmony_ci#define USAGE_PSK_RAW                                               \
241a8e1175bSopenharmony_ci    "    psk=%%s              default: \"\" (disabled)\n"     \
242a8e1175bSopenharmony_ci    "                          The PSK values are in hex, without 0x.\n" \
243a8e1175bSopenharmony_ci    "    psk_list=%%s         default: \"\"\n"                          \
244a8e1175bSopenharmony_ci    "                          A list of (PSK identity, PSK value) pairs.\n" \
245a8e1175bSopenharmony_ci    "                          The PSK values are in hex, without 0x.\n" \
246a8e1175bSopenharmony_ci    "                          id1,psk1[,id2,psk2[,...]]\n"             \
247a8e1175bSopenharmony_ci    "    psk_identity=%%s     default: \"Client_identity\"\n"
248a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
249a8e1175bSopenharmony_ci#define USAGE_PSK_SLOT                          \
250a8e1175bSopenharmony_ci    "    psk_opaque=%%d       default: 0 (don't use opaque static PSK)\n"     \
251a8e1175bSopenharmony_ci    "                          Enable this to store the PSK configured through command line\n" \
252a8e1175bSopenharmony_ci    "                          parameter `psk` in a PSA-based key slot.\n" \
253a8e1175bSopenharmony_ci    "                          Note: Currently only supported in conjunction with\n"                  \
254a8e1175bSopenharmony_ci    "                          the use of min_version to force TLS 1.2 and force_ciphersuite \n"      \
255a8e1175bSopenharmony_ci    "                          to force a particular PSK-only ciphersuite.\n"                         \
256a8e1175bSopenharmony_ci    "                          Note: This is to test integration of PSA-based opaque PSKs with\n"     \
257a8e1175bSopenharmony_ci    "                          Mbed TLS only. Production systems are likely to configure Mbed TLS\n"  \
258a8e1175bSopenharmony_ci    "                          with prepopulated key slots instead of importing raw key material.\n" \
259a8e1175bSopenharmony_ci    "    psk_list_opaque=%%d  default: 0 (don't use opaque dynamic PSKs)\n"     \
260a8e1175bSopenharmony_ci    "                          Enable this to store the list of dynamically chosen PSKs configured\n" \
261a8e1175bSopenharmony_ci    "                          through the command line parameter `psk_list` in PSA-based key slots.\n" \
262a8e1175bSopenharmony_ci    "                          Note: Currently only supported in conjunction with\n" \
263a8e1175bSopenharmony_ci    "                          the use of min_version to force TLS 1.2 and force_ciphersuite \n" \
264a8e1175bSopenharmony_ci    "                          to force a particular PSK-only ciphersuite.\n" \
265a8e1175bSopenharmony_ci    "                          Note: This is to test integration of PSA-based opaque PSKs with\n" \
266a8e1175bSopenharmony_ci    "                          Mbed TLS only. Production systems are likely to configure Mbed TLS\n" \
267a8e1175bSopenharmony_ci    "                          with prepopulated key slots instead of importing raw key material.\n"
268a8e1175bSopenharmony_ci#else
269a8e1175bSopenharmony_ci#define USAGE_PSK_SLOT ""
270a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
271a8e1175bSopenharmony_ci#define USAGE_PSK USAGE_PSK_RAW USAGE_PSK_SLOT
272a8e1175bSopenharmony_ci#else
273a8e1175bSopenharmony_ci#define USAGE_PSK ""
274a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
275a8e1175bSopenharmony_ci
276a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
277a8e1175bSopenharmony_ci#define USAGE_CA_CALLBACK                       \
278a8e1175bSopenharmony_ci    "   ca_callback=%%d       default: 0 (disabled)\n"      \
279a8e1175bSopenharmony_ci    "                         Enable this to use the trusted certificate callback function\n"
280a8e1175bSopenharmony_ci#else
281a8e1175bSopenharmony_ci#define USAGE_CA_CALLBACK ""
282a8e1175bSopenharmony_ci#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
283a8e1175bSopenharmony_ci
284a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C)
285a8e1175bSopenharmony_ci#define USAGE_TICKETS                                       \
286a8e1175bSopenharmony_ci    "    tickets=%%d          default: 1 (enabled)\n"       \
287a8e1175bSopenharmony_ci    "    ticket_rotate=%%d    default: 0 (disabled)\n"      \
288a8e1175bSopenharmony_ci    "    ticket_timeout=%%d   default: 86400 (one day)\n"   \
289a8e1175bSopenharmony_ci    "    ticket_aead=%%s      default: \"AES-256-GCM\"\n"
290a8e1175bSopenharmony_ci#else /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_TICKET_C */
291a8e1175bSopenharmony_ci#define USAGE_TICKETS ""
292a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_TICKET_C */
293a8e1175bSopenharmony_ci
294a8e1175bSopenharmony_ci#define USAGE_EAP_TLS                                       \
295a8e1175bSopenharmony_ci    "    eap_tls=%%d          default: 0 (disabled)\n"
296a8e1175bSopenharmony_ci#define USAGE_NSS_KEYLOG                                    \
297a8e1175bSopenharmony_ci    "    nss_keylog=%%d          default: 0 (disabled)\n"   \
298a8e1175bSopenharmony_ci    "                             This cannot be used with eap_tls=1\n"
299a8e1175bSopenharmony_ci#define USAGE_NSS_KEYLOG_FILE                               \
300a8e1175bSopenharmony_ci    "    nss_keylog_file=%%s\n"
301a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP)
302a8e1175bSopenharmony_ci#define USAGE_SRTP \
303a8e1175bSopenharmony_ci    "    use_srtp=%%d         default: 0 (disabled)\n" \
304a8e1175bSopenharmony_ci    "    srtp_force_profile=%%d  default: 0 (all enabled)\n"   \
305a8e1175bSopenharmony_ci    "                        available profiles:\n"       \
306a8e1175bSopenharmony_ci    "                        1 - SRTP_AES128_CM_HMAC_SHA1_80\n"  \
307a8e1175bSopenharmony_ci    "                        2 - SRTP_AES128_CM_HMAC_SHA1_32\n"  \
308a8e1175bSopenharmony_ci    "                        3 - SRTP_NULL_HMAC_SHA1_80\n"       \
309a8e1175bSopenharmony_ci    "                        4 - SRTP_NULL_HMAC_SHA1_32\n"       \
310a8e1175bSopenharmony_ci    "    support_mki=%%d     default: 0 (not supported)\n"
311a8e1175bSopenharmony_ci#else /* MBEDTLS_SSL_DTLS_SRTP */
312a8e1175bSopenharmony_ci#define USAGE_SRTP ""
313a8e1175bSopenharmony_ci#endif
314a8e1175bSopenharmony_ci
315a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C)
316a8e1175bSopenharmony_ci#define USAGE_CACHE                                             \
317a8e1175bSopenharmony_ci    "    cache_max=%%d        default: cache default (50)\n"    \
318a8e1175bSopenharmony_ci    "    cache_remove=%%d     default: 0 (don't remove)\n"
319a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME)
320a8e1175bSopenharmony_ci#define USAGE_CACHE_TIME \
321a8e1175bSopenharmony_ci    "    cache_timeout=%%d    default: cache default (1d)\n"
322a8e1175bSopenharmony_ci#else
323a8e1175bSopenharmony_ci#define USAGE_CACHE_TIME ""
324a8e1175bSopenharmony_ci#endif
325a8e1175bSopenharmony_ci#else
326a8e1175bSopenharmony_ci#define USAGE_CACHE ""
327a8e1175bSopenharmony_ci#define USAGE_CACHE_TIME ""
328a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_CACHE_C */
329a8e1175bSopenharmony_ci
330a8e1175bSopenharmony_ci#if defined(SNI_OPTION)
331a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_CRL_PARSE_C)
332a8e1175bSopenharmony_ci#define SNI_CRL              ",crl"
333a8e1175bSopenharmony_ci#else
334a8e1175bSopenharmony_ci#define SNI_CRL              ""
335a8e1175bSopenharmony_ci#endif
336a8e1175bSopenharmony_ci
337a8e1175bSopenharmony_ci#define USAGE_SNI                                                           \
338a8e1175bSopenharmony_ci    "    sni=%%s              name1,cert1,key1,ca1"SNI_CRL ",auth1[,...]\n"  \
339a8e1175bSopenharmony_ci                                                           "                        default: disabled\n"
340a8e1175bSopenharmony_ci#else
341a8e1175bSopenharmony_ci#define USAGE_SNI ""
342a8e1175bSopenharmony_ci#endif /* SNI_OPTION */
343a8e1175bSopenharmony_ci
344a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
345a8e1175bSopenharmony_ci#define USAGE_MAX_FRAG_LEN                                      \
346a8e1175bSopenharmony_ci    "    max_frag_len=%%d     default: 16384 (tls default)\n"   \
347a8e1175bSopenharmony_ci    "                        options: 512, 1024, 2048, 4096\n"
348a8e1175bSopenharmony_ci#else
349a8e1175bSopenharmony_ci#define USAGE_MAX_FRAG_LEN ""
350a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
351a8e1175bSopenharmony_ci
352a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN)
353a8e1175bSopenharmony_ci#define USAGE_ALPN \
354a8e1175bSopenharmony_ci    "    alpn=%%s             default: \"\" (disabled)\n"   \
355a8e1175bSopenharmony_ci    "                        example: spdy/1,http/1.1\n"
356a8e1175bSopenharmony_ci#else
357a8e1175bSopenharmony_ci#define USAGE_ALPN ""
358a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ALPN */
359a8e1175bSopenharmony_ci
360a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
361a8e1175bSopenharmony_ci#define USAGE_COOKIES \
362a8e1175bSopenharmony_ci    "    cookies=0/1/-1      default: 1 (enabled)\n"        \
363a8e1175bSopenharmony_ci    "                        0: disabled, -1: library default (broken)\n"
364a8e1175bSopenharmony_ci#else
365a8e1175bSopenharmony_ci#define USAGE_COOKIES ""
366a8e1175bSopenharmony_ci#endif
367a8e1175bSopenharmony_ci
368a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
369a8e1175bSopenharmony_ci#define USAGE_ANTI_REPLAY \
370a8e1175bSopenharmony_ci    "    anti_replay=0/1     default: (library default: enabled)\n"
371a8e1175bSopenharmony_ci#else
372a8e1175bSopenharmony_ci#define USAGE_ANTI_REPLAY ""
373a8e1175bSopenharmony_ci#endif
374a8e1175bSopenharmony_ci
375a8e1175bSopenharmony_ci#define USAGE_BADMAC_LIMIT \
376a8e1175bSopenharmony_ci    "    badmac_limit=%%d     default: (library default: disabled)\n"
377a8e1175bSopenharmony_ci
378a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
379a8e1175bSopenharmony_ci#define USAGE_DTLS \
380a8e1175bSopenharmony_ci    "    dtls=%%d             default: 0 (TLS)\n"                           \
381a8e1175bSopenharmony_ci    "    hs_timeout=%%d-%%d    default: (library default: 1000-60000)\n"    \
382a8e1175bSopenharmony_ci    "                        range of DTLS handshake timeouts in millisecs\n" \
383a8e1175bSopenharmony_ci    "    mtu=%%d              default: (library default: unlimited)\n"  \
384a8e1175bSopenharmony_ci    "    dgram_packing=%%d    default: 1 (allowed)\n"                   \
385a8e1175bSopenharmony_ci    "                        allow or forbid packing of multiple\n" \
386a8e1175bSopenharmony_ci    "                        records within a single datgram.\n"
387a8e1175bSopenharmony_ci#else
388a8e1175bSopenharmony_ci#define USAGE_DTLS ""
389a8e1175bSopenharmony_ci#endif
390a8e1175bSopenharmony_ci
391a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
392a8e1175bSopenharmony_ci#define USAGE_EMS \
393a8e1175bSopenharmony_ci    "    extended_ms=0/1     default: (library default: on)\n"
394a8e1175bSopenharmony_ci#else
395a8e1175bSopenharmony_ci#define USAGE_EMS ""
396a8e1175bSopenharmony_ci#endif
397a8e1175bSopenharmony_ci
398a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
399a8e1175bSopenharmony_ci#define USAGE_ETM \
400a8e1175bSopenharmony_ci    "    etm=0/1             default: (library default: on)\n"
401a8e1175bSopenharmony_ci#else
402a8e1175bSopenharmony_ci#define USAGE_ETM ""
403a8e1175bSopenharmony_ci#endif
404a8e1175bSopenharmony_ci
405a8e1175bSopenharmony_ci#define USAGE_REPRODUCIBLE \
406a8e1175bSopenharmony_ci    "    reproducible=0/1     default: 0 (disabled)\n"
407a8e1175bSopenharmony_ci
408a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION)
409a8e1175bSopenharmony_ci#define USAGE_RENEGO \
410a8e1175bSopenharmony_ci    "    renegotiation=%%d    default: 0 (disabled)\n"      \
411a8e1175bSopenharmony_ci    "    renegotiate=%%d      default: 0 (disabled)\n"      \
412a8e1175bSopenharmony_ci    "    renego_delay=%%d     default: -2 (library default)\n" \
413a8e1175bSopenharmony_ci    "    renego_period=%%d    default: (2^64 - 1 for TLS, 2^48 - 1 for DTLS)\n"
414a8e1175bSopenharmony_ci#else
415a8e1175bSopenharmony_ci#define USAGE_RENEGO ""
416a8e1175bSopenharmony_ci#endif
417a8e1175bSopenharmony_ci
418a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
419a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
420a8e1175bSopenharmony_ci#define USAGE_ECJPAKE \
421a8e1175bSopenharmony_ci    "    ecjpake_pw=%%s           default: none (disabled)\n"   \
422a8e1175bSopenharmony_ci    "    ecjpake_pw_opaque=%%d    default: 0 (disabled)\n"
423a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */
424a8e1175bSopenharmony_ci#define USAGE_ECJPAKE \
425a8e1175bSopenharmony_ci    "    ecjpake_pw=%%s           default: none (disabled)\n"
426a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
427a8e1175bSopenharmony_ci#else /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
428a8e1175bSopenharmony_ci#define USAGE_ECJPAKE ""
429a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
430a8e1175bSopenharmony_ci
431a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
432a8e1175bSopenharmony_ci#define USAGE_EARLY_DATA \
433a8e1175bSopenharmony_ci    "    early_data=%%d      default: library default\n" \
434a8e1175bSopenharmony_ci    "                        options: 0 (disabled), 1 (enabled)\n" \
435a8e1175bSopenharmony_ci    "    max_early_data_size=%%d default: library default\n" \
436a8e1175bSopenharmony_ci    "                            options: max amount of early data\n"
437a8e1175bSopenharmony_ci#else
438a8e1175bSopenharmony_ci#define USAGE_EARLY_DATA ""
439a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
440a8e1175bSopenharmony_ci
441a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) || \
442a8e1175bSopenharmony_ci    (defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) && \
443a8e1175bSopenharmony_ci    defined(PSA_WANT_ALG_FFDH))
444a8e1175bSopenharmony_ci#define USAGE_GROUPS \
445a8e1175bSopenharmony_ci    "    groups=a,b,c,d      default: \"default\" (library default)\n"  \
446a8e1175bSopenharmony_ci    "                        example: \"secp521r1,brainpoolP512r1\"\n"  \
447a8e1175bSopenharmony_ci    "                        - use \"none\" for empty list\n"           \
448a8e1175bSopenharmony_ci    "                        - see mbedtls_ecp_curve_list()\n"                \
449a8e1175bSopenharmony_ci    "                          for acceptable EC group names\n"               \
450a8e1175bSopenharmony_ci    "                        - the following ffdh groups are supported:\n"    \
451a8e1175bSopenharmony_ci    "                          ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144,\n" \
452a8e1175bSopenharmony_ci    "                          ffdhe8192\n"
453a8e1175bSopenharmony_ci#else
454a8e1175bSopenharmony_ci#define USAGE_GROUPS ""
455a8e1175bSopenharmony_ci#endif
456a8e1175bSopenharmony_ci
457a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
458a8e1175bSopenharmony_ci#define USAGE_SIG_ALGS \
459a8e1175bSopenharmony_ci    "    sig_algs=a,b,c,d      default: \"default\" (library default)\n"  \
460a8e1175bSopenharmony_ci    "                          example: \"ecdsa_secp256r1_sha256,ecdsa_secp384r1_sha384\"\n"
461a8e1175bSopenharmony_ci#else
462a8e1175bSopenharmony_ci#define USAGE_SIG_ALGS ""
463a8e1175bSopenharmony_ci#endif
464a8e1175bSopenharmony_ci
465a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
466a8e1175bSopenharmony_ci#define USAGE_SERIALIZATION \
467a8e1175bSopenharmony_ci    "    serialize=%%d        default: 0 (do not serialize/deserialize)\n"     \
468a8e1175bSopenharmony_ci    "                        options: 1 (serialize)\n"                         \
469a8e1175bSopenharmony_ci    "                                 2 (serialize with re-initialization)\n"  \
470a8e1175bSopenharmony_ci    "    context_file=%%s     The file path to write a serialized connection\n" \
471a8e1175bSopenharmony_ci    "                        in the form of base64 code (serialize option\n"   \
472a8e1175bSopenharmony_ci    "                        must be set)\n"                                   \
473a8e1175bSopenharmony_ci    "                         default: \"\" (do nothing)\n"                    \
474a8e1175bSopenharmony_ci    "                         option: a file path\n"
475a8e1175bSopenharmony_ci#else
476a8e1175bSopenharmony_ci#define USAGE_SERIALIZATION ""
477a8e1175bSopenharmony_ci#endif
478a8e1175bSopenharmony_ci
479a8e1175bSopenharmony_ci#define USAGE_KEY_OPAQUE_ALGS \
480a8e1175bSopenharmony_ci    "    key_opaque_algs=%%s  Allowed opaque key 1 algorithms.\n"                      \
481a8e1175bSopenharmony_ci    "                        comma-separated pair of values among the following:\n"    \
482a8e1175bSopenharmony_ci    "                        rsa-sign-pkcs1, rsa-sign-pss, rsa-sign-pss-sha256,\n"     \
483a8e1175bSopenharmony_ci    "                        rsa-sign-pss-sha384, rsa-sign-pss-sha512, rsa-decrypt,\n" \
484a8e1175bSopenharmony_ci    "                        ecdsa-sign, ecdh, none (only acceptable for\n"            \
485a8e1175bSopenharmony_ci    "                        the second value).\n"                                     \
486a8e1175bSopenharmony_ci    "    key_opaque_algs2=%%s Allowed opaque key 2 algorithms.\n"                      \
487a8e1175bSopenharmony_ci    "                        comma-separated pair of values among the following:\n"    \
488a8e1175bSopenharmony_ci    "                        rsa-sign-pkcs1, rsa-sign-pss, rsa-sign-pss-sha256,\n"     \
489a8e1175bSopenharmony_ci    "                        rsa-sign-pss-sha384, rsa-sign-pss-sha512, rsa-decrypt,\n" \
490a8e1175bSopenharmony_ci    "                        ecdsa-sign, ecdh, none (only acceptable for\n"            \
491a8e1175bSopenharmony_ci    "                        the second value).\n"
492a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
493a8e1175bSopenharmony_ci#define USAGE_TLS1_3_KEY_EXCHANGE_MODES \
494a8e1175bSopenharmony_ci    "    tls13_kex_modes=%%s   default: all\n"     \
495a8e1175bSopenharmony_ci    "                          options: psk, psk_ephemeral, psk_all, ephemeral,\n"  \
496a8e1175bSopenharmony_ci    "                                   ephemeral_all, all, psk_or_ephemeral\n"
497a8e1175bSopenharmony_ci#else
498a8e1175bSopenharmony_ci#define USAGE_TLS1_3_KEY_EXCHANGE_MODES ""
499a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
500a8e1175bSopenharmony_ci
501a8e1175bSopenharmony_ci
502a8e1175bSopenharmony_ci/* USAGE is arbitrarily split to stay under the portable string literal
503a8e1175bSopenharmony_ci * length limit: 4095 bytes in C99. */
504a8e1175bSopenharmony_ci#define USAGE1 \
505a8e1175bSopenharmony_ci    "\n usage: ssl_server2 param=<>...\n"                   \
506a8e1175bSopenharmony_ci    "\n acceptable parameters:\n"                           \
507a8e1175bSopenharmony_ci    "    server_addr=%%s      default: (all interfaces)\n"  \
508a8e1175bSopenharmony_ci    "    server_port=%%d      default: 4433\n"              \
509a8e1175bSopenharmony_ci    "    debug_level=%%d      default: 0 (disabled)\n"      \
510a8e1175bSopenharmony_ci    "    build_version=%%d    default: none (disabled)\n"                     \
511a8e1175bSopenharmony_ci    "                        option: 1 (print build version only and stop)\n" \
512a8e1175bSopenharmony_ci    "    buffer_size=%%d      default: 200 \n" \
513a8e1175bSopenharmony_ci    "                         (minimum: 1)\n" \
514a8e1175bSopenharmony_ci    "    response_size=%%d    default: about 152 (basic response)\n" \
515a8e1175bSopenharmony_ci    "                          (minimum: 0, max: 16384)\n" \
516a8e1175bSopenharmony_ci    "                          increases buffer_size if bigger\n" \
517a8e1175bSopenharmony_ci    "    nbio=%%d             default: 0 (blocking I/O)\n"  \
518a8e1175bSopenharmony_ci    "                        options: 1 (non-blocking), 2 (added delays)\n" \
519a8e1175bSopenharmony_ci    "    event=%%d            default: 0 (loop)\n"                            \
520a8e1175bSopenharmony_ci    "                        options: 1 (level-triggered, implies nbio=1),\n" \
521a8e1175bSopenharmony_ci    "    read_timeout=%%d     default: 0 ms (no timeout)\n"    \
522a8e1175bSopenharmony_ci    "\n"                                                    \
523a8e1175bSopenharmony_ci    USAGE_DTLS                                              \
524a8e1175bSopenharmony_ci    USAGE_SRTP                                              \
525a8e1175bSopenharmony_ci    USAGE_COOKIES                                           \
526a8e1175bSopenharmony_ci    USAGE_ANTI_REPLAY                                       \
527a8e1175bSopenharmony_ci    USAGE_BADMAC_LIMIT                                      \
528a8e1175bSopenharmony_ci    "\n"
529a8e1175bSopenharmony_ci#define USAGE2 \
530a8e1175bSopenharmony_ci    "    auth_mode=%%s        default: (library default: none)\n"      \
531a8e1175bSopenharmony_ci    "                        options: none, optional, required\n" \
532a8e1175bSopenharmony_ci    "    cert_req_ca_list=%%d default: 1 (send ca list)\n"  \
533a8e1175bSopenharmony_ci    "                        options: 1 (send ca list), 0 (don't send)\n" \
534a8e1175bSopenharmony_ci    "                                 2 (send conf dn hint), 3 (send hs dn hint)\n" \
535a8e1175bSopenharmony_ci    USAGE_IO                                                \
536a8e1175bSopenharmony_ci    USAGE_KEY_OPAQUE                                        \
537a8e1175bSopenharmony_ci    "\n"                                                    \
538a8e1175bSopenharmony_ci    USAGE_PSK                                               \
539a8e1175bSopenharmony_ci    USAGE_CA_CALLBACK                                       \
540a8e1175bSopenharmony_ci    USAGE_ECJPAKE                                           \
541a8e1175bSopenharmony_ci    "\n"
542a8e1175bSopenharmony_ci#define USAGE3 \
543a8e1175bSopenharmony_ci    "    allow_legacy=%%d     default: (library default: no)\n"      \
544a8e1175bSopenharmony_ci    USAGE_RENEGO                                            \
545a8e1175bSopenharmony_ci    "    exchanges=%%d        default: 1\n"                 \
546a8e1175bSopenharmony_ci    "\n"                                                    \
547a8e1175bSopenharmony_ci    USAGE_TICKETS                                           \
548a8e1175bSopenharmony_ci    USAGE_EAP_TLS                                           \
549a8e1175bSopenharmony_ci    USAGE_REPRODUCIBLE                                      \
550a8e1175bSopenharmony_ci    USAGE_NSS_KEYLOG                                        \
551a8e1175bSopenharmony_ci    USAGE_NSS_KEYLOG_FILE                                   \
552a8e1175bSopenharmony_ci    USAGE_CACHE                                             \
553a8e1175bSopenharmony_ci    USAGE_CACHE_TIME                                        \
554a8e1175bSopenharmony_ci    USAGE_MAX_FRAG_LEN                                      \
555a8e1175bSopenharmony_ci    USAGE_ALPN                                              \
556a8e1175bSopenharmony_ci    USAGE_EMS                                               \
557a8e1175bSopenharmony_ci    USAGE_ETM                                               \
558a8e1175bSopenharmony_ci    USAGE_GROUPS                                            \
559a8e1175bSopenharmony_ci    USAGE_SIG_ALGS                                          \
560a8e1175bSopenharmony_ci    USAGE_KEY_OPAQUE_ALGS                                   \
561a8e1175bSopenharmony_ci    USAGE_EARLY_DATA                                        \
562a8e1175bSopenharmony_ci    "\n"
563a8e1175bSopenharmony_ci
564a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
565a8e1175bSopenharmony_ci#define TLS1_3_VERSION_OPTIONS  ", tls13"
566a8e1175bSopenharmony_ci#else /* MBEDTLS_SSL_PROTO_TLS1_3 */
567a8e1175bSopenharmony_ci#define TLS1_3_VERSION_OPTIONS  ""
568a8e1175bSopenharmony_ci#endif /* !MBEDTLS_SSL_PROTO_TLS1_3 */
569a8e1175bSopenharmony_ci
570a8e1175bSopenharmony_ci#define USAGE4 \
571a8e1175bSopenharmony_ci    USAGE_SSL_ASYNC                                         \
572a8e1175bSopenharmony_ci    USAGE_SNI                                               \
573a8e1175bSopenharmony_ci    "    allow_sha1=%%d       default: 0\n"                                   \
574a8e1175bSopenharmony_ci    "    min_version=%%s      default: (library default: tls12)\n"            \
575a8e1175bSopenharmony_ci    "    max_version=%%s      default: (library default: tls12)\n"            \
576a8e1175bSopenharmony_ci    "    force_version=%%s    default: \"\" (none)\n"                         \
577a8e1175bSopenharmony_ci    "                         options: tls12, dtls12" TLS1_3_VERSION_OPTIONS  \
578a8e1175bSopenharmony_ci    "\n\n"                                                                    \
579a8e1175bSopenharmony_ci    "    force_ciphersuite=<name>    default: all enabled\n"                  \
580a8e1175bSopenharmony_ci    USAGE_TLS1_3_KEY_EXCHANGE_MODES                                           \
581a8e1175bSopenharmony_ci    "    query_config=<name>         return 0 if the specified\n"             \
582a8e1175bSopenharmony_ci    "                                configuration macro is defined and 1\n"  \
583a8e1175bSopenharmony_ci    "                                otherwise. The expansion of the macro\n" \
584a8e1175bSopenharmony_ci    "                                is printed if it is defined\n"           \
585a8e1175bSopenharmony_ci    USAGE_SERIALIZATION                                                       \
586a8e1175bSopenharmony_ci    "\n"
587a8e1175bSopenharmony_ci
588a8e1175bSopenharmony_ci#define PUT_UINT64_BE(out_be, in_le, i)                                   \
589a8e1175bSopenharmony_ci    {                                                                       \
590a8e1175bSopenharmony_ci        (out_be)[(i) + 0] = (unsigned char) (((in_le) >> 56) & 0xFF);    \
591a8e1175bSopenharmony_ci        (out_be)[(i) + 1] = (unsigned char) (((in_le) >> 48) & 0xFF);    \
592a8e1175bSopenharmony_ci        (out_be)[(i) + 2] = (unsigned char) (((in_le) >> 40) & 0xFF);    \
593a8e1175bSopenharmony_ci        (out_be)[(i) + 3] = (unsigned char) (((in_le) >> 32) & 0xFF);    \
594a8e1175bSopenharmony_ci        (out_be)[(i) + 4] = (unsigned char) (((in_le) >> 24) & 0xFF);    \
595a8e1175bSopenharmony_ci        (out_be)[(i) + 5] = (unsigned char) (((in_le) >> 16) & 0xFF);    \
596a8e1175bSopenharmony_ci        (out_be)[(i) + 6] = (unsigned char) (((in_le) >> 8) & 0xFF);    \
597a8e1175bSopenharmony_ci        (out_be)[(i) + 7] = (unsigned char) (((in_le) >> 0) & 0xFF);    \
598a8e1175bSopenharmony_ci    }
599a8e1175bSopenharmony_ci
600a8e1175bSopenharmony_ci/* This is global so it can be easily accessed by callback functions */
601a8e1175bSopenharmony_cirng_context_t rng;
602a8e1175bSopenharmony_ci
603a8e1175bSopenharmony_ci/*
604a8e1175bSopenharmony_ci * global options
605a8e1175bSopenharmony_ci */
606a8e1175bSopenharmony_cistruct options {
607a8e1175bSopenharmony_ci    const char *server_addr;    /* address on which the ssl service runs    */
608a8e1175bSopenharmony_ci    const char *server_port;    /* port on which the ssl service runs       */
609a8e1175bSopenharmony_ci    int debug_level;            /* level of debugging                       */
610a8e1175bSopenharmony_ci    int nbio;                   /* should I/O be blocking?                  */
611a8e1175bSopenharmony_ci    int event;                  /* loop or event-driven IO? level or edge triggered? */
612a8e1175bSopenharmony_ci    uint32_t read_timeout;      /* timeout on mbedtls_ssl_read() in milliseconds    */
613a8e1175bSopenharmony_ci    int response_size;          /* pad response with header to requested size */
614a8e1175bSopenharmony_ci    uint16_t buffer_size;       /* IO buffer size */
615a8e1175bSopenharmony_ci    const char *ca_file;        /* the file with the CA certificate(s)      */
616a8e1175bSopenharmony_ci    const char *ca_path;        /* the path with the CA certificate(s) reside */
617a8e1175bSopenharmony_ci    const char *crt_file;       /* the file with the server certificate     */
618a8e1175bSopenharmony_ci    const char *key_file;       /* the file with the server key             */
619a8e1175bSopenharmony_ci    int key_opaque;             /* handle private key as if it were opaque  */
620a8e1175bSopenharmony_ci    const char *key_pwd;        /* the password for the server key          */
621a8e1175bSopenharmony_ci    const char *crt_file2;      /* the file with the 2nd server certificate */
622a8e1175bSopenharmony_ci    const char *key_file2;      /* the file with the 2nd server key         */
623a8e1175bSopenharmony_ci    const char *key_pwd2;       /* the password for the 2nd server key      */
624a8e1175bSopenharmony_ci    const char *async_operations; /* supported SSL asynchronous operations  */
625a8e1175bSopenharmony_ci    int async_private_delay1;   /* number of times f_async_resume needs to be called for key 1, or -1 for no async */
626a8e1175bSopenharmony_ci    int async_private_delay2;   /* number of times f_async_resume needs to be called for key 2, or -1 for no async */
627a8e1175bSopenharmony_ci    int async_private_error;    /* inject error in async private callback */
628a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
629a8e1175bSopenharmony_ci    int psk_opaque;
630a8e1175bSopenharmony_ci    int psk_list_opaque;
631a8e1175bSopenharmony_ci#endif
632a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
633a8e1175bSopenharmony_ci    int ca_callback;            /* Use callback for trusted certificate list */
634a8e1175bSopenharmony_ci#endif
635a8e1175bSopenharmony_ci    const char *psk;            /* the pre-shared key                       */
636a8e1175bSopenharmony_ci    const char *psk_identity;   /* the pre-shared key identity              */
637a8e1175bSopenharmony_ci    char *psk_list;             /* list of PSK id/key pairs for callback    */
638a8e1175bSopenharmony_ci    const char *ecjpake_pw;     /* the EC J-PAKE password                   */
639a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
640a8e1175bSopenharmony_ci    int ecjpake_pw_opaque;      /* set to 1 to use the opaque method for setting the password */
641a8e1175bSopenharmony_ci#endif
642a8e1175bSopenharmony_ci    int force_ciphersuite[2];   /* protocol/ciphersuite to use, or all      */
643a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
644a8e1175bSopenharmony_ci    int tls13_kex_modes;        /* supported TLS 1.3 key exchange modes     */
645a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
646a8e1175bSopenharmony_ci    int renegotiation;          /* enable / disable renegotiation           */
647a8e1175bSopenharmony_ci    int allow_legacy;           /* allow legacy renegotiation               */
648a8e1175bSopenharmony_ci    int renegotiate;            /* attempt renegotiation?                   */
649a8e1175bSopenharmony_ci    int renego_delay;           /* delay before enforcing renegotiation     */
650a8e1175bSopenharmony_ci    uint64_t renego_period;     /* period for automatic renegotiation       */
651a8e1175bSopenharmony_ci    int exchanges;              /* number of data exchanges                 */
652a8e1175bSopenharmony_ci    int min_version;            /* minimum protocol version accepted        */
653a8e1175bSopenharmony_ci    int max_version;            /* maximum protocol version accepted        */
654a8e1175bSopenharmony_ci    int allow_sha1;             /* flag for SHA-1 support                   */
655a8e1175bSopenharmony_ci    int auth_mode;              /* verify mode for connection               */
656a8e1175bSopenharmony_ci    int cert_req_ca_list;       /* should we send the CA list?              */
657a8e1175bSopenharmony_ci    int cert_req_dn_hint;       /* mode to set DN hints for CA list to send */
658a8e1175bSopenharmony_ci    unsigned char mfl_code;     /* code for maximum fragment length         */
659a8e1175bSopenharmony_ci    int trunc_hmac;             /* accept truncated hmac?                   */
660a8e1175bSopenharmony_ci    int tickets;                /* enable / disable session tickets         */
661a8e1175bSopenharmony_ci    int dummy_ticket;           /* enable / disable dummy ticket generator  */
662a8e1175bSopenharmony_ci    int ticket_rotate;          /* session ticket rotate (code coverage)    */
663a8e1175bSopenharmony_ci    int ticket_timeout;         /* session ticket lifetime                  */
664a8e1175bSopenharmony_ci    int ticket_aead;            /* session ticket protection                */
665a8e1175bSopenharmony_ci    int cache_max;              /* max number of session cache entries      */
666a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME)
667a8e1175bSopenharmony_ci    int cache_timeout;          /* expiration delay of session cache entries*/
668a8e1175bSopenharmony_ci#endif
669a8e1175bSopenharmony_ci    int cache_remove;           /* enable / disable cache entry removal     */
670a8e1175bSopenharmony_ci    char *sni;                  /* string describing sni information        */
671a8e1175bSopenharmony_ci    const char *groups;         /* list of supported groups                 */
672a8e1175bSopenharmony_ci    const char *sig_algs;       /* supported TLS 1.3 signature algorithms   */
673a8e1175bSopenharmony_ci    const char *alpn_string;    /* ALPN supported protocols                 */
674a8e1175bSopenharmony_ci    const char *dhm_file;       /* the file with the DH parameters          */
675a8e1175bSopenharmony_ci    int extended_ms;            /* allow negotiation of extended MS?        */
676a8e1175bSopenharmony_ci    int etm;                    /* allow negotiation of encrypt-then-MAC?   */
677a8e1175bSopenharmony_ci    int transport;              /* TLS or DTLS?                             */
678a8e1175bSopenharmony_ci    int cookies;                /* Use cookies for DTLS? -1 to break them   */
679a8e1175bSopenharmony_ci    int anti_replay;            /* Use anti-replay for DTLS? -1 for default */
680a8e1175bSopenharmony_ci    uint32_t hs_to_min;         /* Initial value of DTLS handshake timer    */
681a8e1175bSopenharmony_ci    uint32_t hs_to_max;         /* Max value of DTLS handshake timer        */
682a8e1175bSopenharmony_ci    int dtls_mtu;               /* UDP Maximum transport unit for DTLS       */
683a8e1175bSopenharmony_ci    int dgram_packing;          /* allow/forbid datagram packing            */
684a8e1175bSopenharmony_ci    int badmac_limit;           /* Limit of records with bad MAC            */
685a8e1175bSopenharmony_ci    int eap_tls;                /* derive EAP-TLS keying material?          */
686a8e1175bSopenharmony_ci    int nss_keylog;             /* export NSS key log material              */
687a8e1175bSopenharmony_ci    const char *nss_keylog_file; /* NSS key log file                        */
688a8e1175bSopenharmony_ci    int cid_enabled;            /* whether to use the CID extension or not  */
689a8e1175bSopenharmony_ci    int cid_enabled_renego;     /* whether to use the CID extension or not
690a8e1175bSopenharmony_ci                                 * during renegotiation                     */
691a8e1175bSopenharmony_ci    const char *cid_val;        /* the CID to use for incoming messages     */
692a8e1175bSopenharmony_ci    int serialize;              /* serialize/deserialize connection         */
693a8e1175bSopenharmony_ci    const char *context_file;   /* the file to write a serialized connection
694a8e1175bSopenharmony_ci                                 * in the form of base64 code (serialize
695a8e1175bSopenharmony_ci                                 * option must be set)                      */
696a8e1175bSopenharmony_ci    const char *cid_val_renego; /* the CID to use for incoming messages
697a8e1175bSopenharmony_ci                                 * after renegotiation                      */
698a8e1175bSopenharmony_ci    int reproducible;           /* make communication reproducible          */
699a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
700a8e1175bSopenharmony_ci    int early_data;               /* early data enablement flag             */
701a8e1175bSopenharmony_ci    uint32_t max_early_data_size; /* max amount of early data               */
702a8e1175bSopenharmony_ci#endif
703a8e1175bSopenharmony_ci    int query_config_mode;      /* whether to read config                   */
704a8e1175bSopenharmony_ci    int use_srtp;               /* Support SRTP                             */
705a8e1175bSopenharmony_ci    int force_srtp_profile;     /* SRTP protection profile to use or all    */
706a8e1175bSopenharmony_ci    int support_mki;            /* The dtls mki mki support                 */
707a8e1175bSopenharmony_ci    const char *key1_opaque_alg1; /* Allowed opaque key 1 alg 1            */
708a8e1175bSopenharmony_ci    const char *key1_opaque_alg2; /* Allowed opaque key 1 alg 2            */
709a8e1175bSopenharmony_ci    const char *key2_opaque_alg1; /* Allowed opaque key 2 alg 1            */
710a8e1175bSopenharmony_ci    const char *key2_opaque_alg2; /* Allowed opaque key 2 alg 2            */
711a8e1175bSopenharmony_ci} opt;
712a8e1175bSopenharmony_ci
713a8e1175bSopenharmony_ci#include "ssl_test_common_source.c"
714a8e1175bSopenharmony_ci
715a8e1175bSopenharmony_ci/*
716a8e1175bSopenharmony_ci * Return authmode from string, or -1 on error
717a8e1175bSopenharmony_ci */
718a8e1175bSopenharmony_cistatic int get_auth_mode(const char *s)
719a8e1175bSopenharmony_ci{
720a8e1175bSopenharmony_ci    if (strcmp(s, "none") == 0) {
721a8e1175bSopenharmony_ci        return MBEDTLS_SSL_VERIFY_NONE;
722a8e1175bSopenharmony_ci    }
723a8e1175bSopenharmony_ci    if (strcmp(s, "optional") == 0) {
724a8e1175bSopenharmony_ci        return MBEDTLS_SSL_VERIFY_OPTIONAL;
725a8e1175bSopenharmony_ci    }
726a8e1175bSopenharmony_ci    if (strcmp(s, "required") == 0) {
727a8e1175bSopenharmony_ci        return MBEDTLS_SSL_VERIFY_REQUIRED;
728a8e1175bSopenharmony_ci    }
729a8e1175bSopenharmony_ci
730a8e1175bSopenharmony_ci    return -1;
731a8e1175bSopenharmony_ci}
732a8e1175bSopenharmony_ci
733a8e1175bSopenharmony_ci/*
734a8e1175bSopenharmony_ci * Used by sni_parse and psk_parse to handle comma-separated lists
735a8e1175bSopenharmony_ci */
736a8e1175bSopenharmony_ci#define GET_ITEM(dst)         \
737a8e1175bSopenharmony_ci    do                          \
738a8e1175bSopenharmony_ci    {                           \
739a8e1175bSopenharmony_ci        (dst) = p;              \
740a8e1175bSopenharmony_ci        while (*p != ',')      \
741a8e1175bSopenharmony_ci        if (++p > end)     \
742a8e1175bSopenharmony_ci        goto error;     \
743a8e1175bSopenharmony_ci        *p++ = '\0';            \
744a8e1175bSopenharmony_ci    } while (0)
745a8e1175bSopenharmony_ci
746a8e1175bSopenharmony_ci#if defined(SNI_OPTION)
747a8e1175bSopenharmony_citypedef struct _sni_entry sni_entry;
748a8e1175bSopenharmony_ci
749a8e1175bSopenharmony_cistruct _sni_entry {
750a8e1175bSopenharmony_ci    const char *name;
751a8e1175bSopenharmony_ci    mbedtls_x509_crt *cert;
752a8e1175bSopenharmony_ci    mbedtls_pk_context *key;
753a8e1175bSopenharmony_ci    mbedtls_x509_crt *ca;
754a8e1175bSopenharmony_ci    mbedtls_x509_crl *crl;
755a8e1175bSopenharmony_ci    int authmode;
756a8e1175bSopenharmony_ci    sni_entry *next;
757a8e1175bSopenharmony_ci};
758a8e1175bSopenharmony_ci
759a8e1175bSopenharmony_civoid sni_free(sni_entry *head)
760a8e1175bSopenharmony_ci{
761a8e1175bSopenharmony_ci    sni_entry *cur = head, *next;
762a8e1175bSopenharmony_ci
763a8e1175bSopenharmony_ci    while (cur != NULL) {
764a8e1175bSopenharmony_ci        mbedtls_x509_crt_free(cur->cert);
765a8e1175bSopenharmony_ci        mbedtls_free(cur->cert);
766a8e1175bSopenharmony_ci
767a8e1175bSopenharmony_ci        mbedtls_pk_free(cur->key);
768a8e1175bSopenharmony_ci        mbedtls_free(cur->key);
769a8e1175bSopenharmony_ci
770a8e1175bSopenharmony_ci        mbedtls_x509_crt_free(cur->ca);
771a8e1175bSopenharmony_ci        mbedtls_free(cur->ca);
772a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_CRL_PARSE_C)
773a8e1175bSopenharmony_ci        mbedtls_x509_crl_free(cur->crl);
774a8e1175bSopenharmony_ci        mbedtls_free(cur->crl);
775a8e1175bSopenharmony_ci#endif
776a8e1175bSopenharmony_ci        next = cur->next;
777a8e1175bSopenharmony_ci        mbedtls_free(cur);
778a8e1175bSopenharmony_ci        cur = next;
779a8e1175bSopenharmony_ci    }
780a8e1175bSopenharmony_ci}
781a8e1175bSopenharmony_ci
782a8e1175bSopenharmony_ci/*
783a8e1175bSopenharmony_ci * Parse a string of sextuples name1,crt1,key1,ca1,crl1,auth1[,...]
784a8e1175bSopenharmony_ci * into a usable sni_entry list. For ca1, crl1, auth1, the special value
785a8e1175bSopenharmony_ci * '-' means unset. If ca1 is unset, then crl1 is ignored too.
786a8e1175bSopenharmony_ci *
787a8e1175bSopenharmony_ci * Modifies the input string! This is not production quality!
788a8e1175bSopenharmony_ci */
789a8e1175bSopenharmony_cisni_entry *sni_parse(char *sni_string)
790a8e1175bSopenharmony_ci{
791a8e1175bSopenharmony_ci    sni_entry *cur = NULL, *new = NULL;
792a8e1175bSopenharmony_ci    char *p = sni_string;
793a8e1175bSopenharmony_ci    char *end = p;
794a8e1175bSopenharmony_ci    char *crt_file, *key_file, *ca_file, *auth_str;
795a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_CRL_PARSE_C)
796a8e1175bSopenharmony_ci    char *crl_file;
797a8e1175bSopenharmony_ci#endif
798a8e1175bSopenharmony_ci
799a8e1175bSopenharmony_ci    while (*end != '\0') {
800a8e1175bSopenharmony_ci        ++end;
801a8e1175bSopenharmony_ci    }
802a8e1175bSopenharmony_ci    *end = ',';
803a8e1175bSopenharmony_ci
804a8e1175bSopenharmony_ci    while (p <= end) {
805a8e1175bSopenharmony_ci        if ((new = mbedtls_calloc(1, sizeof(sni_entry))) == NULL) {
806a8e1175bSopenharmony_ci            sni_free(cur);
807a8e1175bSopenharmony_ci            return NULL;
808a8e1175bSopenharmony_ci        }
809a8e1175bSopenharmony_ci
810a8e1175bSopenharmony_ci        GET_ITEM(new->name);
811a8e1175bSopenharmony_ci        GET_ITEM(crt_file);
812a8e1175bSopenharmony_ci        GET_ITEM(key_file);
813a8e1175bSopenharmony_ci        GET_ITEM(ca_file);
814a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_CRL_PARSE_C)
815a8e1175bSopenharmony_ci        GET_ITEM(crl_file);
816a8e1175bSopenharmony_ci#endif
817a8e1175bSopenharmony_ci        GET_ITEM(auth_str);
818a8e1175bSopenharmony_ci
819a8e1175bSopenharmony_ci        if ((new->cert = mbedtls_calloc(1, sizeof(mbedtls_x509_crt))) == NULL ||
820a8e1175bSopenharmony_ci            (new->key = mbedtls_calloc(1, sizeof(mbedtls_pk_context))) == NULL) {
821a8e1175bSopenharmony_ci            goto error;
822a8e1175bSopenharmony_ci        }
823a8e1175bSopenharmony_ci
824a8e1175bSopenharmony_ci        mbedtls_x509_crt_init(new->cert);
825a8e1175bSopenharmony_ci        mbedtls_pk_init(new->key);
826a8e1175bSopenharmony_ci
827a8e1175bSopenharmony_ci        if (mbedtls_x509_crt_parse_file(new->cert, crt_file) != 0 ||
828a8e1175bSopenharmony_ci            mbedtls_pk_parse_keyfile(new->key, key_file, "", rng_get, &rng) != 0) {
829a8e1175bSopenharmony_ci            goto error;
830a8e1175bSopenharmony_ci        }
831a8e1175bSopenharmony_ci
832a8e1175bSopenharmony_ci        if (strcmp(ca_file, "-") != 0) {
833a8e1175bSopenharmony_ci            if ((new->ca = mbedtls_calloc(1, sizeof(mbedtls_x509_crt))) == NULL) {
834a8e1175bSopenharmony_ci                goto error;
835a8e1175bSopenharmony_ci            }
836a8e1175bSopenharmony_ci
837a8e1175bSopenharmony_ci            mbedtls_x509_crt_init(new->ca);
838a8e1175bSopenharmony_ci
839a8e1175bSopenharmony_ci            if (mbedtls_x509_crt_parse_file(new->ca, ca_file) != 0) {
840a8e1175bSopenharmony_ci                goto error;
841a8e1175bSopenharmony_ci            }
842a8e1175bSopenharmony_ci        }
843a8e1175bSopenharmony_ci
844a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_CRL_PARSE_C)
845a8e1175bSopenharmony_ci        if (strcmp(crl_file, "-") != 0) {
846a8e1175bSopenharmony_ci            if ((new->crl = mbedtls_calloc(1, sizeof(mbedtls_x509_crl))) == NULL) {
847a8e1175bSopenharmony_ci                goto error;
848a8e1175bSopenharmony_ci            }
849a8e1175bSopenharmony_ci
850a8e1175bSopenharmony_ci            mbedtls_x509_crl_init(new->crl);
851a8e1175bSopenharmony_ci
852a8e1175bSopenharmony_ci            if (mbedtls_x509_crl_parse_file(new->crl, crl_file) != 0) {
853a8e1175bSopenharmony_ci                goto error;
854a8e1175bSopenharmony_ci            }
855a8e1175bSopenharmony_ci        }
856a8e1175bSopenharmony_ci#endif
857a8e1175bSopenharmony_ci
858a8e1175bSopenharmony_ci        if (strcmp(auth_str, "-") != 0) {
859a8e1175bSopenharmony_ci            if ((new->authmode = get_auth_mode(auth_str)) < 0) {
860a8e1175bSopenharmony_ci                goto error;
861a8e1175bSopenharmony_ci            }
862a8e1175bSopenharmony_ci        } else {
863a8e1175bSopenharmony_ci            new->authmode = DFL_AUTH_MODE;
864a8e1175bSopenharmony_ci        }
865a8e1175bSopenharmony_ci
866a8e1175bSopenharmony_ci        new->next = cur;
867a8e1175bSopenharmony_ci        cur = new;
868a8e1175bSopenharmony_ci    }
869a8e1175bSopenharmony_ci
870a8e1175bSopenharmony_ci    return cur;
871a8e1175bSopenharmony_ci
872a8e1175bSopenharmony_cierror:
873a8e1175bSopenharmony_ci    sni_free(new);
874a8e1175bSopenharmony_ci    sni_free(cur);
875a8e1175bSopenharmony_ci    return NULL;
876a8e1175bSopenharmony_ci}
877a8e1175bSopenharmony_ci
878a8e1175bSopenharmony_ci/*
879a8e1175bSopenharmony_ci * SNI callback.
880a8e1175bSopenharmony_ci */
881a8e1175bSopenharmony_ciint sni_callback(void *p_info, mbedtls_ssl_context *ssl,
882a8e1175bSopenharmony_ci                 const unsigned char *name, size_t name_len)
883a8e1175bSopenharmony_ci{
884a8e1175bSopenharmony_ci    const sni_entry *cur = (const sni_entry *) p_info;
885a8e1175bSopenharmony_ci
886a8e1175bSopenharmony_ci    /* preserve behavior which checks for SNI match in sni_callback() for
887a8e1175bSopenharmony_ci     * the benefits of tests using sni_callback(), even though the actual
888a8e1175bSopenharmony_ci     * certificate assignment has moved to certificate selection callback
889a8e1175bSopenharmony_ci     * in this application.  This exercises sni_callback and cert_callback
890a8e1175bSopenharmony_ci     * even though real applications might choose to do this differently.
891a8e1175bSopenharmony_ci     * Application might choose to save name and name_len in user_data for
892a8e1175bSopenharmony_ci     * later use in certificate selection callback.
893a8e1175bSopenharmony_ci     */
894a8e1175bSopenharmony_ci    while (cur != NULL) {
895a8e1175bSopenharmony_ci        if (name_len == strlen(cur->name) &&
896a8e1175bSopenharmony_ci            memcmp(name, cur->name, name_len) == 0) {
897a8e1175bSopenharmony_ci            void *p;
898a8e1175bSopenharmony_ci            *(const void **)&p = cur;
899a8e1175bSopenharmony_ci            mbedtls_ssl_set_user_data_p(ssl, p);
900a8e1175bSopenharmony_ci            return 0;
901a8e1175bSopenharmony_ci        }
902a8e1175bSopenharmony_ci
903a8e1175bSopenharmony_ci        cur = cur->next;
904a8e1175bSopenharmony_ci    }
905a8e1175bSopenharmony_ci
906a8e1175bSopenharmony_ci    return -1;
907a8e1175bSopenharmony_ci}
908a8e1175bSopenharmony_ci
909a8e1175bSopenharmony_ci/*
910a8e1175bSopenharmony_ci * server certificate selection callback.
911a8e1175bSopenharmony_ci */
912a8e1175bSopenharmony_ciint cert_callback(mbedtls_ssl_context *ssl)
913a8e1175bSopenharmony_ci{
914a8e1175bSopenharmony_ci    const sni_entry *cur = (sni_entry *) mbedtls_ssl_get_user_data_p(ssl);
915a8e1175bSopenharmony_ci    if (cur != NULL) {
916a8e1175bSopenharmony_ci        /*(exercise mbedtls_ssl_get_hs_sni(); not otherwise used here)*/
917a8e1175bSopenharmony_ci        size_t name_len;
918a8e1175bSopenharmony_ci        const unsigned char *name = mbedtls_ssl_get_hs_sni(ssl, &name_len);
919a8e1175bSopenharmony_ci        if (strlen(cur->name) != name_len ||
920a8e1175bSopenharmony_ci            memcmp(cur->name, name, name_len) != 0) {
921a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_DECODE_ERROR;
922a8e1175bSopenharmony_ci        }
923a8e1175bSopenharmony_ci
924a8e1175bSopenharmony_ci        if (cur->ca != NULL) {
925a8e1175bSopenharmony_ci            mbedtls_ssl_set_hs_ca_chain(ssl, cur->ca, cur->crl);
926a8e1175bSopenharmony_ci        }
927a8e1175bSopenharmony_ci
928a8e1175bSopenharmony_ci        if (cur->authmode != DFL_AUTH_MODE) {
929a8e1175bSopenharmony_ci            mbedtls_ssl_set_hs_authmode(ssl, cur->authmode);
930a8e1175bSopenharmony_ci        }
931a8e1175bSopenharmony_ci
932a8e1175bSopenharmony_ci        return mbedtls_ssl_set_hs_own_cert(ssl, cur->cert, cur->key);
933a8e1175bSopenharmony_ci    }
934a8e1175bSopenharmony_ci
935a8e1175bSopenharmony_ci    return 0;
936a8e1175bSopenharmony_ci}
937a8e1175bSopenharmony_ci
938a8e1175bSopenharmony_ci#endif /* SNI_OPTION */
939a8e1175bSopenharmony_ci
940a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
941a8e1175bSopenharmony_ci
942a8e1175bSopenharmony_citypedef struct _psk_entry psk_entry;
943a8e1175bSopenharmony_ci
944a8e1175bSopenharmony_cistruct _psk_entry {
945a8e1175bSopenharmony_ci    const char *name;
946a8e1175bSopenharmony_ci    size_t key_len;
947a8e1175bSopenharmony_ci    unsigned char key[MBEDTLS_PSK_MAX_LEN];
948a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
949a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t slot;
950a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
951a8e1175bSopenharmony_ci    psk_entry *next;
952a8e1175bSopenharmony_ci};
953a8e1175bSopenharmony_ci
954a8e1175bSopenharmony_ci/*
955a8e1175bSopenharmony_ci * Free a list of psk_entry's
956a8e1175bSopenharmony_ci */
957a8e1175bSopenharmony_ciint psk_free(psk_entry *head)
958a8e1175bSopenharmony_ci{
959a8e1175bSopenharmony_ci    psk_entry *next;
960a8e1175bSopenharmony_ci
961a8e1175bSopenharmony_ci    while (head != NULL) {
962a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
963a8e1175bSopenharmony_ci        psa_status_t status;
964a8e1175bSopenharmony_ci        mbedtls_svc_key_id_t const slot = head->slot;
965a8e1175bSopenharmony_ci
966a8e1175bSopenharmony_ci        if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(slot) != 0) {
967a8e1175bSopenharmony_ci            status = psa_destroy_key(slot);
968a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
969a8e1175bSopenharmony_ci                return status;
970a8e1175bSopenharmony_ci            }
971a8e1175bSopenharmony_ci        }
972a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
973a8e1175bSopenharmony_ci
974a8e1175bSopenharmony_ci        next = head->next;
975a8e1175bSopenharmony_ci        mbedtls_free(head);
976a8e1175bSopenharmony_ci        head = next;
977a8e1175bSopenharmony_ci    }
978a8e1175bSopenharmony_ci
979a8e1175bSopenharmony_ci    return 0;
980a8e1175bSopenharmony_ci}
981a8e1175bSopenharmony_ci
982a8e1175bSopenharmony_ci/*
983a8e1175bSopenharmony_ci * Parse a string of pairs name1,key1[,name2,key2[,...]]
984a8e1175bSopenharmony_ci * into a usable psk_entry list.
985a8e1175bSopenharmony_ci *
986a8e1175bSopenharmony_ci * Modifies the input string! This is not production quality!
987a8e1175bSopenharmony_ci */
988a8e1175bSopenharmony_cipsk_entry *psk_parse(char *psk_string)
989a8e1175bSopenharmony_ci{
990a8e1175bSopenharmony_ci    psk_entry *cur = NULL, *new = NULL;
991a8e1175bSopenharmony_ci    char *p = psk_string;
992a8e1175bSopenharmony_ci    char *end = p;
993a8e1175bSopenharmony_ci    char *key_hex;
994a8e1175bSopenharmony_ci
995a8e1175bSopenharmony_ci    while (*end != '\0') {
996a8e1175bSopenharmony_ci        ++end;
997a8e1175bSopenharmony_ci    }
998a8e1175bSopenharmony_ci    *end = ',';
999a8e1175bSopenharmony_ci
1000a8e1175bSopenharmony_ci    while (p <= end) {
1001a8e1175bSopenharmony_ci        if ((new = mbedtls_calloc(1, sizeof(psk_entry))) == NULL) {
1002a8e1175bSopenharmony_ci            goto error;
1003a8e1175bSopenharmony_ci        }
1004a8e1175bSopenharmony_ci
1005a8e1175bSopenharmony_ci        memset(new, 0, sizeof(psk_entry));
1006a8e1175bSopenharmony_ci
1007a8e1175bSopenharmony_ci        GET_ITEM(new->name);
1008a8e1175bSopenharmony_ci        GET_ITEM(key_hex);
1009a8e1175bSopenharmony_ci
1010a8e1175bSopenharmony_ci        if (mbedtls_test_unhexify(new->key, MBEDTLS_PSK_MAX_LEN,
1011a8e1175bSopenharmony_ci                                  key_hex, &new->key_len) != 0) {
1012a8e1175bSopenharmony_ci            goto error;
1013a8e1175bSopenharmony_ci        }
1014a8e1175bSopenharmony_ci
1015a8e1175bSopenharmony_ci        new->next = cur;
1016a8e1175bSopenharmony_ci        cur = new;
1017a8e1175bSopenharmony_ci    }
1018a8e1175bSopenharmony_ci
1019a8e1175bSopenharmony_ci    return cur;
1020a8e1175bSopenharmony_ci
1021a8e1175bSopenharmony_cierror:
1022a8e1175bSopenharmony_ci    psk_free(new);
1023a8e1175bSopenharmony_ci    psk_free(cur);
1024a8e1175bSopenharmony_ci    return 0;
1025a8e1175bSopenharmony_ci}
1026a8e1175bSopenharmony_ci
1027a8e1175bSopenharmony_ci/*
1028a8e1175bSopenharmony_ci * PSK callback
1029a8e1175bSopenharmony_ci */
1030a8e1175bSopenharmony_ciint psk_callback(void *p_info, mbedtls_ssl_context *ssl,
1031a8e1175bSopenharmony_ci                 const unsigned char *name, size_t name_len)
1032a8e1175bSopenharmony_ci{
1033a8e1175bSopenharmony_ci    psk_entry *cur = (psk_entry *) p_info;
1034a8e1175bSopenharmony_ci
1035a8e1175bSopenharmony_ci    while (cur != NULL) {
1036a8e1175bSopenharmony_ci        if (name_len == strlen(cur->name) &&
1037a8e1175bSopenharmony_ci            memcmp(name, cur->name, name_len) == 0) {
1038a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1039a8e1175bSopenharmony_ci            if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(cur->slot) != 0) {
1040a8e1175bSopenharmony_ci                return mbedtls_ssl_set_hs_psk_opaque(ssl, cur->slot);
1041a8e1175bSopenharmony_ci            } else
1042a8e1175bSopenharmony_ci#endif
1043a8e1175bSopenharmony_ci            return mbedtls_ssl_set_hs_psk(ssl, cur->key, cur->key_len);
1044a8e1175bSopenharmony_ci        }
1045a8e1175bSopenharmony_ci
1046a8e1175bSopenharmony_ci        cur = cur->next;
1047a8e1175bSopenharmony_ci    }
1048a8e1175bSopenharmony_ci
1049a8e1175bSopenharmony_ci    return -1;
1050a8e1175bSopenharmony_ci}
1051a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
1052a8e1175bSopenharmony_ci
1053a8e1175bSopenharmony_cistatic mbedtls_net_context listen_fd, client_fd;
1054a8e1175bSopenharmony_ci
1055a8e1175bSopenharmony_ci/* Interruption handler to ensure clean exit (for valgrind testing) */
1056a8e1175bSopenharmony_ci#if !defined(_WIN32)
1057a8e1175bSopenharmony_cistatic int received_sigterm = 0;
1058a8e1175bSopenharmony_civoid term_handler(int sig)
1059a8e1175bSopenharmony_ci{
1060a8e1175bSopenharmony_ci    ((void) sig);
1061a8e1175bSopenharmony_ci    received_sigterm = 1;
1062a8e1175bSopenharmony_ci    mbedtls_net_free(&listen_fd);   /* causes mbedtls_net_accept() to abort */
1063a8e1175bSopenharmony_ci    mbedtls_net_free(&client_fd);   /* causes net_read() to abort */
1064a8e1175bSopenharmony_ci}
1065a8e1175bSopenharmony_ci#endif
1066a8e1175bSopenharmony_ci
1067a8e1175bSopenharmony_ci/** Return true if \p ret is a status code indicating that there is an
1068a8e1175bSopenharmony_ci * operation in progress on an SSL connection, and false if it indicates
1069a8e1175bSopenharmony_ci * success or a fatal error.
1070a8e1175bSopenharmony_ci *
1071a8e1175bSopenharmony_ci * The possible operations in progress are:
1072a8e1175bSopenharmony_ci *
1073a8e1175bSopenharmony_ci * - A read, when the SSL input buffer does not contain a full message.
1074a8e1175bSopenharmony_ci * - A write, when the SSL output buffer contains some data that has not
1075a8e1175bSopenharmony_ci *   been sent over the network yet.
1076a8e1175bSopenharmony_ci * - An asynchronous callback that has not completed yet. */
1077a8e1175bSopenharmony_cistatic int mbedtls_status_is_ssl_in_progress(int ret)
1078a8e1175bSopenharmony_ci{
1079a8e1175bSopenharmony_ci    return ret == MBEDTLS_ERR_SSL_WANT_READ ||
1080a8e1175bSopenharmony_ci           ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
1081a8e1175bSopenharmony_ci           ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS;
1082a8e1175bSopenharmony_ci}
1083a8e1175bSopenharmony_ci
1084a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
1085a8e1175bSopenharmony_citypedef struct {
1086a8e1175bSopenharmony_ci    mbedtls_x509_crt *cert; /*!< Certificate corresponding to the key */
1087a8e1175bSopenharmony_ci    mbedtls_pk_context *pk; /*!< Private key */
1088a8e1175bSopenharmony_ci    unsigned delay; /*!< Number of resume steps to go through */
1089a8e1175bSopenharmony_ci    unsigned pk_owned : 1; /*!< Whether to free the pk object on exit */
1090a8e1175bSopenharmony_ci} ssl_async_key_slot_t;
1091a8e1175bSopenharmony_ci
1092a8e1175bSopenharmony_citypedef enum {
1093a8e1175bSopenharmony_ci    SSL_ASYNC_INJECT_ERROR_NONE = 0, /*!< Let the callbacks succeed */
1094a8e1175bSopenharmony_ci    SSL_ASYNC_INJECT_ERROR_START, /*!< Inject error during start */
1095a8e1175bSopenharmony_ci    SSL_ASYNC_INJECT_ERROR_CANCEL, /*!< Close the connection after async start */
1096a8e1175bSopenharmony_ci    SSL_ASYNC_INJECT_ERROR_RESUME, /*!< Inject error during resume */
1097a8e1175bSopenharmony_ci#define SSL_ASYNC_INJECT_ERROR_MAX SSL_ASYNC_INJECT_ERROR_RESUME
1098a8e1175bSopenharmony_ci} ssl_async_inject_error_t;
1099a8e1175bSopenharmony_ci
1100a8e1175bSopenharmony_citypedef struct {
1101a8e1175bSopenharmony_ci    ssl_async_key_slot_t slots[4]; /* key, key2, sni1, sni2 */
1102a8e1175bSopenharmony_ci    size_t slots_used;
1103a8e1175bSopenharmony_ci    ssl_async_inject_error_t inject_error;
1104a8e1175bSopenharmony_ci    int (*f_rng)(void *, unsigned char *, size_t);
1105a8e1175bSopenharmony_ci    void *p_rng;
1106a8e1175bSopenharmony_ci} ssl_async_key_context_t;
1107a8e1175bSopenharmony_ci
1108a8e1175bSopenharmony_ciint ssl_async_set_key(ssl_async_key_context_t *ctx,
1109a8e1175bSopenharmony_ci                      mbedtls_x509_crt *cert,
1110a8e1175bSopenharmony_ci                      mbedtls_pk_context *pk,
1111a8e1175bSopenharmony_ci                      int pk_take_ownership,
1112a8e1175bSopenharmony_ci                      unsigned delay)
1113a8e1175bSopenharmony_ci{
1114a8e1175bSopenharmony_ci    if (ctx->slots_used >= sizeof(ctx->slots) / sizeof(*ctx->slots)) {
1115a8e1175bSopenharmony_ci        return -1;
1116a8e1175bSopenharmony_ci    }
1117a8e1175bSopenharmony_ci    ctx->slots[ctx->slots_used].cert = cert;
1118a8e1175bSopenharmony_ci    ctx->slots[ctx->slots_used].pk = pk;
1119a8e1175bSopenharmony_ci    ctx->slots[ctx->slots_used].delay = delay;
1120a8e1175bSopenharmony_ci    ctx->slots[ctx->slots_used].pk_owned = pk_take_ownership;
1121a8e1175bSopenharmony_ci    ++ctx->slots_used;
1122a8e1175bSopenharmony_ci    return 0;
1123a8e1175bSopenharmony_ci}
1124a8e1175bSopenharmony_ci
1125a8e1175bSopenharmony_ci#define SSL_ASYNC_INPUT_MAX_SIZE 512
1126a8e1175bSopenharmony_ci
1127a8e1175bSopenharmony_citypedef enum {
1128a8e1175bSopenharmony_ci    ASYNC_OP_SIGN,
1129a8e1175bSopenharmony_ci    ASYNC_OP_DECRYPT,
1130a8e1175bSopenharmony_ci} ssl_async_operation_type_t;
1131a8e1175bSopenharmony_ci
1132a8e1175bSopenharmony_citypedef struct {
1133a8e1175bSopenharmony_ci    unsigned slot;
1134a8e1175bSopenharmony_ci    ssl_async_operation_type_t operation_type;
1135a8e1175bSopenharmony_ci    mbedtls_md_type_t md_alg;
1136a8e1175bSopenharmony_ci    unsigned char input[SSL_ASYNC_INPUT_MAX_SIZE];
1137a8e1175bSopenharmony_ci    size_t input_len;
1138a8e1175bSopenharmony_ci    unsigned remaining_delay;
1139a8e1175bSopenharmony_ci} ssl_async_operation_context_t;
1140a8e1175bSopenharmony_ci
1141a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
1142a8e1175bSopenharmony_ci
1143a8e1175bSopenharmony_ci/* Note that ssl_async_operation_type_t and the array below need to be kept in sync!
1144a8e1175bSopenharmony_ci * `ssl_async_operation_names[op]` is the name of op for each value `op`
1145a8e1175bSopenharmony_ci * of type `ssl_async_operation_type_t`. */
1146a8e1175bSopenharmony_cistatic const char *const ssl_async_operation_names[] =
1147a8e1175bSopenharmony_ci{
1148a8e1175bSopenharmony_ci    "sign",
1149a8e1175bSopenharmony_ci    "decrypt",
1150a8e1175bSopenharmony_ci};
1151a8e1175bSopenharmony_ci
1152a8e1175bSopenharmony_cistatic int ssl_async_start(mbedtls_ssl_context *ssl,
1153a8e1175bSopenharmony_ci                           mbedtls_x509_crt *cert,
1154a8e1175bSopenharmony_ci                           ssl_async_operation_type_t op_type,
1155a8e1175bSopenharmony_ci                           mbedtls_md_type_t md_alg,
1156a8e1175bSopenharmony_ci                           const unsigned char *input,
1157a8e1175bSopenharmony_ci                           size_t input_len)
1158a8e1175bSopenharmony_ci{
1159a8e1175bSopenharmony_ci    ssl_async_key_context_t *config_data =
1160a8e1175bSopenharmony_ci        mbedtls_ssl_conf_get_async_config_data(ssl->conf);
1161a8e1175bSopenharmony_ci    unsigned slot;
1162a8e1175bSopenharmony_ci    ssl_async_operation_context_t *ctx = NULL;
1163a8e1175bSopenharmony_ci    const char *op_name = ssl_async_operation_names[op_type];
1164a8e1175bSopenharmony_ci
1165a8e1175bSopenharmony_ci    {
1166a8e1175bSopenharmony_ci        char dn[100];
1167a8e1175bSopenharmony_ci        if (mbedtls_x509_dn_gets(dn, sizeof(dn), &cert->subject) > 0) {
1168a8e1175bSopenharmony_ci            mbedtls_printf("Async %s callback: looking for DN=%s\n",
1169a8e1175bSopenharmony_ci                           op_name, dn);
1170a8e1175bSopenharmony_ci        }
1171a8e1175bSopenharmony_ci    }
1172a8e1175bSopenharmony_ci
1173a8e1175bSopenharmony_ci    /* Look for a private key that matches the public key in cert.
1174a8e1175bSopenharmony_ci     * Since this test code has the private key inside Mbed TLS,
1175a8e1175bSopenharmony_ci     * we call mbedtls_pk_check_pair to match a private key with the
1176a8e1175bSopenharmony_ci     * public key. */
1177a8e1175bSopenharmony_ci    for (slot = 0; slot < config_data->slots_used; slot++) {
1178a8e1175bSopenharmony_ci        if (mbedtls_pk_check_pair(&cert->pk,
1179a8e1175bSopenharmony_ci                                  config_data->slots[slot].pk,
1180a8e1175bSopenharmony_ci                                  rng_get, &rng) == 0) {
1181a8e1175bSopenharmony_ci            break;
1182a8e1175bSopenharmony_ci        }
1183a8e1175bSopenharmony_ci    }
1184a8e1175bSopenharmony_ci    if (slot == config_data->slots_used) {
1185a8e1175bSopenharmony_ci        mbedtls_printf("Async %s callback: no key matches this certificate.\n",
1186a8e1175bSopenharmony_ci                       op_name);
1187a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH;
1188a8e1175bSopenharmony_ci    }
1189a8e1175bSopenharmony_ci    mbedtls_printf("Async %s callback: using key slot %u, delay=%u.\n",
1190a8e1175bSopenharmony_ci                   op_name, slot, config_data->slots[slot].delay);
1191a8e1175bSopenharmony_ci
1192a8e1175bSopenharmony_ci    if (config_data->inject_error == SSL_ASYNC_INJECT_ERROR_START) {
1193a8e1175bSopenharmony_ci        mbedtls_printf("Async %s callback: injected error\n", op_name);
1194a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1195a8e1175bSopenharmony_ci    }
1196a8e1175bSopenharmony_ci
1197a8e1175bSopenharmony_ci    if (input_len > SSL_ASYNC_INPUT_MAX_SIZE) {
1198a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
1199a8e1175bSopenharmony_ci    }
1200a8e1175bSopenharmony_ci
1201a8e1175bSopenharmony_ci    ctx = mbedtls_calloc(1, sizeof(*ctx));
1202a8e1175bSopenharmony_ci    if (ctx == NULL) {
1203a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ALLOC_FAILED;
1204a8e1175bSopenharmony_ci    }
1205a8e1175bSopenharmony_ci    ctx->slot = slot;
1206a8e1175bSopenharmony_ci    ctx->operation_type = op_type;
1207a8e1175bSopenharmony_ci    ctx->md_alg = md_alg;
1208a8e1175bSopenharmony_ci    memcpy(ctx->input, input, input_len);
1209a8e1175bSopenharmony_ci    ctx->input_len = input_len;
1210a8e1175bSopenharmony_ci    ctx->remaining_delay = config_data->slots[slot].delay;
1211a8e1175bSopenharmony_ci    mbedtls_ssl_set_async_operation_data(ssl, ctx);
1212a8e1175bSopenharmony_ci
1213a8e1175bSopenharmony_ci    if (ctx->remaining_delay == 0) {
1214a8e1175bSopenharmony_ci        return 0;
1215a8e1175bSopenharmony_ci    } else {
1216a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS;
1217a8e1175bSopenharmony_ci    }
1218a8e1175bSopenharmony_ci}
1219a8e1175bSopenharmony_ci
1220a8e1175bSopenharmony_cistatic int ssl_async_sign(mbedtls_ssl_context *ssl,
1221a8e1175bSopenharmony_ci                          mbedtls_x509_crt *cert,
1222a8e1175bSopenharmony_ci                          mbedtls_md_type_t md_alg,
1223a8e1175bSopenharmony_ci                          const unsigned char *hash,
1224a8e1175bSopenharmony_ci                          size_t hash_len)
1225a8e1175bSopenharmony_ci{
1226a8e1175bSopenharmony_ci    return ssl_async_start(ssl, cert,
1227a8e1175bSopenharmony_ci                           ASYNC_OP_SIGN, md_alg,
1228a8e1175bSopenharmony_ci                           hash, hash_len);
1229a8e1175bSopenharmony_ci}
1230a8e1175bSopenharmony_ci
1231a8e1175bSopenharmony_cistatic int ssl_async_decrypt(mbedtls_ssl_context *ssl,
1232a8e1175bSopenharmony_ci                             mbedtls_x509_crt *cert,
1233a8e1175bSopenharmony_ci                             const unsigned char *input,
1234a8e1175bSopenharmony_ci                             size_t input_len)
1235a8e1175bSopenharmony_ci{
1236a8e1175bSopenharmony_ci    return ssl_async_start(ssl, cert,
1237a8e1175bSopenharmony_ci                           ASYNC_OP_DECRYPT, MBEDTLS_MD_NONE,
1238a8e1175bSopenharmony_ci                           input, input_len);
1239a8e1175bSopenharmony_ci}
1240a8e1175bSopenharmony_ci
1241a8e1175bSopenharmony_cistatic int ssl_async_resume(mbedtls_ssl_context *ssl,
1242a8e1175bSopenharmony_ci                            unsigned char *output,
1243a8e1175bSopenharmony_ci                            size_t *output_len,
1244a8e1175bSopenharmony_ci                            size_t output_size)
1245a8e1175bSopenharmony_ci{
1246a8e1175bSopenharmony_ci    ssl_async_operation_context_t *ctx = mbedtls_ssl_get_async_operation_data(ssl);
1247a8e1175bSopenharmony_ci    ssl_async_key_context_t *config_data =
1248a8e1175bSopenharmony_ci        mbedtls_ssl_conf_get_async_config_data(ssl->conf);
1249a8e1175bSopenharmony_ci    ssl_async_key_slot_t *key_slot = &config_data->slots[ctx->slot];
1250a8e1175bSopenharmony_ci    int ret;
1251a8e1175bSopenharmony_ci    const char *op_name;
1252a8e1175bSopenharmony_ci
1253a8e1175bSopenharmony_ci    if (ctx->remaining_delay > 0) {
1254a8e1175bSopenharmony_ci        --ctx->remaining_delay;
1255a8e1175bSopenharmony_ci        mbedtls_printf("Async resume (slot %u): call %u more times.\n",
1256a8e1175bSopenharmony_ci                       ctx->slot, ctx->remaining_delay);
1257a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS;
1258a8e1175bSopenharmony_ci    }
1259a8e1175bSopenharmony_ci
1260a8e1175bSopenharmony_ci    switch (ctx->operation_type) {
1261a8e1175bSopenharmony_ci        case ASYNC_OP_DECRYPT:
1262a8e1175bSopenharmony_ci            ret = mbedtls_pk_decrypt(key_slot->pk,
1263a8e1175bSopenharmony_ci                                     ctx->input, ctx->input_len,
1264a8e1175bSopenharmony_ci                                     output, output_len, output_size,
1265a8e1175bSopenharmony_ci                                     config_data->f_rng, config_data->p_rng);
1266a8e1175bSopenharmony_ci            break;
1267a8e1175bSopenharmony_ci        case ASYNC_OP_SIGN:
1268a8e1175bSopenharmony_ci            ret = mbedtls_pk_sign(key_slot->pk,
1269a8e1175bSopenharmony_ci                                  ctx->md_alg,
1270a8e1175bSopenharmony_ci                                  ctx->input, ctx->input_len,
1271a8e1175bSopenharmony_ci                                  output, output_size, output_len,
1272a8e1175bSopenharmony_ci                                  config_data->f_rng, config_data->p_rng);
1273a8e1175bSopenharmony_ci            break;
1274a8e1175bSopenharmony_ci        default:
1275a8e1175bSopenharmony_ci            mbedtls_printf(
1276a8e1175bSopenharmony_ci                "Async resume (slot %u): unknown operation type %ld. This shouldn't happen.\n",
1277a8e1175bSopenharmony_ci                ctx->slot,
1278a8e1175bSopenharmony_ci                (long) ctx->operation_type);
1279a8e1175bSopenharmony_ci            mbedtls_free(ctx);
1280a8e1175bSopenharmony_ci            return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1281a8e1175bSopenharmony_ci            break;
1282a8e1175bSopenharmony_ci    }
1283a8e1175bSopenharmony_ci
1284a8e1175bSopenharmony_ci    op_name = ssl_async_operation_names[ctx->operation_type];
1285a8e1175bSopenharmony_ci
1286a8e1175bSopenharmony_ci    if (config_data->inject_error == SSL_ASYNC_INJECT_ERROR_RESUME) {
1287a8e1175bSopenharmony_ci        mbedtls_printf("Async resume callback: %s done but injected error\n",
1288a8e1175bSopenharmony_ci                       op_name);
1289a8e1175bSopenharmony_ci        mbedtls_free(ctx);
1290a8e1175bSopenharmony_ci        return MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE;
1291a8e1175bSopenharmony_ci    }
1292a8e1175bSopenharmony_ci
1293a8e1175bSopenharmony_ci    mbedtls_printf("Async resume (slot %u): %s done, status=%d.\n",
1294a8e1175bSopenharmony_ci                   ctx->slot, op_name, ret);
1295a8e1175bSopenharmony_ci    mbedtls_free(ctx);
1296a8e1175bSopenharmony_ci    return ret;
1297a8e1175bSopenharmony_ci}
1298a8e1175bSopenharmony_ci
1299a8e1175bSopenharmony_cistatic void ssl_async_cancel(mbedtls_ssl_context *ssl)
1300a8e1175bSopenharmony_ci{
1301a8e1175bSopenharmony_ci    ssl_async_operation_context_t *ctx = mbedtls_ssl_get_async_operation_data(ssl);
1302a8e1175bSopenharmony_ci    mbedtls_printf("Async cancel callback.\n");
1303a8e1175bSopenharmony_ci    mbedtls_free(ctx);
1304a8e1175bSopenharmony_ci}
1305a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
1306a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
1307a8e1175bSopenharmony_ci
1308a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1309a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
1310a8e1175bSopenharmony_cistatic psa_status_t psa_setup_psk_key_slot(mbedtls_svc_key_id_t *slot,
1311a8e1175bSopenharmony_ci                                           psa_algorithm_t alg,
1312a8e1175bSopenharmony_ci                                           unsigned char *psk,
1313a8e1175bSopenharmony_ci                                           size_t psk_len)
1314a8e1175bSopenharmony_ci{
1315a8e1175bSopenharmony_ci    psa_status_t status;
1316a8e1175bSopenharmony_ci    psa_key_attributes_t key_attributes;
1317a8e1175bSopenharmony_ci
1318a8e1175bSopenharmony_ci    key_attributes = psa_key_attributes_init();
1319a8e1175bSopenharmony_ci    psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
1320a8e1175bSopenharmony_ci    psa_set_key_algorithm(&key_attributes, alg);
1321a8e1175bSopenharmony_ci    psa_set_key_type(&key_attributes, PSA_KEY_TYPE_DERIVE);
1322a8e1175bSopenharmony_ci
1323a8e1175bSopenharmony_ci    status = psa_import_key(&key_attributes, psk, psk_len, slot);
1324a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
1325a8e1175bSopenharmony_ci        fprintf(stderr, "IMPORT\n");
1326a8e1175bSopenharmony_ci        return status;
1327a8e1175bSopenharmony_ci    }
1328a8e1175bSopenharmony_ci
1329a8e1175bSopenharmony_ci    return PSA_SUCCESS;
1330a8e1175bSopenharmony_ci}
1331a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
1332a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1333a8e1175bSopenharmony_ci
1334a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
1335a8e1175bSopenharmony_ciint report_cid_usage(mbedtls_ssl_context *ssl,
1336a8e1175bSopenharmony_ci                     const char *additional_description)
1337a8e1175bSopenharmony_ci{
1338a8e1175bSopenharmony_ci    int ret;
1339a8e1175bSopenharmony_ci    unsigned char peer_cid[MBEDTLS_SSL_CID_OUT_LEN_MAX];
1340a8e1175bSopenharmony_ci    size_t peer_cid_len;
1341a8e1175bSopenharmony_ci    int cid_negotiated;
1342a8e1175bSopenharmony_ci
1343a8e1175bSopenharmony_ci    if (opt.transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
1344a8e1175bSopenharmony_ci        return 0;
1345a8e1175bSopenharmony_ci    }
1346a8e1175bSopenharmony_ci
1347a8e1175bSopenharmony_ci    /* Check if the use of a CID has been negotiated */
1348a8e1175bSopenharmony_ci    ret = mbedtls_ssl_get_peer_cid(ssl, &cid_negotiated,
1349a8e1175bSopenharmony_ci                                   peer_cid, &peer_cid_len);
1350a8e1175bSopenharmony_ci    if (ret != 0) {
1351a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  ! mbedtls_ssl_get_peer_cid returned -0x%x\n\n",
1352a8e1175bSopenharmony_ci                       (unsigned int) -ret);
1353a8e1175bSopenharmony_ci        return ret;
1354a8e1175bSopenharmony_ci    }
1355a8e1175bSopenharmony_ci
1356a8e1175bSopenharmony_ci    if (cid_negotiated == MBEDTLS_SSL_CID_DISABLED) {
1357a8e1175bSopenharmony_ci        if (opt.cid_enabled == MBEDTLS_SSL_CID_ENABLED) {
1358a8e1175bSopenharmony_ci            mbedtls_printf("(%s) Use of Connection ID was not offered by client.\n",
1359a8e1175bSopenharmony_ci                           additional_description);
1360a8e1175bSopenharmony_ci        }
1361a8e1175bSopenharmony_ci    } else {
1362a8e1175bSopenharmony_ci        size_t idx = 0;
1363a8e1175bSopenharmony_ci        mbedtls_printf("(%s) Use of Connection ID has been negotiated.\n",
1364a8e1175bSopenharmony_ci                       additional_description);
1365a8e1175bSopenharmony_ci        mbedtls_printf("(%s) Peer CID (length %u Bytes): ",
1366a8e1175bSopenharmony_ci                       additional_description,
1367a8e1175bSopenharmony_ci                       (unsigned) peer_cid_len);
1368a8e1175bSopenharmony_ci        while (idx < peer_cid_len) {
1369a8e1175bSopenharmony_ci            mbedtls_printf("%02x ", peer_cid[idx]);
1370a8e1175bSopenharmony_ci            idx++;
1371a8e1175bSopenharmony_ci        }
1372a8e1175bSopenharmony_ci        mbedtls_printf("\n");
1373a8e1175bSopenharmony_ci    }
1374a8e1175bSopenharmony_ci
1375a8e1175bSopenharmony_ci    return 0;
1376a8e1175bSopenharmony_ci}
1377a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
1378a8e1175bSopenharmony_ci
1379a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_HAVE_TIME)
1380a8e1175bSopenharmony_cistatic inline void put_unaligned_uint32(void *p, uint32_t x)
1381a8e1175bSopenharmony_ci{
1382a8e1175bSopenharmony_ci    memcpy(p, &x, sizeof(x));
1383a8e1175bSopenharmony_ci}
1384a8e1175bSopenharmony_ci
1385a8e1175bSopenharmony_ci/* Functions for session ticket tests */
1386a8e1175bSopenharmony_ciint dummy_ticket_write(void *p_ticket, const mbedtls_ssl_session *session,
1387a8e1175bSopenharmony_ci                       unsigned char *start, const unsigned char *end,
1388a8e1175bSopenharmony_ci                       size_t *tlen, uint32_t *ticket_lifetime)
1389a8e1175bSopenharmony_ci{
1390a8e1175bSopenharmony_ci    int ret;
1391a8e1175bSopenharmony_ci    unsigned char *p = start;
1392a8e1175bSopenharmony_ci    size_t clear_len;
1393a8e1175bSopenharmony_ci    ((void) p_ticket);
1394a8e1175bSopenharmony_ci
1395a8e1175bSopenharmony_ci    if (end - p < 4) {
1396a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
1397a8e1175bSopenharmony_ci    }
1398a8e1175bSopenharmony_ci    put_unaligned_uint32(p, 7 * 24 * 3600);
1399a8e1175bSopenharmony_ci    *ticket_lifetime = 7 * 24 * 3600;
1400a8e1175bSopenharmony_ci    p += 4;
1401a8e1175bSopenharmony_ci
1402a8e1175bSopenharmony_ci    /* Dump session state */
1403a8e1175bSopenharmony_ci    if ((ret = mbedtls_ssl_session_save(session, p, end - p,
1404a8e1175bSopenharmony_ci                                        &clear_len)) != 0) {
1405a8e1175bSopenharmony_ci        return ret;
1406a8e1175bSopenharmony_ci    }
1407a8e1175bSopenharmony_ci
1408a8e1175bSopenharmony_ci    *tlen = 4 + clear_len;
1409a8e1175bSopenharmony_ci
1410a8e1175bSopenharmony_ci    return 0;
1411a8e1175bSopenharmony_ci}
1412a8e1175bSopenharmony_ci
1413a8e1175bSopenharmony_ciint dummy_ticket_parse(void *p_ticket, mbedtls_ssl_session *session,
1414a8e1175bSopenharmony_ci                       unsigned char *buf, size_t len)
1415a8e1175bSopenharmony_ci{
1416a8e1175bSopenharmony_ci    int ret;
1417a8e1175bSopenharmony_ci    ((void) p_ticket);
1418a8e1175bSopenharmony_ci
1419a8e1175bSopenharmony_ci    if ((ret = mbedtls_ssl_session_load(session, buf + 4, len - 4)) != 0) {
1420a8e1175bSopenharmony_ci        return ret;
1421a8e1175bSopenharmony_ci    }
1422a8e1175bSopenharmony_ci
1423a8e1175bSopenharmony_ci    switch (opt.dummy_ticket % 11) {
1424a8e1175bSopenharmony_ci        case 1:
1425a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INVALID_MAC;
1426a8e1175bSopenharmony_ci        case 2:
1427a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
1428a8e1175bSopenharmony_ci        case 3:
1429a8e1175bSopenharmony_ci            /* Creation time in the future. */
1430a8e1175bSopenharmony_ci            session->ticket_creation_time = mbedtls_ms_time() + 1000;
1431a8e1175bSopenharmony_ci            break;
1432a8e1175bSopenharmony_ci        case 4:
1433a8e1175bSopenharmony_ci            /* Ticket has reached the end of lifetime. */
1434a8e1175bSopenharmony_ci            session->ticket_creation_time = mbedtls_ms_time() -
1435a8e1175bSopenharmony_ci                                            (7 * 24 * 3600 * 1000 + 1000);
1436a8e1175bSopenharmony_ci            break;
1437a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
1438a8e1175bSopenharmony_ci        case 5:
1439a8e1175bSopenharmony_ci            /* Ticket is valid, but client age is below the lower bound of the tolerance window. */
1440a8e1175bSopenharmony_ci            session->ticket_age_add += MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE + 4 * 1000;
1441a8e1175bSopenharmony_ci            /* Make sure the execution time does not affect the result */
1442a8e1175bSopenharmony_ci            session->ticket_creation_time = mbedtls_ms_time();
1443a8e1175bSopenharmony_ci            break;
1444a8e1175bSopenharmony_ci
1445a8e1175bSopenharmony_ci        case 6:
1446a8e1175bSopenharmony_ci            /* Ticket is valid, but client age is beyond the upper bound of the tolerance window. */
1447a8e1175bSopenharmony_ci            session->ticket_age_add -= MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE + 4 * 1000;
1448a8e1175bSopenharmony_ci            /* Make sure the execution time does not affect the result */
1449a8e1175bSopenharmony_ci            session->ticket_creation_time = mbedtls_ms_time();
1450a8e1175bSopenharmony_ci            break;
1451a8e1175bSopenharmony_ci        case 7:
1452a8e1175bSopenharmony_ci            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_NONE;
1453a8e1175bSopenharmony_ci            break;
1454a8e1175bSopenharmony_ci        case 8:
1455a8e1175bSopenharmony_ci            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
1456a8e1175bSopenharmony_ci            break;
1457a8e1175bSopenharmony_ci        case 9:
1458a8e1175bSopenharmony_ci            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
1459a8e1175bSopenharmony_ci            break;
1460a8e1175bSopenharmony_ci        case 10:
1461a8e1175bSopenharmony_ci            session->ticket_flags = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
1462a8e1175bSopenharmony_ci            break;
1463a8e1175bSopenharmony_ci#endif
1464a8e1175bSopenharmony_ci        default:
1465a8e1175bSopenharmony_ci            break;
1466a8e1175bSopenharmony_ci    }
1467a8e1175bSopenharmony_ci
1468a8e1175bSopenharmony_ci    return ret;
1469a8e1175bSopenharmony_ci}
1470a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_HAVE_TIME */
1471a8e1175bSopenharmony_ci
1472a8e1175bSopenharmony_ciint parse_cipher(char *buf)
1473a8e1175bSopenharmony_ci{
1474a8e1175bSopenharmony_ci    if (strcmp(buf, "AES-128-CCM")) {
1475a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_AES_128_CCM;
1476a8e1175bSopenharmony_ci    } else if (strcmp(buf, "AES-128-GCM")) {
1477a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_AES_128_GCM;
1478a8e1175bSopenharmony_ci    } else if (strcmp(buf, "AES-192-CCM")) {
1479a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_AES_192_CCM;
1480a8e1175bSopenharmony_ci    } else if (strcmp(buf, "AES-192-GCM")) {
1481a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_AES_192_GCM;
1482a8e1175bSopenharmony_ci    } else if (strcmp(buf, "AES-256-CCM")) {
1483a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_AES_256_CCM;
1484a8e1175bSopenharmony_ci    } else if (strcmp(buf, "ARIA-128-CCM")) {
1485a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_ARIA_128_CCM;
1486a8e1175bSopenharmony_ci    } else if (strcmp(buf, "ARIA-128-GCM")) {
1487a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_ARIA_128_GCM;
1488a8e1175bSopenharmony_ci    } else if (strcmp(buf, "ARIA-192-CCM")) {
1489a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_ARIA_192_CCM;
1490a8e1175bSopenharmony_ci    } else if (strcmp(buf, "ARIA-192-GCM")) {
1491a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_ARIA_192_GCM;
1492a8e1175bSopenharmony_ci    } else if (strcmp(buf, "ARIA-256-CCM")) {
1493a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_ARIA_256_CCM;
1494a8e1175bSopenharmony_ci    } else if (strcmp(buf, "ARIA-256-GCM")) {
1495a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_ARIA_256_GCM;
1496a8e1175bSopenharmony_ci    } else if (strcmp(buf, "CAMELLIA-128-CCM")) {
1497a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_CAMELLIA_128_CCM;
1498a8e1175bSopenharmony_ci    } else if (strcmp(buf, "CAMELLIA-192-CCM")) {
1499a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_CAMELLIA_192_CCM;
1500a8e1175bSopenharmony_ci    } else if (strcmp(buf, "CAMELLIA-256-CCM")) {
1501a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_CAMELLIA_256_CCM;
1502a8e1175bSopenharmony_ci    } else if (strcmp(buf, "CHACHA20-POLY1305")) {
1503a8e1175bSopenharmony_ci        return MBEDTLS_CIPHER_CHACHA20_POLY1305;
1504a8e1175bSopenharmony_ci    }
1505a8e1175bSopenharmony_ci    return MBEDTLS_CIPHER_NONE;
1506a8e1175bSopenharmony_ci}
1507a8e1175bSopenharmony_ci
1508a8e1175bSopenharmony_ciint main(int argc, char *argv[])
1509a8e1175bSopenharmony_ci{
1510a8e1175bSopenharmony_ci    int ret = 0, len, written, frags, exchanges_left;
1511a8e1175bSopenharmony_ci    int query_config_ret = 0;
1512a8e1175bSopenharmony_ci    io_ctx_t io_ctx;
1513a8e1175bSopenharmony_ci    unsigned char *buf = 0;
1514a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
1515a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1516a8e1175bSopenharmony_ci    psa_algorithm_t alg = 0;
1517a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t psk_slot = MBEDTLS_SVC_KEY_ID_INIT;
1518a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
1519a8e1175bSopenharmony_ci    unsigned char psk[MBEDTLS_PSK_MAX_LEN];
1520a8e1175bSopenharmony_ci    size_t psk_len = 0;
1521a8e1175bSopenharmony_ci    psk_entry *psk_info = NULL;
1522a8e1175bSopenharmony_ci#endif
1523a8e1175bSopenharmony_ci    const char *pers = "ssl_server2";
1524a8e1175bSopenharmony_ci    unsigned char client_ip[16] = { 0 };
1525a8e1175bSopenharmony_ci    size_t cliip_len;
1526a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_COOKIE_C)
1527a8e1175bSopenharmony_ci    mbedtls_ssl_cookie_ctx cookie_ctx;
1528a8e1175bSopenharmony_ci#endif
1529a8e1175bSopenharmony_ci
1530a8e1175bSopenharmony_ci    mbedtls_ssl_context ssl;
1531a8e1175bSopenharmony_ci    mbedtls_ssl_config conf;
1532a8e1175bSopenharmony_ci#if defined(MBEDTLS_TIMING_C)
1533a8e1175bSopenharmony_ci    mbedtls_timing_delay_context timer;
1534a8e1175bSopenharmony_ci#endif
1535a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION)
1536a8e1175bSopenharmony_ci    unsigned char renego_period[8] = { 0 };
1537a8e1175bSopenharmony_ci#endif
1538a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
1539a8e1175bSopenharmony_ci    uint32_t flags;
1540a8e1175bSopenharmony_ci    mbedtls_x509_crt cacert;
1541a8e1175bSopenharmony_ci    mbedtls_x509_crt srvcert;
1542a8e1175bSopenharmony_ci    mbedtls_pk_context pkey;
1543a8e1175bSopenharmony_ci    mbedtls_x509_crt srvcert2;
1544a8e1175bSopenharmony_ci    mbedtls_pk_context pkey2;
1545a8e1175bSopenharmony_ci    mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default;
1546a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1547a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_slot = MBEDTLS_SVC_KEY_ID_INIT; /* invalid key slot */
1548a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key_slot2 = MBEDTLS_SVC_KEY_ID_INIT; /* invalid key slot */
1549a8e1175bSopenharmony_ci#endif
1550a8e1175bSopenharmony_ci    int key_cert_init = 0, key_cert_init2 = 0;
1551a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
1552a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
1553a8e1175bSopenharmony_ci    ssl_async_key_context_t ssl_async_keys;
1554a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
1555a8e1175bSopenharmony_ci#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
1556a8e1175bSopenharmony_ci    mbedtls_dhm_context dhm;
1557a8e1175bSopenharmony_ci#endif
1558a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C)
1559a8e1175bSopenharmony_ci    mbedtls_ssl_cache_context cache;
1560a8e1175bSopenharmony_ci#endif
1561a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C)
1562a8e1175bSopenharmony_ci    mbedtls_ssl_ticket_context ticket_ctx;
1563a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_TICKET_C */
1564a8e1175bSopenharmony_ci#if defined(SNI_OPTION)
1565a8e1175bSopenharmony_ci    sni_entry *sni_info = NULL;
1566a8e1175bSopenharmony_ci#endif
1567a8e1175bSopenharmony_ci    uint16_t group_list[GROUP_LIST_SIZE];
1568a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN)
1569a8e1175bSopenharmony_ci    const char *alpn_list[ALPN_LIST_SIZE];
1570a8e1175bSopenharmony_ci#endif
1571a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
1572a8e1175bSopenharmony_ci    unsigned char alloc_buf[MEMORY_HEAP_SIZE];
1573a8e1175bSopenharmony_ci#endif
1574a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
1575a8e1175bSopenharmony_ci    unsigned char cid[MBEDTLS_SSL_CID_IN_LEN_MAX];
1576a8e1175bSopenharmony_ci    unsigned char cid_renego[MBEDTLS_SSL_CID_IN_LEN_MAX];
1577a8e1175bSopenharmony_ci    size_t cid_len = 0;
1578a8e1175bSopenharmony_ci    size_t cid_renego_len = 0;
1579a8e1175bSopenharmony_ci#endif
1580a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
1581a8e1175bSopenharmony_ci    unsigned char *context_buf = NULL;
1582a8e1175bSopenharmony_ci    size_t context_buf_len = 0;
1583a8e1175bSopenharmony_ci#endif
1584a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
1585a8e1175bSopenharmony_ci    defined(MBEDTLS_USE_PSA_CRYPTO)
1586a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t ecjpake_pw_slot = MBEDTLS_SVC_KEY_ID_INIT; /* ecjpake password key slot */
1587a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1588a8e1175bSopenharmony_ci
1589a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
1590a8e1175bSopenharmony_ci    uint16_t sig_alg_list[SIG_ALG_LIST_SIZE];
1591a8e1175bSopenharmony_ci#endif
1592a8e1175bSopenharmony_ci
1593a8e1175bSopenharmony_ci    int i;
1594a8e1175bSopenharmony_ci    char *p, *q;
1595a8e1175bSopenharmony_ci    const int *list;
1596a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
1597a8e1175bSopenharmony_ci    psa_status_t status;
1598a8e1175bSopenharmony_ci#endif
1599a8e1175bSopenharmony_ci    unsigned char eap_tls_keymaterial[16];
1600a8e1175bSopenharmony_ci    unsigned char eap_tls_iv[8];
1601a8e1175bSopenharmony_ci    const char *eap_tls_label = "client EAP encryption";
1602a8e1175bSopenharmony_ci    eap_tls_keys eap_tls_keying;
1603a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP)
1604a8e1175bSopenharmony_ci    /*! master keys and master salt for SRTP generated during handshake */
1605a8e1175bSopenharmony_ci    unsigned char dtls_srtp_key_material[MBEDTLS_TLS_SRTP_MAX_KEY_MATERIAL_LENGTH];
1606a8e1175bSopenharmony_ci    const char *dtls_srtp_label = "EXTRACTOR-dtls_srtp";
1607a8e1175bSopenharmony_ci    dtls_srtp_keys dtls_srtp_keying;
1608a8e1175bSopenharmony_ci    const mbedtls_ssl_srtp_profile default_profiles[] = {
1609a8e1175bSopenharmony_ci        MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80,
1610a8e1175bSopenharmony_ci        MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32,
1611a8e1175bSopenharmony_ci        MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80,
1612a8e1175bSopenharmony_ci        MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32,
1613a8e1175bSopenharmony_ci        MBEDTLS_TLS_SRTP_UNSET
1614a8e1175bSopenharmony_ci    };
1615a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_SRTP */
1616a8e1175bSopenharmony_ci
1617a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
1618a8e1175bSopenharmony_ci    mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf));
1619a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG)
1620a8e1175bSopenharmony_ci    size_t current_heap_memory, peak_heap_memory, heap_blocks;
1621a8e1175bSopenharmony_ci#endif  /* MBEDTLS_MEMORY_DEBUG */
1622a8e1175bSopenharmony_ci#endif  /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */
1623a8e1175bSopenharmony_ci
1624a8e1175bSopenharmony_ci#if defined(MBEDTLS_TEST_HOOKS)
1625a8e1175bSopenharmony_ci    test_hooks_init();
1626a8e1175bSopenharmony_ci#endif /* MBEDTLS_TEST_HOOKS */
1627a8e1175bSopenharmony_ci
1628a8e1175bSopenharmony_ci    /*
1629a8e1175bSopenharmony_ci     * Make sure memory references are valid in case we exit early.
1630a8e1175bSopenharmony_ci     */
1631a8e1175bSopenharmony_ci    mbedtls_net_init(&client_fd);
1632a8e1175bSopenharmony_ci    mbedtls_net_init(&listen_fd);
1633a8e1175bSopenharmony_ci    mbedtls_ssl_init(&ssl);
1634a8e1175bSopenharmony_ci    mbedtls_ssl_config_init(&conf);
1635a8e1175bSopenharmony_ci    rng_init(&rng);
1636a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
1637a8e1175bSopenharmony_ci    mbedtls_x509_crt_init(&cacert);
1638a8e1175bSopenharmony_ci    mbedtls_x509_crt_init(&srvcert);
1639a8e1175bSopenharmony_ci    mbedtls_pk_init(&pkey);
1640a8e1175bSopenharmony_ci    mbedtls_x509_crt_init(&srvcert2);
1641a8e1175bSopenharmony_ci    mbedtls_pk_init(&pkey2);
1642a8e1175bSopenharmony_ci#endif
1643a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
1644a8e1175bSopenharmony_ci    memset(&ssl_async_keys, 0, sizeof(ssl_async_keys));
1645a8e1175bSopenharmony_ci#endif
1646a8e1175bSopenharmony_ci#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
1647a8e1175bSopenharmony_ci    mbedtls_dhm_init(&dhm);
1648a8e1175bSopenharmony_ci#endif
1649a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C)
1650a8e1175bSopenharmony_ci    mbedtls_ssl_cache_init(&cache);
1651a8e1175bSopenharmony_ci#endif
1652a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C)
1653a8e1175bSopenharmony_ci    mbedtls_ssl_ticket_init(&ticket_ctx);
1654a8e1175bSopenharmony_ci#endif
1655a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN)
1656a8e1175bSopenharmony_ci    memset((void *) alpn_list, 0, sizeof(alpn_list));
1657a8e1175bSopenharmony_ci#endif
1658a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_COOKIE_C)
1659a8e1175bSopenharmony_ci    mbedtls_ssl_cookie_init(&cookie_ctx);
1660a8e1175bSopenharmony_ci#endif
1661a8e1175bSopenharmony_ci
1662a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
1663a8e1175bSopenharmony_ci    status = psa_crypto_init();
1664a8e1175bSopenharmony_ci    if (status != PSA_SUCCESS) {
1665a8e1175bSopenharmony_ci        mbedtls_fprintf(stderr, "Failed to initialize PSA Crypto implementation: %d\n",
1666a8e1175bSopenharmony_ci                        (int) status);
1667a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
1668a8e1175bSopenharmony_ci        goto exit;
1669a8e1175bSopenharmony_ci    }
1670a8e1175bSopenharmony_ci#endif  /* MBEDTLS_USE_PSA_CRYPTO */
1671a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
1672a8e1175bSopenharmony_ci    mbedtls_test_enable_insecure_external_rng();
1673a8e1175bSopenharmony_ci#endif  /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
1674a8e1175bSopenharmony_ci
1675a8e1175bSopenharmony_ci#if !defined(_WIN32)
1676a8e1175bSopenharmony_ci    /* Abort cleanly on SIGTERM and SIGINT */
1677a8e1175bSopenharmony_ci    signal(SIGTERM, term_handler);
1678a8e1175bSopenharmony_ci    signal(SIGINT, term_handler);
1679a8e1175bSopenharmony_ci#endif
1680a8e1175bSopenharmony_ci
1681a8e1175bSopenharmony_ci    opt.buffer_size         = DFL_IO_BUF_LEN;
1682a8e1175bSopenharmony_ci    opt.server_addr         = DFL_SERVER_ADDR;
1683a8e1175bSopenharmony_ci    opt.server_port         = DFL_SERVER_PORT;
1684a8e1175bSopenharmony_ci    opt.debug_level         = DFL_DEBUG_LEVEL;
1685a8e1175bSopenharmony_ci    opt.event               = DFL_EVENT;
1686a8e1175bSopenharmony_ci    opt.response_size       = DFL_RESPONSE_SIZE;
1687a8e1175bSopenharmony_ci    opt.nbio                = DFL_NBIO;
1688a8e1175bSopenharmony_ci    opt.cid_enabled         = DFL_CID_ENABLED;
1689a8e1175bSopenharmony_ci    opt.cid_enabled_renego  = DFL_CID_ENABLED_RENEGO;
1690a8e1175bSopenharmony_ci    opt.cid_val             = DFL_CID_VALUE;
1691a8e1175bSopenharmony_ci    opt.cid_val_renego      = DFL_CID_VALUE_RENEGO;
1692a8e1175bSopenharmony_ci    opt.read_timeout        = DFL_READ_TIMEOUT;
1693a8e1175bSopenharmony_ci    opt.ca_file             = DFL_CA_FILE;
1694a8e1175bSopenharmony_ci    opt.ca_path             = DFL_CA_PATH;
1695a8e1175bSopenharmony_ci    opt.crt_file            = DFL_CRT_FILE;
1696a8e1175bSopenharmony_ci    opt.key_file            = DFL_KEY_FILE;
1697a8e1175bSopenharmony_ci    opt.key_opaque          = DFL_KEY_OPAQUE;
1698a8e1175bSopenharmony_ci    opt.key_pwd             = DFL_KEY_PWD;
1699a8e1175bSopenharmony_ci    opt.crt_file2           = DFL_CRT_FILE2;
1700a8e1175bSopenharmony_ci    opt.key_file2           = DFL_KEY_FILE2;
1701a8e1175bSopenharmony_ci    opt.key_pwd2            = DFL_KEY_PWD2;
1702a8e1175bSopenharmony_ci    opt.async_operations    = DFL_ASYNC_OPERATIONS;
1703a8e1175bSopenharmony_ci    opt.async_private_delay1 = DFL_ASYNC_PRIVATE_DELAY1;
1704a8e1175bSopenharmony_ci    opt.async_private_delay2 = DFL_ASYNC_PRIVATE_DELAY2;
1705a8e1175bSopenharmony_ci    opt.async_private_error = DFL_ASYNC_PRIVATE_ERROR;
1706a8e1175bSopenharmony_ci    opt.psk                 = DFL_PSK;
1707a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1708a8e1175bSopenharmony_ci    opt.psk_opaque          = DFL_PSK_OPAQUE;
1709a8e1175bSopenharmony_ci    opt.psk_list_opaque     = DFL_PSK_LIST_OPAQUE;
1710a8e1175bSopenharmony_ci#endif
1711a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
1712a8e1175bSopenharmony_ci    opt.ca_callback         = DFL_CA_CALLBACK;
1713a8e1175bSopenharmony_ci#endif
1714a8e1175bSopenharmony_ci    opt.psk_identity        = DFL_PSK_IDENTITY;
1715a8e1175bSopenharmony_ci    opt.psk_list            = DFL_PSK_LIST;
1716a8e1175bSopenharmony_ci    opt.ecjpake_pw          = DFL_ECJPAKE_PW;
1717a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1718a8e1175bSopenharmony_ci    opt.ecjpake_pw_opaque   = DFL_ECJPAKE_PW_OPAQUE;
1719a8e1175bSopenharmony_ci#endif
1720a8e1175bSopenharmony_ci    opt.force_ciphersuite[0] = DFL_FORCE_CIPHER;
1721a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
1722a8e1175bSopenharmony_ci    opt.tls13_kex_modes     = DFL_TLS1_3_KEX_MODES;
1723a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
1724a8e1175bSopenharmony_ci    opt.renegotiation       = DFL_RENEGOTIATION;
1725a8e1175bSopenharmony_ci    opt.allow_legacy        = DFL_ALLOW_LEGACY;
1726a8e1175bSopenharmony_ci    opt.renegotiate         = DFL_RENEGOTIATE;
1727a8e1175bSopenharmony_ci    opt.renego_delay        = DFL_RENEGO_DELAY;
1728a8e1175bSopenharmony_ci    opt.renego_period       = DFL_RENEGO_PERIOD;
1729a8e1175bSopenharmony_ci    opt.exchanges           = DFL_EXCHANGES;
1730a8e1175bSopenharmony_ci    opt.min_version         = DFL_MIN_VERSION;
1731a8e1175bSopenharmony_ci    opt.max_version         = DFL_MAX_VERSION;
1732a8e1175bSopenharmony_ci    opt.allow_sha1          = DFL_SHA1;
1733a8e1175bSopenharmony_ci    opt.auth_mode           = DFL_AUTH_MODE;
1734a8e1175bSopenharmony_ci    opt.cert_req_ca_list    = DFL_CERT_REQ_CA_LIST;
1735a8e1175bSopenharmony_ci    opt.cert_req_dn_hint    = DFL_CERT_REQ_DN_HINT;
1736a8e1175bSopenharmony_ci    opt.mfl_code            = DFL_MFL_CODE;
1737a8e1175bSopenharmony_ci    opt.trunc_hmac          = DFL_TRUNC_HMAC;
1738a8e1175bSopenharmony_ci    opt.tickets             = DFL_TICKETS;
1739a8e1175bSopenharmony_ci    opt.dummy_ticket        = DFL_DUMMY_TICKET;
1740a8e1175bSopenharmony_ci    opt.ticket_rotate       = DFL_TICKET_ROTATE;
1741a8e1175bSopenharmony_ci    opt.ticket_timeout      = DFL_TICKET_TIMEOUT;
1742a8e1175bSopenharmony_ci    opt.ticket_aead         = DFL_TICKET_AEAD;
1743a8e1175bSopenharmony_ci    opt.cache_max           = DFL_CACHE_MAX;
1744a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME)
1745a8e1175bSopenharmony_ci    opt.cache_timeout       = DFL_CACHE_TIMEOUT;
1746a8e1175bSopenharmony_ci#endif
1747a8e1175bSopenharmony_ci    opt.cache_remove        = DFL_CACHE_REMOVE;
1748a8e1175bSopenharmony_ci    opt.sni                 = DFL_SNI;
1749a8e1175bSopenharmony_ci    opt.alpn_string         = DFL_ALPN_STRING;
1750a8e1175bSopenharmony_ci    opt.groups              = DFL_GROUPS;
1751a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
1752a8e1175bSopenharmony_ci    opt.early_data          = DFL_EARLY_DATA;
1753a8e1175bSopenharmony_ci    opt.max_early_data_size = DFL_MAX_EARLY_DATA_SIZE;
1754a8e1175bSopenharmony_ci#endif
1755a8e1175bSopenharmony_ci    opt.sig_algs            = DFL_SIG_ALGS;
1756a8e1175bSopenharmony_ci    opt.dhm_file            = DFL_DHM_FILE;
1757a8e1175bSopenharmony_ci    opt.transport           = DFL_TRANSPORT;
1758a8e1175bSopenharmony_ci    opt.cookies             = DFL_COOKIES;
1759a8e1175bSopenharmony_ci    opt.anti_replay         = DFL_ANTI_REPLAY;
1760a8e1175bSopenharmony_ci    opt.hs_to_min           = DFL_HS_TO_MIN;
1761a8e1175bSopenharmony_ci    opt.hs_to_max           = DFL_HS_TO_MAX;
1762a8e1175bSopenharmony_ci    opt.dtls_mtu            = DFL_DTLS_MTU;
1763a8e1175bSopenharmony_ci    opt.dgram_packing       = DFL_DGRAM_PACKING;
1764a8e1175bSopenharmony_ci    opt.badmac_limit        = DFL_BADMAC_LIMIT;
1765a8e1175bSopenharmony_ci    opt.extended_ms         = DFL_EXTENDED_MS;
1766a8e1175bSopenharmony_ci    opt.etm                 = DFL_ETM;
1767a8e1175bSopenharmony_ci    opt.serialize           = DFL_SERIALIZE;
1768a8e1175bSopenharmony_ci    opt.context_file        = DFL_CONTEXT_FILE;
1769a8e1175bSopenharmony_ci    opt.eap_tls             = DFL_EAP_TLS;
1770a8e1175bSopenharmony_ci    opt.reproducible        = DFL_REPRODUCIBLE;
1771a8e1175bSopenharmony_ci    opt.nss_keylog          = DFL_NSS_KEYLOG;
1772a8e1175bSopenharmony_ci    opt.nss_keylog_file     = DFL_NSS_KEYLOG_FILE;
1773a8e1175bSopenharmony_ci    opt.query_config_mode   = DFL_QUERY_CONFIG_MODE;
1774a8e1175bSopenharmony_ci    opt.use_srtp            = DFL_USE_SRTP;
1775a8e1175bSopenharmony_ci    opt.force_srtp_profile  = DFL_SRTP_FORCE_PROFILE;
1776a8e1175bSopenharmony_ci    opt.support_mki         = DFL_SRTP_SUPPORT_MKI;
1777a8e1175bSopenharmony_ci    opt.key1_opaque_alg1   = DFL_KEY_OPAQUE_ALG;
1778a8e1175bSopenharmony_ci    opt.key1_opaque_alg2   = DFL_KEY_OPAQUE_ALG;
1779a8e1175bSopenharmony_ci    opt.key2_opaque_alg1   = DFL_KEY_OPAQUE_ALG;
1780a8e1175bSopenharmony_ci    opt.key2_opaque_alg2   = DFL_KEY_OPAQUE_ALG;
1781a8e1175bSopenharmony_ci
1782a8e1175bSopenharmony_ci    p = q = NULL;
1783a8e1175bSopenharmony_ci    if (argc < 1) {
1784a8e1175bSopenharmony_ciusage:
1785a8e1175bSopenharmony_ci        if (p != NULL && q != NULL) {
1786a8e1175bSopenharmony_ci            printf("unrecognized value for '%s': '%s'\n", p, q);
1787a8e1175bSopenharmony_ci        } else if (p != NULL && q == NULL) {
1788a8e1175bSopenharmony_ci            printf("unrecognized param: '%s'\n", p);
1789a8e1175bSopenharmony_ci        }
1790a8e1175bSopenharmony_ci
1791a8e1175bSopenharmony_ci        mbedtls_printf("usage: ssl_client2 [param=value] [...]\n");
1792a8e1175bSopenharmony_ci        mbedtls_printf("       ssl_client2 help[_theme]\n");
1793a8e1175bSopenharmony_ci        mbedtls_printf("'help' lists acceptable 'param' and 'value'\n");
1794a8e1175bSopenharmony_ci        mbedtls_printf("'help_ciphersuites' lists available ciphersuites\n");
1795a8e1175bSopenharmony_ci        mbedtls_printf("\n");
1796a8e1175bSopenharmony_ci
1797a8e1175bSopenharmony_ci        if (ret == 0) {
1798a8e1175bSopenharmony_ci            ret = 1;
1799a8e1175bSopenharmony_ci        }
1800a8e1175bSopenharmony_ci        goto exit;
1801a8e1175bSopenharmony_ci    }
1802a8e1175bSopenharmony_ci
1803a8e1175bSopenharmony_ci    for (i = 1; i < argc; i++) {
1804a8e1175bSopenharmony_ci        p = argv[i];
1805a8e1175bSopenharmony_ci
1806a8e1175bSopenharmony_ci        if (strcmp(p, "help") == 0) {
1807a8e1175bSopenharmony_ci            mbedtls_printf(USAGE1);
1808a8e1175bSopenharmony_ci            mbedtls_printf(USAGE2);
1809a8e1175bSopenharmony_ci            mbedtls_printf(USAGE3);
1810a8e1175bSopenharmony_ci            mbedtls_printf(USAGE4);
1811a8e1175bSopenharmony_ci
1812a8e1175bSopenharmony_ci            ret = 0;
1813a8e1175bSopenharmony_ci            goto exit;
1814a8e1175bSopenharmony_ci        }
1815a8e1175bSopenharmony_ci        if (strcmp(p, "help_ciphersuites") == 0) {
1816a8e1175bSopenharmony_ci            mbedtls_printf(" acceptable ciphersuite names:\n");
1817a8e1175bSopenharmony_ci            for (list = mbedtls_ssl_list_ciphersuites();
1818a8e1175bSopenharmony_ci                 *list != 0;
1819a8e1175bSopenharmony_ci                 list++) {
1820a8e1175bSopenharmony_ci                mbedtls_printf(" %s\n", mbedtls_ssl_get_ciphersuite_name(*list));
1821a8e1175bSopenharmony_ci            }
1822a8e1175bSopenharmony_ci
1823a8e1175bSopenharmony_ci            ret = 0;
1824a8e1175bSopenharmony_ci            goto exit;
1825a8e1175bSopenharmony_ci        }
1826a8e1175bSopenharmony_ci
1827a8e1175bSopenharmony_ci        if ((q = strchr(p, '=')) == NULL) {
1828a8e1175bSopenharmony_ci            mbedtls_printf("param requires a value: '%s'\n", p);
1829a8e1175bSopenharmony_ci            p = NULL; // avoid "unrecnognized param" message
1830a8e1175bSopenharmony_ci            goto usage;
1831a8e1175bSopenharmony_ci        }
1832a8e1175bSopenharmony_ci        *q++ = '\0';
1833a8e1175bSopenharmony_ci
1834a8e1175bSopenharmony_ci        if (strcmp(p, "server_port") == 0) {
1835a8e1175bSopenharmony_ci            opt.server_port = q;
1836a8e1175bSopenharmony_ci        } else if (strcmp(p, "server_addr") == 0) {
1837a8e1175bSopenharmony_ci            opt.server_addr = q;
1838a8e1175bSopenharmony_ci        } else if (strcmp(p, "dtls") == 0) {
1839a8e1175bSopenharmony_ci            int t = atoi(q);
1840a8e1175bSopenharmony_ci            if (t == 0) {
1841a8e1175bSopenharmony_ci                opt.transport = MBEDTLS_SSL_TRANSPORT_STREAM;
1842a8e1175bSopenharmony_ci            } else if (t == 1) {
1843a8e1175bSopenharmony_ci                opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
1844a8e1175bSopenharmony_ci            } else {
1845a8e1175bSopenharmony_ci                goto usage;
1846a8e1175bSopenharmony_ci            }
1847a8e1175bSopenharmony_ci        } else if (strcmp(p, "debug_level") == 0) {
1848a8e1175bSopenharmony_ci            opt.debug_level = atoi(q);
1849a8e1175bSopenharmony_ci            if (opt.debug_level < 0 || opt.debug_level > 65535) {
1850a8e1175bSopenharmony_ci                goto usage;
1851a8e1175bSopenharmony_ci            }
1852a8e1175bSopenharmony_ci        } else if (strcmp(p, "build_version") == 0) {
1853a8e1175bSopenharmony_ci            if (strcmp(q, "1") == 0) {
1854a8e1175bSopenharmony_ci                mbedtls_printf("build version: %s (build %d)\n",
1855a8e1175bSopenharmony_ci                               MBEDTLS_VERSION_STRING_FULL,
1856a8e1175bSopenharmony_ci                               MBEDTLS_VERSION_NUMBER);
1857a8e1175bSopenharmony_ci                goto exit;
1858a8e1175bSopenharmony_ci            }
1859a8e1175bSopenharmony_ci        } else if (strcmp(p, "nbio") == 0) {
1860a8e1175bSopenharmony_ci            opt.nbio = atoi(q);
1861a8e1175bSopenharmony_ci            if (opt.nbio < 0 || opt.nbio > 2) {
1862a8e1175bSopenharmony_ci                goto usage;
1863a8e1175bSopenharmony_ci            }
1864a8e1175bSopenharmony_ci        } else if (strcmp(p, "event") == 0) {
1865a8e1175bSopenharmony_ci            opt.event = atoi(q);
1866a8e1175bSopenharmony_ci            if (opt.event < 0 || opt.event > 2) {
1867a8e1175bSopenharmony_ci                goto usage;
1868a8e1175bSopenharmony_ci            }
1869a8e1175bSopenharmony_ci        } else if (strcmp(p, "read_timeout") == 0) {
1870a8e1175bSopenharmony_ci            opt.read_timeout = atoi(q);
1871a8e1175bSopenharmony_ci        } else if (strcmp(p, "buffer_size") == 0) {
1872a8e1175bSopenharmony_ci            opt.buffer_size = atoi(q);
1873a8e1175bSopenharmony_ci            if (opt.buffer_size < 1) {
1874a8e1175bSopenharmony_ci                goto usage;
1875a8e1175bSopenharmony_ci            }
1876a8e1175bSopenharmony_ci        } else if (strcmp(p, "response_size") == 0) {
1877a8e1175bSopenharmony_ci            opt.response_size = atoi(q);
1878a8e1175bSopenharmony_ci            if (opt.response_size < 0 || opt.response_size > MBEDTLS_SSL_OUT_CONTENT_LEN) {
1879a8e1175bSopenharmony_ci                goto usage;
1880a8e1175bSopenharmony_ci            }
1881a8e1175bSopenharmony_ci            if (opt.buffer_size < opt.response_size) {
1882a8e1175bSopenharmony_ci                opt.buffer_size = opt.response_size;
1883a8e1175bSopenharmony_ci            }
1884a8e1175bSopenharmony_ci        } else if (strcmp(p, "ca_file") == 0) {
1885a8e1175bSopenharmony_ci            opt.ca_file = q;
1886a8e1175bSopenharmony_ci        } else if (strcmp(p, "ca_path") == 0) {
1887a8e1175bSopenharmony_ci            opt.ca_path = q;
1888a8e1175bSopenharmony_ci        } else if (strcmp(p, "crt_file") == 0) {
1889a8e1175bSopenharmony_ci            opt.crt_file = q;
1890a8e1175bSopenharmony_ci        } else if (strcmp(p, "key_file") == 0) {
1891a8e1175bSopenharmony_ci            opt.key_file = q;
1892a8e1175bSopenharmony_ci        } else if (strcmp(p, "key_pwd") == 0) {
1893a8e1175bSopenharmony_ci            opt.key_pwd = q;
1894a8e1175bSopenharmony_ci        }
1895a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
1896a8e1175bSopenharmony_ci        else if (strcmp(p, "key_opaque") == 0) {
1897a8e1175bSopenharmony_ci            opt.key_opaque = atoi(q);
1898a8e1175bSopenharmony_ci        }
1899a8e1175bSopenharmony_ci#endif
1900a8e1175bSopenharmony_ci        else if (strcmp(p, "crt_file2") == 0) {
1901a8e1175bSopenharmony_ci            opt.crt_file2 = q;
1902a8e1175bSopenharmony_ci        } else if (strcmp(p, "key_file2") == 0) {
1903a8e1175bSopenharmony_ci            opt.key_file2 = q;
1904a8e1175bSopenharmony_ci        } else if (strcmp(p, "key_pwd2") == 0) {
1905a8e1175bSopenharmony_ci            opt.key_pwd2 = q;
1906a8e1175bSopenharmony_ci        } else if (strcmp(p, "dhm_file") == 0) {
1907a8e1175bSopenharmony_ci            opt.dhm_file = q;
1908a8e1175bSopenharmony_ci        }
1909a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
1910a8e1175bSopenharmony_ci        else if (strcmp(p, "async_operations") == 0) {
1911a8e1175bSopenharmony_ci            opt.async_operations = q;
1912a8e1175bSopenharmony_ci        } else if (strcmp(p, "async_private_delay1") == 0) {
1913a8e1175bSopenharmony_ci            opt.async_private_delay1 = atoi(q);
1914a8e1175bSopenharmony_ci        } else if (strcmp(p, "async_private_delay2") == 0) {
1915a8e1175bSopenharmony_ci            opt.async_private_delay2 = atoi(q);
1916a8e1175bSopenharmony_ci        } else if (strcmp(p, "async_private_error") == 0) {
1917a8e1175bSopenharmony_ci            int n = atoi(q);
1918a8e1175bSopenharmony_ci            if (n < -SSL_ASYNC_INJECT_ERROR_MAX ||
1919a8e1175bSopenharmony_ci                n > SSL_ASYNC_INJECT_ERROR_MAX) {
1920a8e1175bSopenharmony_ci                ret = 2;
1921a8e1175bSopenharmony_ci                goto usage;
1922a8e1175bSopenharmony_ci            }
1923a8e1175bSopenharmony_ci            opt.async_private_error = n;
1924a8e1175bSopenharmony_ci        }
1925a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
1926a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
1927a8e1175bSopenharmony_ci        else if (strcmp(p, "cid") == 0) {
1928a8e1175bSopenharmony_ci            opt.cid_enabled = atoi(q);
1929a8e1175bSopenharmony_ci            if (opt.cid_enabled != 0 && opt.cid_enabled != 1) {
1930a8e1175bSopenharmony_ci                goto usage;
1931a8e1175bSopenharmony_ci            }
1932a8e1175bSopenharmony_ci        } else if (strcmp(p, "cid_renego") == 0) {
1933a8e1175bSopenharmony_ci            opt.cid_enabled_renego = atoi(q);
1934a8e1175bSopenharmony_ci            if (opt.cid_enabled_renego != 0 && opt.cid_enabled_renego != 1) {
1935a8e1175bSopenharmony_ci                goto usage;
1936a8e1175bSopenharmony_ci            }
1937a8e1175bSopenharmony_ci        } else if (strcmp(p, "cid_val") == 0) {
1938a8e1175bSopenharmony_ci            opt.cid_val = q;
1939a8e1175bSopenharmony_ci        } else if (strcmp(p, "cid_val_renego") == 0) {
1940a8e1175bSopenharmony_ci            opt.cid_val_renego = q;
1941a8e1175bSopenharmony_ci        }
1942a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
1943a8e1175bSopenharmony_ci        else if (strcmp(p, "psk") == 0) {
1944a8e1175bSopenharmony_ci            opt.psk = q;
1945a8e1175bSopenharmony_ci        }
1946a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1947a8e1175bSopenharmony_ci        else if (strcmp(p, "psk_opaque") == 0) {
1948a8e1175bSopenharmony_ci            opt.psk_opaque = atoi(q);
1949a8e1175bSopenharmony_ci        } else if (strcmp(p, "psk_list_opaque") == 0) {
1950a8e1175bSopenharmony_ci            opt.psk_list_opaque = atoi(q);
1951a8e1175bSopenharmony_ci        }
1952a8e1175bSopenharmony_ci#endif
1953a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
1954a8e1175bSopenharmony_ci        else if (strcmp(p, "ca_callback") == 0) {
1955a8e1175bSopenharmony_ci            opt.ca_callback = atoi(q);
1956a8e1175bSopenharmony_ci        }
1957a8e1175bSopenharmony_ci#endif
1958a8e1175bSopenharmony_ci        else if (strcmp(p, "psk_identity") == 0) {
1959a8e1175bSopenharmony_ci            opt.psk_identity = q;
1960a8e1175bSopenharmony_ci        } else if (strcmp(p, "psk_list") == 0) {
1961a8e1175bSopenharmony_ci            opt.psk_list = q;
1962a8e1175bSopenharmony_ci        } else if (strcmp(p, "ecjpake_pw") == 0) {
1963a8e1175bSopenharmony_ci            opt.ecjpake_pw = q;
1964a8e1175bSopenharmony_ci        }
1965a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
1966a8e1175bSopenharmony_ci        else if (strcmp(p, "ecjpake_pw_opaque") == 0) {
1967a8e1175bSopenharmony_ci            opt.ecjpake_pw_opaque = atoi(q);
1968a8e1175bSopenharmony_ci        }
1969a8e1175bSopenharmony_ci#endif
1970a8e1175bSopenharmony_ci        else if (strcmp(p, "force_ciphersuite") == 0) {
1971a8e1175bSopenharmony_ci            opt.force_ciphersuite[0] = mbedtls_ssl_get_ciphersuite_id(q);
1972a8e1175bSopenharmony_ci
1973a8e1175bSopenharmony_ci            if (opt.force_ciphersuite[0] == 0) {
1974a8e1175bSopenharmony_ci                ret = 2;
1975a8e1175bSopenharmony_ci                goto usage;
1976a8e1175bSopenharmony_ci            }
1977a8e1175bSopenharmony_ci            opt.force_ciphersuite[1] = 0;
1978a8e1175bSopenharmony_ci        } else if (strcmp(p, "groups") == 0) {
1979a8e1175bSopenharmony_ci            opt.groups = q;
1980a8e1175bSopenharmony_ci        }
1981a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
1982a8e1175bSopenharmony_ci        else if (strcmp(p, "sig_algs") == 0) {
1983a8e1175bSopenharmony_ci            opt.sig_algs = q;
1984a8e1175bSopenharmony_ci        }
1985a8e1175bSopenharmony_ci#endif
1986a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
1987a8e1175bSopenharmony_ci        else if (strcmp(p, "early_data") == 0) {
1988a8e1175bSopenharmony_ci            switch (atoi(q)) {
1989a8e1175bSopenharmony_ci                case 0:
1990a8e1175bSopenharmony_ci                    opt.early_data = MBEDTLS_SSL_EARLY_DATA_DISABLED;
1991a8e1175bSopenharmony_ci                    break;
1992a8e1175bSopenharmony_ci                case 1:
1993a8e1175bSopenharmony_ci                    opt.early_data = MBEDTLS_SSL_EARLY_DATA_ENABLED;
1994a8e1175bSopenharmony_ci                    break;
1995a8e1175bSopenharmony_ci                default: goto usage;
1996a8e1175bSopenharmony_ci            }
1997a8e1175bSopenharmony_ci        } else if (strcmp(p, "max_early_data_size") == 0) {
1998a8e1175bSopenharmony_ci            opt.max_early_data_size = (uint32_t) atoll(q);
1999a8e1175bSopenharmony_ci        }
2000a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
2001a8e1175bSopenharmony_ci        else if (strcmp(p, "renegotiation") == 0) {
2002a8e1175bSopenharmony_ci            opt.renegotiation = (atoi(q)) ?
2003a8e1175bSopenharmony_ci                                MBEDTLS_SSL_RENEGOTIATION_ENABLED :
2004a8e1175bSopenharmony_ci                                MBEDTLS_SSL_RENEGOTIATION_DISABLED;
2005a8e1175bSopenharmony_ci        } else if (strcmp(p, "allow_legacy") == 0) {
2006a8e1175bSopenharmony_ci            switch (atoi(q)) {
2007a8e1175bSopenharmony_ci                case -1:
2008a8e1175bSopenharmony_ci                    opt.allow_legacy = MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE;
2009a8e1175bSopenharmony_ci                    break;
2010a8e1175bSopenharmony_ci                case 0:
2011a8e1175bSopenharmony_ci                    opt.allow_legacy = MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION;
2012a8e1175bSopenharmony_ci                    break;
2013a8e1175bSopenharmony_ci                case 1:
2014a8e1175bSopenharmony_ci                    opt.allow_legacy = MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION;
2015a8e1175bSopenharmony_ci                    break;
2016a8e1175bSopenharmony_ci                default: goto usage;
2017a8e1175bSopenharmony_ci            }
2018a8e1175bSopenharmony_ci        } else if (strcmp(p, "renegotiate") == 0) {
2019a8e1175bSopenharmony_ci            opt.renegotiate = atoi(q);
2020a8e1175bSopenharmony_ci            if (opt.renegotiate < 0 || opt.renegotiate > 1) {
2021a8e1175bSopenharmony_ci                goto usage;
2022a8e1175bSopenharmony_ci            }
2023a8e1175bSopenharmony_ci        } else if (strcmp(p, "renego_delay") == 0) {
2024a8e1175bSopenharmony_ci            opt.renego_delay = atoi(q);
2025a8e1175bSopenharmony_ci        } else if (strcmp(p, "renego_period") == 0) {
2026a8e1175bSopenharmony_ci#if defined(_MSC_VER)
2027a8e1175bSopenharmony_ci            opt.renego_period = _strtoui64(q, NULL, 10);
2028a8e1175bSopenharmony_ci#else
2029a8e1175bSopenharmony_ci            if (sscanf(q, "%" SCNu64, &opt.renego_period) != 1) {
2030a8e1175bSopenharmony_ci                goto usage;
2031a8e1175bSopenharmony_ci            }
2032a8e1175bSopenharmony_ci#endif /* _MSC_VER */
2033a8e1175bSopenharmony_ci            if (opt.renego_period < 2) {
2034a8e1175bSopenharmony_ci                goto usage;
2035a8e1175bSopenharmony_ci            }
2036a8e1175bSopenharmony_ci        } else if (strcmp(p, "exchanges") == 0) {
2037a8e1175bSopenharmony_ci            opt.exchanges = atoi(q);
2038a8e1175bSopenharmony_ci            if (opt.exchanges < 0) {
2039a8e1175bSopenharmony_ci                goto usage;
2040a8e1175bSopenharmony_ci            }
2041a8e1175bSopenharmony_ci        }
2042a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2043a8e1175bSopenharmony_ci        else if (strcmp(p, "tls13_kex_modes") == 0) {
2044a8e1175bSopenharmony_ci            if (strcmp(q, "psk") == 0) {
2045a8e1175bSopenharmony_ci                opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
2046a8e1175bSopenharmony_ci            } else if (strcmp(q, "psk_ephemeral") == 0) {
2047a8e1175bSopenharmony_ci                opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
2048a8e1175bSopenharmony_ci            } else if (strcmp(q, "ephemeral") == 0) {
2049a8e1175bSopenharmony_ci                opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
2050a8e1175bSopenharmony_ci            } else if (strcmp(q, "ephemeral_all") == 0) {
2051a8e1175bSopenharmony_ci                opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ALL;
2052a8e1175bSopenharmony_ci            } else if (strcmp(q, "psk_all") == 0) {
2053a8e1175bSopenharmony_ci                opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
2054a8e1175bSopenharmony_ci            } else if (strcmp(q, "all") == 0) {
2055a8e1175bSopenharmony_ci                opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL;
2056a8e1175bSopenharmony_ci            }
2057a8e1175bSopenharmony_ci            /* The purpose of `psk_or_ephemeral` is to improve test coverage. That
2058a8e1175bSopenharmony_ci             * is not recommended in practice.
2059a8e1175bSopenharmony_ci             * `psk_or_ephemeral` exists in theory, we need this mode to test if
2060a8e1175bSopenharmony_ci             * this setting work correctly. With this key exchange setting, server
2061a8e1175bSopenharmony_ci             * should always perform `ephemeral` handshake. `psk` or `psk_ephemeral`
2062a8e1175bSopenharmony_ci             * is not expected.
2063a8e1175bSopenharmony_ci             */
2064a8e1175bSopenharmony_ci            else if (strcmp(q, "psk_or_ephemeral") == 0) {
2065a8e1175bSopenharmony_ci                opt.tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK |
2066a8e1175bSopenharmony_ci                                      MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
2067a8e1175bSopenharmony_ci            } else {
2068a8e1175bSopenharmony_ci                goto usage;
2069a8e1175bSopenharmony_ci            }
2070a8e1175bSopenharmony_ci        }
2071a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
2072a8e1175bSopenharmony_ci
2073a8e1175bSopenharmony_ci        else if (strcmp(p, "min_version") == 0) {
2074a8e1175bSopenharmony_ci            if (strcmp(q, "tls12") == 0 ||
2075a8e1175bSopenharmony_ci                strcmp(q, "dtls12") == 0) {
2076a8e1175bSopenharmony_ci                opt.min_version = MBEDTLS_SSL_VERSION_TLS1_2;
2077a8e1175bSopenharmony_ci            }
2078a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2079a8e1175bSopenharmony_ci            else if (strcmp(q, "tls13") == 0) {
2080a8e1175bSopenharmony_ci                opt.min_version = MBEDTLS_SSL_VERSION_TLS1_3;
2081a8e1175bSopenharmony_ci            }
2082a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
2083a8e1175bSopenharmony_ci            else {
2084a8e1175bSopenharmony_ci                goto usage;
2085a8e1175bSopenharmony_ci            }
2086a8e1175bSopenharmony_ci        } else if (strcmp(p, "max_version") == 0) {
2087a8e1175bSopenharmony_ci            if (strcmp(q, "tls12") == 0 ||
2088a8e1175bSopenharmony_ci                strcmp(q, "dtls12") == 0) {
2089a8e1175bSopenharmony_ci                opt.max_version = MBEDTLS_SSL_VERSION_TLS1_2;
2090a8e1175bSopenharmony_ci            }
2091a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2092a8e1175bSopenharmony_ci            else if (strcmp(q, "tls13") == 0) {
2093a8e1175bSopenharmony_ci                opt.max_version = MBEDTLS_SSL_VERSION_TLS1_3;
2094a8e1175bSopenharmony_ci            }
2095a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
2096a8e1175bSopenharmony_ci            else {
2097a8e1175bSopenharmony_ci                goto usage;
2098a8e1175bSopenharmony_ci            }
2099a8e1175bSopenharmony_ci        } else if (strcmp(p, "allow_sha1") == 0) {
2100a8e1175bSopenharmony_ci            switch (atoi(q)) {
2101a8e1175bSopenharmony_ci                case 0:     opt.allow_sha1 = 0;   break;
2102a8e1175bSopenharmony_ci                case 1:     opt.allow_sha1 = 1;    break;
2103a8e1175bSopenharmony_ci                default:    goto usage;
2104a8e1175bSopenharmony_ci            }
2105a8e1175bSopenharmony_ci        } else if (strcmp(p, "force_version") == 0) {
2106a8e1175bSopenharmony_ci            if (strcmp(q, "tls12") == 0) {
2107a8e1175bSopenharmony_ci                opt.min_version = MBEDTLS_SSL_VERSION_TLS1_2;
2108a8e1175bSopenharmony_ci                opt.max_version = MBEDTLS_SSL_VERSION_TLS1_2;
2109a8e1175bSopenharmony_ci            } else if (strcmp(q, "dtls12") == 0) {
2110a8e1175bSopenharmony_ci                opt.min_version = MBEDTLS_SSL_VERSION_TLS1_2;
2111a8e1175bSopenharmony_ci                opt.max_version = MBEDTLS_SSL_VERSION_TLS1_2;
2112a8e1175bSopenharmony_ci                opt.transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
2113a8e1175bSopenharmony_ci            }
2114a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2115a8e1175bSopenharmony_ci            else if (strcmp(q, "tls13") == 0) {
2116a8e1175bSopenharmony_ci                opt.min_version = MBEDTLS_SSL_VERSION_TLS1_3;
2117a8e1175bSopenharmony_ci                opt.max_version = MBEDTLS_SSL_VERSION_TLS1_3;
2118a8e1175bSopenharmony_ci            }
2119a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
2120a8e1175bSopenharmony_ci            else {
2121a8e1175bSopenharmony_ci                goto usage;
2122a8e1175bSopenharmony_ci            }
2123a8e1175bSopenharmony_ci        } else if (strcmp(p, "auth_mode") == 0) {
2124a8e1175bSopenharmony_ci            if ((opt.auth_mode = get_auth_mode(q)) < 0) {
2125a8e1175bSopenharmony_ci                goto usage;
2126a8e1175bSopenharmony_ci            }
2127a8e1175bSopenharmony_ci        } else if (strcmp(p, "cert_req_ca_list") == 0) {
2128a8e1175bSopenharmony_ci            opt.cert_req_ca_list = atoi(q);
2129a8e1175bSopenharmony_ci            if (opt.cert_req_ca_list < 0 || opt.cert_req_ca_list > 3) {
2130a8e1175bSopenharmony_ci                goto usage;
2131a8e1175bSopenharmony_ci            }
2132a8e1175bSopenharmony_ci            if (opt.cert_req_ca_list > 1) {
2133a8e1175bSopenharmony_ci                opt.cert_req_dn_hint = opt.cert_req_ca_list;
2134a8e1175bSopenharmony_ci                opt.cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED;
2135a8e1175bSopenharmony_ci            }
2136a8e1175bSopenharmony_ci        } else if (strcmp(p, "max_frag_len") == 0) {
2137a8e1175bSopenharmony_ci            if (strcmp(q, "512") == 0) {
2138a8e1175bSopenharmony_ci                opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_512;
2139a8e1175bSopenharmony_ci            } else if (strcmp(q, "1024") == 0) {
2140a8e1175bSopenharmony_ci                opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_1024;
2141a8e1175bSopenharmony_ci            } else if (strcmp(q, "2048") == 0) {
2142a8e1175bSopenharmony_ci                opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_2048;
2143a8e1175bSopenharmony_ci            } else if (strcmp(q, "4096") == 0) {
2144a8e1175bSopenharmony_ci                opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_4096;
2145a8e1175bSopenharmony_ci            } else {
2146a8e1175bSopenharmony_ci                goto usage;
2147a8e1175bSopenharmony_ci            }
2148a8e1175bSopenharmony_ci        } else if (strcmp(p, "alpn") == 0) {
2149a8e1175bSopenharmony_ci            opt.alpn_string = q;
2150a8e1175bSopenharmony_ci        } else if (strcmp(p, "trunc_hmac") == 0) {
2151a8e1175bSopenharmony_ci            switch (atoi(q)) {
2152a8e1175bSopenharmony_ci                case 0: opt.trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_DISABLED; break;
2153a8e1175bSopenharmony_ci                case 1: opt.trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; break;
2154a8e1175bSopenharmony_ci                default: goto usage;
2155a8e1175bSopenharmony_ci            }
2156a8e1175bSopenharmony_ci        } else if (strcmp(p, "extended_ms") == 0) {
2157a8e1175bSopenharmony_ci            switch (atoi(q)) {
2158a8e1175bSopenharmony_ci                case 0:
2159a8e1175bSopenharmony_ci                    opt.extended_ms = MBEDTLS_SSL_EXTENDED_MS_DISABLED;
2160a8e1175bSopenharmony_ci                    break;
2161a8e1175bSopenharmony_ci                case 1:
2162a8e1175bSopenharmony_ci                    opt.extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
2163a8e1175bSopenharmony_ci                    break;
2164a8e1175bSopenharmony_ci                default: goto usage;
2165a8e1175bSopenharmony_ci            }
2166a8e1175bSopenharmony_ci        } else if (strcmp(p, "etm") == 0) {
2167a8e1175bSopenharmony_ci            switch (atoi(q)) {
2168a8e1175bSopenharmony_ci                case 0: opt.etm = MBEDTLS_SSL_ETM_DISABLED; break;
2169a8e1175bSopenharmony_ci                case 1: opt.etm = MBEDTLS_SSL_ETM_ENABLED; break;
2170a8e1175bSopenharmony_ci                default: goto usage;
2171a8e1175bSopenharmony_ci            }
2172a8e1175bSopenharmony_ci        } else if (strcmp(p, "tickets") == 0) {
2173a8e1175bSopenharmony_ci            opt.tickets = atoi(q);
2174a8e1175bSopenharmony_ci            if (opt.tickets < 0) {
2175a8e1175bSopenharmony_ci                goto usage;
2176a8e1175bSopenharmony_ci            }
2177a8e1175bSopenharmony_ci        } else if (strcmp(p, "dummy_ticket") == 0) {
2178a8e1175bSopenharmony_ci            opt.dummy_ticket = atoi(q);
2179a8e1175bSopenharmony_ci            if (opt.dummy_ticket < 0) {
2180a8e1175bSopenharmony_ci                goto usage;
2181a8e1175bSopenharmony_ci            }
2182a8e1175bSopenharmony_ci        } else if (strcmp(p, "ticket_rotate") == 0) {
2183a8e1175bSopenharmony_ci            opt.ticket_rotate = atoi(q);
2184a8e1175bSopenharmony_ci            if (opt.ticket_rotate < 0 || opt.ticket_rotate > 1) {
2185a8e1175bSopenharmony_ci                goto usage;
2186a8e1175bSopenharmony_ci            }
2187a8e1175bSopenharmony_ci        } else if (strcmp(p, "ticket_timeout") == 0) {
2188a8e1175bSopenharmony_ci            opt.ticket_timeout = atoi(q);
2189a8e1175bSopenharmony_ci            if (opt.ticket_timeout < 0) {
2190a8e1175bSopenharmony_ci                goto usage;
2191a8e1175bSopenharmony_ci            }
2192a8e1175bSopenharmony_ci        } else if (strcmp(p, "ticket_aead") == 0) {
2193a8e1175bSopenharmony_ci            opt.ticket_aead = parse_cipher(q);
2194a8e1175bSopenharmony_ci
2195a8e1175bSopenharmony_ci            if (opt.ticket_aead == MBEDTLS_CIPHER_NONE) {
2196a8e1175bSopenharmony_ci                goto usage;
2197a8e1175bSopenharmony_ci            }
2198a8e1175bSopenharmony_ci        } else if (strcmp(p, "cache_max") == 0) {
2199a8e1175bSopenharmony_ci            opt.cache_max = atoi(q);
2200a8e1175bSopenharmony_ci            if (opt.cache_max < 0) {
2201a8e1175bSopenharmony_ci                goto usage;
2202a8e1175bSopenharmony_ci            }
2203a8e1175bSopenharmony_ci        }
2204a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME)
2205a8e1175bSopenharmony_ci        else if (strcmp(p, "cache_timeout") == 0) {
2206a8e1175bSopenharmony_ci            opt.cache_timeout = atoi(q);
2207a8e1175bSopenharmony_ci            if (opt.cache_timeout < 0) {
2208a8e1175bSopenharmony_ci                goto usage;
2209a8e1175bSopenharmony_ci            }
2210a8e1175bSopenharmony_ci        }
2211a8e1175bSopenharmony_ci#endif
2212a8e1175bSopenharmony_ci        else if (strcmp(p, "cache_remove") == 0) {
2213a8e1175bSopenharmony_ci            opt.cache_remove = atoi(q);
2214a8e1175bSopenharmony_ci            if (opt.cache_remove < 0 || opt.cache_remove > 1) {
2215a8e1175bSopenharmony_ci                goto usage;
2216a8e1175bSopenharmony_ci            }
2217a8e1175bSopenharmony_ci        } else if (strcmp(p, "cookies") == 0) {
2218a8e1175bSopenharmony_ci            opt.cookies = atoi(q);
2219a8e1175bSopenharmony_ci            if (opt.cookies < -1 || opt.cookies > 1) {
2220a8e1175bSopenharmony_ci                goto usage;
2221a8e1175bSopenharmony_ci            }
2222a8e1175bSopenharmony_ci        } else if (strcmp(p, "anti_replay") == 0) {
2223a8e1175bSopenharmony_ci            opt.anti_replay = atoi(q);
2224a8e1175bSopenharmony_ci            if (opt.anti_replay < 0 || opt.anti_replay > 1) {
2225a8e1175bSopenharmony_ci                goto usage;
2226a8e1175bSopenharmony_ci            }
2227a8e1175bSopenharmony_ci        } else if (strcmp(p, "badmac_limit") == 0) {
2228a8e1175bSopenharmony_ci            opt.badmac_limit = atoi(q);
2229a8e1175bSopenharmony_ci            if (opt.badmac_limit < 0) {
2230a8e1175bSopenharmony_ci                goto usage;
2231a8e1175bSopenharmony_ci            }
2232a8e1175bSopenharmony_ci        } else if (strcmp(p, "hs_timeout") == 0) {
2233a8e1175bSopenharmony_ci            if ((p = strchr(q, '-')) == NULL) {
2234a8e1175bSopenharmony_ci                goto usage;
2235a8e1175bSopenharmony_ci            }
2236a8e1175bSopenharmony_ci            *p++ = '\0';
2237a8e1175bSopenharmony_ci            opt.hs_to_min = atoi(q);
2238a8e1175bSopenharmony_ci            opt.hs_to_max = atoi(p);
2239a8e1175bSopenharmony_ci            if (opt.hs_to_min == 0 || opt.hs_to_max < opt.hs_to_min) {
2240a8e1175bSopenharmony_ci                goto usage;
2241a8e1175bSopenharmony_ci            }
2242a8e1175bSopenharmony_ci        } else if (strcmp(p, "mtu") == 0) {
2243a8e1175bSopenharmony_ci            opt.dtls_mtu = atoi(q);
2244a8e1175bSopenharmony_ci            if (opt.dtls_mtu < 0) {
2245a8e1175bSopenharmony_ci                goto usage;
2246a8e1175bSopenharmony_ci            }
2247a8e1175bSopenharmony_ci        } else if (strcmp(p, "dgram_packing") == 0) {
2248a8e1175bSopenharmony_ci            opt.dgram_packing = atoi(q);
2249a8e1175bSopenharmony_ci            if (opt.dgram_packing != 0 &&
2250a8e1175bSopenharmony_ci                opt.dgram_packing != 1) {
2251a8e1175bSopenharmony_ci                goto usage;
2252a8e1175bSopenharmony_ci            }
2253a8e1175bSopenharmony_ci        } else if (strcmp(p, "sni") == 0) {
2254a8e1175bSopenharmony_ci            opt.sni = q;
2255a8e1175bSopenharmony_ci        } else if (strcmp(p, "query_config") == 0) {
2256a8e1175bSopenharmony_ci            opt.query_config_mode = 1;
2257a8e1175bSopenharmony_ci            query_config_ret = query_config(q);
2258a8e1175bSopenharmony_ci            goto exit;
2259a8e1175bSopenharmony_ci        } else if (strcmp(p, "serialize") == 0) {
2260a8e1175bSopenharmony_ci            opt.serialize = atoi(q);
2261a8e1175bSopenharmony_ci            if (opt.serialize < 0 || opt.serialize > 2) {
2262a8e1175bSopenharmony_ci                goto usage;
2263a8e1175bSopenharmony_ci            }
2264a8e1175bSopenharmony_ci        } else if (strcmp(p, "context_file") == 0) {
2265a8e1175bSopenharmony_ci            opt.context_file = q;
2266a8e1175bSopenharmony_ci        } else if (strcmp(p, "eap_tls") == 0) {
2267a8e1175bSopenharmony_ci            opt.eap_tls = atoi(q);
2268a8e1175bSopenharmony_ci            if (opt.eap_tls < 0 || opt.eap_tls > 1) {
2269a8e1175bSopenharmony_ci                goto usage;
2270a8e1175bSopenharmony_ci            }
2271a8e1175bSopenharmony_ci        } else if (strcmp(p, "reproducible") == 0) {
2272a8e1175bSopenharmony_ci            opt.reproducible = 1;
2273a8e1175bSopenharmony_ci        } else if (strcmp(p, "nss_keylog") == 0) {
2274a8e1175bSopenharmony_ci            opt.nss_keylog = atoi(q);
2275a8e1175bSopenharmony_ci            if (opt.nss_keylog < 0 || opt.nss_keylog > 1) {
2276a8e1175bSopenharmony_ci                goto usage;
2277a8e1175bSopenharmony_ci            }
2278a8e1175bSopenharmony_ci        } else if (strcmp(p, "nss_keylog_file") == 0) {
2279a8e1175bSopenharmony_ci            opt.nss_keylog_file = q;
2280a8e1175bSopenharmony_ci        } else if (strcmp(p, "use_srtp") == 0) {
2281a8e1175bSopenharmony_ci            opt.use_srtp = atoi(q);
2282a8e1175bSopenharmony_ci        } else if (strcmp(p, "srtp_force_profile") == 0) {
2283a8e1175bSopenharmony_ci            opt.force_srtp_profile = atoi(q);
2284a8e1175bSopenharmony_ci        } else if (strcmp(p, "support_mki") == 0) {
2285a8e1175bSopenharmony_ci            opt.support_mki = atoi(q);
2286a8e1175bSopenharmony_ci        } else if (strcmp(p, "key_opaque_algs") == 0) {
2287a8e1175bSopenharmony_ci            if (key_opaque_alg_parse(q, &opt.key1_opaque_alg1,
2288a8e1175bSopenharmony_ci                                     &opt.key1_opaque_alg2) != 0) {
2289a8e1175bSopenharmony_ci                goto usage;
2290a8e1175bSopenharmony_ci            }
2291a8e1175bSopenharmony_ci        } else if (strcmp(p, "key_opaque_algs2") == 0) {
2292a8e1175bSopenharmony_ci            if (key_opaque_alg_parse(q, &opt.key2_opaque_alg1,
2293a8e1175bSopenharmony_ci                                     &opt.key2_opaque_alg2) != 0) {
2294a8e1175bSopenharmony_ci                goto usage;
2295a8e1175bSopenharmony_ci            }
2296a8e1175bSopenharmony_ci        } else {
2297a8e1175bSopenharmony_ci            /* This signals that the problem is with p not q */
2298a8e1175bSopenharmony_ci            q = NULL;
2299a8e1175bSopenharmony_ci            goto usage;
2300a8e1175bSopenharmony_ci        }
2301a8e1175bSopenharmony_ci    }
2302a8e1175bSopenharmony_ci    /* This signals that any further erorrs are not with a single option */
2303a8e1175bSopenharmony_ci    p = q = NULL;
2304a8e1175bSopenharmony_ci
2305a8e1175bSopenharmony_ci    if (opt.nss_keylog != 0 && opt.eap_tls != 0) {
2306a8e1175bSopenharmony_ci        mbedtls_printf("Error: eap_tls and nss_keylog options cannot be used together.\n");
2307a8e1175bSopenharmony_ci        goto usage;
2308a8e1175bSopenharmony_ci    }
2309a8e1175bSopenharmony_ci
2310a8e1175bSopenharmony_ci    /* Event-driven IO is incompatible with the above custom
2311a8e1175bSopenharmony_ci     * receive and send functions, as the polling builds on
2312a8e1175bSopenharmony_ci     * refers to the underlying net_context. */
2313a8e1175bSopenharmony_ci    if (opt.event == 1 && opt.nbio != 1) {
2314a8e1175bSopenharmony_ci        mbedtls_printf("Warning: event-driven IO mandates nbio=1 - overwrite\n");
2315a8e1175bSopenharmony_ci        opt.nbio = 1;
2316a8e1175bSopenharmony_ci    }
2317a8e1175bSopenharmony_ci
2318a8e1175bSopenharmony_ci#if defined(MBEDTLS_DEBUG_C)
2319a8e1175bSopenharmony_ci    mbedtls_debug_set_threshold(opt.debug_level);
2320a8e1175bSopenharmony_ci#endif
2321a8e1175bSopenharmony_ci
2322a8e1175bSopenharmony_ci    /* buf will alternatively contain the input read from the client and the
2323a8e1175bSopenharmony_ci     * response that's about to be sent, plus a null byte in each case. */
2324a8e1175bSopenharmony_ci    size_t buf_content_size = opt.buffer_size;
2325a8e1175bSopenharmony_ci    /* The default response contains the ciphersuite name. Leave enough
2326a8e1175bSopenharmony_ci     * room for that plus some margin. */
2327a8e1175bSopenharmony_ci    if (buf_content_size < strlen(HTTP_RESPONSE) + 80) {
2328a8e1175bSopenharmony_ci        buf_content_size = strlen(HTTP_RESPONSE) + 80;
2329a8e1175bSopenharmony_ci    }
2330a8e1175bSopenharmony_ci    if (opt.response_size != DFL_RESPONSE_SIZE &&
2331a8e1175bSopenharmony_ci        buf_content_size < (size_t) opt.response_size) {
2332a8e1175bSopenharmony_ci        buf_content_size = opt.response_size;
2333a8e1175bSopenharmony_ci    }
2334a8e1175bSopenharmony_ci    buf = mbedtls_calloc(1, buf_content_size + 1);
2335a8e1175bSopenharmony_ci    if (buf == NULL) {
2336a8e1175bSopenharmony_ci        mbedtls_printf("Could not allocate %lu bytes\n",
2337a8e1175bSopenharmony_ci                       (unsigned long) buf_content_size + 1);
2338a8e1175bSopenharmony_ci        ret = 3;
2339a8e1175bSopenharmony_ci        goto exit;
2340a8e1175bSopenharmony_ci    }
2341a8e1175bSopenharmony_ci
2342a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
2343a8e1175bSopenharmony_ci    if (opt.psk_opaque != 0) {
2344a8e1175bSopenharmony_ci        if (strlen(opt.psk) == 0) {
2345a8e1175bSopenharmony_ci            mbedtls_printf("psk_opaque set but no psk to be imported specified.\n");
2346a8e1175bSopenharmony_ci            ret = 2;
2347a8e1175bSopenharmony_ci            goto usage;
2348a8e1175bSopenharmony_ci        }
2349a8e1175bSopenharmony_ci
2350a8e1175bSopenharmony_ci        if (opt.force_ciphersuite[0] <= 0) {
2351a8e1175bSopenharmony_ci            mbedtls_printf(
2352a8e1175bSopenharmony_ci                "opaque PSKs are only supported in conjunction with forcing TLS 1.2 and a PSK-only ciphersuite through the 'force_ciphersuite' option.\n");
2353a8e1175bSopenharmony_ci            ret = 2;
2354a8e1175bSopenharmony_ci            goto usage;
2355a8e1175bSopenharmony_ci        }
2356a8e1175bSopenharmony_ci    }
2357a8e1175bSopenharmony_ci
2358a8e1175bSopenharmony_ci    if (opt.psk_list_opaque != 0) {
2359a8e1175bSopenharmony_ci        if (opt.psk_list == NULL) {
2360a8e1175bSopenharmony_ci            mbedtls_printf("psk_slot set but no psk to be imported specified.\n");
2361a8e1175bSopenharmony_ci            ret = 2;
2362a8e1175bSopenharmony_ci            goto usage;
2363a8e1175bSopenharmony_ci        }
2364a8e1175bSopenharmony_ci
2365a8e1175bSopenharmony_ci        if (opt.force_ciphersuite[0] <= 0) {
2366a8e1175bSopenharmony_ci            mbedtls_printf(
2367a8e1175bSopenharmony_ci                "opaque PSKs are only supported in conjunction with forcing TLS 1.2 and a PSK-only ciphersuite through the 'force_ciphersuite' option.\n");
2368a8e1175bSopenharmony_ci            ret = 2;
2369a8e1175bSopenharmony_ci            goto usage;
2370a8e1175bSopenharmony_ci        }
2371a8e1175bSopenharmony_ci    }
2372a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
2373a8e1175bSopenharmony_ci
2374a8e1175bSopenharmony_ci    if (opt.force_ciphersuite[0] > 0) {
2375a8e1175bSopenharmony_ci        const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
2376a8e1175bSopenharmony_ci        ciphersuite_info =
2377a8e1175bSopenharmony_ci            mbedtls_ssl_ciphersuite_from_id(opt.force_ciphersuite[0]);
2378a8e1175bSopenharmony_ci
2379a8e1175bSopenharmony_ci        if (opt.max_version != -1 &&
2380a8e1175bSopenharmony_ci            ciphersuite_info->min_tls_version > opt.max_version) {
2381a8e1175bSopenharmony_ci            mbedtls_printf("forced ciphersuite not allowed with this protocol version\n");
2382a8e1175bSopenharmony_ci            ret = 2;
2383a8e1175bSopenharmony_ci            goto usage;
2384a8e1175bSopenharmony_ci        }
2385a8e1175bSopenharmony_ci        if (opt.min_version != -1 &&
2386a8e1175bSopenharmony_ci            ciphersuite_info->max_tls_version < opt.min_version) {
2387a8e1175bSopenharmony_ci            mbedtls_printf("forced ciphersuite not allowed with this protocol version\n");
2388a8e1175bSopenharmony_ci            ret = 2;
2389a8e1175bSopenharmony_ci            goto usage;
2390a8e1175bSopenharmony_ci        }
2391a8e1175bSopenharmony_ci
2392a8e1175bSopenharmony_ci        /* If we select a version that's not supported by
2393a8e1175bSopenharmony_ci         * this suite, then there will be no common ciphersuite... */
2394a8e1175bSopenharmony_ci        if (opt.max_version == -1 ||
2395a8e1175bSopenharmony_ci            opt.max_version > ciphersuite_info->max_tls_version) {
2396a8e1175bSopenharmony_ci            opt.max_version = ciphersuite_info->max_tls_version;
2397a8e1175bSopenharmony_ci        }
2398a8e1175bSopenharmony_ci        if (opt.min_version < ciphersuite_info->min_tls_version) {
2399a8e1175bSopenharmony_ci            opt.min_version = ciphersuite_info->min_tls_version;
2400a8e1175bSopenharmony_ci        }
2401a8e1175bSopenharmony_ci
2402a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
2403a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
2404a8e1175bSopenharmony_ci        if (opt.psk_opaque != 0 || opt.psk_list_opaque != 0) {
2405a8e1175bSopenharmony_ci            /* Determine KDF algorithm the opaque PSK will be used in. */
2406a8e1175bSopenharmony_ci#if defined(MBEDTLS_MD_CAN_SHA384)
2407a8e1175bSopenharmony_ci            if (ciphersuite_info->mac == MBEDTLS_MD_SHA384) {
2408a8e1175bSopenharmony_ci                alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
2409a8e1175bSopenharmony_ci            } else
2410a8e1175bSopenharmony_ci#endif /* MBEDTLS_MD_CAN_SHA384 */
2411a8e1175bSopenharmony_ci            alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
2412a8e1175bSopenharmony_ci        }
2413a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
2414a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
2415a8e1175bSopenharmony_ci    }
2416a8e1175bSopenharmony_ci
2417a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2418a8e1175bSopenharmony_ci    if (mbedtls_test_unhexify(cid, sizeof(cid),
2419a8e1175bSopenharmony_ci                              opt.cid_val, &cid_len) != 0) {
2420a8e1175bSopenharmony_ci        mbedtls_printf("CID not valid hex\n");
2421a8e1175bSopenharmony_ci        goto exit;
2422a8e1175bSopenharmony_ci    }
2423a8e1175bSopenharmony_ci
2424a8e1175bSopenharmony_ci    /* Keep CID settings for renegotiation unless
2425a8e1175bSopenharmony_ci     * specified otherwise. */
2426a8e1175bSopenharmony_ci    if (opt.cid_enabled_renego == DFL_CID_ENABLED_RENEGO) {
2427a8e1175bSopenharmony_ci        opt.cid_enabled_renego = opt.cid_enabled;
2428a8e1175bSopenharmony_ci    }
2429a8e1175bSopenharmony_ci    if (opt.cid_val_renego == DFL_CID_VALUE_RENEGO) {
2430a8e1175bSopenharmony_ci        opt.cid_val_renego = opt.cid_val;
2431a8e1175bSopenharmony_ci    }
2432a8e1175bSopenharmony_ci
2433a8e1175bSopenharmony_ci    if (mbedtls_test_unhexify(cid_renego, sizeof(cid_renego),
2434a8e1175bSopenharmony_ci                              opt.cid_val_renego, &cid_renego_len) != 0) {
2435a8e1175bSopenharmony_ci        mbedtls_printf("CID not valid hex\n");
2436a8e1175bSopenharmony_ci        goto exit;
2437a8e1175bSopenharmony_ci    }
2438a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2439a8e1175bSopenharmony_ci
2440a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
2441a8e1175bSopenharmony_ci    /*
2442a8e1175bSopenharmony_ci     * Unhexify the pre-shared key and parse the list if any given
2443a8e1175bSopenharmony_ci     */
2444a8e1175bSopenharmony_ci    if (mbedtls_test_unhexify(psk, sizeof(psk),
2445a8e1175bSopenharmony_ci                              opt.psk, &psk_len) != 0) {
2446a8e1175bSopenharmony_ci        mbedtls_printf("pre-shared key not valid hex\n");
2447a8e1175bSopenharmony_ci        goto exit;
2448a8e1175bSopenharmony_ci    }
2449a8e1175bSopenharmony_ci
2450a8e1175bSopenharmony_ci    if (opt.psk_list != NULL) {
2451a8e1175bSopenharmony_ci        if ((psk_info = psk_parse(opt.psk_list)) == NULL) {
2452a8e1175bSopenharmony_ci            mbedtls_printf("psk_list invalid");
2453a8e1175bSopenharmony_ci            goto exit;
2454a8e1175bSopenharmony_ci        }
2455a8e1175bSopenharmony_ci    }
2456a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED */
2457a8e1175bSopenharmony_ci
2458a8e1175bSopenharmony_ci    if (opt.groups != NULL) {
2459a8e1175bSopenharmony_ci        if (parse_groups(opt.groups, group_list, GROUP_LIST_SIZE) != 0) {
2460a8e1175bSopenharmony_ci            goto exit;
2461a8e1175bSopenharmony_ci        }
2462a8e1175bSopenharmony_ci    }
2463a8e1175bSopenharmony_ci
2464a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
2465a8e1175bSopenharmony_ci    if (opt.sig_algs != NULL) {
2466a8e1175bSopenharmony_ci        p = (char *) opt.sig_algs;
2467a8e1175bSopenharmony_ci        i = 0;
2468a8e1175bSopenharmony_ci
2469a8e1175bSopenharmony_ci        /* Leave room for a final MBEDTLS_TLS1_3_SIG_NONE in signature algorithm list (sig_alg_list). */
2470a8e1175bSopenharmony_ci        while (i < SIG_ALG_LIST_SIZE - 1 && *p != '\0') {
2471a8e1175bSopenharmony_ci            q = p;
2472a8e1175bSopenharmony_ci
2473a8e1175bSopenharmony_ci            /* Terminate the current string */
2474a8e1175bSopenharmony_ci            while (*p != ',' && *p != '\0') {
2475a8e1175bSopenharmony_ci                p++;
2476a8e1175bSopenharmony_ci            }
2477a8e1175bSopenharmony_ci            if (*p == ',') {
2478a8e1175bSopenharmony_ci                *p++ = '\0';
2479a8e1175bSopenharmony_ci            }
2480a8e1175bSopenharmony_ci
2481a8e1175bSopenharmony_ci            if (strcmp(q, "rsa_pkcs1_sha256") == 0) {
2482a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA256;
2483a8e1175bSopenharmony_ci            } else if (strcmp(q, "rsa_pkcs1_sha384") == 0) {
2484a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA384;
2485a8e1175bSopenharmony_ci            } else if (strcmp(q, "rsa_pkcs1_sha512") == 0) {
2486a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA512;
2487a8e1175bSopenharmony_ci            } else if (strcmp(q, "ecdsa_secp256r1_sha256") == 0) {
2488a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ECDSA_SECP256R1_SHA256;
2489a8e1175bSopenharmony_ci            } else if (strcmp(q, "ecdsa_secp384r1_sha384") == 0) {
2490a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ECDSA_SECP384R1_SHA384;
2491a8e1175bSopenharmony_ci            } else if (strcmp(q, "ecdsa_secp521r1_sha512") == 0) {
2492a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ECDSA_SECP521R1_SHA512;
2493a8e1175bSopenharmony_ci            } else if (strcmp(q, "rsa_pss_rsae_sha256") == 0) {
2494a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA256;
2495a8e1175bSopenharmony_ci            } else if (strcmp(q, "rsa_pss_rsae_sha384") == 0) {
2496a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA384;
2497a8e1175bSopenharmony_ci            } else if (strcmp(q, "rsa_pss_rsae_sha512") == 0) {
2498a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_RSAE_SHA512;
2499a8e1175bSopenharmony_ci            } else if (strcmp(q, "ed25519") == 0) {
2500a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ED25519;
2501a8e1175bSopenharmony_ci            } else if (strcmp(q, "ed448") == 0) {
2502a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ED448;
2503a8e1175bSopenharmony_ci            } else if (strcmp(q, "rsa_pss_pss_sha256") == 0) {
2504a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA256;
2505a8e1175bSopenharmony_ci            } else if (strcmp(q, "rsa_pss_pss_sha384") == 0) {
2506a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA384;
2507a8e1175bSopenharmony_ci            } else if (strcmp(q, "rsa_pss_pss_sha512") == 0) {
2508a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PSS_PSS_SHA512;
2509a8e1175bSopenharmony_ci            } else if (strcmp(q, "rsa_pkcs1_sha1") == 0) {
2510a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_RSA_PKCS1_SHA1;
2511a8e1175bSopenharmony_ci            } else if (strcmp(q, "ecdsa_sha1") == 0) {
2512a8e1175bSopenharmony_ci                sig_alg_list[i++] = MBEDTLS_TLS1_3_SIG_ECDSA_SHA1;
2513a8e1175bSopenharmony_ci            } else {
2514a8e1175bSopenharmony_ci                ret = -1;
2515a8e1175bSopenharmony_ci                mbedtls_printf("unknown signature algorithm \"%s\"\n", q);
2516a8e1175bSopenharmony_ci                mbedtls_print_supported_sig_algs();
2517a8e1175bSopenharmony_ci                goto exit;
2518a8e1175bSopenharmony_ci            }
2519a8e1175bSopenharmony_ci        }
2520a8e1175bSopenharmony_ci
2521a8e1175bSopenharmony_ci        if (i == (SIG_ALG_LIST_SIZE - 1) && *p != '\0') {
2522a8e1175bSopenharmony_ci            mbedtls_printf("signature algorithm list too long, maximum %d",
2523a8e1175bSopenharmony_ci                           SIG_ALG_LIST_SIZE - 1);
2524a8e1175bSopenharmony_ci            goto exit;
2525a8e1175bSopenharmony_ci        }
2526a8e1175bSopenharmony_ci
2527a8e1175bSopenharmony_ci        sig_alg_list[i] = MBEDTLS_TLS1_3_SIG_NONE;
2528a8e1175bSopenharmony_ci    }
2529a8e1175bSopenharmony_ci#endif
2530a8e1175bSopenharmony_ci
2531a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN)
2532a8e1175bSopenharmony_ci    if (opt.alpn_string != NULL) {
2533a8e1175bSopenharmony_ci        p = (char *) opt.alpn_string;
2534a8e1175bSopenharmony_ci        i = 0;
2535a8e1175bSopenharmony_ci
2536a8e1175bSopenharmony_ci        /* Leave room for a final NULL in alpn_list */
2537a8e1175bSopenharmony_ci        while (i < ALPN_LIST_SIZE - 1 && *p != '\0') {
2538a8e1175bSopenharmony_ci            alpn_list[i++] = p;
2539a8e1175bSopenharmony_ci
2540a8e1175bSopenharmony_ci            /* Terminate the current string and move on to next one */
2541a8e1175bSopenharmony_ci            while (*p != ',' && *p != '\0') {
2542a8e1175bSopenharmony_ci                p++;
2543a8e1175bSopenharmony_ci            }
2544a8e1175bSopenharmony_ci            if (*p == ',') {
2545a8e1175bSopenharmony_ci                *p++ = '\0';
2546a8e1175bSopenharmony_ci            }
2547a8e1175bSopenharmony_ci        }
2548a8e1175bSopenharmony_ci    }
2549a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ALPN */
2550a8e1175bSopenharmony_ci
2551a8e1175bSopenharmony_ci    mbedtls_printf("build version: %s (build %d)\n",
2552a8e1175bSopenharmony_ci                   MBEDTLS_VERSION_STRING_FULL, MBEDTLS_VERSION_NUMBER);
2553a8e1175bSopenharmony_ci
2554a8e1175bSopenharmony_ci    /*
2555a8e1175bSopenharmony_ci     * 0. Initialize the RNG and the session data
2556a8e1175bSopenharmony_ci     */
2557a8e1175bSopenharmony_ci    mbedtls_printf("\n  . Seeding the random number generator...");
2558a8e1175bSopenharmony_ci    fflush(stdout);
2559a8e1175bSopenharmony_ci
2560a8e1175bSopenharmony_ci    ret = rng_seed(&rng, opt.reproducible, pers);
2561a8e1175bSopenharmony_ci    if (ret != 0) {
2562a8e1175bSopenharmony_ci        goto exit;
2563a8e1175bSopenharmony_ci    }
2564a8e1175bSopenharmony_ci    mbedtls_printf(" ok\n");
2565a8e1175bSopenharmony_ci
2566a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
2567a8e1175bSopenharmony_ci    /*
2568a8e1175bSopenharmony_ci     * 1.1. Load the trusted CA
2569a8e1175bSopenharmony_ci     */
2570a8e1175bSopenharmony_ci    mbedtls_printf("  . Loading the CA root certificate ...");
2571a8e1175bSopenharmony_ci    fflush(stdout);
2572a8e1175bSopenharmony_ci
2573a8e1175bSopenharmony_ci    if (strcmp(opt.ca_path, "none") == 0 ||
2574a8e1175bSopenharmony_ci        strcmp(opt.ca_file, "none") == 0) {
2575a8e1175bSopenharmony_ci        ret = 0;
2576a8e1175bSopenharmony_ci    } else
2577a8e1175bSopenharmony_ci#if defined(MBEDTLS_FS_IO)
2578a8e1175bSopenharmony_ci    if (strlen(opt.ca_path)) {
2579a8e1175bSopenharmony_ci        ret = mbedtls_x509_crt_parse_path(&cacert, opt.ca_path);
2580a8e1175bSopenharmony_ci    } else if (strlen(opt.ca_file)) {
2581a8e1175bSopenharmony_ci        ret = mbedtls_x509_crt_parse_file(&cacert, opt.ca_file);
2582a8e1175bSopenharmony_ci    } else
2583a8e1175bSopenharmony_ci#endif
2584a8e1175bSopenharmony_ci    {
2585a8e1175bSopenharmony_ci#if defined(MBEDTLS_PEM_PARSE_C)
2586a8e1175bSopenharmony_ci        for (i = 0; mbedtls_test_cas[i] != NULL; i++) {
2587a8e1175bSopenharmony_ci            ret = mbedtls_x509_crt_parse(&cacert,
2588a8e1175bSopenharmony_ci                                         (const unsigned char *) mbedtls_test_cas[i],
2589a8e1175bSopenharmony_ci                                         mbedtls_test_cas_len[i]);
2590a8e1175bSopenharmony_ci            if (ret != 0) {
2591a8e1175bSopenharmony_ci                break;
2592a8e1175bSopenharmony_ci            }
2593a8e1175bSopenharmony_ci        }
2594a8e1175bSopenharmony_ci#endif /* MBEDTLS_PEM_PARSE_C */
2595a8e1175bSopenharmony_ci        if (ret == 0) {
2596a8e1175bSopenharmony_ci            for (i = 0; mbedtls_test_cas_der[i] != NULL; i++) {
2597a8e1175bSopenharmony_ci                ret = mbedtls_x509_crt_parse_der(&cacert,
2598a8e1175bSopenharmony_ci                                                 (const unsigned char *) mbedtls_test_cas_der[i],
2599a8e1175bSopenharmony_ci                                                 mbedtls_test_cas_der_len[i]);
2600a8e1175bSopenharmony_ci                if (ret != 0) {
2601a8e1175bSopenharmony_ci                    break;
2602a8e1175bSopenharmony_ci                }
2603a8e1175bSopenharmony_ci            }
2604a8e1175bSopenharmony_ci        }
2605a8e1175bSopenharmony_ci    }
2606a8e1175bSopenharmony_ci    if (ret < 0) {
2607a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n",
2608a8e1175bSopenharmony_ci                       (unsigned int) -ret);
2609a8e1175bSopenharmony_ci        goto exit;
2610a8e1175bSopenharmony_ci    }
2611a8e1175bSopenharmony_ci
2612a8e1175bSopenharmony_ci    mbedtls_printf(" ok (%d skipped)\n", ret);
2613a8e1175bSopenharmony_ci
2614a8e1175bSopenharmony_ci    /*
2615a8e1175bSopenharmony_ci     * 1.2. Load own certificate and private key
2616a8e1175bSopenharmony_ci     */
2617a8e1175bSopenharmony_ci    mbedtls_printf("  . Loading the server cert. and key...");
2618a8e1175bSopenharmony_ci    fflush(stdout);
2619a8e1175bSopenharmony_ci
2620a8e1175bSopenharmony_ci#if defined(MBEDTLS_FS_IO)
2621a8e1175bSopenharmony_ci    if (strlen(opt.crt_file) && strcmp(opt.crt_file, "none") != 0) {
2622a8e1175bSopenharmony_ci        key_cert_init++;
2623a8e1175bSopenharmony_ci        if ((ret = mbedtls_x509_crt_parse_file(&srvcert, opt.crt_file)) != 0) {
2624a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  !  mbedtls_x509_crt_parse_file returned -0x%x\n\n",
2625a8e1175bSopenharmony_ci                           (unsigned int) -ret);
2626a8e1175bSopenharmony_ci            goto exit;
2627a8e1175bSopenharmony_ci        }
2628a8e1175bSopenharmony_ci    }
2629a8e1175bSopenharmony_ci    if (strlen(opt.key_file) && strcmp(opt.key_file, "none") != 0) {
2630a8e1175bSopenharmony_ci        key_cert_init++;
2631a8e1175bSopenharmony_ci        if ((ret = mbedtls_pk_parse_keyfile(&pkey, opt.key_file,
2632a8e1175bSopenharmony_ci                                            opt.key_pwd, rng_get, &rng)) != 0) {
2633a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  !  mbedtls_pk_parse_keyfile returned -0x%x\n\n",
2634a8e1175bSopenharmony_ci                           (unsigned int) -ret);
2635a8e1175bSopenharmony_ci            goto exit;
2636a8e1175bSopenharmony_ci        }
2637a8e1175bSopenharmony_ci    }
2638a8e1175bSopenharmony_ci    if (key_cert_init == 1) {
2639a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  !  crt_file without key_file or vice-versa\n\n");
2640a8e1175bSopenharmony_ci        goto exit;
2641a8e1175bSopenharmony_ci    }
2642a8e1175bSopenharmony_ci
2643a8e1175bSopenharmony_ci    if (strlen(opt.crt_file2) && strcmp(opt.crt_file2, "none") != 0) {
2644a8e1175bSopenharmony_ci        key_cert_init2++;
2645a8e1175bSopenharmony_ci        if ((ret = mbedtls_x509_crt_parse_file(&srvcert2, opt.crt_file2)) != 0) {
2646a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  !  mbedtls_x509_crt_parse_file(2) returned -0x%x\n\n",
2647a8e1175bSopenharmony_ci                           (unsigned int) -ret);
2648a8e1175bSopenharmony_ci            goto exit;
2649a8e1175bSopenharmony_ci        }
2650a8e1175bSopenharmony_ci    }
2651a8e1175bSopenharmony_ci    if (strlen(opt.key_file2) && strcmp(opt.key_file2, "none") != 0) {
2652a8e1175bSopenharmony_ci        key_cert_init2++;
2653a8e1175bSopenharmony_ci        if ((ret = mbedtls_pk_parse_keyfile(&pkey2, opt.key_file2,
2654a8e1175bSopenharmony_ci                                            opt.key_pwd2, rng_get, &rng)) != 0) {
2655a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  !  mbedtls_pk_parse_keyfile(2) returned -0x%x\n\n",
2656a8e1175bSopenharmony_ci                           (unsigned int) -ret);
2657a8e1175bSopenharmony_ci            goto exit;
2658a8e1175bSopenharmony_ci        }
2659a8e1175bSopenharmony_ci    }
2660a8e1175bSopenharmony_ci    if (key_cert_init2 == 1) {
2661a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  !  crt_file2 without key_file2 or vice-versa\n\n");
2662a8e1175bSopenharmony_ci        goto exit;
2663a8e1175bSopenharmony_ci    }
2664a8e1175bSopenharmony_ci#endif
2665a8e1175bSopenharmony_ci    if (key_cert_init == 0 &&
2666a8e1175bSopenharmony_ci        strcmp(opt.crt_file, "none") != 0 &&
2667a8e1175bSopenharmony_ci        strcmp(opt.key_file, "none") != 0 &&
2668a8e1175bSopenharmony_ci        key_cert_init2 == 0 &&
2669a8e1175bSopenharmony_ci        strcmp(opt.crt_file2, "none") != 0 &&
2670a8e1175bSopenharmony_ci        strcmp(opt.key_file2, "none") != 0) {
2671a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C)
2672a8e1175bSopenharmony_ci        if ((ret = mbedtls_x509_crt_parse(&srvcert,
2673a8e1175bSopenharmony_ci                                          (const unsigned char *) mbedtls_test_srv_crt_rsa,
2674a8e1175bSopenharmony_ci                                          mbedtls_test_srv_crt_rsa_len)) != 0) {
2675a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n",
2676a8e1175bSopenharmony_ci                           (unsigned int) -ret);
2677a8e1175bSopenharmony_ci            goto exit;
2678a8e1175bSopenharmony_ci        }
2679a8e1175bSopenharmony_ci        if ((ret = mbedtls_pk_parse_key(&pkey,
2680a8e1175bSopenharmony_ci                                        (const unsigned char *) mbedtls_test_srv_key_rsa,
2681a8e1175bSopenharmony_ci                                        mbedtls_test_srv_key_rsa_len, NULL, 0,
2682a8e1175bSopenharmony_ci                                        rng_get, &rng)) != 0) {
2683a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  !  mbedtls_pk_parse_key returned -0x%x\n\n",
2684a8e1175bSopenharmony_ci                           (unsigned int) -ret);
2685a8e1175bSopenharmony_ci            goto exit;
2686a8e1175bSopenharmony_ci        }
2687a8e1175bSopenharmony_ci        key_cert_init = 2;
2688a8e1175bSopenharmony_ci#endif /* MBEDTLS_RSA_C */
2689a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_CAN_ECDSA_SOME)
2690a8e1175bSopenharmony_ci        if ((ret = mbedtls_x509_crt_parse(&srvcert2,
2691a8e1175bSopenharmony_ci                                          (const unsigned char *) mbedtls_test_srv_crt_ec,
2692a8e1175bSopenharmony_ci                                          mbedtls_test_srv_crt_ec_len)) != 0) {
2693a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  !  x509_crt_parse2 returned -0x%x\n\n",
2694a8e1175bSopenharmony_ci                           (unsigned int) -ret);
2695a8e1175bSopenharmony_ci            goto exit;
2696a8e1175bSopenharmony_ci        }
2697a8e1175bSopenharmony_ci        if ((ret = mbedtls_pk_parse_key(&pkey2,
2698a8e1175bSopenharmony_ci                                        (const unsigned char *) mbedtls_test_srv_key_ec,
2699a8e1175bSopenharmony_ci                                        mbedtls_test_srv_key_ec_len, NULL, 0,
2700a8e1175bSopenharmony_ci                                        rng_get, &rng)) != 0) {
2701a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  !  pk_parse_key2 returned -0x%x\n\n",
2702a8e1175bSopenharmony_ci                           (unsigned int) -ret);
2703a8e1175bSopenharmony_ci            goto exit;
2704a8e1175bSopenharmony_ci        }
2705a8e1175bSopenharmony_ci        key_cert_init2 = 2;
2706a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_CAN_ECDSA_SOME */
2707a8e1175bSopenharmony_ci    }
2708a8e1175bSopenharmony_ci
2709a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
2710a8e1175bSopenharmony_ci    if (opt.key_opaque != 0) {
2711a8e1175bSopenharmony_ci        psa_algorithm_t psa_alg, psa_alg2 = PSA_ALG_NONE;
2712a8e1175bSopenharmony_ci        psa_key_usage_t psa_usage = 0;
2713a8e1175bSopenharmony_ci
2714a8e1175bSopenharmony_ci        if (key_opaque_set_alg_usage(opt.key1_opaque_alg1,
2715a8e1175bSopenharmony_ci                                     opt.key1_opaque_alg2,
2716a8e1175bSopenharmony_ci                                     &psa_alg, &psa_alg2,
2717a8e1175bSopenharmony_ci                                     &psa_usage,
2718a8e1175bSopenharmony_ci                                     mbedtls_pk_get_type(&pkey)) == 0) {
2719a8e1175bSopenharmony_ci            ret = pk_wrap_as_opaque(&pkey, psa_alg, psa_alg2, psa_usage, &key_slot);
2720a8e1175bSopenharmony_ci            if (ret != 0) {
2721a8e1175bSopenharmony_ci                mbedtls_printf(" failed\n  !  "
2722a8e1175bSopenharmony_ci                               "pk_wrap_as_opaque returned -0x%x\n\n",
2723a8e1175bSopenharmony_ci                               (unsigned int)  -ret);
2724a8e1175bSopenharmony_ci                goto exit;
2725a8e1175bSopenharmony_ci            }
2726a8e1175bSopenharmony_ci        }
2727a8e1175bSopenharmony_ci
2728a8e1175bSopenharmony_ci        psa_alg = PSA_ALG_NONE; psa_alg2 = PSA_ALG_NONE;
2729a8e1175bSopenharmony_ci        psa_usage = 0;
2730a8e1175bSopenharmony_ci
2731a8e1175bSopenharmony_ci        if (key_opaque_set_alg_usage(opt.key2_opaque_alg1,
2732a8e1175bSopenharmony_ci                                     opt.key2_opaque_alg2,
2733a8e1175bSopenharmony_ci                                     &psa_alg, &psa_alg2,
2734a8e1175bSopenharmony_ci                                     &psa_usage,
2735a8e1175bSopenharmony_ci                                     mbedtls_pk_get_type(&pkey2)) == 0) {
2736a8e1175bSopenharmony_ci            ret = pk_wrap_as_opaque(&pkey2, psa_alg, psa_alg2, psa_usage, &key_slot2);
2737a8e1175bSopenharmony_ci            if (ret != 0) {
2738a8e1175bSopenharmony_ci                mbedtls_printf(" failed\n  !  "
2739a8e1175bSopenharmony_ci                               "mbedtls_pk_get_psa_attributes returned -0x%x\n\n",
2740a8e1175bSopenharmony_ci                               (unsigned int)  -ret);
2741a8e1175bSopenharmony_ci                goto exit;
2742a8e1175bSopenharmony_ci            }
2743a8e1175bSopenharmony_ci        }
2744a8e1175bSopenharmony_ci    }
2745a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
2746a8e1175bSopenharmony_ci
2747a8e1175bSopenharmony_ci    mbedtls_printf(" ok (key types: %s, %s)\n",
2748a8e1175bSopenharmony_ci                   key_cert_init ? mbedtls_pk_get_name(&pkey) : "none",
2749a8e1175bSopenharmony_ci                   key_cert_init2 ? mbedtls_pk_get_name(&pkey2) : "none");
2750a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
2751a8e1175bSopenharmony_ci
2752a8e1175bSopenharmony_ci#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
2753a8e1175bSopenharmony_ci    if (opt.dhm_file != NULL) {
2754a8e1175bSopenharmony_ci        mbedtls_printf("  . Loading DHM parameters...");
2755a8e1175bSopenharmony_ci        fflush(stdout);
2756a8e1175bSopenharmony_ci
2757a8e1175bSopenharmony_ci        if ((ret = mbedtls_dhm_parse_dhmfile(&dhm, opt.dhm_file)) != 0) {
2758a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_dhm_parse_dhmfile returned -0x%04X\n\n",
2759a8e1175bSopenharmony_ci                           (unsigned int) -ret);
2760a8e1175bSopenharmony_ci            goto exit;
2761a8e1175bSopenharmony_ci        }
2762a8e1175bSopenharmony_ci
2763a8e1175bSopenharmony_ci        mbedtls_printf(" ok\n");
2764a8e1175bSopenharmony_ci    }
2765a8e1175bSopenharmony_ci#endif
2766a8e1175bSopenharmony_ci
2767a8e1175bSopenharmony_ci#if defined(SNI_OPTION)
2768a8e1175bSopenharmony_ci    if (opt.sni != NULL) {
2769a8e1175bSopenharmony_ci        mbedtls_printf("  . Setting up SNI information...");
2770a8e1175bSopenharmony_ci        fflush(stdout);
2771a8e1175bSopenharmony_ci
2772a8e1175bSopenharmony_ci        if ((sni_info = sni_parse(opt.sni)) == NULL) {
2773a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n");
2774a8e1175bSopenharmony_ci            goto exit;
2775a8e1175bSopenharmony_ci        }
2776a8e1175bSopenharmony_ci
2777a8e1175bSopenharmony_ci        mbedtls_printf(" ok\n");
2778a8e1175bSopenharmony_ci    }
2779a8e1175bSopenharmony_ci#endif /* SNI_OPTION */
2780a8e1175bSopenharmony_ci
2781a8e1175bSopenharmony_ci    /*
2782a8e1175bSopenharmony_ci     * 2. Setup stuff
2783a8e1175bSopenharmony_ci     */
2784a8e1175bSopenharmony_ci    mbedtls_printf("  . Setting up the SSL/TLS structure...");
2785a8e1175bSopenharmony_ci    fflush(stdout);
2786a8e1175bSopenharmony_ci
2787a8e1175bSopenharmony_ci    if ((ret = mbedtls_ssl_config_defaults(&conf,
2788a8e1175bSopenharmony_ci                                           MBEDTLS_SSL_IS_SERVER,
2789a8e1175bSopenharmony_ci                                           opt.transport,
2790a8e1175bSopenharmony_ci                                           MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
2791a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  ! mbedtls_ssl_config_defaults returned -0x%x\n\n",
2792a8e1175bSopenharmony_ci                       (unsigned int) -ret);
2793a8e1175bSopenharmony_ci        goto exit;
2794a8e1175bSopenharmony_ci    }
2795a8e1175bSopenharmony_ci
2796a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
2797a8e1175bSopenharmony_ci    /* The default algorithms profile disables SHA-1, but our tests still
2798a8e1175bSopenharmony_ci       rely on it heavily. Hence we allow it here. A real-world server
2799a8e1175bSopenharmony_ci       should use the default profile unless there is a good reason not to. */
2800a8e1175bSopenharmony_ci    if (opt.allow_sha1 > 0) {
2801a8e1175bSopenharmony_ci        crt_profile_for_test.allowed_mds |= MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1);
2802a8e1175bSopenharmony_ci        mbedtls_ssl_conf_cert_profile(&conf, &crt_profile_for_test);
2803a8e1175bSopenharmony_ci        mbedtls_ssl_conf_sig_algs(&conf, ssl_sig_algs_for_test);
2804a8e1175bSopenharmony_ci    }
2805a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
2806a8e1175bSopenharmony_ci
2807a8e1175bSopenharmony_ci    if (opt.auth_mode != DFL_AUTH_MODE) {
2808a8e1175bSopenharmony_ci        mbedtls_ssl_conf_authmode(&conf, opt.auth_mode);
2809a8e1175bSopenharmony_ci    }
2810a8e1175bSopenharmony_ci
2811a8e1175bSopenharmony_ci    if (opt.cert_req_ca_list != DFL_CERT_REQ_CA_LIST) {
2812a8e1175bSopenharmony_ci        mbedtls_ssl_conf_cert_req_ca_list(&conf, opt.cert_req_ca_list);
2813a8e1175bSopenharmony_ci    }
2814a8e1175bSopenharmony_ci
2815a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
2816a8e1175bSopenharmony_ci    if (opt.early_data != DFL_EARLY_DATA) {
2817a8e1175bSopenharmony_ci        mbedtls_ssl_conf_early_data(&conf, opt.early_data);
2818a8e1175bSopenharmony_ci    }
2819a8e1175bSopenharmony_ci    if (opt.max_early_data_size != DFL_MAX_EARLY_DATA_SIZE) {
2820a8e1175bSopenharmony_ci        mbedtls_ssl_conf_max_early_data_size(
2821a8e1175bSopenharmony_ci            &conf, opt.max_early_data_size);
2822a8e1175bSopenharmony_ci    }
2823a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
2824a8e1175bSopenharmony_ci
2825a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
2826a8e1175bSopenharmony_ci    /* exercise setting DN hints for server certificate request
2827a8e1175bSopenharmony_ci     * (Intended for use where the client cert expected has been signed by
2828a8e1175bSopenharmony_ci     *  a specific CA which is an intermediate in a CA chain, not the root) */
2829a8e1175bSopenharmony_ci    if (opt.cert_req_dn_hint == 2 && key_cert_init2) {
2830a8e1175bSopenharmony_ci        mbedtls_ssl_conf_dn_hints(&conf, &srvcert2);
2831a8e1175bSopenharmony_ci    }
2832a8e1175bSopenharmony_ci#endif
2833a8e1175bSopenharmony_ci
2834a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
2835a8e1175bSopenharmony_ci    if (opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX) {
2836a8e1175bSopenharmony_ci        mbedtls_ssl_conf_handshake_timeout(&conf, opt.hs_to_min, opt.hs_to_max);
2837a8e1175bSopenharmony_ci    }
2838a8e1175bSopenharmony_ci
2839a8e1175bSopenharmony_ci    if (opt.dgram_packing != DFL_DGRAM_PACKING) {
2840a8e1175bSopenharmony_ci        mbedtls_ssl_set_datagram_packing(&ssl, opt.dgram_packing);
2841a8e1175bSopenharmony_ci    }
2842a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
2843a8e1175bSopenharmony_ci
2844a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
2845a8e1175bSopenharmony_ci    if ((ret = mbedtls_ssl_conf_max_frag_len(&conf, opt.mfl_code)) != 0) {
2846a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  ! mbedtls_ssl_conf_max_frag_len returned %d\n\n", ret);
2847a8e1175bSopenharmony_ci        goto exit;
2848a8e1175bSopenharmony_ci    }
2849a8e1175bSopenharmony_ci#endif
2850a8e1175bSopenharmony_ci
2851a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2852a8e1175bSopenharmony_ci    if (opt.cid_enabled == 1 || opt.cid_enabled_renego == 1) {
2853a8e1175bSopenharmony_ci        if (opt.cid_enabled == 1        &&
2854a8e1175bSopenharmony_ci            opt.cid_enabled_renego == 1 &&
2855a8e1175bSopenharmony_ci            cid_len != cid_renego_len) {
2856a8e1175bSopenharmony_ci            mbedtls_printf("CID length must not change during renegotiation\n");
2857a8e1175bSopenharmony_ci            goto usage;
2858a8e1175bSopenharmony_ci        }
2859a8e1175bSopenharmony_ci
2860a8e1175bSopenharmony_ci        if (opt.cid_enabled == 1) {
2861a8e1175bSopenharmony_ci            ret = mbedtls_ssl_conf_cid(&conf, cid_len,
2862a8e1175bSopenharmony_ci                                       MBEDTLS_SSL_UNEXPECTED_CID_IGNORE);
2863a8e1175bSopenharmony_ci        } else {
2864a8e1175bSopenharmony_ci            ret = mbedtls_ssl_conf_cid(&conf, cid_renego_len,
2865a8e1175bSopenharmony_ci                                       MBEDTLS_SSL_UNEXPECTED_CID_IGNORE);
2866a8e1175bSopenharmony_ci        }
2867a8e1175bSopenharmony_ci
2868a8e1175bSopenharmony_ci        if (ret != 0) {
2869a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_conf_cid_len returned -%#04x\n\n",
2870a8e1175bSopenharmony_ci                           (unsigned int) -ret);
2871a8e1175bSopenharmony_ci            goto exit;
2872a8e1175bSopenharmony_ci        }
2873a8e1175bSopenharmony_ci    }
2874a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
2875a8e1175bSopenharmony_ci
2876a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP)
2877a8e1175bSopenharmony_ci    const mbedtls_ssl_srtp_profile forced_profile[] =
2878a8e1175bSopenharmony_ci    { opt.force_srtp_profile, MBEDTLS_TLS_SRTP_UNSET };
2879a8e1175bSopenharmony_ci    if (opt.use_srtp == 1) {
2880a8e1175bSopenharmony_ci        if (opt.force_srtp_profile != 0) {
2881a8e1175bSopenharmony_ci            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles(&conf, forced_profile);
2882a8e1175bSopenharmony_ci        } else {
2883a8e1175bSopenharmony_ci            ret = mbedtls_ssl_conf_dtls_srtp_protection_profiles(&conf, default_profiles);
2884a8e1175bSopenharmony_ci        }
2885a8e1175bSopenharmony_ci
2886a8e1175bSopenharmony_ci        if (ret != 0) {
2887a8e1175bSopenharmony_ci            mbedtls_printf(
2888a8e1175bSopenharmony_ci                " failed\n  ! mbedtls_ssl_conf_dtls_srtp_protection_profiles returned %d\n\n",
2889a8e1175bSopenharmony_ci                ret);
2890a8e1175bSopenharmony_ci            goto exit;
2891a8e1175bSopenharmony_ci        }
2892a8e1175bSopenharmony_ci
2893a8e1175bSopenharmony_ci        mbedtls_ssl_conf_srtp_mki_value_supported(&conf,
2894a8e1175bSopenharmony_ci                                                  opt.support_mki ?
2895a8e1175bSopenharmony_ci                                                  MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED :
2896a8e1175bSopenharmony_ci                                                  MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED);
2897a8e1175bSopenharmony_ci
2898a8e1175bSopenharmony_ci    } else if (opt.force_srtp_profile != 0) {
2899a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  ! must enable use_srtp to force srtp profile\n\n");
2900a8e1175bSopenharmony_ci        goto exit;
2901a8e1175bSopenharmony_ci    }
2902a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_SRTP */
2903a8e1175bSopenharmony_ci
2904a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
2905a8e1175bSopenharmony_ci    if (opt.extended_ms != DFL_EXTENDED_MS) {
2906a8e1175bSopenharmony_ci        mbedtls_ssl_conf_extended_master_secret(&conf, opt.extended_ms);
2907a8e1175bSopenharmony_ci    }
2908a8e1175bSopenharmony_ci#endif
2909a8e1175bSopenharmony_ci
2910a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
2911a8e1175bSopenharmony_ci    if (opt.etm != DFL_ETM) {
2912a8e1175bSopenharmony_ci        mbedtls_ssl_conf_encrypt_then_mac(&conf, opt.etm);
2913a8e1175bSopenharmony_ci    }
2914a8e1175bSopenharmony_ci#endif
2915a8e1175bSopenharmony_ci
2916a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN)
2917a8e1175bSopenharmony_ci    if (opt.alpn_string != NULL) {
2918a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_conf_alpn_protocols(&conf, alpn_list)) != 0) {
2919a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_conf_alpn_protocols returned %d\n\n", ret);
2920a8e1175bSopenharmony_ci            goto exit;
2921a8e1175bSopenharmony_ci        }
2922a8e1175bSopenharmony_ci    }
2923a8e1175bSopenharmony_ci#endif
2924a8e1175bSopenharmony_ci
2925a8e1175bSopenharmony_ci    if (opt.reproducible) {
2926a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME)
2927a8e1175bSopenharmony_ci#if defined(MBEDTLS_PLATFORM_TIME_ALT)
2928a8e1175bSopenharmony_ci        mbedtls_platform_set_time(dummy_constant_time);
2929a8e1175bSopenharmony_ci#else
2930a8e1175bSopenharmony_ci        fprintf(stderr, "Warning: reproducible option used without constant time\n");
2931a8e1175bSopenharmony_ci#endif
2932a8e1175bSopenharmony_ci#endif  /* MBEDTLS_HAVE_TIME */
2933a8e1175bSopenharmony_ci    }
2934a8e1175bSopenharmony_ci    mbedtls_ssl_conf_rng(&conf, rng_get, &rng);
2935a8e1175bSopenharmony_ci    mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
2936a8e1175bSopenharmony_ci
2937a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C)
2938a8e1175bSopenharmony_ci    if (opt.cache_max != -1) {
2939a8e1175bSopenharmony_ci        mbedtls_ssl_cache_set_max_entries(&cache, opt.cache_max);
2940a8e1175bSopenharmony_ci    }
2941a8e1175bSopenharmony_ci
2942a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME)
2943a8e1175bSopenharmony_ci    if (opt.cache_timeout != -1) {
2944a8e1175bSopenharmony_ci        mbedtls_ssl_cache_set_timeout(&cache, opt.cache_timeout);
2945a8e1175bSopenharmony_ci    }
2946a8e1175bSopenharmony_ci#endif
2947a8e1175bSopenharmony_ci
2948a8e1175bSopenharmony_ci    mbedtls_ssl_conf_session_cache(&conf, &cache,
2949a8e1175bSopenharmony_ci                                   mbedtls_ssl_cache_get,
2950a8e1175bSopenharmony_ci                                   mbedtls_ssl_cache_set);
2951a8e1175bSopenharmony_ci#endif
2952a8e1175bSopenharmony_ci
2953a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C)
2954a8e1175bSopenharmony_ci    if (opt.tickets != MBEDTLS_SSL_SESSION_TICKETS_DISABLED) {
2955a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME)
2956a8e1175bSopenharmony_ci        if (opt.dummy_ticket) {
2957a8e1175bSopenharmony_ci            mbedtls_ssl_conf_session_tickets_cb(&conf,
2958a8e1175bSopenharmony_ci                                                dummy_ticket_write,
2959a8e1175bSopenharmony_ci                                                dummy_ticket_parse,
2960a8e1175bSopenharmony_ci                                                NULL);
2961a8e1175bSopenharmony_ci        } else
2962a8e1175bSopenharmony_ci#endif /* MBEDTLS_HAVE_TIME */
2963a8e1175bSopenharmony_ci        {
2964a8e1175bSopenharmony_ci            if ((ret = mbedtls_ssl_ticket_setup(&ticket_ctx,
2965a8e1175bSopenharmony_ci                                                rng_get, &rng,
2966a8e1175bSopenharmony_ci                                                opt.ticket_aead,
2967a8e1175bSopenharmony_ci                                                opt.ticket_timeout)) != 0) {
2968a8e1175bSopenharmony_ci                mbedtls_printf(
2969a8e1175bSopenharmony_ci                    " failed\n  ! mbedtls_ssl_ticket_setup returned %d\n\n",
2970a8e1175bSopenharmony_ci                    ret);
2971a8e1175bSopenharmony_ci                goto exit;
2972a8e1175bSopenharmony_ci            }
2973a8e1175bSopenharmony_ci
2974a8e1175bSopenharmony_ci            mbedtls_ssl_conf_session_tickets_cb(&conf,
2975a8e1175bSopenharmony_ci                                                mbedtls_ssl_ticket_write,
2976a8e1175bSopenharmony_ci                                                mbedtls_ssl_ticket_parse,
2977a8e1175bSopenharmony_ci                                                &ticket_ctx);
2978a8e1175bSopenharmony_ci        }
2979a8e1175bSopenharmony_ci
2980a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2981a8e1175bSopenharmony_ci        mbedtls_ssl_conf_new_session_tickets(&conf, opt.tickets);
2982a8e1175bSopenharmony_ci#endif
2983a8e1175bSopenharmony_ci        /* exercise manual ticket rotation (not required for typical use)
2984a8e1175bSopenharmony_ci         * (used for external synchronization of session ticket encryption keys)
2985a8e1175bSopenharmony_ci         */
2986a8e1175bSopenharmony_ci        if (opt.ticket_rotate) {
2987a8e1175bSopenharmony_ci            unsigned char kbuf[MBEDTLS_SSL_TICKET_MAX_KEY_BYTES];
2988a8e1175bSopenharmony_ci            unsigned char name[MBEDTLS_SSL_TICKET_KEY_NAME_BYTES];
2989a8e1175bSopenharmony_ci            if ((ret = rng_get(&rng, name, sizeof(name))) != 0 ||
2990a8e1175bSopenharmony_ci                (ret = rng_get(&rng, kbuf, sizeof(kbuf))) != 0 ||
2991a8e1175bSopenharmony_ci                (ret = mbedtls_ssl_ticket_rotate(&ticket_ctx,
2992a8e1175bSopenharmony_ci                                                 name, sizeof(name), kbuf, sizeof(kbuf),
2993a8e1175bSopenharmony_ci                                                 opt.ticket_timeout)) != 0) {
2994a8e1175bSopenharmony_ci                mbedtls_printf(" failed\n  ! mbedtls_ssl_ticket_rotate returned %d\n\n", ret);
2995a8e1175bSopenharmony_ci                goto exit;
2996a8e1175bSopenharmony_ci            }
2997a8e1175bSopenharmony_ci        }
2998a8e1175bSopenharmony_ci    }
2999a8e1175bSopenharmony_ci#endif
3000a8e1175bSopenharmony_ci
3001a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
3002a8e1175bSopenharmony_ci    if (opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3003a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_COOKIE_C)
3004a8e1175bSopenharmony_ci        if (opt.cookies > 0) {
3005a8e1175bSopenharmony_ci            if ((ret = mbedtls_ssl_cookie_setup(&cookie_ctx,
3006a8e1175bSopenharmony_ci                                                rng_get, &rng)) != 0) {
3007a8e1175bSopenharmony_ci                mbedtls_printf(" failed\n  ! mbedtls_ssl_cookie_setup returned %d\n\n", ret);
3008a8e1175bSopenharmony_ci                goto exit;
3009a8e1175bSopenharmony_ci            }
3010a8e1175bSopenharmony_ci
3011a8e1175bSopenharmony_ci            mbedtls_ssl_conf_dtls_cookies(&conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check,
3012a8e1175bSopenharmony_ci                                          &cookie_ctx);
3013a8e1175bSopenharmony_ci        } else
3014a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_COOKIE_C */
3015a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
3016a8e1175bSopenharmony_ci        if (opt.cookies == 0) {
3017a8e1175bSopenharmony_ci            mbedtls_ssl_conf_dtls_cookies(&conf, NULL, NULL, NULL);
3018a8e1175bSopenharmony_ci        } else
3019a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
3020a8e1175bSopenharmony_ci        {
3021a8e1175bSopenharmony_ci            ; /* Nothing to do */
3022a8e1175bSopenharmony_ci        }
3023a8e1175bSopenharmony_ci
3024a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
3025a8e1175bSopenharmony_ci        if (opt.anti_replay != DFL_ANTI_REPLAY) {
3026a8e1175bSopenharmony_ci            mbedtls_ssl_conf_dtls_anti_replay(&conf, opt.anti_replay);
3027a8e1175bSopenharmony_ci        }
3028a8e1175bSopenharmony_ci#endif
3029a8e1175bSopenharmony_ci
3030a8e1175bSopenharmony_ci        if (opt.badmac_limit != DFL_BADMAC_LIMIT) {
3031a8e1175bSopenharmony_ci            mbedtls_ssl_conf_dtls_badmac_limit(&conf, opt.badmac_limit);
3032a8e1175bSopenharmony_ci        }
3033a8e1175bSopenharmony_ci    }
3034a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */
3035a8e1175bSopenharmony_ci
3036a8e1175bSopenharmony_ci    if (opt.force_ciphersuite[0] != DFL_FORCE_CIPHER) {
3037a8e1175bSopenharmony_ci        mbedtls_ssl_conf_ciphersuites(&conf, opt.force_ciphersuite);
3038a8e1175bSopenharmony_ci    }
3039a8e1175bSopenharmony_ci
3040a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
3041a8e1175bSopenharmony_ci    mbedtls_ssl_conf_tls13_key_exchange_modes(&conf, opt.tls13_kex_modes);
3042a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
3043a8e1175bSopenharmony_ci
3044a8e1175bSopenharmony_ci    if (opt.allow_legacy != DFL_ALLOW_LEGACY) {
3045a8e1175bSopenharmony_ci        mbedtls_ssl_conf_legacy_renegotiation(&conf, opt.allow_legacy);
3046a8e1175bSopenharmony_ci    }
3047a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION)
3048a8e1175bSopenharmony_ci    mbedtls_ssl_conf_renegotiation(&conf, opt.renegotiation);
3049a8e1175bSopenharmony_ci
3050a8e1175bSopenharmony_ci    if (opt.renego_delay != DFL_RENEGO_DELAY) {
3051a8e1175bSopenharmony_ci        mbedtls_ssl_conf_renegotiation_enforced(&conf, opt.renego_delay);
3052a8e1175bSopenharmony_ci    }
3053a8e1175bSopenharmony_ci
3054a8e1175bSopenharmony_ci    if (opt.renego_period != DFL_RENEGO_PERIOD) {
3055a8e1175bSopenharmony_ci        PUT_UINT64_BE(renego_period, opt.renego_period, 0);
3056a8e1175bSopenharmony_ci        mbedtls_ssl_conf_renegotiation_period(&conf, renego_period);
3057a8e1175bSopenharmony_ci    }
3058a8e1175bSopenharmony_ci#endif
3059a8e1175bSopenharmony_ci
3060a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
3061a8e1175bSopenharmony_ci    if (strcmp(opt.ca_path, "none") != 0 &&
3062a8e1175bSopenharmony_ci        strcmp(opt.ca_file, "none") != 0) {
3063a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
3064a8e1175bSopenharmony_ci        if (opt.ca_callback != 0) {
3065a8e1175bSopenharmony_ci            mbedtls_ssl_conf_ca_cb(&conf, ca_callback, &cacert);
3066a8e1175bSopenharmony_ci        } else
3067a8e1175bSopenharmony_ci#endif
3068a8e1175bSopenharmony_ci        mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
3069a8e1175bSopenharmony_ci    }
3070a8e1175bSopenharmony_ci    if (key_cert_init) {
3071a8e1175bSopenharmony_ci        mbedtls_pk_context *pk = &pkey;
3072a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3073a8e1175bSopenharmony_ci        if (opt.async_private_delay1 >= 0) {
3074a8e1175bSopenharmony_ci            ret = ssl_async_set_key(&ssl_async_keys, &srvcert, pk, 0,
3075a8e1175bSopenharmony_ci                                    opt.async_private_delay1);
3076a8e1175bSopenharmony_ci            if (ret < 0) {
3077a8e1175bSopenharmony_ci                mbedtls_printf("  Test error: ssl_async_set_key failed (%d)\n",
3078a8e1175bSopenharmony_ci                               ret);
3079a8e1175bSopenharmony_ci                goto exit;
3080a8e1175bSopenharmony_ci            }
3081a8e1175bSopenharmony_ci            pk = NULL;
3082a8e1175bSopenharmony_ci        }
3083a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
3084a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_conf_own_cert(&conf, &srvcert, pk)) != 0) {
3085a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret);
3086a8e1175bSopenharmony_ci            goto exit;
3087a8e1175bSopenharmony_ci        }
3088a8e1175bSopenharmony_ci    }
3089a8e1175bSopenharmony_ci    if (key_cert_init2) {
3090a8e1175bSopenharmony_ci        mbedtls_pk_context *pk = &pkey2;
3091a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3092a8e1175bSopenharmony_ci        if (opt.async_private_delay2 >= 0) {
3093a8e1175bSopenharmony_ci            ret = ssl_async_set_key(&ssl_async_keys, &srvcert2, pk, 0,
3094a8e1175bSopenharmony_ci                                    opt.async_private_delay2);
3095a8e1175bSopenharmony_ci            if (ret < 0) {
3096a8e1175bSopenharmony_ci                mbedtls_printf("  Test error: ssl_async_set_key failed (%d)\n",
3097a8e1175bSopenharmony_ci                               ret);
3098a8e1175bSopenharmony_ci                goto exit;
3099a8e1175bSopenharmony_ci            }
3100a8e1175bSopenharmony_ci            pk = NULL;
3101a8e1175bSopenharmony_ci        }
3102a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
3103a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_conf_own_cert(&conf, &srvcert2, pk)) != 0) {
3104a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret);
3105a8e1175bSopenharmony_ci            goto exit;
3106a8e1175bSopenharmony_ci        }
3107a8e1175bSopenharmony_ci    }
3108a8e1175bSopenharmony_ci
3109a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3110a8e1175bSopenharmony_ci    if (opt.async_operations[0] != '-') {
3111a8e1175bSopenharmony_ci        mbedtls_ssl_async_sign_t *sign = NULL;
3112a8e1175bSopenharmony_ci        mbedtls_ssl_async_decrypt_t *decrypt = NULL;
3113a8e1175bSopenharmony_ci        const char *r;
3114a8e1175bSopenharmony_ci        for (r = opt.async_operations; *r; r++) {
3115a8e1175bSopenharmony_ci            switch (*r) {
3116a8e1175bSopenharmony_ci                case 'd':
3117a8e1175bSopenharmony_ci                    decrypt = ssl_async_decrypt;
3118a8e1175bSopenharmony_ci                    break;
3119a8e1175bSopenharmony_ci                case 's':
3120a8e1175bSopenharmony_ci                    sign = ssl_async_sign;
3121a8e1175bSopenharmony_ci                    break;
3122a8e1175bSopenharmony_ci            }
3123a8e1175bSopenharmony_ci        }
3124a8e1175bSopenharmony_ci        ssl_async_keys.inject_error = (opt.async_private_error < 0 ?
3125a8e1175bSopenharmony_ci                                       -opt.async_private_error :
3126a8e1175bSopenharmony_ci                                       opt.async_private_error);
3127a8e1175bSopenharmony_ci        ssl_async_keys.f_rng = rng_get;
3128a8e1175bSopenharmony_ci        ssl_async_keys.p_rng = &rng;
3129a8e1175bSopenharmony_ci        mbedtls_ssl_conf_async_private_cb(&conf,
3130a8e1175bSopenharmony_ci                                          sign,
3131a8e1175bSopenharmony_ci                                          decrypt,
3132a8e1175bSopenharmony_ci                                          ssl_async_resume,
3133a8e1175bSopenharmony_ci                                          ssl_async_cancel,
3134a8e1175bSopenharmony_ci                                          &ssl_async_keys);
3135a8e1175bSopenharmony_ci    }
3136a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
3137a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
3138a8e1175bSopenharmony_ci
3139a8e1175bSopenharmony_ci#if defined(SNI_OPTION)
3140a8e1175bSopenharmony_ci    if (opt.sni != NULL) {
3141a8e1175bSopenharmony_ci        mbedtls_ssl_conf_sni(&conf, sni_callback, sni_info);
3142a8e1175bSopenharmony_ci        mbedtls_ssl_conf_cert_cb(&conf, cert_callback);
3143a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3144a8e1175bSopenharmony_ci        if (opt.async_private_delay2 >= 0) {
3145a8e1175bSopenharmony_ci            sni_entry *cur;
3146a8e1175bSopenharmony_ci            for (cur = sni_info; cur != NULL; cur = cur->next) {
3147a8e1175bSopenharmony_ci                ret = ssl_async_set_key(&ssl_async_keys,
3148a8e1175bSopenharmony_ci                                        cur->cert, cur->key, 1,
3149a8e1175bSopenharmony_ci                                        opt.async_private_delay2);
3150a8e1175bSopenharmony_ci                if (ret < 0) {
3151a8e1175bSopenharmony_ci                    mbedtls_printf("  Test error: ssl_async_set_key failed (%d)\n",
3152a8e1175bSopenharmony_ci                                   ret);
3153a8e1175bSopenharmony_ci                    goto exit;
3154a8e1175bSopenharmony_ci                }
3155a8e1175bSopenharmony_ci                cur->key = NULL;
3156a8e1175bSopenharmony_ci            }
3157a8e1175bSopenharmony_ci        }
3158a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
3159a8e1175bSopenharmony_ci    }
3160a8e1175bSopenharmony_ci#endif
3161a8e1175bSopenharmony_ci
3162a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_HAVE_ECC_KEYS) || \
3163a8e1175bSopenharmony_ci    (defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED) && \
3164a8e1175bSopenharmony_ci    defined(PSA_WANT_ALG_FFDH))
3165a8e1175bSopenharmony_ci    if (opt.groups != NULL &&
3166a8e1175bSopenharmony_ci        strcmp(opt.groups, "default") != 0) {
3167a8e1175bSopenharmony_ci        mbedtls_ssl_conf_groups(&conf, group_list);
3168a8e1175bSopenharmony_ci    }
3169a8e1175bSopenharmony_ci#endif
3170a8e1175bSopenharmony_ci
3171a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
3172a8e1175bSopenharmony_ci    if (opt.sig_algs != NULL) {
3173a8e1175bSopenharmony_ci        mbedtls_ssl_conf_sig_algs(&conf, sig_alg_list);
3174a8e1175bSopenharmony_ci    }
3175a8e1175bSopenharmony_ci#endif
3176a8e1175bSopenharmony_ci
3177a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
3178a8e1175bSopenharmony_ci
3179a8e1175bSopenharmony_ci    if (strlen(opt.psk) != 0 && strlen(opt.psk_identity) != 0) {
3180a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
3181a8e1175bSopenharmony_ci        if (opt.psk_opaque != 0) {
3182a8e1175bSopenharmony_ci            /* The algorithm has already been determined earlier. */
3183a8e1175bSopenharmony_ci            status = psa_setup_psk_key_slot(&psk_slot, alg, psk, psk_len);
3184a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
3185a8e1175bSopenharmony_ci                fprintf(stderr, "SETUP FAIL\n");
3186a8e1175bSopenharmony_ci                ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
3187a8e1175bSopenharmony_ci                goto exit;
3188a8e1175bSopenharmony_ci            }
3189a8e1175bSopenharmony_ci            if ((ret = mbedtls_ssl_conf_psk_opaque(&conf, psk_slot,
3190a8e1175bSopenharmony_ci                                                   (const unsigned char *) opt.psk_identity,
3191a8e1175bSopenharmony_ci                                                   strlen(opt.psk_identity))) != 0) {
3192a8e1175bSopenharmony_ci                mbedtls_printf(" failed\n  ! mbedtls_ssl_conf_psk_opaque returned %d\n\n",
3193a8e1175bSopenharmony_ci                               ret);
3194a8e1175bSopenharmony_ci                goto exit;
3195a8e1175bSopenharmony_ci            }
3196a8e1175bSopenharmony_ci        } else
3197a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
3198a8e1175bSopenharmony_ci        if (psk_len > 0) {
3199a8e1175bSopenharmony_ci            ret = mbedtls_ssl_conf_psk(&conf, psk, psk_len,
3200a8e1175bSopenharmony_ci                                       (const unsigned char *) opt.psk_identity,
3201a8e1175bSopenharmony_ci                                       strlen(opt.psk_identity));
3202a8e1175bSopenharmony_ci            if (ret != 0) {
3203a8e1175bSopenharmony_ci                mbedtls_printf("  failed\n  mbedtls_ssl_conf_psk returned -0x%04X\n\n",
3204a8e1175bSopenharmony_ci                               (unsigned int) -ret);
3205a8e1175bSopenharmony_ci                goto exit;
3206a8e1175bSopenharmony_ci            }
3207a8e1175bSopenharmony_ci        }
3208a8e1175bSopenharmony_ci    }
3209a8e1175bSopenharmony_ci
3210a8e1175bSopenharmony_ci    if (opt.psk_list != NULL) {
3211a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
3212a8e1175bSopenharmony_ci        if (opt.psk_list_opaque != 0) {
3213a8e1175bSopenharmony_ci            psk_entry *cur_psk;
3214a8e1175bSopenharmony_ci            for (cur_psk = psk_info; cur_psk != NULL; cur_psk = cur_psk->next) {
3215a8e1175bSopenharmony_ci
3216a8e1175bSopenharmony_ci                status = psa_setup_psk_key_slot(&cur_psk->slot, alg,
3217a8e1175bSopenharmony_ci                                                cur_psk->key,
3218a8e1175bSopenharmony_ci                                                cur_psk->key_len);
3219a8e1175bSopenharmony_ci                if (status != PSA_SUCCESS) {
3220a8e1175bSopenharmony_ci                    ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
3221a8e1175bSopenharmony_ci                    goto exit;
3222a8e1175bSopenharmony_ci                }
3223a8e1175bSopenharmony_ci            }
3224a8e1175bSopenharmony_ci        }
3225a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */
3226a8e1175bSopenharmony_ci
3227a8e1175bSopenharmony_ci        mbedtls_ssl_conf_psk_cb(&conf, psk_callback, psk_info);
3228a8e1175bSopenharmony_ci    }
3229a8e1175bSopenharmony_ci#endif
3230a8e1175bSopenharmony_ci
3231a8e1175bSopenharmony_ci#if defined(MBEDTLS_DHM_C)
3232a8e1175bSopenharmony_ci    /*
3233a8e1175bSopenharmony_ci     * Use different group than default DHM group
3234a8e1175bSopenharmony_ci     */
3235a8e1175bSopenharmony_ci#if defined(MBEDTLS_FS_IO)
3236a8e1175bSopenharmony_ci    if (opt.dhm_file != NULL) {
3237a8e1175bSopenharmony_ci        ret = mbedtls_ssl_conf_dh_param_ctx(&conf, &dhm);
3238a8e1175bSopenharmony_ci    }
3239a8e1175bSopenharmony_ci#endif
3240a8e1175bSopenharmony_ci    if (ret != 0) {
3241a8e1175bSopenharmony_ci        mbedtls_printf("  failed\n  mbedtls_ssl_conf_dh_param returned -0x%04X\n\n",
3242a8e1175bSopenharmony_ci                       (unsigned int) -ret);
3243a8e1175bSopenharmony_ci        goto exit;
3244a8e1175bSopenharmony_ci    }
3245a8e1175bSopenharmony_ci#endif
3246a8e1175bSopenharmony_ci
3247a8e1175bSopenharmony_ci    if (opt.min_version != DFL_MIN_VERSION) {
3248a8e1175bSopenharmony_ci        mbedtls_ssl_conf_min_tls_version(&conf, opt.min_version);
3249a8e1175bSopenharmony_ci    }
3250a8e1175bSopenharmony_ci
3251a8e1175bSopenharmony_ci    if (opt.max_version != DFL_MIN_VERSION) {
3252a8e1175bSopenharmony_ci        mbedtls_ssl_conf_max_tls_version(&conf, opt.max_version);
3253a8e1175bSopenharmony_ci    }
3254a8e1175bSopenharmony_ci
3255a8e1175bSopenharmony_ci    if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
3256a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n", (unsigned int) -ret);
3257a8e1175bSopenharmony_ci        goto exit;
3258a8e1175bSopenharmony_ci    }
3259a8e1175bSopenharmony_ci
3260a8e1175bSopenharmony_ci    if (opt.eap_tls != 0) {
3261a8e1175bSopenharmony_ci        mbedtls_ssl_set_export_keys_cb(&ssl, eap_tls_key_derivation,
3262a8e1175bSopenharmony_ci                                       &eap_tls_keying);
3263a8e1175bSopenharmony_ci    } else if (opt.nss_keylog != 0) {
3264a8e1175bSopenharmony_ci        mbedtls_ssl_set_export_keys_cb(&ssl,
3265a8e1175bSopenharmony_ci                                       nss_keylog_export,
3266a8e1175bSopenharmony_ci                                       NULL);
3267a8e1175bSopenharmony_ci    }
3268a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP)
3269a8e1175bSopenharmony_ci    else if (opt.use_srtp != 0) {
3270a8e1175bSopenharmony_ci        mbedtls_ssl_set_export_keys_cb(&ssl, dtls_srtp_key_derivation,
3271a8e1175bSopenharmony_ci                                       &dtls_srtp_keying);
3272a8e1175bSopenharmony_ci    }
3273a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_SRTP */
3274a8e1175bSopenharmony_ci
3275a8e1175bSopenharmony_ci    io_ctx.ssl = &ssl;
3276a8e1175bSopenharmony_ci    io_ctx.net = &client_fd;
3277a8e1175bSopenharmony_ci    mbedtls_ssl_set_bio(&ssl, &io_ctx, send_cb, recv_cb,
3278a8e1175bSopenharmony_ci                        opt.nbio == 0 ? recv_timeout_cb : NULL);
3279a8e1175bSopenharmony_ci
3280a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3281a8e1175bSopenharmony_ci    if (opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3282a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_set_cid(&ssl, opt.cid_enabled,
3283a8e1175bSopenharmony_ci                                       cid, cid_len)) != 0) {
3284a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_set_cid returned %d\n\n",
3285a8e1175bSopenharmony_ci                           ret);
3286a8e1175bSopenharmony_ci            goto exit;
3287a8e1175bSopenharmony_ci        }
3288a8e1175bSopenharmony_ci    }
3289a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3290a8e1175bSopenharmony_ci
3291a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS)
3292a8e1175bSopenharmony_ci    if (opt.dtls_mtu != DFL_DTLS_MTU) {
3293a8e1175bSopenharmony_ci        mbedtls_ssl_set_mtu(&ssl, opt.dtls_mtu);
3294a8e1175bSopenharmony_ci    }
3295a8e1175bSopenharmony_ci#endif
3296a8e1175bSopenharmony_ci
3297a8e1175bSopenharmony_ci#if defined(MBEDTLS_TIMING_C)
3298a8e1175bSopenharmony_ci    mbedtls_ssl_set_timer_cb(&ssl, &timer, mbedtls_timing_set_delay,
3299a8e1175bSopenharmony_ci                             mbedtls_timing_get_delay);
3300a8e1175bSopenharmony_ci#endif
3301a8e1175bSopenharmony_ci
3302a8e1175bSopenharmony_ci    mbedtls_printf(" ok\n");
3303a8e1175bSopenharmony_ci
3304a8e1175bSopenharmony_ci    /*
3305a8e1175bSopenharmony_ci     * 3. Setup the listening TCP socket
3306a8e1175bSopenharmony_ci     */
3307a8e1175bSopenharmony_ci    mbedtls_printf("  . Bind on %s://%s:%s/ ...",
3308a8e1175bSopenharmony_ci                   opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ? "tcp" : "udp",
3309a8e1175bSopenharmony_ci                   opt.server_addr ? opt.server_addr : "*",
3310a8e1175bSopenharmony_ci                   opt.server_port);
3311a8e1175bSopenharmony_ci    fflush(stdout);
3312a8e1175bSopenharmony_ci
3313a8e1175bSopenharmony_ci    if ((ret = mbedtls_net_bind(&listen_fd, opt.server_addr, opt.server_port,
3314a8e1175bSopenharmony_ci                                opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM ?
3315a8e1175bSopenharmony_ci                                MBEDTLS_NET_PROTO_TCP : MBEDTLS_NET_PROTO_UDP)) != 0) {
3316a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  ! mbedtls_net_bind returned -0x%x\n\n", (unsigned int) -ret);
3317a8e1175bSopenharmony_ci        goto exit;
3318a8e1175bSopenharmony_ci    }
3319a8e1175bSopenharmony_ci    mbedtls_printf(" ok\n");
3320a8e1175bSopenharmony_ci
3321a8e1175bSopenharmony_cireset:
3322a8e1175bSopenharmony_ci#if !defined(_WIN32)
3323a8e1175bSopenharmony_ci    if (received_sigterm) {
3324a8e1175bSopenharmony_ci        mbedtls_printf(" interrupted by SIGTERM (not in net_accept())\n");
3325a8e1175bSopenharmony_ci        if (ret == MBEDTLS_ERR_NET_INVALID_CONTEXT) {
3326a8e1175bSopenharmony_ci            ret = 0;
3327a8e1175bSopenharmony_ci        }
3328a8e1175bSopenharmony_ci
3329a8e1175bSopenharmony_ci        goto exit;
3330a8e1175bSopenharmony_ci    }
3331a8e1175bSopenharmony_ci#endif
3332a8e1175bSopenharmony_ci
3333a8e1175bSopenharmony_ci    if (ret == MBEDTLS_ERR_SSL_CLIENT_RECONNECT) {
3334a8e1175bSopenharmony_ci        mbedtls_printf("  ! Client initiated reconnection from same port\n");
3335a8e1175bSopenharmony_ci        goto handshake;
3336a8e1175bSopenharmony_ci    }
3337a8e1175bSopenharmony_ci
3338a8e1175bSopenharmony_ci#ifdef MBEDTLS_ERROR_C
3339a8e1175bSopenharmony_ci    if (ret != 0) {
3340a8e1175bSopenharmony_ci        char error_buf[100];
3341a8e1175bSopenharmony_ci        mbedtls_strerror(ret, error_buf, 100);
3342a8e1175bSopenharmony_ci        mbedtls_printf("Last error was: %d - %s\n\n", ret, error_buf);
3343a8e1175bSopenharmony_ci    }
3344a8e1175bSopenharmony_ci#endif
3345a8e1175bSopenharmony_ci
3346a8e1175bSopenharmony_ci    mbedtls_net_free(&client_fd);
3347a8e1175bSopenharmony_ci
3348a8e1175bSopenharmony_ci    mbedtls_ssl_session_reset(&ssl);
3349a8e1175bSopenharmony_ci
3350a8e1175bSopenharmony_ci    /*
3351a8e1175bSopenharmony_ci     * 3. Wait until a client connects
3352a8e1175bSopenharmony_ci     */
3353a8e1175bSopenharmony_ci    mbedtls_printf("  . Waiting for a remote connection ...");
3354a8e1175bSopenharmony_ci    fflush(stdout);
3355a8e1175bSopenharmony_ci
3356a8e1175bSopenharmony_ci    if ((ret = mbedtls_net_accept(&listen_fd, &client_fd,
3357a8e1175bSopenharmony_ci                                  client_ip, sizeof(client_ip), &cliip_len)) != 0) {
3358a8e1175bSopenharmony_ci#if !defined(_WIN32)
3359a8e1175bSopenharmony_ci        if (received_sigterm) {
3360a8e1175bSopenharmony_ci            mbedtls_printf(" interrupted by SIGTERM (in net_accept())\n");
3361a8e1175bSopenharmony_ci            if (ret == MBEDTLS_ERR_NET_ACCEPT_FAILED) {
3362a8e1175bSopenharmony_ci                ret = 0;
3363a8e1175bSopenharmony_ci            }
3364a8e1175bSopenharmony_ci
3365a8e1175bSopenharmony_ci            goto exit;
3366a8e1175bSopenharmony_ci        }
3367a8e1175bSopenharmony_ci#endif
3368a8e1175bSopenharmony_ci
3369a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  ! mbedtls_net_accept returned -0x%x\n\n", (unsigned int) -ret);
3370a8e1175bSopenharmony_ci        goto exit;
3371a8e1175bSopenharmony_ci    }
3372a8e1175bSopenharmony_ci
3373a8e1175bSopenharmony_ci    if (opt.nbio > 0) {
3374a8e1175bSopenharmony_ci        ret = mbedtls_net_set_nonblock(&client_fd);
3375a8e1175bSopenharmony_ci    } else {
3376a8e1175bSopenharmony_ci        ret = mbedtls_net_set_block(&client_fd);
3377a8e1175bSopenharmony_ci    }
3378a8e1175bSopenharmony_ci    if (ret != 0) {
3379a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  ! net_set_(non)block() returned -0x%x\n\n", (unsigned int) -ret);
3380a8e1175bSopenharmony_ci        goto exit;
3381a8e1175bSopenharmony_ci    }
3382a8e1175bSopenharmony_ci
3383a8e1175bSopenharmony_ci    mbedtls_ssl_conf_read_timeout(&conf, opt.read_timeout);
3384a8e1175bSopenharmony_ci
3385a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
3386a8e1175bSopenharmony_ci    if (opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3387a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_set_client_transport_id(&ssl,
3388a8e1175bSopenharmony_ci                                                       client_ip, cliip_len)) != 0) {
3389a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_set_client_transport_id() returned -0x%x\n\n",
3390a8e1175bSopenharmony_ci                           (unsigned int) -ret);
3391a8e1175bSopenharmony_ci            goto exit;
3392a8e1175bSopenharmony_ci        }
3393a8e1175bSopenharmony_ci    }
3394a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
3395a8e1175bSopenharmony_ci
3396a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
3397a8e1175bSopenharmony_ci    if (opt.ecjpake_pw != DFL_ECJPAKE_PW) {
3398a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
3399a8e1175bSopenharmony_ci        if (opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE) {
3400a8e1175bSopenharmony_ci            psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
3401a8e1175bSopenharmony_ci
3402a8e1175bSopenharmony_ci            psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
3403a8e1175bSopenharmony_ci            psa_set_key_algorithm(&attributes, PSA_ALG_JPAKE);
3404a8e1175bSopenharmony_ci            psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD);
3405a8e1175bSopenharmony_ci
3406a8e1175bSopenharmony_ci            status = psa_import_key(&attributes,
3407a8e1175bSopenharmony_ci                                    (const unsigned char *) opt.ecjpake_pw,
3408a8e1175bSopenharmony_ci                                    strlen(opt.ecjpake_pw),
3409a8e1175bSopenharmony_ci                                    &ecjpake_pw_slot);
3410a8e1175bSopenharmony_ci            if (status != PSA_SUCCESS) {
3411a8e1175bSopenharmony_ci                mbedtls_printf(" failed\n  ! psa_import_key returned %d\n\n",
3412a8e1175bSopenharmony_ci                               status);
3413a8e1175bSopenharmony_ci                goto exit;
3414a8e1175bSopenharmony_ci            }
3415a8e1175bSopenharmony_ci            if ((ret = mbedtls_ssl_set_hs_ecjpake_password_opaque(&ssl,
3416a8e1175bSopenharmony_ci                                                                  ecjpake_pw_slot)) != 0) {
3417a8e1175bSopenharmony_ci                mbedtls_printf(
3418a8e1175bSopenharmony_ci                    " failed\n  ! mbedtls_ssl_set_hs_ecjpake_password_opaque returned %d\n\n",
3419a8e1175bSopenharmony_ci                    ret);
3420a8e1175bSopenharmony_ci                goto exit;
3421a8e1175bSopenharmony_ci            }
3422a8e1175bSopenharmony_ci            mbedtls_printf("using opaque password\n");
3423a8e1175bSopenharmony_ci        } else
3424a8e1175bSopenharmony_ci#endif  /* MBEDTLS_USE_PSA_CRYPTO */
3425a8e1175bSopenharmony_ci        {
3426a8e1175bSopenharmony_ci            if ((ret = mbedtls_ssl_set_hs_ecjpake_password(&ssl,
3427a8e1175bSopenharmony_ci                                                           (const unsigned char *) opt.ecjpake_pw,
3428a8e1175bSopenharmony_ci                                                           strlen(opt.ecjpake_pw))) != 0) {
3429a8e1175bSopenharmony_ci                mbedtls_printf(" failed\n  ! mbedtls_ssl_set_hs_ecjpake_password returned %d\n\n",
3430a8e1175bSopenharmony_ci                               ret);
3431a8e1175bSopenharmony_ci                goto exit;
3432a8e1175bSopenharmony_ci            }
3433a8e1175bSopenharmony_ci        }
3434a8e1175bSopenharmony_ci    }
3435a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
3436a8e1175bSopenharmony_ci
3437a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
3438a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
3439a8e1175bSopenharmony_ci    /* exercise setting DN hints for server certificate request
3440a8e1175bSopenharmony_ci     * (Intended for use where the client cert expected has been signed by
3441a8e1175bSopenharmony_ci     *  a specific CA which is an intermediate in a CA chain, not the root)
3442a8e1175bSopenharmony_ci     * (Additionally, the CA choice would typically be influenced by SNI
3443a8e1175bSopenharmony_ci     *  if being set per-handshake using mbedtls_ssl_set_hs_dn_hints()) */
3444a8e1175bSopenharmony_ci    if (opt.cert_req_dn_hint == 3 && key_cert_init2) {
3445a8e1175bSopenharmony_ci        mbedtls_ssl_set_hs_dn_hints(&ssl, &srvcert2);
3446a8e1175bSopenharmony_ci    }
3447a8e1175bSopenharmony_ci#endif
3448a8e1175bSopenharmony_ci#endif
3449a8e1175bSopenharmony_ci
3450a8e1175bSopenharmony_ci    mbedtls_printf(" ok\n");
3451a8e1175bSopenharmony_ci
3452a8e1175bSopenharmony_ci    /*
3453a8e1175bSopenharmony_ci     * 4. Handshake
3454a8e1175bSopenharmony_ci     */
3455a8e1175bSopenharmony_cihandshake:
3456a8e1175bSopenharmony_ci    mbedtls_printf("  . Performing the SSL/TLS handshake...");
3457a8e1175bSopenharmony_ci    fflush(stdout);
3458a8e1175bSopenharmony_ci
3459a8e1175bSopenharmony_ci    while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
3460a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
3461a8e1175bSopenharmony_ci        if (ret == MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA) {
3462a8e1175bSopenharmony_ci            memset(buf, 0, opt.buffer_size);
3463a8e1175bSopenharmony_ci            ret = mbedtls_ssl_read_early_data(&ssl, buf, opt.buffer_size);
3464a8e1175bSopenharmony_ci            if (ret > 0) {
3465a8e1175bSopenharmony_ci                buf[ret] = '\0';
3466a8e1175bSopenharmony_ci                mbedtls_printf(" %d early data bytes read\n\n%s\n",
3467a8e1175bSopenharmony_ci                               ret, (char *) buf);
3468a8e1175bSopenharmony_ci            }
3469a8e1175bSopenharmony_ci            continue;
3470a8e1175bSopenharmony_ci        }
3471a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
3472a8e1175bSopenharmony_ci
3473a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3474a8e1175bSopenharmony_ci        if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS &&
3475a8e1175bSopenharmony_ci            ssl_async_keys.inject_error == SSL_ASYNC_INJECT_ERROR_CANCEL) {
3476a8e1175bSopenharmony_ci            mbedtls_printf(" cancelling on injected error\n");
3477a8e1175bSopenharmony_ci            break;
3478a8e1175bSopenharmony_ci        }
3479a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
3480a8e1175bSopenharmony_ci
3481a8e1175bSopenharmony_ci        if (!mbedtls_status_is_ssl_in_progress(ret)) {
3482a8e1175bSopenharmony_ci            break;
3483a8e1175bSopenharmony_ci        }
3484a8e1175bSopenharmony_ci
3485a8e1175bSopenharmony_ci        /* For event-driven IO, wait for socket to become available */
3486a8e1175bSopenharmony_ci        if (opt.event == 1 /* level triggered IO */) {
3487a8e1175bSopenharmony_ci#if defined(MBEDTLS_TIMING_C)
3488a8e1175bSopenharmony_ci            ret = idle(&client_fd, &timer, ret);
3489a8e1175bSopenharmony_ci#else
3490a8e1175bSopenharmony_ci            ret = idle(&client_fd, ret);
3491a8e1175bSopenharmony_ci#endif
3492a8e1175bSopenharmony_ci            if (ret != 0) {
3493a8e1175bSopenharmony_ci                goto reset;
3494a8e1175bSopenharmony_ci            }
3495a8e1175bSopenharmony_ci        }
3496a8e1175bSopenharmony_ci    }
3497a8e1175bSopenharmony_ci
3498a8e1175bSopenharmony_ci    if (ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) {
3499a8e1175bSopenharmony_ci        mbedtls_printf(" hello verification requested\n");
3500a8e1175bSopenharmony_ci        ret = 0;
3501a8e1175bSopenharmony_ci        goto reset;
3502a8e1175bSopenharmony_ci    } else if (ret != 0) {
3503a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n",
3504a8e1175bSopenharmony_ci                       (unsigned int) -ret);
3505a8e1175bSopenharmony_ci
3506a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
3507a8e1175bSopenharmony_ci        if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
3508a8e1175bSopenharmony_ci            char vrfy_buf[512];
3509a8e1175bSopenharmony_ci            flags = mbedtls_ssl_get_verify_result(&ssl);
3510a8e1175bSopenharmony_ci
3511a8e1175bSopenharmony_ci            x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), "  ! ", flags);
3512a8e1175bSopenharmony_ci
3513a8e1175bSopenharmony_ci            mbedtls_printf("%s\n", vrfy_buf);
3514a8e1175bSopenharmony_ci        }
3515a8e1175bSopenharmony_ci#endif
3516a8e1175bSopenharmony_ci
3517a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3518a8e1175bSopenharmony_ci        if (opt.async_private_error < 0) {
3519a8e1175bSopenharmony_ci            /* Injected error only the first time round, to test reset */
3520a8e1175bSopenharmony_ci            ssl_async_keys.inject_error = SSL_ASYNC_INJECT_ERROR_NONE;
3521a8e1175bSopenharmony_ci        }
3522a8e1175bSopenharmony_ci#endif
3523a8e1175bSopenharmony_ci        goto reset;
3524a8e1175bSopenharmony_ci    } else { /* ret == 0 */
3525a8e1175bSopenharmony_ci        int suite_id = mbedtls_ssl_get_ciphersuite_id_from_ssl(&ssl);
3526a8e1175bSopenharmony_ci        const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
3527a8e1175bSopenharmony_ci        ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(suite_id);
3528a8e1175bSopenharmony_ci
3529a8e1175bSopenharmony_ci        mbedtls_printf(" ok\n    [ Protocol is %s ]\n"
3530a8e1175bSopenharmony_ci                       "    [ Ciphersuite is %s ]\n"
3531a8e1175bSopenharmony_ci                       "    [ Key size is %u ]\n",
3532a8e1175bSopenharmony_ci                       mbedtls_ssl_get_version(&ssl),
3533a8e1175bSopenharmony_ci                       mbedtls_ssl_ciphersuite_get_name(ciphersuite_info),
3534a8e1175bSopenharmony_ci                       (unsigned int)
3535a8e1175bSopenharmony_ci                       mbedtls_ssl_ciphersuite_get_cipher_key_bitlen(ciphersuite_info));
3536a8e1175bSopenharmony_ci    }
3537a8e1175bSopenharmony_ci
3538a8e1175bSopenharmony_ci    if ((ret = mbedtls_ssl_get_record_expansion(&ssl)) >= 0) {
3539a8e1175bSopenharmony_ci        mbedtls_printf("    [ Record expansion is %d ]\n", ret);
3540a8e1175bSopenharmony_ci    } else {
3541a8e1175bSopenharmony_ci        mbedtls_printf("    [ Record expansion is unknown ]\n");
3542a8e1175bSopenharmony_ci    }
3543a8e1175bSopenharmony_ci
3544a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) || defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
3545a8e1175bSopenharmony_ci    mbedtls_printf("    [ Maximum incoming record payload length is %u ]\n",
3546a8e1175bSopenharmony_ci                   (unsigned int) mbedtls_ssl_get_max_in_record_payload(&ssl));
3547a8e1175bSopenharmony_ci    mbedtls_printf("    [ Maximum outgoing record payload length is %u ]\n",
3548a8e1175bSopenharmony_ci                   (unsigned int) mbedtls_ssl_get_max_out_record_payload(&ssl));
3549a8e1175bSopenharmony_ci#endif
3550a8e1175bSopenharmony_ci
3551a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN)
3552a8e1175bSopenharmony_ci    if (opt.alpn_string != NULL) {
3553a8e1175bSopenharmony_ci        const char *alp = mbedtls_ssl_get_alpn_protocol(&ssl);
3554a8e1175bSopenharmony_ci        mbedtls_printf("    [ Application Layer Protocol is %s ]\n",
3555a8e1175bSopenharmony_ci                       alp ? alp : "(none)");
3556a8e1175bSopenharmony_ci    }
3557a8e1175bSopenharmony_ci#endif
3558a8e1175bSopenharmony_ci
3559a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
3560a8e1175bSopenharmony_ci    /*
3561a8e1175bSopenharmony_ci     * 5. Verify the client certificate
3562a8e1175bSopenharmony_ci     */
3563a8e1175bSopenharmony_ci    mbedtls_printf("  . Verifying peer X.509 certificate...");
3564a8e1175bSopenharmony_ci
3565a8e1175bSopenharmony_ci    if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) {
3566a8e1175bSopenharmony_ci        char vrfy_buf[512];
3567a8e1175bSopenharmony_ci
3568a8e1175bSopenharmony_ci        mbedtls_printf(" failed\n");
3569a8e1175bSopenharmony_ci
3570a8e1175bSopenharmony_ci        x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), "  ! ", flags);
3571a8e1175bSopenharmony_ci        mbedtls_printf("%s\n", vrfy_buf);
3572a8e1175bSopenharmony_ci    } else {
3573a8e1175bSopenharmony_ci        mbedtls_printf(" ok\n");
3574a8e1175bSopenharmony_ci    }
3575a8e1175bSopenharmony_ci
3576a8e1175bSopenharmony_ci#if !defined(MBEDTLS_X509_REMOVE_INFO)
3577a8e1175bSopenharmony_ci    if (mbedtls_ssl_get_peer_cert(&ssl) != NULL) {
3578a8e1175bSopenharmony_ci        char crt_buf[512];
3579a8e1175bSopenharmony_ci
3580a8e1175bSopenharmony_ci        mbedtls_printf("  . Peer certificate information    ...\n");
3581a8e1175bSopenharmony_ci        mbedtls_x509_crt_info(crt_buf, sizeof(crt_buf), "      ",
3582a8e1175bSopenharmony_ci                              mbedtls_ssl_get_peer_cert(&ssl));
3583a8e1175bSopenharmony_ci        mbedtls_printf("%s\n", crt_buf);
3584a8e1175bSopenharmony_ci    }
3585a8e1175bSopenharmony_ci#endif /* MBEDTLS_X509_REMOVE_INFO */
3586a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
3587a8e1175bSopenharmony_ci
3588a8e1175bSopenharmony_ci    if (opt.eap_tls != 0) {
3589a8e1175bSopenharmony_ci        size_t j = 0;
3590a8e1175bSopenharmony_ci
3591a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_tls_prf(eap_tls_keying.tls_prf_type,
3592a8e1175bSopenharmony_ci                                       eap_tls_keying.master_secret,
3593a8e1175bSopenharmony_ci                                       sizeof(eap_tls_keying.master_secret),
3594a8e1175bSopenharmony_ci                                       eap_tls_label,
3595a8e1175bSopenharmony_ci                                       eap_tls_keying.randbytes,
3596a8e1175bSopenharmony_ci                                       sizeof(eap_tls_keying.randbytes),
3597a8e1175bSopenharmony_ci                                       eap_tls_keymaterial,
3598a8e1175bSopenharmony_ci                                       sizeof(eap_tls_keymaterial)))
3599a8e1175bSopenharmony_ci            != 0) {
3600a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
3601a8e1175bSopenharmony_ci                           (unsigned int) -ret);
3602a8e1175bSopenharmony_ci            goto reset;
3603a8e1175bSopenharmony_ci        }
3604a8e1175bSopenharmony_ci
3605a8e1175bSopenharmony_ci        mbedtls_printf("    EAP-TLS key material is:");
3606a8e1175bSopenharmony_ci        for (j = 0; j < sizeof(eap_tls_keymaterial); j++) {
3607a8e1175bSopenharmony_ci            if (j % 8 == 0) {
3608a8e1175bSopenharmony_ci                mbedtls_printf("\n    ");
3609a8e1175bSopenharmony_ci            }
3610a8e1175bSopenharmony_ci            mbedtls_printf("%02x ", eap_tls_keymaterial[j]);
3611a8e1175bSopenharmony_ci        }
3612a8e1175bSopenharmony_ci        mbedtls_printf("\n");
3613a8e1175bSopenharmony_ci
3614a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_tls_prf(eap_tls_keying.tls_prf_type, NULL, 0,
3615a8e1175bSopenharmony_ci                                       eap_tls_label,
3616a8e1175bSopenharmony_ci                                       eap_tls_keying.randbytes,
3617a8e1175bSopenharmony_ci                                       sizeof(eap_tls_keying.randbytes),
3618a8e1175bSopenharmony_ci                                       eap_tls_iv,
3619a8e1175bSopenharmony_ci                                       sizeof(eap_tls_iv))) != 0) {
3620a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
3621a8e1175bSopenharmony_ci                           (unsigned int) -ret);
3622a8e1175bSopenharmony_ci            goto reset;
3623a8e1175bSopenharmony_ci        }
3624a8e1175bSopenharmony_ci
3625a8e1175bSopenharmony_ci        mbedtls_printf("    EAP-TLS IV is:");
3626a8e1175bSopenharmony_ci        for (j = 0; j < sizeof(eap_tls_iv); j++) {
3627a8e1175bSopenharmony_ci            if (j % 8 == 0) {
3628a8e1175bSopenharmony_ci                mbedtls_printf("\n    ");
3629a8e1175bSopenharmony_ci            }
3630a8e1175bSopenharmony_ci            mbedtls_printf("%02x ", eap_tls_iv[j]);
3631a8e1175bSopenharmony_ci        }
3632a8e1175bSopenharmony_ci        mbedtls_printf("\n");
3633a8e1175bSopenharmony_ci    }
3634a8e1175bSopenharmony_ci
3635a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP)
3636a8e1175bSopenharmony_ci    else if (opt.use_srtp != 0) {
3637a8e1175bSopenharmony_ci        size_t j = 0;
3638a8e1175bSopenharmony_ci        mbedtls_dtls_srtp_info dtls_srtp_negotiation_result;
3639a8e1175bSopenharmony_ci        mbedtls_ssl_get_dtls_srtp_negotiation_result(&ssl, &dtls_srtp_negotiation_result);
3640a8e1175bSopenharmony_ci
3641a8e1175bSopenharmony_ci        if (dtls_srtp_negotiation_result.chosen_dtls_srtp_profile
3642a8e1175bSopenharmony_ci            == MBEDTLS_TLS_SRTP_UNSET) {
3643a8e1175bSopenharmony_ci            mbedtls_printf("    Unable to negotiate "
3644a8e1175bSopenharmony_ci                           "the use of DTLS-SRTP\n");
3645a8e1175bSopenharmony_ci        } else {
3646a8e1175bSopenharmony_ci            if ((ret = mbedtls_ssl_tls_prf(dtls_srtp_keying.tls_prf_type,
3647a8e1175bSopenharmony_ci                                           dtls_srtp_keying.master_secret,
3648a8e1175bSopenharmony_ci                                           sizeof(dtls_srtp_keying.master_secret),
3649a8e1175bSopenharmony_ci                                           dtls_srtp_label,
3650a8e1175bSopenharmony_ci                                           dtls_srtp_keying.randbytes,
3651a8e1175bSopenharmony_ci                                           sizeof(dtls_srtp_keying.randbytes),
3652a8e1175bSopenharmony_ci                                           dtls_srtp_key_material,
3653a8e1175bSopenharmony_ci                                           sizeof(dtls_srtp_key_material)))
3654a8e1175bSopenharmony_ci                != 0) {
3655a8e1175bSopenharmony_ci                mbedtls_printf(" failed\n  ! mbedtls_ssl_tls_prf returned -0x%x\n\n",
3656a8e1175bSopenharmony_ci                               (unsigned int) -ret);
3657a8e1175bSopenharmony_ci                goto exit;
3658a8e1175bSopenharmony_ci            }
3659a8e1175bSopenharmony_ci
3660a8e1175bSopenharmony_ci            mbedtls_printf("    DTLS-SRTP key material is:");
3661a8e1175bSopenharmony_ci            for (j = 0; j < sizeof(dtls_srtp_key_material); j++) {
3662a8e1175bSopenharmony_ci                if (j % 8 == 0) {
3663a8e1175bSopenharmony_ci                    mbedtls_printf("\n    ");
3664a8e1175bSopenharmony_ci                }
3665a8e1175bSopenharmony_ci                mbedtls_printf("%02x ", dtls_srtp_key_material[j]);
3666a8e1175bSopenharmony_ci            }
3667a8e1175bSopenharmony_ci            mbedtls_printf("\n");
3668a8e1175bSopenharmony_ci
3669a8e1175bSopenharmony_ci            /* produce a less readable output used to perform automatic checks
3670a8e1175bSopenharmony_ci             * - compare client and server output
3671a8e1175bSopenharmony_ci             * - interop test with openssl which client produces this kind of output
3672a8e1175bSopenharmony_ci             */
3673a8e1175bSopenharmony_ci            mbedtls_printf("    Keying material: ");
3674a8e1175bSopenharmony_ci            for (j = 0; j < sizeof(dtls_srtp_key_material); j++) {
3675a8e1175bSopenharmony_ci                mbedtls_printf("%02X", dtls_srtp_key_material[j]);
3676a8e1175bSopenharmony_ci            }
3677a8e1175bSopenharmony_ci            mbedtls_printf("\n");
3678a8e1175bSopenharmony_ci
3679a8e1175bSopenharmony_ci            if (dtls_srtp_negotiation_result.mki_len > 0) {
3680a8e1175bSopenharmony_ci                mbedtls_printf("    DTLS-SRTP mki value: ");
3681a8e1175bSopenharmony_ci                for (j = 0; j < dtls_srtp_negotiation_result.mki_len; j++) {
3682a8e1175bSopenharmony_ci                    mbedtls_printf("%02X", dtls_srtp_negotiation_result.mki_value[j]);
3683a8e1175bSopenharmony_ci                }
3684a8e1175bSopenharmony_ci            } else {
3685a8e1175bSopenharmony_ci                mbedtls_printf("    DTLS-SRTP no mki value negotiated");
3686a8e1175bSopenharmony_ci            }
3687a8e1175bSopenharmony_ci            mbedtls_printf("\n");
3688a8e1175bSopenharmony_ci
3689a8e1175bSopenharmony_ci        }
3690a8e1175bSopenharmony_ci    }
3691a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_SRTP */
3692a8e1175bSopenharmony_ci
3693a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3694a8e1175bSopenharmony_ci    ret = report_cid_usage(&ssl, "initial handshake");
3695a8e1175bSopenharmony_ci    if (ret != 0) {
3696a8e1175bSopenharmony_ci        goto exit;
3697a8e1175bSopenharmony_ci    }
3698a8e1175bSopenharmony_ci
3699a8e1175bSopenharmony_ci    if (opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3700a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_set_cid(&ssl, opt.cid_enabled_renego,
3701a8e1175bSopenharmony_ci                                       cid_renego, cid_renego_len)) != 0) {
3702a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_set_cid returned %d\n\n",
3703a8e1175bSopenharmony_ci                           ret);
3704a8e1175bSopenharmony_ci            goto exit;
3705a8e1175bSopenharmony_ci        }
3706a8e1175bSopenharmony_ci    }
3707a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3708a8e1175bSopenharmony_ci
3709a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG)
3710a8e1175bSopenharmony_ci    mbedtls_memory_buffer_alloc_cur_get(&current_heap_memory, &heap_blocks);
3711a8e1175bSopenharmony_ci    mbedtls_memory_buffer_alloc_max_get(&peak_heap_memory, &heap_blocks);
3712a8e1175bSopenharmony_ci    mbedtls_printf("Heap memory usage after handshake: %lu bytes. Peak memory usage was %lu\n",
3713a8e1175bSopenharmony_ci                   (unsigned long) current_heap_memory, (unsigned long) peak_heap_memory);
3714a8e1175bSopenharmony_ci#endif  /* MBEDTLS_MEMORY_DEBUG */
3715a8e1175bSopenharmony_ci
3716a8e1175bSopenharmony_ci    if (opt.exchanges == 0) {
3717a8e1175bSopenharmony_ci        goto close_notify;
3718a8e1175bSopenharmony_ci    }
3719a8e1175bSopenharmony_ci
3720a8e1175bSopenharmony_ci    exchanges_left = opt.exchanges;
3721a8e1175bSopenharmony_cidata_exchange:
3722a8e1175bSopenharmony_ci    /*
3723a8e1175bSopenharmony_ci     * 6. Read the HTTP Request
3724a8e1175bSopenharmony_ci     */
3725a8e1175bSopenharmony_ci    mbedtls_printf("  < Read from client:");
3726a8e1175bSopenharmony_ci    fflush(stdout);
3727a8e1175bSopenharmony_ci
3728a8e1175bSopenharmony_ci    /*
3729a8e1175bSopenharmony_ci     * TLS and DTLS need different reading styles (stream vs datagram)
3730a8e1175bSopenharmony_ci     */
3731a8e1175bSopenharmony_ci    if (opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM) {
3732a8e1175bSopenharmony_ci        do {
3733a8e1175bSopenharmony_ci            int terminated = 0;
3734a8e1175bSopenharmony_ci            len = opt.buffer_size;
3735a8e1175bSopenharmony_ci            memset(buf, 0, opt.buffer_size);
3736a8e1175bSopenharmony_ci            ret = mbedtls_ssl_read(&ssl, buf, len);
3737a8e1175bSopenharmony_ci
3738a8e1175bSopenharmony_ci            if (mbedtls_status_is_ssl_in_progress(ret)) {
3739a8e1175bSopenharmony_ci                if (opt.event == 1 /* level triggered IO */) {
3740a8e1175bSopenharmony_ci#if defined(MBEDTLS_TIMING_C)
3741a8e1175bSopenharmony_ci                    idle(&client_fd, &timer, ret);
3742a8e1175bSopenharmony_ci#else
3743a8e1175bSopenharmony_ci                    idle(&client_fd, ret);
3744a8e1175bSopenharmony_ci#endif
3745a8e1175bSopenharmony_ci                }
3746a8e1175bSopenharmony_ci
3747a8e1175bSopenharmony_ci                continue;
3748a8e1175bSopenharmony_ci            }
3749a8e1175bSopenharmony_ci
3750a8e1175bSopenharmony_ci            if (ret <= 0) {
3751a8e1175bSopenharmony_ci                switch (ret) {
3752a8e1175bSopenharmony_ci                    case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
3753a8e1175bSopenharmony_ci                        mbedtls_printf(" connection was closed gracefully\n");
3754a8e1175bSopenharmony_ci                        goto close_notify;
3755a8e1175bSopenharmony_ci
3756a8e1175bSopenharmony_ci                    case 0:
3757a8e1175bSopenharmony_ci                    case MBEDTLS_ERR_NET_CONN_RESET:
3758a8e1175bSopenharmony_ci                        mbedtls_printf(" connection was reset by peer\n");
3759a8e1175bSopenharmony_ci                        ret = MBEDTLS_ERR_NET_CONN_RESET;
3760a8e1175bSopenharmony_ci                        goto reset;
3761a8e1175bSopenharmony_ci
3762a8e1175bSopenharmony_ci                    default:
3763a8e1175bSopenharmony_ci                        mbedtls_printf(" mbedtls_ssl_read returned -0x%x\n", (unsigned int) -ret);
3764a8e1175bSopenharmony_ci                        goto reset;
3765a8e1175bSopenharmony_ci                }
3766a8e1175bSopenharmony_ci            }
3767a8e1175bSopenharmony_ci
3768a8e1175bSopenharmony_ci            if (mbedtls_ssl_get_bytes_avail(&ssl) == 0) {
3769a8e1175bSopenharmony_ci                len = ret;
3770a8e1175bSopenharmony_ci                buf[len] = '\0';
3771a8e1175bSopenharmony_ci                mbedtls_printf(" %d bytes read\n\n%s\n", len, (char *) buf);
3772a8e1175bSopenharmony_ci
3773a8e1175bSopenharmony_ci                /* End of message should be detected according to the syntax of the
3774a8e1175bSopenharmony_ci                 * application protocol (eg HTTP), just use a dummy test here. */
3775a8e1175bSopenharmony_ci                if (buf[len - 1] == '\n') {
3776a8e1175bSopenharmony_ci                    terminated = 1;
3777a8e1175bSopenharmony_ci                }
3778a8e1175bSopenharmony_ci            } else {
3779a8e1175bSopenharmony_ci                int extra_len, ori_len;
3780a8e1175bSopenharmony_ci                unsigned char *larger_buf;
3781a8e1175bSopenharmony_ci
3782a8e1175bSopenharmony_ci                ori_len = ret;
3783a8e1175bSopenharmony_ci                extra_len = (int) mbedtls_ssl_get_bytes_avail(&ssl);
3784a8e1175bSopenharmony_ci
3785a8e1175bSopenharmony_ci                larger_buf = mbedtls_calloc(1, ori_len + extra_len + 1);
3786a8e1175bSopenharmony_ci                if (larger_buf == NULL) {
3787a8e1175bSopenharmony_ci                    mbedtls_printf("  ! memory allocation failed\n");
3788a8e1175bSopenharmony_ci                    ret = 1;
3789a8e1175bSopenharmony_ci                    goto reset;
3790a8e1175bSopenharmony_ci                }
3791a8e1175bSopenharmony_ci
3792a8e1175bSopenharmony_ci                memset(larger_buf, 0, ori_len + extra_len);
3793a8e1175bSopenharmony_ci                memcpy(larger_buf, buf, ori_len);
3794a8e1175bSopenharmony_ci
3795a8e1175bSopenharmony_ci                /* This read should never fail and get the whole cached data */
3796a8e1175bSopenharmony_ci                ret = mbedtls_ssl_read(&ssl, larger_buf + ori_len, extra_len);
3797a8e1175bSopenharmony_ci                if (ret != extra_len ||
3798a8e1175bSopenharmony_ci                    mbedtls_ssl_get_bytes_avail(&ssl) != 0) {
3799a8e1175bSopenharmony_ci                    mbedtls_printf("  ! mbedtls_ssl_read failed on cached data\n");
3800a8e1175bSopenharmony_ci                    ret = 1;
3801a8e1175bSopenharmony_ci                    goto reset;
3802a8e1175bSopenharmony_ci                }
3803a8e1175bSopenharmony_ci
3804a8e1175bSopenharmony_ci                larger_buf[ori_len + extra_len] = '\0';
3805a8e1175bSopenharmony_ci                mbedtls_printf(" %d bytes read (%d + %d)\n\n%s\n",
3806a8e1175bSopenharmony_ci                               ori_len + extra_len, ori_len, extra_len,
3807a8e1175bSopenharmony_ci                               (char *) larger_buf);
3808a8e1175bSopenharmony_ci
3809a8e1175bSopenharmony_ci                /* End of message should be detected according to the syntax of the
3810a8e1175bSopenharmony_ci                 * application protocol (eg HTTP), just use a dummy test here. */
3811a8e1175bSopenharmony_ci                if (larger_buf[ori_len + extra_len - 1] == '\n') {
3812a8e1175bSopenharmony_ci                    terminated = 1;
3813a8e1175bSopenharmony_ci                }
3814a8e1175bSopenharmony_ci
3815a8e1175bSopenharmony_ci                mbedtls_free(larger_buf);
3816a8e1175bSopenharmony_ci            }
3817a8e1175bSopenharmony_ci
3818a8e1175bSopenharmony_ci            if (terminated) {
3819a8e1175bSopenharmony_ci                ret = 0;
3820a8e1175bSopenharmony_ci                break;
3821a8e1175bSopenharmony_ci            }
3822a8e1175bSopenharmony_ci        } while (1);
3823a8e1175bSopenharmony_ci    } else { /* Not stream, so datagram */
3824a8e1175bSopenharmony_ci        len = opt.buffer_size;
3825a8e1175bSopenharmony_ci        memset(buf, 0, opt.buffer_size);
3826a8e1175bSopenharmony_ci
3827a8e1175bSopenharmony_ci        do {
3828a8e1175bSopenharmony_ci            /* Without the call to `mbedtls_ssl_check_pending`, it might
3829a8e1175bSopenharmony_ci             * happen that the client sends application data in the same
3830a8e1175bSopenharmony_ci             * datagram as the Finished message concluding the handshake.
3831a8e1175bSopenharmony_ci             * In this case, the application data would be ready to be
3832a8e1175bSopenharmony_ci             * processed while the underlying transport wouldn't signal
3833a8e1175bSopenharmony_ci             * any further incoming data.
3834a8e1175bSopenharmony_ci             *
3835a8e1175bSopenharmony_ci             * See the test 'Event-driven I/O: session-id resume, UDP packing'
3836a8e1175bSopenharmony_ci             * in tests/ssl-opt.sh.
3837a8e1175bSopenharmony_ci             */
3838a8e1175bSopenharmony_ci
3839a8e1175bSopenharmony_ci            /* For event-driven IO, wait for socket to become available */
3840a8e1175bSopenharmony_ci            if (mbedtls_ssl_check_pending(&ssl) == 0 &&
3841a8e1175bSopenharmony_ci                opt.event == 1 /* level triggered IO */) {
3842a8e1175bSopenharmony_ci#if defined(MBEDTLS_TIMING_C)
3843a8e1175bSopenharmony_ci                idle(&client_fd, &timer, MBEDTLS_ERR_SSL_WANT_READ);
3844a8e1175bSopenharmony_ci#else
3845a8e1175bSopenharmony_ci                idle(&client_fd, MBEDTLS_ERR_SSL_WANT_READ);
3846a8e1175bSopenharmony_ci#endif
3847a8e1175bSopenharmony_ci            }
3848a8e1175bSopenharmony_ci
3849a8e1175bSopenharmony_ci            ret = mbedtls_ssl_read(&ssl, buf, len);
3850a8e1175bSopenharmony_ci
3851a8e1175bSopenharmony_ci            /* Note that even if `mbedtls_ssl_check_pending` returns true,
3852a8e1175bSopenharmony_ci             * it can happen that the subsequent call to `mbedtls_ssl_read`
3853a8e1175bSopenharmony_ci             * returns `MBEDTLS_ERR_SSL_WANT_READ`, because the pending messages
3854a8e1175bSopenharmony_ci             * might be discarded (e.g. because they are retransmissions). */
3855a8e1175bSopenharmony_ci        } while (mbedtls_status_is_ssl_in_progress(ret));
3856a8e1175bSopenharmony_ci
3857a8e1175bSopenharmony_ci        if (ret <= 0) {
3858a8e1175bSopenharmony_ci            switch (ret) {
3859a8e1175bSopenharmony_ci                case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
3860a8e1175bSopenharmony_ci                    mbedtls_printf(" connection was closed gracefully\n");
3861a8e1175bSopenharmony_ci                    goto close_notify;
3862a8e1175bSopenharmony_ci
3863a8e1175bSopenharmony_ci                default:
3864a8e1175bSopenharmony_ci                    mbedtls_printf(" mbedtls_ssl_read returned -0x%x\n", (unsigned int) -ret);
3865a8e1175bSopenharmony_ci                    goto reset;
3866a8e1175bSopenharmony_ci            }
3867a8e1175bSopenharmony_ci        }
3868a8e1175bSopenharmony_ci
3869a8e1175bSopenharmony_ci        len = ret;
3870a8e1175bSopenharmony_ci        buf[len] = '\0';
3871a8e1175bSopenharmony_ci        mbedtls_printf(" %d bytes read\n\n%s", len, (char *) buf);
3872a8e1175bSopenharmony_ci        ret = 0;
3873a8e1175bSopenharmony_ci    }
3874a8e1175bSopenharmony_ci
3875a8e1175bSopenharmony_ci    /*
3876a8e1175bSopenharmony_ci     * 7a. Request renegotiation while client is waiting for input from us.
3877a8e1175bSopenharmony_ci     * (only on the first exchange, to be able to test retransmission)
3878a8e1175bSopenharmony_ci     */
3879a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION)
3880a8e1175bSopenharmony_ci    if (opt.renegotiate && exchanges_left == opt.exchanges) {
3881a8e1175bSopenharmony_ci        mbedtls_printf("  . Requestion renegotiation...");
3882a8e1175bSopenharmony_ci        fflush(stdout);
3883a8e1175bSopenharmony_ci
3884a8e1175bSopenharmony_ci        while ((ret = mbedtls_ssl_renegotiate(&ssl)) != 0) {
3885a8e1175bSopenharmony_ci            if (!mbedtls_status_is_ssl_in_progress(ret)) {
3886a8e1175bSopenharmony_ci                mbedtls_printf(" failed\n  ! mbedtls_ssl_renegotiate returned %d\n\n", ret);
3887a8e1175bSopenharmony_ci                goto reset;
3888a8e1175bSopenharmony_ci            }
3889a8e1175bSopenharmony_ci
3890a8e1175bSopenharmony_ci            /* For event-driven IO, wait for socket to become available */
3891a8e1175bSopenharmony_ci            if (opt.event == 1 /* level triggered IO */) {
3892a8e1175bSopenharmony_ci#if defined(MBEDTLS_TIMING_C)
3893a8e1175bSopenharmony_ci                idle(&client_fd, &timer, ret);
3894a8e1175bSopenharmony_ci#else
3895a8e1175bSopenharmony_ci                idle(&client_fd, ret);
3896a8e1175bSopenharmony_ci#endif
3897a8e1175bSopenharmony_ci            }
3898a8e1175bSopenharmony_ci        }
3899a8e1175bSopenharmony_ci
3900a8e1175bSopenharmony_ci        mbedtls_printf(" ok\n");
3901a8e1175bSopenharmony_ci    }
3902a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */
3903a8e1175bSopenharmony_ci
3904a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
3905a8e1175bSopenharmony_ci    ret = report_cid_usage(&ssl, "after renegotiation");
3906a8e1175bSopenharmony_ci    if (ret != 0) {
3907a8e1175bSopenharmony_ci        goto exit;
3908a8e1175bSopenharmony_ci    }
3909a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
3910a8e1175bSopenharmony_ci
3911a8e1175bSopenharmony_ci    /*
3912a8e1175bSopenharmony_ci     * 7. Write the 200 Response
3913a8e1175bSopenharmony_ci     */
3914a8e1175bSopenharmony_ci    mbedtls_printf("  > Write to client:");
3915a8e1175bSopenharmony_ci    fflush(stdout);
3916a8e1175bSopenharmony_ci
3917a8e1175bSopenharmony_ci    /* If the format of the response changes, make sure there is enough
3918a8e1175bSopenharmony_ci     * room in buf (buf_content_size calculation above). */
3919a8e1175bSopenharmony_ci    len = sprintf((char *) buf, HTTP_RESPONSE,
3920a8e1175bSopenharmony_ci                  mbedtls_ssl_get_ciphersuite(&ssl));
3921a8e1175bSopenharmony_ci
3922a8e1175bSopenharmony_ci    /* Add padding to the response to reach opt.response_size in length */
3923a8e1175bSopenharmony_ci    if (opt.response_size != DFL_RESPONSE_SIZE &&
3924a8e1175bSopenharmony_ci        len < opt.response_size) {
3925a8e1175bSopenharmony_ci        memset(buf + len, 'B', opt.response_size - len);
3926a8e1175bSopenharmony_ci        len += opt.response_size - len;
3927a8e1175bSopenharmony_ci    }
3928a8e1175bSopenharmony_ci
3929a8e1175bSopenharmony_ci    /* Truncate if response size is smaller than the "natural" size */
3930a8e1175bSopenharmony_ci    if (opt.response_size != DFL_RESPONSE_SIZE &&
3931a8e1175bSopenharmony_ci        len > opt.response_size) {
3932a8e1175bSopenharmony_ci        len = opt.response_size;
3933a8e1175bSopenharmony_ci
3934a8e1175bSopenharmony_ci        /* Still end with \r\n unless that's really not possible */
3935a8e1175bSopenharmony_ci        if (len >= 2) {
3936a8e1175bSopenharmony_ci            buf[len - 2] = '\r';
3937a8e1175bSopenharmony_ci        }
3938a8e1175bSopenharmony_ci        if (len >= 1) {
3939a8e1175bSopenharmony_ci            buf[len - 1] = '\n';
3940a8e1175bSopenharmony_ci        }
3941a8e1175bSopenharmony_ci    }
3942a8e1175bSopenharmony_ci
3943a8e1175bSopenharmony_ci    if (opt.transport == MBEDTLS_SSL_TRANSPORT_STREAM) {
3944a8e1175bSopenharmony_ci        for (written = 0, frags = 0; written < len; written += ret, frags++) {
3945a8e1175bSopenharmony_ci            while ((ret = mbedtls_ssl_write(&ssl, buf + written, len - written))
3946a8e1175bSopenharmony_ci                   <= 0) {
3947a8e1175bSopenharmony_ci                if (ret == MBEDTLS_ERR_NET_CONN_RESET) {
3948a8e1175bSopenharmony_ci                    mbedtls_printf(" failed\n  ! peer closed the connection\n\n");
3949a8e1175bSopenharmony_ci                    goto reset;
3950a8e1175bSopenharmony_ci                }
3951a8e1175bSopenharmony_ci
3952a8e1175bSopenharmony_ci                if (!mbedtls_status_is_ssl_in_progress(ret)) {
3953a8e1175bSopenharmony_ci                    mbedtls_printf(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret);
3954a8e1175bSopenharmony_ci                    goto reset;
3955a8e1175bSopenharmony_ci                }
3956a8e1175bSopenharmony_ci
3957a8e1175bSopenharmony_ci                /* For event-driven IO, wait for socket to become available */
3958a8e1175bSopenharmony_ci                if (opt.event == 1 /* level triggered IO */) {
3959a8e1175bSopenharmony_ci#if defined(MBEDTLS_TIMING_C)
3960a8e1175bSopenharmony_ci                    idle(&client_fd, &timer, ret);
3961a8e1175bSopenharmony_ci#else
3962a8e1175bSopenharmony_ci                    idle(&client_fd, ret);
3963a8e1175bSopenharmony_ci#endif
3964a8e1175bSopenharmony_ci                }
3965a8e1175bSopenharmony_ci            }
3966a8e1175bSopenharmony_ci        }
3967a8e1175bSopenharmony_ci    } else { /* Not stream, so datagram */
3968a8e1175bSopenharmony_ci        while (1) {
3969a8e1175bSopenharmony_ci            ret = mbedtls_ssl_write(&ssl, buf, len);
3970a8e1175bSopenharmony_ci
3971a8e1175bSopenharmony_ci            if (!mbedtls_status_is_ssl_in_progress(ret)) {
3972a8e1175bSopenharmony_ci                break;
3973a8e1175bSopenharmony_ci            }
3974a8e1175bSopenharmony_ci
3975a8e1175bSopenharmony_ci            /* For event-driven IO, wait for socket to become available */
3976a8e1175bSopenharmony_ci            if (opt.event == 1 /* level triggered IO */) {
3977a8e1175bSopenharmony_ci#if defined(MBEDTLS_TIMING_C)
3978a8e1175bSopenharmony_ci                idle(&client_fd, &timer, ret);
3979a8e1175bSopenharmony_ci#else
3980a8e1175bSopenharmony_ci                idle(&client_fd, ret);
3981a8e1175bSopenharmony_ci#endif
3982a8e1175bSopenharmony_ci            }
3983a8e1175bSopenharmony_ci        }
3984a8e1175bSopenharmony_ci
3985a8e1175bSopenharmony_ci        if (ret < 0) {
3986a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret);
3987a8e1175bSopenharmony_ci            goto reset;
3988a8e1175bSopenharmony_ci        }
3989a8e1175bSopenharmony_ci
3990a8e1175bSopenharmony_ci        frags = 1;
3991a8e1175bSopenharmony_ci        written = ret;
3992a8e1175bSopenharmony_ci    }
3993a8e1175bSopenharmony_ci
3994a8e1175bSopenharmony_ci    buf[written] = '\0';
3995a8e1175bSopenharmony_ci    mbedtls_printf(" %d bytes written in %d fragments\n\n%s\n", written, frags, (char *) buf);
3996a8e1175bSopenharmony_ci    ret = 0;
3997a8e1175bSopenharmony_ci
3998a8e1175bSopenharmony_ci    /*
3999a8e1175bSopenharmony_ci     * 7b. Simulate serialize/deserialize and go back to data exchange
4000a8e1175bSopenharmony_ci     */
4001a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
4002a8e1175bSopenharmony_ci    if (opt.serialize != 0) {
4003a8e1175bSopenharmony_ci        size_t buf_len;
4004a8e1175bSopenharmony_ci
4005a8e1175bSopenharmony_ci        mbedtls_printf("  . Serializing live connection...");
4006a8e1175bSopenharmony_ci
4007a8e1175bSopenharmony_ci        ret = mbedtls_ssl_context_save(&ssl, NULL, 0, &buf_len);
4008a8e1175bSopenharmony_ci        if (ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) {
4009a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_context_save returned "
4010a8e1175bSopenharmony_ci                           "-0x%x\n\n", (unsigned int) -ret);
4011a8e1175bSopenharmony_ci
4012a8e1175bSopenharmony_ci            goto exit;
4013a8e1175bSopenharmony_ci        }
4014a8e1175bSopenharmony_ci
4015a8e1175bSopenharmony_ci        if ((context_buf = mbedtls_calloc(1, buf_len)) == NULL) {
4016a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! Couldn't allocate buffer for "
4017a8e1175bSopenharmony_ci                           "serialized context");
4018a8e1175bSopenharmony_ci
4019a8e1175bSopenharmony_ci            goto exit;
4020a8e1175bSopenharmony_ci        }
4021a8e1175bSopenharmony_ci        context_buf_len = buf_len;
4022a8e1175bSopenharmony_ci
4023a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_context_save(&ssl, context_buf,
4024a8e1175bSopenharmony_ci                                            buf_len, &buf_len)) != 0) {
4025a8e1175bSopenharmony_ci            mbedtls_printf(" failed\n  ! mbedtls_ssl_context_save returned "
4026a8e1175bSopenharmony_ci                           "-0x%x\n\n", (unsigned int) -ret);
4027a8e1175bSopenharmony_ci
4028a8e1175bSopenharmony_ci            goto exit;
4029a8e1175bSopenharmony_ci        }
4030a8e1175bSopenharmony_ci
4031a8e1175bSopenharmony_ci        mbedtls_printf(" ok\n");
4032a8e1175bSopenharmony_ci
4033a8e1175bSopenharmony_ci        /* Save serialized context to the 'opt.context_file' as a base64 code */
4034a8e1175bSopenharmony_ci        if (0 < strlen(opt.context_file)) {
4035a8e1175bSopenharmony_ci            FILE *b64_file;
4036a8e1175bSopenharmony_ci            uint8_t *b64_buf;
4037a8e1175bSopenharmony_ci            size_t b64_len;
4038a8e1175bSopenharmony_ci
4039a8e1175bSopenharmony_ci            mbedtls_printf("  . Save serialized context to a file... ");
4040a8e1175bSopenharmony_ci
4041a8e1175bSopenharmony_ci            mbedtls_base64_encode(NULL, 0, &b64_len, context_buf, buf_len);
4042a8e1175bSopenharmony_ci
4043a8e1175bSopenharmony_ci            if ((b64_buf = mbedtls_calloc(1, b64_len)) == NULL) {
4044a8e1175bSopenharmony_ci                mbedtls_printf("failed\n  ! Couldn't allocate buffer for "
4045a8e1175bSopenharmony_ci                               "the base64 code\n");
4046a8e1175bSopenharmony_ci                goto exit;
4047a8e1175bSopenharmony_ci            }
4048a8e1175bSopenharmony_ci
4049a8e1175bSopenharmony_ci            if ((ret = mbedtls_base64_encode(b64_buf, b64_len, &b64_len,
4050a8e1175bSopenharmony_ci                                             context_buf, buf_len)) != 0) {
4051a8e1175bSopenharmony_ci                mbedtls_printf("failed\n  ! mbedtls_base64_encode returned "
4052a8e1175bSopenharmony_ci                               "-0x%x\n", (unsigned int) -ret);
4053a8e1175bSopenharmony_ci                mbedtls_free(b64_buf);
4054a8e1175bSopenharmony_ci                goto exit;
4055a8e1175bSopenharmony_ci            }
4056a8e1175bSopenharmony_ci
4057a8e1175bSopenharmony_ci            if ((b64_file = fopen(opt.context_file, "w")) == NULL) {
4058a8e1175bSopenharmony_ci                mbedtls_printf("failed\n  ! Cannot open '%s' for writing.\n",
4059a8e1175bSopenharmony_ci                               opt.context_file);
4060a8e1175bSopenharmony_ci                mbedtls_free(b64_buf);
4061a8e1175bSopenharmony_ci                goto exit;
4062a8e1175bSopenharmony_ci            }
4063a8e1175bSopenharmony_ci
4064a8e1175bSopenharmony_ci            if (b64_len != fwrite(b64_buf, 1, b64_len, b64_file)) {
4065a8e1175bSopenharmony_ci                mbedtls_printf("failed\n  ! fwrite(%ld bytes) failed\n",
4066a8e1175bSopenharmony_ci                               (long) b64_len);
4067a8e1175bSopenharmony_ci                mbedtls_free(b64_buf);
4068a8e1175bSopenharmony_ci                fclose(b64_file);
4069a8e1175bSopenharmony_ci                goto exit;
4070a8e1175bSopenharmony_ci            }
4071a8e1175bSopenharmony_ci
4072a8e1175bSopenharmony_ci            mbedtls_free(b64_buf);
4073a8e1175bSopenharmony_ci            fclose(b64_file);
4074a8e1175bSopenharmony_ci
4075a8e1175bSopenharmony_ci            mbedtls_printf("ok\n");
4076a8e1175bSopenharmony_ci        }
4077a8e1175bSopenharmony_ci
4078a8e1175bSopenharmony_ci        /*
4079a8e1175bSopenharmony_ci         * This simulates a workflow where you have a long-lived server
4080a8e1175bSopenharmony_ci         * instance, potentially with a pool of ssl_context objects, and you
4081a8e1175bSopenharmony_ci         * just want to re-use one while the connection is inactive: in that
4082a8e1175bSopenharmony_ci         * case you can just reset() it, and then it's ready to receive
4083a8e1175bSopenharmony_ci         * serialized data from another connection (or the same here).
4084a8e1175bSopenharmony_ci         */
4085a8e1175bSopenharmony_ci        if (opt.serialize == 1) {
4086a8e1175bSopenharmony_ci            /* nothing to do here, done by context_save() already */
4087a8e1175bSopenharmony_ci            mbedtls_printf("  . Context has been reset... ok\n");
4088a8e1175bSopenharmony_ci        }
4089a8e1175bSopenharmony_ci
4090a8e1175bSopenharmony_ci        /*
4091a8e1175bSopenharmony_ci         * This simulates a workflow where you have one server instance per
4092a8e1175bSopenharmony_ci         * connection, and want to release it entire when the connection is
4093a8e1175bSopenharmony_ci         * inactive, and spawn it again when needed again - this would happen
4094a8e1175bSopenharmony_ci         * between ssl_free() and ssl_init() below, together with any other
4095a8e1175bSopenharmony_ci         * teardown/startup code needed - for example, preparing the
4096a8e1175bSopenharmony_ci         * ssl_config again (see section 3 "setup stuff" in this file).
4097a8e1175bSopenharmony_ci         */
4098a8e1175bSopenharmony_ci        if (opt.serialize == 2) {
4099a8e1175bSopenharmony_ci            mbedtls_printf("  . Freeing and reinitializing context...");
4100a8e1175bSopenharmony_ci
4101a8e1175bSopenharmony_ci            mbedtls_ssl_free(&ssl);
4102a8e1175bSopenharmony_ci
4103a8e1175bSopenharmony_ci            mbedtls_ssl_init(&ssl);
4104a8e1175bSopenharmony_ci
4105a8e1175bSopenharmony_ci            if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
4106a8e1175bSopenharmony_ci                mbedtls_printf(" failed\n  ! mbedtls_ssl_setup returned "
4107a8e1175bSopenharmony_ci                               "-0x%x\n\n", (unsigned int) -ret);
4108a8e1175bSopenharmony_ci                goto exit;
4109a8e1175bSopenharmony_ci            }
4110a8e1175bSopenharmony_ci
4111a8e1175bSopenharmony_ci            /*
4112a8e1175bSopenharmony_ci             * This illustrates the minimum amount of things you need to set
4113a8e1175bSopenharmony_ci             * up, however you could set up much more if desired, for example
4114a8e1175bSopenharmony_ci             * if you want to share your set up code between the case of
4115a8e1175bSopenharmony_ci             * establishing a new connection and this case.
4116a8e1175bSopenharmony_ci             */
4117a8e1175bSopenharmony_ci            if (opt.nbio == 2) {
4118a8e1175bSopenharmony_ci                mbedtls_ssl_set_bio(&ssl, &client_fd, delayed_send,
4119a8e1175bSopenharmony_ci                                    delayed_recv, NULL);
4120a8e1175bSopenharmony_ci            } else {
4121a8e1175bSopenharmony_ci                mbedtls_ssl_set_bio(&ssl, &client_fd, mbedtls_net_send,
4122a8e1175bSopenharmony_ci                                    mbedtls_net_recv,
4123a8e1175bSopenharmony_ci                                    opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL);
4124a8e1175bSopenharmony_ci            }
4125a8e1175bSopenharmony_ci
4126a8e1175bSopenharmony_ci#if defined(MBEDTLS_TIMING_C)
4127a8e1175bSopenharmony_ci            mbedtls_ssl_set_timer_cb(&ssl, &timer,
4128a8e1175bSopenharmony_ci                                     mbedtls_timing_set_delay,
4129a8e1175bSopenharmony_ci                                     mbedtls_timing_get_delay);
4130a8e1175bSopenharmony_ci#endif /* MBEDTLS_TIMING_C */
4131a8e1175bSopenharmony_ci
4132a8e1175bSopenharmony_ci            mbedtls_printf(" ok\n");
4133a8e1175bSopenharmony_ci        }
4134a8e1175bSopenharmony_ci
4135a8e1175bSopenharmony_ci        mbedtls_printf("  . Deserializing connection...");
4136a8e1175bSopenharmony_ci
4137a8e1175bSopenharmony_ci        if ((ret = mbedtls_ssl_context_load(&ssl, context_buf,
4138a8e1175bSopenharmony_ci                                            buf_len)) != 0) {
4139a8e1175bSopenharmony_ci            mbedtls_printf("failed\n  ! mbedtls_ssl_context_load returned "
4140a8e1175bSopenharmony_ci                           "-0x%x\n\n", (unsigned int) -ret);
4141a8e1175bSopenharmony_ci
4142a8e1175bSopenharmony_ci            goto exit;
4143a8e1175bSopenharmony_ci        }
4144a8e1175bSopenharmony_ci
4145a8e1175bSopenharmony_ci        mbedtls_free(context_buf);
4146a8e1175bSopenharmony_ci        context_buf = NULL;
4147a8e1175bSopenharmony_ci        context_buf_len = 0;
4148a8e1175bSopenharmony_ci
4149a8e1175bSopenharmony_ci        mbedtls_printf(" ok\n");
4150a8e1175bSopenharmony_ci    }
4151a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
4152a8e1175bSopenharmony_ci
4153a8e1175bSopenharmony_ci    /*
4154a8e1175bSopenharmony_ci     * 7c. Continue doing data exchanges?
4155a8e1175bSopenharmony_ci     */
4156a8e1175bSopenharmony_ci    if (--exchanges_left > 0) {
4157a8e1175bSopenharmony_ci        goto data_exchange;
4158a8e1175bSopenharmony_ci    }
4159a8e1175bSopenharmony_ci
4160a8e1175bSopenharmony_ci    /*
4161a8e1175bSopenharmony_ci     * 8. Done, cleanly close the connection
4162a8e1175bSopenharmony_ci     */
4163a8e1175bSopenharmony_ciclose_notify:
4164a8e1175bSopenharmony_ci    mbedtls_printf("  . Closing the connection...");
4165a8e1175bSopenharmony_ci
4166a8e1175bSopenharmony_ci    /* No error checking, the connection might be closed already */
4167a8e1175bSopenharmony_ci    do {
4168a8e1175bSopenharmony_ci        ret = mbedtls_ssl_close_notify(&ssl);
4169a8e1175bSopenharmony_ci    } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
4170a8e1175bSopenharmony_ci    ret = 0;
4171a8e1175bSopenharmony_ci
4172a8e1175bSopenharmony_ci    mbedtls_printf(" done\n");
4173a8e1175bSopenharmony_ci
4174a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C)
4175a8e1175bSopenharmony_ci    if (opt.cache_remove > 0) {
4176a8e1175bSopenharmony_ci        mbedtls_ssl_cache_remove(&cache, ssl.session->id, ssl.session->id_len);
4177a8e1175bSopenharmony_ci    }
4178a8e1175bSopenharmony_ci#endif
4179a8e1175bSopenharmony_ci
4180a8e1175bSopenharmony_ci    goto reset;
4181a8e1175bSopenharmony_ci
4182a8e1175bSopenharmony_ci    /*
4183a8e1175bSopenharmony_ci     * Cleanup and exit
4184a8e1175bSopenharmony_ci     */
4185a8e1175bSopenharmony_ciexit:
4186a8e1175bSopenharmony_ci#ifdef MBEDTLS_ERROR_C
4187a8e1175bSopenharmony_ci    if (ret != 0) {
4188a8e1175bSopenharmony_ci        char error_buf[100];
4189a8e1175bSopenharmony_ci        mbedtls_strerror(ret, error_buf, 100);
4190a8e1175bSopenharmony_ci        mbedtls_printf("Last error was: -0x%X - %s\n\n", (unsigned int) -ret, error_buf);
4191a8e1175bSopenharmony_ci    }
4192a8e1175bSopenharmony_ci#endif
4193a8e1175bSopenharmony_ci
4194a8e1175bSopenharmony_ci    if (opt.query_config_mode == DFL_QUERY_CONFIG_MODE) {
4195a8e1175bSopenharmony_ci        mbedtls_printf("  . Cleaning up...");
4196a8e1175bSopenharmony_ci        fflush(stdout);
4197a8e1175bSopenharmony_ci    }
4198a8e1175bSopenharmony_ci
4199a8e1175bSopenharmony_ci    mbedtls_net_free(&client_fd);
4200a8e1175bSopenharmony_ci    mbedtls_net_free(&listen_fd);
4201a8e1175bSopenharmony_ci
4202a8e1175bSopenharmony_ci    mbedtls_ssl_free(&ssl);
4203a8e1175bSopenharmony_ci    mbedtls_ssl_config_free(&conf);
4204a8e1175bSopenharmony_ci
4205a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CACHE_C)
4206a8e1175bSopenharmony_ci    mbedtls_ssl_cache_free(&cache);
4207a8e1175bSopenharmony_ci#endif
4208a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_TICKET_C)
4209a8e1175bSopenharmony_ci    mbedtls_ssl_ticket_free(&ticket_ctx);
4210a8e1175bSopenharmony_ci#endif
4211a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_COOKIE_C)
4212a8e1175bSopenharmony_ci    mbedtls_ssl_cookie_free(&cookie_ctx);
4213a8e1175bSopenharmony_ci#endif
4214a8e1175bSopenharmony_ci
4215a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
4216a8e1175bSopenharmony_ci    if (context_buf != NULL) {
4217a8e1175bSopenharmony_ci        mbedtls_platform_zeroize(context_buf, context_buf_len);
4218a8e1175bSopenharmony_ci    }
4219a8e1175bSopenharmony_ci    mbedtls_free(context_buf);
4220a8e1175bSopenharmony_ci#endif
4221a8e1175bSopenharmony_ci
4222a8e1175bSopenharmony_ci#if defined(SNI_OPTION)
4223a8e1175bSopenharmony_ci    sni_free(sni_info);
4224a8e1175bSopenharmony_ci#endif
4225a8e1175bSopenharmony_ci
4226a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED)
4227a8e1175bSopenharmony_ci    ret = psk_free(psk_info);
4228a8e1175bSopenharmony_ci    if ((ret != 0) && (opt.query_config_mode == DFL_QUERY_CONFIG_MODE)) {
4229a8e1175bSopenharmony_ci        mbedtls_printf("Failed to list of opaque PSKs - error was %d\n", ret);
4230a8e1175bSopenharmony_ci    }
4231a8e1175bSopenharmony_ci#endif
4232a8e1175bSopenharmony_ci
4233a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
4234a8e1175bSopenharmony_ci    mbedtls_x509_crt_free(&cacert);
4235a8e1175bSopenharmony_ci    mbedtls_x509_crt_free(&srvcert);
4236a8e1175bSopenharmony_ci    mbedtls_pk_free(&pkey);
4237a8e1175bSopenharmony_ci    mbedtls_x509_crt_free(&srvcert2);
4238a8e1175bSopenharmony_ci    mbedtls_pk_free(&pkey2);
4239a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO)
4240a8e1175bSopenharmony_ci    psa_destroy_key(key_slot);
4241a8e1175bSopenharmony_ci    psa_destroy_key(key_slot2);
4242a8e1175bSopenharmony_ci#endif
4243a8e1175bSopenharmony_ci#endif
4244a8e1175bSopenharmony_ci
4245a8e1175bSopenharmony_ci#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
4246a8e1175bSopenharmony_ci    mbedtls_dhm_free(&dhm);
4247a8e1175bSopenharmony_ci#endif
4248a8e1175bSopenharmony_ci
4249a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
4250a8e1175bSopenharmony_ci    for (i = 0; (size_t) i < ssl_async_keys.slots_used; i++) {
4251a8e1175bSopenharmony_ci        if (ssl_async_keys.slots[i].pk_owned) {
4252a8e1175bSopenharmony_ci            mbedtls_pk_free(ssl_async_keys.slots[i].pk);
4253a8e1175bSopenharmony_ci            mbedtls_free(ssl_async_keys.slots[i].pk);
4254a8e1175bSopenharmony_ci            ssl_async_keys.slots[i].pk = NULL;
4255a8e1175bSopenharmony_ci        }
4256a8e1175bSopenharmony_ci    }
4257a8e1175bSopenharmony_ci#endif
4258a8e1175bSopenharmony_ci
4259a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED) && \
4260a8e1175bSopenharmony_ci    defined(MBEDTLS_USE_PSA_CRYPTO)
4261a8e1175bSopenharmony_ci    if (opt.psk_opaque != 0) {
4262a8e1175bSopenharmony_ci        /* This is ok even if the slot hasn't been
4263a8e1175bSopenharmony_ci         * initialized (we might have jumed here
4264a8e1175bSopenharmony_ci         * immediately because of bad cmd line params,
4265a8e1175bSopenharmony_ci         * for example). */
4266a8e1175bSopenharmony_ci        status = psa_destroy_key(psk_slot);
4267a8e1175bSopenharmony_ci        if ((status != PSA_SUCCESS) &&
4268a8e1175bSopenharmony_ci            (opt.query_config_mode == DFL_QUERY_CONFIG_MODE)) {
4269a8e1175bSopenharmony_ci            mbedtls_printf("Failed to destroy key slot %u - error was %d",
4270a8e1175bSopenharmony_ci                           (unsigned) MBEDTLS_SVC_KEY_ID_GET_KEY_ID(psk_slot),
4271a8e1175bSopenharmony_ci                           (int) status);
4272a8e1175bSopenharmony_ci        }
4273a8e1175bSopenharmony_ci    }
4274a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_PSK_ENABLED &&
4275a8e1175bSopenharmony_ci          MBEDTLS_USE_PSA_CRYPTO */
4276a8e1175bSopenharmony_ci
4277a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
4278a8e1175bSopenharmony_ci    defined(MBEDTLS_USE_PSA_CRYPTO)
4279a8e1175bSopenharmony_ci    /*
4280a8e1175bSopenharmony_ci     * In case opaque keys it's the user responsibility to keep the key valid
4281a8e1175bSopenharmony_ci     * for the duration of the handshake and destroy it at the end
4282a8e1175bSopenharmony_ci     */
4283a8e1175bSopenharmony_ci    if ((opt.ecjpake_pw_opaque != DFL_ECJPAKE_PW_OPAQUE)) {
4284a8e1175bSopenharmony_ci        psa_key_attributes_t check_attributes = PSA_KEY_ATTRIBUTES_INIT;
4285a8e1175bSopenharmony_ci
4286a8e1175bSopenharmony_ci        /* Verify that the key is still valid before destroying it */
4287a8e1175bSopenharmony_ci        if (psa_get_key_attributes(ecjpake_pw_slot, &check_attributes) !=
4288a8e1175bSopenharmony_ci            PSA_SUCCESS) {
4289a8e1175bSopenharmony_ci            if (ret == 0) {
4290a8e1175bSopenharmony_ci                ret = 1;
4291a8e1175bSopenharmony_ci            }
4292a8e1175bSopenharmony_ci            mbedtls_printf("The EC J-PAKE password key has unexpectedly been already destroyed\n");
4293a8e1175bSopenharmony_ci        } else {
4294a8e1175bSopenharmony_ci            psa_destroy_key(ecjpake_pw_slot);
4295a8e1175bSopenharmony_ci        }
4296a8e1175bSopenharmony_ci    }
4297a8e1175bSopenharmony_ci#endif  /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED && MBEDTLS_USE_PSA_CRYPTO */
4298a8e1175bSopenharmony_ci
4299a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)
4300a8e1175bSopenharmony_ci    const char *message = mbedtls_test_helper_is_psa_leaking();
4301a8e1175bSopenharmony_ci    if (message) {
4302a8e1175bSopenharmony_ci        if (ret == 0) {
4303a8e1175bSopenharmony_ci            ret = 1;
4304a8e1175bSopenharmony_ci        }
4305a8e1175bSopenharmony_ci        mbedtls_printf("PSA memory leak detected: %s\n",  message);
4306a8e1175bSopenharmony_ci    }
4307a8e1175bSopenharmony_ci#endif
4308a8e1175bSopenharmony_ci
4309a8e1175bSopenharmony_ci    /* For builds with MBEDTLS_TEST_USE_PSA_CRYPTO_RNG psa crypto
4310a8e1175bSopenharmony_ci     * resources are freed by rng_free(). */
4311a8e1175bSopenharmony_ci#if (defined(MBEDTLS_USE_PSA_CRYPTO) || defined(MBEDTLS_SSL_PROTO_TLS1_3)) \
4312a8e1175bSopenharmony_ci    && !defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
4313a8e1175bSopenharmony_ci    mbedtls_psa_crypto_free();
4314a8e1175bSopenharmony_ci#endif
4315a8e1175bSopenharmony_ci
4316a8e1175bSopenharmony_ci    rng_free(&rng);
4317a8e1175bSopenharmony_ci
4318a8e1175bSopenharmony_ci    mbedtls_free(buf);
4319a8e1175bSopenharmony_ci
4320a8e1175bSopenharmony_ci#if defined(MBEDTLS_TEST_HOOKS)
4321a8e1175bSopenharmony_ci    /* Let test hooks detect errors such as resource leaks.
4322a8e1175bSopenharmony_ci     * Don't do it in query_config mode, because some test code prints
4323a8e1175bSopenharmony_ci     * information to stdout and this gets mixed with the regular output. */
4324a8e1175bSopenharmony_ci    if (opt.query_config_mode == DFL_QUERY_CONFIG_MODE) {
4325a8e1175bSopenharmony_ci        if (test_hooks_failure_detected()) {
4326a8e1175bSopenharmony_ci            if (ret == 0) {
4327a8e1175bSopenharmony_ci                ret = 1;
4328a8e1175bSopenharmony_ci            }
4329a8e1175bSopenharmony_ci            mbedtls_printf("Test hooks detected errors.\n");
4330a8e1175bSopenharmony_ci        }
4331a8e1175bSopenharmony_ci    }
4332a8e1175bSopenharmony_ci    test_hooks_free();
4333a8e1175bSopenharmony_ci#endif /* MBEDTLS_TEST_HOOKS */
4334a8e1175bSopenharmony_ci
4335a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
4336a8e1175bSopenharmony_ci#if defined(MBEDTLS_MEMORY_DEBUG)
4337a8e1175bSopenharmony_ci    mbedtls_memory_buffer_alloc_status();
4338a8e1175bSopenharmony_ci#endif
4339a8e1175bSopenharmony_ci    mbedtls_memory_buffer_alloc_free();
4340a8e1175bSopenharmony_ci#endif  /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */
4341a8e1175bSopenharmony_ci
4342a8e1175bSopenharmony_ci    if (opt.query_config_mode == DFL_QUERY_CONFIG_MODE) {
4343a8e1175bSopenharmony_ci        mbedtls_printf(" done.\n");
4344a8e1175bSopenharmony_ci    }
4345a8e1175bSopenharmony_ci
4346a8e1175bSopenharmony_ci    // Shell can not handle large exit numbers -> 1 for errors
4347a8e1175bSopenharmony_ci    if (ret < 0) {
4348a8e1175bSopenharmony_ci        ret = 1;
4349a8e1175bSopenharmony_ci    }
4350a8e1175bSopenharmony_ci
4351a8e1175bSopenharmony_ci    if (opt.query_config_mode == DFL_QUERY_CONFIG_MODE) {
4352a8e1175bSopenharmony_ci        mbedtls_exit(ret);
4353a8e1175bSopenharmony_ci    } else {
4354a8e1175bSopenharmony_ci        mbedtls_exit(query_config_ret);
4355a8e1175bSopenharmony_ci    }
4356a8e1175bSopenharmony_ci}
4357a8e1175bSopenharmony_ci#endif /* !MBEDTLS_SSL_TEST_IMPOSSIBLE && MBEDTLS_SSL_SRV_C */
4358