OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
bio_lib.c
Go to the documentation of this file.
1 /* crypto/bio/bio_lib.c */
2 /* Copyright (C) 1995-1998 Eric Young ([email protected])
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young ([email protected]).
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 ([email protected]).
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 ([email protected])"
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 ([email protected])"
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 
67  {
68  BIO *ret=NULL;
69 
70  ret=(BIO *)OPENSSL_malloc(sizeof(BIO));
71  if (ret == NULL)
72  {
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;
101  if (method->create != NULL)
102  if (!method->create(bio))
103  {
105  &bio->ex_data);
106  return(0);
107  }
108  return(1);
109  }
110 
112  {
113  int i;
114 
115  if (a == NULL) return(0);
116 
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 
134 
135  if ((a->method == NULL) || (a->method->destroy == NULL)) return(1);
136  a->method->destroy(a);
137  OPENSSL_free(a);
138  return(1);
139  }
140 
142  { BIO_free(a); }
143 
145  {
146  b->flags &= ~flags;
147  }
148 
149 int BIO_test_flags(const BIO *b, int flags)
150  {
151  return (b->flags & flags);
152  }
153 
155  {
156  b->flags |= flags;
157  }
158 
159 long (*BIO_get_callback(const BIO *b))(struct bio_st *,int,const char *,int, long,long)
160  {
161  return b->callback;
162  }
163 
164 void BIO_set_callback(BIO *b, long (*cb)(struct bio_st *,int,const char *,int, long,long))
165  {
166  b->callback = cb;
167  }
168 
169 void BIO_set_callback_arg(BIO *b, char *arg)
170  {
171  b->cb_arg = arg;
172  }
173 
174 char * BIO_get_callback_arg(const BIO *b)
175  {
176  return b->cb_arg;
177  }
178 
179 const char * BIO_method_name(const BIO *b)
180  {
181  return b->method->name;
182  }
183 
184 int BIO_method_type(const BIO *b)
185  {
186  return b->method->type;
187  }
188 
189 
190 int 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  {
198  return(-2);
199  }
200 
201  cb=b->callback;
202  if ((cb != NULL) &&
203  ((i=(int)cb(b,BIO_CB_READ,out,outl,0L,1L)) <= 0))
204  return(i);
205 
206  if (!b->init)
207  {
209  return(-2);
210  }
211 
212  i=b->method->bread(b,out,outl);
213 
214  if (i > 0) b->num_read+=(unsigned long)i;
215 
216  if (cb != NULL)
217  i=(int)cb(b,BIO_CB_READ|BIO_CB_RETURN,out,outl,
218  0L,(long)i);
219  return(i);
220  }
221 
222 int BIO_write(BIO *b, const void *in, int inl)
223  {
224  int i;
225  long (*cb)(BIO *,int,const char *,int,long,long);
226 
227  if (b == NULL)
228  return(0);
229 
230  cb=b->callback;
231  if ((b->method == NULL) || (b->method->bwrite == NULL))
232  {
234  return(-2);
235  }
236 
237  if ((cb != NULL) &&
238  ((i=(int)cb(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0))
239  return(i);
240 
241  if (!b->init)
242  {
244  return(-2);
245  }
246 
247  i=b->method->bwrite(b,in,inl);
248 
249  if (i > 0) b->num_write+=(unsigned long)i;
250 
251  if (cb != NULL)
252  i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl,
253  0L,(long)i);
254  return(i);
255  }
256 
257 int BIO_puts(BIO *b, const char *in)
258  {
259  int i;
260  long (*cb)(BIO *,int,const char *,int,long,long);
261 
262  if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL))
263  {
265  return(-2);
266  }
267 
268  cb=b->callback;
269 
270  if ((cb != NULL) &&
271  ((i=(int)cb(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0))
272  return(i);
273 
274  if (!b->init)
275  {
277  return(-2);
278  }
279 
280  i=b->method->bputs(b,in);
281 
282  if (i > 0) b->num_write+=(unsigned long)i;
283 
284  if (cb != NULL)
285  i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0,
286  0L,(long)i);
287  return(i);
288  }
289 
290 int BIO_gets(BIO *b, char *in, int inl)
291  {
292  int i;
293  long (*cb)(BIO *,int,const char *,int,long,long);
294 
295  if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL))
296  {
298  return(-2);
299  }
300 
301  cb=b->callback;
302 
303  if ((cb != NULL) &&
304  ((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0))
305  return(i);
306 
307  if (!b->init)
308  {
310  return(-2);
311  }
312 
313  i=b->method->bgets(b,in,inl);
314 
315  if (cb != NULL)
316  i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl,
317  0L,(long)i);
318  return(i);
319  }
320 
321 int BIO_indent(BIO *b,int indent,int max)
322  {
323  if(indent < 0)
324  indent=0;
325  if(indent > max)
326  indent=max;
327  while(indent--)
328  if(BIO_puts(b," ") != 1)
329  return 0;
330  return 1;
331  }
332 
333 long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
334  {
335  int i;
336 
337  i=iarg;
338  return(BIO_ctrl(b,cmd,larg,(char *)&i));
339  }
340 
341 char *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
342  {
343  char *p=NULL;
344 
345  if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0)
346  return(NULL);
347  else
348  return(p);
349  }
350 
351 long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
352  {
353  long ret;
354  long (*cb)(BIO *,int,const char *,int,long,long);
355 
356  if (b == NULL) return(0);
357 
358  if ((b->method == NULL) || (b->method->ctrl == NULL))
359  {
361  return(-2);
362  }
363 
364  cb=b->callback;
365 
366  if ((cb != NULL) &&
367  ((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))
368  return(ret);
369 
370  ret=b->method->ctrl(b,cmd,larg,parg);
371 
372  if (cb != NULL)
373  ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,
374  larg,ret);
375  return(ret);
376  }
377 
378 long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long))
379  {
380  long ret;
381  long (*cb)(BIO *,int,const char *,int,long,long);
382 
383  if (b == NULL) return(0);
384 
385  if ((b->method == NULL) || (b->method->callback_ctrl == NULL))
386  {
388  return(-2);
389  }
390 
391  cb=b->callback;
392 
393  if ((cb != NULL) &&
394  ((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0))
395  return(ret);
396 
397  ret=b->method->callback_ctrl(b,cmd,fp);
398 
399  if (cb != NULL)
400  ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd,
401  0,ret);
402  return(ret);
403  }
404 
405 /* It is unfortunate to duplicate in functions what the BIO_(w)pending macros
406  * do; but those macros have inappropriate return type, and for interfacing
407  * from other programming languages, C macros aren't much of a help anyway. */
408 size_t BIO_ctrl_pending(BIO *bio)
409  {
410  return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
411  }
412 
413 size_t BIO_ctrl_wpending(BIO *bio)
414  {
415  return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
416  }
417 
418 
419 /* put the 'bio' on the end of b's list of operators */
420 BIO *BIO_push(BIO *b, BIO *bio)
421  {
422  BIO *lb;
423 
424  if (b == NULL) return(bio);
425  lb=b;
426  while (lb->next_bio != NULL)
427  lb=lb->next_bio;
428  lb->next_bio=bio;
429  if (bio != NULL)
430  bio->prev_bio=lb;
431  /* called to do internal processing */
432  BIO_ctrl(b,BIO_CTRL_PUSH,0,lb);
433  return(b);
434  }
435 
436 /* Remove the first and return the rest */
438  {
439  BIO *ret;
440 
441  if (b == NULL) return(NULL);
442  ret=b->next_bio;
443 
444  BIO_ctrl(b,BIO_CTRL_POP,0,b);
445 
446  if (b->prev_bio != NULL)
447  b->prev_bio->next_bio=b->next_bio;
448  if (b->next_bio != NULL)
449  b->next_bio->prev_bio=b->prev_bio;
450 
451  b->next_bio=NULL;
452  b->prev_bio=NULL;
453  return(ret);
454  }
455 
456 BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
457  {
458  BIO *b,*last;
459 
460  b=last=bio;
461  for (;;)
462  {
463  if (!BIO_should_retry(b)) break;
464  last=b;
465  b=b->next_bio;
466  if (b == NULL) break;
467  }
468  if (reason != NULL) *reason=last->retry_reason;
469  return(last);
470  }
471 
473  {
474  return(bio->retry_reason);
475  }
476 
478  {
479  int mt,mask;
480 
481  if(!bio) return NULL;
482  mask=type&0xff;
483  do {
484  if (bio->method != NULL)
485  {
486  mt=bio->method->type;
487 
488  if (!mask)
489  {
490  if (mt & type) return(bio);
491  }
492  else if (mt == type)
493  return(bio);
494  }
495  bio=bio->next_bio;
496  } while (bio != NULL);
497  return(NULL);
498  }
499 
501  {
502  if(!b) return NULL;
503  return b->next_bio;
504  }
505 
506 void BIO_free_all(BIO *bio)
507  {
508  BIO *b;
509  int ref;
510 
511  while (bio != NULL)
512  {
513  b=bio;
514  ref=b->references;
515  bio=bio->next_bio;
516  BIO_free(b);
517  /* Since ref count > 1, don't free anyone else. */
518  if (ref > 1) break;
519  }
520  }
521 
523  {
524  BIO *ret=NULL,*eoc=NULL,*bio,*new_bio;
525 
526  for (bio=in; bio != NULL; bio=bio->next_bio)
527  {
528  if ((new_bio=BIO_new(bio->method)) == NULL) goto err;
529  new_bio->callback=bio->callback;
530  new_bio->cb_arg=bio->cb_arg;
531  new_bio->init=bio->init;
532  new_bio->shutdown=bio->shutdown;
533  new_bio->flags=bio->flags;
534 
535  /* This will let SSL_s_sock() work with stdin/stdout */
536  new_bio->num=bio->num;
537 
538  if (!BIO_dup_state(bio,(char *)new_bio))
539  {
540  BIO_free(new_bio);
541  goto err;
542  }
543 
544  /* copy app data */
545  if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
546  &bio->ex_data))
547  goto err;
548 
549  if (ret == NULL)
550  {
551  eoc=new_bio;
552  ret=eoc;
553  }
554  else
555  {
556  BIO_push(eoc,new_bio);
557  eoc=new_bio;
558  }
559  }
560  return(ret);
561 err:
562  if (ret != NULL)
563  BIO_free(ret);
564  return(NULL);
565  }
566 
568  {
571  }
572 
573 int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
575  {
576  return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp,
577  new_func, dup_func, free_func);
578  }
579 
580 int BIO_set_ex_data(BIO *bio, int idx, void *data)
581  {
582  return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data));
583  }
584 
585 void *BIO_get_ex_data(BIO *bio, int idx)
586  {
587  return(CRYPTO_get_ex_data(&(bio->ex_data),idx));
588  }
589 
590 unsigned long BIO_number_read(BIO *bio)
591 {
592  if(bio) return bio->num_read;
593  return 0;
594 }
595 
596 unsigned long BIO_number_written(BIO *bio)
597 {
598  if(bio) return bio->num_write;
599  return 0;
600 }
601