/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#include <openssl/base64.h>

#include <assert.h>


static const unsigned char data_bin2ascii[65] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

#define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f])
#define conv_ascii2bin(a) (data_ascii2bin[(a) & 0x7f])

/* 64 char lines
 * pad input with 0
 * left over chars are set to =
 * 1 byte  => xx==
 * 2 bytes => xxx=
 * 3 bytes => xxxx
 */
#define BIN_PER_LINE    (64/4*3)
#define CHUNKS_PER_LINE (64/4)
#define CHAR_PER_LINE   (64+1)

/* 0xF0 is a EOLN
 * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
 * 0xF2 is EOF
 * 0xE0 is ignore at start of line.
 * 0xFF is error */

#define B64_EOLN 0xF0
#define B64_CR 0xF1
#define B64_EOF 0xF2
#define B64_WS 0xE0
#define B64_ERROR 0xFF
#define B64_NOT_BASE64(a) (((a) | 0x13) == 0xF3)

static const unsigned char data_ascii2bin[128] = {
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF0, 0xFF,
    0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
    0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
    0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
    0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
    0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};

void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) {
  ctx->length = 48;
  ctx->num = 0;
  ctx->line_num = 0;
}

void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
                      const uint8_t *in, size_t in_len) {
  unsigned i, j;
  unsigned total = 0;

  *out_len = 0;
  if (in_len == 0) {
    return;
  }

  assert(ctx->length <= sizeof(ctx->enc_data));

  if ((ctx->num + in_len) < ctx->length) {
    memcpy(&ctx->enc_data[ctx->num], in, in_len);
    ctx->num += in_len;
    return;
  }
  if (ctx->num != 0) {
    i = ctx->length - ctx->num;
    memcpy(&ctx->enc_data[ctx->num], in, i);
    in += i;
    in_len -= i;
    j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
    ctx->num = 0;
    out += j;
    *(out++) = '\n';
    *out = '\0';
    total = j + 1;
  }
  while (in_len >= ctx->length) {
    j = EVP_EncodeBlock(out, in, ctx->length);
    in += ctx->length;
    in_len -= ctx->length;
    out += j;
    *(out++) = '\n';
    *out = '\0';
    total += j + 1;
  }
  if (in_len != 0) {
    memcpy(&ctx->enc_data[0], in, in_len);
  }
  ctx->num = in_len;
  *out_len = total;
}

void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
  unsigned ret = 0;

  if (ctx->num != 0) {
    ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
    out[ret++] = '\n';
    out[ret] = '\0';
    ctx->num = 0;
  }
  *out_len = ret;
}

size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
  unsigned long l;
  size_t i, ret = 0;

  for (i = src_len; i > 0; i -= 3) {
    if (i >= 3) {
      l = (((unsigned long)src[0]) << 16L) | (((unsigned long)src[1]) << 8L) | src[2];
      *(dst++) = conv_bin2ascii(l >> 18L);
      *(dst++) = conv_bin2ascii(l >> 12L);
      *(dst++) = conv_bin2ascii(l >> 6L);
      *(dst++) = conv_bin2ascii(l);
    } else {
      l = ((unsigned long)src[0]) << 16L;
      if (i == 2) {
        l |= ((unsigned long)src[1] << 8L);
      }

      *(dst++) = conv_bin2ascii(l >> 18L);
      *(dst++) = conv_bin2ascii(l >> 12L);
      *(dst++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L);
      *(dst++) = '=';
    }
    ret += 4;
    src += 3;
  }

  *dst = '\0';
  return ret;
}

void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
  ctx->length = 30;
  ctx->num = 0;
  ctx->line_num = 0;
  ctx->expect_nl = 0;
}

int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
                     const uint8_t *in, size_t in_len) {
  int seof = -1, eof = 0, rv = -1, v, tmp, exp_nl;
  uint8_t *d;
  unsigned i, n, ln, ret = 0;

  n = ctx->num;
  d = ctx->enc_data;
  ln = ctx->line_num;
  exp_nl = ctx->expect_nl;

  /* last line of input. */
  if (in_len == 0 || (n == 0 && conv_ascii2bin(in[0]) == B64_EOF)) {
    rv = 0;
    goto end;
  }

  /* We parse the input data */
  for (i = 0; i < in_len; i++) {
    /* If the current line is > 80 characters, scream alot */
    if (ln >= 80) {
      rv = -1;
      goto end;
    }

    /* Get char and put it into the buffer */
    tmp = *(in++);
    v = conv_ascii2bin(tmp);
    /* only save the good data :-) */
    if (!B64_NOT_BASE64(v)) {
      assert(n < sizeof(ctx->enc_data));
      d[n++] = tmp;
      ln++;
    } else if (v == B64_ERROR) {
      rv = -1;
      goto end;
    }

    /* have we seen a '=' which is 'definitly' the last
     * input line.  seof will point to the character that
     * holds it. and eof will hold how many characters to
     * chop off. */
    if (tmp == '=') {
      if (seof == -1) {
        seof = n;
      }
      eof++;
    }

    if (v == B64_CR) {
      ln = 0;
      if (exp_nl) {
        continue;
      }
    }

    /* eoln */
    if (v == B64_EOLN) {
      ln = 0;
      if (exp_nl) {
        exp_nl = 0;
        continue;
      }
    }
    exp_nl = 0;

    /* If we are at the end of input and it looks like a
     * line, process it. */
    if ((i + 1) == in_len && (((n & 3) == 0) || eof)) {
      v = B64_EOF;
      /* In case things were given us in really small
         records (so two '=' were given in separate
         updates), eof may contain the incorrect number
         of ending bytes to skip, so let's redo the count */
      eof = 0;
      if (d[n - 1] == '=') {
        eof++;
      }
      if (d[n - 2] == '=') {
        eof++;
      }
      /* There will never be more than two '=' */
    }

    if ((v == B64_EOF && (n & 3) == 0) || n >= 64) {
      /* This is needed to work correctly on 64 byte input
       * lines.  We process the line and then need to
       * accept the '\n' */
      if (v != B64_EOF && n >= 64) {
        exp_nl = 1;
      }
      if (n > 0) {
        v = EVP_DecodeBlock(out, d, n);
        n = 0;
        if (v < 0) {
          rv = 0;
          goto end;
        }
        ret += (v - eof);
      } else {
        eof = 1;
        v = 0;
      }

      /* This is the case where we have had a short
       * but valid input line */
      if (v < (int)ctx->length && eof) {
        rv = 0;
        goto end;
      } else {
        ctx->length = v;
      }

      if (seof >= 0) {
        rv = 0;
        goto end;
      }
      out += v;
    }
  }
  rv = 1;

end:
  *out_len = ret;
  ctx->num = n;
  ctx->line_num = ln;
  ctx->expect_nl = exp_nl;
  return rv;
}

int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *outl) {
  int i;

  *outl = 0;
  if (ctx->num != 0) {
    i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
    if (i < 0) {
      return -1;
    }
    ctx->num = 0;
    *outl = i;
    return 1;
  } else {
    return 1;
  }
}

size_t EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
  int a, b, c, d;
  unsigned long l;
  size_t i, ret = 0;

  /* trim white space from the start of the line. */
  while (conv_ascii2bin(*src) == B64_WS && src_len > 0) {
    src++;
    src_len--;
  }

  /* strip off stuff at the end of the line
   * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
  while (src_len > 3 && B64_NOT_BASE64(conv_ascii2bin(src[src_len - 1]))) {
    src_len--;
  }

  if (src_len % 4 != 0) {
    return -1;
  }

  for (i = 0; i < src_len; i += 4) {
    a = conv_ascii2bin(*(src++));
    b = conv_ascii2bin(*(src++));
    c = conv_ascii2bin(*(src++));
    d = conv_ascii2bin(*(src++));
    if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) {
      return -1;
    }
    l = ((((unsigned long)a) << 18L) | (((unsigned long)b) << 12L) |
         (((unsigned long)c) << 6L) | (((unsigned long)d)));
    *(dst++) = (uint8_t)(l >> 16L) & 0xff;
    *(dst++) = (uint8_t)(l >> 8L) & 0xff;
    *(dst++) = (uint8_t)(l) & 0xff;
    ret += 3;
  }

  return ret;
}
