Back port ssltestlib code to 1.0.2
[openssl.git] / test / ssltestlib.c
1 /*
2  * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <string.h>
11 #include <openssl/safestack.h>
12
13 #include "ssltestlib.h"
14
15 #define SSL_IS_DTLS(s)  (s->method->version == DTLS_ANY_VERSION \
16     || s->method->version == DTLS1_2_VERSION \
17     || s->method->version == DTLS1_VERSION)
18
19 static int tls_dump_new(BIO *bi);
20 static int tls_dump_free(BIO *a);
21 static int tls_dump_read(BIO *b, char *out, int outl);
22 static int tls_dump_write(BIO *b, const char *in, int inl);
23 static long tls_dump_ctrl(BIO *b, int cmd, long num, void *ptr);
24 static int tls_dump_gets(BIO *bp, char *buf, int size);
25 static int tls_dump_puts(BIO *bp, const char *str);
26
27 /* Choose a sufficiently large type likely to be unused for this custom BIO */
28 # define BIO_TYPE_TLS_DUMP_FILTER  (0x80 | BIO_TYPE_FILTER)
29
30 # define BIO_TYPE_MEMPACKET_TEST      0x81
31
32 static BIO_METHOD method_tls_dump = {
33     BIO_TYPE_TLS_DUMP_FILTER,
34     "TLS dump filter",
35     tls_dump_write,
36     tls_dump_read,
37     tls_dump_puts,
38     tls_dump_gets,
39     tls_dump_ctrl,
40     tls_dump_new,
41     tls_dump_free
42 };
43
44 BIO_METHOD *bio_f_tls_dump_filter(void)
45 {
46     return &method_tls_dump;
47 }
48
49 static int tls_dump_new(BIO *bio)
50 {
51     bio->init = 1;
52     return 1;
53 }
54
55 static int tls_dump_free(BIO *bio)
56 {
57     bio->init = 0;
58
59     return 1;
60 }
61
62 static void copy_flags(BIO *bio)
63 {
64     int flags;
65     BIO *next = BIO_next(bio);
66
67     flags = BIO_test_flags(next, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS);
68     BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY | BIO_FLAGS_RWS);
69     BIO_set_flags(bio, flags);
70 }
71
72 #define RECORD_CONTENT_TYPE     0
73 #define RECORD_VERSION_HI       1
74 #define RECORD_VERSION_LO       2
75 #define RECORD_EPOCH_HI         3
76 #define RECORD_EPOCH_LO         4
77 #define RECORD_SEQUENCE_START   5
78 #define RECORD_SEQUENCE_END     10
79 #define RECORD_LEN_HI           11
80 #define RECORD_LEN_LO           12
81
82 #define MSG_TYPE                0
83 #define MSG_LEN_HI              1
84 #define MSG_LEN_MID             2
85 #define MSG_LEN_LO              3
86 #define MSG_SEQ_HI              4
87 #define MSG_SEQ_LO              5
88 #define MSG_FRAG_OFF_HI         6
89 #define MSG_FRAG_OFF_MID        7
90 #define MSG_FRAG_OFF_LO         8
91 #define MSG_FRAG_LEN_HI         9
92 #define MSG_FRAG_LEN_MID        10
93 #define MSG_FRAG_LEN_LO         11
94
95
96 static void dump_data(const char *data, int len)
97 {
98     int rem, i, content, reclen, msglen, fragoff, fraglen, epoch;
99     unsigned char *rec;
100
101     printf("---- START OF PACKET ----\n");
102
103     rem = len;
104     rec = (unsigned char *)data;
105
106     while (rem > 0) {
107         if (rem != len)
108             printf("*\n");
109         printf("*---- START OF RECORD ----\n");
110         if (rem < DTLS1_RT_HEADER_LENGTH) {
111             printf("*---- RECORD TRUNCATED ----\n");
112             break;
113         }
114         content = rec[RECORD_CONTENT_TYPE];
115         printf("** Record Content-type: %d\n", content);
116         printf("** Record Version: %02x%02x\n",
117                rec[RECORD_VERSION_HI], rec[RECORD_VERSION_LO]);
118         epoch = (rec[RECORD_EPOCH_HI] << 8) | rec[RECORD_EPOCH_LO];
119         printf("** Record Epoch: %d\n", epoch);
120         printf("** Record Sequence: ");
121         for (i = RECORD_SEQUENCE_START; i <= RECORD_SEQUENCE_END; i++)
122             printf("%02x", rec[i]);
123         reclen = (rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO];
124         printf("\n** Record Length: %d\n", reclen);
125
126         /* Now look at message */
127         rec += DTLS1_RT_HEADER_LENGTH;
128         rem -= DTLS1_RT_HEADER_LENGTH;
129         if (content == SSL3_RT_HANDSHAKE) {
130             printf("**---- START OF HANDSHAKE MESSAGE FRAGMENT ----\n");
131             if (epoch > 0) {
132                 printf("**---- HANDSHAKE MESSAGE FRAGMENT ENCRYPTED ----\n");
133             } else if (rem < DTLS1_HM_HEADER_LENGTH
134                     || reclen < DTLS1_HM_HEADER_LENGTH) {
135                 printf("**---- HANDSHAKE MESSAGE FRAGMENT TRUNCATED ----\n");
136             } else {
137                 printf("*** Message Type: %d\n", rec[MSG_TYPE]);
138                 msglen = (rec[MSG_LEN_HI] << 16) | (rec[MSG_LEN_MID] << 8)
139                          | rec[MSG_LEN_LO];
140                 printf("*** Message Length: %d\n", msglen);
141                 printf("*** Message sequence: %d\n",
142                        (rec[MSG_SEQ_HI] << 8) | rec[MSG_SEQ_LO]);
143                 fragoff = (rec[MSG_FRAG_OFF_HI] << 16)
144                           | (rec[MSG_FRAG_OFF_MID] << 8)
145                           | rec[MSG_FRAG_OFF_LO];
146                 printf("*** Message Fragment offset: %d\n", fragoff);
147                 fraglen = (rec[MSG_FRAG_LEN_HI] << 16)
148                           | (rec[MSG_FRAG_LEN_MID] << 8)
149                           | rec[MSG_FRAG_LEN_LO];
150                 printf("*** Message Fragment len: %d\n", fraglen);
151                 if (fragoff + fraglen > msglen)
152                     printf("***---- HANDSHAKE MESSAGE FRAGMENT INVALID ----\n");
153                 else if(reclen < fraglen)
154                     printf("**---- HANDSHAKE MESSAGE FRAGMENT TRUNCATED ----\n");
155                 else
156                     printf("**---- END OF HANDSHAKE MESSAGE FRAGMENT ----\n");
157             }
158         }
159         if (rem < reclen) {
160             printf("*---- RECORD TRUNCATED ----\n");
161             rem = 0;
162         } else {
163             rec += reclen;
164             rem -= reclen;
165             printf("*---- END OF RECORD ----\n");
166         }
167     }
168     printf("---- END OF PACKET ----\n\n");
169     fflush(stdout);
170 }
171
172 static int tls_dump_read(BIO *bio, char *out, int outl)
173 {
174     int ret;
175     BIO *next = BIO_next(bio);
176
177     ret = BIO_read(next, out, outl);
178     copy_flags(bio);
179
180     if (ret > 0) {
181         dump_data(out, ret);
182     }
183
184     return ret;
185 }
186
187 static int tls_dump_write(BIO *bio, const char *in, int inl)
188 {
189     int ret;
190     BIO *next = BIO_next(bio);
191
192     ret = BIO_write(next, in, inl);
193     copy_flags(bio);
194
195     return ret;
196 }
197
198 static long tls_dump_ctrl(BIO *bio, int cmd, long num, void *ptr)
199 {
200     long ret;
201     BIO *next = BIO_next(bio);
202
203     if (next == NULL)
204         return 0;
205
206     switch (cmd) {
207     case BIO_CTRL_DUP:
208         ret = 0L;
209         break;
210     default:
211         ret = BIO_ctrl(next, cmd, num, ptr);
212         break;
213     }
214     return ret;
215 }
216
217 static int tls_dump_gets(BIO *bio, char *buf, int size)
218 {
219     /* We don't support this - not needed anyway */
220     return -1;
221 }
222
223 static int tls_dump_puts(BIO *bio, const char *str)
224 {
225     return tls_dump_write(bio, str, strlen(str));
226 }
227
228
229 typedef struct mempacket_st {
230     unsigned char *data;
231     int len;
232     unsigned int num;
233     unsigned int type;
234 } MEMPACKET;
235
236 /*
237  * These defines would normally be auto-generated and in safestack.h...but this
238  * is just for tests so its probably not an appropriate place
239  */
240 # define sk_MEMPACKET_new(cmp) SKM_sk_new(MEMPACKET, (cmp))
241 # define sk_MEMPACKET_new_null() SKM_sk_new_null(MEMPACKET)
242 # define sk_MEMPACKET_free(st) SKM_sk_free(MEMPACKET, (st))
243 # define sk_MEMPACKET_num(st) SKM_sk_num(MEMPACKET, (st))
244 # define sk_MEMPACKET_value(st, i) SKM_sk_value(MEMPACKET, (st), (i))
245 # define sk_MEMPACKET_set(st, i, val) SKM_sk_set(MEMPACKET, (st), (i), (val))
246 # define sk_MEMPACKET_zero(st) SKM_sk_zero(MEMPACKET, (st))
247 # define sk_MEMPACKET_push(st, val) SKM_sk_push(MEMPACKET, (st), (val))
248 # define sk_MEMPACKET_unshift(st, val) SKM_sk_unshift(MEMPACKET, (st), (val))
249 # define sk_MEMPACKET_find(st, val) SKM_sk_find(MEMPACKET, (st), (val))
250 # define sk_MEMPACKET_find_ex(st, val) SKM_sk_find_ex(MEMPACKET, (st), (val))
251 # define sk_MEMPACKET_delete(st, i) SKM_sk_delete(MEMPACKET, (st), (i))
252 # define sk_MEMPACKET_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEMPACKET, (st), (ptr))
253 # define sk_MEMPACKET_insert(st, val, i) SKM_sk_insert(MEMPACKET, (st), (val), (i))
254 # define sk_MEMPACKET_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEMPACKET, (st), (cmp))
255 # define sk_MEMPACKET_dup(st) SKM_sk_dup(MEMPACKET, st)
256 # define sk_MEMPACKET_pop_free(st, free_func) SKM_sk_pop_free(MEMPACKET, (st), (free_func))
257 # define sk_MEMPACKET_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MEMPACKET, (st), (copy_func), (free_func))
258 # define sk_MEMPACKET_shift(st) SKM_sk_shift(MEMPACKET, (st))
259 # define sk_MEMPACKET_pop(st) SKM_sk_pop(MEMPACKET, (st))
260 # define sk_MEMPACKET_sort(st) SKM_sk_sort(MEMPACKET, (st))
261 # define sk_MEMPACKET_is_sorted(st) SKM_sk_is_sorted(MEMPACKET, (st))
262
263 static void mempacket_free(MEMPACKET *pkt)
264 {
265     if (pkt->data != NULL)
266         OPENSSL_free(pkt->data);
267     OPENSSL_free(pkt);
268 }
269
270 typedef struct mempacket_test_ctx_st {
271     STACK_OF(MEMPACKET) *pkts;
272     unsigned int epoch;
273     unsigned int currrec;
274     unsigned int currpkt;
275     unsigned int lastpkt;
276     unsigned int noinject;
277 } MEMPACKET_TEST_CTX;
278
279 static int mempacket_test_new(BIO *bi);
280 static int mempacket_test_free(BIO *a);
281 static int mempacket_test_read(BIO *b, char *out, int outl);
282 static int mempacket_test_write(BIO *b, const char *in, int inl);
283 static long mempacket_test_ctrl(BIO *b, int cmd, long num, void *ptr);
284 static int mempacket_test_gets(BIO *bp, char *buf, int size);
285 static int mempacket_test_puts(BIO *bp, const char *str);
286
287 static BIO_METHOD method_mempacket_test = {
288     BIO_TYPE_MEMPACKET_TEST,
289     "Mem Packet Test",
290     mempacket_test_write,
291     mempacket_test_read,
292     mempacket_test_puts,
293     mempacket_test_gets,
294     mempacket_test_ctrl,
295     mempacket_test_new,
296     mempacket_test_free
297 };
298
299 BIO_METHOD *bio_s_mempacket_test(void)
300 {
301     return &method_mempacket_test;
302 }
303
304 static int mempacket_test_new(BIO *bio)
305 {
306     MEMPACKET_TEST_CTX *ctx = OPENSSL_malloc(sizeof(*ctx));
307     if (ctx == NULL)
308         return 0;
309     memset(ctx, 0, sizeof(*ctx));
310
311     ctx->pkts = sk_MEMPACKET_new_null();
312     if (ctx->pkts == NULL) {
313         OPENSSL_free(ctx);
314         return 0;
315     }
316     bio->init = 1;
317     bio->ptr = ctx;
318     return 1;
319 }
320
321 static int mempacket_test_free(BIO *bio)
322 {
323     MEMPACKET_TEST_CTX *ctx = bio->ptr;
324
325     sk_MEMPACKET_pop_free(ctx->pkts, mempacket_free);
326     OPENSSL_free(ctx);
327     bio->ptr = NULL;
328     bio->init = 0;
329
330     return 1;
331 }
332
333 /* Record Header values */
334 #define EPOCH_HI        4
335 #define EPOCH_LO        5
336 #define RECORD_SEQUENCE 10
337 #define RECORD_LEN_HI   11
338 #define RECORD_LEN_LO   12
339
340 #define STANDARD_PACKET                 0
341
342 static int mempacket_test_read(BIO *bio, char *out, int outl)
343 {
344     MEMPACKET_TEST_CTX *ctx = bio->ptr;
345     MEMPACKET *thispkt;
346     unsigned char *rec;
347     int rem;
348     unsigned int seq, offset, len, epoch;
349
350     BIO_clear_retry_flags(bio);
351
352     thispkt = sk_MEMPACKET_value(ctx->pkts, 0);
353     if (thispkt == NULL || thispkt->num != ctx->currpkt) {
354         /* Probably run out of data */
355         BIO_set_retry_read(bio);
356         return -1;
357     }
358     sk_MEMPACKET_shift(ctx->pkts);
359     ctx->currpkt++;
360
361     if (outl > thispkt->len)
362         outl = thispkt->len;
363
364     if (thispkt->type != INJECT_PACKET_IGNORE_REC_SEQ) {
365         /*
366          * Overwrite the record sequence number. We strictly number them in
367          * the order received. Since we are actually a reliable transport
368          * we know that there won't be any re-ordering. We overwrite to deal
369          * with any packets that have been injected
370          */
371         rem = thispkt->len;
372         rec = thispkt->data;
373         while (rem > 0) {
374             if (rem < DTLS1_RT_HEADER_LENGTH) {
375                 return -1;
376             }
377             epoch = (rec[EPOCH_HI] << 8) | rec[EPOCH_LO];
378             if (epoch != ctx->epoch) {
379                 ctx->epoch = epoch;
380                 ctx->currrec = 0;
381             }
382             seq = ctx->currrec;
383             offset = 0;
384             do {
385                 rec[RECORD_SEQUENCE - offset] = seq & 0xFF;
386                 seq >>= 8;
387                 offset++;
388             } while (seq > 0);
389             ctx->currrec++;
390
391             len = ((rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO])
392                   + DTLS1_RT_HEADER_LENGTH;
393
394             rec += len;
395             rem -= len;
396         }
397     }
398
399     memcpy(out, thispkt->data, outl);
400
401     mempacket_free(thispkt);
402
403     return outl;
404 }
405
406 int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum,
407                           int type)
408 {
409     MEMPACKET_TEST_CTX *ctx = bio->ptr;
410     MEMPACKET *thispkt, *looppkt, *nextpkt;
411     int i;
412
413     if (ctx == NULL)
414         return -1;
415
416     /* We only allow injection before we've started writing any data */
417     if (pktnum >= 0) {
418         if (ctx->noinject)
419             return -1;
420     } else {
421         ctx->noinject = 1;
422     }
423
424     thispkt = OPENSSL_malloc(sizeof(MEMPACKET));
425     if (thispkt == NULL)
426         return -1;
427
428     thispkt->data = OPENSSL_malloc(inl);
429     if (thispkt->data == NULL) {
430         mempacket_free(thispkt);
431         return -1;
432     }
433
434     memcpy(thispkt->data, in, inl);
435     thispkt->len = inl;
436     thispkt->num = (pktnum >= 0) ? (unsigned int)pktnum : ctx->lastpkt;
437     thispkt->type = type;
438
439     for(i = 0; (looppkt = sk_MEMPACKET_value(ctx->pkts, i)) != NULL; i++) {
440         /* Check if we found the right place to insert this packet */
441         if (looppkt->num > thispkt->num) {
442             if (sk_MEMPACKET_insert(ctx->pkts, thispkt, i) == 0) {
443                 mempacket_free(thispkt);
444                 return -1;
445             }
446             /* If we're doing up front injection then we're done */
447             if (pktnum >= 0)
448                 return inl;
449             /*
450              * We need to do some accounting on lastpkt. We increment it first,
451              * but it might now equal the value of injected packets, so we need
452              * to skip over those
453              */
454             ctx->lastpkt++;
455             do {
456                 i++;
457                 nextpkt = sk_MEMPACKET_value(ctx->pkts, i);
458                 if (nextpkt != NULL && nextpkt->num == ctx->lastpkt)
459                     ctx->lastpkt++;
460                 else
461                     return inl;
462             } while(1);
463         } else if(looppkt->num == thispkt->num) {
464             if (!ctx->noinject) {
465                 /* We injected two packets with the same packet number! */
466                 return -1;
467             }
468             ctx->lastpkt++;
469             thispkt->num++;
470         }
471     }
472     /*
473      * We didn't find any packets with a packet number equal to or greater than
474      * this one, so we just add it onto the end
475      */
476     if (!sk_MEMPACKET_push(ctx->pkts, thispkt)) {
477         mempacket_free(thispkt);
478         return -1;
479     }
480
481     if (pktnum < 0)
482         ctx->lastpkt++;
483
484     return inl;
485 }
486
487 static int mempacket_test_write(BIO *bio, const char *in, int inl)
488 {
489     return mempacket_test_inject(bio, in, inl, -1, STANDARD_PACKET);
490 }
491
492 static long mempacket_test_ctrl(BIO *bio, int cmd, long num, void *ptr)
493 {
494     long ret = 1;
495     MEMPACKET_TEST_CTX *ctx = bio->ptr;
496     MEMPACKET *thispkt;
497
498     switch (cmd) {
499     case BIO_CTRL_EOF:
500         ret = (long)(sk_MEMPACKET_num(ctx->pkts) == 0);
501         break;
502     case BIO_CTRL_GET_CLOSE:
503         ret = bio->shutdown;
504         break;
505     case BIO_CTRL_SET_CLOSE:
506         bio->shutdown = (int)num;
507         break;
508     case BIO_CTRL_WPENDING:
509         ret = 0L;
510         break;
511     case BIO_CTRL_PENDING:
512         thispkt = sk_MEMPACKET_value(ctx->pkts, 0);
513         if (thispkt == NULL)
514             ret = 0;
515         else
516             ret = thispkt->len;
517         break;
518     case BIO_CTRL_FLUSH:
519         ret = 1;
520         break;
521     case BIO_CTRL_RESET:
522     case BIO_CTRL_DUP:
523     case BIO_CTRL_PUSH:
524     case BIO_CTRL_POP:
525     default:
526         ret = 0;
527         break;
528     }
529     return ret;
530 }
531
532 static int mempacket_test_gets(BIO *bio, char *buf, int size)
533 {
534     /* We don't support this - not needed anyway */
535     return -1;
536 }
537
538 static int mempacket_test_puts(BIO *bio, const char *str)
539 {
540     return mempacket_test_write(bio, str, strlen(str));
541 }
542
543 int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
544                         SSL_CTX **sctx, SSL_CTX **cctx, char *certfile,
545                         char *privkeyfile)
546 {
547     SSL_CTX *serverctx = NULL;
548     SSL_CTX *clientctx = NULL;
549
550     serverctx = SSL_CTX_new(sm);
551     clientctx = SSL_CTX_new(cm);
552     if (serverctx == NULL || clientctx == NULL) {
553         printf("Failed to create SSL_CTX\n");
554         goto err;
555     }
556
557     if (SSL_CTX_use_certificate_file(serverctx, certfile,
558                                      SSL_FILETYPE_PEM) <= 0) {
559         printf("Failed to load server certificate\n");
560         goto err;
561     }
562     if (SSL_CTX_use_PrivateKey_file(serverctx, privkeyfile,
563                                     SSL_FILETYPE_PEM) <= 0) {
564         printf("Failed to load server private key\n");
565     }
566     if (SSL_CTX_check_private_key(serverctx) <= 0) {
567         printf("Failed to check private key\n");
568         goto err;
569     }
570
571     *sctx = serverctx;
572     *cctx = clientctx;
573
574     return 1;
575  err:
576     SSL_CTX_free(serverctx);
577     SSL_CTX_free(clientctx);
578     return 0;
579 }
580
581 #define MAXLOOPS    100000
582
583 /*
584  * NOTE: Transfers control of the BIOs - this function will free them on error
585  */
586 int create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
587                           SSL **cssl, BIO *s_to_c_fbio, BIO *c_to_s_fbio)
588 {
589     SSL *serverssl, *clientssl;
590     BIO *s_to_c_bio = NULL, *c_to_s_bio = NULL;
591
592     serverssl = SSL_new(serverctx);
593     clientssl = SSL_new(clientctx);
594
595     if (serverssl == NULL || clientssl == NULL) {
596         printf("Failed to create SSL object\n");
597         goto error;
598     }
599
600     if (SSL_IS_DTLS(clientssl)) {
601         s_to_c_bio = BIO_new(bio_s_mempacket_test());
602         c_to_s_bio = BIO_new(bio_s_mempacket_test());;
603     } else {
604         s_to_c_bio = BIO_new(BIO_s_mem());
605         c_to_s_bio = BIO_new(BIO_s_mem());
606     }
607     if (s_to_c_bio == NULL || c_to_s_bio == NULL) {
608         printf("Failed to create mem BIOs\n");
609         goto error;
610     }
611
612     if (s_to_c_fbio != NULL)
613         s_to_c_bio = BIO_push(s_to_c_fbio, s_to_c_bio);
614     if (c_to_s_fbio != NULL)
615         c_to_s_bio = BIO_push(c_to_s_fbio, c_to_s_bio);
616     if (s_to_c_bio == NULL || c_to_s_bio == NULL) {
617         printf("Failed to create chained BIOs\n");
618         goto error;
619     }
620
621     /* Set Non-blocking IO behaviour */
622     BIO_set_mem_eof_return(s_to_c_bio, -1);
623     BIO_set_mem_eof_return(c_to_s_bio, -1);
624
625     /* Up ref these as we are passing them to two SSL objects */
626     CRYPTO_add(&s_to_c_bio->references, 1, CRYPTO_LOCK_BIO);
627     CRYPTO_add(&c_to_s_bio->references, 1, CRYPTO_LOCK_BIO);
628
629     SSL_set_bio(serverssl, c_to_s_bio, s_to_c_bio);
630     SSL_set_bio(clientssl, s_to_c_bio, c_to_s_bio);
631
632     /* BIOs will now be freed when SSL objects are freed */
633     s_to_c_bio = c_to_s_bio = NULL;
634     s_to_c_fbio = c_to_s_fbio = NULL;
635
636     *sssl = serverssl;
637     *cssl = clientssl;
638
639     return 1;
640
641  error:
642     SSL_free(serverssl);
643     SSL_free(clientssl);
644     BIO_free(s_to_c_bio);
645     BIO_free(c_to_s_bio);
646     BIO_free(s_to_c_fbio);
647     BIO_free(c_to_s_fbio);
648
649     return 0;
650 }
651
652 int create_ssl_connection(SSL *serverssl, SSL *clientssl)
653 {
654     int retc = -1, rets = -1, err, abortctr = 0;
655
656     do {
657         err = SSL_ERROR_WANT_WRITE;
658         while (retc <= 0 && err == SSL_ERROR_WANT_WRITE) {
659             retc = SSL_connect(clientssl);
660             if (retc <= 0)
661                 err = SSL_get_error(clientssl, retc);
662         }
663
664         if (retc <= 0 && err != SSL_ERROR_WANT_READ) {
665             printf("SSL_connect() failed %d, %d\n", retc, err);
666             return 0;
667         }
668
669         err = SSL_ERROR_WANT_WRITE;
670         while (rets <= 0 && err == SSL_ERROR_WANT_WRITE) {
671             rets = SSL_accept(serverssl);
672             if (rets <= 0)
673                 err = SSL_get_error(serverssl, rets);
674         }
675
676         if (rets <= 0 && err != SSL_ERROR_WANT_READ) {
677             printf("SSL_accept() failed %d, %d\n", retc, err);
678             return 0;
679         }
680         if (++abortctr == MAXLOOPS) {
681             printf("No progress made\n");
682             return 0;
683         }
684     } while (retc <=0 || rets <= 0);
685
686     return 1;
687 }