Make the necessary changes to work with the recent "ex_data" overhaul.
[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 long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
276         {
277         int i;
278
279         i=iarg;
280         return(BIO_ctrl(b,cmd,larg,(char *)&i));
281         }
282
283 char *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
284         {
285         char *p=NULL;
286
287         if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0)
288                 return(NULL);
289         else
290                 return(p);
291         }
292
293 long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
294         {
295         long ret;
296         long (*cb)();
297
298         if (b == NULL) return(0);
299
300         if ((b->method == NULL) || (b->method->ctrl == NULL))
301                 {
302                 BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
303                 return(-2);
304                 }
305
306         cb=b->callback;
307
308         if ((cb != NULL) &&
309                 ((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))
310                 return(ret);
311
312         ret=b->method->ctrl(b,cmd,larg,parg);
313
314         if (cb != NULL)
315                 ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,
316                         larg,ret);
317         return(ret);
318         }
319
320 long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long))
321         {
322         long ret;
323         long (*cb)();
324
325         if (b == NULL) return(0);
326
327         if ((b->method == NULL) || (b->method->callback_ctrl == NULL))
328                 {
329                 BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);
330                 return(-2);
331                 }
332
333         cb=b->callback;
334
335         if ((cb != NULL) &&
336                 ((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0))
337                 return(ret);
338
339         ret=b->method->callback_ctrl(b,cmd,fp);
340
341         if (cb != NULL)
342                 ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd,
343                         0,ret);
344         return(ret);
345         }
346
347 /* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
348  * do; but those macros have inappropriate return type, and for interfacing
349  * from other programming languages, C macros aren't much of a help anyway. */
350 size_t BIO_ctrl_pending(BIO *bio)
351         {
352         return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
353         }
354
355 size_t BIO_ctrl_wpending(BIO *bio)
356         {
357         return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
358         }
359
360
361 /* put the 'bio' on the end of b's list of operators */
362 BIO *BIO_push(BIO *b, BIO *bio)
363         {
364         BIO *lb;
365
366         if (b == NULL) return(bio);
367         lb=b;
368         while (lb->next_bio != NULL)
369                 lb=lb->next_bio;
370         lb->next_bio=bio;
371         if (bio != NULL)
372                 bio->prev_bio=lb;
373         /* called to do internal processing */
374         BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL);
375         return(b);
376         }
377
378 /* Remove the first and return the rest */
379 BIO *BIO_pop(BIO *b)
380         {
381         BIO *ret;
382
383         if (b == NULL) return(NULL);
384         ret=b->next_bio;
385
386         if (b->prev_bio != NULL)
387                 b->prev_bio->next_bio=b->next_bio;
388         if (b->next_bio != NULL)
389                 b->next_bio->prev_bio=b->prev_bio;
390
391         b->next_bio=NULL;
392         b->prev_bio=NULL;
393         BIO_ctrl(b,BIO_CTRL_POP,0,NULL);
394         return(ret);
395         }
396
397 BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
398         {
399         BIO *b,*last;
400
401         b=last=bio;
402         for (;;)
403                 {
404                 if (!BIO_should_retry(b)) break;
405                 last=b;
406                 b=b->next_bio;
407                 if (b == NULL) break;
408                 }
409         if (reason != NULL) *reason=last->retry_reason;
410         return(last);
411         }
412
413 int BIO_get_retry_reason(BIO *bio)
414         {
415         return(bio->retry_reason);
416         }
417
418 BIO *BIO_find_type(BIO *bio, int type)
419         {
420         int mt,mask;
421
422         if(!bio) return NULL;
423         mask=type&0xff;
424         do      {
425                 if (bio->method != NULL)
426                         {
427                         mt=bio->method->type;
428
429                         if (!mask)
430                                 {
431                                 if (mt & type) return(bio);
432                                 }
433                         else if (mt == type)
434                                 return(bio);
435                         }
436                 bio=bio->next_bio;
437                 } while (bio != NULL);
438         return(NULL);
439         }
440
441 BIO *BIO_next(BIO *b)
442         {
443         if(!b) return NULL;
444         return b->next_bio;
445         }
446
447 void BIO_free_all(BIO *bio)
448         {
449         BIO *b;
450         int ref;
451
452         while (bio != NULL)
453                 {
454                 b=bio;
455                 ref=b->references;
456                 bio=bio->next_bio;
457                 BIO_free(b);
458                 /* Since ref count > 1, don't free anyone else. */
459                 if (ref > 1) break;
460                 }
461         }
462
463 BIO *BIO_dup_chain(BIO *in)
464         {
465         BIO *ret=NULL,*eoc=NULL,*bio,*new;
466
467         for (bio=in; bio != NULL; bio=bio->next_bio)
468                 {
469                 if ((new=BIO_new(bio->method)) == NULL) goto err;
470                 new->callback=bio->callback;
471                 new->cb_arg=bio->cb_arg;
472                 new->init=bio->init;
473                 new->shutdown=bio->shutdown;
474                 new->flags=bio->flags;
475
476                 /* This will let SSL_s_sock() work with stdin/stdout */
477                 new->num=bio->num;
478
479                 if (!BIO_dup_state(bio,(char *)new))
480                         {
481                         BIO_free(new);
482                         goto err;
483                         }
484
485                 /* copy app data */
486                 if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new->ex_data,
487                                         &bio->ex_data))
488                         goto err;
489
490                 if (ret == NULL)
491                         {
492                         eoc=new;
493                         ret=eoc;
494                         }
495                 else
496                         {
497                         BIO_push(eoc,new);
498                         eoc=new;
499                         }
500                 }
501         return(ret);
502 err:
503         if (ret != NULL)
504                 BIO_free(ret);
505         return(NULL);   
506         }
507
508 void BIO_copy_next_retry(BIO *b)
509         {
510         BIO_set_flags(b,BIO_get_retry_flags(b->next_bio));
511         b->retry_reason=b->next_bio->retry_reason;
512         }
513
514 int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
515              CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
516         {
517         return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp,
518                                 new_func, dup_func, free_func);
519         }
520
521 int BIO_set_ex_data(BIO *bio, int idx, void *data)
522         {
523         return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data));
524         }
525
526 void *BIO_get_ex_data(BIO *bio, int idx)
527         {
528         return(CRYPTO_get_ex_data(&(bio->ex_data),idx));
529         }
530
531 unsigned long BIO_number_read(BIO *bio)
532 {
533         if(bio) return bio->num_read;
534         return 0;
535 }
536
537 unsigned long BIO_number_written(BIO *bio)
538 {
539         if(bio) return bio->num_write;
540         return 0;
541 }
542
543 IMPLEMENT_STACK_OF(BIO)