| GCC Code Coverage Report | |||||||||||||||||||||
        
  | 
    |||||||||||||||||||||
| Line | Branch | Exec | Source | 
1  | 
    /* $OpenBSD: bio_ssl.c,v 1.27 2017/02/07 02:08:38 beck Exp $ */  | 
    ||
2  | 
    /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)  | 
    ||
3  | 
    * All rights reserved.  | 
    ||
4  | 
    *  | 
    ||
5  | 
    * This package is an SSL implementation written  | 
    ||
6  | 
    * by Eric Young (eay@cryptsoft.com).  | 
    ||
7  | 
    * The implementation was written so as to conform with Netscapes SSL.  | 
    ||
8  | 
    *  | 
    ||
9  | 
    * This library is free for commercial and non-commercial use as long as  | 
    ||
10  | 
    * the following conditions are aheared to. The following conditions  | 
    ||
11  | 
    * apply to all code found in this distribution, be it the RC4, RSA,  | 
    ||
12  | 
    * lhash, DES, etc., code; not just the SSL code. The SSL documentation  | 
    ||
13  | 
    * included with this distribution is covered by the same copyright terms  | 
    ||
14  | 
    * except that the holder is Tim Hudson (tjh@cryptsoft.com).  | 
    ||
15  | 
    *  | 
    ||
16  | 
    * Copyright remains Eric Young's, and as such any Copyright notices in  | 
    ||
17  | 
    * the code are not to be removed.  | 
    ||
18  | 
    * If this package is used in a product, Eric Young should be given attribution  | 
    ||
19  | 
    * as the author of the parts of the library used.  | 
    ||
20  | 
    * This can be in the form of a textual message at program startup or  | 
    ||
21  | 
    * in documentation (online or textual) provided with the package.  | 
    ||
22  | 
    *  | 
    ||
23  | 
    * Redistribution and use in source and binary forms, with or without  | 
    ||
24  | 
    * modification, are permitted provided that the following conditions  | 
    ||
25  | 
    * are met:  | 
    ||
26  | 
    * 1. Redistributions of source code must retain the copyright  | 
    ||
27  | 
    * notice, this list of conditions and the following disclaimer.  | 
    ||
28  | 
    * 2. Redistributions in binary form must reproduce the above copyright  | 
    ||
29  | 
    * notice, this list of conditions and the following disclaimer in the  | 
    ||
30  | 
    * documentation and/or other materials provided with the distribution.  | 
    ||
31  | 
    * 3. All advertising materials mentioning features or use of this software  | 
    ||
32  | 
    * must display the following acknowledgement:  | 
    ||
33  | 
    * "This product includes cryptographic software written by  | 
    ||
34  | 
    * Eric Young (eay@cryptsoft.com)"  | 
    ||
35  | 
    * The word 'cryptographic' can be left out if the rouines from the library  | 
    ||
36  | 
    * being used are not cryptographic related :-).  | 
    ||
37  | 
    * 4. If you include any Windows specific code (or a derivative thereof) from  | 
    ||
38  | 
    * the apps directory (application code) you must include an acknowledgement:  | 
    ||
39  | 
    * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"  | 
    ||
40  | 
    *  | 
    ||
41  | 
    * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND  | 
    ||
42  | 
    * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  | 
    ||
43  | 
    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  | 
    ||
44  | 
    * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE  | 
    ||
45  | 
    * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  | 
    ||
46  | 
    * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  | 
    ||
47  | 
    * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  | 
    ||
48  | 
    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  | 
    ||
49  | 
    * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  | 
    ||
50  | 
    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  | 
    ||
51  | 
    * SUCH DAMAGE.  | 
    ||
52  | 
    *  | 
    ||
53  | 
    * The licence and distribution terms for any publically available version or  | 
    ||
54  | 
    * derivative of this code cannot be changed. i.e. this code cannot simply be  | 
    ||
55  | 
    * copied and put under another distribution licence  | 
    ||
56  | 
    * [including the GNU Public Licence.]  | 
    ||
57  | 
    */  | 
    ||
58  | 
    |||
59  | 
    #include <errno.h>  | 
    ||
60  | 
    #include <stdio.h>  | 
    ||
61  | 
    #include <stdlib.h>  | 
    ||
62  | 
    #include <string.h>  | 
    ||
63  | 
    |||
64  | 
    #include <openssl/bio.h>  | 
    ||
65  | 
    #include <openssl/crypto.h>  | 
    ||
66  | 
    #include <openssl/err.h>  | 
    ||
67  | 
    #include <openssl/ssl.h>  | 
    ||
68  | 
    |||
69  | 
    #include "ssl_locl.h"  | 
    ||
70  | 
    |||
71  | 
    static int ssl_write(BIO *h, const char *buf, int num);  | 
    ||
72  | 
    static int ssl_read(BIO *h, char *buf, int size);  | 
    ||
73  | 
    static int ssl_puts(BIO *h, const char *str);  | 
    ||
74  | 
    static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);  | 
    ||
75  | 
    static int ssl_new(BIO *h);  | 
    ||
76  | 
    static int ssl_free(BIO *data);  | 
    ||
77  | 
    static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);  | 
    ||
78  | 
    typedef struct bio_ssl_st { | 
    ||
79  | 
    SSL *ssl; /* The ssl handle :-) */  | 
    ||
80  | 
    /* re-negotiate every time the total number of bytes is this size */  | 
    ||
81  | 
    int num_renegotiates;  | 
    ||
82  | 
    unsigned long renegotiate_count;  | 
    ||
83  | 
    unsigned long byte_count;  | 
    ||
84  | 
    unsigned long renegotiate_timeout;  | 
    ||
85  | 
    time_t last_time;  | 
    ||
86  | 
    } BIO_SSL;  | 
    ||
87  | 
    |||
88  | 
    static BIO_METHOD methods_sslp = { | 
    ||
89  | 
    .type = BIO_TYPE_SSL,  | 
    ||
90  | 
    .name = "ssl",  | 
    ||
91  | 
    .bwrite = ssl_write,  | 
    ||
92  | 
    .bread = ssl_read,  | 
    ||
93  | 
    .bputs = ssl_puts,  | 
    ||
94  | 
    .ctrl = ssl_ctrl,  | 
    ||
95  | 
    .create = ssl_new,  | 
    ||
96  | 
    .destroy = ssl_free,  | 
    ||
97  | 
    .callback_ctrl = ssl_callback_ctrl,  | 
    ||
98  | 
    };  | 
    ||
99  | 
    |||
100  | 
    BIO_METHOD *  | 
    ||
101  | 
    BIO_f_ssl(void)  | 
    ||
102  | 
    { | 
    ||
103  | 
    720  | 
    return (&methods_sslp);  | 
    |
104  | 
    }  | 
    ||
105  | 
    |||
106  | 
    static int  | 
    ||
107  | 
    ssl_new(BIO *bi)  | 
    ||
108  | 
    { | 
    ||
109  | 
    BIO_SSL *bs;  | 
    ||
110  | 
    |||
111  | 
    720  | 
    bs = calloc(1, sizeof(BIO_SSL));  | 
    |
112  | 
    ✗✓ | 360  | 
    	if (bs == NULL) { | 
    
113  | 
    SSLerrorx(ERR_R_MALLOC_FAILURE);  | 
    ||
114  | 
    return (0);  | 
    ||
115  | 
    }  | 
    ||
116  | 
    360  | 
    bi->init = 0;  | 
    |
117  | 
    360  | 
    bi->ptr = (char *)bs;  | 
    |
118  | 
    360  | 
    bi->flags = 0;  | 
    |
119  | 
    360  | 
    return (1);  | 
    |
120  | 
    360  | 
    }  | 
    |
121  | 
    |||
122  | 
    static int  | 
    ||
123  | 
    ssl_free(BIO *a)  | 
    ||
124  | 
    { | 
    ||
125  | 
    BIO_SSL *bs;  | 
    ||
126  | 
    |||
127  | 
    ✗✓ | 720  | 
    if (a == NULL)  | 
    
128  | 
    return (0);  | 
    ||
129  | 
    360  | 
    bs = (BIO_SSL *)a->ptr;  | 
    |
130  | 
    ✓✗ | 360  | 
    if (bs->ssl != NULL)  | 
    
131  | 
    360  | 
    SSL_shutdown(bs->ssl);  | 
    |
132  | 
    ✗✓ | 360  | 
    	if (a->shutdown) { | 
    
133  | 
    if (a->init && (bs->ssl != NULL))  | 
    ||
134  | 
    SSL_free(bs->ssl);  | 
    ||
135  | 
    a->init = 0;  | 
    ||
136  | 
    a->flags = 0;  | 
    ||
137  | 
    }  | 
    ||
138  | 
    360  | 
    free(a->ptr);  | 
    |
139  | 
    360  | 
    return (1);  | 
    |
140  | 
    360  | 
    }  | 
    |
141  | 
    |||
142  | 
    static int  | 
    ||
143  | 
    ssl_read(BIO *b, char *out, int outl)  | 
    ||
144  | 
    { | 
    ||
145  | 
    int ret = 1;  | 
    ||
146  | 
    BIO_SSL *sb;  | 
    ||
147  | 
    SSL *ssl;  | 
    ||
148  | 
    int retry_reason = 0;  | 
    ||
149  | 
    int r = 0;  | 
    ||
150  | 
    |||
151  | 
    ✗✓ | 9612  | 
    if (out == NULL)  | 
    
152  | 
    return (0);  | 
    ||
153  | 
    9612  | 
    sb = (BIO_SSL *)b->ptr;  | 
    |
154  | 
    9612  | 
    ssl = sb->ssl;  | 
    |
155  | 
    |||
156  | 
    9612  | 
    BIO_clear_retry_flags(b);  | 
    |
157  | 
    |||
158  | 
    9612  | 
    ret = SSL_read(ssl, out, outl);  | 
    |
159  | 
    |||
160  | 
    ✓✓✓✗ ✗✗✓  | 
    9612  | 
    	switch (SSL_get_error(ssl, ret)) { | 
    
161  | 
    case SSL_ERROR_NONE:  | 
    ||
162  | 
    ✓✗ | 360  | 
    if (ret <= 0)  | 
    
163  | 
    break;  | 
    ||
164  | 
    ✗✓ | 360  | 
    		if (sb->renegotiate_count > 0) { | 
    
165  | 
    sb->byte_count += ret;  | 
    ||
166  | 
    			if (sb->byte_count > sb->renegotiate_count) { | 
    ||
167  | 
    sb->byte_count = 0;  | 
    ||
168  | 
    sb->num_renegotiates++;  | 
    ||
169  | 
    SSL_renegotiate(ssl);  | 
    ||
170  | 
    r = 1;  | 
    ||
171  | 
    }  | 
    ||
172  | 
    }  | 
    ||
173  | 
    ✗✓ | 360  | 
    		if ((sb->renegotiate_timeout > 0) && (!r)) { | 
    
174  | 
    time_t tm;  | 
    ||
175  | 
    |||
176  | 
    tm = time(NULL);  | 
    ||
177  | 
    			if (tm > sb->last_time + sb->renegotiate_timeout) { | 
    ||
178  | 
    sb->last_time = tm;  | 
    ||
179  | 
    sb->num_renegotiates++;  | 
    ||
180  | 
    SSL_renegotiate(ssl);  | 
    ||
181  | 
    }  | 
    ||
182  | 
    }  | 
    ||
183  | 
    |||
184  | 
    break;  | 
    ||
185  | 
    case SSL_ERROR_WANT_READ:  | 
    ||
186  | 
    3888  | 
    BIO_set_retry_read(b);  | 
    |
187  | 
    3888  | 
    break;  | 
    |
188  | 
    case SSL_ERROR_WANT_WRITE:  | 
    ||
189  | 
    558  | 
    BIO_set_retry_write(b);  | 
    |
190  | 
    558  | 
    break;  | 
    |
191  | 
    case SSL_ERROR_WANT_X509_LOOKUP:  | 
    ||
192  | 
    BIO_set_retry_special(b);  | 
    ||
193  | 
    retry_reason = BIO_RR_SSL_X509_LOOKUP;  | 
    ||
194  | 
    break;  | 
    ||
195  | 
    case SSL_ERROR_WANT_ACCEPT:  | 
    ||
196  | 
    BIO_set_retry_special(b);  | 
    ||
197  | 
    retry_reason = BIO_RR_ACCEPT;  | 
    ||
198  | 
    break;  | 
    ||
199  | 
    case SSL_ERROR_WANT_CONNECT:  | 
    ||
200  | 
    BIO_set_retry_special(b);  | 
    ||
201  | 
    retry_reason = BIO_RR_CONNECT;  | 
    ||
202  | 
    break;  | 
    ||
203  | 
    case SSL_ERROR_SYSCALL:  | 
    ||
204  | 
    case SSL_ERROR_SSL:  | 
    ||
205  | 
    case SSL_ERROR_ZERO_RETURN:  | 
    ||
206  | 
    default:  | 
    ||
207  | 
    break;  | 
    ||
208  | 
    }  | 
    ||
209  | 
    |||
210  | 
    4806  | 
    b->retry_reason = retry_reason;  | 
    |
211  | 
    4806  | 
    return (ret);  | 
    |
212  | 
    4806  | 
    }  | 
    |
213  | 
    |||
214  | 
    static int  | 
    ||
215  | 
    ssl_write(BIO *b, const char *out, int outl)  | 
    ||
216  | 
    { | 
    ||
217  | 
    int ret, r = 0;  | 
    ||
218  | 
    int retry_reason = 0;  | 
    ||
219  | 
    SSL *ssl;  | 
    ||
220  | 
    BIO_SSL *bs;  | 
    ||
221  | 
    |||
222  | 
    ✗✓ | 9180  | 
    if (out == NULL)  | 
    
223  | 
    return (0);  | 
    ||
224  | 
    9180  | 
    bs = (BIO_SSL *)b->ptr;  | 
    |
225  | 
    9180  | 
    ssl = bs->ssl;  | 
    |
226  | 
    |||
227  | 
    9180  | 
    BIO_clear_retry_flags(b);  | 
    |
228  | 
    |||
229  | 
    /* ret=SSL_do_handshake(ssl);  | 
    ||
230  | 
    if (ret > 0) */  | 
    ||
231  | 
    9180  | 
    ret = SSL_write(ssl, out, outl);  | 
    |
232  | 
    |||
233  | 
    ✓✓✓✗ ✗✓  | 
    9180  | 
    	switch (SSL_get_error(ssl, ret)) { | 
    
234  | 
    case SSL_ERROR_NONE:  | 
    ||
235  | 
    ✓✗ | 360  | 
    if (ret <= 0)  | 
    
236  | 
    break;  | 
    ||
237  | 
    ✗✓ | 360  | 
    		if (bs->renegotiate_count > 0) { | 
    
238  | 
    bs->byte_count += ret;  | 
    ||
239  | 
    			if (bs->byte_count > bs->renegotiate_count) { | 
    ||
240  | 
    bs->byte_count = 0;  | 
    ||
241  | 
    bs->num_renegotiates++;  | 
    ||
242  | 
    SSL_renegotiate(ssl);  | 
    ||
243  | 
    r = 1;  | 
    ||
244  | 
    }  | 
    ||
245  | 
    }  | 
    ||
246  | 
    ✗✓ | 360  | 
    		if ((bs->renegotiate_timeout > 0) && (!r)) { | 
    
247  | 
    time_t tm;  | 
    ||
248  | 
    |||
249  | 
    tm = time(NULL);  | 
    ||
250  | 
    			if (tm > bs->last_time + bs->renegotiate_timeout) { | 
    ||
251  | 
    bs->last_time = tm;  | 
    ||
252  | 
    bs->num_renegotiates++;  | 
    ||
253  | 
    SSL_renegotiate(ssl);  | 
    ||
254  | 
    }  | 
    ||
255  | 
    }  | 
    ||
256  | 
    break;  | 
    ||
257  | 
    case SSL_ERROR_WANT_WRITE:  | 
    ||
258  | 
    1116  | 
    BIO_set_retry_write(b);  | 
    |
259  | 
    1116  | 
    break;  | 
    |
260  | 
    case SSL_ERROR_WANT_READ:  | 
    ||
261  | 
    3114  | 
    BIO_set_retry_read(b);  | 
    |
262  | 
    3114  | 
    break;  | 
    |
263  | 
    case SSL_ERROR_WANT_X509_LOOKUP:  | 
    ||
264  | 
    BIO_set_retry_special(b);  | 
    ||
265  | 
    retry_reason = BIO_RR_SSL_X509_LOOKUP;  | 
    ||
266  | 
    break;  | 
    ||
267  | 
    case SSL_ERROR_WANT_CONNECT:  | 
    ||
268  | 
    BIO_set_retry_special(b);  | 
    ||
269  | 
    retry_reason = BIO_RR_CONNECT;  | 
    ||
270  | 
    case SSL_ERROR_SYSCALL:  | 
    ||
271  | 
    case SSL_ERROR_SSL:  | 
    ||
272  | 
    default:  | 
    ||
273  | 
    break;  | 
    ||
274  | 
    }  | 
    ||
275  | 
    |||
276  | 
    4590  | 
    b->retry_reason = retry_reason;  | 
    |
277  | 
    4590  | 
    return (ret);  | 
    |
278  | 
    4590  | 
    }  | 
    |
279  | 
    |||
280  | 
    static long  | 
    ||
281  | 
    ssl_ctrl(BIO *b, int cmd, long num, void *ptr)  | 
    ||
282  | 
    { | 
    ||
283  | 
    SSL **sslp, *ssl;  | 
    ||
284  | 
    BIO_SSL *bs;  | 
    ||
285  | 
    BIO *dbio, *bio;  | 
    ||
286  | 
    long ret = 1;  | 
    ||
287  | 
    |||
288  | 
    4176  | 
    bs = (BIO_SSL *)b->ptr;  | 
    |
289  | 
    2088  | 
    ssl = bs->ssl;  | 
    |
290  | 
    ✗✓ | 2088  | 
    if ((ssl == NULL) && (cmd != BIO_C_SET_SSL))  | 
    
291  | 
    return (0);  | 
    ||
292  | 
    ✗✗✗✗ ✗✗✓✗ ✗✗✗✓ ✗✗✗✗ ✗✗✗✗ ✗  | 
    2088  | 
    	switch (cmd) { | 
    
293  | 
    case BIO_CTRL_RESET:  | 
    ||
294  | 
    SSL_shutdown(ssl);  | 
    ||
295  | 
    |||
296  | 
    if (ssl->internal->handshake_func ==  | 
    ||
297  | 
    ssl->method->internal->ssl_connect)  | 
    ||
298  | 
    SSL_set_connect_state(ssl);  | 
    ||
299  | 
    else if (ssl->internal->handshake_func ==  | 
    ||
300  | 
    ssl->method->internal->ssl_accept)  | 
    ||
301  | 
    SSL_set_accept_state(ssl);  | 
    ||
302  | 
    |||
303  | 
    SSL_clear(ssl);  | 
    ||
304  | 
    |||
305  | 
    if (b->next_bio != NULL)  | 
    ||
306  | 
    ret = BIO_ctrl(b->next_bio, cmd, num, ptr);  | 
    ||
307  | 
    else if (ssl->rbio != NULL)  | 
    ||
308  | 
    ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);  | 
    ||
309  | 
    else  | 
    ||
310  | 
    ret = 1;  | 
    ||
311  | 
    break;  | 
    ||
312  | 
    case BIO_CTRL_INFO:  | 
    ||
313  | 
    ret = 0;  | 
    ||
314  | 
    break;  | 
    ||
315  | 
    case BIO_C_SSL_MODE:  | 
    ||
316  | 
    if (num) /* client mode */  | 
    ||
317  | 
    SSL_set_connect_state(ssl);  | 
    ||
318  | 
    else  | 
    ||
319  | 
    SSL_set_accept_state(ssl);  | 
    ||
320  | 
    break;  | 
    ||
321  | 
    case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:  | 
    ||
322  | 
    ret = bs->renegotiate_timeout;  | 
    ||
323  | 
    if (num < 60)  | 
    ||
324  | 
    num = 5;  | 
    ||
325  | 
    bs->renegotiate_timeout = (unsigned long)num;  | 
    ||
326  | 
    bs->last_time = time(NULL);  | 
    ||
327  | 
    break;  | 
    ||
328  | 
    case BIO_C_SET_SSL_RENEGOTIATE_BYTES:  | 
    ||
329  | 
    ret = bs->renegotiate_count;  | 
    ||
330  | 
    if ((long)num >=512)  | 
    ||
331  | 
    bs->renegotiate_count = (unsigned long)num;  | 
    ||
332  | 
    break;  | 
    ||
333  | 
    case BIO_C_GET_SSL_NUM_RENEGOTIATES:  | 
    ||
334  | 
    ret = bs->num_renegotiates;  | 
    ||
335  | 
    break;  | 
    ||
336  | 
    case BIO_C_SET_SSL:  | 
    ||
337  | 
    ✗✓ | 360  | 
    		if (ssl != NULL) { | 
    
338  | 
    ssl_free(b);  | 
    ||
339  | 
    if (!ssl_new(b))  | 
    ||
340  | 
    return 0;  | 
    ||
341  | 
    }  | 
    ||
342  | 
    360  | 
    b->shutdown = (int)num;  | 
    |
343  | 
    360  | 
    ssl = (SSL *)ptr;  | 
    |
344  | 
    360  | 
    ((BIO_SSL *)b->ptr)->ssl = ssl;  | 
    |
345  | 
    360  | 
    bio = SSL_get_rbio(ssl);  | 
    |
346  | 
    ✓✗ | 360  | 
    		if (bio != NULL) { | 
    
347  | 
    ✗✓ | 360  | 
    if (b->next_bio != NULL)  | 
    
348  | 
    BIO_push(bio, b->next_bio);  | 
    ||
349  | 
    360  | 
    b->next_bio = bio;  | 
    |
350  | 
    360  | 
    CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO);  | 
    |
351  | 
    360  | 
    }  | 
    |
352  | 
    360  | 
    b->init = 1;  | 
    |
353  | 
    360  | 
    break;  | 
    |
354  | 
    case BIO_C_GET_SSL:  | 
    ||
355  | 
    		if (ptr != NULL) { | 
    ||
356  | 
    sslp = (SSL **)ptr;  | 
    ||
357  | 
    *sslp = ssl;  | 
    ||
358  | 
    } else  | 
    ||
359  | 
    ret = 0;  | 
    ||
360  | 
    break;  | 
    ||
361  | 
    case BIO_CTRL_GET_CLOSE:  | 
    ||
362  | 
    ret = b->shutdown;  | 
    ||
363  | 
    break;  | 
    ||
364  | 
    case BIO_CTRL_SET_CLOSE:  | 
    ||
365  | 
    b->shutdown = (int)num;  | 
    ||
366  | 
    break;  | 
    ||
367  | 
    case BIO_CTRL_WPENDING:  | 
    ||
368  | 
    ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);  | 
    ||
369  | 
    break;  | 
    ||
370  | 
    case BIO_CTRL_PENDING:  | 
    ||
371  | 
    1728  | 
    ret = SSL_pending(ssl);  | 
    |
372  | 
    ✓✗ | 1728  | 
    if (ret == 0)  | 
    
373  | 
    1728  | 
    ret = BIO_pending(ssl->rbio);  | 
    |
374  | 
    break;  | 
    ||
375  | 
    case BIO_CTRL_FLUSH:  | 
    ||
376  | 
    BIO_clear_retry_flags(b);  | 
    ||
377  | 
    ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);  | 
    ||
378  | 
    BIO_copy_next_retry(b);  | 
    ||
379  | 
    break;  | 
    ||
380  | 
    case BIO_CTRL_PUSH:  | 
    ||
381  | 
    		if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) { | 
    ||
382  | 
    SSL_set_bio(ssl, b->next_bio, b->next_bio);  | 
    ||
383  | 
    CRYPTO_add(&b->next_bio->references, 1,  | 
    ||
384  | 
    CRYPTO_LOCK_BIO);  | 
    ||
385  | 
    }  | 
    ||
386  | 
    break;  | 
    ||
387  | 
    case BIO_CTRL_POP:  | 
    ||
388  | 
    /* Only detach if we are the BIO explicitly being popped */  | 
    ||
389  | 
    		if (b == ptr) { | 
    ||
390  | 
    /* Shouldn't happen in practice because the  | 
    ||
391  | 
    * rbio and wbio are the same when pushed.  | 
    ||
392  | 
    */  | 
    ||
393  | 
    if (ssl->rbio != ssl->wbio)  | 
    ||
394  | 
    BIO_free_all(ssl->wbio);  | 
    ||
395  | 
    if (b->next_bio != NULL)  | 
    ||
396  | 
    CRYPTO_add(&b->next_bio->references, -1, CRYPTO_LOCK_BIO);  | 
    ||
397  | 
    ssl->wbio = NULL;  | 
    ||
398  | 
    ssl->rbio = NULL;  | 
    ||
399  | 
    }  | 
    ||
400  | 
    break;  | 
    ||
401  | 
    case BIO_C_DO_STATE_MACHINE:  | 
    ||
402  | 
    BIO_clear_retry_flags(b);  | 
    ||
403  | 
    |||
404  | 
    b->retry_reason = 0;  | 
    ||
405  | 
    ret = (int)SSL_do_handshake(ssl);  | 
    ||
406  | 
    |||
407  | 
    		switch (SSL_get_error(ssl, (int)ret)) { | 
    ||
408  | 
    case SSL_ERROR_WANT_READ:  | 
    ||
409  | 
    BIO_set_flags(b,  | 
    ||
410  | 
    BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);  | 
    ||
411  | 
    break;  | 
    ||
412  | 
    case SSL_ERROR_WANT_WRITE:  | 
    ||
413  | 
    BIO_set_flags(b,  | 
    ||
414  | 
    BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY);  | 
    ||
415  | 
    break;  | 
    ||
416  | 
    case SSL_ERROR_WANT_CONNECT:  | 
    ||
417  | 
    BIO_set_flags(b,  | 
    ||
418  | 
    BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY);  | 
    ||
419  | 
    b->retry_reason = b->next_bio->retry_reason;  | 
    ||
420  | 
    break;  | 
    ||
421  | 
    default:  | 
    ||
422  | 
    break;  | 
    ||
423  | 
    }  | 
    ||
424  | 
    break;  | 
    ||
425  | 
    case BIO_CTRL_DUP:  | 
    ||
426  | 
    dbio = (BIO *)ptr;  | 
    ||
427  | 
    if (((BIO_SSL *)dbio->ptr)->ssl != NULL)  | 
    ||
428  | 
    SSL_free(((BIO_SSL *)dbio->ptr)->ssl);  | 
    ||
429  | 
    ((BIO_SSL *)dbio->ptr)->ssl = SSL_dup(ssl);  | 
    ||
430  | 
    ((BIO_SSL *)dbio->ptr)->renegotiate_count =  | 
    ||
431  | 
    ((BIO_SSL *)b->ptr)->renegotiate_count;  | 
    ||
432  | 
    ((BIO_SSL *)dbio->ptr)->byte_count =  | 
    ||
433  | 
    ((BIO_SSL *)b->ptr)->byte_count;  | 
    ||
434  | 
    ((BIO_SSL *)dbio->ptr)->renegotiate_timeout =  | 
    ||
435  | 
    ((BIO_SSL *)b->ptr)->renegotiate_timeout;  | 
    ||
436  | 
    ((BIO_SSL *)dbio->ptr)->last_time =  | 
    ||
437  | 
    ((BIO_SSL *)b->ptr)->last_time;  | 
    ||
438  | 
    ret = (((BIO_SSL *)dbio->ptr)->ssl != NULL);  | 
    ||
439  | 
    break;  | 
    ||
440  | 
    case BIO_C_GET_FD:  | 
    ||
441  | 
    ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);  | 
    ||
442  | 
    break;  | 
    ||
443  | 
    case BIO_CTRL_SET_CALLBACK:  | 
    ||
444  | 
    		{ | 
    ||
445  | 
    ret = 0;  | 
    ||
446  | 
    }  | 
    ||
447  | 
    break;  | 
    ||
448  | 
    case BIO_CTRL_GET_CALLBACK:  | 
    ||
449  | 
    		{ | 
    ||
450  | 
    void (**fptr)(const SSL *xssl, int type, int val);  | 
    ||
451  | 
    |||
452  | 
    fptr = (void (**)(const SSL *xssl, int type, int val))  | 
    ||
453  | 
    ptr;  | 
    ||
454  | 
    *fptr = SSL_get_info_callback(ssl);  | 
    ||
455  | 
    }  | 
    ||
456  | 
    break;  | 
    ||
457  | 
    default:  | 
    ||
458  | 
    ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);  | 
    ||
459  | 
    break;  | 
    ||
460  | 
    }  | 
    ||
461  | 
    2088  | 
    return (ret);  | 
    |
462  | 
    2088  | 
    }  | 
    |
463  | 
    |||
464  | 
    static long  | 
    ||
465  | 
    ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)  | 
    ||
466  | 
    { | 
    ||
467  | 
    SSL *ssl;  | 
    ||
468  | 
    BIO_SSL *bs;  | 
    ||
469  | 
    long ret = 1;  | 
    ||
470  | 
    |||
471  | 
    bs = (BIO_SSL *)b->ptr;  | 
    ||
472  | 
    ssl = bs->ssl;  | 
    ||
473  | 
    	switch (cmd) { | 
    ||
474  | 
    case BIO_CTRL_SET_CALLBACK:  | 
    ||
475  | 
    		{ | 
    ||
476  | 
    /* FIXME: setting this via a completely different prototype  | 
    ||
477  | 
    seems like a crap idea */  | 
    ||
478  | 
    SSL_set_info_callback(ssl,  | 
    ||
479  | 
    (void (*)(const SSL *, int, int))fp);  | 
    ||
480  | 
    }  | 
    ||
481  | 
    break;  | 
    ||
482  | 
    default:  | 
    ||
483  | 
    ret = BIO_callback_ctrl(ssl->rbio, cmd, fp);  | 
    ||
484  | 
    break;  | 
    ||
485  | 
    }  | 
    ||
486  | 
    return (ret);  | 
    ||
487  | 
    }  | 
    ||
488  | 
    |||
489  | 
    static int  | 
    ||
490  | 
    ssl_puts(BIO *bp, const char *str)  | 
    ||
491  | 
    { | 
    ||
492  | 
    int n, ret;  | 
    ||
493  | 
    |||
494  | 
    n = strlen(str);  | 
    ||
495  | 
    ret = BIO_write(bp, str, n);  | 
    ||
496  | 
    return (ret);  | 
    ||
497  | 
    }  | 
    ||
498  | 
    |||
499  | 
    BIO *  | 
    ||
500  | 
    BIO_new_buffer_ssl_connect(SSL_CTX *ctx)  | 
    ||
501  | 
    { | 
    ||
502  | 
    BIO *ret = NULL, *buf = NULL, *ssl = NULL;  | 
    ||
503  | 
    |||
504  | 
    if ((buf = BIO_new(BIO_f_buffer())) == NULL)  | 
    ||
505  | 
    goto err;  | 
    ||
506  | 
    if ((ssl = BIO_new_ssl_connect(ctx)) == NULL)  | 
    ||
507  | 
    goto err;  | 
    ||
508  | 
    if ((ret = BIO_push(buf, ssl)) == NULL)  | 
    ||
509  | 
    goto err;  | 
    ||
510  | 
    return (ret);  | 
    ||
511  | 
    |||
512  | 
    err:  | 
    ||
513  | 
    BIO_free(buf);  | 
    ||
514  | 
    BIO_free(ssl);  | 
    ||
515  | 
    return (NULL);  | 
    ||
516  | 
    }  | 
    ||
517  | 
    |||
518  | 
    BIO *  | 
    ||
519  | 
    BIO_new_ssl_connect(SSL_CTX *ctx)  | 
    ||
520  | 
    { | 
    ||
521  | 
    BIO *ret = NULL, *con = NULL, *ssl = NULL;  | 
    ||
522  | 
    |||
523  | 
    if ((con = BIO_new(BIO_s_connect())) == NULL)  | 
    ||
524  | 
    goto err;  | 
    ||
525  | 
    if ((ssl = BIO_new_ssl(ctx, 1)) == NULL)  | 
    ||
526  | 
    goto err;  | 
    ||
527  | 
    if ((ret = BIO_push(ssl, con)) == NULL)  | 
    ||
528  | 
    goto err;  | 
    ||
529  | 
    return (ret);  | 
    ||
530  | 
    |||
531  | 
    err:  | 
    ||
532  | 
    BIO_free(con);  | 
    ||
533  | 
    BIO_free(ssl);  | 
    ||
534  | 
    return (NULL);  | 
    ||
535  | 
    }  | 
    ||
536  | 
    |||
537  | 
    BIO *  | 
    ||
538  | 
    BIO_new_ssl(SSL_CTX *ctx, int client)  | 
    ||
539  | 
    { | 
    ||
540  | 
    BIO *ret;  | 
    ||
541  | 
    SSL *ssl;  | 
    ||
542  | 
    |||
543  | 
    if ((ret = BIO_new(BIO_f_ssl())) == NULL)  | 
    ||
544  | 
    goto err;  | 
    ||
545  | 
    if ((ssl = SSL_new(ctx)) == NULL)  | 
    ||
546  | 
    goto err;  | 
    ||
547  | 
    |||
548  | 
    if (client)  | 
    ||
549  | 
    SSL_set_connect_state(ssl);  | 
    ||
550  | 
    else  | 
    ||
551  | 
    SSL_set_accept_state(ssl);  | 
    ||
552  | 
    |||
553  | 
    BIO_set_ssl(ret, ssl, BIO_CLOSE);  | 
    ||
554  | 
    return (ret);  | 
    ||
555  | 
    |||
556  | 
    err:  | 
    ||
557  | 
    BIO_free(ret);  | 
    ||
558  | 
    return (NULL);  | 
    ||
559  | 
    }  | 
    ||
560  | 
    |||
561  | 
    int  | 
    ||
562  | 
    BIO_ssl_copy_session_id(BIO *t, BIO *f)  | 
    ||
563  | 
    { | 
    ||
564  | 
    t = BIO_find_type(t, BIO_TYPE_SSL);  | 
    ||
565  | 
    f = BIO_find_type(f, BIO_TYPE_SSL);  | 
    ||
566  | 
    if ((t == NULL) || (f == NULL))  | 
    ||
567  | 
    return (0);  | 
    ||
568  | 
    if ((((BIO_SSL *)t->ptr)->ssl == NULL) ||  | 
    ||
569  | 
    (((BIO_SSL *)f->ptr)->ssl == NULL))  | 
    ||
570  | 
    return (0);  | 
    ||
571  | 
    SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl, ((BIO_SSL *)f->ptr)->ssl);  | 
    ||
572  | 
    return (1);  | 
    ||
573  | 
    }  | 
    ||
574  | 
    |||
575  | 
    void  | 
    ||
576  | 
    BIO_ssl_shutdown(BIO *b)  | 
    ||
577  | 
    { | 
    ||
578  | 
    SSL *s;  | 
    ||
579  | 
    |||
580  | 
    	while (b != NULL) { | 
    ||
581  | 
    		if (b->method->type == BIO_TYPE_SSL) { | 
    ||
582  | 
    s = ((BIO_SSL *)b->ptr)->ssl;  | 
    ||
583  | 
    SSL_shutdown(s);  | 
    ||
584  | 
    break;  | 
    ||
585  | 
    }  | 
    ||
586  | 
    b = b->next_bio;  | 
    ||
587  | 
    }  | 
    ||
588  | 
    }  | 
    
| Generated by: GCOVR (Version 3.3) |