1*0Sstevel@tonic-gate /* crypto/bio/bio_lib.c */ 2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*0Sstevel@tonic-gate * All rights reserved. 4*0Sstevel@tonic-gate * 5*0Sstevel@tonic-gate * This package is an SSL implementation written 6*0Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 7*0Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 10*0Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 11*0Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 12*0Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*0Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 14*0Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*0Sstevel@tonic-gate * 16*0Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 17*0Sstevel@tonic-gate * the code are not to be removed. 18*0Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 19*0Sstevel@tonic-gate * as the author of the parts of the library used. 20*0Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 21*0Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 24*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 25*0Sstevel@tonic-gate * are met: 26*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 27*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 28*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 29*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 30*0Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 31*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 32*0Sstevel@tonic-gate * must display the following acknowledgement: 33*0Sstevel@tonic-gate * "This product includes cryptographic software written by 34*0Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 35*0Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 36*0Sstevel@tonic-gate * being used are not cryptographic related :-). 37*0Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 38*0Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 39*0Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*0Sstevel@tonic-gate * 41*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*0Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*0Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*0Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*0Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*0Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*0Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*0Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*0Sstevel@tonic-gate * SUCH DAMAGE. 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 54*0Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 55*0Sstevel@tonic-gate * copied and put under another distribution licence 56*0Sstevel@tonic-gate * [including the GNU Public Licence.] 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #include <stdio.h> 60*0Sstevel@tonic-gate #include <errno.h> 61*0Sstevel@tonic-gate #include <openssl/crypto.h> 62*0Sstevel@tonic-gate #include "cryptlib.h" 63*0Sstevel@tonic-gate #include <openssl/bio.h> 64*0Sstevel@tonic-gate #include <openssl/stack.h> 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate BIO *BIO_new(BIO_METHOD *method) 67*0Sstevel@tonic-gate { 68*0Sstevel@tonic-gate BIO *ret=NULL; 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gate ret=(BIO *)OPENSSL_malloc(sizeof(BIO)); 71*0Sstevel@tonic-gate if (ret == NULL) 72*0Sstevel@tonic-gate { 73*0Sstevel@tonic-gate BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE); 74*0Sstevel@tonic-gate return(NULL); 75*0Sstevel@tonic-gate } 76*0Sstevel@tonic-gate if (!BIO_set(ret,method)) 77*0Sstevel@tonic-gate { 78*0Sstevel@tonic-gate OPENSSL_free(ret); 79*0Sstevel@tonic-gate ret=NULL; 80*0Sstevel@tonic-gate } 81*0Sstevel@tonic-gate return(ret); 82*0Sstevel@tonic-gate } 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate int BIO_set(BIO *bio, BIO_METHOD *method) 85*0Sstevel@tonic-gate { 86*0Sstevel@tonic-gate bio->method=method; 87*0Sstevel@tonic-gate bio->callback=NULL; 88*0Sstevel@tonic-gate bio->cb_arg=NULL; 89*0Sstevel@tonic-gate bio->init=0; 90*0Sstevel@tonic-gate bio->shutdown=1; 91*0Sstevel@tonic-gate bio->flags=0; 92*0Sstevel@tonic-gate bio->retry_reason=0; 93*0Sstevel@tonic-gate bio->num=0; 94*0Sstevel@tonic-gate bio->ptr=NULL; 95*0Sstevel@tonic-gate bio->prev_bio=NULL; 96*0Sstevel@tonic-gate bio->next_bio=NULL; 97*0Sstevel@tonic-gate bio->references=1; 98*0Sstevel@tonic-gate bio->num_read=0L; 99*0Sstevel@tonic-gate bio->num_write=0L; 100*0Sstevel@tonic-gate CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); 101*0Sstevel@tonic-gate if (method->create != NULL) 102*0Sstevel@tonic-gate if (!method->create(bio)) 103*0Sstevel@tonic-gate { 104*0Sstevel@tonic-gate CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, 105*0Sstevel@tonic-gate &bio->ex_data); 106*0Sstevel@tonic-gate return(0); 107*0Sstevel@tonic-gate } 108*0Sstevel@tonic-gate return(1); 109*0Sstevel@tonic-gate } 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate int BIO_free(BIO *a) 112*0Sstevel@tonic-gate { 113*0Sstevel@tonic-gate int ret=0,i; 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate if (a == NULL) return(0); 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gate i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_BIO); 118*0Sstevel@tonic-gate #ifdef REF_PRINT 119*0Sstevel@tonic-gate REF_PRINT("BIO",a); 120*0Sstevel@tonic-gate #endif 121*0Sstevel@tonic-gate if (i > 0) return(1); 122*0Sstevel@tonic-gate #ifdef REF_CHECK 123*0Sstevel@tonic-gate if (i < 0) 124*0Sstevel@tonic-gate { 125*0Sstevel@tonic-gate fprintf(stderr,"BIO_free, bad reference count\n"); 126*0Sstevel@tonic-gate abort(); 127*0Sstevel@tonic-gate } 128*0Sstevel@tonic-gate #endif 129*0Sstevel@tonic-gate if ((a->callback != NULL) && 130*0Sstevel@tonic-gate ((i=(int)a->callback(a,BIO_CB_FREE,NULL,0,0L,1L)) <= 0)) 131*0Sstevel@tonic-gate return(i); 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data); 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate if ((a->method == NULL) || (a->method->destroy == NULL)) return(1); 136*0Sstevel@tonic-gate ret=a->method->destroy(a); 137*0Sstevel@tonic-gate OPENSSL_free(a); 138*0Sstevel@tonic-gate return(1); 139*0Sstevel@tonic-gate } 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate void BIO_vfree(BIO *a) 142*0Sstevel@tonic-gate { BIO_free(a); } 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate int BIO_read(BIO *b, void *out, int outl) 145*0Sstevel@tonic-gate { 146*0Sstevel@tonic-gate int i; 147*0Sstevel@tonic-gate long (*cb)(); 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) 150*0Sstevel@tonic-gate { 151*0Sstevel@tonic-gate BIOerr(BIO_F_BIO_READ,BIO_R_UNSUPPORTED_METHOD); 152*0Sstevel@tonic-gate return(-2); 153*0Sstevel@tonic-gate } 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate cb=b->callback; 156*0Sstevel@tonic-gate if ((cb != NULL) && 157*0Sstevel@tonic-gate ((i=(int)cb(b,BIO_CB_READ,out,outl,0L,1L)) <= 0)) 158*0Sstevel@tonic-gate return(i); 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate if (!b->init) 161*0Sstevel@tonic-gate { 162*0Sstevel@tonic-gate BIOerr(BIO_F_BIO_READ,BIO_R_UNINITIALIZED); 163*0Sstevel@tonic-gate return(-2); 164*0Sstevel@tonic-gate } 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gate i=b->method->bread(b,out,outl); 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate if (i > 0) b->num_read+=(unsigned long)i; 169*0Sstevel@tonic-gate 170*0Sstevel@tonic-gate if (cb != NULL) 171*0Sstevel@tonic-gate i=(int)cb(b,BIO_CB_READ|BIO_CB_RETURN,out,outl, 172*0Sstevel@tonic-gate 0L,(long)i); 173*0Sstevel@tonic-gate return(i); 174*0Sstevel@tonic-gate } 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate int BIO_write(BIO *b, const void *in, int inl) 177*0Sstevel@tonic-gate { 178*0Sstevel@tonic-gate int i; 179*0Sstevel@tonic-gate long (*cb)(); 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate if (b == NULL) 182*0Sstevel@tonic-gate return(0); 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate cb=b->callback; 185*0Sstevel@tonic-gate if ((b->method == NULL) || (b->method->bwrite == NULL)) 186*0Sstevel@tonic-gate { 187*0Sstevel@tonic-gate BIOerr(BIO_F_BIO_WRITE,BIO_R_UNSUPPORTED_METHOD); 188*0Sstevel@tonic-gate return(-2); 189*0Sstevel@tonic-gate } 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate if ((cb != NULL) && 192*0Sstevel@tonic-gate ((i=(int)cb(b,BIO_CB_WRITE,in,inl,0L,1L)) <= 0)) 193*0Sstevel@tonic-gate return(i); 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate if (!b->init) 196*0Sstevel@tonic-gate { 197*0Sstevel@tonic-gate BIOerr(BIO_F_BIO_WRITE,BIO_R_UNINITIALIZED); 198*0Sstevel@tonic-gate return(-2); 199*0Sstevel@tonic-gate } 200*0Sstevel@tonic-gate 201*0Sstevel@tonic-gate i=b->method->bwrite(b,in,inl); 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate if (i > 0) b->num_write+=(unsigned long)i; 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate if (cb != NULL) 206*0Sstevel@tonic-gate i=(int)cb(b,BIO_CB_WRITE|BIO_CB_RETURN,in,inl, 207*0Sstevel@tonic-gate 0L,(long)i); 208*0Sstevel@tonic-gate return(i); 209*0Sstevel@tonic-gate } 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate int BIO_puts(BIO *b, const char *in) 212*0Sstevel@tonic-gate { 213*0Sstevel@tonic-gate int i; 214*0Sstevel@tonic-gate long (*cb)(); 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) 217*0Sstevel@tonic-gate { 218*0Sstevel@tonic-gate BIOerr(BIO_F_BIO_PUTS,BIO_R_UNSUPPORTED_METHOD); 219*0Sstevel@tonic-gate return(-2); 220*0Sstevel@tonic-gate } 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate cb=b->callback; 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate if ((cb != NULL) && 225*0Sstevel@tonic-gate ((i=(int)cb(b,BIO_CB_PUTS,in,0,0L,1L)) <= 0)) 226*0Sstevel@tonic-gate return(i); 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate if (!b->init) 229*0Sstevel@tonic-gate { 230*0Sstevel@tonic-gate BIOerr(BIO_F_BIO_PUTS,BIO_R_UNINITIALIZED); 231*0Sstevel@tonic-gate return(-2); 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate i=b->method->bputs(b,in); 235*0Sstevel@tonic-gate 236*0Sstevel@tonic-gate if (i > 0) b->num_write+=(unsigned long)i; 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate if (cb != NULL) 239*0Sstevel@tonic-gate i=(int)cb(b,BIO_CB_PUTS|BIO_CB_RETURN,in,0, 240*0Sstevel@tonic-gate 0L,(long)i); 241*0Sstevel@tonic-gate return(i); 242*0Sstevel@tonic-gate } 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gate int BIO_gets(BIO *b, char *in, int inl) 245*0Sstevel@tonic-gate { 246*0Sstevel@tonic-gate int i; 247*0Sstevel@tonic-gate long (*cb)(); 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) 250*0Sstevel@tonic-gate { 251*0Sstevel@tonic-gate BIOerr(BIO_F_BIO_GETS,BIO_R_UNSUPPORTED_METHOD); 252*0Sstevel@tonic-gate return(-2); 253*0Sstevel@tonic-gate } 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gate cb=b->callback; 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate if ((cb != NULL) && 258*0Sstevel@tonic-gate ((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0)) 259*0Sstevel@tonic-gate return(i); 260*0Sstevel@tonic-gate 261*0Sstevel@tonic-gate if (!b->init) 262*0Sstevel@tonic-gate { 263*0Sstevel@tonic-gate BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITIALIZED); 264*0Sstevel@tonic-gate return(-2); 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gate i=b->method->bgets(b,in,inl); 268*0Sstevel@tonic-gate 269*0Sstevel@tonic-gate if (cb != NULL) 270*0Sstevel@tonic-gate i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl, 271*0Sstevel@tonic-gate 0L,(long)i); 272*0Sstevel@tonic-gate return(i); 273*0Sstevel@tonic-gate } 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gate int BIO_indent(BIO *b,int indent,int max) 276*0Sstevel@tonic-gate { 277*0Sstevel@tonic-gate if(indent < 0) 278*0Sstevel@tonic-gate indent=0; 279*0Sstevel@tonic-gate if(indent > max) 280*0Sstevel@tonic-gate indent=max; 281*0Sstevel@tonic-gate while(indent--) 282*0Sstevel@tonic-gate if(BIO_puts(b," ") != 1) 283*0Sstevel@tonic-gate return 0; 284*0Sstevel@tonic-gate return 1; 285*0Sstevel@tonic-gate } 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) 288*0Sstevel@tonic-gate { 289*0Sstevel@tonic-gate int i; 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gate i=iarg; 292*0Sstevel@tonic-gate return(BIO_ctrl(b,cmd,larg,(char *)&i)); 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) 296*0Sstevel@tonic-gate { 297*0Sstevel@tonic-gate char *p=NULL; 298*0Sstevel@tonic-gate 299*0Sstevel@tonic-gate if (BIO_ctrl(b,cmd,larg,(char *)&p) <= 0) 300*0Sstevel@tonic-gate return(NULL); 301*0Sstevel@tonic-gate else 302*0Sstevel@tonic-gate return(p); 303*0Sstevel@tonic-gate } 304*0Sstevel@tonic-gate 305*0Sstevel@tonic-gate long BIO_ctrl(BIO *b, int cmd, long larg, void *parg) 306*0Sstevel@tonic-gate { 307*0Sstevel@tonic-gate long ret; 308*0Sstevel@tonic-gate long (*cb)(); 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate if (b == NULL) return(0); 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gate if ((b->method == NULL) || (b->method->ctrl == NULL)) 313*0Sstevel@tonic-gate { 314*0Sstevel@tonic-gate BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD); 315*0Sstevel@tonic-gate return(-2); 316*0Sstevel@tonic-gate } 317*0Sstevel@tonic-gate 318*0Sstevel@tonic-gate cb=b->callback; 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate if ((cb != NULL) && 321*0Sstevel@tonic-gate ((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0)) 322*0Sstevel@tonic-gate return(ret); 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate ret=b->method->ctrl(b,cmd,larg,parg); 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate if (cb != NULL) 327*0Sstevel@tonic-gate ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd, 328*0Sstevel@tonic-gate larg,ret); 329*0Sstevel@tonic-gate return(ret); 330*0Sstevel@tonic-gate } 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long)) 333*0Sstevel@tonic-gate { 334*0Sstevel@tonic-gate long ret; 335*0Sstevel@tonic-gate long (*cb)(); 336*0Sstevel@tonic-gate 337*0Sstevel@tonic-gate if (b == NULL) return(0); 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) 340*0Sstevel@tonic-gate { 341*0Sstevel@tonic-gate BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD); 342*0Sstevel@tonic-gate return(-2); 343*0Sstevel@tonic-gate } 344*0Sstevel@tonic-gate 345*0Sstevel@tonic-gate cb=b->callback; 346*0Sstevel@tonic-gate 347*0Sstevel@tonic-gate if ((cb != NULL) && 348*0Sstevel@tonic-gate ((ret=cb(b,BIO_CB_CTRL,(void *)&fp,cmd,0,1L)) <= 0)) 349*0Sstevel@tonic-gate return(ret); 350*0Sstevel@tonic-gate 351*0Sstevel@tonic-gate ret=b->method->callback_ctrl(b,cmd,fp); 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate if (cb != NULL) 354*0Sstevel@tonic-gate ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,(void *)&fp,cmd, 355*0Sstevel@tonic-gate 0,ret); 356*0Sstevel@tonic-gate return(ret); 357*0Sstevel@tonic-gate } 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gate /* It is unfortunate to duplicate in functions what the BIO_(w)pending macros 360*0Sstevel@tonic-gate * do; but those macros have inappropriate return type, and for interfacing 361*0Sstevel@tonic-gate * from other programming languages, C macros aren't much of a help anyway. */ 362*0Sstevel@tonic-gate size_t BIO_ctrl_pending(BIO *bio) 363*0Sstevel@tonic-gate { 364*0Sstevel@tonic-gate return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); 365*0Sstevel@tonic-gate } 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate size_t BIO_ctrl_wpending(BIO *bio) 368*0Sstevel@tonic-gate { 369*0Sstevel@tonic-gate return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); 370*0Sstevel@tonic-gate } 371*0Sstevel@tonic-gate 372*0Sstevel@tonic-gate 373*0Sstevel@tonic-gate /* put the 'bio' on the end of b's list of operators */ 374*0Sstevel@tonic-gate BIO *BIO_push(BIO *b, BIO *bio) 375*0Sstevel@tonic-gate { 376*0Sstevel@tonic-gate BIO *lb; 377*0Sstevel@tonic-gate 378*0Sstevel@tonic-gate if (b == NULL) return(bio); 379*0Sstevel@tonic-gate lb=b; 380*0Sstevel@tonic-gate while (lb->next_bio != NULL) 381*0Sstevel@tonic-gate lb=lb->next_bio; 382*0Sstevel@tonic-gate lb->next_bio=bio; 383*0Sstevel@tonic-gate if (bio != NULL) 384*0Sstevel@tonic-gate bio->prev_bio=lb; 385*0Sstevel@tonic-gate /* called to do internal processing */ 386*0Sstevel@tonic-gate BIO_ctrl(b,BIO_CTRL_PUSH,0,NULL); 387*0Sstevel@tonic-gate return(b); 388*0Sstevel@tonic-gate } 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gate /* Remove the first and return the rest */ 391*0Sstevel@tonic-gate BIO *BIO_pop(BIO *b) 392*0Sstevel@tonic-gate { 393*0Sstevel@tonic-gate BIO *ret; 394*0Sstevel@tonic-gate 395*0Sstevel@tonic-gate if (b == NULL) return(NULL); 396*0Sstevel@tonic-gate ret=b->next_bio; 397*0Sstevel@tonic-gate 398*0Sstevel@tonic-gate BIO_ctrl(b,BIO_CTRL_POP,0,NULL); 399*0Sstevel@tonic-gate 400*0Sstevel@tonic-gate if (b->prev_bio != NULL) 401*0Sstevel@tonic-gate b->prev_bio->next_bio=b->next_bio; 402*0Sstevel@tonic-gate if (b->next_bio != NULL) 403*0Sstevel@tonic-gate b->next_bio->prev_bio=b->prev_bio; 404*0Sstevel@tonic-gate 405*0Sstevel@tonic-gate b->next_bio=NULL; 406*0Sstevel@tonic-gate b->prev_bio=NULL; 407*0Sstevel@tonic-gate return(ret); 408*0Sstevel@tonic-gate } 409*0Sstevel@tonic-gate 410*0Sstevel@tonic-gate BIO *BIO_get_retry_BIO(BIO *bio, int *reason) 411*0Sstevel@tonic-gate { 412*0Sstevel@tonic-gate BIO *b,*last; 413*0Sstevel@tonic-gate 414*0Sstevel@tonic-gate b=last=bio; 415*0Sstevel@tonic-gate for (;;) 416*0Sstevel@tonic-gate { 417*0Sstevel@tonic-gate if (!BIO_should_retry(b)) break; 418*0Sstevel@tonic-gate last=b; 419*0Sstevel@tonic-gate b=b->next_bio; 420*0Sstevel@tonic-gate if (b == NULL) break; 421*0Sstevel@tonic-gate } 422*0Sstevel@tonic-gate if (reason != NULL) *reason=last->retry_reason; 423*0Sstevel@tonic-gate return(last); 424*0Sstevel@tonic-gate } 425*0Sstevel@tonic-gate 426*0Sstevel@tonic-gate int BIO_get_retry_reason(BIO *bio) 427*0Sstevel@tonic-gate { 428*0Sstevel@tonic-gate return(bio->retry_reason); 429*0Sstevel@tonic-gate } 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate BIO *BIO_find_type(BIO *bio, int type) 432*0Sstevel@tonic-gate { 433*0Sstevel@tonic-gate int mt,mask; 434*0Sstevel@tonic-gate 435*0Sstevel@tonic-gate if(!bio) return NULL; 436*0Sstevel@tonic-gate mask=type&0xff; 437*0Sstevel@tonic-gate do { 438*0Sstevel@tonic-gate if (bio->method != NULL) 439*0Sstevel@tonic-gate { 440*0Sstevel@tonic-gate mt=bio->method->type; 441*0Sstevel@tonic-gate 442*0Sstevel@tonic-gate if (!mask) 443*0Sstevel@tonic-gate { 444*0Sstevel@tonic-gate if (mt & type) return(bio); 445*0Sstevel@tonic-gate } 446*0Sstevel@tonic-gate else if (mt == type) 447*0Sstevel@tonic-gate return(bio); 448*0Sstevel@tonic-gate } 449*0Sstevel@tonic-gate bio=bio->next_bio; 450*0Sstevel@tonic-gate } while (bio != NULL); 451*0Sstevel@tonic-gate return(NULL); 452*0Sstevel@tonic-gate } 453*0Sstevel@tonic-gate 454*0Sstevel@tonic-gate BIO *BIO_next(BIO *b) 455*0Sstevel@tonic-gate { 456*0Sstevel@tonic-gate if(!b) return NULL; 457*0Sstevel@tonic-gate return b->next_bio; 458*0Sstevel@tonic-gate } 459*0Sstevel@tonic-gate 460*0Sstevel@tonic-gate void BIO_free_all(BIO *bio) 461*0Sstevel@tonic-gate { 462*0Sstevel@tonic-gate BIO *b; 463*0Sstevel@tonic-gate int ref; 464*0Sstevel@tonic-gate 465*0Sstevel@tonic-gate while (bio != NULL) 466*0Sstevel@tonic-gate { 467*0Sstevel@tonic-gate b=bio; 468*0Sstevel@tonic-gate ref=b->references; 469*0Sstevel@tonic-gate bio=bio->next_bio; 470*0Sstevel@tonic-gate BIO_free(b); 471*0Sstevel@tonic-gate /* Since ref count > 1, don't free anyone else. */ 472*0Sstevel@tonic-gate if (ref > 1) break; 473*0Sstevel@tonic-gate } 474*0Sstevel@tonic-gate } 475*0Sstevel@tonic-gate 476*0Sstevel@tonic-gate BIO *BIO_dup_chain(BIO *in) 477*0Sstevel@tonic-gate { 478*0Sstevel@tonic-gate BIO *ret=NULL,*eoc=NULL,*bio,*new; 479*0Sstevel@tonic-gate 480*0Sstevel@tonic-gate for (bio=in; bio != NULL; bio=bio->next_bio) 481*0Sstevel@tonic-gate { 482*0Sstevel@tonic-gate if ((new=BIO_new(bio->method)) == NULL) goto err; 483*0Sstevel@tonic-gate new->callback=bio->callback; 484*0Sstevel@tonic-gate new->cb_arg=bio->cb_arg; 485*0Sstevel@tonic-gate new->init=bio->init; 486*0Sstevel@tonic-gate new->shutdown=bio->shutdown; 487*0Sstevel@tonic-gate new->flags=bio->flags; 488*0Sstevel@tonic-gate 489*0Sstevel@tonic-gate /* This will let SSL_s_sock() work with stdin/stdout */ 490*0Sstevel@tonic-gate new->num=bio->num; 491*0Sstevel@tonic-gate 492*0Sstevel@tonic-gate if (!BIO_dup_state(bio,(char *)new)) 493*0Sstevel@tonic-gate { 494*0Sstevel@tonic-gate BIO_free(new); 495*0Sstevel@tonic-gate goto err; 496*0Sstevel@tonic-gate } 497*0Sstevel@tonic-gate 498*0Sstevel@tonic-gate /* copy app data */ 499*0Sstevel@tonic-gate if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new->ex_data, 500*0Sstevel@tonic-gate &bio->ex_data)) 501*0Sstevel@tonic-gate goto err; 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate if (ret == NULL) 504*0Sstevel@tonic-gate { 505*0Sstevel@tonic-gate eoc=new; 506*0Sstevel@tonic-gate ret=eoc; 507*0Sstevel@tonic-gate } 508*0Sstevel@tonic-gate else 509*0Sstevel@tonic-gate { 510*0Sstevel@tonic-gate BIO_push(eoc,new); 511*0Sstevel@tonic-gate eoc=new; 512*0Sstevel@tonic-gate } 513*0Sstevel@tonic-gate } 514*0Sstevel@tonic-gate return(ret); 515*0Sstevel@tonic-gate err: 516*0Sstevel@tonic-gate if (ret != NULL) 517*0Sstevel@tonic-gate BIO_free(ret); 518*0Sstevel@tonic-gate return(NULL); 519*0Sstevel@tonic-gate } 520*0Sstevel@tonic-gate 521*0Sstevel@tonic-gate void BIO_copy_next_retry(BIO *b) 522*0Sstevel@tonic-gate { 523*0Sstevel@tonic-gate BIO_set_flags(b,BIO_get_retry_flags(b->next_bio)); 524*0Sstevel@tonic-gate b->retry_reason=b->next_bio->retry_reason; 525*0Sstevel@tonic-gate } 526*0Sstevel@tonic-gate 527*0Sstevel@tonic-gate int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, 528*0Sstevel@tonic-gate CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) 529*0Sstevel@tonic-gate { 530*0Sstevel@tonic-gate return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp, 531*0Sstevel@tonic-gate new_func, dup_func, free_func); 532*0Sstevel@tonic-gate } 533*0Sstevel@tonic-gate 534*0Sstevel@tonic-gate int BIO_set_ex_data(BIO *bio, int idx, void *data) 535*0Sstevel@tonic-gate { 536*0Sstevel@tonic-gate return(CRYPTO_set_ex_data(&(bio->ex_data),idx,data)); 537*0Sstevel@tonic-gate } 538*0Sstevel@tonic-gate 539*0Sstevel@tonic-gate void *BIO_get_ex_data(BIO *bio, int idx) 540*0Sstevel@tonic-gate { 541*0Sstevel@tonic-gate return(CRYPTO_get_ex_data(&(bio->ex_data),idx)); 542*0Sstevel@tonic-gate } 543*0Sstevel@tonic-gate 544*0Sstevel@tonic-gate unsigned long BIO_number_read(BIO *bio) 545*0Sstevel@tonic-gate { 546*0Sstevel@tonic-gate if(bio) return bio->num_read; 547*0Sstevel@tonic-gate return 0; 548*0Sstevel@tonic-gate } 549*0Sstevel@tonic-gate 550*0Sstevel@tonic-gate unsigned long BIO_number_written(BIO *bio) 551*0Sstevel@tonic-gate { 552*0Sstevel@tonic-gate if(bio) return bio->num_write; 553*0Sstevel@tonic-gate return 0; 554*0Sstevel@tonic-gate } 555*0Sstevel@tonic-gate 556*0Sstevel@tonic-gate IMPLEMENT_STACK_OF(BIO) 557