5f780d75b8680835d37ba10ef8d654bb175208f7
[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(TLS_server_method());
20     clientctx = SSL_CTX_new(TLS_client_method());
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     SSL *serverssl, *clientssl;
60     BIO *s_to_c_bio = NULL, *c_to_s_bio = NULL;
61
62     serverssl = SSL_new(serverctx);
63     clientssl = SSL_new(clientctx);
64
65     if (serverssl == NULL || clientssl == NULL) {
66         printf("Failed to create SSL object\n");
67         goto error;
68     }
69
70     s_to_c_bio = BIO_new(BIO_s_mem());
71     c_to_s_bio = BIO_new(BIO_s_mem());
72     if (s_to_c_bio == NULL || c_to_s_bio == NULL) {
73         printf("Failed to create mem BIOs\n");
74         goto error;
75     }
76
77     if (s_to_c_fbio != NULL)
78         s_to_c_bio = BIO_push(s_to_c_fbio, s_to_c_bio);
79     if (c_to_s_fbio != NULL)
80         c_to_s_bio = BIO_push(c_to_s_fbio, c_to_s_bio);
81     if (s_to_c_bio == NULL || c_to_s_bio == NULL) {
82         printf("Failed to create chained BIOs\n");
83         goto error;
84     }
85
86     /* Set Non-blocking IO behaviour */
87     BIO_set_mem_eof_return(s_to_c_bio, -1);
88     BIO_set_mem_eof_return(c_to_s_bio, -1);
89
90     /* Up ref these as we are passing them to two SSL objects */
91     BIO_up_ref(s_to_c_bio);
92     BIO_up_ref(c_to_s_bio);
93
94     SSL_set_bio(serverssl, c_to_s_bio, s_to_c_bio);
95     SSL_set_bio(clientssl, s_to_c_bio, c_to_s_bio);
96
97     /* BIOs will now be freed when SSL objects are freed */
98     s_to_c_bio = c_to_s_bio = NULL;
99     s_to_c_fbio = c_to_s_fbio = NULL;
100
101     do {
102         err = SSL_ERROR_WANT_WRITE;
103         while (retc <= 0 && err == SSL_ERROR_WANT_WRITE) {
104             retc = SSL_connect(clientssl);
105             if (retc <= 0)
106                 err = SSL_get_error(clientssl, retc);
107         }
108
109         if (retc <= 0 && err != SSL_ERROR_WANT_READ) {
110             printf("SSL_connect() failed %d, %d\n", retc, err);
111             goto error;
112         }
113
114         err = SSL_ERROR_WANT_WRITE;
115         while (rets <= 0 && err == SSL_ERROR_WANT_WRITE) {
116             rets = SSL_accept(serverssl);
117             if (rets <= 0)
118                 err = SSL_get_error(serverssl, rets);
119         }
120
121         if (rets <= 0 && err != SSL_ERROR_WANT_READ) {
122             printf("SSL_accept() failed %d, %d\n", retc, err);
123             goto error;
124         }
125         if (++abortctr == MAXLOOPS) {
126             printf("No progress made\n");
127             goto error;
128         }
129     } while (retc <=0 || rets <= 0);
130
131     *sssl = serverssl;
132     *cssl = clientssl;
133
134     return 1;
135
136  error:
137     SSL_free(serverssl);
138     SSL_free(clientssl);
139     BIO_free(s_to_c_bio);
140     BIO_free(c_to_s_bio);
141     BIO_free(s_to_c_fbio);
142     BIO_free(c_to_s_fbio);
143
144     return 0;
145 }