GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/bio/bio_lib.c Lines: 143 264 54.2 %
Date: 2016-12-06 Branches: 64 166 38.6 %

Line Branch Exec Source
1
/* $OpenBSD: bio_lib.c,v 1.22 2015/02/10 11:22:21 jsing 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
62
#include <openssl/bio.h>
63
#include <openssl/crypto.h>
64
#include <openssl/err.h>
65
#include <openssl/stack.h>
66
67
BIO *
68
BIO_new(BIO_METHOD *method)
69
453
{
70
453
	BIO *ret = NULL;
71
72
453
	ret = malloc(sizeof(BIO));
73
453
	if (ret == NULL) {
74
		BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
75
		return (NULL);
76
	}
77
453
	if (!BIO_set(ret, method)) {
78
		free(ret);
79
		ret = NULL;
80
	}
81
453
	return (ret);
82
}
83
84
int
85
BIO_set(BIO *bio, BIO_METHOD *method)
86
453
{
87
453
	bio->method = method;
88
453
	bio->callback = NULL;
89
453
	bio->cb_arg = NULL;
90
453
	bio->init = 0;
91
453
	bio->shutdown = 1;
92
453
	bio->flags = 0;
93
453
	bio->retry_reason = 0;
94
453
	bio->num = 0;
95
453
	bio->ptr = NULL;
96
453
	bio->prev_bio = NULL;
97
453
	bio->next_bio = NULL;
98
453
	bio->references = 1;
99
453
	bio->num_read = 0L;
100
453
	bio->num_write = 0L;
101
453
	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
102
453
	if (method->create != NULL)
103
453
		if (!method->create(bio)) {
104
			CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio,
105
			    &bio->ex_data);
106
			return (0);
107
		}
108
453
	return (1);
109
}
110
111
int
112
BIO_free(BIO *a)
113
458
{
114
	int i;
115
116
458
	if (a == NULL)
117
10
		return (0);
118
119
448
	i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO);
120
448
	if (i > 0)
121
		return (1);
122

448
	if ((a->callback != NULL) &&
123
	    ((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0))
124
		return (i);
125
126
448
	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
127
128

448
	if (a->method != NULL && a->method->destroy != NULL)
129
448
		a->method->destroy(a);
130
448
	free(a);
131
448
	return (1);
132
}
133
134
void
135
BIO_vfree(BIO *a)
136
{
137
	BIO_free(a);
138
}
139
140
void
141
BIO_clear_flags(BIO *b, int flags)
142
1028
{
143
1028
	b->flags &= ~flags;
144
1028
}
145
146
int
147
BIO_test_flags(const BIO *b, int flags)
148
607
{
149
607
	return (b->flags & flags);
150
}
151
152
void
153
BIO_set_flags(BIO *b, int flags)
154
205
{
155
205
	b->flags |= flags;
156
205
}
157
158
long
159
(*BIO_get_callback(const BIO *b))(struct bio_st *, int, const char *, int,
160
    long, long)
161
{
162
	return b->callback;
163
}
164
165
void
166
BIO_set_callback(BIO *b, long (*cb)(struct bio_st *, int, const char *, int,
167
    long, long))
168
{
169
	b->callback = cb;
170
}
171
172
void
173
BIO_set_callback_arg(BIO *b, char *arg)
174
{
175
	b->cb_arg = arg;
176
}
177
178
char *
179
BIO_get_callback_arg(const BIO *b)
180
{
181
	return b->cb_arg;
182
}
183
184
const char *
185
BIO_method_name(const BIO *b)
186
{
187
	return b->method->name;
188
}
189
190
int
191
BIO_method_type(const BIO *b)
192
2
{
193
2
	return b->method->type;
194
}
195
196
int
197
BIO_read(BIO *b, void *out, int outl)
198
364
{
199
	int i;
200
	long (*cb)(BIO *, int, const char *, int, long, long);
201
202

364
	if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) {
203
		BIOerr(BIO_F_BIO_READ, BIO_R_UNSUPPORTED_METHOD);
204
		return (-2);
205
	}
206
207
364
	cb = b->callback;
208

364
	if ((cb != NULL) &&
209
	    ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0))
210
		return (i);
211
212
364
	if (!b->init) {
213
		BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED);
214
		return (-2);
215
	}
216
217
364
	i = b->method->bread(b, out, outl);
218
219
364
	if (i > 0)
220
219
		b->num_read += (unsigned long)i;
221
222
364
	if (cb != NULL)
223
		i = (int)cb(b, BIO_CB_READ|BIO_CB_RETURN, out, outl,
224
		    0L, (long)i);
225
364
	return (i);
226
}
227
228
int
229
BIO_write(BIO *b, const void *in, int inl)
230
794112
{
231
	int i;
232
	long (*cb)(BIO *, int, const char *, int, long, long);
233
234
794112
	if (b == NULL)
235
		return (0);
236
237
794112
	cb = b->callback;
238

794112
	if ((b->method == NULL) || (b->method->bwrite == NULL)) {
239
		BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD);
240
		return (-2);
241
	}
242
243

794112
	if ((cb != NULL) &&
244
	    ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0))
245
		return (i);
246
247
794112
	if (!b->init) {
248
		BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED);
249
		return (-2);
250
	}
251
252
794112
	i = b->method->bwrite(b, in, inl);
253
254
794112
	if (i > 0)
255
794110
		b->num_write += (unsigned long)i;
256
257
794112
	if (cb != NULL)
258
		i = (int)cb(b, BIO_CB_WRITE|BIO_CB_RETURN, in, inl,
259
		    0L, (long)i);
260
794112
	return (i);
261
}
262
263
int
264
BIO_puts(BIO *b, const char *in)
265
7397
{
266
	int i;
267
	long (*cb)(BIO *, int, const char *, int, long, long);
268
269

7397
	if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
270
		BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD);
271
		return (-2);
272
	}
273
274
7397
	cb = b->callback;
275
276

7397
	if ((cb != NULL) &&
277
	    ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0))
278
		return (i);
279
280
7397
	if (!b->init) {
281
		BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED);
282
		return (-2);
283
	}
284
285
7397
	i = b->method->bputs(b, in);
286
287
7397
	if (i > 0)
288
7397
		b->num_write += (unsigned long)i;
289
290
7397
	if (cb != NULL)
291
		i = (int)cb(b, BIO_CB_PUTS|BIO_CB_RETURN, in, 0, 0L, (long)i);
292
7397
	return (i);
293
}
294
295
int
296
BIO_gets(BIO *b, char *in, int inl)
297
7574
{
298
	int i;
299
	long (*cb)(BIO *, int, const char *, int, long, long);
300
301

7574
	if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
302
		BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
303
		return (-2);
304
	}
305
306
7574
	cb = b->callback;
307
308

7574
	if ((cb != NULL) &&
309
	    ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0))
310
		return (i);
311
312
7574
	if (!b->init) {
313
		BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
314
		return (-2);
315
	}
316
317
7574
	i = b->method->bgets(b, in, inl);
318
319
7574
	if (cb != NULL)
320
		i = (int)cb(b, BIO_CB_GETS|BIO_CB_RETURN, in, inl, 0L, (long)i);
321
7574
	return (i);
322
}
323
324
int
325
BIO_indent(BIO *b, int indent, int max)
326
30
{
327
30
	if (indent < 0)
328
		indent = 0;
329
30
	if (indent > max)
330
		indent = max;
331
126
	while (indent--)
332
96
		if (BIO_puts(b, " ") != 1)
333
			return 0;
334
30
	return 1;
335
}
336
337
long
338
BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
339
4
{
340
	int i;
341
342
4
	i = iarg;
343
4
	return (BIO_ctrl(b, cmd, larg, (char *)&i));
344
}
345
346
char *
347
BIO_ptr_ctrl(BIO *b, int cmd, long larg)
348
{
349
	char *p = NULL;
350
351
	if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
352
		return (NULL);
353
	else
354
		return (p);
355
}
356
357
long
358
BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
359
1983
{
360
	long ret;
361
	long (*cb)(BIO *, int, const char *, int, long, long);
362
363
1983
	if (b == NULL)
364
		return (0);
365
366

1983
	if ((b->method == NULL) || (b->method->ctrl == NULL)) {
367
		BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
368
		return (-2);
369
	}
370
371
1983
	cb = b->callback;
372
373

1983
	if ((cb != NULL) &&
374
	    ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0))
375
		return (ret);
376
377
1983
	ret = b->method->ctrl(b, cmd, larg, parg);
378
379
1983
	if (cb != NULL)
380
		ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN, parg, cmd, larg, ret);
381
1983
	return (ret);
382
}
383
384
long
385
BIO_callback_ctrl(BIO *b, int cmd,
386
    void (*fp)(struct bio_st *, int, const char *, int, long, long))
387
{
388
	long ret;
389
	long (*cb)(BIO *, int, const char *, int, long, long);
390
391
	if (b == NULL)
392
		return (0);
393
394
	if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) {
395
		BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD);
396
		return (-2);
397
	}
398
399
	cb = b->callback;
400
401
	if ((cb != NULL) &&
402
	    ((ret = cb(b, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L)) <= 0))
403
		return (ret);
404
405
	ret = b->method->callback_ctrl(b, cmd, fp);
406
407
	if (cb != NULL)
408
		ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN, (void *)&fp, cmd, 0, ret);
409
	return (ret);
410
}
411
412
/* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
413
 * do; but those macros have inappropriate return type, and for interfacing
414
 * from other programming languages, C macros aren't much of a help anyway. */
415
size_t
416
BIO_ctrl_pending(BIO *bio)
417
{
418
	return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
419
}
420
421
size_t
422
BIO_ctrl_wpending(BIO *bio)
423
{
424
	return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
425
}
426
427
428
/* put the 'bio' on the end of b's list of operators */
429
BIO *
430
BIO_push(BIO *b, BIO *bio)
431
172
{
432
	BIO *lb;
433
434
172
	if (b == NULL)
435
		return (bio);
436
172
	lb = b;
437
344
	while (lb->next_bio != NULL)
438
		lb = lb->next_bio;
439
172
	lb->next_bio = bio;
440
172
	if (bio != NULL)
441
172
		bio->prev_bio = lb;
442
	/* called to do internal processing */
443
172
	BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
444
172
	return (b);
445
}
446
447
/* Remove the first and return the rest */
448
BIO *
449
BIO_pop(BIO *b)
450
5
{
451
	BIO *ret;
452
453
5
	if (b == NULL)
454
		return (NULL);
455
5
	ret = b->next_bio;
456
457
5
	BIO_ctrl(b, BIO_CTRL_POP, 0, b);
458
459
5
	if (b->prev_bio != NULL)
460
		b->prev_bio->next_bio = b->next_bio;
461
5
	if (b->next_bio != NULL)
462
5
		b->next_bio->prev_bio = b->prev_bio;
463
464
5
	b->next_bio = NULL;
465
5
	b->prev_bio = NULL;
466
5
	return (ret);
467
}
468
469
BIO *
470
BIO_get_retry_BIO(BIO *bio, int *reason)
471
{
472
	BIO *b, *last;
473
474
	b = last = bio;
475
	for (;;) {
476
		if (!BIO_should_retry(b))
477
			break;
478
		last = b;
479
		b = b->next_bio;
480
		if (b == NULL)
481
			break;
482
	}
483
	if (reason != NULL)
484
		*reason = last->retry_reason;
485
	return (last);
486
}
487
488
int
489
BIO_get_retry_reason(BIO *bio)
490
{
491
	return (bio->retry_reason);
492
}
493
494
BIO *
495
BIO_find_type(BIO *bio, int type)
496
6
{
497
	int mt, mask;
498
499
6
	if (!bio)
500
		return NULL;
501
6
	mask = type & 0xff;
502
	do {
503
8
		if (bio->method != NULL) {
504
8
			mt = bio->method->type;
505
8
			if (!mask) {
506
				if (mt & type)
507
					return (bio);
508
8
			} else if (mt == type)
509
6
				return (bio);
510
		}
511
2
		bio = bio->next_bio;
512
2
	} while (bio != NULL);
513
	return (NULL);
514
}
515
516
BIO *
517
BIO_next(BIO *b)
518
{
519
	if (!b)
520
		return NULL;
521
	return b->next_bio;
522
}
523
524
void
525
BIO_free_all(BIO *bio)
526
169
{
527
	BIO *b;
528
	int ref;
529
530
664
	while (bio != NULL) {
531
326
		b = bio;
532
326
		ref = b->references;
533
326
		bio = bio->next_bio;
534
326
		BIO_free(b);
535
		/* Since ref count > 1, don't free anyone else. */
536
326
		if (ref > 1)
537
			break;
538
	}
539
169
}
540
541
BIO *
542
BIO_dup_chain(BIO *in)
543
{
544
	BIO *ret = NULL, *eoc = NULL, *bio, *new_bio;
545
546
	for (bio = in; bio != NULL; bio = bio->next_bio) {
547
		if ((new_bio = BIO_new(bio->method)) == NULL)
548
			goto err;
549
		new_bio->callback = bio->callback;
550
		new_bio->cb_arg = bio->cb_arg;
551
		new_bio->init = bio->init;
552
		new_bio->shutdown = bio->shutdown;
553
		new_bio->flags = bio->flags;
554
555
		/* This will let SSL_s_sock() work with stdin/stdout */
556
		new_bio->num = bio->num;
557
558
		if (!BIO_dup_state(bio, (char *)new_bio)) {
559
			BIO_free(new_bio);
560
			goto err;
561
		}
562
563
		/* copy app data */
564
		if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO,
565
		    &new_bio->ex_data, &bio->ex_data))
566
			goto err;
567
568
		if (ret == NULL) {
569
			eoc = new_bio;
570
			ret = eoc;
571
		} else {
572
			BIO_push(eoc, new_bio);
573
			eoc = new_bio;
574
		}
575
	}
576
	return (ret);
577
err:
578
	BIO_free(ret);
579
	return (NULL);
580
581
}
582
583
void
584
BIO_copy_next_retry(BIO *b)
585
130
{
586
130
	BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
587
130
	b->retry_reason = b->next_bio->retry_reason;
588
130
}
589
590
int
591
BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
592
    CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
593
{
594
	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp,
595
	    new_func, dup_func, free_func);
596
}
597
598
int
599
BIO_set_ex_data(BIO *bio, int idx, void *data)
600
{
601
	return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data));
602
}
603
604
void *
605
BIO_get_ex_data(BIO *bio, int idx)
606
{
607
	return (CRYPTO_get_ex_data(&(bio->ex_data), idx));
608
}
609
610
unsigned long
611
BIO_number_read(BIO *bio)
612
{
613
	if (bio)
614
		return bio->num_read;
615
	return 0;
616
}
617
618
unsigned long
619
BIO_number_written(BIO *bio)
620
{
621
	if (bio)
622
		return bio->num_write;
623
	return 0;
624
}