LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/evp - bio_b64.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 255 0.0 %
Date: 2015-10-10 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /* crypto/evp/bio_b64.c */
       2             : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3             :  * All rights reserved.
       4             :  *
       5             :  * This package is an SSL implementation written
       6             :  * by Eric Young (eay@cryptsoft.com).
       7             :  * The implementation was written so as to conform with Netscapes SSL.
       8             :  *
       9             :  * This library is free for commercial and non-commercial use as long as
      10             :  * the following conditions are aheared to.  The following conditions
      11             :  * apply to all code found in this distribution, be it the RC4, RSA,
      12             :  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
      13             :  * included with this distribution is covered by the same copyright terms
      14             :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15             :  *
      16             :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17             :  * the code are not to be removed.
      18             :  * If this package is used in a product, Eric Young should be given attribution
      19             :  * as the author of the parts of the library used.
      20             :  * This can be in the form of a textual message at program startup or
      21             :  * in documentation (online or textual) provided with the package.
      22             :  *
      23             :  * Redistribution and use in source and binary forms, with or without
      24             :  * modification, are permitted provided that the following conditions
      25             :  * are met:
      26             :  * 1. Redistributions of source code must retain the copyright
      27             :  *    notice, this list of conditions and the following disclaimer.
      28             :  * 2. Redistributions in binary form must reproduce the above copyright
      29             :  *    notice, this list of conditions and the following disclaimer in the
      30             :  *    documentation and/or other materials provided with the distribution.
      31             :  * 3. All advertising materials mentioning features or use of this software
      32             :  *    must display the following acknowledgement:
      33             :  *    "This product includes cryptographic software written by
      34             :  *     Eric Young (eay@cryptsoft.com)"
      35             :  *    The word 'cryptographic' can be left out if the rouines from the library
      36             :  *    being used are not cryptographic related :-).
      37             :  * 4. If you include any Windows specific code (or a derivative thereof) from
      38             :  *    the apps directory (application code) you must include an acknowledgement:
      39             :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40             :  *
      41             :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      49             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      50             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      51             :  * SUCH DAMAGE.
      52             :  *
      53             :  * The licence and distribution terms for any publically available version or
      54             :  * derivative of this code cannot be changed.  i.e. this code cannot simply be
      55             :  * copied and put under another distribution licence
      56             :  * [including the GNU Public Licence.]
      57             :  */
      58             : 
      59             : #include <stdio.h>
      60             : #include <errno.h>
      61             : #include "cryptlib.h"
      62             : #include <openssl/buffer.h>
      63             : #include <openssl/evp.h>
      64             : 
      65             : static int b64_write(BIO *h, const char *buf, int num);
      66             : static int b64_read(BIO *h, char *buf, int size);
      67             : static int b64_puts(BIO *h, const char *str);
      68             : /*
      69             :  * static int b64_gets(BIO *h, char *str, int size);
      70             :  */
      71             : static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2);
      72             : static int b64_new(BIO *h);
      73             : static int b64_free(BIO *data);
      74             : static long b64_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
      75             : #define B64_BLOCK_SIZE  1024
      76             : #define B64_BLOCK_SIZE2 768
      77             : #define B64_NONE        0
      78             : #define B64_ENCODE      1
      79             : #define B64_DECODE      2
      80             : 
      81             : typedef struct b64_struct {
      82             :     /*
      83             :      * BIO *bio; moved to the BIO structure
      84             :      */
      85             :     int buf_len;
      86             :     int buf_off;
      87             :     int tmp_len;                /* used to find the start when decoding */
      88             :     int tmp_nl;                 /* If true, scan until '\n' */
      89             :     int encode;
      90             :     int start;                  /* have we started decoding yet? */
      91             :     int cont;                   /* <= 0 when finished */
      92             :     EVP_ENCODE_CTX base64;
      93             :     char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10];
      94             :     char tmp[B64_BLOCK_SIZE];
      95             : } BIO_B64_CTX;
      96             : 
      97             : static BIO_METHOD methods_b64 = {
      98             :     BIO_TYPE_BASE64, "base64 encoding",
      99             :     b64_write,
     100             :     b64_read,
     101             :     b64_puts,
     102             :     NULL,                       /* b64_gets, */
     103             :     b64_ctrl,
     104             :     b64_new,
     105             :     b64_free,
     106             :     b64_callback_ctrl,
     107             : };
     108             : 
     109           0 : BIO_METHOD *BIO_f_base64(void)
     110             : {
     111           0 :     return (&methods_b64);
     112             : }
     113             : 
     114           0 : static int b64_new(BIO *bi)
     115             : {
     116             :     BIO_B64_CTX *ctx;
     117             : 
     118           0 :     ctx = (BIO_B64_CTX *)OPENSSL_malloc(sizeof(BIO_B64_CTX));
     119           0 :     if (ctx == NULL)
     120             :         return (0);
     121             : 
     122           0 :     ctx->buf_len = 0;
     123           0 :     ctx->tmp_len = 0;
     124           0 :     ctx->tmp_nl = 0;
     125           0 :     ctx->buf_off = 0;
     126           0 :     ctx->cont = 1;
     127           0 :     ctx->start = 1;
     128           0 :     ctx->encode = 0;
     129             : 
     130           0 :     bi->init = 1;
     131           0 :     bi->ptr = (char *)ctx;
     132           0 :     bi->flags = 0;
     133           0 :     bi->num = 0;
     134           0 :     return (1);
     135             : }
     136             : 
     137           0 : static int b64_free(BIO *a)
     138             : {
     139           0 :     if (a == NULL)
     140             :         return (0);
     141           0 :     OPENSSL_free(a->ptr);
     142           0 :     a->ptr = NULL;
     143           0 :     a->init = 0;
     144           0 :     a->flags = 0;
     145           0 :     return (1);
     146             : }
     147             : 
     148           0 : static int b64_read(BIO *b, char *out, int outl)
     149             : {
     150             :     int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
     151             :     BIO_B64_CTX *ctx;
     152             :     unsigned char *p, *q;
     153             : 
     154           0 :     if (out == NULL)
     155             :         return (0);
     156           0 :     ctx = (BIO_B64_CTX *)b->ptr;
     157             : 
     158           0 :     if ((ctx == NULL) || (b->next_bio == NULL))
     159             :         return (0);
     160             : 
     161           0 :     BIO_clear_retry_flags(b);
     162             : 
     163           0 :     if (ctx->encode != B64_DECODE) {
     164           0 :         ctx->encode = B64_DECODE;
     165           0 :         ctx->buf_len = 0;
     166           0 :         ctx->buf_off = 0;
     167           0 :         ctx->tmp_len = 0;
     168           0 :         EVP_DecodeInit(&(ctx->base64));
     169             :     }
     170             : 
     171             :     /* First check if there are bytes decoded/encoded */
     172           0 :     if (ctx->buf_len > 0) {
     173           0 :         OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
     174           0 :         i = ctx->buf_len - ctx->buf_off;
     175           0 :         if (i > outl)
     176             :             i = outl;
     177           0 :         OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf));
     178           0 :         memcpy(out, &(ctx->buf[ctx->buf_off]), i);
     179             :         ret = i;
     180           0 :         out += i;
     181           0 :         outl -= i;
     182           0 :         ctx->buf_off += i;
     183           0 :         if (ctx->buf_len == ctx->buf_off) {
     184           0 :             ctx->buf_len = 0;
     185           0 :             ctx->buf_off = 0;
     186             :         }
     187             :     }
     188             : 
     189             :     /*
     190             :      * At this point, we have room of outl bytes and an empty buffer, so we
     191             :      * should read in some more.
     192             :      */
     193             : 
     194             :     ret_code = 0;
     195           0 :     while (outl > 0) {
     196           0 :         if (ctx->cont <= 0)
     197             :             break;
     198             : 
     199           0 :         i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]),
     200           0 :                      B64_BLOCK_SIZE - ctx->tmp_len);
     201             : 
     202           0 :         if (i <= 0) {
     203             :             ret_code = i;
     204             : 
     205             :             /* Should we continue next time we are called? */
     206           0 :             if (!BIO_should_retry(b->next_bio)) {
     207           0 :                 ctx->cont = i;
     208             :                 /* If buffer empty break */
     209           0 :                 if (ctx->tmp_len == 0)
     210             :                     break;
     211             :                 /* Fall through and process what we have */
     212             :                 else
     213             :                     i = 0;
     214             :             }
     215             :             /* else we retry and add more data to buffer */
     216             :             else
     217             :                 break;
     218             :         }
     219           0 :         i += ctx->tmp_len;
     220           0 :         ctx->tmp_len = i;
     221             : 
     222             :         /*
     223             :          * We need to scan, a line at a time until we have a valid line if we
     224             :          * are starting.
     225             :          */
     226           0 :         if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) {
     227             :             /* ctx->start=1; */
     228           0 :             ctx->tmp_len = 0;
     229           0 :         } else if (ctx->start) {
     230           0 :             q = p = (unsigned char *)ctx->tmp;
     231           0 :             num = 0;
     232           0 :             for (j = 0; j < i; j++) {
     233           0 :                 if (*(q++) != '\n')
     234           0 :                     continue;
     235             : 
     236             :                 /*
     237             :                  * due to a previous very long line, we need to keep on
     238             :                  * scanning for a '\n' before we even start looking for
     239             :                  * base64 encoded stuff.
     240             :                  */
     241           0 :                 if (ctx->tmp_nl) {
     242             :                     p = q;
     243           0 :                     ctx->tmp_nl = 0;
     244           0 :                     continue;
     245             :                 }
     246             : 
     247           0 :                 k = EVP_DecodeUpdate(&(ctx->base64),
     248           0 :                                      (unsigned char *)ctx->buf,
     249           0 :                                      &num, p, q - p);
     250           0 :                 if ((k <= 0) && (num == 0) && (ctx->start))
     251           0 :                     EVP_DecodeInit(&ctx->base64);
     252             :                 else {
     253           0 :                     if (p != (unsigned char *)
     254             :                         &(ctx->tmp[0])) {
     255           0 :                         i -= (p - (unsigned char *)
     256             :                               &(ctx->tmp[0]));
     257           0 :                         for (x = 0; x < i; x++)
     258           0 :                             ctx->tmp[x] = p[x];
     259             :                     }
     260           0 :                     EVP_DecodeInit(&ctx->base64);
     261           0 :                     ctx->start = 0;
     262           0 :                     break;
     263             :                 }
     264             :                 p = q;
     265             :             }
     266             : 
     267             :             /* we fell off the end without starting */
     268           0 :             if ((j == i) && (num == 0)) {
     269             :                 /*
     270             :                  * Is this is one long chunk?, if so, keep on reading until a
     271             :                  * new line.
     272             :                  */
     273           0 :                 if (p == (unsigned char *)&(ctx->tmp[0])) {
     274             :                     /* Check buffer full */
     275           0 :                     if (i == B64_BLOCK_SIZE) {
     276           0 :                         ctx->tmp_nl = 1;
     277           0 :                         ctx->tmp_len = 0;
     278             :                     }
     279           0 :                 } else if (p != q) { /* finished on a '\n' */
     280           0 :                     n = q - p;
     281           0 :                     for (ii = 0; ii < n; ii++)
     282           0 :                         ctx->tmp[ii] = p[ii];
     283           0 :                     ctx->tmp_len = n;
     284             :                 }
     285             :                 /* else finished on a '\n' */
     286           0 :                 continue;
     287             :             } else {
     288           0 :                 ctx->tmp_len = 0;
     289             :             }
     290           0 :         } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) {
     291             :             /*
     292             :              * If buffer isn't full and we can retry then restart to read in
     293             :              * more data.
     294             :              */
     295           0 :             continue;
     296             :         }
     297             : 
     298           0 :         if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
     299             :             int z, jj;
     300             : 
     301             : #if 0
     302             :             jj = (i >> 2) << 2;
     303             : #else
     304           0 :             jj = i & ~3;        /* process per 4 */
     305             : #endif
     306           0 :             z = EVP_DecodeBlock((unsigned char *)ctx->buf,
     307           0 :                                 (unsigned char *)ctx->tmp, jj);
     308           0 :             if (jj > 2) {
     309           0 :                 if (ctx->tmp[jj - 1] == '=') {
     310           0 :                     z--;
     311           0 :                     if (ctx->tmp[jj - 2] == '=')
     312           0 :                         z--;
     313             :                 }
     314             :             }
     315             :             /*
     316             :              * z is now number of output bytes and jj is the number consumed
     317             :              */
     318           0 :             if (jj != i) {
     319           0 :                 memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
     320           0 :                 ctx->tmp_len = i - jj;
     321             :             }
     322           0 :             ctx->buf_len = 0;
     323           0 :             if (z > 0) {
     324           0 :                 ctx->buf_len = z;
     325             :             }
     326             :             i = z;
     327             :         } else {
     328           0 :             i = EVP_DecodeUpdate(&(ctx->base64),
     329           0 :                                  (unsigned char *)ctx->buf, &ctx->buf_len,
     330           0 :                                  (unsigned char *)ctx->tmp, i);
     331           0 :             ctx->tmp_len = 0;
     332             :         }
     333           0 :         ctx->buf_off = 0;
     334           0 :         if (i < 0) {
     335             :             ret_code = 0;
     336           0 :             ctx->buf_len = 0;
     337           0 :             break;
     338             :         }
     339             : 
     340           0 :         if (ctx->buf_len <= outl)
     341             :             i = ctx->buf_len;
     342             :         else
     343             :             i = outl;
     344             : 
     345           0 :         memcpy(out, ctx->buf, i);
     346           0 :         ret += i;
     347           0 :         ctx->buf_off = i;
     348           0 :         if (ctx->buf_off == ctx->buf_len) {
     349           0 :             ctx->buf_len = 0;
     350           0 :             ctx->buf_off = 0;
     351             :         }
     352           0 :         outl -= i;
     353           0 :         out += i;
     354             :     }
     355             :     /* BIO_clear_retry_flags(b); */
     356           0 :     BIO_copy_next_retry(b);
     357           0 :     return ((ret == 0) ? ret_code : ret);
     358             : }
     359             : 
     360           0 : static int b64_write(BIO *b, const char *in, int inl)
     361             : {
     362             :     int ret = 0;
     363             :     int n;
     364             :     int i;
     365             :     BIO_B64_CTX *ctx;
     366             : 
     367           0 :     ctx = (BIO_B64_CTX *)b->ptr;
     368           0 :     BIO_clear_retry_flags(b);
     369             : 
     370           0 :     if (ctx->encode != B64_ENCODE) {
     371           0 :         ctx->encode = B64_ENCODE;
     372           0 :         ctx->buf_len = 0;
     373           0 :         ctx->buf_off = 0;
     374           0 :         ctx->tmp_len = 0;
     375           0 :         EVP_EncodeInit(&(ctx->base64));
     376             :     }
     377             : 
     378           0 :     OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf));
     379           0 :     OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
     380           0 :     OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
     381           0 :     n = ctx->buf_len - ctx->buf_off;
     382           0 :     while (n > 0) {
     383           0 :         i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
     384           0 :         if (i <= 0) {
     385           0 :             BIO_copy_next_retry(b);
     386           0 :             return (i);
     387             :         }
     388           0 :         OPENSSL_assert(i <= n);
     389           0 :         ctx->buf_off += i;
     390           0 :         OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
     391           0 :         OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
     392           0 :         n -= i;
     393             :     }
     394             :     /* at this point all pending data has been written */
     395           0 :     ctx->buf_off = 0;
     396           0 :     ctx->buf_len = 0;
     397             : 
     398           0 :     if ((in == NULL) || (inl <= 0))
     399             :         return (0);
     400             : 
     401           0 :     while (inl > 0) {
     402           0 :         n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;
     403             : 
     404           0 :         if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
     405           0 :             if (ctx->tmp_len > 0) {
     406           0 :                 OPENSSL_assert(ctx->tmp_len <= 3);
     407           0 :                 n = 3 - ctx->tmp_len;
     408             :                 /*
     409             :                  * There's a theoretical possibility for this
     410             :                  */
     411           0 :                 if (n > inl)
     412             :                     n = inl;
     413           0 :                 memcpy(&(ctx->tmp[ctx->tmp_len]), in, n);
     414           0 :                 ctx->tmp_len += n;
     415           0 :                 ret += n;
     416           0 :                 if (ctx->tmp_len < 3)
     417             :                     break;
     418           0 :                 ctx->buf_len =
     419           0 :                     EVP_EncodeBlock((unsigned char *)ctx->buf,
     420           0 :                                     (unsigned char *)ctx->tmp, ctx->tmp_len);
     421           0 :                 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
     422           0 :                 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
     423             :                 /*
     424             :                  * Since we're now done using the temporary buffer, the
     425             :                  * length should be 0'd
     426             :                  */
     427           0 :                 ctx->tmp_len = 0;
     428             :             } else {
     429           0 :                 if (n < 3) {
     430           0 :                     memcpy(ctx->tmp, in, n);
     431           0 :                     ctx->tmp_len = n;
     432           0 :                     ret += n;
     433           0 :                     break;
     434             :                 }
     435           0 :                 n -= n % 3;
     436           0 :                 ctx->buf_len =
     437           0 :                     EVP_EncodeBlock((unsigned char *)ctx->buf,
     438             :                                     (const unsigned char *)in, n);
     439           0 :                 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
     440           0 :                 OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
     441           0 :                 ret += n;
     442             :             }
     443             :         } else {
     444           0 :             EVP_EncodeUpdate(&(ctx->base64),
     445           0 :                              (unsigned char *)ctx->buf, &ctx->buf_len,
     446             :                              (unsigned char *)in, n);
     447           0 :             OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
     448           0 :             OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
     449           0 :             ret += n;
     450             :         }
     451           0 :         inl -= n;
     452           0 :         in += n;
     453             : 
     454           0 :         ctx->buf_off = 0;
     455           0 :         n = ctx->buf_len;
     456           0 :         while (n > 0) {
     457           0 :             i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
     458           0 :             if (i <= 0) {
     459           0 :                 BIO_copy_next_retry(b);
     460           0 :                 return ((ret == 0) ? i : ret);
     461             :             }
     462           0 :             OPENSSL_assert(i <= n);
     463           0 :             n -= i;
     464           0 :             ctx->buf_off += i;
     465           0 :             OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
     466           0 :             OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
     467             :         }
     468           0 :         ctx->buf_len = 0;
     469           0 :         ctx->buf_off = 0;
     470             :     }
     471           0 :     return (ret);
     472             : }
     473             : 
     474           0 : static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
     475             : {
     476             :     BIO_B64_CTX *ctx;
     477             :     long ret = 1;
     478             :     int i;
     479             : 
     480           0 :     ctx = (BIO_B64_CTX *)b->ptr;
     481             : 
     482           0 :     switch (cmd) {
     483             :     case BIO_CTRL_RESET:
     484           0 :         ctx->cont = 1;
     485           0 :         ctx->start = 1;
     486           0 :         ctx->encode = B64_NONE;
     487           0 :         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
     488           0 :         break;
     489             :     case BIO_CTRL_EOF:         /* More to read */
     490           0 :         if (ctx->cont <= 0)
     491             :             ret = 1;
     492             :         else
     493           0 :             ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
     494             :         break;
     495             :     case BIO_CTRL_WPENDING:    /* More to write in buffer */
     496           0 :         OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
     497           0 :         ret = ctx->buf_len - ctx->buf_off;
     498           0 :         if ((ret == 0) && (ctx->encode != B64_NONE)
     499           0 :             && (ctx->base64.num != 0))
     500             :             ret = 1;
     501           0 :         else if (ret <= 0)
     502           0 :             ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
     503             :         break;
     504             :     case BIO_CTRL_PENDING:     /* More to read in buffer */
     505           0 :         OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
     506           0 :         ret = ctx->buf_len - ctx->buf_off;
     507           0 :         if (ret <= 0)
     508           0 :             ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
     509             :         break;
     510             :     case BIO_CTRL_FLUSH:
     511             :         /* do a final write */
     512             :  again:
     513           0 :         while (ctx->buf_len != ctx->buf_off) {
     514           0 :             i = b64_write(b, NULL, 0);
     515           0 :             if (i < 0)
     516           0 :                 return i;
     517             :         }
     518           0 :         if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
     519           0 :             if (ctx->tmp_len != 0) {
     520           0 :                 ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf,
     521           0 :                                                (unsigned char *)ctx->tmp,
     522             :                                                ctx->tmp_len);
     523           0 :                 ctx->buf_off = 0;
     524           0 :                 ctx->tmp_len = 0;
     525           0 :                 goto again;
     526             :             }
     527           0 :         } else if (ctx->encode != B64_NONE && ctx->base64.num != 0) {
     528           0 :             ctx->buf_off = 0;
     529           0 :             EVP_EncodeFinal(&(ctx->base64),
     530           0 :                             (unsigned char *)ctx->buf, &(ctx->buf_len));
     531             :             /* push out the bytes */
     532           0 :             goto again;
     533             :         }
     534             :         /* Finally flush the underlying BIO */
     535           0 :         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
     536           0 :         break;
     537             : 
     538             :     case BIO_C_DO_STATE_MACHINE:
     539           0 :         BIO_clear_retry_flags(b);
     540           0 :         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
     541           0 :         BIO_copy_next_retry(b);
     542           0 :         break;
     543             : 
     544             :     case BIO_CTRL_DUP:
     545             :         break;
     546             :     case BIO_CTRL_INFO:
     547             :     case BIO_CTRL_GET:
     548             :     case BIO_CTRL_SET:
     549             :     default:
     550           0 :         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
     551           0 :         break;
     552             :     }
     553           0 :     return (ret);
     554             : }
     555             : 
     556           0 : static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
     557             : {
     558             :     long ret = 1;
     559             : 
     560           0 :     if (b->next_bio == NULL)
     561             :         return (0);
     562             :     switch (cmd) {
     563             :     default:
     564           0 :         ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
     565             :         break;
     566             :     }
     567           0 :     return (ret);
     568             : }
     569             : 
     570           0 : static int b64_puts(BIO *b, const char *str)
     571             : {
     572           0 :     return b64_write(b, str, strlen(str));
     573             : }

Generated by: LCOV version 1.10