Add more session tests
[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 "ssltestlib.h"
11
12 int create_ssl_ctx_pair(const SSL_METHOD *sm, const SSL_METHOD *cm,
13                         SSL_CTX **sctx, SSL_CTX **cctx, char *certfile,
14                         char *privkeyfile)
15 {
16     SSL_CTX *serverctx = NULL;
17     SSL_CTX *clientctx = NULL;
18
19     serverctx = SSL_CTX_new(sm);
20     clientctx = SSL_CTX_new(cm);
21     if (serverctx == NULL || clientctx == NULL) {
22         printf("Failed to create SSL_CTX\n");
23         goto err;
24     }
25
26     if (SSL_CTX_use_certificate_file(serverctx, certfile,
27                                      SSL_FILETYPE_PEM) <= 0) {
28         printf("Failed to load server certificate\n");
29         goto err;
30     }
31     if (SSL_CTX_use_PrivateKey_file(serverctx, privkeyfile,
32                                     SSL_FILETYPE_PEM) <= 0) {
33         printf("Failed to load server private key\n");
34     }
35     if (SSL_CTX_check_private_key(serverctx) <= 0) {
36         printf("Failed to check private key\n");
37         goto err;
38     }
39
40     *sctx = serverctx;
41     *cctx = clientctx;
42
43     return 1;
44  err:
45     SSL_CTX_free(serverctx);
46     SSL_CTX_free(clientctx);
47     return 0;
48 }
49
50 #define MAXLOOPS    100000
51
52 /*
53  * NOTE: Transfers control of the BIOs - this function will free them on error
54  */
55 int create_ssl_connection(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
56                           SSL **cssl, BIO *s_to_c_fbio, BIO *c_to_s_fbio)
57 {
58     int retc = -1, rets = -1, err, abortctr = 0;
59     int clienterr = 0, servererr = 0;
60     SSL *serverssl, *clientssl;
61     BIO *s_to_c_bio = NULL, *c_to_s_bio = NULL;
62
63     if (*sssl == NULL)
64         serverssl = SSL_new(serverctx);
65     else
66         serverssl = *sssl;
67     if (*cssl == NULL)
68         clientssl = SSL_new(clientctx);
69     else
70         clientssl = *cssl;
71
72     if (serverssl == NULL || clientssl == NULL) {
73         printf("Failed to create SSL object\n");
74         goto error;
75     }
76
77     s_to_c_bio = BIO_new(BIO_s_mem());
78     c_to_s_bio = BIO_new(BIO_s_mem());
79     if (s_to_c_bio == NULL || c_to_s_bio == NULL) {
80         printf("Failed to create mem BIOs\n");
81         goto error;
82     }
83
84     if (s_to_c_fbio != NULL)
85         s_to_c_bio = BIO_push(s_to_c_fbio, s_to_c_bio);
86     if (c_to_s_fbio != NULL)
87         c_to_s_bio = BIO_push(c_to_s_fbio, c_to_s_bio);
88     if (s_to_c_bio == NULL || c_to_s_bio == NULL) {
89         printf("Failed to create chained BIOs\n");
90         goto error;
91     }
92
93     /* Set Non-blocking IO behaviour */
94     BIO_set_mem_eof_return(s_to_c_bio, -1);
95     BIO_set_mem_eof_return(c_to_s_bio, -1);
96
97     /* Up ref these as we are passing them to two SSL objects */
98     BIO_up_ref(s_to_c_bio);
99     BIO_up_ref(c_to_s_bio);
100
101     SSL_set_bio(serverssl, c_to_s_bio, s_to_c_bio);
102     SSL_set_bio(clientssl, s_to_c_bio, c_to_s_bio);
103
104     /* BIOs will now be freed when SSL objects are freed */
105     s_to_c_bio = c_to_s_bio = NULL;
106     s_to_c_fbio = c_to_s_fbio = NULL;
107
108     do {
109         err = SSL_ERROR_WANT_WRITE;
110         while (!clienterr && retc <= 0 && err == SSL_ERROR_WANT_WRITE) {
111             retc = SSL_connect(clientssl);
112             if (retc <= 0)
113                 err = SSL_get_error(clientssl, retc);
114         }
115
116         if (!clienterr && retc <= 0 && err != SSL_ERROR_WANT_READ) {
117             printf("SSL_connect() failed %d, %d\n", retc, err);
118             clienterr = 1;
119         }
120
121         err = SSL_ERROR_WANT_WRITE;
122         while (!servererr && rets <= 0 && err == SSL_ERROR_WANT_WRITE) {
123             rets = SSL_accept(serverssl);
124             if (rets <= 0)
125                 err = SSL_get_error(serverssl, rets);
126         }
127
128         if (!servererr && rets <= 0 && err != SSL_ERROR_WANT_READ) {
129             printf("SSL_accept() failed %d, %d\n", retc, err);
130             servererr = 1;
131         }
132         if (clienterr && servererr)
133             goto error;
134         if (++abortctr == MAXLOOPS) {
135             printf("No progress made\n");
136             goto error;
137         }
138     } while (retc <=0 || rets <= 0);
139
140     *sssl = serverssl;
141     *cssl = clientssl;
142
143     return 1;
144
145  error:
146     if (*sssl == NULL) {
147         SSL_free(serverssl);
148         BIO_free(s_to_c_bio);
149         BIO_free(s_to_c_fbio);
150     }
151     if (*cssl == NULL) {
152         SSL_free(clientssl);
153         BIO_free(c_to_s_bio);
154         BIO_free(c_to_s_fbio);
155     }
156
157     return 0;
158 }