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