bio_lib.c revision 296465
1185377Ssam/* crypto/bio/bio_lib.c */
2185377Ssam/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3185377Ssam * All rights reserved.
4185377Ssam *
5185377Ssam * This package is an SSL implementation written
6185377Ssam * by Eric Young (eay@cryptsoft.com).
7185377Ssam * The implementation was written so as to conform with Netscapes SSL.
8185377Ssam *
9185377Ssam * This library is free for commercial and non-commercial use as long as
10185377Ssam * the following conditions are aheared to.  The following conditions
11185377Ssam * apply to all code found in this distribution, be it the RC4, RSA,
12185377Ssam * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13185377Ssam * included with this distribution is covered by the same copyright terms
14185377Ssam * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15185377Ssam *
16185377Ssam * Copyright remains Eric Young's, and as such any Copyright notices in
17204644Srpaulo * the code are not to be removed.
18185377Ssam * If this package is used in a product, Eric Young should be given attribution
19185377Ssam * as the author of the parts of the library used.
20185377Ssam * This can be in the form of a textual message at program startup or
21185377Ssam * in documentation (online or textual) provided with the package.
22185377Ssam *
23185377Ssam * Redistribution and use in source and binary forms, with or without
24185377Ssam * modification, are permitted provided that the following conditions
25185377Ssam * are met:
26185377Ssam * 1. Redistributions of source code must retain the copyright
27185377Ssam *    notice, this list of conditions and the following disclaimer.
28185377Ssam * 2. Redistributions in binary form must reproduce the above copyright
29185377Ssam *    notice, this list of conditions and the following disclaimer in the
30185377Ssam *    documentation and/or other materials provided with the distribution.
31185377Ssam * 3. All advertising materials mentioning features or use of this software
32185377Ssam *    must display the following acknowledgement:
33185377Ssam *    "This product includes cryptographic software written by
34185377Ssam *     Eric Young (eay@cryptsoft.com)"
35185377Ssam *    The word 'cryptographic' can be left out if the rouines from the library
36185377Ssam *    being used are not cryptographic related :-).
37185377Ssam * 4. If you include any Windows specific code (or a derivative thereof) from
38185377Ssam *    the apps directory (application code) you must include an acknowledgement:
39185377Ssam *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40185377Ssam *
41185377Ssam * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42185377Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43185377Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44185377Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45185377Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46185377Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47185377Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48185377Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49185377Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50185377Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51185377Ssam * SUCH DAMAGE.
52185377Ssam *
53185377Ssam * The licence and distribution terms for any publically available version or
54185377Ssam * derivative of this code cannot be changed.  i.e. this code cannot simply be
55185377Ssam * copied and put under another distribution licence
56185377Ssam * [including the GNU Public Licence.]
57185377Ssam */
58185377Ssam
59185377Ssam#include <stdio.h>
60185377Ssam#include <errno.h>
61185377Ssam#include <openssl/crypto.h>
62185377Ssam#include "cryptlib.h"
63185377Ssam#include <openssl/bio.h>
64185377Ssam#include <openssl/stack.h>
65185377Ssam
66185377SsamBIO *BIO_new(BIO_METHOD *method)
67185377Ssam{
68185377Ssam    BIO *ret = NULL;
69185377Ssam
70185377Ssam    ret = (BIO *)OPENSSL_malloc(sizeof(BIO));
71185377Ssam    if (ret == NULL) {
72185377Ssam        BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
73185377Ssam        return (NULL);
74185377Ssam    }
75185377Ssam    if (!BIO_set(ret, method)) {
76185377Ssam        OPENSSL_free(ret);
77185377Ssam        ret = NULL;
78185377Ssam    }
79185377Ssam    return (ret);
80185377Ssam}
81185377Ssam
82185377Ssamint BIO_set(BIO *bio, BIO_METHOD *method)
83185377Ssam{
84185377Ssam    bio->method = method;
85185377Ssam    bio->callback = NULL;
86185377Ssam    bio->cb_arg = NULL;
87185377Ssam    bio->init = 0;
88185377Ssam    bio->shutdown = 1;
89185377Ssam    bio->flags = 0;
90185377Ssam    bio->retry_reason = 0;
91185377Ssam    bio->num = 0;
92185377Ssam    bio->ptr = NULL;
93185377Ssam    bio->prev_bio = NULL;
94185377Ssam    bio->next_bio = NULL;
95185377Ssam    bio->references = 1;
96185377Ssam    bio->num_read = 0L;
97185377Ssam    bio->num_write = 0L;
98185377Ssam    CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
99185377Ssam    if (method->create != NULL)
100185377Ssam        if (!method->create(bio)) {
101185377Ssam            CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
102185377Ssam            return (0);
103185377Ssam        }
104185377Ssam    return (1);
105185377Ssam}
106185377Ssam
107185377Ssamint BIO_free(BIO *a)
108185377Ssam{
109262969Sadrian    int i;
110185377Ssam
111185377Ssam    if (a == NULL)
112185377Ssam        return (0);
113265112Sadrian
114265112Sadrian    i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO);
115185377Ssam#ifdef REF_PRINT
116185377Ssam    REF_PRINT("BIO", a);
117185377Ssam#endif
118185377Ssam    if (i > 0)
119265112Sadrian        return (1);
120265112Sadrian#ifdef REF_CHECK
121185377Ssam    if (i < 0) {
122185377Ssam        fprintf(stderr, "BIO_free, bad reference count\n");
123185377Ssam        abort();
124265112Sadrian    }
125265112Sadrian#endif
126185377Ssam    if ((a->callback != NULL) &&
127185377Ssam        ((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0))
128185377Ssam        return (i);
129185377Ssam
130185377Ssam    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
131185377Ssam
132264900Sadrian    if ((a->method != NULL) && (a->method->destroy != NULL))
133185377Ssam        a->method->destroy(a);
134185377Ssam    OPENSSL_free(a);
135185377Ssam    return (1);
136185377Ssam}
137185377Ssam
138185377Ssamvoid BIO_vfree(BIO *a)
139185377Ssam{
140185377Ssam    BIO_free(a);
141}
142
143void BIO_clear_flags(BIO *b, int flags)
144{
145    b->flags &= ~flags;
146}
147
148int BIO_test_flags(const BIO *b, int flags)
149{
150    return (b->flags & flags);
151}
152
153void BIO_set_flags(BIO *b, int flags)
154{
155    b->flags |= flags;
156}
157
158long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *,
159                                        int, long, long) {
160    return b->callback;
161}
162
163void BIO_set_callback(BIO *b,
164                      long (*cb) (struct bio_st *, int, const char *, int,
165                                  long, long))
166{
167    b->callback = cb;
168}
169
170void BIO_set_callback_arg(BIO *b, char *arg)
171{
172    b->cb_arg = arg;
173}
174
175char *BIO_get_callback_arg(const BIO *b)
176{
177    return b->cb_arg;
178}
179
180const char *BIO_method_name(const BIO *b)
181{
182    return b->method->name;
183}
184
185int BIO_method_type(const BIO *b)
186{
187    return b->method->type;
188}
189
190int BIO_read(BIO *b, void *out, int outl)
191{
192    int i;
193    long (*cb) (BIO *, int, const char *, int, long, long);
194
195    if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) {
196        BIOerr(BIO_F_BIO_READ, BIO_R_UNSUPPORTED_METHOD);
197        return (-2);
198    }
199
200    cb = b->callback;
201    if ((cb != NULL) &&
202        ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0))
203        return (i);
204
205    if (!b->init) {
206        BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED);
207        return (-2);
208    }
209
210    i = b->method->bread(b, out, outl);
211
212    if (i > 0)
213        b->num_read += (unsigned long)i;
214
215    if (cb != NULL)
216        i = (int)cb(b, BIO_CB_READ | BIO_CB_RETURN, out, outl, 0L, (long)i);
217    return (i);
218}
219
220int BIO_write(BIO *b, const void *in, int inl)
221{
222    int i;
223    long (*cb) (BIO *, int, const char *, int, long, long);
224
225    if (b == NULL)
226        return (0);
227
228    cb = b->callback;
229    if ((b->method == NULL) || (b->method->bwrite == NULL)) {
230        BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD);
231        return (-2);
232    }
233
234    if ((cb != NULL) &&
235        ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0))
236        return (i);
237
238    if (!b->init) {
239        BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED);
240        return (-2);
241    }
242
243    i = b->method->bwrite(b, in, inl);
244
245    if (i > 0)
246        b->num_write += (unsigned long)i;
247
248    if (cb != NULL)
249        i = (int)cb(b, BIO_CB_WRITE | BIO_CB_RETURN, in, inl, 0L, (long)i);
250    return (i);
251}
252
253int BIO_puts(BIO *b, const char *in)
254{
255    int i;
256    long (*cb) (BIO *, int, const char *, int, long, long);
257
258    if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
259        BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD);
260        return (-2);
261    }
262
263    cb = b->callback;
264
265    if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0))
266        return (i);
267
268    if (!b->init) {
269        BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED);
270        return (-2);
271    }
272
273    i = b->method->bputs(b, in);
274
275    if (i > 0)
276        b->num_write += (unsigned long)i;
277
278    if (cb != NULL)
279        i = (int)cb(b, BIO_CB_PUTS | BIO_CB_RETURN, in, 0, 0L, (long)i);
280    return (i);
281}
282
283int BIO_gets(BIO *b, char *in, int inl)
284{
285    int i;
286    long (*cb) (BIO *, int, const char *, int, long, long);
287
288    if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
289        BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
290        return (-2);
291    }
292
293    cb = b->callback;
294
295    if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0))
296        return (i);
297
298    if (!b->init) {
299        BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
300        return (-2);
301    }
302
303    i = b->method->bgets(b, in, inl);
304
305    if (cb != NULL)
306        i = (int)cb(b, BIO_CB_GETS | BIO_CB_RETURN, in, inl, 0L, (long)i);
307    return (i);
308}
309
310int BIO_indent(BIO *b, int indent, int max)
311{
312    if (indent < 0)
313        indent = 0;
314    if (indent > max)
315        indent = max;
316    while (indent--)
317        if (BIO_puts(b, " ") != 1)
318            return 0;
319    return 1;
320}
321
322long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
323{
324    int i;
325
326    i = iarg;
327    return (BIO_ctrl(b, cmd, larg, (char *)&i));
328}
329
330char *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
331{
332    char *p = NULL;
333
334    if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
335        return (NULL);
336    else
337        return (p);
338}
339
340long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
341{
342    long ret;
343    long (*cb) (BIO *, int, const char *, int, long, long);
344
345    if (b == NULL)
346        return (0);
347
348    if ((b->method == NULL) || (b->method->ctrl == NULL)) {
349        BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
350        return (-2);
351    }
352
353    cb = b->callback;
354
355    if ((cb != NULL) &&
356        ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0))
357        return (ret);
358
359    ret = b->method->ctrl(b, cmd, larg, parg);
360
361    if (cb != NULL)
362        ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, cmd, larg, ret);
363    return (ret);
364}
365
366long BIO_callback_ctrl(BIO *b, int cmd,
367                       void (*fp) (struct bio_st *, int, const char *, int,
368                                   long, long))
369{
370    long ret;
371    long (*cb) (BIO *, int, const char *, int, long, long);
372
373    if (b == NULL)
374        return (0);
375
376    if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) {
377        BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD);
378        return (-2);
379    }
380
381    cb = b->callback;
382
383    if ((cb != NULL) &&
384        ((ret = cb(b, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L)) <= 0))
385        return (ret);
386
387    ret = b->method->callback_ctrl(b, cmd, fp);
388
389    if (cb != NULL)
390        ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, cmd, 0, ret);
391    return (ret);
392}
393
394/*
395 * It is unfortunate to duplicate in functions what the BIO_(w)pending macros
396 * do; but those macros have inappropriate return type, and for interfacing
397 * from other programming languages, C macros aren't much of a help anyway.
398 */
399size_t BIO_ctrl_pending(BIO *bio)
400{
401    return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
402}
403
404size_t BIO_ctrl_wpending(BIO *bio)
405{
406    return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
407}
408
409/* put the 'bio' on the end of b's list of operators */
410BIO *BIO_push(BIO *b, BIO *bio)
411{
412    BIO *lb;
413
414    if (b == NULL)
415        return (bio);
416    lb = b;
417    while (lb->next_bio != NULL)
418        lb = lb->next_bio;
419    lb->next_bio = bio;
420    if (bio != NULL)
421        bio->prev_bio = lb;
422    /* called to do internal processing */
423    BIO_ctrl(b, BIO_CTRL_PUSH, 0, NULL);
424    return (b);
425}
426
427/* Remove the first and return the rest */
428BIO *BIO_pop(BIO *b)
429{
430    BIO *ret;
431
432    if (b == NULL)
433        return (NULL);
434    ret = b->next_bio;
435
436    BIO_ctrl(b, BIO_CTRL_POP, 0, NULL);
437
438    if (b->prev_bio != NULL)
439        b->prev_bio->next_bio = b->next_bio;
440    if (b->next_bio != NULL)
441        b->next_bio->prev_bio = b->prev_bio;
442
443    b->next_bio = NULL;
444    b->prev_bio = NULL;
445    return (ret);
446}
447
448BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
449{
450    BIO *b, *last;
451
452    b = last = bio;
453    for (;;) {
454        if (!BIO_should_retry(b))
455            break;
456        last = b;
457        b = b->next_bio;
458        if (b == NULL)
459            break;
460    }
461    if (reason != NULL)
462        *reason = last->retry_reason;
463    return (last);
464}
465
466int BIO_get_retry_reason(BIO *bio)
467{
468    return (bio->retry_reason);
469}
470
471BIO *BIO_find_type(BIO *bio, int type)
472{
473    int mt, mask;
474
475    if (!bio)
476        return NULL;
477    mask = type & 0xff;
478    do {
479        if (bio->method != NULL) {
480            mt = bio->method->type;
481
482            if (!mask) {
483                if (mt & type)
484                    return (bio);
485            } else if (mt == type)
486                return (bio);
487        }
488        bio = bio->next_bio;
489    } while (bio != NULL);
490    return (NULL);
491}
492
493BIO *BIO_next(BIO *b)
494{
495    if (!b)
496        return NULL;
497    return b->next_bio;
498}
499
500void BIO_free_all(BIO *bio)
501{
502    BIO *b;
503    int ref;
504
505    while (bio != NULL) {
506        b = bio;
507        ref = b->references;
508        bio = bio->next_bio;
509        BIO_free(b);
510        /* Since ref count > 1, don't free anyone else. */
511        if (ref > 1)
512            break;
513    }
514}
515
516BIO *BIO_dup_chain(BIO *in)
517{
518    BIO *ret = NULL, *eoc = NULL, *bio, *new;
519
520    for (bio = in; bio != NULL; bio = bio->next_bio) {
521        if ((new = BIO_new(bio->method)) == NULL)
522            goto err;
523        new->callback = bio->callback;
524        new->cb_arg = bio->cb_arg;
525        new->init = bio->init;
526        new->shutdown = bio->shutdown;
527        new->flags = bio->flags;
528
529        /* This will let SSL_s_sock() work with stdin/stdout */
530        new->num = bio->num;
531
532        if (!BIO_dup_state(bio, (char *)new)) {
533            BIO_free(new);
534            goto err;
535        }
536
537        /* copy app data */
538        if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new->ex_data,
539                                &bio->ex_data))
540            goto err;
541
542        if (ret == NULL) {
543            eoc = new;
544            ret = eoc;
545        } else {
546            BIO_push(eoc, new);
547            eoc = new;
548        }
549    }
550    return (ret);
551 err:
552    if (ret != NULL)
553        BIO_free(ret);
554    return (NULL);
555}
556
557void BIO_copy_next_retry(BIO *b)
558{
559    BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
560    b->retry_reason = b->next_bio->retry_reason;
561}
562
563int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
564                         CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
565{
566    return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp,
567                                   new_func, dup_func, free_func);
568}
569
570int BIO_set_ex_data(BIO *bio, int idx, void *data)
571{
572    return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data));
573}
574
575void *BIO_get_ex_data(BIO *bio, int idx)
576{
577    return (CRYPTO_get_ex_data(&(bio->ex_data), idx));
578}
579
580unsigned long BIO_number_read(BIO *bio)
581{
582    if (bio)
583        return bio->num_read;
584    return 0;
585}
586
587unsigned long BIO_number_written(BIO *bio)
588{
589    if (bio)
590        return bio->num_write;
591    return 0;
592}
593
594IMPLEMENT_STACK_OF(BIO)
595