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 #include <openssl/type_check.h>
     64 
     65 #include "../internal.h"
     66 
     67 
     68 /* Encoding. */
     69 
     70 static const unsigned char data_bin2ascii[65] =
     71     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     72 
     73 #define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f])
     74 
     75 OPENSSL_COMPILE_ASSERT(sizeof(((EVP_ENCODE_CTX *)(NULL))->data) % 3 == 0,
     76                        data_length_must_be_multiple_of_base64_chunk_size);
     77 
     78 int EVP_EncodedLength(size_t *out_len, size_t len) {
     79   if (len + 2 < len) {
     80     return 0;
     81   }
     82   len += 2;
     83   len /= 3;
     84 
     85   if (((len << 2) >> 2) != len) {
     86     return 0;
     87   }
     88   len <<= 2;
     89 
     90   if (len + 1 < len) {
     91     return 0;
     92   }
     93   len++;
     94 
     95   *out_len = len;
     96   return 1;
     97 }
     98 
     99 void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) {
    100   OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
    101 }
    102 
    103 void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
    104                       const uint8_t *in, size_t in_len) {
    105   size_t total = 0;
    106 
    107   *out_len = 0;
    108   if (in_len == 0) {
    109     return;
    110   }
    111 
    112   assert(ctx->data_used < sizeof(ctx->data));
    113 
    114   if (sizeof(ctx->data) - ctx->data_used > in_len) {
    115     OPENSSL_memcpy(&ctx->data[ctx->data_used], in, in_len);
    116     ctx->data_used += (unsigned)in_len;
    117     return;
    118   }
    119 
    120   if (ctx->data_used != 0) {
    121     const size_t todo = sizeof(ctx->data) - ctx->data_used;
    122     OPENSSL_memcpy(&ctx->data[ctx->data_used], in, todo);
    123     in += todo;
    124     in_len -= todo;
    125 
    126     size_t encoded = EVP_EncodeBlock(out, ctx->data, sizeof(ctx->data));
    127     ctx->data_used = 0;
    128 
    129     out += encoded;
    130     *(out++) = '\n';
    131     *out = '\0';
    132 
    133     total = encoded + 1;
    134   }
    135 
    136   while (in_len >= sizeof(ctx->data)) {
    137     size_t encoded = EVP_EncodeBlock(out, in, sizeof(ctx->data));
    138     in += sizeof(ctx->data);
    139     in_len -= sizeof(ctx->data);
    140 
    141     out += encoded;
    142     *(out++) = '\n';
    143     *out = '\0';
    144 
    145     if (total + encoded + 1 < total) {
    146       *out_len = 0;
    147       return;
    148     }
    149 
    150     total += encoded + 1;
    151   }
    152 
    153   if (in_len != 0) {
    154     OPENSSL_memcpy(ctx->data, in, in_len);
    155   }
    156 
    157   ctx->data_used = (unsigned)in_len;
    158 
    159   if (total > INT_MAX) {
    160     /* We cannot signal an error, but we can at least avoid making *out_len
    161      * negative. */
    162     total = 0;
    163   }
    164   *out_len = (int)total;
    165 }
    166 
    167 void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
    168   if (ctx->data_used == 0) {
    169     *out_len = 0;
    170     return;
    171   }
    172 
    173   size_t encoded = EVP_EncodeBlock(out, ctx->data, ctx->data_used);
    174   out[encoded++] = '\n';
    175   out[encoded] = '\0';
    176   ctx->data_used = 0;
    177 
    178   /* ctx->data_used is bounded by sizeof(ctx->data), so this does not
    179    * overflow. */
    180   assert(encoded <= INT_MAX);
    181   *out_len = (int)encoded;
    182 }
    183 
    184 size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
    185   uint32_t l;
    186   size_t remaining = src_len, ret = 0;
    187 
    188   while (remaining) {
    189     if (remaining >= 3) {
    190       l = (((uint32_t)src[0]) << 16L) | (((uint32_t)src[1]) << 8L) | src[2];
    191       *(dst++) = conv_bin2ascii(l >> 18L);
    192       *(dst++) = conv_bin2ascii(l >> 12L);
    193       *(dst++) = conv_bin2ascii(l >> 6L);
    194       *(dst++) = conv_bin2ascii(l);
    195       remaining -= 3;
    196     } else {
    197       l = ((uint32_t)src[0]) << 16L;
    198       if (remaining == 2) {
    199         l |= ((uint32_t)src[1] << 8L);
    200       }
    201 
    202       *(dst++) = conv_bin2ascii(l >> 18L);
    203       *(dst++) = conv_bin2ascii(l >> 12L);
    204       *(dst++) = (remaining == 1) ? '=' : conv_bin2ascii(l >> 6L);
    205       *(dst++) = '=';
    206       remaining = 0;
    207     }
    208     ret += 4;
    209     src += 3;
    210   }
    211 
    212   *dst = '\0';
    213   return ret;
    214 }
    215 
    216 
    217 /* Decoding. */
    218 
    219 int EVP_DecodedLength(size_t *out_len, size_t len) {
    220   if (len % 4 != 0) {
    221     return 0;
    222   }
    223 
    224   *out_len = (len / 4) * 3;
    225   return 1;
    226 }
    227 
    228 void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
    229   OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
    230 }
    231 
    232 /* kBase64ASCIIToBinData maps characters (c < 128) to their base64 value, or
    233  * else 0xff if they are invalid. As a special case, the padding character
    234  * ('=') is mapped to zero. */
    235 static const uint8_t kBase64ASCIIToBinData[128] = {
    236     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff,
    237     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    238     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff,
    239     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
    240     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
    241     0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
    242     0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
    243     0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
    244     0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
    245     0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
    246     0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
    247 };
    248 
    249 static uint8_t base64_ascii_to_bin(uint8_t a) {
    250   if (a >= 128) {
    251     return 0xFF;
    252   }
    253 
    254   return kBase64ASCIIToBinData[a];
    255 }
    256 
    257 /* base64_decode_quad decodes a single quad (i.e. four characters) of base64
    258  * data and writes up to three bytes to |out|. It sets |*out_num_bytes| to the
    259  * number of bytes written, which will be less than three if the quad ended
    260  * with padding.  It returns one on success or zero on error. */
    261 static int base64_decode_quad(uint8_t *out, size_t *out_num_bytes,
    262                               const uint8_t *in) {
    263   const uint8_t a = base64_ascii_to_bin(in[0]);
    264   const uint8_t b = base64_ascii_to_bin(in[1]);
    265   const uint8_t c = base64_ascii_to_bin(in[2]);
    266   const uint8_t d = base64_ascii_to_bin(in[3]);
    267   if (a == 0xff || b == 0xff || c == 0xff || d == 0xff) {
    268     return 0;
    269   }
    270 
    271   const uint32_t v = ((uint32_t)a) << 18 | ((uint32_t)b) << 12 |
    272                      ((uint32_t)c) << 6 | (uint32_t)d;
    273 
    274   const unsigned padding_pattern = (in[0] == '=') << 3 |
    275                                    (in[1] == '=') << 2 |
    276                                    (in[2] == '=') << 1 |
    277                                    (in[3] == '=');
    278 
    279   switch (padding_pattern) {
    280     case 0:
    281       /* The common case of no padding. */
    282       *out_num_bytes = 3;
    283       out[0] = v >> 16;
    284       out[1] = v >> 8;
    285       out[2] = v;
    286       break;
    287 
    288     case 1: /* xxx= */
    289       *out_num_bytes = 2;
    290       out[0] = v >> 16;
    291       out[1] = v >> 8;
    292       break;
    293 
    294     case 3: /* xx== */
    295       *out_num_bytes = 1;
    296       out[0] = v >> 16;
    297       break;
    298 
    299     default:
    300       return 0;
    301   }
    302 
    303   return 1;
    304 }
    305 
    306 int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
    307                      const uint8_t *in, size_t in_len) {
    308   *out_len = 0;
    309 
    310   if (ctx->error_encountered) {
    311     return -1;
    312   }
    313 
    314   size_t bytes_out = 0, i;
    315   for (i = 0; i < in_len; i++) {
    316     const char c = in[i];
    317     switch (c) {
    318       case ' ':
    319       case '\t':
    320       case '\r':
    321       case '\n':
    322         continue;
    323     }
    324 
    325     if (base64_ascii_to_bin(c) == 0xff || ctx->eof_seen) {
    326       ctx->error_encountered = 1;
    327       return -1;
    328     }
    329 
    330     ctx->data[ctx->data_used++] = c;
    331     if (ctx->data_used == 4) {
    332       size_t num_bytes_resulting;
    333       if (!base64_decode_quad(out, &num_bytes_resulting, ctx->data)) {
    334         ctx->error_encountered = 1;
    335         return -1;
    336       }
    337 
    338       ctx->data_used = 0;
    339       bytes_out += num_bytes_resulting;
    340       out += num_bytes_resulting;
    341 
    342       if (num_bytes_resulting < 3) {
    343         ctx->eof_seen = 1;
    344       }
    345     }
    346   }
    347 
    348   if (bytes_out > INT_MAX) {
    349     ctx->error_encountered = 1;
    350     *out_len = 0;
    351     return -1;
    352   }
    353   *out_len = (int)bytes_out;
    354 
    355   if (ctx->eof_seen) {
    356     return 0;
    357   }
    358 
    359   return 1;
    360 }
    361 
    362 int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
    363   *out_len = 0;
    364   if (ctx->error_encountered || ctx->data_used != 0) {
    365     return -1;
    366   }
    367 
    368   return 1;
    369 }
    370 
    371 int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out,
    372                      const uint8_t *in, size_t in_len) {
    373   *out_len = 0;
    374 
    375   if (in_len % 4 != 0) {
    376     return 0;
    377   }
    378 
    379   size_t max_len;
    380   if (!EVP_DecodedLength(&max_len, in_len) ||
    381       max_out < max_len) {
    382     return 0;
    383   }
    384 
    385   size_t i, bytes_out = 0;
    386   for (i = 0; i < in_len; i += 4) {
    387     size_t num_bytes_resulting;
    388 
    389     if (!base64_decode_quad(out, &num_bytes_resulting, &in[i])) {
    390       return 0;
    391     }
    392 
    393     bytes_out += num_bytes_resulting;
    394     out += num_bytes_resulting;
    395     if (num_bytes_resulting != 3 && i != in_len - 4) {
    396       return 0;
    397     }
    398   }
    399 
    400   *out_len = bytes_out;
    401   return 1;
    402 }
    403 
    404 int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
    405   /* Trim spaces and tabs from the beginning of the input. */
    406   while (src_len > 0) {
    407     if (src[0] != ' ' && src[0] != '\t') {
    408       break;
    409     }
    410 
    411     src++;
    412     src_len--;
    413   }
    414 
    415   /* Trim newlines, spaces and tabs from the end of the line. */
    416   while (src_len > 0) {
    417     switch (src[src_len-1]) {
    418       case ' ':
    419       case '\t':
    420       case '\r':
    421       case '\n':
    422         src_len--;
    423         continue;
    424     }
    425 
    426     break;
    427   }
    428 
    429   size_t dst_len;
    430   if (!EVP_DecodedLength(&dst_len, src_len) ||
    431       dst_len > INT_MAX ||
    432       !EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) {
    433     return -1;
    434   }
    435 
    436   /* EVP_DecodeBlock does not take padding into account, so put the
    437    * NULs back in... so the caller can strip them back out. */
    438   while (dst_len % 3 != 0) {
    439     dst[dst_len++] = '\0';
    440   }
    441   assert(dst_len <= INT_MAX);
    442 
    443   return (int)dst_len;
    444 }
    445