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 
     62 
     63 static const unsigned char data_bin2ascii[65] =
     64     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     65 
     66 #define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f])
     67 
     68 /* 64 char lines
     69  * pad input with 0
     70  * left over chars are set to =
     71  * 1 byte  => xx==
     72  * 2 bytes => xxx=
     73  * 3 bytes => xxxx
     74  */
     75 #define BIN_PER_LINE    (64/4*3)
     76 #define CHUNKS_PER_LINE (64/4)
     77 #define CHAR_PER_LINE   (64+1)
     78 
     79 /* 0xF0 is a EOLN
     80  * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
     81  * 0xF2 is EOF
     82  * 0xE0 is ignore at start of line.
     83  * 0xFF is error */
     84 
     85 #define B64_EOLN 0xF0
     86 #define B64_CR 0xF1
     87 #define B64_EOF 0xF2
     88 #define B64_WS 0xE0
     89 #define B64_ERROR 0xFF
     90 #define B64_NOT_BASE64(a) (((a) | 0x13) == 0xF3)
     91 
     92 static const uint8_t data_ascii2bin[128] = {
     93     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF0, 0xFF,
     94     0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
     95     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF,
     96     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
     97     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
     98     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
     99     0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
    100     0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    101     0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
    102     0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
    103     0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    104 };
    105 
    106 static uint8_t conv_ascii2bin(uint8_t a) {
    107   if (a >= 128) {
    108     return 0xFF;
    109   }
    110   return data_ascii2bin[a];
    111 }
    112 
    113 void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) {
    114   ctx->length = 48;
    115   ctx->num = 0;
    116   ctx->line_num = 0;
    117 }
    118 
    119 void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
    120                       const uint8_t *in, size_t in_len) {
    121   unsigned i, j;
    122   unsigned total = 0;
    123 
    124   *out_len = 0;
    125   if (in_len == 0) {
    126     return;
    127   }
    128 
    129   assert(ctx->length <= sizeof(ctx->enc_data));
    130 
    131   if (ctx->num + in_len < ctx->length) {
    132     memcpy(&ctx->enc_data[ctx->num], in, in_len);
    133     ctx->num += in_len;
    134     return;
    135   }
    136   if (ctx->num != 0) {
    137     i = ctx->length - ctx->num;
    138     memcpy(&ctx->enc_data[ctx->num], in, i);
    139     in += i;
    140     in_len -= i;
    141     j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
    142     ctx->num = 0;
    143     out += j;
    144     *(out++) = '\n';
    145     *out = '\0';
    146     total = j + 1;
    147   }
    148   while (in_len >= ctx->length) {
    149     j = EVP_EncodeBlock(out, in, ctx->length);
    150     in += ctx->length;
    151     in_len -= ctx->length;
    152     out += j;
    153     *(out++) = '\n';
    154     *out = '\0';
    155     total += j + 1;
    156   }
    157   if (in_len != 0) {
    158     memcpy(&ctx->enc_data[0], in, in_len);
    159   }
    160   ctx->num = in_len;
    161   *out_len = total;
    162 }
    163 
    164 void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
    165   unsigned ret = 0;
    166 
    167   if (ctx->num != 0) {
    168     ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
    169     out[ret++] = '\n';
    170     out[ret] = '\0';
    171     ctx->num = 0;
    172   }
    173   *out_len = ret;
    174 }
    175 
    176 size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
    177   uint32_t l;
    178   size_t remaining = src_len, ret = 0;
    179 
    180   while (remaining) {
    181     if (remaining >= 3) {
    182       l = (((uint32_t)src[0]) << 16L) | (((uint32_t)src[1]) << 8L) | src[2];
    183       *(dst++) = conv_bin2ascii(l >> 18L);
    184       *(dst++) = conv_bin2ascii(l >> 12L);
    185       *(dst++) = conv_bin2ascii(l >> 6L);
    186       *(dst++) = conv_bin2ascii(l);
    187       remaining -= 3;
    188     } else {
    189       l = ((uint32_t)src[0]) << 16L;
    190       if (remaining == 2) {
    191         l |= ((uint32_t)src[1] << 8L);
    192       }
    193 
    194       *(dst++) = conv_bin2ascii(l >> 18L);
    195       *(dst++) = conv_bin2ascii(l >> 12L);
    196       *(dst++) = (remaining == 1) ? '=' : conv_bin2ascii(l >> 6L);
    197       *(dst++) = '=';
    198       remaining = 0;
    199     }
    200     ret += 4;
    201     src += 3;
    202   }
    203 
    204   *dst = '\0';
    205   return ret;
    206 }
    207 
    208 int EVP_DecodedLength(size_t *out_len, size_t len) {
    209   if (len % 4 != 0) {
    210     return 0;
    211   }
    212   *out_len = (len / 4) * 3;
    213   return 1;
    214 }
    215 
    216 int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out,
    217                      const uint8_t *in, size_t in_len) {
    218   uint8_t a, b, c, d;
    219   size_t pad_len = 0, len = 0, max_len, i;
    220   uint32_t l;
    221 
    222   if (!EVP_DecodedLength(&max_len, in_len) || max_out < max_len) {
    223     return 0;
    224   }
    225 
    226   for (i = 0; i < in_len; i += 4) {
    227     a = conv_ascii2bin(*(in++));
    228     b = conv_ascii2bin(*(in++));
    229     if (i + 4 == in_len && in[1] == '=') {
    230         if (in[0] == '=') {
    231           pad_len = 2;
    232         } else {
    233           pad_len = 1;
    234         }
    235     }
    236     if (pad_len < 2) {
    237       c = conv_ascii2bin(*(in++));
    238     } else {
    239       c = 0;
    240     }
    241     if (pad_len < 1) {
    242       d = conv_ascii2bin(*(in++));
    243     } else {
    244       d = 0;
    245     }
    246     if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) {
    247       return 0;
    248     }
    249     l = ((((uint32_t)a) << 18L) | (((uint32_t)b) << 12L) |
    250          (((uint32_t)c) << 6L) | (((uint32_t)d)));
    251     *(out++) = (uint8_t)(l >> 16L) & 0xff;
    252     if (pad_len < 2) {
    253       *(out++) = (uint8_t)(l >> 8L) & 0xff;
    254     }
    255     if (pad_len < 1) {
    256       *(out++) = (uint8_t)(l) & 0xff;
    257     }
    258     len += 3 - pad_len;
    259   }
    260   *out_len = len;
    261   return 1;
    262 }
    263 
    264 void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
    265   ctx->length = 30;
    266   ctx->num = 0;
    267   ctx->line_num = 0;
    268   ctx->expect_nl = 0;
    269 }
    270 
    271 int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
    272                      const uint8_t *in, size_t in_len) {
    273   int seof = -1, eof = 0, rv = -1, v, tmp, exp_nl;
    274   uint8_t *d;
    275   unsigned i, n, ln, ret = 0;
    276 
    277   n = ctx->num;
    278   d = ctx->enc_data;
    279   ln = ctx->line_num;
    280   exp_nl = ctx->expect_nl;
    281 
    282   /* last line of input. */
    283   if (in_len == 0 || (n == 0 && conv_ascii2bin(in[0]) == B64_EOF)) {
    284     rv = 0;
    285     goto end;
    286   }
    287 
    288   /* We parse the input data */
    289   for (i = 0; i < in_len; i++) {
    290     /* If the current line is > 80 characters, scream alot */
    291     if (ln >= 80) {
    292       rv = -1;
    293       goto end;
    294     }
    295 
    296     /* Get char and put it into the buffer */
    297     tmp = *(in++);
    298     v = conv_ascii2bin(tmp);
    299     /* only save the good data :-) */
    300     if (!B64_NOT_BASE64(v)) {
    301       assert(n < sizeof(ctx->enc_data));
    302       d[n++] = tmp;
    303       ln++;
    304     } else if (v == B64_ERROR) {
    305       rv = -1;
    306       goto end;
    307     }
    308 
    309     /* have we seen a '=' which is 'definitly' the last
    310      * input line.  seof will point to the character that
    311      * holds it. and eof will hold how many characters to
    312      * chop off. */
    313     if (tmp == '=') {
    314       if (seof == -1) {
    315         seof = n;
    316       }
    317       eof++;
    318       if (eof > 2) {
    319         /* There are, at most, two equals signs at the end of base64 data. */
    320         rv = -1;
    321         goto end;
    322       }
    323     }
    324 
    325     if (v == B64_CR) {
    326       ln = 0;
    327       if (exp_nl) {
    328         continue;
    329       }
    330     }
    331 
    332     /* eoln */
    333     if (v == B64_EOLN) {
    334       ln = 0;
    335       if (exp_nl) {
    336         exp_nl = 0;
    337         continue;
    338       }
    339     }
    340     exp_nl = 0;
    341 
    342     /* If we are at the end of input and it looks like a
    343      * line, process it. */
    344     if ((i + 1) == in_len && (((n & 3) == 0) || eof)) {
    345       v = B64_EOF;
    346       /* In case things were given us in really small
    347          records (so two '=' were given in separate
    348          updates), eof may contain the incorrect number
    349          of ending bytes to skip, so let's redo the count */
    350       eof = 0;
    351       if (d[n - 1] == '=') {
    352         eof++;
    353       }
    354       if (d[n - 2] == '=') {
    355         eof++;
    356       }
    357       /* There will never be more than two '=' */
    358     }
    359 
    360     if ((v == B64_EOF && (n & 3) == 0) || n >= 64) {
    361       /* This is needed to work correctly on 64 byte input
    362        * lines.  We process the line and then need to
    363        * accept the '\n' */
    364       if (v != B64_EOF && n >= 64) {
    365         exp_nl = 1;
    366       }
    367       if (n > 0) {
    368         /* TODO(davidben): Switch this to EVP_DecodeBase64. */
    369         v = EVP_DecodeBlock(out, d, n);
    370         n = 0;
    371         if (v < 0) {
    372           rv = 0;
    373           goto end;
    374         }
    375         ret += (v - eof);
    376       } else {
    377         eof = 1;
    378         v = 0;
    379       }
    380 
    381       /* This is the case where we have had a short
    382        * but valid input line */
    383       if (v < (int)ctx->length && eof) {
    384         rv = 0;
    385         goto end;
    386       } else {
    387         ctx->length = v;
    388       }
    389 
    390       if (seof >= 0) {
    391         rv = 0;
    392         goto end;
    393       }
    394       out += v;
    395     }
    396   }
    397   rv = 1;
    398 
    399 end:
    400   *out_len = ret;
    401   ctx->num = n;
    402   ctx->line_num = ln;
    403   ctx->expect_nl = exp_nl;
    404   return rv;
    405 }
    406 
    407 int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *outl) {
    408   int i;
    409 
    410   *outl = 0;
    411   if (ctx->num != 0) {
    412     /* TODO(davidben): Switch this to EVP_DecodeBase64. */
    413     i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
    414     if (i < 0) {
    415       return -1;
    416     }
    417     ctx->num = 0;
    418     *outl = i;
    419     return 1;
    420   } else {
    421     return 1;
    422   }
    423 }
    424 
    425 int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
    426   size_t dst_len;
    427 
    428   /* trim white space from the start of the line. */
    429   while (conv_ascii2bin(*src) == B64_WS && src_len > 0) {
    430     src++;
    431     src_len--;
    432   }
    433 
    434   /* strip off stuff at the end of the line
    435    * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
    436   while (src_len > 3 && B64_NOT_BASE64(conv_ascii2bin(src[src_len - 1]))) {
    437     src_len--;
    438   }
    439 
    440   if (!EVP_DecodedLength(&dst_len, src_len) || dst_len > INT_MAX) {
    441     return -1;
    442   }
    443   if (!EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) {
    444     return -1;
    445   }
    446 
    447   /* EVP_DecodeBlock does not take padding into account, so put the
    448    * NULs back in... so the caller can strip them back out. */
    449   while (dst_len % 3 != 0) {
    450     dst[dst_len++] = '\0';
    451   }
    452   assert(dst_len <= INT_MAX);
    453 
    454   return dst_len;
    455 }
    456 
    457 int EVP_EncodedLength(size_t *out_len, size_t len) {
    458   if (len + 2 < len) {
    459     return 0;
    460   }
    461   len += 2;
    462   len /= 3;
    463   if (((len << 2) >> 2) != len) {
    464     return 0;
    465   }
    466   len <<= 2;
    467   if (len + 1 < len) {
    468     return 0;
    469   }
    470   len++;
    471   *out_len = len;
    472   return 1;
    473 }
    474