Security fixes brought forward from 0.9.7.
[openssl.git] / crypto / bio / bio_lib.c
1 /* crypto/bio/bio_lib.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 <errno.h>
61 #include <openssl/crypto.h>
62 #include "cryptlib.h"
63 #include <openssl/bio.h>
64 #include <openssl/stack.h>
65
66 BIO *BIO_new(BIO_METHOD *method)
67         {
68         BIO *ret=NULL;
69
70         ret=(BIO *)OPENSSL_malloc(sizeof(BIO));
71         if (ret == NULL)
72                 {
73                 BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE);
74                 return(NULL);
75                 }
76         if (!BIO_set(ret,method))
77                 {
78                 OPENSSL_free(ret);
79                 ret=NULL;
80                 }
81         return(ret);
82         }
83
84 int BIO_set(BIO *bio, BIO_METHOD *method)
85         {
86         bio->method=method;
87         bio->callback=NULL;
88         bio->cb_arg=NULL;
89         bio->init=0;
90         bio->shutdown=1;
91         bio->flags=0;
92         bio->retry_reason=0;
93         bio->num=0;
94         bio->ptr=NULL;
95         bio->prev_bio=NULL;
96         bio->next_bio=NULL;
97         bio->references=1;
98         bio->num_read=0L;
99         bio->num_write=0L;
100         CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
101         if (method->create != NULL)
102                 if (!method->create(bio))
103                         {
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 BIO_free(BIO *a)
112         {
113         int ret=0,i;
114
115         if (a == NULL) return(0);
116
117         i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_BIO);
118 #ifdef REF_PRINT
119         REF_PRINT("BIO",a);
120 #endif
121         if (i > 0) return(1);
122 #ifdef REF_CHECK
123         if (i < 0)
124                 {
125                 fprintf(stderr,"BIO_free, bad reference count\n");
126                 abort();
127                 }
128 #endif
129         if ((a->callback != NULL) &&
130                 ((i=(int)a->callback(a,BIO_CB_FREE,NULL,0,0L,1L)) <= 0))
131                         return(i);
132
133         CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
134
135         if ((a->method == NULL) || (a->method->destroy == NULL)) return(1);
136         ret=a->method->destroy(a);
137         OPENSSL_free(a);
138         return(1);
139         }
140
141 void BIO_vfree(BIO *a)
142     { BIO_free(a); }
143
144 int BIO_read(BIO *b, void *out, int outl)
145         {
146         int i;
147         long (*cb)();
148
149         if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL))
150                 {
151                 BIOerr(BIO_F_BIO_READ,BIO_R_UNSUPPORTED_METHOD);
152                 return(-2);
153                 }
154
155         cb=b->callback;
156         if ((cb != NULL) &&
157                 ((i=(int)cb(b,BIO_CB_READ,out,outl,0L,1L)) <= 0))
158                         return(i);
159
160         if (!b->init)
161                 {
162                 BIOerr(BIO_F_BIO_READ,BIO_R_UNINITIALIZED);
163                 return(-2);
164                 }
165
166         i=b->method->bread(b,out,outl);
167
168         if (i > 0) b->num_read+=(unsigned long)i;
169
170         if (cb != NULL)
171                 i=(int)cb(b,BIO_CB_READ|BIO_CB_RETURN,out,outl,
172                         0L,(long)i);
173         return(i);
174         }
175
176 int BIO_write(BIO *b, const void *in, int inl)
177         {
178         int i;
179         long (*cb)();
180
181         if (b == NULL)
182                 return(0);
183
184         cb=b->callback;
185         if ((b->method == NULL) || (b->method->bwrite == NULL))
186                 {
187                 BIOerr(BIO_F_BIO_WRITE,BIO_R_UNSUPPORTED_METHOD);
188                 return(-2);
189                 }
190
191         if ((cb != NULL) &&
192                 ((i=(int)cb(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0))
193                         return(i);
194
195         if (!b->init)
196                 {
197                 BIOerr(BIO_F_BIO_WRITE,BIO_R_UNINITIALIZED);
198                 return(-2);
199                 }
200
201         i=b->method->bwrite(b,in,inl);
202
203         if (i > 0) b->num_write+=(unsigned long)i;
204
205         if (cb != NULL)
206                 i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl,
207                         0L,(long)i);
208         return(i);
209         }
210
211 int BIO_puts(BIO *b, const char *in)
212         {
213         int i;
214         long (*cb)();
215
216         if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL))
217                 {
218                 BIOerr(BIO_F_BIO_PUTS,BIO_R_UNSUPPORTED_METHOD);
219                 return(-2);
220                 }
221
222         cb=b->callback;
223
224         if ((cb != NULL) &&
225                 ((i=(int)cb(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0))
226                         return(i);
227
228         if (!b->init)
229                 {
230                 BIOerr(BIO_F_BIO_PUTS,BIO_R_UNINITIALIZED);
231                 return(-2);
232                 }
233
234         i=b->method->bputs(b,in);
235
236         if (i > 0) b->num_write+=(unsigned long)i;
237
238         if (cb != NULL)
239                 i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0,
240                         0L,(long)i);
241         return(i);
242         }
243
244 int BIO_gets(BIO *b, char *in, int inl)
245         {
246         int i;
247         long (*cb)();
248
249         if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL))
250                 {
251                 BIOerr(BIO_F_BIO_GETS,BIO_R_UNSUPPORTED_METHOD);
252                 return(-2);
253                 }
254
255         cb=b->callback;
256
257         if ((cb != NULL) &&
258                 ((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0))
259                         return(i);
260
261         if (!b->init)
262                 {
263                 BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITIALIZED);
264                 return(-2);
265                 }
266
267         i=b->method->bgets(b,in,inl);
268
269         if (cb != NULL)
270                 i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl,
271                         0L,(long)i);
272         return(i);
273         }
274
275 int BIO_indent(BIO *b,int indent,int max)
276         {
277         if(indent < 0)
278                 indent=0;
279         if(indent > max)
280                 indent=max;
281         while(indent--)
282                 if(BIO_puts(b," ") != 1)
283                         return 0;
284         return 1;
285         }
286
287 long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
288         {
289         int i;
290
291         i=iarg;
292         return(BIO_ctrl(b,cmd,larg,(char *)&i));
293         }
294
295 char *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
296         {
297         char *p=NULL;
298
299         if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0)
300                 return(NULL);
301         else
302                 return(p);
303         }
304
305 long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
306         {
307         long ret;
308         long (*cb)();
309
310         if (b == NULL) return(0);
311
312         if ((b->method == NULL) || (b->method->ctrl == NULL))
313                 {
314                 BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
315                 return(-2);
316                 }
317
318         cb=b->callback;
319
320         if ((cb != NULL) &&
321                 ((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))
322                 return(ret);
323
324         ret=b->method->ctrl(b,cmd,larg,parg);
325
326         if (cb != NULL)
327                 ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,
328                         larg,ret);
329         return(ret);
330         }
331
332 long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long))
333         {
334         long ret;
335         long (*cb)();
336
337         if (b == NULL) return(0);
338
339         if ((b->method == NULL) || (b->method->callback_ctrl == NULL))
340                 {
341                 BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
342                 return(-2);
343                 }
344
345         cb=b->callback;
346
347         if ((cb != NULL) &&
348                 ((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0))
349                 return(ret);
350
351         ret=b->method->callback_ctrl(b,cmd,fp);
352
353         if (cb != NULL)
354                 ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd,
355                         0,ret);
356         return(ret);
357         }
358
359 /* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
360  * do; but those macros have inappropriate return type, and for interfacing
361  * from other programming languages, C macros aren't much of a help anyway. */
362 size_t BIO_ctrl_pending(BIO *bio)
363         {
364         return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
365         }
366
367 size_t BIO_ctrl_wpending(BIO *bio)
368         {
369         return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
370         }
371
372
373 /* put the 'bio' on the end of b's list of operators */
374 BIO *BIO_push(BIO *b, BIO *bio)
375         {
376         BIO *lb;
377
378         if (b == NULL) return(bio);
379         lb=b;
380         while (lb->next_bio != NULL)
381                 lb=lb->next_bio;
382         lb->next_bio=bio;
383         if (bio != NULL)
384                 bio->prev_bio=lb;
385         /* called to do internal processing */
386         BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL);
387         return(b);
388         }
389
390 /* Remove the first and return the rest */
391 BIO *BIO_pop(BIO *b)
392         {
393         BIO *ret;
394
395         if (b == NULL) return(NULL);
396         ret=b->next_bio;
397
398         if (b->prev_bio != NULL)
399                 b->prev_bio->next_bio=b->next_bio;
400         if (b->next_bio != NULL)
401                 b->next_bio->prev_bio=b->prev_bio;
402
403         b->next_bio=NULL;
404         b->prev_bio=NULL;
405         BIO_ctrl(b,BIO_CTRL_POP,0,NULL);
406         return(ret);
407         }
408
409 BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
410         {
411         BIO *b,*last;
412
413         b=last=bio;
414         for (;;)
415                 {
416                 if (!BIO_should_retry(b)) break;
417                 last=b;
418                 b=b->next_bio;
419                 if (b == NULL) break;
420                 }
421         if (reason != NULL) *reason=last->retry_reason;
422         return(last);
423         }
424
425 int BIO_get_retry_reason(BIO *bio)
426         {
427         return(bio->retry_reason);
428         }
429
430 BIO *BIO_find_type(BIO *bio, int type)
431         {
432         int mt,mask;
433
434         if(!bio) return NULL;
435         mask=type&0xff;
436         do      {
437                 if (bio->method != NULL)
438                         {
439                         mt=bio->method->type;
440
441                         if (!mask)
442                                 {
443                                 if (mt & type) return(bio);
444                                 }
445                         else if (mt == type)
446                                 return(bio);
447                         }
448                 bio=bio->next_bio;
449                 } while (bio != NULL);
450         return(NULL);
451         }
452
453 BIO *BIO_next(BIO *b)
454         {
455         if(!b) return NULL;
456         return b->next_bio;
457         }
458
459 void BIO_free_all(BIO *bio)
460         {
461         BIO *b;
462         int ref;
463
464         while (bio != NULL)
465                 {
466                 b=bio;
467                 ref=b->references;
468                 bio=bio->next_bio;
469                 BIO_free(b);
470                 /* Since ref count > 1, don't free anyone else. */
471                 if (ref > 1) break;
472                 }
473         }
474
475 BIO *BIO_dup_chain(BIO *in)
476         {
477         BIO *ret=NULL,*eoc=NULL,*bio,*new;
478
479         for (bio=in; bio != NULL; bio=bio->next_bio)
480                 {
481                 if ((new=BIO_new(bio->method)) == NULL) goto err;
482                 new->callback=bio->callback;
483                 new->cb_arg=bio->cb_arg;
484                 new->init=bio->init;
485                 new->shutdown=bio->shutdown;
486                 new->flags=bio->flags;
487
488                 /* This will let SSL_s_sock() work with stdin/stdout */
489                 new->num=bio->num;
490
491                 if (!BIO_dup_state(bio,(char *)new))
492                         {
493                         BIO_free(new);
494                         goto err;
495                         }
496
497                 /* copy app data */
498                 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new->ex_data,
499                                         &bio->ex_data))
500                         goto err;
501
502                 if (ret == NULL)
503                         {
504                         eoc=new;
505                         ret=eoc;
506                         }
507                 else
508                         {
509                         BIO_push(eoc,new);
510                         eoc=new;
511                         }
512                 }
513         return(ret);
514 err:
515         if (ret != NULL)
516                 BIO_free(ret);
517         return(NULL);   
518         }
519
520 void BIO_copy_next_retry(BIO *b)
521         {
522         BIO_set_flags(b,BIO_get_retry_flags(b->next_bio));
523         b->retry_reason=b->next_bio->retry_reason;
524         }
525
526 int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
527              CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
528         {
529         return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp,
530                                 new_func, dup_func, free_func);
531         }
532
533 int BIO_set_ex_data(BIO *bio, int idx, void *data)
534         {
535         return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data));
536         }
537
538 void *BIO_get_ex_data(BIO *bio, int idx)
539         {
540         return(CRYPTO_get_ex_data(&(bio->ex_data),idx));
541         }
542
543 unsigned long BIO_number_read(BIO *bio)
544 {
545         if(bio) return bio->num_read;
546         return 0;
547 }
548
549 unsigned long BIO_number_written(BIO *bio)
550 {
551         if(bio) return bio->num_write;
552         return 0;
553 }
554
555 IMPLEMENT_STACK_OF(BIO)