xref: /netbsd-src/crypto/external/bsd/openssl/dist/ssl/bio_ssl.c (revision 97e3c58506797315d86c0608cba9d3f55de0c735)
1c7da899bSchristos /*
2*97e3c585Schristos  * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
3a89c9211Schristos  *
4b0d17251Schristos  * Licensed under the Apache License 2.0 (the "License").  You may not use
5c7da899bSchristos  * this file except in compliance with the License.  You can obtain a copy
6c7da899bSchristos  * in the file LICENSE in the source distribution or at
7c7da899bSchristos  * https://www.openssl.org/source/license.html
8a89c9211Schristos  */
9a89c9211Schristos 
10a89c9211Schristos #include <stdio.h>
11a89c9211Schristos #include <stdlib.h>
12a89c9211Schristos #include <string.h>
13a89c9211Schristos #include <errno.h>
14a89c9211Schristos #include <openssl/crypto.h>
15c7da899bSchristos #include "internal/bio.h"
16a89c9211Schristos #include <openssl/err.h>
177d004720Schristos #include "ssl_local.h"
18a89c9211Schristos 
1913d40330Schristos static int ssl_write(BIO *h, const char *buf, size_t size, size_t *written);
2013d40330Schristos static int ssl_read(BIO *b, char *buf, size_t size, size_t *readbytes);
21a89c9211Schristos static int ssl_puts(BIO *h, const char *str);
22a89c9211Schristos static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
23a89c9211Schristos static int ssl_new(BIO *h);
24a89c9211Schristos static int ssl_free(BIO *data);
2553060421Schristos static long ssl_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
26635165faSspz typedef struct bio_ssl_st {
27a89c9211Schristos     SSL *ssl;                   /* The ssl handle :-) */
28a89c9211Schristos     /* re-negotiate every time the total number of bytes is this size */
29a89c9211Schristos     int num_renegotiates;
30a89c9211Schristos     unsigned long renegotiate_count;
3113d40330Schristos     size_t byte_count;
32a89c9211Schristos     unsigned long renegotiate_timeout;
33a89c9211Schristos     unsigned long last_time;
34a89c9211Schristos } BIO_SSL;
35a89c9211Schristos 
36c7da899bSchristos static const BIO_METHOD methods_sslp = {
3753060421Schristos     BIO_TYPE_SSL,
3853060421Schristos     "ssl",
39a89c9211Schristos     ssl_write,
4013d40330Schristos     NULL,                       /* ssl_write_old, */
41a89c9211Schristos     ssl_read,
4213d40330Schristos     NULL,                       /* ssl_read_old,  */
43a89c9211Schristos     ssl_puts,
44a89c9211Schristos     NULL,                       /* ssl_gets,      */
45a89c9211Schristos     ssl_ctrl,
46a89c9211Schristos     ssl_new,
47a89c9211Schristos     ssl_free,
48a89c9211Schristos     ssl_callback_ctrl,
49a89c9211Schristos };
50a89c9211Schristos 
51c7da899bSchristos const BIO_METHOD *BIO_f_ssl(void)
52a89c9211Schristos {
5313d40330Schristos     return &methods_sslp;
54a89c9211Schristos }
55a89c9211Schristos 
56a89c9211Schristos static int ssl_new(BIO *bi)
57a89c9211Schristos {
58c7da899bSchristos     BIO_SSL *bs = OPENSSL_zalloc(sizeof(*bs));
59a89c9211Schristos 
60635165faSspz     if (bs == NULL) {
61b0d17251Schristos         ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
6213d40330Schristos         return 0;
63a89c9211Schristos     }
64c7da899bSchristos     BIO_set_init(bi, 0);
65c7da899bSchristos     BIO_set_data(bi, bs);
66c7da899bSchristos     /* Clear all flags */
67c7da899bSchristos     BIO_clear_flags(bi, ~0);
68c7da899bSchristos 
69c7da899bSchristos     return 1;
70a89c9211Schristos }
71a89c9211Schristos 
72a89c9211Schristos static int ssl_free(BIO *a)
73a89c9211Schristos {
74a89c9211Schristos     BIO_SSL *bs;
75a89c9211Schristos 
76635165faSspz     if (a == NULL)
7713d40330Schristos         return 0;
78c7da899bSchristos     bs = BIO_get_data(a);
7921497c5cSchristos     if (BIO_get_shutdown(a)) {
80*97e3c585Schristos         if (bs->ssl != NULL && !SSL_in_init(bs->ssl))
81635165faSspz             SSL_shutdown(bs->ssl);
82c7da899bSchristos         if (BIO_get_init(a))
83a89c9211Schristos             SSL_free(bs->ssl);
8421497c5cSchristos         BIO_clear_flags(a, ~0); /* Clear all flags */
85c7da899bSchristos         BIO_set_init(a, 0);
86a89c9211Schristos     }
87c7da899bSchristos     OPENSSL_free(bs);
88c7da899bSchristos     return 1;
89a89c9211Schristos }
90a89c9211Schristos 
9113d40330Schristos static int ssl_read(BIO *b, char *buf, size_t size, size_t *readbytes)
92a89c9211Schristos {
93a89c9211Schristos     int ret = 1;
94a89c9211Schristos     BIO_SSL *sb;
95a89c9211Schristos     SSL *ssl;
96a89c9211Schristos     int retry_reason = 0;
97a89c9211Schristos     int r = 0;
98a89c9211Schristos 
9913d40330Schristos     if (buf == NULL)
10013d40330Schristos         return 0;
101c7da899bSchristos     sb = BIO_get_data(b);
102a89c9211Schristos     ssl = sb->ssl;
103a89c9211Schristos 
104a89c9211Schristos     BIO_clear_retry_flags(b);
105a89c9211Schristos 
10613d40330Schristos     ret = ssl_read_internal(ssl, buf, size, readbytes);
107a89c9211Schristos 
108635165faSspz     switch (SSL_get_error(ssl, ret)) {
109a89c9211Schristos     case SSL_ERROR_NONE:
110635165faSspz         if (sb->renegotiate_count > 0) {
11113d40330Schristos             sb->byte_count += *readbytes;
112635165faSspz             if (sb->byte_count > sb->renegotiate_count) {
113a89c9211Schristos                 sb->byte_count = 0;
114a89c9211Schristos                 sb->num_renegotiates++;
115a89c9211Schristos                 SSL_renegotiate(ssl);
116a89c9211Schristos                 r = 1;
117a89c9211Schristos             }
118a89c9211Schristos         }
119635165faSspz         if ((sb->renegotiate_timeout > 0) && (!r)) {
120a89c9211Schristos             unsigned long tm;
121a89c9211Schristos 
122a89c9211Schristos             tm = (unsigned long)time(NULL);
123635165faSspz             if (tm > sb->last_time + sb->renegotiate_timeout) {
124a89c9211Schristos                 sb->last_time = tm;
125a89c9211Schristos                 sb->num_renegotiates++;
126a89c9211Schristos                 SSL_renegotiate(ssl);
127a89c9211Schristos             }
128a89c9211Schristos         }
129a89c9211Schristos 
130a89c9211Schristos         break;
131a89c9211Schristos     case SSL_ERROR_WANT_READ:
132a89c9211Schristos         BIO_set_retry_read(b);
133a89c9211Schristos         break;
134a89c9211Schristos     case SSL_ERROR_WANT_WRITE:
135a89c9211Schristos         BIO_set_retry_write(b);
136a89c9211Schristos         break;
137a89c9211Schristos     case SSL_ERROR_WANT_X509_LOOKUP:
138a89c9211Schristos         BIO_set_retry_special(b);
139a89c9211Schristos         retry_reason = BIO_RR_SSL_X509_LOOKUP;
140a89c9211Schristos         break;
141a89c9211Schristos     case SSL_ERROR_WANT_ACCEPT:
142a89c9211Schristos         BIO_set_retry_special(b);
143a89c9211Schristos         retry_reason = BIO_RR_ACCEPT;
144a89c9211Schristos         break;
145a89c9211Schristos     case SSL_ERROR_WANT_CONNECT:
146a89c9211Schristos         BIO_set_retry_special(b);
147a89c9211Schristos         retry_reason = BIO_RR_CONNECT;
148a89c9211Schristos         break;
149a89c9211Schristos     case SSL_ERROR_SYSCALL:
150a89c9211Schristos     case SSL_ERROR_SSL:
151a89c9211Schristos     case SSL_ERROR_ZERO_RETURN:
152a89c9211Schristos     default:
153a89c9211Schristos         break;
154a89c9211Schristos     }
155a89c9211Schristos 
156c7da899bSchristos     BIO_set_retry_reason(b, retry_reason);
15713d40330Schristos 
15813d40330Schristos     return ret;
159a89c9211Schristos }
160a89c9211Schristos 
16113d40330Schristos static int ssl_write(BIO *b, const char *buf, size_t size, size_t *written)
162a89c9211Schristos {
163a89c9211Schristos     int ret, r = 0;
164a89c9211Schristos     int retry_reason = 0;
165a89c9211Schristos     SSL *ssl;
166a89c9211Schristos     BIO_SSL *bs;
167a89c9211Schristos 
16813d40330Schristos     if (buf == NULL)
16913d40330Schristos         return 0;
170c7da899bSchristos     bs = BIO_get_data(b);
171a89c9211Schristos     ssl = bs->ssl;
172a89c9211Schristos 
173a89c9211Schristos     BIO_clear_retry_flags(b);
174a89c9211Schristos 
17513d40330Schristos     ret = ssl_write_internal(ssl, buf, size, written);
176a89c9211Schristos 
177635165faSspz     switch (SSL_get_error(ssl, ret)) {
178a89c9211Schristos     case SSL_ERROR_NONE:
179635165faSspz         if (bs->renegotiate_count > 0) {
18013d40330Schristos             bs->byte_count += *written;
181635165faSspz             if (bs->byte_count > bs->renegotiate_count) {
182a89c9211Schristos                 bs->byte_count = 0;
183a89c9211Schristos                 bs->num_renegotiates++;
184a89c9211Schristos                 SSL_renegotiate(ssl);
185a89c9211Schristos                 r = 1;
186a89c9211Schristos             }
187a89c9211Schristos         }
188635165faSspz         if ((bs->renegotiate_timeout > 0) && (!r)) {
189a89c9211Schristos             unsigned long tm;
190a89c9211Schristos 
191a89c9211Schristos             tm = (unsigned long)time(NULL);
192635165faSspz             if (tm > bs->last_time + bs->renegotiate_timeout) {
193a89c9211Schristos                 bs->last_time = tm;
194a89c9211Schristos                 bs->num_renegotiates++;
195a89c9211Schristos                 SSL_renegotiate(ssl);
196a89c9211Schristos             }
197a89c9211Schristos         }
198a89c9211Schristos         break;
199a89c9211Schristos     case SSL_ERROR_WANT_WRITE:
200a89c9211Schristos         BIO_set_retry_write(b);
201a89c9211Schristos         break;
202a89c9211Schristos     case SSL_ERROR_WANT_READ:
203a89c9211Schristos         BIO_set_retry_read(b);
204a89c9211Schristos         break;
205a89c9211Schristos     case SSL_ERROR_WANT_X509_LOOKUP:
206a89c9211Schristos         BIO_set_retry_special(b);
207a89c9211Schristos         retry_reason = BIO_RR_SSL_X509_LOOKUP;
208a89c9211Schristos         break;
209a89c9211Schristos     case SSL_ERROR_WANT_CONNECT:
210a89c9211Schristos         BIO_set_retry_special(b);
211a89c9211Schristos         retry_reason = BIO_RR_CONNECT;
212a89c9211Schristos     case SSL_ERROR_SYSCALL:
213a89c9211Schristos     case SSL_ERROR_SSL:
214a89c9211Schristos     default:
215a89c9211Schristos         break;
216a89c9211Schristos     }
217a89c9211Schristos 
218c7da899bSchristos     BIO_set_retry_reason(b, retry_reason);
21913d40330Schristos 
220c7da899bSchristos     return ret;
221a89c9211Schristos }
222a89c9211Schristos 
223a89c9211Schristos static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
224a89c9211Schristos {
225a89c9211Schristos     SSL **sslp, *ssl;
226c7da899bSchristos     BIO_SSL *bs, *dbs;
227a89c9211Schristos     BIO *dbio, *bio;
228a89c9211Schristos     long ret = 1;
229c7da899bSchristos     BIO *next;
230a89c9211Schristos 
231c7da899bSchristos     bs = BIO_get_data(b);
232c7da899bSchristos     next = BIO_next(b);
233a89c9211Schristos     ssl = bs->ssl;
234a89c9211Schristos     if ((ssl == NULL) && (cmd != BIO_C_SET_SSL))
23513d40330Schristos         return 0;
236635165faSspz     switch (cmd) {
237a89c9211Schristos     case BIO_CTRL_RESET:
238a89c9211Schristos         SSL_shutdown(ssl);
239a89c9211Schristos 
240a89c9211Schristos         if (ssl->handshake_func == ssl->method->ssl_connect)
241a89c9211Schristos             SSL_set_connect_state(ssl);
242a89c9211Schristos         else if (ssl->handshake_func == ssl->method->ssl_accept)
243a89c9211Schristos             SSL_set_accept_state(ssl);
244a89c9211Schristos 
245c7da899bSchristos         if (!SSL_clear(ssl)) {
246c7da899bSchristos             ret = 0;
247c7da899bSchristos             break;
248c7da899bSchristos         }
249a89c9211Schristos 
250c7da899bSchristos         if (next != NULL)
251c7da899bSchristos             ret = BIO_ctrl(next, cmd, num, ptr);
252a89c9211Schristos         else if (ssl->rbio != NULL)
253a89c9211Schristos             ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
254a89c9211Schristos         else
255a89c9211Schristos             ret = 1;
256a89c9211Schristos         break;
257a89c9211Schristos     case BIO_CTRL_INFO:
258a89c9211Schristos         ret = 0;
259a89c9211Schristos         break;
260a89c9211Schristos     case BIO_C_SSL_MODE:
261a89c9211Schristos         if (num)                /* client mode */
262a89c9211Schristos             SSL_set_connect_state(ssl);
263a89c9211Schristos         else
264a89c9211Schristos             SSL_set_accept_state(ssl);
265a89c9211Schristos         break;
266a89c9211Schristos     case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:
267a89c9211Schristos         ret = bs->renegotiate_timeout;
268635165faSspz         if (num < 60)
269635165faSspz             num = 5;
270a89c9211Schristos         bs->renegotiate_timeout = (unsigned long)num;
271a89c9211Schristos         bs->last_time = (unsigned long)time(NULL);
272a89c9211Schristos         break;
273a89c9211Schristos     case BIO_C_SET_SSL_RENEGOTIATE_BYTES:
274a89c9211Schristos         ret = bs->renegotiate_count;
275a89c9211Schristos         if ((long)num >= 512)
276a89c9211Schristos             bs->renegotiate_count = (unsigned long)num;
277a89c9211Schristos         break;
278a89c9211Schristos     case BIO_C_GET_SSL_NUM_RENEGOTIATES:
279a89c9211Schristos         ret = bs->num_renegotiates;
280a89c9211Schristos         break;
281a89c9211Schristos     case BIO_C_SET_SSL:
282635165faSspz         if (ssl != NULL) {
283a89c9211Schristos             ssl_free(b);
2844e3dcb23Sspz             if (!ssl_new(b))
2854e3dcb23Sspz                 return 0;
286f30e0929Schristos             bs = BIO_get_data(b);
2874e3dcb23Sspz         }
288c7da899bSchristos         BIO_set_shutdown(b, num);
289a89c9211Schristos         ssl = (SSL *)ptr;
290c7da899bSchristos         bs->ssl = ssl;
291a89c9211Schristos         bio = SSL_get_rbio(ssl);
292635165faSspz         if (bio != NULL) {
293c7da899bSchristos             if (next != NULL)
294c7da899bSchristos                 BIO_push(bio, next);
295c7da899bSchristos             BIO_set_next(b, bio);
296c7da899bSchristos             BIO_up_ref(bio);
297a89c9211Schristos         }
298c7da899bSchristos         BIO_set_init(b, 1);
299a89c9211Schristos         break;
300a89c9211Schristos     case BIO_C_GET_SSL:
301635165faSspz         if (ptr != NULL) {
302a89c9211Schristos             sslp = (SSL **)ptr;
303a89c9211Schristos             *sslp = ssl;
304635165faSspz         } else
305a89c9211Schristos             ret = 0;
306a89c9211Schristos         break;
307a89c9211Schristos     case BIO_CTRL_GET_CLOSE:
308c7da899bSchristos         ret = BIO_get_shutdown(b);
309a89c9211Schristos         break;
310a89c9211Schristos     case BIO_CTRL_SET_CLOSE:
311c7da899bSchristos         BIO_set_shutdown(b, (int)num);
312a89c9211Schristos         break;
313a89c9211Schristos     case BIO_CTRL_WPENDING:
314a89c9211Schristos         ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
315a89c9211Schristos         break;
316a89c9211Schristos     case BIO_CTRL_PENDING:
317a89c9211Schristos         ret = SSL_pending(ssl);
318a89c9211Schristos         if (ret == 0)
319a89c9211Schristos             ret = BIO_pending(ssl->rbio);
320a89c9211Schristos         break;
321a89c9211Schristos     case BIO_CTRL_FLUSH:
322a89c9211Schristos         BIO_clear_retry_flags(b);
323a89c9211Schristos         ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
324a89c9211Schristos         BIO_copy_next_retry(b);
325a89c9211Schristos         break;
326a89c9211Schristos     case BIO_CTRL_PUSH:
327c7da899bSchristos         if ((next != NULL) && (next != ssl->rbio)) {
328c7da899bSchristos             /*
329c7da899bSchristos              * We are going to pass ownership of next to the SSL object...but
330c7da899bSchristos              * we don't own a reference to pass yet - so up ref
331c7da899bSchristos              */
332c7da899bSchristos             BIO_up_ref(next);
333c7da899bSchristos             SSL_set_bio(ssl, next, next);
334a89c9211Schristos         }
335a89c9211Schristos         break;
336a89c9211Schristos     case BIO_CTRL_POP:
337a89c9211Schristos         /* Only detach if we are the BIO explicitly being popped */
338635165faSspz         if (b == ptr) {
339c7da899bSchristos             /* This will clear the reference we obtained during push */
340c7da899bSchristos             SSL_set_bio(ssl, NULL, NULL);
341a89c9211Schristos         }
342a89c9211Schristos         break;
343a89c9211Schristos     case BIO_C_DO_STATE_MACHINE:
344a89c9211Schristos         BIO_clear_retry_flags(b);
345a89c9211Schristos 
346c7da899bSchristos         BIO_set_retry_reason(b, 0);
347a89c9211Schristos         ret = (int)SSL_do_handshake(ssl);
348a89c9211Schristos 
349635165faSspz         switch (SSL_get_error(ssl, (int)ret)) {
350a89c9211Schristos         case SSL_ERROR_WANT_READ:
351635165faSspz             BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY);
352a89c9211Schristos             break;
353a89c9211Schristos         case SSL_ERROR_WANT_WRITE:
354635165faSspz             BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY);
355a89c9211Schristos             break;
356a89c9211Schristos         case SSL_ERROR_WANT_CONNECT:
357635165faSspz             BIO_set_flags(b, BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY);
358c7da899bSchristos             BIO_set_retry_reason(b, BIO_get_retry_reason(next));
359a89c9211Schristos             break;
3603e7df5c2Schristos         case SSL_ERROR_WANT_X509_LOOKUP:
3613e7df5c2Schristos             BIO_set_retry_special(b);
362c7da899bSchristos             BIO_set_retry_reason(b, BIO_RR_SSL_X509_LOOKUP);
3633e7df5c2Schristos             break;
364a89c9211Schristos         default:
365a89c9211Schristos             break;
366a89c9211Schristos         }
367a89c9211Schristos         break;
368a89c9211Schristos     case BIO_CTRL_DUP:
369a89c9211Schristos         dbio = (BIO *)ptr;
370c7da899bSchristos         dbs = BIO_get_data(dbio);
371c7da899bSchristos         SSL_free(dbs->ssl);
372c7da899bSchristos         dbs->ssl = SSL_dup(ssl);
373c7da899bSchristos         dbs->num_renegotiates = bs->num_renegotiates;
374c7da899bSchristos         dbs->renegotiate_count = bs->renegotiate_count;
375c7da899bSchristos         dbs->byte_count = bs->byte_count;
376c7da899bSchristos         dbs->renegotiate_timeout = bs->renegotiate_timeout;
377c7da899bSchristos         dbs->last_time = bs->last_time;
378c7da899bSchristos         ret = (dbs->ssl != NULL);
379a89c9211Schristos         break;
380a89c9211Schristos     case BIO_C_GET_FD:
381a89c9211Schristos         ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
382a89c9211Schristos         break;
383a89c9211Schristos     case BIO_CTRL_SET_CALLBACK:
38413d40330Schristos         ret = 0; /* use callback ctrl */
385a89c9211Schristos         break;
386a89c9211Schristos     default:
387a89c9211Schristos         ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
388a89c9211Schristos         break;
389a89c9211Schristos     }
39013d40330Schristos     return ret;
391a89c9211Schristos }
392a89c9211Schristos 
39353060421Schristos static long ssl_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
394a89c9211Schristos {
395a89c9211Schristos     SSL *ssl;
396a89c9211Schristos     BIO_SSL *bs;
397a89c9211Schristos     long ret = 1;
398a89c9211Schristos 
399c7da899bSchristos     bs = BIO_get_data(b);
400a89c9211Schristos     ssl = bs->ssl;
401635165faSspz     switch (cmd) {
402a89c9211Schristos     case BIO_CTRL_SET_CALLBACK:
40353060421Schristos         ret = BIO_callback_ctrl(ssl->rbio, cmd, fp);
404a89c9211Schristos         break;
405a89c9211Schristos     default:
40653060421Schristos         ret = 0;
407a89c9211Schristos         break;
408a89c9211Schristos     }
40913d40330Schristos     return ret;
410a89c9211Schristos }
411a89c9211Schristos 
412a89c9211Schristos static int ssl_puts(BIO *bp, const char *str)
413a89c9211Schristos {
414a89c9211Schristos     int n, ret;
415a89c9211Schristos 
416a89c9211Schristos     n = strlen(str);
417a89c9211Schristos     ret = BIO_write(bp, str, n);
41813d40330Schristos     return ret;
419a89c9211Schristos }
420a89c9211Schristos 
421a89c9211Schristos BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
422a89c9211Schristos {
423a89c9211Schristos #ifndef OPENSSL_NO_SOCK
424a89c9211Schristos     BIO *ret = NULL, *buf = NULL, *ssl = NULL;
425a89c9211Schristos 
426a89c9211Schristos     if ((buf = BIO_new(BIO_f_buffer())) == NULL)
42713d40330Schristos         return NULL;
428a89c9211Schristos     if ((ssl = BIO_new_ssl_connect(ctx)) == NULL)
429a89c9211Schristos         goto err;
430a89c9211Schristos     if ((ret = BIO_push(buf, ssl)) == NULL)
431a89c9211Schristos         goto err;
43213d40330Schristos     return ret;
433a89c9211Schristos  err:
434635165faSspz     BIO_free(buf);
435635165faSspz     BIO_free(ssl);
436a89c9211Schristos #endif
43713d40330Schristos     return NULL;
438a89c9211Schristos }
439a89c9211Schristos 
440a89c9211Schristos BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
441a89c9211Schristos {
44232daad53Schristos #ifndef OPENSSL_NO_SOCK
443a89c9211Schristos     BIO *ret = NULL, *con = NULL, *ssl = NULL;
444a89c9211Schristos 
445a89c9211Schristos     if ((con = BIO_new(BIO_s_connect())) == NULL)
44613d40330Schristos         return NULL;
447a89c9211Schristos     if ((ssl = BIO_new_ssl(ctx, 1)) == NULL)
448a89c9211Schristos         goto err;
449a89c9211Schristos     if ((ret = BIO_push(ssl, con)) == NULL)
450a89c9211Schristos         goto err;
45113d40330Schristos     return ret;
452a89c9211Schristos  err:
45321497c5cSchristos     BIO_free(ssl);
454635165faSspz     BIO_free(con);
45532daad53Schristos #endif
45613d40330Schristos     return NULL;
457a89c9211Schristos }
458a89c9211Schristos 
459a89c9211Schristos BIO *BIO_new_ssl(SSL_CTX *ctx, int client)
460a89c9211Schristos {
461a89c9211Schristos     BIO *ret;
462a89c9211Schristos     SSL *ssl;
463a89c9211Schristos 
464a89c9211Schristos     if ((ret = BIO_new(BIO_f_ssl())) == NULL)
46513d40330Schristos         return NULL;
466635165faSspz     if ((ssl = SSL_new(ctx)) == NULL) {
467a89c9211Schristos         BIO_free(ret);
46813d40330Schristos         return NULL;
469a89c9211Schristos     }
470a89c9211Schristos     if (client)
471a89c9211Schristos         SSL_set_connect_state(ssl);
472a89c9211Schristos     else
473a89c9211Schristos         SSL_set_accept_state(ssl);
474a89c9211Schristos 
475a89c9211Schristos     BIO_set_ssl(ret, ssl, BIO_CLOSE);
47613d40330Schristos     return ret;
477a89c9211Schristos }
478a89c9211Schristos 
479a89c9211Schristos int BIO_ssl_copy_session_id(BIO *t, BIO *f)
480a89c9211Schristos {
481c7da899bSchristos     BIO_SSL *tdata, *fdata;
482a89c9211Schristos     t = BIO_find_type(t, BIO_TYPE_SSL);
483a89c9211Schristos     f = BIO_find_type(f, BIO_TYPE_SSL);
484a89c9211Schristos     if ((t == NULL) || (f == NULL))
485c7da899bSchristos         return 0;
486c7da899bSchristos     tdata = BIO_get_data(t);
487c7da899bSchristos     fdata = BIO_get_data(f);
488c7da899bSchristos     if ((tdata->ssl == NULL) || (fdata->ssl == NULL))
48913d40330Schristos         return 0;
490c7da899bSchristos     if (!SSL_copy_session_id(tdata->ssl, (fdata->ssl)))
491c7da899bSchristos         return 0;
49213d40330Schristos     return 1;
493a89c9211Schristos }
494a89c9211Schristos 
495a89c9211Schristos void BIO_ssl_shutdown(BIO *b)
496a89c9211Schristos {
497c7da899bSchristos     BIO_SSL *bdata;
498a89c9211Schristos 
499c7da899bSchristos     for (; b != NULL; b = BIO_next(b)) {
500c7da899bSchristos         if (BIO_method_type(b) != BIO_TYPE_SSL)
501c7da899bSchristos             continue;
502c7da899bSchristos         bdata = BIO_get_data(b);
503c7da899bSchristos         if (bdata != NULL && bdata->ssl != NULL)
504c7da899bSchristos             SSL_shutdown(bdata->ssl);
505a89c9211Schristos     }
506a89c9211Schristos }
507