LCOV - code coverage report
Current view: top level - bio - bss_bio.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 224 307 73.0 %
Date: 2014-08-02 Functions: 18 21 85.7 %
Branches: 92 179 51.4 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/bio/bss_bio.c  -*- Mode: C; c-file-style: "eay" -*- */
       2                 :            : /* ====================================================================
       3                 :            :  * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
       4                 :            :  *
       5                 :            :  * Redistribution and use in source and binary forms, with or without
       6                 :            :  * modification, are permitted provided that the following conditions
       7                 :            :  * are met:
       8                 :            :  *
       9                 :            :  * 1. Redistributions of source code must retain the above copyright
      10                 :            :  *    notice, this list of conditions and the following disclaimer. 
      11                 :            :  *
      12                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      13                 :            :  *    notice, this list of conditions and the following disclaimer in
      14                 :            :  *    the documentation and/or other materials provided with the
      15                 :            :  *    distribution.
      16                 :            :  *
      17                 :            :  * 3. All advertising materials mentioning features or use of this
      18                 :            :  *    software must display the following acknowledgment:
      19                 :            :  *    "This product includes software developed by the OpenSSL Project
      20                 :            :  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
      21                 :            :  *
      22                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      23                 :            :  *    endorse or promote products derived from this software without
      24                 :            :  *    prior written permission. For written permission, please contact
      25                 :            :  *    openssl-core@openssl.org.
      26                 :            :  *
      27                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      28                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      29                 :            :  *    permission of the OpenSSL Project.
      30                 :            :  *
      31                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      32                 :            :  *    acknowledgment:
      33                 :            :  *    "This product includes software developed by the OpenSSL Project
      34                 :            :  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
      35                 :            :  *
      36                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      37                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      38                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      39                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      40                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      41                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      42                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      43                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      44                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      45                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      46                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      47                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      48                 :            :  * ====================================================================
      49                 :            :  *
      50                 :            :  * This product includes cryptographic software written by Eric Young
      51                 :            :  * (eay@cryptsoft.com).  This product includes software written by Tim
      52                 :            :  * Hudson (tjh@cryptsoft.com).
      53                 :            :  *
      54                 :            :  */
      55                 :            : 
      56                 :            : /* Special method for a BIO where the other endpoint is also a BIO
      57                 :            :  * of this kind, handled by the same thread (i.e. the "peer" is actually
      58                 :            :  * ourselves, wearing a different hat).
      59                 :            :  * Such "BIO pairs" are mainly for using the SSL library with I/O interfaces
      60                 :            :  * for which no specific BIO method is available.
      61                 :            :  * See ssl/ssltest.c for some hints on how this can be used. */
      62                 :            : 
      63                 :            : /* BIO_DEBUG implies BIO_PAIR_DEBUG */
      64                 :            : #ifdef BIO_DEBUG
      65                 :            : # ifndef BIO_PAIR_DEBUG
      66                 :            : #  define BIO_PAIR_DEBUG
      67                 :            : # endif
      68                 :            : #endif
      69                 :            : 
      70                 :            : /* disable assert() unless BIO_PAIR_DEBUG has been defined */
      71                 :            : #ifndef BIO_PAIR_DEBUG
      72                 :            : # ifndef NDEBUG
      73                 :            : #  define NDEBUG
      74                 :            : # endif
      75                 :            : #endif
      76                 :            : 
      77                 :            : #include <assert.h>
      78                 :            : #include <limits.h>
      79                 :            : #include <stdlib.h>
      80                 :            : #include <string.h>
      81                 :            : 
      82                 :            : #include <openssl/bio.h>
      83                 :            : #include <openssl/err.h>
      84                 :            : #include <openssl/crypto.h>
      85                 :            : 
      86                 :            : #include "e_os.h"
      87                 :            : 
      88                 :            : /* VxWorks defines SSIZE_MAX with an empty value causing compile errors */
      89                 :            : #if defined(OPENSSL_SYS_VXWORKS)
      90                 :            : # undef SSIZE_MAX
      91                 :            : #endif
      92                 :            : #ifndef SSIZE_MAX
      93                 :            : # define SSIZE_MAX INT_MAX
      94                 :            : #endif
      95                 :            : 
      96                 :            : static int bio_new(BIO *bio);
      97                 :            : static int bio_free(BIO *bio);
      98                 :            : static int bio_read(BIO *bio, char *buf, int size);
      99                 :            : static int bio_write(BIO *bio, const char *buf, int num);
     100                 :            : static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
     101                 :            : static int bio_puts(BIO *bio, const char *str);
     102                 :            : 
     103                 :            : static int bio_make_pair(BIO *bio1, BIO *bio2);
     104                 :            : static void bio_destroy_pair(BIO *bio);
     105                 :            : 
     106                 :            : static BIO_METHOD methods_biop =
     107                 :            : {
     108                 :            :         BIO_TYPE_BIO,
     109                 :            :         "BIO pair",
     110                 :            :         bio_write,
     111                 :            :         bio_read,
     112                 :            :         bio_puts,
     113                 :            :         NULL /* no bio_gets */,
     114                 :            :         bio_ctrl,
     115                 :            :         bio_new,
     116                 :            :         bio_free,
     117                 :            :         NULL /* no bio_callback_ctrl */
     118                 :            : };
     119                 :            : 
     120                 :       1518 : BIO_METHOD *BIO_s_bio(void)
     121                 :            :         {
     122                 :       1518 :         return &methods_biop;
     123                 :            :         }
     124                 :            : 
     125                 :            : struct bio_bio_st
     126                 :            : {
     127                 :            :         BIO *peer;     /* NULL if buf == NULL.
     128                 :            :                         * If peer != NULL, then peer->ptr is also a bio_bio_st,
     129                 :            :                         * and its "peer" member points back to us.
     130                 :            :                         * peer != NULL iff init != 0 in the BIO. */
     131                 :            :         
     132                 :            :         /* This is for what we write (i.e. reading uses peer's struct): */
     133                 :            :         int closed;     /* valid iff peer != NULL */
     134                 :            :         size_t len;     /* valid iff buf != NULL; 0 if peer == NULL */
     135                 :            :         size_t offset;  /* valid iff buf != NULL; 0 if len == 0 */
     136                 :            :         size_t size;
     137                 :            :         char *buf;      /* "size" elements (if != NULL) */
     138                 :            : 
     139                 :            :         size_t request; /* valid iff peer != NULL; 0 if len != 0,
     140                 :            :                          * otherwise set by peer to number of bytes
     141                 :            :                          * it (unsuccessfully) tried to read,
     142                 :            :                          * never more than buffer space (size-len) warrants. */
     143                 :            : };
     144                 :            : 
     145                 :       3036 : static int bio_new(BIO *bio)
     146                 :            :         {
     147                 :            :         struct bio_bio_st *b;
     148                 :            :         
     149                 :       3036 :         b = OPENSSL_malloc(sizeof *b);
     150         [ +  - ]:       3036 :         if (b == NULL)
     151                 :            :                 return 0;
     152                 :            : 
     153                 :       3036 :         b->peer = NULL;
     154                 :       3036 :         b->size = 17*1024; /* enough for one TLS record (just a default) */
     155                 :       3036 :         b->buf = NULL;
     156                 :            : 
     157                 :       3036 :         bio->ptr = b;
     158                 :       3036 :         return 1;
     159                 :            :         }
     160                 :            : 
     161                 :            : 
     162                 :       3036 : static int bio_free(BIO *bio)
     163                 :            :         {
     164                 :            :         struct bio_bio_st *b;
     165                 :            : 
     166         [ +  - ]:       3036 :         if (bio == NULL)
     167                 :            :                 return 0;
     168                 :       3036 :         b = bio->ptr;
     169                 :            : 
     170                 :            :         assert(b != NULL);
     171                 :            : 
     172         [ +  + ]:       3036 :         if (b->peer)
     173                 :       1518 :                 bio_destroy_pair(bio);
     174                 :            :         
     175         [ +  - ]:       3036 :         if (b->buf != NULL)
     176                 :            :                 {
     177                 :       3036 :                 OPENSSL_free(b->buf);
     178                 :            :                 }
     179                 :            : 
     180                 :       3036 :         OPENSSL_free(b);
     181                 :            : 
     182                 :       3036 :         return 1;
     183                 :            :         }
     184                 :            : 
     185                 :            : 
     186                 :            : 
     187                 :     122754 : static int bio_read(BIO *bio, char *buf, int size_)
     188                 :            :         {
     189                 :     122754 :         size_t size = size_;
     190                 :            :         size_t rest;
     191                 :            :         struct bio_bio_st *b, *peer_b;
     192                 :            : 
     193                 :     122754 :         BIO_clear_retry_flags(bio);
     194                 :            : 
     195         [ +  - ]:     122754 :         if (!bio->init)
     196                 :            :                 return 0;
     197                 :            : 
     198                 :     122754 :         b = bio->ptr;
     199                 :            :         assert(b != NULL);
     200                 :            :         assert(b->peer != NULL);
     201                 :     122754 :         peer_b = b->peer->ptr;
     202                 :            :         assert(peer_b != NULL);
     203                 :            :         assert(peer_b->buf != NULL);
     204                 :            : 
     205                 :     122754 :         peer_b->request = 0; /* will be set in "retry_read" situation */
     206                 :            : 
     207         [ +  - ]:     122754 :         if (buf == NULL || size == 0)
     208                 :            :                 return 0;
     209                 :            : 
     210         [ +  + ]:     122754 :         if (peer_b->len == 0)
     211                 :            :                 {
     212         [ +  - ]:      66575 :                 if (peer_b->closed)
     213                 :            :                         return 0; /* writer has closed, and no data is left */
     214                 :            :                 else
     215                 :            :                         {
     216                 :      66575 :                         BIO_set_retry_read(bio); /* buffer is empty */
     217         [ +  + ]:      66575 :                         if (size <= peer_b->size)
     218                 :      59412 :                                 peer_b->request = size;
     219                 :            :                         else
     220                 :            :                                 /* don't ask for more than the peer can
     221                 :            :                                  * deliver in one write */
     222                 :       7163 :                                 peer_b->request = peer_b->size;
     223                 :            :                         return -1;
     224                 :            :                         }
     225                 :            :                 }
     226                 :            : 
     227                 :            :         /* we can read */
     228         [ +  + ]:      56179 :         if (peer_b->len < size)
     229                 :      15005 :                 size = peer_b->len;
     230                 :            : 
     231                 :            :         /* now read "size" bytes */
     232                 :            :         
     233                 :      56179 :         rest = size;
     234                 :            :         
     235                 :            :         assert(rest > 0);
     236                 :            :         do /* one or two iterations */
     237                 :            :                 {
     238                 :            :                 size_t chunk;
     239                 :            :                 
     240                 :            :                 assert(rest <= peer_b->len);
     241         [ +  + ]:      58116 :                 if (peer_b->offset + rest <= peer_b->size)
     242                 :            :                         chunk = rest;
     243                 :            :                 else
     244                 :            :                         /* wrap around ring buffer */
     245                 :       1937 :                         chunk = peer_b->size - peer_b->offset;
     246                 :            :                 assert(peer_b->offset + chunk <= peer_b->size);
     247                 :            :                 
     248                 :      58116 :                 memcpy(buf, peer_b->buf + peer_b->offset, chunk);
     249                 :            :                 
     250                 :      58116 :                 peer_b->len -= chunk;
     251         [ +  + ]:      58116 :                 if (peer_b->len)
     252                 :            :                         {
     253                 :      30081 :                         peer_b->offset += chunk;
     254                 :            :                         assert(peer_b->offset <= peer_b->size);
     255         [ +  + ]:      30081 :                         if (peer_b->offset == peer_b->size)
     256                 :       2014 :                                 peer_b->offset = 0;
     257                 :      30081 :                         buf += chunk;
     258                 :            :                         }
     259                 :            :                 else
     260                 :            :                         {
     261                 :            :                         /* buffer now empty, no need to advance "buf" */
     262                 :            :                         assert(chunk == rest);
     263                 :      28035 :                         peer_b->offset = 0;
     264                 :            :                         }
     265                 :      58116 :                 rest -= chunk;
     266                 :            :                 }
     267         [ +  + ]:      58116 :         while (rest);
     268                 :            :         
     269                 :      56179 :         return size;
     270                 :            :         }
     271                 :            : 
     272                 :            : /* non-copying interface: provide pointer to available data in buffer
     273                 :            :  *    bio_nread0:  return number of available bytes
     274                 :            :  *    bio_nread:   also advance index
     275                 :            :  * (example usage:  bio_nread0(), read from buffer, bio_nread()
     276                 :            :  *  or just         bio_nread(), read from buffer)
     277                 :            :  */
     278                 :            : /* WARNING: The non-copying interface is largely untested as of yet
     279                 :            :  * and may contain bugs. */
     280                 :       6199 : static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
     281                 :            :         {
     282                 :            :         struct bio_bio_st *b, *peer_b;
     283                 :            :         ossl_ssize_t num;
     284                 :            :         
     285                 :       6199 :         BIO_clear_retry_flags(bio);
     286                 :            : 
     287         [ +  - ]:       6199 :         if (!bio->init)
     288                 :            :                 return 0;
     289                 :            :         
     290                 :       6199 :         b = bio->ptr;
     291                 :            :         assert(b != NULL);
     292                 :            :         assert(b->peer != NULL);
     293                 :       6199 :         peer_b = b->peer->ptr;
     294                 :            :         assert(peer_b != NULL);
     295                 :            :         assert(peer_b->buf != NULL);
     296                 :            :         
     297                 :       6199 :         peer_b->request = 0;
     298                 :            :         
     299         [ -  + ]:       6199 :         if (peer_b->len == 0)
     300                 :            :                 {
     301                 :            :                 char dummy;
     302                 :            :                 
     303                 :            :                 /* avoid code duplication -- nothing available for reading */
     304                 :          0 :                 return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
     305                 :            :                 }
     306                 :            : 
     307                 :       6199 :         num = peer_b->len;
     308         [ -  + ]:       6199 :         if (peer_b->size < peer_b->offset + num)
     309                 :            :                 /* no ring buffer wrap-around for non-copying interface */
     310                 :          0 :                 num = peer_b->size - peer_b->offset;
     311                 :            :         assert(num > 0);
     312                 :            : 
     313         [ +  - ]:       6199 :         if (buf != NULL)
     314                 :       6199 :                 *buf = peer_b->buf + peer_b->offset;
     315                 :       6199 :         return num;
     316                 :            :         }
     317                 :            : 
     318                 :       6199 : static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
     319                 :            :         {
     320                 :            :         struct bio_bio_st *b, *peer_b;
     321                 :            :         ossl_ssize_t num, available;
     322                 :            : 
     323         [ +  - ]:       6199 :         if (num_ > SSIZE_MAX)
     324                 :            :                 num = SSIZE_MAX;
     325                 :            :         else
     326                 :       6199 :                 num = (ossl_ssize_t)num_;
     327                 :            : 
     328                 :       6199 :         available = bio_nread0(bio, buf);
     329         [ -  + ]:       6199 :         if (num > available)
     330                 :          0 :                 num = available;
     331         [ +  - ]:       6199 :         if (num <= 0)
     332                 :            :                 return num;
     333                 :            : 
     334                 :       6199 :         b = bio->ptr;
     335                 :       6199 :         peer_b = b->peer->ptr;
     336                 :            : 
     337                 :       6199 :         peer_b->len -= num;
     338         [ -  + ]:       6199 :         if (peer_b->len) 
     339                 :            :                 {
     340                 :          0 :                 peer_b->offset += num;
     341                 :            :                 assert(peer_b->offset <= peer_b->size);
     342         [ #  # ]:          0 :                 if (peer_b->offset == peer_b->size)
     343                 :          0 :                         peer_b->offset = 0;
     344                 :            :                 }
     345                 :            :         else
     346                 :       6199 :                 peer_b->offset = 0;
     347                 :            : 
     348                 :            :         return num;
     349                 :            :         }
     350                 :            : 
     351                 :            : 
     352                 :      41750 : static int bio_write(BIO *bio, const char *buf, int num_)
     353                 :            :         {
     354                 :      41750 :         size_t num = num_;
     355                 :            :         size_t rest;
     356                 :            :         struct bio_bio_st *b;
     357                 :            : 
     358                 :      41750 :         BIO_clear_retry_flags(bio);
     359                 :            : 
     360 [ +  - ][ +  - ]:      41750 :         if (!bio->init || buf == NULL || num == 0)
     361                 :            :                 return 0;
     362                 :            : 
     363                 :      41750 :         b = bio->ptr;                
     364                 :            :         assert(b != NULL);
     365                 :            :         assert(b->peer != NULL);
     366                 :            :         assert(b->buf != NULL);
     367                 :            : 
     368                 :      41750 :         b->request = 0;
     369         [ -  + ]:      41750 :         if (b->closed)
     370                 :            :                 {
     371                 :            :                 /* we already closed */
     372                 :          0 :                 BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
     373                 :          0 :                 return -1;
     374                 :            :                 }
     375                 :            : 
     376                 :            :         assert(b->len <= b->size);
     377                 :            : 
     378         [ +  + ]:      41750 :         if (b->len == b->size)
     379                 :            :                 {
     380                 :      18472 :                 BIO_set_retry_write(bio); /* buffer is full */
     381                 :      18472 :                 return -1;
     382                 :            :                 }
     383                 :            : 
     384                 :            :         /* we can write */
     385         [ +  + ]:      23278 :         if (num > b->size - b->len)
     386                 :      12404 :                 num = b->size - b->len;
     387                 :            :         
     388                 :            :         /* now write "num" bytes */
     389                 :            : 
     390                 :      23278 :         rest = num;
     391                 :            :         
     392                 :            :         assert(rest > 0);
     393                 :            :         do /* one or two iterations */
     394                 :            :                 {
     395                 :            :                 size_t write_offset;
     396                 :            :                 size_t chunk;
     397                 :            : 
     398                 :            :                 assert(b->len + rest <= b->size);
     399                 :            : 
     400                 :      23730 :                 write_offset = b->offset + b->len;
     401         [ +  + ]:      23730 :                 if (write_offset >= b->size)
     402                 :       6304 :                         write_offset -= b->size;
     403                 :            :                 /* b->buf[write_offset] is the first byte we can write to. */
     404                 :            : 
     405         [ +  + ]:      23730 :                 if (write_offset + rest <= b->size)
     406                 :            :                         chunk = rest;
     407                 :            :                 else
     408                 :            :                         /* wrap around ring buffer */
     409                 :        452 :                         chunk = b->size - write_offset;
     410                 :            :                 
     411                 :      23730 :                 memcpy(b->buf + write_offset, buf, chunk);
     412                 :            :                 
     413                 :      23730 :                 b->len += chunk;
     414                 :            : 
     415                 :            :                 assert(b->len <= b->size);
     416                 :            :                 
     417                 :      23730 :                 rest -= chunk;
     418                 :      23730 :                 buf += chunk;
     419                 :            :                 }
     420         [ +  + ]:      23730 :         while (rest);
     421                 :            : 
     422                 :      23278 :         return num;
     423                 :            :         }
     424                 :            : 
     425                 :            : /* non-copying interface: provide pointer to region to write to
     426                 :            :  *   bio_nwrite0:  check how much space is available
     427                 :            :  *   bio_nwrite:   also increase length
     428                 :            :  * (example usage:  bio_nwrite0(), write to buffer, bio_nwrite()
     429                 :            :  *  or just         bio_nwrite(), write to buffer)
     430                 :            :  */
     431                 :      39096 : static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
     432                 :            :         {
     433                 :            :         struct bio_bio_st *b;
     434                 :            :         size_t num;
     435                 :            :         size_t write_offset;
     436                 :            : 
     437                 :      39096 :         BIO_clear_retry_flags(bio);
     438                 :            : 
     439         [ +  - ]:      39096 :         if (!bio->init)
     440                 :            :                 return 0;
     441                 :            : 
     442                 :      39096 :         b = bio->ptr;                
     443                 :            :         assert(b != NULL);
     444                 :            :         assert(b->peer != NULL);
     445                 :            :         assert(b->buf != NULL);
     446                 :            : 
     447                 :      39096 :         b->request = 0;
     448         [ -  + ]:      39096 :         if (b->closed)
     449                 :            :                 {
     450                 :          0 :                 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
     451                 :          0 :                 return -1;
     452                 :            :                 }
     453                 :            : 
     454                 :            :         assert(b->len <= b->size);
     455                 :            : 
     456         [ -  + ]:      39096 :         if (b->len == b->size)
     457                 :            :                 {
     458                 :          0 :                 BIO_set_retry_write(bio);
     459                 :          0 :                 return -1;
     460                 :            :                 }
     461                 :            : 
     462                 :      39096 :         num = b->size - b->len;
     463                 :      39096 :         write_offset = b->offset + b->len;
     464         [ -  + ]:      39096 :         if (write_offset >= b->size)
     465                 :          0 :                 write_offset -= b->size;
     466         [ -  + ]:      39096 :         if (write_offset + num > b->size)
     467                 :            :                 /* no ring buffer wrap-around for non-copying interface
     468                 :            :                  * (to fulfil the promise by BIO_ctrl_get_write_guarantee,
     469                 :            :                  * BIO_nwrite may have to be called twice) */
     470                 :          0 :                 num = b->size - write_offset;
     471                 :            : 
     472         [ +  - ]:      39096 :         if (buf != NULL)
     473                 :      39096 :                 *buf = b->buf + write_offset;
     474                 :            :         assert(write_offset + num <= b->size);
     475                 :            : 
     476                 :      39096 :         return num;
     477                 :            :         }
     478                 :            : 
     479                 :      19548 : static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
     480                 :            :         {
     481                 :            :         struct bio_bio_st *b;
     482                 :            :         ossl_ssize_t num, space;
     483                 :            : 
     484         [ +  - ]:      19548 :         if (num_ > SSIZE_MAX)
     485                 :            :                 num = SSIZE_MAX;
     486                 :            :         else
     487                 :      19548 :                 num = (ossl_ssize_t)num_;
     488                 :            : 
     489                 :      19548 :         space = bio_nwrite0(bio, buf);
     490         [ -  + ]:      19548 :         if (num > space)
     491                 :          0 :                 num = space;
     492         [ +  - ]:      19548 :         if (num <= 0)
     493                 :            :                 return num;
     494                 :      19548 :         b = bio->ptr;
     495                 :            :         assert(b != NULL);
     496                 :      19548 :         b->len += num;
     497                 :            :         assert(b->len <= b->size);
     498                 :            : 
     499                 :      19548 :         return num;
     500                 :            :         }
     501                 :            : 
     502                 :            : 
     503                 :     167677 : static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
     504                 :            :         {
     505                 :            :         long ret;
     506                 :     167677 :         struct bio_bio_st *b = bio->ptr;
     507                 :            :         
     508                 :            :         assert(b != NULL);
     509                 :            : 
     510   [ +  -  +  -  :     167677 :         switch (cmd)
          +  +  -  -  -  
          +  +  +  -  -  
          -  +  -  -  -  
                   +  + ]
     511                 :            :                 {
     512                 :            :         /* specific CTRL codes */
     513                 :            : 
     514                 :            :         case BIO_C_SET_WRITE_BUF_SIZE:
     515         [ -  + ]:       3036 :                 if (b->peer)
     516                 :            :                         {
     517                 :          0 :                         BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
     518                 :          0 :                         ret = 0;
     519                 :            :                         }
     520         [ -  + ]:       3036 :                 else if (num == 0)
     521                 :            :                         {
     522                 :          0 :                         BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
     523                 :          0 :                         ret = 0;
     524                 :            :                         }
     525                 :            :                 else
     526                 :            :                         {
     527                 :       3036 :                         size_t new_size = num;
     528                 :            : 
     529         [ +  - ]:       3036 :                         if (b->size != new_size)
     530                 :            :                                 {
     531         [ -  + ]:       3036 :                                 if (b->buf) 
     532                 :            :                                         {
     533                 :          0 :                                         OPENSSL_free(b->buf);
     534                 :          0 :                                         b->buf = NULL;
     535                 :            :                                         }
     536                 :       3036 :                                 b->size = new_size;
     537                 :            :                                 }
     538                 :            :                         ret = 1;
     539                 :            :                         }
     540                 :            :                 break;
     541                 :            : 
     542                 :            :         case BIO_C_GET_WRITE_BUF_SIZE:
     543                 :          0 :                 ret = (long) b->size;
     544                 :          0 :                 break;
     545                 :            : 
     546                 :            :         case BIO_C_MAKE_BIO_PAIR:
     547                 :            :                 {
     548                 :       1518 :                 BIO *other_bio = ptr;
     549                 :            :                 
     550         [ -  + ]:       1518 :                 if (bio_make_pair(bio, other_bio))
     551                 :            :                         ret = 1;
     552                 :            :                 else
     553                 :          0 :                         ret = 0;
     554                 :            :                 }
     555                 :            :                 break;
     556                 :            :                 
     557                 :            :         case BIO_C_DESTROY_BIO_PAIR:
     558                 :            :                 /* Affects both BIOs in the pair -- call just once!
     559                 :            :                  * Or let BIO_free(bio1); BIO_free(bio2); do the job. */
     560                 :          0 :                 bio_destroy_pair(bio);
     561                 :          0 :                 ret = 1;
     562                 :          0 :                 break;
     563                 :            : 
     564                 :            :         case BIO_C_GET_WRITE_GUARANTEE:
     565                 :            :                 /* How many bytes can the caller feed to the next write
     566                 :            :                  * without having to keep any? */
     567 [ +  - ][ +  - ]:      31308 :                 if (b->peer == NULL || b->closed)
     568                 :            :                         ret = 0;
     569                 :            :                 else
     570                 :      31308 :                         ret = (long) b->size - b->len;
     571                 :            :                 break;
     572                 :            : 
     573                 :            :         case BIO_C_GET_READ_REQUEST:
     574                 :            :                 /* If the peer unsuccessfully tried to read, how many bytes
     575                 :            :                  * were requested?  (As with BIO_CTRL_PENDING, that number
     576                 :            :                  * can usually be treated as boolean.) */
     577                 :      25109 :                 ret = (long) b->request;
     578                 :      25109 :                 break;
     579                 :            : 
     580                 :            :         case BIO_C_RESET_READ_REQUEST:
     581                 :            :                 /* Reset request.  (Can be useful after read attempts
     582                 :            :                  * at the other side that are meant to be non-blocking,
     583                 :            :                  * e.g. when probing SSL_read to see if any data is
     584                 :            :                  * available.) */
     585                 :          0 :                 b->request = 0;
     586                 :          0 :                 ret = 1;
     587                 :          0 :                 break;
     588                 :            : 
     589                 :            :         case BIO_C_SHUTDOWN_WR:
     590                 :            :                 /* similar to shutdown(..., SHUT_WR) */
     591                 :          0 :                 b->closed = 1;
     592                 :          0 :                 ret = 1;
     593                 :          0 :                 break;
     594                 :            : 
     595                 :            :         case BIO_C_NREAD0:
     596                 :            :                 /* prepare for non-copying read */
     597                 :          0 :                 ret = (long) bio_nread0(bio, ptr);
     598                 :          0 :                 break;
     599                 :            :                 
     600                 :            :         case BIO_C_NREAD:
     601                 :            :                 /* non-copying read */
     602                 :       6199 :                 ret = (long) bio_nread(bio, ptr, (size_t) num);
     603                 :       6199 :                 break;
     604                 :            :                 
     605                 :            :         case BIO_C_NWRITE0:
     606                 :            :                 /* prepare for non-copying write */
     607                 :      19548 :                 ret = (long) bio_nwrite0(bio, ptr);
     608                 :      19548 :                 break;
     609                 :            : 
     610                 :            :         case BIO_C_NWRITE:
     611                 :            :                 /* non-copying write */
     612                 :      19548 :                 ret = (long) bio_nwrite(bio, ptr, (size_t) num);
     613                 :      19548 :                 break;
     614                 :            :                 
     615                 :            : 
     616                 :            :         /* standard CTRL codes follow */
     617                 :            : 
     618                 :            :         case BIO_CTRL_RESET:
     619         [ #  # ]:          0 :                 if (b->buf != NULL)
     620                 :            :                         {
     621                 :          0 :                         b->len = 0;
     622                 :          0 :                         b->offset = 0;
     623                 :            :                         }
     624                 :            :                 ret = 0;
     625                 :            :                 break;          
     626                 :            : 
     627                 :            :         case BIO_CTRL_GET_CLOSE:
     628                 :          0 :                 ret = bio->shutdown;
     629                 :          0 :                 break;
     630                 :            : 
     631                 :            :         case BIO_CTRL_SET_CLOSE:
     632                 :          0 :                 bio->shutdown = (int) num;
     633                 :          0 :                 ret = 1;
     634                 :          0 :                 break;
     635                 :            : 
     636                 :            :         case BIO_CTRL_PENDING:
     637         [ +  - ]:      56417 :                 if (b->peer != NULL)
     638                 :            :                         {
     639                 :      56417 :                         struct bio_bio_st *peer_b = b->peer->ptr;
     640                 :            :                         
     641                 :      56417 :                         ret = (long) peer_b->len;
     642                 :            :                         }
     643                 :            :                 else
     644                 :            :                         ret = 0;
     645                 :            :                 break;
     646                 :            : 
     647                 :            :         case BIO_CTRL_WPENDING:
     648         [ #  # ]:          0 :                 if (b->buf != NULL)
     649                 :          0 :                         ret = (long) b->len;
     650                 :            :                 else
     651                 :            :                         ret = 0;
     652                 :            :                 break;
     653                 :            : 
     654                 :            :         case BIO_CTRL_DUP:
     655                 :            :                 /* See BIO_dup_chain for circumstances we have to expect. */
     656                 :            :                 {
     657                 :          0 :                 BIO *other_bio = ptr;
     658                 :            :                 struct bio_bio_st *other_b;
     659                 :            :                 
     660                 :            :                 assert(other_bio != NULL);
     661                 :          0 :                 other_b = other_bio->ptr;
     662                 :            :                 assert(other_b != NULL);
     663                 :            :                 
     664                 :            :                 assert(other_b->buf == NULL); /* other_bio is always fresh */
     665                 :            : 
     666                 :          0 :                 other_b->size = b->size;
     667                 :            :                 }
     668                 :            : 
     669                 :          0 :                 ret = 1;
     670                 :          0 :                 break;
     671                 :            : 
     672                 :            :         case BIO_CTRL_FLUSH:
     673                 :            :                 ret = 1;
     674                 :            :                 break;
     675                 :            : 
     676                 :            :         case BIO_CTRL_EOF:
     677                 :            :                 {
     678                 :          0 :                 BIO *other_bio = ptr;
     679                 :            :                 
     680         [ #  # ]:          0 :                 if (other_bio)
     681                 :            :                         {
     682                 :          0 :                         struct bio_bio_st *other_b = other_bio->ptr;
     683                 :            :                         
     684                 :            :                         assert(other_b != NULL);
     685 [ #  # ][ #  # ]:          0 :                         ret = other_b->len == 0 && other_b->closed;
     686                 :            :                         }
     687                 :            :                 else
     688                 :            :                         ret = 1;
     689                 :            :                 }
     690                 :            :                 break;
     691                 :            : 
     692                 :            :         default:
     693                 :       2860 :                 ret = 0;
     694                 :            :                 }
     695                 :     167677 :         return ret;
     696                 :            :         }
     697                 :            : 
     698                 :          0 : static int bio_puts(BIO *bio, const char *str)
     699                 :            :         {
     700                 :          0 :         return bio_write(bio, str, strlen(str));
     701                 :            :         }
     702                 :            : 
     703                 :            : 
     704                 :       1518 : static int bio_make_pair(BIO *bio1, BIO *bio2)
     705                 :            :         {
     706                 :            :         struct bio_bio_st *b1, *b2;
     707                 :            : 
     708                 :            :         assert(bio1 != NULL);
     709                 :            :         assert(bio2 != NULL);
     710                 :            : 
     711                 :       1518 :         b1 = bio1->ptr;
     712                 :       1518 :         b2 = bio2->ptr;
     713                 :            :         
     714 [ +  - ][ -  + ]:       1518 :         if (b1->peer != NULL || b2->peer != NULL)
     715                 :            :                 {
     716                 :          0 :                 BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
     717                 :          0 :                 return 0;
     718                 :            :                 }
     719                 :            :         
     720         [ +  - ]:       1518 :         if (b1->buf == NULL)
     721                 :            :                 {
     722                 :       1518 :                 b1->buf = OPENSSL_malloc(b1->size);
     723         [ -  + ]:       1518 :                 if (b1->buf == NULL)
     724                 :            :                         {
     725                 :          0 :                         BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
     726                 :          0 :                         return 0;
     727                 :            :                         }
     728                 :       1518 :                 b1->len = 0;
     729                 :       1518 :                 b1->offset = 0;
     730                 :            :                 }
     731                 :            :         
     732         [ +  - ]:       1518 :         if (b2->buf == NULL)
     733                 :            :                 {
     734                 :       1518 :                 b2->buf = OPENSSL_malloc(b2->size);
     735         [ -  + ]:       1518 :                 if (b2->buf == NULL)
     736                 :            :                         {
     737                 :          0 :                         BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
     738                 :          0 :                         return 0;
     739                 :            :                         }
     740                 :       1518 :                 b2->len = 0;
     741                 :       1518 :                 b2->offset = 0;
     742                 :            :                 }
     743                 :            :         
     744                 :       1518 :         b1->peer = bio2;
     745                 :       1518 :         b1->closed = 0;
     746                 :       1518 :         b1->request = 0;
     747                 :       1518 :         b2->peer = bio1;
     748                 :       1518 :         b2->closed = 0;
     749                 :       1518 :         b2->request = 0;
     750                 :            : 
     751                 :       1518 :         bio1->init = 1;
     752                 :       1518 :         bio2->init = 1;
     753                 :            : 
     754                 :       1518 :         return 1;
     755                 :            :         }
     756                 :            : 
     757                 :       3036 : static void bio_destroy_pair(BIO *bio)
     758                 :            :         {
     759                 :       1518 :         struct bio_bio_st *b = bio->ptr;
     760                 :            : 
     761         [ +  - ]:       1518 :         if (b != NULL)
     762                 :            :                 {
     763                 :       1518 :                 BIO *peer_bio = b->peer;
     764                 :            : 
     765         [ +  - ]:       1518 :                 if (peer_bio != NULL)
     766                 :            :                         {
     767                 :       1518 :                         struct bio_bio_st *peer_b = peer_bio->ptr;
     768                 :            : 
     769                 :            :                         assert(peer_b != NULL);
     770                 :            :                         assert(peer_b->peer == bio);
     771                 :            : 
     772                 :       1518 :                         peer_b->peer = NULL;
     773                 :       1518 :                         peer_bio->init = 0;
     774                 :            :                         assert(peer_b->buf != NULL);
     775                 :       1518 :                         peer_b->len = 0;
     776                 :       1518 :                         peer_b->offset = 0;
     777                 :            :                         
     778                 :       1518 :                         b->peer = NULL;
     779                 :       1518 :                         bio->init = 0;
     780                 :            :                         assert(b->buf != NULL);
     781                 :       1518 :                         b->len = 0;
     782                 :       1518 :                         b->offset = 0;
     783                 :            :                         }
     784                 :            :                 }
     785                 :       1518 :         }
     786                 :            :  
     787                 :            : 
     788                 :            : /* Exported convenience functions */
     789                 :       1518 : int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
     790                 :            :         BIO **bio2_p, size_t writebuf2)
     791                 :            :          {
     792                 :       1518 :          BIO *bio1 = NULL, *bio2 = NULL;
     793                 :            :          long r;
     794                 :       1518 :          int ret = 0;
     795                 :            : 
     796                 :       1518 :          bio1 = BIO_new(BIO_s_bio());
     797         [ +  - ]:       1518 :          if (bio1 == NULL)
     798                 :            :                  goto err;
     799                 :       1518 :          bio2 = BIO_new(BIO_s_bio());
     800         [ +  - ]:       1518 :          if (bio2 == NULL)
     801                 :            :                  goto err;
     802                 :            : 
     803         [ +  - ]:       1518 :          if (writebuf1)
     804                 :            :                  {
     805                 :       1518 :                  r = BIO_set_write_buf_size(bio1, writebuf1);
     806         [ +  - ]:       1518 :                  if (!r)
     807                 :            :                          goto err;
     808                 :            :                  }
     809         [ +  - ]:       1518 :          if (writebuf2)
     810                 :            :                  {
     811                 :       1518 :                  r = BIO_set_write_buf_size(bio2, writebuf2);
     812         [ +  - ]:       1518 :                  if (!r)
     813                 :            :                          goto err;
     814                 :            :                  }
     815                 :            : 
     816                 :       1518 :          r = BIO_make_bio_pair(bio1, bio2);
     817         [ +  - ]:       1518 :          if (!r)
     818                 :            :                  goto err;
     819                 :       1518 :          ret = 1;
     820                 :            : 
     821                 :            :  err:
     822         [ -  + ]:       1518 :          if (ret == 0)
     823                 :            :                  {
     824         [ #  # ]:          0 :                  if (bio1)
     825                 :            :                          {
     826                 :          0 :                          BIO_free(bio1);
     827                 :          0 :                          bio1 = NULL;
     828                 :            :                          }
     829         [ #  # ]:          0 :                  if (bio2)
     830                 :            :                          {
     831                 :          0 :                          BIO_free(bio2);
     832                 :          0 :                          bio2 = NULL;
     833                 :            :                          }
     834                 :            :                  }
     835                 :            : 
     836                 :       1518 :          *bio1_p = bio1;
     837                 :       1518 :          *bio2_p = bio2;
     838                 :       1518 :          return ret;
     839                 :            :          }
     840                 :            : 
     841                 :      31308 : size_t BIO_ctrl_get_write_guarantee(BIO *bio)
     842                 :            :         {
     843                 :      31308 :         return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
     844                 :            :         }
     845                 :            : 
     846                 :      25109 : size_t BIO_ctrl_get_read_request(BIO *bio)
     847                 :            :         {
     848                 :      25109 :         return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
     849                 :            :         }
     850                 :            : 
     851                 :          0 : int BIO_ctrl_reset_read_request(BIO *bio)
     852                 :            :         {
     853                 :          0 :         return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
     854                 :            :         }
     855                 :            : 
     856                 :            : 
     857                 :            : /* BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
     858                 :            :  * (conceivably some other BIOs could allow non-copying reads and writes too.)
     859                 :            :  */
     860                 :          0 : int BIO_nread0(BIO *bio, char **buf)
     861                 :            :         {
     862                 :            :         long ret;
     863                 :            : 
     864         [ #  # ]:          0 :         if (!bio->init)
     865                 :            :                 {
     866                 :          0 :                 BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
     867                 :          0 :                 return -2;
     868                 :            :                 }
     869                 :            : 
     870                 :          0 :         ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
     871         [ #  # ]:          0 :         if (ret > INT_MAX)
     872                 :            :                 return INT_MAX;
     873                 :            :         else
     874                 :          0 :                 return (int) ret;
     875                 :            :         }
     876                 :            : 
     877                 :       6199 : int BIO_nread(BIO *bio, char **buf, int num)
     878                 :            :         {
     879                 :            :         int ret;
     880                 :            : 
     881         [ -  + ]:       6199 :         if (!bio->init)
     882                 :            :                 {
     883                 :          0 :                 BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
     884                 :          0 :                 return -2;
     885                 :            :                 }
     886                 :            : 
     887                 :       6199 :         ret = (int) BIO_ctrl(bio, BIO_C_NREAD, num, buf);
     888         [ +  - ]:       6199 :         if (ret > 0)
     889                 :       6199 :                 bio->num_read += ret;
     890                 :       6199 :         return ret;
     891                 :            :         }
     892                 :            : 
     893                 :      19548 : int BIO_nwrite0(BIO *bio, char **buf)
     894                 :            :         {
     895                 :            :         long ret;
     896                 :            : 
     897         [ -  + ]:      19548 :         if (!bio->init)
     898                 :            :                 {
     899                 :          0 :                 BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
     900                 :          0 :                 return -2;
     901                 :            :                 }
     902                 :            : 
     903                 :      19548 :         ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
     904         [ +  - ]:      19548 :         if (ret > INT_MAX)
     905                 :            :                 return INT_MAX;
     906                 :            :         else
     907                 :      19548 :                 return (int) ret;
     908                 :            :         }
     909                 :            : 
     910                 :      19548 : int BIO_nwrite(BIO *bio, char **buf, int num)
     911                 :            :         {
     912                 :            :         int ret;
     913                 :            : 
     914         [ -  + ]:      19548 :         if (!bio->init)
     915                 :            :                 {
     916                 :          0 :                 BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
     917                 :          0 :                 return -2;
     918                 :            :                 }
     919                 :            : 
     920                 :      19548 :         ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
     921         [ +  - ]:      19548 :         if (ret > 0)
     922                 :      19548 :                 bio->num_write += ret;
     923                 :      19548 :         return ret;
     924                 :            :         }

Generated by: LCOV version 1.9