bf_nbio.c revision 160814
11573Srgrimes/* crypto/bio/bf_nbio.c */ 21573Srgrimes/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 31573Srgrimes * All rights reserved. 41573Srgrimes * 51573Srgrimes * This package is an SSL implementation written 61573Srgrimes * by Eric Young (eay@cryptsoft.com). 71573Srgrimes * The implementation was written so as to conform with Netscapes SSL. 8227753Stheraven * 9227753Stheraven * This library is free for commercial and non-commercial use as long as 10227753Stheraven * the following conditions are aheared to. The following conditions 11227753Stheraven * apply to all code found in this distribution, be it the RC4, RSA, 12227753Stheraven * lhash, DES, etc., code; not just the SSL code. The SSL documentation 131573Srgrimes * included with this distribution is covered by the same copyright terms 141573Srgrimes * except that the holder is Tim Hudson (tjh@cryptsoft.com). 151573Srgrimes * 161573Srgrimes * Copyright remains Eric Young's, and as such any Copyright notices in 171573Srgrimes * the code are not to be removed. 181573Srgrimes * If this package is used in a product, Eric Young should be given attribution 191573Srgrimes * as the author of the parts of the library used. 201573Srgrimes * This can be in the form of a textual message at program startup or 211573Srgrimes * in documentation (online or textual) provided with the package. 221573Srgrimes * 231573Srgrimes * Redistribution and use in source and binary forms, with or without 241573Srgrimes * modification, are permitted provided that the following conditions 251573Srgrimes * are met: 261573Srgrimes * 1. Redistributions of source code must retain the copyright 271573Srgrimes * notice, this list of conditions and the following disclaimer. 281573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 291573Srgrimes * notice, this list of conditions and the following disclaimer in the 301573Srgrimes * documentation and/or other materials provided with the distribution. 311573Srgrimes * 3. All advertising materials mentioning features or use of this software 321573Srgrimes * must display the following acknowledgement: 331573Srgrimes * "This product includes cryptographic software written by 341573Srgrimes * Eric Young (eay@cryptsoft.com)" 351573Srgrimes * The word 'cryptographic' can be left out if the rouines from the library 361573Srgrimes * being used are not cryptographic related :-). 371573Srgrimes * 4. If you include any Windows specific code (or a derivative thereof) from 381573Srgrimes * the apps directory (application code) you must include an acknowledgement: 391573Srgrimes * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 401573Srgrimes * 4190045Sobrien * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4290045Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 431573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 441573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 451573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 461573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 471573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 481573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 491573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 501573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 511573Srgrimes * SUCH DAMAGE. 521573Srgrimes * 531573Srgrimes * The licence and distribution terms for any publically available version or 541573Srgrimes * derivative of this code cannot be changed. i.e. this code cannot simply be 551573Srgrimes * copied and put under another distribution licence 561573Srgrimes * [including the GNU Public Licence.] 571573Srgrimes */ 581573Srgrimes 591573Srgrimes#include <stdio.h> 601573Srgrimes#include <errno.h> 611573Srgrimes#include "cryptlib.h" 621573Srgrimes#include <openssl/rand.h> 631573Srgrimes#include <openssl/bio.h> 648870Srgrimes 651573Srgrimes/* BIO_put and BIO_get both add to the digest, 661573Srgrimes * BIO_gets returns the digest */ 671573Srgrimes 681573Srgrimesstatic int nbiof_write(BIO *h,const char *buf,int num); 69132817Stjrstatic int nbiof_read(BIO *h,char *buf,int size); 70132817Stjrstatic int nbiof_puts(BIO *h,const char *str); 71132817Stjrstatic int nbiof_gets(BIO *h,char *str,int size); 72132817Stjrstatic long nbiof_ctrl(BIO *h,int cmd,long arg1,void *arg2); 73132817Stjrstatic int nbiof_new(BIO *h); 74132817Stjrstatic int nbiof_free(BIO *data); 75132817Stjrstatic long nbiof_callback_ctrl(BIO *h,int cmd,bio_info_cb *fp); 76132817Stjrtypedef struct nbio_test_st 77132817Stjr { 78132817Stjr /* only set if we sent a 'should retry' error */ 791573Srgrimes int lrn; 801573Srgrimes int lwn; 811573Srgrimes } NBIO_TEST; 821573Srgrimes 831573Srgrimesstatic BIO_METHOD methods_nbiof= 841573Srgrimes { 851573Srgrimes BIO_TYPE_NBIO_TEST, 86132817Stjr "non-blocking IO test filter", 871573Srgrimes nbiof_write, 88132817Stjr nbiof_read, 891573Srgrimes nbiof_puts, 901573Srgrimes nbiof_gets, 911573Srgrimes nbiof_ctrl, 921573Srgrimes nbiof_new, 93132817Stjr nbiof_free, 941573Srgrimes nbiof_callback_ctrl, 9519276Sache }; 9619276Sache 971573SrgrimesBIO_METHOD *BIO_f_nbio_test(void) 981573Srgrimes { 991573Srgrimes return(&methods_nbiof); 1001573Srgrimes } 1011573Srgrimes 1021573Srgrimesstatic int nbiof_new(BIO *bi) 1031573Srgrimes { 1041573Srgrimes NBIO_TEST *nt; 1051573Srgrimes 1061573Srgrimes if (!(nt=(NBIO_TEST *)OPENSSL_malloc(sizeof(NBIO_TEST)))) return(0); 1071573Srgrimes nt->lrn= -1; 1081573Srgrimes nt->lwn= -1; 1091573Srgrimes bi->ptr=(char *)nt; 1101573Srgrimes bi->init=1; 1111573Srgrimes bi->flags=0; 1121573Srgrimes return(1); 1131573Srgrimes } 1141573Srgrimes 1151573Srgrimesstatic int nbiof_free(BIO *a) 1161573Srgrimes { 117132817Stjr if (a == NULL) return(0); 118132817Stjr if (a->ptr != NULL) 119132817Stjr OPENSSL_free(a->ptr); 120132817Stjr a->ptr=NULL; 1211573Srgrimes a->init=0; 122132817Stjr a->flags=0; 1231573Srgrimes return(1); 1241573Srgrimes } 1251573Srgrimes 1261573Srgrimesstatic int nbiof_read(BIO *b, char *out, int outl) 1271573Srgrimes { 1281573Srgrimes NBIO_TEST *nt; 129132817Stjr int ret=0; 1301573Srgrimes#if 1 1311573Srgrimes int num; 1321573Srgrimes unsigned char n; 1331573Srgrimes#endif 1341573Srgrimes 1351573Srgrimes if (out == NULL) return(0); 136132817Stjr if (b->next_bio == NULL) return(0); 1371573Srgrimes nt=(NBIO_TEST *)b->ptr; 1381573Srgrimes 1391573Srgrimes BIO_clear_retry_flags(b); 1401573Srgrimes#if 1 1411573Srgrimes RAND_pseudo_bytes(&n,1); 1421573Srgrimes num=(n&0x07); 1431573Srgrimes 1441573Srgrimes if (outl > num) outl=num; 1451573Srgrimes 1461573Srgrimes if (num == 0) 14790045Sobrien { 148158812Sache ret= -1; 14990045Sobrien BIO_set_retry_read(b); 15090045Sobrien } 151180021Smtm else 1521573Srgrimes#endif 15390045Sobrien { 1541573Srgrimes ret=BIO_read(b->next_bio,out,outl); 15590045Sobrien if (ret < 0) 156158812Sache BIO_copy_next_retry(b); 157158812Sache } 158158812Sache return(ret); 159158812Sache } 160158812Sache 16174963Speterstatic int nbiof_write(BIO *b, const char *in, int inl) 16290045Sobrien { 163158812Sache NBIO_TEST *nt; 164158812Sache int ret=0; 16590045Sobrien int num; 1661573Srgrimes unsigned char n; 16790045Sobrien 1681573Srgrimes if ((in == NULL) || (inl <= 0)) return(0); 1691573Srgrimes if (b->next_bio == NULL) return(0); 1701573Srgrimes nt=(NBIO_TEST *)b->ptr; 171228754Seadler 172228754Seadler BIO_clear_retry_flags(b); 1731573Srgrimes 174159294Sdelphij#if 1 175158812Sache if (nt->lwn > 0) 176132817Stjr { 177132817Stjr num=nt->lwn; 178132817Stjr nt->lwn=0; 179132817Stjr } 1801573Srgrimes else 181159294Sdelphij { 1821573Srgrimes RAND_pseudo_bytes(&n,1); 1831573Srgrimes num=(n&7); 1841573Srgrimes } 1851573Srgrimes 1861573Srgrimes if (inl > num) inl=num; 1871573Srgrimes 18880525Smikeh if (num == 0) 18974469Sjlemon { 19080525Smikeh ret= -1; 19180525Smikeh BIO_set_retry_write(b); 19280525Smikeh } 19374469Sjlemon else 1941573Srgrimes#endif 1951573Srgrimes { 1961573Srgrimes ret=BIO_write(b->next_bio,in,inl); 1971573Srgrimes if (ret < 0) 1981573Srgrimes { 19974963Speter BIO_copy_next_retry(b); 200132817Stjr nt->lwn=inl; 201132817Stjr } 202132817Stjr } 203132817Stjr return(ret); 204132817Stjr } 205132817Stjr 206132817Stjrstatic long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr) 207132817Stjr { 208132817Stjr long ret; 209132817Stjr 210132817Stjr if (b->next_bio == NULL) return(0); 211132817Stjr switch (cmd) 2121573Srgrimes { 213132817Stjr case BIO_C_DO_STATE_MACHINE: 214132817Stjr BIO_clear_retry_flags(b); 215132817Stjr ret=BIO_ctrl(b->next_bio,cmd,num,ptr); 216132817Stjr BIO_copy_next_retry(b); 217132817Stjr break; 218132817Stjr case BIO_CTRL_DUP: 2191573Srgrimes ret=0L; 220132817Stjr break; 221132817Stjr default: 222132817Stjr ret=BIO_ctrl(b->next_bio,cmd,num,ptr); 223132817Stjr break; 224132817Stjr } 225132817Stjr return(ret); 226132817Stjr } 227132817Stjr 228132817Stjrstatic long nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) 229132817Stjr { 230132817Stjr long ret=1; 2311573Srgrimes 2321573Srgrimes if (b->next_bio == NULL) return(0); 2331573Srgrimes switch (cmd) 2341573Srgrimes { 23574469Sjlemon default: 2361573Srgrimes ret=BIO_callback_ctrl(b->next_bio,cmd,fp); 23774469Sjlemon break; 2381573Srgrimes } 2391573Srgrimes return(ret); 2401573Srgrimes } 2411573Srgrimes 2421573Srgrimesstatic int nbiof_gets(BIO *bp, char *buf, int size) 2431573Srgrimes { 2441573Srgrimes if (bp->next_bio == NULL) return(0); 24574963Speter return(BIO_gets(bp->next_bio,buf,size)); 246159294Sdelphij } 2471573Srgrimes 2481573Srgrimes 2491573Srgrimesstatic int nbiof_puts(BIO *bp, const char *str) 2501573Srgrimes { 2511573Srgrimes if (bp->next_bio == NULL) return(0); 2521573Srgrimes return(BIO_puts(bp->next_bio,str)); 25374469Sjlemon } 2541573Srgrimes 255180021Smtm 25674469Sjlemon