8 #include <botan/base64.h>     9 #include <botan/mem_ops.h>    10 #include <botan/internal/rounding.h>    11 #include <botan/internal/assert.h>    18 static const byte BIN_TO_BASE64[64] = {
    19    'A', 
'B', 
'C', 
'D', 
'E', 
'F', 
'G', 
'H', 
'I', 
'J', 
'K', 
'L', 
'M',
    20    'N', 
'O', 
'P', 
'Q', 
'R', 
'S', 
'T', 
'U', 
'V', 
'W', 
'X', 
'Y', 
'Z',
    21    'a', 
'b', 
'c', 
'd', 
'e', 
'f', 
'g', 
'h', 
'i', 
'j', 
'k', 
'l', 
'm',
    22    'n', 
'o', 
'p', 
'q', 
'r', 
's', 
't', 
'u', 
'v', 
'w', 
'x', 
'y', 
'z',
    23    '0', 
'1', 
'2', 
'3', 
'4', 
'5', 
'6', 
'7', 
'8', 
'9', 
'+', 
'/'    26 void do_base64_encode(
char out[4], 
const byte in[3])
    28    out[0] = BIN_TO_BASE64[((in[0] & 0xFC) >> 2)];
    29    out[1] = BIN_TO_BASE64[((in[0] & 0x03) << 4) | (in[1] >> 4)];
    30    out[2] = BIN_TO_BASE64[((in[1] & 0x0F) << 2) | (in[2] >> 6)];
    31    out[3] = BIN_TO_BASE64[((in[2] & 0x3F)     )];
    39                      size_t& input_consumed,
    44    size_t input_remaining = input_length;
    45    size_t output_produced = 0;
    47    while(input_remaining >= 3)
    49       do_base64_encode(out + output_produced, in + input_consumed);
    56    if(final_inputs && input_remaining)
    58       byte remainder[3] = { 0 };
    59       for(
size_t i = 0; i != input_remaining; ++i)
    60          remainder[i] = in[input_consumed + i];
    62       do_base64_encode(out + output_produced, remainder);
    64       size_t empty_bits = 8 * (3 - input_remaining);
    65       size_t index = output_produced + 4 - 1;
    66       while(empty_bits >= 8)
    72       input_consumed += input_remaining;
    76    return output_produced;
    82    std::string output((round_up<size_t>(input_length, 3) / 3) * 4, 0);
   103                      size_t& input_consumed,
   111    static const byte BASE64_TO_BIN[256] = {
   112       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
   113       0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   114       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   115       0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   116       0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35,
   117       0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
   118       0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04,
   119       0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
   120       0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
   121       0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C,
   122       0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
   123       0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
   124       0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   125       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   126       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   127       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   128       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   129       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   130       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   131       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   132       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   133       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   134       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   135       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   136       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   137       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
   139    byte* out_ptr = output;
   141    size_t decode_buf_pos = 0;
   142    size_t final_truncate = 0;
   146    for(
size_t i = 0; i != input_length; ++i)
   148       const byte bin = BASE64_TO_BIN[
static_cast<byte>(input[i])];
   152          decode_buf[decode_buf_pos] = bin;
   155       else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
   157          std::string bad_char(1, input[i]);
   160          else if(bad_char == 
"\n")
   162          else if(bad_char == 
"\r")
   165          throw std::invalid_argument(
   166            std::string(
"base64_decode: invalid base64 character '") +
   173       if(final_inputs && (i == input_length - 1))
   177             for(
size_t i = decode_buf_pos; i != 4; ++i)
   179             final_truncate = (4 - decode_buf_pos);
   184       if(decode_buf_pos == 4)
   186          out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4);
   187          out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2);
   188          out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3];
   192          input_consumed = i+1;
   196    while(input_consumed < input_length &&
   197          BASE64_TO_BIN[static_cast<byte>(input[input_consumed])] == 0x80)
   202    size_t written = (out_ptr - output) - final_truncate;
   214                                   consumed, 
true, ignore_ws);
   216    if(consumed != input_length)
   217       throw std::invalid_argument(
"base64_decode: input did not have full bytes");
   223                      const std::string& input,
   226    return base64_decode(output, &input[0], input.length(), ignore_ws);
 
size_t base64_decode(byte output[], const char input[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws)
void clear_mem(T *ptr, size_t n)
#define BOTAN_ASSERT_EQUAL(value1, value2, msg)
size_t base64_encode(char out[], const byte in[], size_t input_length, size_t &input_consumed, bool final_inputs)