aboutsummaryrefslogtreecommitdiffstats
path: root/src/codec/base64/base64.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-09-28 22:14:54 +0000
committerlloyd <[email protected]>2008-09-28 22:14:54 +0000
commit31204986023619c385d378e79a6511bb81ef7b78 (patch)
treece272a6585dc070f750f6875b0450d53145b935d /src/codec/base64/base64.cpp
parent42c0fe76ab6d9625d0e51c68b8dd187322c991bd (diff)
Move almost all of the ASN.1, BER, and DER codec related code into new
module asn1 Move hex and base64 codecs into new codecs directory. Also move zlib and bzip2 to codecs from compress.
Diffstat (limited to 'src/codec/base64/base64.cpp')
-rw-r--r--src/codec/base64/base64.cpp225
1 files changed, 225 insertions, 0 deletions
diff --git a/src/codec/base64/base64.cpp b/src/codec/base64/base64.cpp
new file mode 100644
index 000000000..0e01d94f3
--- /dev/null
+++ b/src/codec/base64/base64.cpp
@@ -0,0 +1,225 @@
+/*************************************************
+* Base64 Encoder/Decoder Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/base64.h>
+#include <botan/charset.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*************************************************
+* Base64_Encoder Constructor *
+*************************************************/
+Base64_Encoder::Base64_Encoder(bool breaks, u32bit length, bool t_n) :
+ line_length(breaks ? length : 0), trailing_newline(t_n)
+ {
+ in.create(48);
+ out.create(4);
+
+ counter = position = 0;
+ }
+
+/*************************************************
+* Base64 Encoding Operation *
+*************************************************/
+void Base64_Encoder::encode(const byte in[3], byte out[4])
+ {
+ out[0] = BIN_TO_BASE64[((in[0] & 0xFC) >> 2)];
+ out[1] = BIN_TO_BASE64[((in[0] & 0x03) << 4) | (in[1] >> 4)];
+ out[2] = BIN_TO_BASE64[((in[1] & 0x0F) << 2) | (in[2] >> 6)];
+ out[3] = BIN_TO_BASE64[((in[2] & 0x3F) )];
+ }
+
+/*************************************************
+* Encode and send a block *
+*************************************************/
+void Base64_Encoder::encode_and_send(const byte block[], u32bit length)
+ {
+ for(u32bit j = 0; j != length; j += 3)
+ {
+ encode(block + j, out);
+ do_output(out, 4);
+ }
+ }
+
+/*************************************************
+* Handle the output *
+*************************************************/
+void Base64_Encoder::do_output(const byte input[], u32bit length)
+ {
+ if(line_length == 0)
+ send(input, length);
+ else
+ {
+ u32bit remaining = length, offset = 0;
+ while(remaining)
+ {
+ u32bit sent = std::min(line_length - counter, remaining);
+ send(input + offset, sent);
+ counter += sent;
+ remaining -= sent;
+ offset += sent;
+ if(counter == line_length)
+ {
+ send('\n');
+ counter = 0;
+ }
+ }
+ }
+ }
+
+/*************************************************
+* Convert some data into Base64 *
+*************************************************/
+void Base64_Encoder::write(const byte input[], u32bit length)
+ {
+ in.copy(position, input, length);
+ if(position + length >= in.size())
+ {
+ encode_and_send(in, in.size());
+ input += (in.size() - position);
+ length -= (in.size() - position);
+ while(length >= in.size())
+ {
+ encode_and_send(input, in.size());
+ input += in.size();
+ length -= in.size();
+ }
+ in.copy(input, length);
+ position = 0;
+ }
+ position += length;
+ }
+
+/*************************************************
+* Flush buffers *
+*************************************************/
+void Base64_Encoder::end_msg()
+ {
+ u32bit start_of_last_block = 3 * (position / 3),
+ left_over = position % 3;
+ encode_and_send(in, start_of_last_block);
+
+ if(left_over)
+ {
+ SecureBuffer<byte, 3> remainder(in + start_of_last_block, left_over);
+
+ encode(remainder, out);
+
+ u32bit empty_bits = 8 * (3 - left_over), index = 4 - 1;
+ while(empty_bits >= 8)
+ {
+ out[index--] = '=';
+ empty_bits -= 6;
+ }
+
+ do_output(out, 4);
+ }
+
+ if(trailing_newline || (counter && line_length))
+ send('\n');
+
+ counter = position = 0;
+ }
+
+/*************************************************
+* Base64_Decoder Constructor *
+*************************************************/
+Base64_Decoder::Base64_Decoder(Decoder_Checking c) : checking(c)
+ {
+ in.create(48);
+ out.create(3);
+ position = 0;
+ }
+
+/*************************************************
+* Check if a character is a valid Base64 char *
+*************************************************/
+bool Base64_Decoder::is_valid(byte in)
+ {
+ return (BASE64_TO_BIN[in] != 0x80);
+ }
+
+/*************************************************
+* Base64 Decoding Operation *
+*************************************************/
+void Base64_Decoder::decode(const byte in[4], byte out[3])
+ {
+ out[0] = ((BASE64_TO_BIN[in[0]] << 2) | (BASE64_TO_BIN[in[1]] >> 4));
+ out[1] = ((BASE64_TO_BIN[in[1]] << 4) | (BASE64_TO_BIN[in[2]] >> 2));
+ out[2] = ((BASE64_TO_BIN[in[2]] << 6) | (BASE64_TO_BIN[in[3]]));
+ }
+
+/*************************************************
+* Decode and send a block *
+*************************************************/
+void Base64_Decoder::decode_and_send(const byte block[], u32bit length)
+ {
+ for(u32bit j = 0; j != length; j += 4)
+ {
+ decode(block + j, out);
+ send(out, 3);
+ }
+ }
+
+/*************************************************
+* Handle processing an invalid character *
+*************************************************/
+void Base64_Decoder::handle_bad_char(byte c)
+ {
+ if(c == '=' || checking == NONE)
+ return;
+
+ if((checking == IGNORE_WS) && Charset::is_space(c))
+ return;
+
+ throw Decoding_Error(
+ std::string("Base64_Decoder: Invalid base64 character '") +
+ static_cast<char>(c) + "'"
+ );
+ }
+
+/*************************************************
+* Convert some data from Base64 *
+*************************************************/
+void Base64_Decoder::write(const byte input[], u32bit length)
+ {
+ for(u32bit j = 0; j != length; ++j)
+ {
+ if(is_valid(input[j]))
+ in[position++] = input[j];
+ else
+ handle_bad_char(input[j]);
+
+ if(position == in.size())
+ {
+ decode_and_send(in, in.size());
+ position = 0;
+ }
+ }
+ }
+
+/*************************************************
+* Flush buffers *
+*************************************************/
+void Base64_Decoder::end_msg()
+ {
+ if(position != 0)
+ {
+ u32bit start_of_last_block = 4 * (position / 4),
+ left_over = position % 4;
+ decode_and_send(in, start_of_last_block);
+
+ if(left_over)
+ {
+ SecureBuffer<byte, 4> remainder(in + start_of_last_block, left_over);
+ decode(remainder, out);
+ send(out, ((left_over == 1) ? (1) : (left_over - 1)));
+ }
+ }
+ position = 0;
+ }
+
+}