~ubuntu-branches/ubuntu/hardy/openssl/hardy-security

« back to all changes in this revision

Viewing changes to ssl/bio_ssl.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Martin
  • Date: 2004-05-24 17:02:29 UTC
  • Revision ID: james.westby@ubuntu.com-20040524170229-ixlo08bbbly0xied
Tags: upstream-0.9.7d
ImportĀ upstreamĀ versionĀ 0.9.7d

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ssl/bio_ssl.c */
 
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 <stdio.h>
 
60
#include <stdlib.h>
 
61
#include <string.h>
 
62
#include <errno.h>
 
63
#include <openssl/crypto.h>
 
64
#include <openssl/bio.h>
 
65
#include <openssl/err.h>
 
66
#include <openssl/ssl.h>
 
67
 
 
68
static int ssl_write(BIO *h, const char *buf, int num);
 
69
static int ssl_read(BIO *h, char *buf, int size);
 
70
static int ssl_puts(BIO *h, const char *str);
 
71
static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
 
72
static int ssl_new(BIO *h);
 
73
static int ssl_free(BIO *data);
 
74
static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
 
75
typedef struct bio_ssl_st
 
76
        {
 
77
        SSL *ssl; /* The ssl handle :-) */
 
78
        /* re-negotiate every time the total number of bytes is this size */
 
79
        int num_renegotiates;
 
80
        unsigned long renegotiate_count;
 
81
        unsigned long byte_count;
 
82
        unsigned long renegotiate_timeout;
 
83
        unsigned long last_time;
 
84
        } BIO_SSL;
 
85
 
 
86
static BIO_METHOD methods_sslp=
 
87
        {
 
88
        BIO_TYPE_SSL,"ssl",
 
89
        ssl_write,
 
90
        ssl_read,
 
91
        ssl_puts,
 
92
        NULL, /* ssl_gets, */
 
93
        ssl_ctrl,
 
94
        ssl_new,
 
95
        ssl_free,
 
96
        ssl_callback_ctrl,
 
97
        };
 
98
 
 
99
BIO_METHOD *BIO_f_ssl(void)
 
100
        {
 
101
        return(&methods_sslp);
 
102
        }
 
103
 
 
104
static int ssl_new(BIO *bi)
 
105
        {
 
106
        BIO_SSL *bs;
 
107
 
 
108
        bs=(BIO_SSL *)OPENSSL_malloc(sizeof(BIO_SSL));
 
109
        if (bs == NULL)
 
110
                {
 
111
                BIOerr(BIO_F_SSL_NEW,ERR_R_MALLOC_FAILURE);
 
112
                return(0);
 
113
                }
 
114
        memset(bs,0,sizeof(BIO_SSL));
 
115
        bi->init=0;
 
116
        bi->ptr=(char *)bs;
 
117
        bi->flags=0;
 
118
        return(1);
 
119
        }
 
120
 
 
121
static int ssl_free(BIO *a)
 
122
        {
 
123
        BIO_SSL *bs;
 
124
 
 
125
        if (a == NULL) return(0);
 
126
        bs=(BIO_SSL *)a->ptr;
 
127
        if (bs->ssl != NULL) SSL_shutdown(bs->ssl);
 
128
        if (a->shutdown)
 
129
                {
 
130
                if (a->init && (bs->ssl != NULL))
 
131
                        SSL_free(bs->ssl);
 
132
                a->init=0;
 
133
                a->flags=0;
 
134
                }
 
135
        if (a->ptr != NULL)
 
136
                OPENSSL_free(a->ptr);
 
137
        return(1);
 
138
        }
 
139
        
 
140
static int ssl_read(BIO *b, char *out, int outl)
 
141
        {
 
142
        int ret=1;
 
143
        BIO_SSL *sb;
 
144
        SSL *ssl;
 
145
        int retry_reason=0;
 
146
        int r=0;
 
147
 
 
148
        if (out == NULL) return(0);
 
149
        sb=(BIO_SSL *)b->ptr;
 
150
        ssl=sb->ssl;
 
151
 
 
152
        BIO_clear_retry_flags(b);
 
153
 
 
154
#if 0
 
155
        if (!SSL_is_init_finished(ssl))
 
156
                {
 
157
/*              ret=SSL_do_handshake(ssl); */
 
158
                if (ret > 0)
 
159
                        {
 
160
 
 
161
                        outflags=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
 
162
                        ret= -1;
 
163
                        goto end;
 
164
                        }
 
165
                }
 
166
#endif
 
167
/*      if (ret > 0) */
 
168
        ret=SSL_read(ssl,out,outl);
 
169
 
 
170
        switch (SSL_get_error(ssl,ret))
 
171
                {
 
172
        case SSL_ERROR_NONE:
 
173
                if (ret <= 0) break;
 
174
                if (sb->renegotiate_count > 0)
 
175
                        {
 
176
                        sb->byte_count+=ret;
 
177
                        if (sb->byte_count > sb->renegotiate_count)
 
178
                                {
 
179
                                sb->byte_count=0;
 
180
                                sb->num_renegotiates++;
 
181
                                SSL_renegotiate(ssl);
 
182
                                r=1;
 
183
                                }
 
184
                        }
 
185
                if ((sb->renegotiate_timeout > 0) && (!r))
 
186
                        {
 
187
                        unsigned long tm;
 
188
 
 
189
                        tm=(unsigned long)time(NULL);
 
190
                        if (tm > sb->last_time+sb->renegotiate_timeout)
 
191
                                {
 
192
                                sb->last_time=tm;
 
193
                                sb->num_renegotiates++;
 
194
                                SSL_renegotiate(ssl);
 
195
                                }
 
196
                        }
 
197
 
 
198
                break;
 
199
        case SSL_ERROR_WANT_READ:
 
200
                BIO_set_retry_read(b);
 
201
                break;
 
202
        case SSL_ERROR_WANT_WRITE:
 
203
                BIO_set_retry_write(b);
 
204
                break;
 
205
        case SSL_ERROR_WANT_X509_LOOKUP:
 
206
                BIO_set_retry_special(b);
 
207
                retry_reason=BIO_RR_SSL_X509_LOOKUP;
 
208
                break;
 
209
        case SSL_ERROR_WANT_ACCEPT:
 
210
                BIO_set_retry_special(b);
 
211
                retry_reason=BIO_RR_ACCEPT;
 
212
                break;
 
213
        case SSL_ERROR_WANT_CONNECT:
 
214
                BIO_set_retry_special(b);
 
215
                retry_reason=BIO_RR_CONNECT;
 
216
                break;
 
217
        case SSL_ERROR_SYSCALL:
 
218
        case SSL_ERROR_SSL:
 
219
        case SSL_ERROR_ZERO_RETURN:
 
220
        default:
 
221
                break;
 
222
                }
 
223
 
 
224
        b->retry_reason=retry_reason;
 
225
        return(ret);
 
226
        }
 
227
 
 
228
static int ssl_write(BIO *b, const char *out, int outl)
 
229
        {
 
230
        int ret,r=0;
 
231
        int retry_reason=0;
 
232
        SSL *ssl;
 
233
        BIO_SSL *bs;
 
234
 
 
235
        if (out == NULL) return(0);
 
236
        bs=(BIO_SSL *)b->ptr;
 
237
        ssl=bs->ssl;
 
238
 
 
239
        BIO_clear_retry_flags(b);
 
240
 
 
241
/*      ret=SSL_do_handshake(ssl);
 
242
        if (ret > 0) */
 
243
        ret=SSL_write(ssl,out,outl);
 
244
 
 
245
        switch (SSL_get_error(ssl,ret))
 
246
                {
 
247
        case SSL_ERROR_NONE:
 
248
                if (ret <= 0) break;
 
249
                if (bs->renegotiate_count > 0)
 
250
                        {
 
251
                        bs->byte_count+=ret;
 
252
                        if (bs->byte_count > bs->renegotiate_count)
 
253
                                {
 
254
                                bs->byte_count=0;
 
255
                                bs->num_renegotiates++;
 
256
                                SSL_renegotiate(ssl);
 
257
                                r=1;
 
258
                                }
 
259
                        }
 
260
                if ((bs->renegotiate_timeout > 0) && (!r))
 
261
                        {
 
262
                        unsigned long tm;
 
263
 
 
264
                        tm=(unsigned long)time(NULL);
 
265
                        if (tm > bs->last_time+bs->renegotiate_timeout)
 
266
                                {
 
267
                                bs->last_time=tm;
 
268
                                bs->num_renegotiates++;
 
269
                                SSL_renegotiate(ssl);
 
270
                                }
 
271
                        }
 
272
                break;
 
273
        case SSL_ERROR_WANT_WRITE:
 
274
                BIO_set_retry_write(b);
 
275
                break;
 
276
        case SSL_ERROR_WANT_READ:
 
277
                BIO_set_retry_read(b);
 
278
                break;
 
279
        case SSL_ERROR_WANT_X509_LOOKUP:
 
280
                BIO_set_retry_special(b);
 
281
                retry_reason=BIO_RR_SSL_X509_LOOKUP;
 
282
                break;
 
283
        case SSL_ERROR_WANT_CONNECT:
 
284
                BIO_set_retry_special(b);
 
285
                retry_reason=BIO_RR_CONNECT;
 
286
        case SSL_ERROR_SYSCALL:
 
287
        case SSL_ERROR_SSL:
 
288
        default:
 
289
                break;
 
290
                }
 
291
 
 
292
        b->retry_reason=retry_reason;
 
293
        return(ret);
 
294
        }
 
295
 
 
296
static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
 
297
        {
 
298
        SSL **sslp,*ssl;
 
299
        BIO_SSL *bs;
 
300
        BIO *dbio,*bio;
 
301
        long ret=1;
 
302
 
 
303
        bs=(BIO_SSL *)b->ptr;
 
304
        ssl=bs->ssl;
 
305
        if ((ssl == NULL)  && (cmd != BIO_C_SET_SSL))
 
306
                return(0);
 
307
        switch (cmd)
 
308
                {
 
309
        case BIO_CTRL_RESET:
 
310
                SSL_shutdown(ssl);
 
311
 
 
312
                if (ssl->handshake_func == ssl->method->ssl_connect)
 
313
                        SSL_set_connect_state(ssl);
 
314
                else if (ssl->handshake_func == ssl->method->ssl_accept)
 
315
                        SSL_set_accept_state(ssl);
 
316
 
 
317
                SSL_clear(ssl);
 
318
 
 
319
                if (b->next_bio != NULL)
 
320
                        ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
 
321
                else if (ssl->rbio != NULL)
 
322
                        ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
 
323
                else
 
324
                        ret=1;
 
325
                break;
 
326
        case BIO_CTRL_INFO:
 
327
                ret=0;
 
328
                break;
 
329
        case BIO_C_SSL_MODE:
 
330
                if (num) /* client mode */
 
331
                        SSL_set_connect_state(ssl);
 
332
                else
 
333
                        SSL_set_accept_state(ssl);
 
334
                break;
 
335
        case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:
 
336
                ret=bs->renegotiate_timeout;
 
337
                if (num < 60) num=5;
 
338
                bs->renegotiate_timeout=(unsigned long)num;
 
339
                bs->last_time=(unsigned long)time(NULL);
 
340
                break;
 
341
        case BIO_C_SET_SSL_RENEGOTIATE_BYTES:
 
342
                ret=bs->renegotiate_count;
 
343
                if ((long)num >=512)
 
344
                        bs->renegotiate_count=(unsigned long)num;
 
345
                break;
 
346
        case BIO_C_GET_SSL_NUM_RENEGOTIATES:
 
347
                ret=bs->num_renegotiates;
 
348
                break;
 
349
        case BIO_C_SET_SSL:
 
350
                if (ssl != NULL)
 
351
                        ssl_free(b);
 
352
                b->shutdown=(int)num;
 
353
                ssl=(SSL *)ptr;
 
354
                ((BIO_SSL *)b->ptr)->ssl=ssl;
 
355
                bio=SSL_get_rbio(ssl);
 
356
                if (bio != NULL)
 
357
                        {
 
358
                        if (b->next_bio != NULL)
 
359
                                BIO_push(bio,b->next_bio);
 
360
                        b->next_bio=bio;
 
361
                        CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO);
 
362
                        }
 
363
                b->init=1;
 
364
                break;
 
365
        case BIO_C_GET_SSL:
 
366
                if (ptr != NULL)
 
367
                        {
 
368
                        sslp=(SSL **)ptr;
 
369
                        *sslp=ssl;
 
370
                        }
 
371
                else
 
372
                        ret=0;
 
373
                break;
 
374
        case BIO_CTRL_GET_CLOSE:
 
375
                ret=b->shutdown;
 
376
                break;
 
377
        case BIO_CTRL_SET_CLOSE:
 
378
                b->shutdown=(int)num;
 
379
                break;
 
380
        case BIO_CTRL_WPENDING:
 
381
                ret=BIO_ctrl(ssl->wbio,cmd,num,ptr);
 
382
                break;
 
383
        case BIO_CTRL_PENDING:
 
384
                ret=SSL_pending(ssl);
 
385
                if (ret == 0)
 
386
                        ret=BIO_pending(ssl->rbio);
 
387
                break;
 
388
        case BIO_CTRL_FLUSH:
 
389
                BIO_clear_retry_flags(b);
 
390
                ret=BIO_ctrl(ssl->wbio,cmd,num,ptr);
 
391
                BIO_copy_next_retry(b);
 
392
                break;
 
393
        case BIO_CTRL_PUSH:
 
394
                if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio))
 
395
                        {
 
396
                        SSL_set_bio(ssl,b->next_bio,b->next_bio);
 
397
                        CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO);
 
398
                        }
 
399
                break;
 
400
        case BIO_CTRL_POP:
 
401
                /* ugly bit of a hack */
 
402
                if (ssl->rbio != ssl->wbio) /* we are in trouble :-( */
 
403
                        {
 
404
                        BIO_free_all(ssl->wbio);
 
405
                        }
 
406
                if (b->next_bio != NULL)
 
407
                        {
 
408
                        CRYPTO_add(&b->next_bio->references,1,CRYPTO_LOCK_BIO);
 
409
                        }
 
410
                ssl->wbio=NULL;
 
411
                ssl->rbio=NULL;
 
412
                break;
 
413
        case BIO_C_DO_STATE_MACHINE:
 
414
                BIO_clear_retry_flags(b);
 
415
 
 
416
                b->retry_reason=0;
 
417
                ret=(int)SSL_do_handshake(ssl);
 
418
 
 
419
                switch (SSL_get_error(ssl,(int)ret))
 
420
                        {
 
421
                case SSL_ERROR_WANT_READ:
 
422
                        BIO_set_flags(b,
 
423
                                BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY);
 
424
                        break;
 
425
                case SSL_ERROR_WANT_WRITE:
 
426
                        BIO_set_flags(b,
 
427
                                BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY);
 
428
                        break;
 
429
                case SSL_ERROR_WANT_CONNECT:
 
430
                        BIO_set_flags(b,
 
431
                                BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY);
 
432
                        b->retry_reason=b->next_bio->retry_reason;
 
433
                        break;
 
434
                default:
 
435
                        break;
 
436
                        }
 
437
                break;
 
438
        case BIO_CTRL_DUP:
 
439
                dbio=(BIO *)ptr;
 
440
                if (((BIO_SSL *)dbio->ptr)->ssl != NULL)
 
441
                        SSL_free(((BIO_SSL *)dbio->ptr)->ssl);
 
442
                ((BIO_SSL *)dbio->ptr)->ssl=SSL_dup(ssl);
 
443
                ((BIO_SSL *)dbio->ptr)->renegotiate_count=
 
444
                        ((BIO_SSL *)b->ptr)->renegotiate_count;
 
445
                ((BIO_SSL *)dbio->ptr)->byte_count=
 
446
                        ((BIO_SSL *)b->ptr)->byte_count;
 
447
                ((BIO_SSL *)dbio->ptr)->renegotiate_timeout=
 
448
                        ((BIO_SSL *)b->ptr)->renegotiate_timeout;
 
449
                ((BIO_SSL *)dbio->ptr)->last_time=
 
450
                        ((BIO_SSL *)b->ptr)->last_time;
 
451
                ret=(((BIO_SSL *)dbio->ptr)->ssl != NULL);
 
452
                break;
 
453
        case BIO_C_GET_FD:
 
454
                ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
 
455
                break;
 
456
        case BIO_CTRL_SET_CALLBACK:
 
457
                {
 
458
#if 0 /* FIXME: Should this be used?  -- Richard Levitte */
 
459
                BIOerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
 
460
                ret = -1;
 
461
#else
 
462
                ret=0;
 
463
#endif
 
464
                }
 
465
                break;
 
466
        case BIO_CTRL_GET_CALLBACK:
 
467
                {
 
468
                void (**fptr)();
 
469
 
 
470
                fptr=(void (**)())ptr;
 
471
                *fptr=SSL_get_info_callback(ssl);
 
472
                }
 
473
                break;
 
474
        default:
 
475
                ret=BIO_ctrl(ssl->rbio,cmd,num,ptr);
 
476
                break;
 
477
                }
 
478
        return(ret);
 
479
        }
 
480
 
 
481
static long ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
 
482
        {
 
483
        SSL *ssl;
 
484
        BIO_SSL *bs;
 
485
        long ret=1;
 
486
 
 
487
        bs=(BIO_SSL *)b->ptr;
 
488
        ssl=bs->ssl;
 
489
        switch (cmd)
 
490
                {
 
491
        case BIO_CTRL_SET_CALLBACK:
 
492
                {
 
493
                /* FIXME: setting this via a completely different prototype
 
494
                   seems like a crap idea */
 
495
                SSL_set_info_callback(ssl,(void (*)(const SSL *,int,int))fp);
 
496
                }
 
497
                break;
 
498
        default:
 
499
                ret=BIO_callback_ctrl(ssl->rbio,cmd,fp);
 
500
                break;
 
501
                }
 
502
        return(ret);
 
503
        }
 
504
 
 
505
static int ssl_puts(BIO *bp, const char *str)
 
506
        {
 
507
        int n,ret;
 
508
 
 
509
        n=strlen(str);
 
510
        ret=BIO_write(bp,str,n);
 
511
        return(ret);
 
512
        }
 
513
 
 
514
BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
 
515
        {
 
516
#ifndef OPENSSL_NO_SOCK
 
517
        BIO *ret=NULL,*buf=NULL,*ssl=NULL;
 
518
 
 
519
        if ((buf=BIO_new(BIO_f_buffer())) == NULL)
 
520
                return(NULL);
 
521
        if ((ssl=BIO_new_ssl_connect(ctx)) == NULL)
 
522
                goto err;
 
523
        if ((ret=BIO_push(buf,ssl)) == NULL)
 
524
                goto err;
 
525
        return(ret);
 
526
err:
 
527
        if (buf != NULL) BIO_free(buf);
 
528
        if (ssl != NULL) BIO_free(ssl);
 
529
#endif
 
530
        return(NULL);
 
531
        }
 
532
 
 
533
BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
 
534
        {
 
535
        BIO *ret=NULL,*con=NULL,*ssl=NULL;
 
536
 
 
537
        if ((con=BIO_new(BIO_s_connect())) == NULL)
 
538
                return(NULL);
 
539
        if ((ssl=BIO_new_ssl(ctx,1)) == NULL)
 
540
                goto err;
 
541
        if ((ret=BIO_push(ssl,con)) == NULL)
 
542
                goto err;
 
543
        return(ret);
 
544
err:
 
545
        if (con != NULL) BIO_free(con);
 
546
        if (ret != NULL) BIO_free(ret);
 
547
        return(NULL);
 
548
        }
 
549
 
 
550
BIO *BIO_new_ssl(SSL_CTX *ctx, int client)
 
551
        {
 
552
        BIO *ret;
 
553
        SSL *ssl;
 
554
 
 
555
        if ((ret=BIO_new(BIO_f_ssl())) == NULL)
 
556
                return(NULL);
 
557
        if ((ssl=SSL_new(ctx)) == NULL)
 
558
                {
 
559
                BIO_free(ret);
 
560
                return(NULL);
 
561
                }
 
562
        if (client)
 
563
                SSL_set_connect_state(ssl);
 
564
        else
 
565
                SSL_set_accept_state(ssl);
 
566
                
 
567
        BIO_set_ssl(ret,ssl,BIO_CLOSE);
 
568
        return(ret);
 
569
        }
 
570
 
 
571
int BIO_ssl_copy_session_id(BIO *t, BIO *f)
 
572
        {
 
573
        t=BIO_find_type(t,BIO_TYPE_SSL);
 
574
        f=BIO_find_type(f,BIO_TYPE_SSL);
 
575
        if ((t == NULL) || (f == NULL))
 
576
                return(0);
 
577
        if (    (((BIO_SSL *)t->ptr)->ssl == NULL) || 
 
578
                (((BIO_SSL *)f->ptr)->ssl == NULL))
 
579
                return(0);
 
580
        SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,((BIO_SSL *)f->ptr)->ssl);
 
581
        return(1);
 
582
        }
 
583
 
 
584
void BIO_ssl_shutdown(BIO *b)
 
585
        {
 
586
        SSL *s;
 
587
 
 
588
        while (b != NULL)
 
589
                {
 
590
                if (b->method->type == BIO_TYPE_SSL)
 
591
                        {
 
592
                        s=((BIO_SSL *)b->ptr)->ssl;
 
593
                        SSL_shutdown(s);
 
594
                        break;
 
595
                        }
 
596
                b=b->next_bio;
 
597
                }
 
598
        }