Home | History | Annotate | Download | only in base64
      1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      2  * All rights reserved.
      3  *
      4  * This package is an SSL implementation written
      5  * by Eric Young (eay (at) cryptsoft.com).
      6  * The implementation was written so as to conform with Netscapes SSL.
      7  *
      8  * This library is free for commercial and non-commercial use as long as
      9  * the following conditions are aheared to.  The following conditions
     10  * apply to all code found in this distribution, be it the RC4, RSA,
     11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     12  * included with this distribution is covered by the same copyright terms
     13  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     14  *
     15  * Copyright remains Eric Young's, and as such any Copyright notices in
     16  * the code are not to be removed.
     17  * If this package is used in a product, Eric Young should be given attribution
     18  * as the author of the parts of the library used.
     19  * This can be in the form of a textual message at program startup or
     20  * in documentation (online or textual) provided with the package.
     21  *
     22  * Redistribution and use in source and binary forms, with or without
     23  * modification, are permitted provided that the following conditions
     24  * are met:
     25  * 1. Redistributions of source code must retain the copyright
     26  *    notice, this list of conditions and the following disclaimer.
     27  * 2. Redistributions in binary form must reproduce the above copyright
     28  *    notice, this list of conditions and the following disclaimer in the
     29  *    documentation and/or other materials provided with the distribution.
     30  * 3. All advertising materials mentioning features or use of this software
     31  *    must display the following acknowledgement:
     32  *    "This product includes cryptographic software written by
     33  *     Eric Young (eay (at) cryptsoft.com)"
     34  *    The word 'cryptographic' can be left out if the rouines from the library
     35  *    being used are not cryptographic related :-).
     36  * 4. If you include any Windows specific code (or a derivative thereof) from
     37  *    the apps directory (application code) you must include an acknowledgement:
     38  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     39  *
     40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     50  * SUCH DAMAGE.
     51  *
     52  * The licence and distribution terms for any publically available version or
     53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     54  * copied and put under another distribution licence
     55  * [including the GNU Public Licence.] */
     56 
     57 #include <openssl/base64.h>
     58 
     59 #include <assert.h>
     60 #include <limits.h>
     61 #include <string.h>
     62 
     63 
     64 static const unsigned char data_bin2ascii[65] =
     65     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     66 
     67 #define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f])
     68 
     69 /* 64 char lines
     70  * pad input with 0
     71  * left over chars are set to =
     72  * 1 byte  => xx==
     73  * 2 bytes => xxx=
     74  * 3 bytes => xxxx
     75  */
     76 #define BIN_PER_LINE    (64/4*3)
     77 #define CHUNKS_PER_LINE (64/4)
     78 #define CHAR_PER_LINE   (64+1)
     79 
     80 /* 0xF0 is a EOLN
     81  * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
     82  * 0xF2 is EOF
     83  * 0xE0 is ignore at start of line.
     84  * 0xFF is error */
     85 
     86 #define B64_EOLN 0xF0
     87 #define B64_CR 0xF1
     88 #define B64_EOF 0xF2
     89 #define B64_WS 0xE0
     90 #define B64_ERROR 0xFF
     91 #define B64_NOT_BASE64(a) (((a) | 0x13) == 0xF3)
     92 
     93 static const uint8_t data_ascii2bin[128] = {
     94     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF0, 0xFF,
     95     0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     96     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF,
     97     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
     98     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
     99     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
    100     0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
    101     0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    102     0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
    103     0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
    104     0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    105 };
    106 
    107 static uint8_t conv_ascii2bin(uint8_t a) {
    108   if (a >= 128) {
    109     return 0xFF;
    110   }
    111   return data_ascii2bin[a];
    112 }
    113 
    114 void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) {
    115   ctx->length = 48;
    116   ctx->num = 0;
    117   ctx->line_num = 0;
    118 }
    119 
    120 void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
    121                       const uint8_t *in, size_t in_len) {
    122   unsigned i, j;
    123   unsigned total = 0;
    124 
    125   *out_len = 0;
    126   if (in_len == 0) {
    127     return;
    128   }
    129 
    130   assert(ctx->length <= sizeof(ctx->enc_data));
    131 
    132   if (ctx->num + in_len < ctx->length) {
    133     memcpy(&ctx->enc_data[ctx->num], in, in_len);
    134     ctx->num += in_len;
    135     return;
    136   }
    137   if (ctx->num != 0) {
    138     i = ctx->length - ctx->num;
    139     memcpy(&ctx->enc_data[ctx->num], in, i);
    140     in += i;
    141     in_len -= i;
    142     j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
    143     ctx->num = 0;
    144     out += j;
    145     *(out++) = '\n';
    146     *out = '\0';
    147     total = j + 1;
    148   }
    149   while (in_len >= ctx->length) {
    150     j = EVP_EncodeBlock(out, in, ctx->length);
    151     in += ctx->length;
    152     in_len -= ctx->length;
    153     out += j;
    154     *(out++) = '\n';
    155     *out = '\0';
    156     total += j + 1;
    157   }
    158   if (in_len != 0) {
    159     memcpy(&ctx->enc_data[0], in, in_len);
    160   }
    161   ctx->num = in_len;
    162   *out_len = total;
    163 }
    164 
    165 void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
    166   unsigned ret = 0;
    167 
    168   if (ctx->num != 0) {
    169     ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
    170     out[ret++] = '\n';
    171     out[ret] = '\0';
    172     ctx->num = 0;
    173   }
    174   *out_len = ret;
    175 }
    176 
    177 size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
    178   uint32_t l;
    179   size_t remaining = src_len, ret = 0;
    180 
    181   while (remaining) {
    182     if (remaining >= 3) {
    183       l = (((uint32_t)src[0]) << 16L) | (((uint32_t)src[1]) << 8L) | src[2];
    184       *(dst++) = conv_bin2ascii(l >> 18L);
    185       *(dst++) = conv_bin2ascii(l >> 12L);
    186       *(dst++) = conv_bin2ascii(l >> 6L);
    187       *(dst++) = conv_bin2ascii(l);
    188       remaining -= 3;
    189     } else {
    190       l = ((uint32_t)src[0]) << 16L;
    191       if (remaining == 2) {
    192         l |= ((uint32_t)src[1] << 8L);
    193       }
    194 
    195       *(dst++) = conv_bin2ascii(l >> 18L);
    196       *(dst++) = conv_bin2ascii(l >> 12L);
    197       *(dst++) = (remaining == 1) ? '=' : conv_bin2ascii(l >> 6L);
    198       *(dst++) = '=';
    199       remaining = 0;
    200     }
    201     ret += 4;
    202     src += 3;
    203   }
    204 
    205   *dst = '\0';
    206   return ret;
    207 }
    208 
    209 int EVP_DecodedLength(size_t *out_len, size_t len) {
    210   if (len % 4 != 0) {
    211     return 0;
    212   }
    213   *out_len = (len / 4) * 3;
    214   return 1;
    215 }
    216 
    217 int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out,
    218                      const uint8_t *in, size_t in_len) {
    219   uint8_t a, b, c, d;
    220   size_t pad_len = 0, len = 0, max_len, i;
    221   uint32_t l;
    222 
    223   if (!EVP_DecodedLength(&max_len, in_len) || max_out < max_len) {
    224     return 0;
    225   }
    226 
    227   for (i = 0; i < in_len; i += 4) {
    228     a = conv_ascii2bin(*(in++));
    229     b = conv_ascii2bin(*(in++));
    230     if (i + 4 == in_len && in[1] == '=') {
    231         if (in[0] == '=') {
    232           pad_len = 2;
    233         } else {
    234           pad_len = 1;
    235         }
    236     }
    237     if (pad_len < 2) {
    238       c = conv_ascii2bin(*(in++));
    239     } else {
    240       c = 0;
    241     }
    242     if (pad_len < 1) {
    243       d = conv_ascii2bin(*(in++));
    244     } else {
    245       d = 0;
    246     }
    247     if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) {
    248       return 0;
    249     }
    250     l = ((((uint32_t)a) << 18L) | (((uint32_t)b) << 12L) |
    251          (((uint32_t)c) << 6L) | (((uint32_t)d)));
    252     *(out++) = (uint8_t)(l >> 16L) & 0xff;
    253     if (pad_len < 2) {
    254       *(out++) = (uint8_t)(l >> 8L) & 0xff;
    255     }
    256     if (pad_len < 1) {
    257       *(out++) = (uint8_t)(l) & 0xff;
    258     }
    259     len += 3 - pad_len;
    260   }
    261   *out_len = len;
    262   return 1;
    263 }
    264 
    265 void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
    266   ctx->length = 30;
    267   ctx->num = 0;
    268   ctx->line_num = 0;
    269   ctx->expect_nl = 0;
    270 }
    271 
    272 int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
    273                      const uint8_t *in, size_t in_len) {
    274   int seof = -1, eof = 0, rv = -1, v, tmp, exp_nl;
    275   uint8_t *d;
    276   unsigned i, n, ln, ret = 0;
    277 
    278   n = ctx->num;
    279   d = ctx->enc_data;
    280   ln = ctx->line_num;
    281   exp_nl = ctx->expect_nl;
    282 
    283   /* last line of input. */
    284   if (in_len == 0 || (n == 0 && conv_ascii2bin(in[0]) == B64_EOF)) {
    285     rv = 0;
    286     goto end;
    287   }
    288 
    289   /* We parse the input data */
    290   for (i = 0; i < in_len; i++) {
    291     /* If the current line is > 80 characters, scream alot */
    292     if (ln >= 80) {
    293       rv = -1;
    294       goto end;
    295     }
    296 
    297     /* Get char and put it into the buffer */
    298     tmp = *(in++);
    299     v = conv_ascii2bin(tmp);
    300     /* only save the good data :-) */
    301     if (!B64_NOT_BASE64(v)) {
    302       assert(n < sizeof(ctx->enc_data));
    303       d[n++] = tmp;
    304       ln++;
    305     } else if (v == B64_ERROR) {
    306       rv = -1;
    307       goto end;
    308     }
    309 
    310     /* have we seen a '=' which is 'definitly' the last
    311      * input line.  seof will point to the character that
    312      * holds it. and eof will hold how many characters to
    313      * chop off. */
    314     if (tmp == '=') {
    315       if (seof == -1) {
    316         seof = n;
    317       }
    318       eof++;
    319       if (eof > 2) {
    320         /* There are, at most, two equals signs at the end of base64 data. */
    321         rv = -1;
    322         goto end;
    323       }
    324     }
    325 
    326     if (v == B64_CR) {
    327       ln = 0;
    328       if (exp_nl) {
    329         continue;
    330       }
    331     }
    332 
    333     /* eoln */
    334     if (v == B64_EOLN) {
    335       ln = 0;
    336       if (exp_nl) {
    337         exp_nl = 0;
    338         continue;
    339       }
    340     }
    341     exp_nl = 0;
    342 
    343     /* If we are at the end of input and it looks like a
    344      * line, process it. */
    345     if ((i + 1) == in_len && (((n & 3) == 0) || eof)) {
    346       v = B64_EOF;
    347       /* In case things were given us in really small
    348          records (so two '=' were given in separate
    349          updates), eof may contain the incorrect number
    350          of ending bytes to skip, so let's redo the count */
    351       eof = 0;
    352       if (d[n - 1] == '=') {
    353         eof++;
    354       }
    355       if (d[n - 2] == '=') {
    356         eof++;
    357       }
    358       /* There will never be more than two '=' */
    359     }
    360 
    361     if ((v == B64_EOF && (n & 3) == 0) || n >= 64) {
    362       /* This is needed to work correctly on 64 byte input
    363        * lines.  We process the line and then need to
    364        * accept the '\n' */
    365       if (v != B64_EOF && n >= 64) {
    366         exp_nl = 1;
    367       }
    368       if (n > 0) {
    369         /* TODO(davidben): Switch this to EVP_DecodeBase64. */
    370         v = EVP_DecodeBlock(out, d, n);
    371         n = 0;
    372         if (v < 0) {
    373           rv = 0;
    374           goto end;
    375         }
    376         if (eof > v) {
    377           rv = -1;
    378           goto end;
    379         }
    380         ret += (v - eof);
    381       } else {
    382         eof = 1;
    383         v = 0;
    384       }
    385 
    386       /* This is the case where we have had a short
    387        * but valid input line */
    388       if (v < (int)ctx->length && eof) {
    389         rv = 0;
    390         goto end;
    391       } else {
    392         ctx->length = v;
    393       }
    394 
    395       if (seof >= 0) {
    396         rv = 0;
    397         goto end;
    398       }
    399       out += v;
    400     }
    401   }
    402   rv = 1;
    403 
    404 end:
    405   *out_len = ret;
    406   ctx->num = n;
    407   ctx->line_num = ln;
    408   ctx->expect_nl = exp_nl;
    409   return rv;
    410 }
    411 
    412 int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *outl) {
    413   int i;
    414 
    415   *outl = 0;
    416   if (ctx->num != 0) {
    417     /* TODO(davidben): Switch this to EVP_DecodeBase64. */
    418     i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
    419     if (i < 0) {
    420       return -1;
    421     }
    422     ctx->num = 0;
    423     *outl = i;
    424     return 1;
    425   } else {
    426     return 1;
    427   }
    428 }
    429 
    430 int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
    431   size_t dst_len;
    432 
    433   /* trim white space from the start of the line. */
    434   while (conv_ascii2bin(*src) == B64_WS && src_len > 0) {
    435     src++;
    436     src_len--;
    437   }
    438 
    439   /* strip off stuff at the end of the line
    440    * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
    441   while (src_len > 3 && B64_NOT_BASE64(conv_ascii2bin(src[src_len - 1]))) {
    442     src_len--;
    443   }
    444 
    445   if (!EVP_DecodedLength(&dst_len, src_len) || dst_len > INT_MAX) {
    446     return -1;
    447   }
    448   if (!EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) {
    449     return -1;
    450   }
    451 
    452   /* EVP_DecodeBlock does not take padding into account, so put the
    453    * NULs back in... so the caller can strip them back out. */
    454   while (dst_len % 3 != 0) {
    455     dst[dst_len++] = '\0';
    456   }
    457   assert(dst_len <= INT_MAX);
    458 
    459   return dst_len;
    460 }
    461 
    462 int EVP_EncodedLength(size_t *out_len, size_t len) {
    463   if (len + 2 < len) {
    464     return 0;
    465   }
    466   len += 2;
    467   len /= 3;
    468   if (((len << 2) >> 2) != len) {
    469     return 0;
    470   }
    471   len <<= 2;
    472   if (len + 1 < len) {
    473     return 0;
    474   }
    475   len++;
    476   *out_len = len;
    477   return 1;
    478 }
    479