xref: /freebsd/crypto/openssl/test/helpers/ssltestlib.c (revision 44096ebd22ddd0081a357011714eff8963614b65)
1e0c4386eSCy Schubert /*
2*44096ebdSEnji Cooper  * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
3e0c4386eSCy Schubert  *
4e0c4386eSCy Schubert  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e0c4386eSCy Schubert  * this file except in compliance with the License.  You can obtain a copy
6e0c4386eSCy Schubert  * in the file LICENSE in the source distribution or at
7e0c4386eSCy Schubert  * https://www.openssl.org/source/license.html
8e0c4386eSCy Schubert  */
9e0c4386eSCy Schubert 
10*44096ebdSEnji Cooper /*
11*44096ebdSEnji Cooper  * We need access to the deprecated low level ENGINE APIs for legacy purposes
12*44096ebdSEnji Cooper  * when the deprecated calls are not hidden
13*44096ebdSEnji Cooper  */
14*44096ebdSEnji Cooper #ifndef OPENSSL_NO_DEPRECATED_3_0
15*44096ebdSEnji Cooper # define OPENSSL_SUPPRESS_DEPRECATED
16*44096ebdSEnji Cooper #endif
17*44096ebdSEnji Cooper 
18e0c4386eSCy Schubert #include <string.h>
19e0c4386eSCy Schubert 
20*44096ebdSEnji Cooper #include <openssl/engine.h>
21e0c4386eSCy Schubert #include "internal/nelem.h"
22e0c4386eSCy Schubert #include "ssltestlib.h"
23e0c4386eSCy Schubert #include "../testutil.h"
24e0c4386eSCy Schubert #include "e_os.h" /* for ossl_sleep() etc. */
25e0c4386eSCy Schubert 
26e0c4386eSCy Schubert #ifdef OPENSSL_SYS_UNIX
27e0c4386eSCy Schubert # include <unistd.h>
28e0c4386eSCy Schubert # ifndef OPENSSL_NO_KTLS
29e0c4386eSCy Schubert #  include <netinet/in.h>
30e0c4386eSCy Schubert #  include <netinet/in.h>
31e0c4386eSCy Schubert #  include <arpa/inet.h>
32e0c4386eSCy Schubert #  include <sys/socket.h>
33e0c4386eSCy Schubert #  include <unistd.h>
34e0c4386eSCy Schubert #  include <fcntl.h>
35e0c4386eSCy Schubert # endif
36e0c4386eSCy Schubert #endif
37e0c4386eSCy Schubert 
38e0c4386eSCy Schubert static int tls_dump_new(BIO *bi);
39e0c4386eSCy Schubert static int tls_dump_free(BIO *a);
40e0c4386eSCy Schubert static int tls_dump_read(BIO *b, char *out, int outl);
41e0c4386eSCy Schubert static int tls_dump_write(BIO *b, const char *in, int inl);
42e0c4386eSCy Schubert static long tls_dump_ctrl(BIO *b, int cmd, long num, void *ptr);
43e0c4386eSCy Schubert static int tls_dump_gets(BIO *bp, char *buf, int size);
44e0c4386eSCy Schubert static int tls_dump_puts(BIO *bp, const char *str);
45e0c4386eSCy Schubert 
46e0c4386eSCy Schubert /* Choose a sufficiently large type likely to be unused for this custom BIO */
47e0c4386eSCy Schubert #define BIO_TYPE_TLS_DUMP_FILTER  (0x80 | BIO_TYPE_FILTER)
48e0c4386eSCy Schubert #define BIO_TYPE_MEMPACKET_TEST    0x81
49e0c4386eSCy Schubert #define BIO_TYPE_ALWAYS_RETRY      0x82
50e0c4386eSCy Schubert 
51e0c4386eSCy Schubert static BIO_METHOD *method_tls_dump = NULL;
52e0c4386eSCy Schubert static BIO_METHOD *meth_mem = NULL;
53e0c4386eSCy Schubert static BIO_METHOD *meth_always_retry = NULL;
54e0c4386eSCy Schubert static int retry_err = -1;
55e0c4386eSCy Schubert 
56e0c4386eSCy Schubert /* Note: Not thread safe! */
57e0c4386eSCy Schubert const BIO_METHOD *bio_f_tls_dump_filter(void)
58e0c4386eSCy Schubert {
59e0c4386eSCy Schubert     if (method_tls_dump == NULL) {
60e0c4386eSCy Schubert         method_tls_dump = BIO_meth_new(BIO_TYPE_TLS_DUMP_FILTER,
61e0c4386eSCy Schubert                                         "TLS dump filter");
62e0c4386eSCy Schubert         if (   method_tls_dump == NULL
63e0c4386eSCy Schubert             || !BIO_meth_set_write(method_tls_dump, tls_dump_write)
64e0c4386eSCy Schubert             || !BIO_meth_set_read(method_tls_dump, tls_dump_read)
65e0c4386eSCy Schubert             || !BIO_meth_set_puts(method_tls_dump, tls_dump_puts)
66e0c4386eSCy Schubert             || !BIO_meth_set_gets(method_tls_dump, tls_dump_gets)
67e0c4386eSCy Schubert             || !BIO_meth_set_ctrl(method_tls_dump, tls_dump_ctrl)
68e0c4386eSCy Schubert             || !BIO_meth_set_create(method_tls_dump, tls_dump_new)
69e0c4386eSCy Schubert             || !BIO_meth_set_destroy(method_tls_dump, tls_dump_free))
70e0c4386eSCy Schubert             return NULL;
71e0c4386eSCy Schubert     }
72e0c4386eSCy Schubert     return method_tls_dump;
73e0c4386eSCy Schubert }
74e0c4386eSCy Schubert 
75e0c4386eSCy Schubert void bio_f_tls_dump_filter_free(void)
76e0c4386eSCy Schubert {
77e0c4386eSCy Schubert     BIO_meth_free(method_tls_dump);
78e0c4386eSCy Schubert }
79e0c4386eSCy Schubert 
80e0c4386eSCy Schubert static int tls_dump_new(BIO *bio)
81e0c4386eSCy Schubert {
82e0c4386eSCy Schubert     BIO_set_init(bio, 1);
83e0c4386eSCy Schubert     return 1;
84e0c4386eSCy Schubert }
85e0c4386eSCy Schubert 
86e0c4386eSCy Schubert static int tls_dump_free(BIO *bio)
87e0c4386eSCy Schubert {
88e0c4386eSCy Schubert     BIO_set_init(bio, 0);
89e0c4386eSCy Schubert 
90e0c4386eSCy Schubert     return 1;
91e0c4386eSCy Schubert }
92e0c4386eSCy Schubert 
93e0c4386eSCy Schubert static void copy_flags(BIO *bio)
94e0c4386eSCy Schubert {
95e0c4386eSCy Schubert     int flags;
96e0c4386eSCy Schubert     BIO *next = BIO_next(bio);
97e0c4386eSCy Schubert 
98e0c4386eSCy Schubert     flags = BIO_test_flags(next, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS);
99e0c4386eSCy Schubert     BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS);
100e0c4386eSCy Schubert     BIO_set_flags(bio, flags);
101e0c4386eSCy Schubert }
102e0c4386eSCy Schubert 
103e0c4386eSCy Schubert #define RECORD_CONTENT_TYPE     0
104e0c4386eSCy Schubert #define RECORD_VERSION_HI       1
105e0c4386eSCy Schubert #define RECORD_VERSION_LO       2
106e0c4386eSCy Schubert #define RECORD_EPOCH_HI         3
107e0c4386eSCy Schubert #define RECORD_EPOCH_LO         4
108e0c4386eSCy Schubert #define RECORD_SEQUENCE_START   5
109e0c4386eSCy Schubert #define RECORD_SEQUENCE_END     10
110e0c4386eSCy Schubert #define RECORD_LEN_HI           11
111e0c4386eSCy Schubert #define RECORD_LEN_LO           12
112e0c4386eSCy Schubert 
113e0c4386eSCy Schubert #define MSG_TYPE                0
114e0c4386eSCy Schubert #define MSG_LEN_HI              1
115e0c4386eSCy Schubert #define MSG_LEN_MID             2
116e0c4386eSCy Schubert #define MSG_LEN_LO              3
117e0c4386eSCy Schubert #define MSG_SEQ_HI              4
118e0c4386eSCy Schubert #define MSG_SEQ_LO              5
119e0c4386eSCy Schubert #define MSG_FRAG_OFF_HI         6
120e0c4386eSCy Schubert #define MSG_FRAG_OFF_MID        7
121e0c4386eSCy Schubert #define MSG_FRAG_OFF_LO         8
122e0c4386eSCy Schubert #define MSG_FRAG_LEN_HI         9
123e0c4386eSCy Schubert #define MSG_FRAG_LEN_MID        10
124e0c4386eSCy Schubert #define MSG_FRAG_LEN_LO         11
125e0c4386eSCy Schubert 
126e0c4386eSCy Schubert 
127e0c4386eSCy Schubert static void dump_data(const char *data, int len)
128e0c4386eSCy Schubert {
129e0c4386eSCy Schubert     int rem, i, content, reclen, msglen, fragoff, fraglen, epoch;
130e0c4386eSCy Schubert     unsigned char *rec;
131e0c4386eSCy Schubert 
132e0c4386eSCy Schubert     printf("---- START OF PACKET ----\n");
133e0c4386eSCy Schubert 
134e0c4386eSCy Schubert     rem = len;
135e0c4386eSCy Schubert     rec = (unsigned char *)data;
136e0c4386eSCy Schubert 
137e0c4386eSCy Schubert     while (rem > 0) {
138e0c4386eSCy Schubert         if (rem != len)
139e0c4386eSCy Schubert             printf("*\n");
140e0c4386eSCy Schubert         printf("*---- START OF RECORD ----\n");
141e0c4386eSCy Schubert         if (rem < DTLS1_RT_HEADER_LENGTH) {
142e0c4386eSCy Schubert             printf("*---- RECORD TRUNCATED ----\n");
143e0c4386eSCy Schubert             break;
144e0c4386eSCy Schubert         }
145e0c4386eSCy Schubert         content = rec[RECORD_CONTENT_TYPE];
146e0c4386eSCy Schubert         printf("** Record Content-type: %d\n", content);
147e0c4386eSCy Schubert         printf("** Record Version: %02x%02x\n",
148e0c4386eSCy Schubert                rec[RECORD_VERSION_HI], rec[RECORD_VERSION_LO]);
149e0c4386eSCy Schubert         epoch = (rec[RECORD_EPOCH_HI] << 8) | rec[RECORD_EPOCH_LO];
150e0c4386eSCy Schubert         printf("** Record Epoch: %d\n", epoch);
151e0c4386eSCy Schubert         printf("** Record Sequence: ");
152e0c4386eSCy Schubert         for (i = RECORD_SEQUENCE_START; i <= RECORD_SEQUENCE_END; i++)
153e0c4386eSCy Schubert             printf("%02x", rec[i]);
154e0c4386eSCy Schubert         reclen = (rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO];
155e0c4386eSCy Schubert         printf("\n** Record Length: %d\n", reclen);
156e0c4386eSCy Schubert 
157e0c4386eSCy Schubert         /* Now look at message */
158e0c4386eSCy Schubert         rec += DTLS1_RT_HEADER_LENGTH;
159e0c4386eSCy Schubert         rem -= DTLS1_RT_HEADER_LENGTH;
160e0c4386eSCy Schubert         if (content == SSL3_RT_HANDSHAKE) {
161e0c4386eSCy Schubert             printf("**---- START OF HANDSHAKE MESSAGE FRAGMENT ----\n");
162e0c4386eSCy Schubert             if (epoch > 0) {
163e0c4386eSCy Schubert                 printf("**---- HANDSHAKE MESSAGE FRAGMENT ENCRYPTED ----\n");
164e0c4386eSCy Schubert             } else if (rem < DTLS1_HM_HEADER_LENGTH
165e0c4386eSCy Schubert                     || reclen < DTLS1_HM_HEADER_LENGTH) {
166e0c4386eSCy Schubert                 printf("**---- HANDSHAKE MESSAGE FRAGMENT TRUNCATED ----\n");
167e0c4386eSCy Schubert             } else {
168e0c4386eSCy Schubert                 printf("*** Message Type: %d\n", rec[MSG_TYPE]);
169e0c4386eSCy Schubert                 msglen = (rec[MSG_LEN_HI] << 16) | (rec[MSG_LEN_MID] << 8)
170e0c4386eSCy Schubert                          | rec[MSG_LEN_LO];
171e0c4386eSCy Schubert                 printf("*** Message Length: %d\n", msglen);
172e0c4386eSCy Schubert                 printf("*** Message sequence: %d\n",
173e0c4386eSCy Schubert                        (rec[MSG_SEQ_HI] << 8) | rec[MSG_SEQ_LO]);
174e0c4386eSCy Schubert                 fragoff = (rec[MSG_FRAG_OFF_HI] << 16)
175e0c4386eSCy Schubert                           | (rec[MSG_FRAG_OFF_MID] << 8)
176e0c4386eSCy Schubert                           | rec[MSG_FRAG_OFF_LO];
177e0c4386eSCy Schubert                 printf("*** Message Fragment offset: %d\n", fragoff);
178e0c4386eSCy Schubert                 fraglen = (rec[MSG_FRAG_LEN_HI] << 16)
179e0c4386eSCy Schubert                           | (rec[MSG_FRAG_LEN_MID] << 8)
180e0c4386eSCy Schubert                           | rec[MSG_FRAG_LEN_LO];
181e0c4386eSCy Schubert                 printf("*** Message Fragment len: %d\n", fraglen);
182e0c4386eSCy Schubert                 if (fragoff + fraglen > msglen)
183e0c4386eSCy Schubert                     printf("***---- HANDSHAKE MESSAGE FRAGMENT INVALID ----\n");
184e0c4386eSCy Schubert                 else if (reclen < fraglen)
185e0c4386eSCy Schubert                     printf("**---- HANDSHAKE MESSAGE FRAGMENT TRUNCATED ----\n");
186e0c4386eSCy Schubert                 else
187e0c4386eSCy Schubert                     printf("**---- END OF HANDSHAKE MESSAGE FRAGMENT ----\n");
188e0c4386eSCy Schubert             }
189e0c4386eSCy Schubert         }
190e0c4386eSCy Schubert         if (rem < reclen) {
191e0c4386eSCy Schubert             printf("*---- RECORD TRUNCATED ----\n");
192e0c4386eSCy Schubert             rem = 0;
193e0c4386eSCy Schubert         } else {
194e0c4386eSCy Schubert             rec += reclen;
195e0c4386eSCy Schubert             rem -= reclen;
196e0c4386eSCy Schubert             printf("*---- END OF RECORD ----\n");
197e0c4386eSCy Schubert         }
198e0c4386eSCy Schubert     }
199e0c4386eSCy Schubert     printf("---- END OF PACKET ----\n\n");
200e0c4386eSCy Schubert     fflush(stdout);
201e0c4386eSCy Schubert }
202e0c4386eSCy Schubert 
203e0c4386eSCy Schubert static int tls_dump_read(BIO *bio, char *out, int outl)
204e0c4386eSCy Schubert {
205e0c4386eSCy Schubert     int ret;
206e0c4386eSCy Schubert     BIO *next = BIO_next(bio);
207e0c4386eSCy Schubert 
208e0c4386eSCy Schubert     ret = BIO_read(next, out, outl);
209e0c4386eSCy Schubert     copy_flags(bio);
210e0c4386eSCy Schubert 
211e0c4386eSCy Schubert     if (ret > 0) {
212e0c4386eSCy Schubert         dump_data(out, ret);
213e0c4386eSCy Schubert     }
214e0c4386eSCy Schubert 
215e0c4386eSCy Schubert     return ret;
216e0c4386eSCy Schubert }
217e0c4386eSCy Schubert 
218e0c4386eSCy Schubert static int tls_dump_write(BIO *bio, const char *in, int inl)
219e0c4386eSCy Schubert {
220e0c4386eSCy Schubert     int ret;
221e0c4386eSCy Schubert     BIO *next = BIO_next(bio);
222e0c4386eSCy Schubert 
223e0c4386eSCy Schubert     ret = BIO_write(next, in, inl);
224e0c4386eSCy Schubert     copy_flags(bio);
225e0c4386eSCy Schubert 
226e0c4386eSCy Schubert     return ret;
227e0c4386eSCy Schubert }
228e0c4386eSCy Schubert 
229e0c4386eSCy Schubert static long tls_dump_ctrl(BIO *bio, int cmd, long num, void *ptr)
230e0c4386eSCy Schubert {
231e0c4386eSCy Schubert     long ret;
232e0c4386eSCy Schubert     BIO *next = BIO_next(bio);
233e0c4386eSCy Schubert 
234e0c4386eSCy Schubert     if (next == NULL)
235e0c4386eSCy Schubert         return 0;
236e0c4386eSCy Schubert 
237e0c4386eSCy Schubert     switch (cmd) {
238e0c4386eSCy Schubert     case BIO_CTRL_DUP:
239e0c4386eSCy Schubert         ret = 0L;
240e0c4386eSCy Schubert         break;
241e0c4386eSCy Schubert     default:
242e0c4386eSCy Schubert         ret = BIO_ctrl(next, cmd, num, ptr);
243e0c4386eSCy Schubert         break;
244e0c4386eSCy Schubert     }
245e0c4386eSCy Schubert     return ret;
246e0c4386eSCy Schubert }
247e0c4386eSCy Schubert 
248e0c4386eSCy Schubert static int tls_dump_gets(BIO *bio, char *buf, int size)
249e0c4386eSCy Schubert {
250e0c4386eSCy Schubert     /* We don't support this - not needed anyway */
251e0c4386eSCy Schubert     return -1;
252e0c4386eSCy Schubert }
253e0c4386eSCy Schubert 
254e0c4386eSCy Schubert static int tls_dump_puts(BIO *bio, const char *str)
255e0c4386eSCy Schubert {
256e0c4386eSCy Schubert     return tls_dump_write(bio, str, strlen(str));
257e0c4386eSCy Schubert }
258e0c4386eSCy Schubert 
259e0c4386eSCy Schubert 
260e0c4386eSCy Schubert struct mempacket_st {
261e0c4386eSCy Schubert     unsigned char *data;
262e0c4386eSCy Schubert     int len;
263e0c4386eSCy Schubert     unsigned int num;
264e0c4386eSCy Schubert     unsigned int type;
265e0c4386eSCy Schubert };
266e0c4386eSCy Schubert 
267e0c4386eSCy Schubert static void mempacket_free(MEMPACKET *pkt)
268e0c4386eSCy Schubert {
269e0c4386eSCy Schubert     if (pkt->data != NULL)
270e0c4386eSCy Schubert         OPENSSL_free(pkt->data);
271e0c4386eSCy Schubert     OPENSSL_free(pkt);
272e0c4386eSCy Schubert }
273e0c4386eSCy Schubert 
274e0c4386eSCy Schubert typedef struct mempacket_test_ctx_st {
275e0c4386eSCy Schubert     STACK_OF(MEMPACKET) *pkts;
276e0c4386eSCy Schubert     unsigned int epoch;
277e0c4386eSCy Schubert     unsigned int currrec;
278e0c4386eSCy Schubert     unsigned int currpkt;
279e0c4386eSCy Schubert     unsigned int lastpkt;
280e0c4386eSCy Schubert     unsigned int injected;
281e0c4386eSCy Schubert     unsigned int noinject;
282e0c4386eSCy Schubert     unsigned int dropepoch;
283e0c4386eSCy Schubert     int droprec;
284e0c4386eSCy Schubert     int duprec;
285e0c4386eSCy Schubert } MEMPACKET_TEST_CTX;
286e0c4386eSCy Schubert 
287e0c4386eSCy Schubert static int mempacket_test_new(BIO *bi);
288e0c4386eSCy Schubert static int mempacket_test_free(BIO *a);
289e0c4386eSCy Schubert static int mempacket_test_read(BIO *b, char *out, int outl);
290e0c4386eSCy Schubert static int mempacket_test_write(BIO *b, const char *in, int inl);
291e0c4386eSCy Schubert static long mempacket_test_ctrl(BIO *b, int cmd, long num, void *ptr);
292e0c4386eSCy Schubert static int mempacket_test_gets(BIO *bp, char *buf, int size);
293e0c4386eSCy Schubert static int mempacket_test_puts(BIO *bp, const char *str);
294e0c4386eSCy Schubert 
295e0c4386eSCy Schubert const BIO_METHOD *bio_s_mempacket_test(void)
296e0c4386eSCy Schubert {
297e0c4386eSCy Schubert     if (meth_mem == NULL) {
298e0c4386eSCy Schubert         if (!TEST_ptr(meth_mem = BIO_meth_new(BIO_TYPE_MEMPACKET_TEST,
299e0c4386eSCy Schubert                                               "Mem Packet Test"))
300e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_write(meth_mem, mempacket_test_write))
301e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_read(meth_mem, mempacket_test_read))
302e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_puts(meth_mem, mempacket_test_puts))
303e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_gets(meth_mem, mempacket_test_gets))
304e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_ctrl(meth_mem, mempacket_test_ctrl))
305e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_create(meth_mem, mempacket_test_new))
306e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_destroy(meth_mem, mempacket_test_free)))
307e0c4386eSCy Schubert             return NULL;
308e0c4386eSCy Schubert     }
309e0c4386eSCy Schubert     return meth_mem;
310e0c4386eSCy Schubert }
311e0c4386eSCy Schubert 
312e0c4386eSCy Schubert void bio_s_mempacket_test_free(void)
313e0c4386eSCy Schubert {
314e0c4386eSCy Schubert     BIO_meth_free(meth_mem);
315e0c4386eSCy Schubert }
316e0c4386eSCy Schubert 
317e0c4386eSCy Schubert static int mempacket_test_new(BIO *bio)
318e0c4386eSCy Schubert {
319e0c4386eSCy Schubert     MEMPACKET_TEST_CTX *ctx;
320e0c4386eSCy Schubert 
321e0c4386eSCy Schubert     if (!TEST_ptr(ctx = OPENSSL_zalloc(sizeof(*ctx))))
322e0c4386eSCy Schubert         return 0;
323e0c4386eSCy Schubert     if (!TEST_ptr(ctx->pkts = sk_MEMPACKET_new_null())) {
324e0c4386eSCy Schubert         OPENSSL_free(ctx);
325e0c4386eSCy Schubert         return 0;
326e0c4386eSCy Schubert     }
327e0c4386eSCy Schubert     ctx->dropepoch = 0;
328e0c4386eSCy Schubert     ctx->droprec = -1;
329e0c4386eSCy Schubert     BIO_set_init(bio, 1);
330e0c4386eSCy Schubert     BIO_set_data(bio, ctx);
331e0c4386eSCy Schubert     return 1;
332e0c4386eSCy Schubert }
333e0c4386eSCy Schubert 
334e0c4386eSCy Schubert static int mempacket_test_free(BIO *bio)
335e0c4386eSCy Schubert {
336e0c4386eSCy Schubert     MEMPACKET_TEST_CTX *ctx = BIO_get_data(bio);
337e0c4386eSCy Schubert 
338e0c4386eSCy Schubert     sk_MEMPACKET_pop_free(ctx->pkts, mempacket_free);
339e0c4386eSCy Schubert     OPENSSL_free(ctx);
340e0c4386eSCy Schubert     BIO_set_data(bio, NULL);
341e0c4386eSCy Schubert     BIO_set_init(bio, 0);
342e0c4386eSCy Schubert     return 1;
343e0c4386eSCy Schubert }
344e0c4386eSCy Schubert 
345e0c4386eSCy Schubert /* Record Header values */
346e0c4386eSCy Schubert #define EPOCH_HI        3
347e0c4386eSCy Schubert #define EPOCH_LO        4
348e0c4386eSCy Schubert #define RECORD_SEQUENCE 10
349e0c4386eSCy Schubert #define RECORD_LEN_HI   11
350e0c4386eSCy Schubert #define RECORD_LEN_LO   12
351e0c4386eSCy Schubert 
352e0c4386eSCy Schubert #define STANDARD_PACKET                 0
353e0c4386eSCy Schubert 
354e0c4386eSCy Schubert static int mempacket_test_read(BIO *bio, char *out, int outl)
355e0c4386eSCy Schubert {
356e0c4386eSCy Schubert     MEMPACKET_TEST_CTX *ctx = BIO_get_data(bio);
357e0c4386eSCy Schubert     MEMPACKET *thispkt;
358e0c4386eSCy Schubert     unsigned char *rec;
359e0c4386eSCy Schubert     int rem;
360e0c4386eSCy Schubert     unsigned int seq, offset, len, epoch;
361e0c4386eSCy Schubert 
362e0c4386eSCy Schubert     BIO_clear_retry_flags(bio);
363e0c4386eSCy Schubert     if ((thispkt = sk_MEMPACKET_value(ctx->pkts, 0)) == NULL
364e0c4386eSCy Schubert         || thispkt->num != ctx->currpkt) {
365e0c4386eSCy Schubert         /* Probably run out of data */
366e0c4386eSCy Schubert         BIO_set_retry_read(bio);
367e0c4386eSCy Schubert         return -1;
368e0c4386eSCy Schubert     }
369e0c4386eSCy Schubert     (void)sk_MEMPACKET_shift(ctx->pkts);
370e0c4386eSCy Schubert     ctx->currpkt++;
371e0c4386eSCy Schubert 
372e0c4386eSCy Schubert     if (outl > thispkt->len)
373e0c4386eSCy Schubert         outl = thispkt->len;
374e0c4386eSCy Schubert 
375e0c4386eSCy Schubert     if (thispkt->type != INJECT_PACKET_IGNORE_REC_SEQ
376e0c4386eSCy Schubert             && (ctx->injected || ctx->droprec >= 0)) {
377e0c4386eSCy Schubert         /*
378e0c4386eSCy Schubert          * Overwrite the record sequence number. We strictly number them in
379e0c4386eSCy Schubert          * the order received. Since we are actually a reliable transport
380e0c4386eSCy Schubert          * we know that there won't be any re-ordering. We overwrite to deal
381e0c4386eSCy Schubert          * with any packets that have been injected
382e0c4386eSCy Schubert          */
383e0c4386eSCy Schubert         for (rem = thispkt->len, rec = thispkt->data; rem > 0; rem -= len) {
384e0c4386eSCy Schubert             if (rem < DTLS1_RT_HEADER_LENGTH)
385e0c4386eSCy Schubert                 return -1;
386e0c4386eSCy Schubert             epoch = (rec[EPOCH_HI] << 8) | rec[EPOCH_LO];
387e0c4386eSCy Schubert             if (epoch != ctx->epoch) {
388e0c4386eSCy Schubert                 ctx->epoch = epoch;
389e0c4386eSCy Schubert                 ctx->currrec = 0;
390e0c4386eSCy Schubert             }
391e0c4386eSCy Schubert             seq = ctx->currrec;
392e0c4386eSCy Schubert             offset = 0;
393e0c4386eSCy Schubert             do {
394e0c4386eSCy Schubert                 rec[RECORD_SEQUENCE - offset] = seq & 0xFF;
395e0c4386eSCy Schubert                 seq >>= 8;
396e0c4386eSCy Schubert                 offset++;
397e0c4386eSCy Schubert             } while (seq > 0);
398e0c4386eSCy Schubert 
399e0c4386eSCy Schubert             len = ((rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO])
400e0c4386eSCy Schubert                   + DTLS1_RT_HEADER_LENGTH;
401e0c4386eSCy Schubert             if (rem < (int)len)
402e0c4386eSCy Schubert                 return -1;
403e0c4386eSCy Schubert             if (ctx->droprec == (int)ctx->currrec && ctx->dropepoch == epoch) {
404e0c4386eSCy Schubert                 if (rem > (int)len)
405e0c4386eSCy Schubert                     memmove(rec, rec + len, rem - len);
406e0c4386eSCy Schubert                 outl -= len;
407e0c4386eSCy Schubert                 ctx->droprec = -1;
408e0c4386eSCy Schubert                 if (outl == 0)
409e0c4386eSCy Schubert                     BIO_set_retry_read(bio);
410e0c4386eSCy Schubert             } else {
411e0c4386eSCy Schubert                 rec += len;
412e0c4386eSCy Schubert             }
413e0c4386eSCy Schubert 
414e0c4386eSCy Schubert             ctx->currrec++;
415e0c4386eSCy Schubert         }
416e0c4386eSCy Schubert     }
417e0c4386eSCy Schubert 
418e0c4386eSCy Schubert     memcpy(out, thispkt->data, outl);
419e0c4386eSCy Schubert     mempacket_free(thispkt);
420e0c4386eSCy Schubert     return outl;
421e0c4386eSCy Schubert }
422e0c4386eSCy Schubert 
423e0c4386eSCy Schubert /*
424e0c4386eSCy Schubert  * Look for records from different epochs in the last datagram and swap them
425e0c4386eSCy Schubert  * around
426e0c4386eSCy Schubert  */
427e0c4386eSCy Schubert int mempacket_swap_epoch(BIO *bio)
428e0c4386eSCy Schubert {
429e0c4386eSCy Schubert     MEMPACKET_TEST_CTX *ctx = BIO_get_data(bio);
430e0c4386eSCy Schubert     MEMPACKET *thispkt;
431e0c4386eSCy Schubert     int rem, len, prevlen = 0, pktnum;
432e0c4386eSCy Schubert     unsigned char *rec, *prevrec = NULL, *tmp;
433e0c4386eSCy Schubert     unsigned int epoch;
434e0c4386eSCy Schubert     int numpkts = sk_MEMPACKET_num(ctx->pkts);
435e0c4386eSCy Schubert 
436e0c4386eSCy Schubert     if (numpkts <= 0)
437e0c4386eSCy Schubert         return 0;
438e0c4386eSCy Schubert 
439e0c4386eSCy Schubert     /*
440e0c4386eSCy Schubert      * If there are multiple packets we only look in the last one. This should
441e0c4386eSCy Schubert      * always be the one where any epoch change occurs.
442e0c4386eSCy Schubert      */
443e0c4386eSCy Schubert     thispkt = sk_MEMPACKET_value(ctx->pkts, numpkts - 1);
444e0c4386eSCy Schubert     if (thispkt == NULL)
445e0c4386eSCy Schubert         return 0;
446e0c4386eSCy Schubert 
447e0c4386eSCy Schubert     for (rem = thispkt->len, rec = thispkt->data; rem > 0; rem -= len, rec += len) {
448e0c4386eSCy Schubert         if (rem < DTLS1_RT_HEADER_LENGTH)
449e0c4386eSCy Schubert             return 0;
450e0c4386eSCy Schubert         epoch = (rec[EPOCH_HI] << 8) | rec[EPOCH_LO];
451e0c4386eSCy Schubert         len = ((rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO])
452e0c4386eSCy Schubert                 + DTLS1_RT_HEADER_LENGTH;
453e0c4386eSCy Schubert         if (rem < len)
454e0c4386eSCy Schubert             return 0;
455e0c4386eSCy Schubert 
456e0c4386eSCy Schubert         /* Assumes the epoch change does not happen on the first record */
457e0c4386eSCy Schubert         if (epoch != ctx->epoch) {
458e0c4386eSCy Schubert             if (prevrec == NULL)
459e0c4386eSCy Schubert                 return 0;
460e0c4386eSCy Schubert 
461e0c4386eSCy Schubert             /*
462e0c4386eSCy Schubert              * We found 2 records with different epochs. Take a copy of the
463e0c4386eSCy Schubert              * earlier record
464e0c4386eSCy Schubert              */
465e0c4386eSCy Schubert             tmp = OPENSSL_malloc(prevlen);
466e0c4386eSCy Schubert             if (tmp == NULL)
467e0c4386eSCy Schubert                 return 0;
468e0c4386eSCy Schubert 
469e0c4386eSCy Schubert             memcpy(tmp, prevrec, prevlen);
470e0c4386eSCy Schubert             /*
471e0c4386eSCy Schubert              * Move everything from this record onwards, including any trailing
472e0c4386eSCy Schubert              * records, and overwrite the earlier record
473e0c4386eSCy Schubert              */
474e0c4386eSCy Schubert             memmove(prevrec, rec, rem);
475e0c4386eSCy Schubert             thispkt->len -= prevlen;
476e0c4386eSCy Schubert             pktnum = thispkt->num;
477e0c4386eSCy Schubert 
478e0c4386eSCy Schubert             /*
479e0c4386eSCy Schubert              * Create a new packet for the earlier record that we took out and
480e0c4386eSCy Schubert              * add it to the end of the packet list.
481e0c4386eSCy Schubert              */
482e0c4386eSCy Schubert             thispkt = OPENSSL_malloc(sizeof(*thispkt));
483e0c4386eSCy Schubert             if (thispkt == NULL) {
484e0c4386eSCy Schubert                 OPENSSL_free(tmp);
485e0c4386eSCy Schubert                 return 0;
486e0c4386eSCy Schubert             }
487e0c4386eSCy Schubert             thispkt->type = INJECT_PACKET;
488e0c4386eSCy Schubert             thispkt->data = tmp;
489e0c4386eSCy Schubert             thispkt->len = prevlen;
490e0c4386eSCy Schubert             thispkt->num = pktnum + 1;
491e0c4386eSCy Schubert             if (sk_MEMPACKET_insert(ctx->pkts, thispkt, numpkts) <= 0) {
492e0c4386eSCy Schubert                 OPENSSL_free(tmp);
493e0c4386eSCy Schubert                 OPENSSL_free(thispkt);
494e0c4386eSCy Schubert                 return 0;
495e0c4386eSCy Schubert             }
496e0c4386eSCy Schubert 
497e0c4386eSCy Schubert             return 1;
498e0c4386eSCy Schubert         }
499e0c4386eSCy Schubert         prevrec = rec;
500e0c4386eSCy Schubert         prevlen = len;
501e0c4386eSCy Schubert     }
502e0c4386eSCy Schubert 
503e0c4386eSCy Schubert     return 0;
504e0c4386eSCy Schubert }
505e0c4386eSCy Schubert 
506e0c4386eSCy Schubert /* Move packet from position s to position d in the list (d < s) */
507e0c4386eSCy Schubert int mempacket_move_packet(BIO *bio, int d, int s)
508e0c4386eSCy Schubert {
509e0c4386eSCy Schubert     MEMPACKET_TEST_CTX *ctx = BIO_get_data(bio);
510e0c4386eSCy Schubert     MEMPACKET *thispkt;
511e0c4386eSCy Schubert     int numpkts = sk_MEMPACKET_num(ctx->pkts);
512e0c4386eSCy Schubert     int i;
513e0c4386eSCy Schubert 
514e0c4386eSCy Schubert     if (d >= s)
515e0c4386eSCy Schubert         return 0;
516e0c4386eSCy Schubert 
517e0c4386eSCy Schubert     /* We need at least s + 1 packets to be able to swap them */
518e0c4386eSCy Schubert     if (numpkts <= s)
519e0c4386eSCy Schubert         return 0;
520e0c4386eSCy Schubert 
521e0c4386eSCy Schubert     /* Get the packet at position s */
522e0c4386eSCy Schubert     thispkt = sk_MEMPACKET_value(ctx->pkts, s);
523e0c4386eSCy Schubert     if (thispkt == NULL)
524e0c4386eSCy Schubert         return 0;
525e0c4386eSCy Schubert 
526e0c4386eSCy Schubert     /* Remove and re-add it */
527e0c4386eSCy Schubert     if (sk_MEMPACKET_delete(ctx->pkts, s) != thispkt)
528e0c4386eSCy Schubert         return 0;
529e0c4386eSCy Schubert 
530e0c4386eSCy Schubert     thispkt->num -= (s - d);
531e0c4386eSCy Schubert     if (sk_MEMPACKET_insert(ctx->pkts, thispkt, d) <= 0)
532e0c4386eSCy Schubert         return 0;
533e0c4386eSCy Schubert 
534e0c4386eSCy Schubert     /* Increment the packet numbers for moved packets */
535e0c4386eSCy Schubert     for (i = d + 1; i <= s; i++) {
536e0c4386eSCy Schubert         thispkt = sk_MEMPACKET_value(ctx->pkts, i);
537e0c4386eSCy Schubert         thispkt->num++;
538e0c4386eSCy Schubert     }
539e0c4386eSCy Schubert     return 1;
540e0c4386eSCy Schubert }
541e0c4386eSCy Schubert 
542e0c4386eSCy Schubert int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum,
543e0c4386eSCy Schubert                           int type)
544e0c4386eSCy Schubert {
545e0c4386eSCy Schubert     MEMPACKET_TEST_CTX *ctx = BIO_get_data(bio);
546e0c4386eSCy Schubert     MEMPACKET *thispkt = NULL, *looppkt, *nextpkt, *allpkts[3];
547e0c4386eSCy Schubert     int i, duprec;
548e0c4386eSCy Schubert     const unsigned char *inu = (const unsigned char *)in;
549e0c4386eSCy Schubert     size_t len = ((inu[RECORD_LEN_HI] << 8) | inu[RECORD_LEN_LO])
550e0c4386eSCy Schubert                  + DTLS1_RT_HEADER_LENGTH;
551e0c4386eSCy Schubert 
552e0c4386eSCy Schubert     if (ctx == NULL)
553e0c4386eSCy Schubert         return -1;
554e0c4386eSCy Schubert 
555e0c4386eSCy Schubert     if ((size_t)inl < len)
556e0c4386eSCy Schubert         return -1;
557e0c4386eSCy Schubert 
558e0c4386eSCy Schubert     if ((size_t)inl == len)
559e0c4386eSCy Schubert         duprec = 0;
560e0c4386eSCy Schubert     else
561e0c4386eSCy Schubert         duprec = ctx->duprec > 0;
562e0c4386eSCy Schubert 
563e0c4386eSCy Schubert     /* We don't support arbitrary injection when duplicating records */
564e0c4386eSCy Schubert     if (duprec && pktnum != -1)
565e0c4386eSCy Schubert         return -1;
566e0c4386eSCy Schubert 
567e0c4386eSCy Schubert     /* We only allow injection before we've started writing any data */
568e0c4386eSCy Schubert     if (pktnum >= 0) {
569e0c4386eSCy Schubert         if (ctx->noinject)
570e0c4386eSCy Schubert             return -1;
571e0c4386eSCy Schubert         ctx->injected  = 1;
572e0c4386eSCy Schubert     } else {
573e0c4386eSCy Schubert         ctx->noinject = 1;
574e0c4386eSCy Schubert     }
575e0c4386eSCy Schubert 
576e0c4386eSCy Schubert     for (i = 0; i < (duprec ? 3 : 1); i++) {
577e0c4386eSCy Schubert         if (!TEST_ptr(allpkts[i] = OPENSSL_malloc(sizeof(*thispkt))))
578e0c4386eSCy Schubert             goto err;
579e0c4386eSCy Schubert         thispkt = allpkts[i];
580e0c4386eSCy Schubert 
581e0c4386eSCy Schubert         if (!TEST_ptr(thispkt->data = OPENSSL_malloc(inl)))
582e0c4386eSCy Schubert             goto err;
583e0c4386eSCy Schubert         /*
584e0c4386eSCy Schubert          * If we are duplicating the packet, we duplicate it three times. The
585e0c4386eSCy Schubert          * first two times we drop the first record if there are more than one.
586e0c4386eSCy Schubert          * In this way we know that libssl will not be able to make progress
587e0c4386eSCy Schubert          * until it receives the last packet, and hence will be forced to
588e0c4386eSCy Schubert          * buffer these records.
589e0c4386eSCy Schubert          */
590e0c4386eSCy Schubert         if (duprec && i != 2) {
591e0c4386eSCy Schubert             memcpy(thispkt->data, in + len, inl - len);
592e0c4386eSCy Schubert             thispkt->len = inl - len;
593e0c4386eSCy Schubert         } else {
594e0c4386eSCy Schubert             memcpy(thispkt->data, in, inl);
595e0c4386eSCy Schubert             thispkt->len = inl;
596e0c4386eSCy Schubert         }
597e0c4386eSCy Schubert         thispkt->num = (pktnum >= 0) ? (unsigned int)pktnum : ctx->lastpkt + i;
598e0c4386eSCy Schubert         thispkt->type = type;
599e0c4386eSCy Schubert     }
600e0c4386eSCy Schubert 
601e0c4386eSCy Schubert     for (i = 0; i < sk_MEMPACKET_num(ctx->pkts); i++) {
602e0c4386eSCy Schubert         if (!TEST_ptr(looppkt = sk_MEMPACKET_value(ctx->pkts, i)))
603e0c4386eSCy Schubert             goto err;
604e0c4386eSCy Schubert         /* Check if we found the right place to insert this packet */
605e0c4386eSCy Schubert         if (looppkt->num > thispkt->num) {
606e0c4386eSCy Schubert             if (sk_MEMPACKET_insert(ctx->pkts, thispkt, i) == 0)
607e0c4386eSCy Schubert                 goto err;
608e0c4386eSCy Schubert             /* If we're doing up front injection then we're done */
609e0c4386eSCy Schubert             if (pktnum >= 0)
610e0c4386eSCy Schubert                 return inl;
611e0c4386eSCy Schubert             /*
612e0c4386eSCy Schubert              * We need to do some accounting on lastpkt. We increment it first,
613e0c4386eSCy Schubert              * but it might now equal the value of injected packets, so we need
614e0c4386eSCy Schubert              * to skip over those
615e0c4386eSCy Schubert              */
616e0c4386eSCy Schubert             ctx->lastpkt++;
617e0c4386eSCy Schubert             do {
618e0c4386eSCy Schubert                 i++;
619e0c4386eSCy Schubert                 nextpkt = sk_MEMPACKET_value(ctx->pkts, i);
620e0c4386eSCy Schubert                 if (nextpkt != NULL && nextpkt->num == ctx->lastpkt)
621e0c4386eSCy Schubert                     ctx->lastpkt++;
622e0c4386eSCy Schubert                 else
623e0c4386eSCy Schubert                     return inl;
624e0c4386eSCy Schubert             } while(1);
625e0c4386eSCy Schubert         } else if (looppkt->num == thispkt->num) {
626e0c4386eSCy Schubert             if (!ctx->noinject) {
627e0c4386eSCy Schubert                 /* We injected two packets with the same packet number! */
628e0c4386eSCy Schubert                 goto err;
629e0c4386eSCy Schubert             }
630e0c4386eSCy Schubert             ctx->lastpkt++;
631e0c4386eSCy Schubert             thispkt->num++;
632e0c4386eSCy Schubert         }
633e0c4386eSCy Schubert     }
634e0c4386eSCy Schubert     /*
635e0c4386eSCy Schubert      * We didn't find any packets with a packet number equal to or greater than
636e0c4386eSCy Schubert      * this one, so we just add it onto the end
637e0c4386eSCy Schubert      */
638e0c4386eSCy Schubert     for (i = 0; i < (duprec ? 3 : 1); i++) {
639e0c4386eSCy Schubert         thispkt = allpkts[i];
640e0c4386eSCy Schubert         if (!sk_MEMPACKET_push(ctx->pkts, thispkt))
641e0c4386eSCy Schubert             goto err;
642e0c4386eSCy Schubert 
643e0c4386eSCy Schubert         if (pktnum < 0)
644e0c4386eSCy Schubert             ctx->lastpkt++;
645e0c4386eSCy Schubert     }
646e0c4386eSCy Schubert 
647e0c4386eSCy Schubert     return inl;
648e0c4386eSCy Schubert 
649e0c4386eSCy Schubert  err:
650e0c4386eSCy Schubert     for (i = 0; i < (ctx->duprec > 0 ? 3 : 1); i++)
651e0c4386eSCy Schubert         mempacket_free(allpkts[i]);
652e0c4386eSCy Schubert     return -1;
653e0c4386eSCy Schubert }
654e0c4386eSCy Schubert 
655e0c4386eSCy Schubert static int mempacket_test_write(BIO *bio, const char *in, int inl)
656e0c4386eSCy Schubert {
657e0c4386eSCy Schubert     return mempacket_test_inject(bio, in, inl, -1, STANDARD_PACKET);
658e0c4386eSCy Schubert }
659e0c4386eSCy Schubert 
660e0c4386eSCy Schubert static long mempacket_test_ctrl(BIO *bio, int cmd, long num, void *ptr)
661e0c4386eSCy Schubert {
662e0c4386eSCy Schubert     long ret = 1;
663e0c4386eSCy Schubert     MEMPACKET_TEST_CTX *ctx = BIO_get_data(bio);
664e0c4386eSCy Schubert     MEMPACKET *thispkt;
665e0c4386eSCy Schubert 
666e0c4386eSCy Schubert     switch (cmd) {
667e0c4386eSCy Schubert     case BIO_CTRL_EOF:
668e0c4386eSCy Schubert         ret = (long)(sk_MEMPACKET_num(ctx->pkts) == 0);
669e0c4386eSCy Schubert         break;
670e0c4386eSCy Schubert     case BIO_CTRL_GET_CLOSE:
671e0c4386eSCy Schubert         ret = BIO_get_shutdown(bio);
672e0c4386eSCy Schubert         break;
673e0c4386eSCy Schubert     case BIO_CTRL_SET_CLOSE:
674e0c4386eSCy Schubert         BIO_set_shutdown(bio, (int)num);
675e0c4386eSCy Schubert         break;
676e0c4386eSCy Schubert     case BIO_CTRL_WPENDING:
677e0c4386eSCy Schubert         ret = 0L;
678e0c4386eSCy Schubert         break;
679e0c4386eSCy Schubert     case BIO_CTRL_PENDING:
680e0c4386eSCy Schubert         thispkt = sk_MEMPACKET_value(ctx->pkts, 0);
681e0c4386eSCy Schubert         if (thispkt == NULL)
682e0c4386eSCy Schubert             ret = 0;
683e0c4386eSCy Schubert         else
684e0c4386eSCy Schubert             ret = thispkt->len;
685e0c4386eSCy Schubert         break;
686e0c4386eSCy Schubert     case BIO_CTRL_FLUSH:
687e0c4386eSCy Schubert         ret = 1;
688e0c4386eSCy Schubert         break;
689e0c4386eSCy Schubert     case MEMPACKET_CTRL_SET_DROP_EPOCH:
690e0c4386eSCy Schubert         ctx->dropepoch = (unsigned int)num;
691e0c4386eSCy Schubert         break;
692e0c4386eSCy Schubert     case MEMPACKET_CTRL_SET_DROP_REC:
693e0c4386eSCy Schubert         ctx->droprec = (int)num;
694e0c4386eSCy Schubert         break;
695e0c4386eSCy Schubert     case MEMPACKET_CTRL_GET_DROP_REC:
696e0c4386eSCy Schubert         ret = ctx->droprec;
697e0c4386eSCy Schubert         break;
698e0c4386eSCy Schubert     case MEMPACKET_CTRL_SET_DUPLICATE_REC:
699e0c4386eSCy Schubert         ctx->duprec = (int)num;
700e0c4386eSCy Schubert         break;
701e0c4386eSCy Schubert     case BIO_CTRL_RESET:
702e0c4386eSCy Schubert     case BIO_CTRL_DUP:
703e0c4386eSCy Schubert     case BIO_CTRL_PUSH:
704e0c4386eSCy Schubert     case BIO_CTRL_POP:
705e0c4386eSCy Schubert     default:
706e0c4386eSCy Schubert         ret = 0;
707e0c4386eSCy Schubert         break;
708e0c4386eSCy Schubert     }
709e0c4386eSCy Schubert     return ret;
710e0c4386eSCy Schubert }
711e0c4386eSCy Schubert 
712e0c4386eSCy Schubert static int mempacket_test_gets(BIO *bio, char *buf, int size)
713e0c4386eSCy Schubert {
714e0c4386eSCy Schubert     /* We don't support this - not needed anyway */
715e0c4386eSCy Schubert     return -1;
716e0c4386eSCy Schubert }
717e0c4386eSCy Schubert 
718e0c4386eSCy Schubert static int mempacket_test_puts(BIO *bio, const char *str)
719e0c4386eSCy Schubert {
720e0c4386eSCy Schubert     return mempacket_test_write(bio, str, strlen(str));
721e0c4386eSCy Schubert }
722e0c4386eSCy Schubert 
723e0c4386eSCy Schubert static int always_retry_new(BIO *bi);
724e0c4386eSCy Schubert static int always_retry_free(BIO *a);
725e0c4386eSCy Schubert static int always_retry_read(BIO *b, char *out, int outl);
726e0c4386eSCy Schubert static int always_retry_write(BIO *b, const char *in, int inl);
727e0c4386eSCy Schubert static long always_retry_ctrl(BIO *b, int cmd, long num, void *ptr);
728e0c4386eSCy Schubert static int always_retry_gets(BIO *bp, char *buf, int size);
729e0c4386eSCy Schubert static int always_retry_puts(BIO *bp, const char *str);
730e0c4386eSCy Schubert 
731e0c4386eSCy Schubert const BIO_METHOD *bio_s_always_retry(void)
732e0c4386eSCy Schubert {
733e0c4386eSCy Schubert     if (meth_always_retry == NULL) {
734e0c4386eSCy Schubert         if (!TEST_ptr(meth_always_retry = BIO_meth_new(BIO_TYPE_ALWAYS_RETRY,
735e0c4386eSCy Schubert                                                        "Always Retry"))
736e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_write(meth_always_retry,
737e0c4386eSCy Schubert                                              always_retry_write))
738e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_read(meth_always_retry,
739e0c4386eSCy Schubert                                             always_retry_read))
740e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_puts(meth_always_retry,
741e0c4386eSCy Schubert                                             always_retry_puts))
742e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_gets(meth_always_retry,
743e0c4386eSCy Schubert                                             always_retry_gets))
744e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_ctrl(meth_always_retry,
745e0c4386eSCy Schubert                                             always_retry_ctrl))
746e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_create(meth_always_retry,
747e0c4386eSCy Schubert                                               always_retry_new))
748e0c4386eSCy Schubert             || !TEST_true(BIO_meth_set_destroy(meth_always_retry,
749e0c4386eSCy Schubert                                                always_retry_free)))
750e0c4386eSCy Schubert             return NULL;
751e0c4386eSCy Schubert     }
752e0c4386eSCy Schubert     return meth_always_retry;
753e0c4386eSCy Schubert }
754e0c4386eSCy Schubert 
755e0c4386eSCy Schubert void bio_s_always_retry_free(void)
756e0c4386eSCy Schubert {
757e0c4386eSCy Schubert     BIO_meth_free(meth_always_retry);
758e0c4386eSCy Schubert }
759e0c4386eSCy Schubert 
760e0c4386eSCy Schubert static int always_retry_new(BIO *bio)
761e0c4386eSCy Schubert {
762e0c4386eSCy Schubert     BIO_set_init(bio, 1);
763e0c4386eSCy Schubert     return 1;
764e0c4386eSCy Schubert }
765e0c4386eSCy Schubert 
766e0c4386eSCy Schubert static int always_retry_free(BIO *bio)
767e0c4386eSCy Schubert {
768e0c4386eSCy Schubert     BIO_set_data(bio, NULL);
769e0c4386eSCy Schubert     BIO_set_init(bio, 0);
770e0c4386eSCy Schubert     return 1;
771e0c4386eSCy Schubert }
772e0c4386eSCy Schubert 
773e0c4386eSCy Schubert void set_always_retry_err_val(int err)
774e0c4386eSCy Schubert {
775e0c4386eSCy Schubert     retry_err = err;
776e0c4386eSCy Schubert }
777e0c4386eSCy Schubert 
778e0c4386eSCy Schubert static int always_retry_read(BIO *bio, char *out, int outl)
779e0c4386eSCy Schubert {
780e0c4386eSCy Schubert     BIO_set_retry_read(bio);
781e0c4386eSCy Schubert     return retry_err;
782e0c4386eSCy Schubert }
783e0c4386eSCy Schubert 
784e0c4386eSCy Schubert static int always_retry_write(BIO *bio, const char *in, int inl)
785e0c4386eSCy Schubert {
786e0c4386eSCy Schubert     BIO_set_retry_write(bio);
787e0c4386eSCy Schubert     return retry_err;
788e0c4386eSCy Schubert }
789e0c4386eSCy Schubert 
790e0c4386eSCy Schubert static long always_retry_ctrl(BIO *bio, int cmd, long num, void *ptr)
791e0c4386eSCy Schubert {
792e0c4386eSCy Schubert     long ret = 1;
793e0c4386eSCy Schubert 
794e0c4386eSCy Schubert     switch (cmd) {
795e0c4386eSCy Schubert     case BIO_CTRL_FLUSH:
796e0c4386eSCy Schubert         BIO_set_retry_write(bio);
797e0c4386eSCy Schubert         /* fall through */
798e0c4386eSCy Schubert     case BIO_CTRL_EOF:
799e0c4386eSCy Schubert     case BIO_CTRL_RESET:
800e0c4386eSCy Schubert     case BIO_CTRL_DUP:
801e0c4386eSCy Schubert     case BIO_CTRL_PUSH:
802e0c4386eSCy Schubert     case BIO_CTRL_POP:
803e0c4386eSCy Schubert     default:
804e0c4386eSCy Schubert         ret = 0;
805e0c4386eSCy Schubert         break;
806e0c4386eSCy Schubert     }
807e0c4386eSCy Schubert     return ret;
808e0c4386eSCy Schubert }
809e0c4386eSCy Schubert 
810e0c4386eSCy Schubert static int always_retry_gets(BIO *bio, char *buf, int size)
811e0c4386eSCy Schubert {
812e0c4386eSCy Schubert     BIO_set_retry_read(bio);
813e0c4386eSCy Schubert     return retry_err;
814e0c4386eSCy Schubert }
815e0c4386eSCy Schubert 
816e0c4386eSCy Schubert static int always_retry_puts(BIO *bio, const char *str)
817e0c4386eSCy Schubert {
818e0c4386eSCy Schubert     BIO_set_retry_write(bio);
819e0c4386eSCy Schubert     return retry_err;
820e0c4386eSCy Schubert }
821e0c4386eSCy Schubert 
822e0c4386eSCy Schubert int create_ssl_ctx_pair(OSSL_LIB_CTX *libctx, const SSL_METHOD *sm,
823e0c4386eSCy Schubert                         const SSL_METHOD *cm, int min_proto_version,
824e0c4386eSCy Schubert                         int max_proto_version, SSL_CTX **sctx, SSL_CTX **cctx,
825e0c4386eSCy Schubert                         char *certfile, char *privkeyfile)
826e0c4386eSCy Schubert {
827e0c4386eSCy Schubert     SSL_CTX *serverctx = NULL;
828e0c4386eSCy Schubert     SSL_CTX *clientctx = NULL;
829e0c4386eSCy Schubert 
830e0c4386eSCy Schubert     if (sctx != NULL) {
831e0c4386eSCy Schubert         if (*sctx != NULL)
832e0c4386eSCy Schubert             serverctx = *sctx;
833e0c4386eSCy Schubert         else if (!TEST_ptr(serverctx = SSL_CTX_new_ex(libctx, NULL, sm))
834e0c4386eSCy Schubert             || !TEST_true(SSL_CTX_set_options(serverctx,
835e0c4386eSCy Schubert                                               SSL_OP_ALLOW_CLIENT_RENEGOTIATION)))
836e0c4386eSCy Schubert             goto err;
837e0c4386eSCy Schubert     }
838e0c4386eSCy Schubert 
839e0c4386eSCy Schubert     if (cctx != NULL) {
840e0c4386eSCy Schubert         if (*cctx != NULL)
841e0c4386eSCy Schubert             clientctx = *cctx;
842e0c4386eSCy Schubert         else if (!TEST_ptr(clientctx = SSL_CTX_new_ex(libctx, NULL, cm)))
843e0c4386eSCy Schubert             goto err;
844e0c4386eSCy Schubert     }
845e0c4386eSCy Schubert 
846e0c4386eSCy Schubert #if !defined(OPENSSL_NO_TLS1_3) \
847e0c4386eSCy Schubert     && defined(OPENSSL_NO_EC) \
848e0c4386eSCy Schubert     && defined(OPENSSL_NO_DH)
849e0c4386eSCy Schubert     /*
850e0c4386eSCy Schubert      * There are no usable built-in TLSv1.3 groups if ec and dh are both
851e0c4386eSCy Schubert      * disabled
852e0c4386eSCy Schubert      */
853e0c4386eSCy Schubert     if (max_proto_version == 0
854e0c4386eSCy Schubert             && (sm == TLS_server_method() || cm == TLS_client_method()))
855e0c4386eSCy Schubert         max_proto_version = TLS1_2_VERSION;
856e0c4386eSCy Schubert #endif
857e0c4386eSCy Schubert 
858e0c4386eSCy Schubert     if (serverctx != NULL
859e0c4386eSCy Schubert             && ((min_proto_version > 0
860e0c4386eSCy Schubert                  && !TEST_true(SSL_CTX_set_min_proto_version(serverctx,
861e0c4386eSCy Schubert                                                             min_proto_version)))
862e0c4386eSCy Schubert                 || (max_proto_version > 0
863e0c4386eSCy Schubert                     && !TEST_true(SSL_CTX_set_max_proto_version(serverctx,
864e0c4386eSCy Schubert                                                                 max_proto_version)))))
865e0c4386eSCy Schubert         goto err;
866e0c4386eSCy Schubert     if (clientctx != NULL
867e0c4386eSCy Schubert         && ((min_proto_version > 0
868e0c4386eSCy Schubert              && !TEST_true(SSL_CTX_set_min_proto_version(clientctx,
869e0c4386eSCy Schubert                                                          min_proto_version)))
870e0c4386eSCy Schubert             || (max_proto_version > 0
871e0c4386eSCy Schubert                 && !TEST_true(SSL_CTX_set_max_proto_version(clientctx,
872e0c4386eSCy Schubert                                                             max_proto_version)))))
873e0c4386eSCy Schubert         goto err;
874e0c4386eSCy Schubert 
875e0c4386eSCy Schubert     if (serverctx != NULL && certfile != NULL && privkeyfile != NULL) {
876e0c4386eSCy Schubert         if (!TEST_int_eq(SSL_CTX_use_certificate_file(serverctx, certfile,
877e0c4386eSCy Schubert                                                       SSL_FILETYPE_PEM), 1)
878e0c4386eSCy Schubert                 || !TEST_int_eq(SSL_CTX_use_PrivateKey_file(serverctx,
879e0c4386eSCy Schubert                                                             privkeyfile,
880e0c4386eSCy Schubert                                                             SSL_FILETYPE_PEM), 1)
881e0c4386eSCy Schubert                 || !TEST_int_eq(SSL_CTX_check_private_key(serverctx), 1))
882e0c4386eSCy Schubert             goto err;
883e0c4386eSCy Schubert     }
884e0c4386eSCy Schubert 
885e0c4386eSCy Schubert     if (sctx != NULL)
886e0c4386eSCy Schubert         *sctx = serverctx;
887e0c4386eSCy Schubert     if (cctx != NULL)
888e0c4386eSCy Schubert         *cctx = clientctx;
889e0c4386eSCy Schubert     return 1;
890e0c4386eSCy Schubert 
891e0c4386eSCy Schubert  err:
892e0c4386eSCy Schubert     if (sctx != NULL && *sctx == NULL)
893e0c4386eSCy Schubert         SSL_CTX_free(serverctx);
894e0c4386eSCy Schubert     if (cctx != NULL && *cctx == NULL)
895e0c4386eSCy Schubert         SSL_CTX_free(clientctx);
896e0c4386eSCy Schubert     return 0;
897e0c4386eSCy Schubert }
898e0c4386eSCy Schubert 
899e0c4386eSCy Schubert #define MAXLOOPS    1000000
900e0c4386eSCy Schubert 
901e0c4386eSCy Schubert #if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK)
902e0c4386eSCy Schubert static int set_nb(int fd)
903e0c4386eSCy Schubert {
904e0c4386eSCy Schubert     int flags;
905e0c4386eSCy Schubert 
906e0c4386eSCy Schubert     flags = fcntl(fd,F_GETFL,0);
907e0c4386eSCy Schubert     if (flags == -1)
908e0c4386eSCy Schubert         return flags;
909e0c4386eSCy Schubert     flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
910e0c4386eSCy Schubert     return flags;
911e0c4386eSCy Schubert }
912e0c4386eSCy Schubert 
913e0c4386eSCy Schubert int create_test_sockets(int *cfdp, int *sfdp)
914e0c4386eSCy Schubert {
915e0c4386eSCy Schubert     struct sockaddr_in sin;
916e0c4386eSCy Schubert     const char *host = "127.0.0.1";
917e0c4386eSCy Schubert     int cfd_connected = 0, ret = 0;
918e0c4386eSCy Schubert     socklen_t slen = sizeof(sin);
919e0c4386eSCy Schubert     int afd = -1, cfd = -1, sfd = -1;
920e0c4386eSCy Schubert 
921e0c4386eSCy Schubert     memset ((char *) &sin, 0, sizeof(sin));
922e0c4386eSCy Schubert     sin.sin_family = AF_INET;
923e0c4386eSCy Schubert     sin.sin_addr.s_addr = inet_addr(host);
924e0c4386eSCy Schubert 
925e0c4386eSCy Schubert     afd = socket(AF_INET, SOCK_STREAM, 0);
926e0c4386eSCy Schubert     if (afd < 0)
927e0c4386eSCy Schubert         return 0;
928e0c4386eSCy Schubert 
929e0c4386eSCy Schubert     if (bind(afd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
930e0c4386eSCy Schubert         goto out;
931e0c4386eSCy Schubert 
932e0c4386eSCy Schubert     if (getsockname(afd, (struct sockaddr*)&sin, &slen) < 0)
933e0c4386eSCy Schubert         goto out;
934e0c4386eSCy Schubert 
935e0c4386eSCy Schubert     if (listen(afd, 1) < 0)
936e0c4386eSCy Schubert         goto out;
937e0c4386eSCy Schubert 
938e0c4386eSCy Schubert     cfd = socket(AF_INET, SOCK_STREAM, 0);
939e0c4386eSCy Schubert     if (cfd < 0)
940e0c4386eSCy Schubert         goto out;
941e0c4386eSCy Schubert 
942e0c4386eSCy Schubert     if (set_nb(afd) == -1)
943e0c4386eSCy Schubert         goto out;
944e0c4386eSCy Schubert 
945e0c4386eSCy Schubert     while (sfd == -1 || !cfd_connected ) {
946e0c4386eSCy Schubert         sfd = accept(afd, NULL, 0);
947e0c4386eSCy Schubert         if (sfd == -1 && errno != EAGAIN)
948e0c4386eSCy Schubert             goto out;
949e0c4386eSCy Schubert 
950e0c4386eSCy Schubert         if (!cfd_connected && connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
951e0c4386eSCy Schubert             goto out;
952e0c4386eSCy Schubert         else
953e0c4386eSCy Schubert             cfd_connected = 1;
954e0c4386eSCy Schubert     }
955e0c4386eSCy Schubert 
956e0c4386eSCy Schubert     if (set_nb(cfd) == -1 || set_nb(sfd) == -1)
957e0c4386eSCy Schubert         goto out;
958e0c4386eSCy Schubert     ret = 1;
959e0c4386eSCy Schubert     *cfdp = cfd;
960e0c4386eSCy Schubert     *sfdp = sfd;
961e0c4386eSCy Schubert     goto success;
962e0c4386eSCy Schubert 
963e0c4386eSCy Schubert out:
964e0c4386eSCy Schubert     if (cfd != -1)
965e0c4386eSCy Schubert         close(cfd);
966e0c4386eSCy Schubert     if (sfd != -1)
967e0c4386eSCy Schubert         close(sfd);
968e0c4386eSCy Schubert success:
969e0c4386eSCy Schubert     if (afd != -1)
970e0c4386eSCy Schubert         close(afd);
971e0c4386eSCy Schubert     return ret;
972e0c4386eSCy Schubert }
973e0c4386eSCy Schubert 
974e0c4386eSCy Schubert int create_ssl_objects2(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
975e0c4386eSCy Schubert                           SSL **cssl, int sfd, int cfd)
976e0c4386eSCy Schubert {
977e0c4386eSCy Schubert     SSL *serverssl = NULL, *clientssl = NULL;
978e0c4386eSCy Schubert     BIO *s_to_c_bio = NULL, *c_to_s_bio = NULL;
979e0c4386eSCy Schubert 
980e0c4386eSCy Schubert     if (*sssl != NULL)
981e0c4386eSCy Schubert         serverssl = *sssl;
982e0c4386eSCy Schubert     else if (!TEST_ptr(serverssl = SSL_new(serverctx)))
983e0c4386eSCy Schubert         goto error;
984e0c4386eSCy Schubert     if (*cssl != NULL)
985e0c4386eSCy Schubert         clientssl = *cssl;
986e0c4386eSCy Schubert     else if (!TEST_ptr(clientssl = SSL_new(clientctx)))
987e0c4386eSCy Schubert         goto error;
988e0c4386eSCy Schubert 
989e0c4386eSCy Schubert     if (!TEST_ptr(s_to_c_bio = BIO_new_socket(sfd, BIO_NOCLOSE))
990e0c4386eSCy Schubert             || !TEST_ptr(c_to_s_bio = BIO_new_socket(cfd, BIO_NOCLOSE)))
991e0c4386eSCy Schubert         goto error;
992e0c4386eSCy Schubert 
993e0c4386eSCy Schubert     SSL_set_bio(clientssl, c_to_s_bio, c_to_s_bio);
994e0c4386eSCy Schubert     SSL_set_bio(serverssl, s_to_c_bio, s_to_c_bio);
995e0c4386eSCy Schubert     *sssl = serverssl;
996e0c4386eSCy Schubert     *cssl = clientssl;
997e0c4386eSCy Schubert     return 1;
998e0c4386eSCy Schubert 
999e0c4386eSCy Schubert  error:
1000e0c4386eSCy Schubert     SSL_free(serverssl);
1001e0c4386eSCy Schubert     SSL_free(clientssl);
1002e0c4386eSCy Schubert     BIO_free(s_to_c_bio);
1003e0c4386eSCy Schubert     BIO_free(c_to_s_bio);
1004e0c4386eSCy Schubert     return 0;
1005e0c4386eSCy Schubert }
1006e0c4386eSCy Schubert #endif
1007e0c4386eSCy Schubert 
1008e0c4386eSCy Schubert /*
1009e0c4386eSCy Schubert  * NOTE: Transfers control of the BIOs - this function will free them on error
1010e0c4386eSCy Schubert  */
1011e0c4386eSCy Schubert int create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
1012e0c4386eSCy Schubert                           SSL **cssl, BIO *s_to_c_fbio, BIO *c_to_s_fbio)
1013e0c4386eSCy Schubert {
1014e0c4386eSCy Schubert     SSL *serverssl = NULL, *clientssl = NULL;
1015e0c4386eSCy Schubert     BIO *s_to_c_bio = NULL, *c_to_s_bio = NULL;
1016e0c4386eSCy Schubert 
1017e0c4386eSCy Schubert     if (*sssl != NULL)
1018e0c4386eSCy Schubert         serverssl = *sssl;
1019e0c4386eSCy Schubert     else if (!TEST_ptr(serverssl = SSL_new(serverctx)))
1020e0c4386eSCy Schubert         goto error;
1021e0c4386eSCy Schubert     if (*cssl != NULL)
1022e0c4386eSCy Schubert         clientssl = *cssl;
1023e0c4386eSCy Schubert     else if (!TEST_ptr(clientssl = SSL_new(clientctx)))
1024e0c4386eSCy Schubert         goto error;
1025e0c4386eSCy Schubert 
1026e0c4386eSCy Schubert     if (SSL_is_dtls(clientssl)) {
1027e0c4386eSCy Schubert         if (!TEST_ptr(s_to_c_bio = BIO_new(bio_s_mempacket_test()))
1028e0c4386eSCy Schubert                 || !TEST_ptr(c_to_s_bio = BIO_new(bio_s_mempacket_test())))
1029e0c4386eSCy Schubert             goto error;
1030e0c4386eSCy Schubert     } else {
1031e0c4386eSCy Schubert         if (!TEST_ptr(s_to_c_bio = BIO_new(BIO_s_mem()))
1032e0c4386eSCy Schubert                 || !TEST_ptr(c_to_s_bio = BIO_new(BIO_s_mem())))
1033e0c4386eSCy Schubert             goto error;
1034e0c4386eSCy Schubert     }
1035e0c4386eSCy Schubert 
1036e0c4386eSCy Schubert     if (s_to_c_fbio != NULL
1037e0c4386eSCy Schubert             && !TEST_ptr(s_to_c_bio = BIO_push(s_to_c_fbio, s_to_c_bio)))
1038e0c4386eSCy Schubert         goto error;
1039e0c4386eSCy Schubert     if (c_to_s_fbio != NULL
1040e0c4386eSCy Schubert             && !TEST_ptr(c_to_s_bio = BIO_push(c_to_s_fbio, c_to_s_bio)))
1041e0c4386eSCy Schubert         goto error;
1042e0c4386eSCy Schubert 
1043e0c4386eSCy Schubert     /* Set Non-blocking IO behaviour */
1044e0c4386eSCy Schubert     BIO_set_mem_eof_return(s_to_c_bio, -1);
1045e0c4386eSCy Schubert     BIO_set_mem_eof_return(c_to_s_bio, -1);
1046e0c4386eSCy Schubert 
1047e0c4386eSCy Schubert     /* Up ref these as we are passing them to two SSL objects */
1048e0c4386eSCy Schubert     SSL_set_bio(serverssl, c_to_s_bio, s_to_c_bio);
1049e0c4386eSCy Schubert     BIO_up_ref(s_to_c_bio);
1050e0c4386eSCy Schubert     BIO_up_ref(c_to_s_bio);
1051e0c4386eSCy Schubert     SSL_set_bio(clientssl, s_to_c_bio, c_to_s_bio);
1052e0c4386eSCy Schubert     *sssl = serverssl;
1053e0c4386eSCy Schubert     *cssl = clientssl;
1054e0c4386eSCy Schubert     return 1;
1055e0c4386eSCy Schubert 
1056e0c4386eSCy Schubert  error:
1057e0c4386eSCy Schubert     SSL_free(serverssl);
1058e0c4386eSCy Schubert     SSL_free(clientssl);
1059e0c4386eSCy Schubert     BIO_free(s_to_c_bio);
1060e0c4386eSCy Schubert     BIO_free(c_to_s_bio);
1061e0c4386eSCy Schubert     BIO_free(s_to_c_fbio);
1062e0c4386eSCy Schubert     BIO_free(c_to_s_fbio);
1063e0c4386eSCy Schubert 
1064e0c4386eSCy Schubert     return 0;
1065e0c4386eSCy Schubert }
1066e0c4386eSCy Schubert 
1067e0c4386eSCy Schubert /*
1068e0c4386eSCy Schubert  * Create an SSL connection, but does not read any post-handshake
1069e0c4386eSCy Schubert  * NewSessionTicket messages.
1070e0c4386eSCy Schubert  * If |read| is set and we're using DTLS then we will attempt to SSL_read on
1071e0c4386eSCy Schubert  * the connection once we've completed one half of it, to ensure any retransmits
1072e0c4386eSCy Schubert  * get triggered.
1073e0c4386eSCy Schubert  * We stop the connection attempt (and return a failure value) if either peer
1074e0c4386eSCy Schubert  * has SSL_get_error() return the value in the |want| parameter. The connection
1075e0c4386eSCy Schubert  * attempt could be restarted by a subsequent call to this function.
1076e0c4386eSCy Schubert  */
1077e0c4386eSCy Schubert int create_bare_ssl_connection(SSL *serverssl, SSL *clientssl, int want,
1078e0c4386eSCy Schubert                                int read)
1079e0c4386eSCy Schubert {
1080e0c4386eSCy Schubert     int retc = -1, rets = -1, err, abortctr = 0;
1081e0c4386eSCy Schubert     int clienterr = 0, servererr = 0;
1082e0c4386eSCy Schubert     int isdtls = SSL_is_dtls(serverssl);
1083e0c4386eSCy Schubert 
1084e0c4386eSCy Schubert     do {
1085e0c4386eSCy Schubert         err = SSL_ERROR_WANT_WRITE;
1086e0c4386eSCy Schubert         while (!clienterr && retc <= 0 && err == SSL_ERROR_WANT_WRITE) {
1087e0c4386eSCy Schubert             retc = SSL_connect(clientssl);
1088e0c4386eSCy Schubert             if (retc <= 0)
1089e0c4386eSCy Schubert                 err = SSL_get_error(clientssl, retc);
1090e0c4386eSCy Schubert         }
1091e0c4386eSCy Schubert 
1092e0c4386eSCy Schubert         if (!clienterr && retc <= 0 && err != SSL_ERROR_WANT_READ) {
1093e0c4386eSCy Schubert             TEST_info("SSL_connect() failed %d, %d", retc, err);
1094e0c4386eSCy Schubert             if (want != SSL_ERROR_SSL)
1095e0c4386eSCy Schubert                 TEST_openssl_errors();
1096e0c4386eSCy Schubert             clienterr = 1;
1097e0c4386eSCy Schubert         }
1098e0c4386eSCy Schubert         if (want != SSL_ERROR_NONE && err == want)
1099e0c4386eSCy Schubert             return 0;
1100e0c4386eSCy Schubert 
1101e0c4386eSCy Schubert         err = SSL_ERROR_WANT_WRITE;
1102e0c4386eSCy Schubert         while (!servererr && rets <= 0 && err == SSL_ERROR_WANT_WRITE) {
1103e0c4386eSCy Schubert             rets = SSL_accept(serverssl);
1104e0c4386eSCy Schubert             if (rets <= 0)
1105e0c4386eSCy Schubert                 err = SSL_get_error(serverssl, rets);
1106e0c4386eSCy Schubert         }
1107e0c4386eSCy Schubert 
1108e0c4386eSCy Schubert         if (!servererr && rets <= 0
1109e0c4386eSCy Schubert                 && err != SSL_ERROR_WANT_READ
1110e0c4386eSCy Schubert                 && err != SSL_ERROR_WANT_X509_LOOKUP) {
1111e0c4386eSCy Schubert             TEST_info("SSL_accept() failed %d, %d", rets, err);
1112e0c4386eSCy Schubert             if (want != SSL_ERROR_SSL)
1113e0c4386eSCy Schubert                 TEST_openssl_errors();
1114e0c4386eSCy Schubert             servererr = 1;
1115e0c4386eSCy Schubert         }
1116e0c4386eSCy Schubert         if (want != SSL_ERROR_NONE && err == want)
1117e0c4386eSCy Schubert             return 0;
1118e0c4386eSCy Schubert         if (clienterr && servererr)
1119e0c4386eSCy Schubert             return 0;
1120e0c4386eSCy Schubert         if (isdtls && read) {
1121e0c4386eSCy Schubert             unsigned char buf[20];
1122e0c4386eSCy Schubert 
1123e0c4386eSCy Schubert             /* Trigger any retransmits that may be appropriate */
1124e0c4386eSCy Schubert             if (rets > 0 && retc <= 0) {
1125e0c4386eSCy Schubert                 if (SSL_read(serverssl, buf, sizeof(buf)) > 0) {
1126e0c4386eSCy Schubert                     /* We don't expect this to succeed! */
1127e0c4386eSCy Schubert                     TEST_info("Unexpected SSL_read() success!");
1128e0c4386eSCy Schubert                     return 0;
1129e0c4386eSCy Schubert                 }
1130e0c4386eSCy Schubert             }
1131e0c4386eSCy Schubert             if (retc > 0 && rets <= 0) {
1132e0c4386eSCy Schubert                 if (SSL_read(clientssl, buf, sizeof(buf)) > 0) {
1133e0c4386eSCy Schubert                     /* We don't expect this to succeed! */
1134e0c4386eSCy Schubert                     TEST_info("Unexpected SSL_read() success!");
1135e0c4386eSCy Schubert                     return 0;
1136e0c4386eSCy Schubert                 }
1137e0c4386eSCy Schubert             }
1138e0c4386eSCy Schubert         }
1139e0c4386eSCy Schubert         if (++abortctr == MAXLOOPS) {
1140e0c4386eSCy Schubert             TEST_info("No progress made");
1141e0c4386eSCy Schubert             return 0;
1142e0c4386eSCy Schubert         }
1143e0c4386eSCy Schubert         if (isdtls && abortctr <= 50 && (abortctr % 10) == 0) {
1144e0c4386eSCy Schubert             /*
1145e0c4386eSCy Schubert              * It looks like we're just spinning. Pause for a short period to
1146e0c4386eSCy Schubert              * give the DTLS timer a chance to do something. We only do this for
1147e0c4386eSCy Schubert              * the first few times to prevent hangs.
1148e0c4386eSCy Schubert              */
1149e0c4386eSCy Schubert             ossl_sleep(50);
1150e0c4386eSCy Schubert         }
1151e0c4386eSCy Schubert     } while (retc <=0 || rets <= 0);
1152e0c4386eSCy Schubert 
1153e0c4386eSCy Schubert     return 1;
1154e0c4386eSCy Schubert }
1155e0c4386eSCy Schubert 
1156e0c4386eSCy Schubert /*
1157e0c4386eSCy Schubert  * Create an SSL connection including any post handshake NewSessionTicket
1158e0c4386eSCy Schubert  * messages.
1159e0c4386eSCy Schubert  */
1160e0c4386eSCy Schubert int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want)
1161e0c4386eSCy Schubert {
1162e0c4386eSCy Schubert     int i;
1163e0c4386eSCy Schubert     unsigned char buf;
1164e0c4386eSCy Schubert     size_t readbytes;
1165e0c4386eSCy Schubert 
1166e0c4386eSCy Schubert     if (!create_bare_ssl_connection(serverssl, clientssl, want, 1))
1167e0c4386eSCy Schubert         return 0;
1168e0c4386eSCy Schubert 
1169e0c4386eSCy Schubert     /*
1170e0c4386eSCy Schubert      * We attempt to read some data on the client side which we expect to fail.
1171e0c4386eSCy Schubert      * This will ensure we have received the NewSessionTicket in TLSv1.3 where
1172e0c4386eSCy Schubert      * appropriate. We do this twice because there are 2 NewSessionTickets.
1173e0c4386eSCy Schubert      */
1174e0c4386eSCy Schubert     for (i = 0; i < 2; i++) {
1175e0c4386eSCy Schubert         if (SSL_read_ex(clientssl, &buf, sizeof(buf), &readbytes) > 0) {
1176e0c4386eSCy Schubert             if (!TEST_ulong_eq(readbytes, 0))
1177e0c4386eSCy Schubert                 return 0;
1178e0c4386eSCy Schubert         } else if (!TEST_int_eq(SSL_get_error(clientssl, 0),
1179e0c4386eSCy Schubert                                 SSL_ERROR_WANT_READ)) {
1180e0c4386eSCy Schubert             return 0;
1181e0c4386eSCy Schubert         }
1182e0c4386eSCy Schubert     }
1183e0c4386eSCy Schubert 
1184e0c4386eSCy Schubert     return 1;
1185e0c4386eSCy Schubert }
1186e0c4386eSCy Schubert 
1187e0c4386eSCy Schubert void shutdown_ssl_connection(SSL *serverssl, SSL *clientssl)
1188e0c4386eSCy Schubert {
1189e0c4386eSCy Schubert     SSL_shutdown(clientssl);
1190e0c4386eSCy Schubert     SSL_shutdown(serverssl);
1191e0c4386eSCy Schubert     SSL_free(serverssl);
1192e0c4386eSCy Schubert     SSL_free(clientssl);
1193e0c4386eSCy Schubert }
1194*44096ebdSEnji Cooper 
1195*44096ebdSEnji Cooper ENGINE *load_dasync(void)
1196*44096ebdSEnji Cooper {
1197*44096ebdSEnji Cooper #if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_DYNAMIC_ENGINE)
1198*44096ebdSEnji Cooper     ENGINE *e;
1199*44096ebdSEnji Cooper 
1200*44096ebdSEnji Cooper     if (!TEST_ptr(e = ENGINE_by_id("dasync")))
1201*44096ebdSEnji Cooper         return NULL;
1202*44096ebdSEnji Cooper 
1203*44096ebdSEnji Cooper     if (!TEST_true(ENGINE_init(e))) {
1204*44096ebdSEnji Cooper         ENGINE_free(e);
1205*44096ebdSEnji Cooper         return NULL;
1206*44096ebdSEnji Cooper     }
1207*44096ebdSEnji Cooper 
1208*44096ebdSEnji Cooper     if (!TEST_true(ENGINE_register_ciphers(e))) {
1209*44096ebdSEnji Cooper         ENGINE_free(e);
1210*44096ebdSEnji Cooper         return NULL;
1211*44096ebdSEnji Cooper     }
1212*44096ebdSEnji Cooper 
1213*44096ebdSEnji Cooper     return e;
1214*44096ebdSEnji Cooper #else
1215*44096ebdSEnji Cooper     return NULL;
1216*44096ebdSEnji Cooper #endif
1217*44096ebdSEnji Cooper }
1218