xref: /dragonfly/crypto/libressl/crypto/bio/bio_lib.c (revision f5b1c8a1)
1 /* $OpenBSD: bio_lib.c,v 1.21 2014/07/25 06:05:32 doug 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 {
70 	BIO *ret = NULL;
71 
72 	ret = malloc(sizeof(BIO));
73 	if (ret == NULL) {
74 		BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
75 		return (NULL);
76 	}
77 	if (!BIO_set(ret, method)) {
78 		free(ret);
79 		ret = NULL;
80 	}
81 	return (ret);
82 }
83 
84 int
85 BIO_set(BIO *bio, BIO_METHOD *method)
86 {
87 	bio->method = method;
88 	bio->callback = NULL;
89 	bio->cb_arg = NULL;
90 	bio->init = 0;
91 	bio->shutdown = 1;
92 	bio->flags = 0;
93 	bio->retry_reason = 0;
94 	bio->num = 0;
95 	bio->ptr = NULL;
96 	bio->prev_bio = NULL;
97 	bio->next_bio = NULL;
98 	bio->references = 1;
99 	bio->num_read = 0L;
100 	bio->num_write = 0L;
101 	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
102 	if (method->create != NULL)
103 		if (!method->create(bio)) {
104 			CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio,
105 			    &bio->ex_data);
106 			return (0);
107 		}
108 	return (1);
109 }
110 
111 int
112 BIO_free(BIO *a)
113 {
114 	int i;
115 
116 	if (a == NULL)
117 		return (0);
118 
119 	i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO);
120 	if (i > 0)
121 		return (1);
122 	if ((a->callback != NULL) &&
123 	    ((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0))
124 		return (i);
125 
126 	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
127 
128 	if (a->method != NULL && a->method->destroy != NULL)
129 		a->method->destroy(a);
130 	free(a);
131 	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 {
143 	b->flags &= ~flags;
144 }
145 
146 int
147 BIO_test_flags(const BIO *b, int flags)
148 {
149 	return (b->flags & flags);
150 }
151 
152 void
153 BIO_set_flags(BIO *b, int flags)
154 {
155 	b->flags |= flags;
156 }
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 {
193 	return b->method->type;
194 }
195 
196 int
197 BIO_read(BIO *b, void *out, int outl)
198 {
199 	int i;
200 	long (*cb)(BIO *, int, const char *, int, long, long);
201 
202 	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 	cb = b->callback;
208 	if ((cb != NULL) &&
209 	    ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0))
210 		return (i);
211 
212 	if (!b->init) {
213 		BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED);
214 		return (-2);
215 	}
216 
217 	i = b->method->bread(b, out, outl);
218 
219 	if (i > 0)
220 		b->num_read += (unsigned long)i;
221 
222 	if (cb != NULL)
223 		i = (int)cb(b, BIO_CB_READ|BIO_CB_RETURN, out, outl,
224 		    0L, (long)i);
225 	return (i);
226 }
227 
228 int
229 BIO_write(BIO *b, const void *in, int inl)
230 {
231 	int i;
232 	long (*cb)(BIO *, int, const char *, int, long, long);
233 
234 	if (b == NULL)
235 		return (0);
236 
237 	cb = b->callback;
238 	if ((b->method == NULL) || (b->method->bwrite == NULL)) {
239 		BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD);
240 		return (-2);
241 	}
242 
243 	if ((cb != NULL) &&
244 	    ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0))
245 		return (i);
246 
247 	if (!b->init) {
248 		BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED);
249 		return (-2);
250 	}
251 
252 	i = b->method->bwrite(b, in, inl);
253 
254 	if (i > 0)
255 		b->num_write += (unsigned long)i;
256 
257 	if (cb != NULL)
258 		i = (int)cb(b, BIO_CB_WRITE|BIO_CB_RETURN, in, inl,
259 		    0L, (long)i);
260 	return (i);
261 }
262 
263 int
264 BIO_puts(BIO *b, const char *in)
265 {
266 	int i;
267 	long (*cb)(BIO *, int, const char *, int, long, long);
268 
269 	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 	cb = b->callback;
275 
276 	if ((cb != NULL) &&
277 	    ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0))
278 		return (i);
279 
280 	if (!b->init) {
281 		BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED);
282 		return (-2);
283 	}
284 
285 	i = b->method->bputs(b, in);
286 
287 	if (i > 0)
288 		b->num_write += (unsigned long)i;
289 
290 	if (cb != NULL)
291 		i = (int)cb(b, BIO_CB_PUTS|BIO_CB_RETURN, in, 0, 0L, (long)i);
292 	return (i);
293 }
294 
295 int
296 BIO_gets(BIO *b, char *in, int inl)
297 {
298 	int i;
299 	long (*cb)(BIO *, int, const char *, int, long, long);
300 
301 	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 	cb = b->callback;
307 
308 	if ((cb != NULL) &&
309 	    ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0))
310 		return (i);
311 
312 	if (!b->init) {
313 		BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
314 		return (-2);
315 	}
316 
317 	i = b->method->bgets(b, in, inl);
318 
319 	if (cb != NULL)
320 		i = (int)cb(b, BIO_CB_GETS|BIO_CB_RETURN, in, inl, 0L, (long)i);
321 	return (i);
322 }
323 
324 int
325 BIO_indent(BIO *b, int indent, int max)
326 {
327 	if (indent < 0)
328 		indent = 0;
329 	if (indent > max)
330 		indent = max;
331 	while (indent--)
332 		if (BIO_puts(b, " ") != 1)
333 			return 0;
334 	return 1;
335 }
336 
337 long
338 BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
339 {
340 	int i;
341 
342 	i = iarg;
343 	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 {
360 	long ret;
361 	long (*cb)(BIO *, int, const char *, int, long, long);
362 
363 	if (b == NULL)
364 		return (0);
365 
366 	if ((b->method == NULL) || (b->method->ctrl == NULL)) {
367 		BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
368 		return (-2);
369 	}
370 
371 	cb = b->callback;
372 
373 	if ((cb != NULL) &&
374 	    ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0))
375 		return (ret);
376 
377 	ret = b->method->ctrl(b, cmd, larg, parg);
378 
379 	if (cb != NULL)
380 		ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN, parg, cmd, larg, ret);
381 	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 {
432 	BIO *lb;
433 
434 	if (b == NULL)
435 		return (bio);
436 	lb = b;
437 	while (lb->next_bio != NULL)
438 		lb = lb->next_bio;
439 	lb->next_bio = bio;
440 	if (bio != NULL)
441 		bio->prev_bio = lb;
442 	/* called to do internal processing */
443 	BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
444 	return (b);
445 }
446 
447 /* Remove the first and return the rest */
448 BIO *
449 BIO_pop(BIO *b)
450 {
451 	BIO *ret;
452 
453 	if (b == NULL)
454 		return (NULL);
455 	ret = b->next_bio;
456 
457 	BIO_ctrl(b, BIO_CTRL_POP, 0, b);
458 
459 	if (b->prev_bio != NULL)
460 		b->prev_bio->next_bio = b->next_bio;
461 	if (b->next_bio != NULL)
462 		b->next_bio->prev_bio = b->prev_bio;
463 
464 	b->next_bio = NULL;
465 	b->prev_bio = NULL;
466 	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 {
497 	int mt, mask;
498 
499 	if (!bio)
500 		return NULL;
501 	mask = type & 0xff;
502 	do {
503 		if (bio->method != NULL) {
504 			mt = bio->method->type;
505 			if (!mask) {
506 				if (mt & type)
507 					return (bio);
508 			} else if (mt == type)
509 				return (bio);
510 		}
511 		bio = bio->next_bio;
512 	} 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 {
527 	BIO *b;
528 	int ref;
529 
530 	while (bio != NULL) {
531 		b = bio;
532 		ref = b->references;
533 		bio = bio->next_bio;
534 		BIO_free(b);
535 		/* Since ref count > 1, don't free anyone else. */
536 		if (ref > 1)
537 			break;
538 	}
539 }
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 {
586 	BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
587 	b->retry_reason = b->next_bio->retry_reason;
588 }
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 }
625