aboutsummaryrefslogtreecommitdiffstats
path: root/src/codec
diff options
context:
space:
mode:
Diffstat (limited to 'src/codec')
-rw-r--r--src/codec/base64/base64.cpp225
-rw-r--r--src/codec/base64/base64.h60
-rw-r--r--src/codec/base64/modinfo.txt10
-rw-r--r--src/codec/bzip2/bzip2.cpp271
-rw-r--r--src/codec/bzip2/bzip2.h59
-rw-r--r--src/codec/bzip2/modinfo.txt17
-rw-r--r--src/codec/hex/hex.cpp188
-rw-r--r--src/codec/hex/hex.h64
-rw-r--r--src/codec/hex/modinfo.txt10
-rw-r--r--src/codec/zlib/modinfo.txt19
-rw-r--r--src/codec/zlib/zlib.cpp283
-rw-r--r--src/codec/zlib/zlib.h56
12 files changed, 1262 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;
+ }
+
+}
diff --git a/src/codec/base64/base64.h b/src/codec/base64/base64.h
new file mode 100644
index 000000000..0003875a6
--- /dev/null
+++ b/src/codec/base64/base64.h
@@ -0,0 +1,60 @@
+/*************************************************
+* Base64 Encoder/Decoder Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_BASE64_H__
+#define BOTAN_BASE64_H__
+
+#include <botan/filter.h>
+#include <botan/enums.h>
+
+namespace Botan {
+
+/*************************************************
+* Base64 Encoder *
+*************************************************/
+class BOTAN_DLL Base64_Encoder : public Filter
+ {
+ public:
+ static void encode(const byte[3], byte[4]);
+
+ void write(const byte[], u32bit);
+ void end_msg();
+ Base64_Encoder(bool = false, u32bit = 72, bool = false);
+ private:
+ void encode_and_send(const byte[], u32bit);
+ void do_output(const byte[], u32bit);
+ static const byte BIN_TO_BASE64[64];
+
+ const u32bit line_length;
+ const bool trailing_newline;
+ SecureVector<byte> in, out;
+ u32bit position, counter;
+ };
+
+/*************************************************
+* Base64 Decoder *
+*************************************************/
+class BOTAN_DLL Base64_Decoder : public Filter
+ {
+ public:
+ static void decode(const byte[4], byte[3]);
+ static bool is_valid(byte);
+
+ void write(const byte[], u32bit);
+ void end_msg();
+ Base64_Decoder(Decoder_Checking = NONE);
+ private:
+ void decode_and_send(const byte[], u32bit);
+ void handle_bad_char(byte);
+ static const byte BASE64_TO_BIN[256];
+
+ const Decoder_Checking checking;
+ SecureVector<byte> in, out;
+ u32bit position;
+ };
+
+}
+
+#endif
diff --git a/src/codec/base64/modinfo.txt b/src/codec/base64/modinfo.txt
new file mode 100644
index 000000000..4e7b38584
--- /dev/null
+++ b/src/codec/base64/modinfo.txt
@@ -0,0 +1,10 @@
+realname "Base64 Codec"
+
+define BASE64_CODEC
+
+load_on auto
+
+<add>
+base64.cpp
+base64.h
+</add>
diff --git a/src/codec/bzip2/bzip2.cpp b/src/codec/bzip2/bzip2.cpp
new file mode 100644
index 000000000..712dacd7d
--- /dev/null
+++ b/src/codec/bzip2/bzip2.cpp
@@ -0,0 +1,271 @@
+/*************************************************
+* Bzip Compressor Source File *
+* (C) 2001 Peter J Jones *
+* 2001-2007 Jack Lloyd *
+* 2006 Matt Johnston *
+*************************************************/
+
+#include <botan/bzip2.h>
+#include <map>
+#include <cstring>
+#define BZ_NO_STDIO
+#include <bzlib.h>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Allocation Information for Bzip *
+*************************************************/
+class Bzip_Alloc_Info
+ {
+ public:
+ std::map<void*, u32bit> current_allocs;
+ Allocator* alloc;
+
+ Bzip_Alloc_Info() { alloc = Allocator::get(false); }
+ };
+
+/*************************************************
+* Allocation Function for Bzip *
+*************************************************/
+void* bzip_malloc(void* info_ptr, int n, int size)
+ {
+ Bzip_Alloc_Info* info = static_cast<Bzip_Alloc_Info*>(info_ptr);
+ void* ptr = info->alloc->allocate(n * size);
+ info->current_allocs[ptr] = n * size;
+ return ptr;
+ }
+
+/*************************************************
+* Allocation Function for Bzip *
+*************************************************/
+void bzip_free(void* info_ptr, void* ptr)
+ {
+ Bzip_Alloc_Info* info = static_cast<Bzip_Alloc_Info*>(info_ptr);
+ std::map<void*, u32bit>::const_iterator i = info->current_allocs.find(ptr);
+ if(i == info->current_allocs.end())
+ throw Invalid_Argument("bzip_free: Got pointer not allocated by us");
+ info->alloc->deallocate(ptr, i->second);
+ }
+
+}
+
+/*************************************************
+* Wrapper Type for Bzip2 Stream *
+*************************************************/
+class Bzip_Stream
+ {
+ public:
+ bz_stream stream;
+
+ Bzip_Stream()
+ {
+ std::memset(&stream, 0, sizeof(bz_stream));
+ stream.bzalloc = bzip_malloc;
+ stream.bzfree = bzip_free;
+ stream.opaque = new Bzip_Alloc_Info;
+ }
+ ~Bzip_Stream()
+ {
+ Bzip_Alloc_Info* info = static_cast<Bzip_Alloc_Info*>(stream.opaque);
+ delete info;
+ std::memset(&stream, 0, sizeof(bz_stream));
+ }
+ };
+
+/*************************************************
+* Bzip_Compression Constructor *
+*************************************************/
+Bzip_Compression::Bzip_Compression(u32bit l) :
+ level((l >= 9) ? 9 : l), buffer(DEFAULT_BUFFERSIZE)
+ {
+ bz = 0;
+ }
+
+/*************************************************
+* Start Compressing with Bzip *
+*************************************************/
+void Bzip_Compression::start_msg()
+ {
+ clear();
+ bz = new Bzip_Stream;
+ if(BZ2_bzCompressInit(&(bz->stream), level, 0, 0) != BZ_OK)
+ throw Exception("Bzip_Compression: Memory allocation error");
+ }
+
+/*************************************************
+* Compress Input with Bzip *
+*************************************************/
+void Bzip_Compression::write(const byte input[], u32bit length)
+ {
+ bz->stream.next_in = reinterpret_cast<char*>(const_cast<byte*>(input));
+ bz->stream.avail_in = length;
+
+ while(bz->stream.avail_in != 0)
+ {
+ bz->stream.next_out = reinterpret_cast<char*>(buffer.begin());
+ bz->stream.avail_out = buffer.size();
+ BZ2_bzCompress(&(bz->stream), BZ_RUN);
+ send(buffer, buffer.size() - bz->stream.avail_out);
+ }
+ }
+
+/*************************************************
+* Finish Compressing with Bzip *
+*************************************************/
+void Bzip_Compression::end_msg()
+ {
+ bz->stream.next_in = 0;
+ bz->stream.avail_in = 0;
+
+ int rc = BZ_OK;
+ while(rc != BZ_STREAM_END)
+ {
+ bz->stream.next_out = reinterpret_cast<char*>(buffer.begin());
+ bz->stream.avail_out = buffer.size();
+ rc = BZ2_bzCompress(&(bz->stream), BZ_FINISH);
+ send(buffer, buffer.size() - bz->stream.avail_out);
+ }
+ clear();
+ }
+
+/*************************************************
+* Flush the Bzip Compressor *
+*************************************************/
+void Bzip_Compression::flush()
+ {
+ bz->stream.next_in = 0;
+ bz->stream.avail_in = 0;
+
+ int rc = BZ_OK;
+ while(rc != BZ_RUN_OK)
+ {
+ bz->stream.next_out = reinterpret_cast<char*>(buffer.begin());
+ bz->stream.avail_out = buffer.size();
+ rc = BZ2_bzCompress(&(bz->stream), BZ_FLUSH);
+ send(buffer, buffer.size() - bz->stream.avail_out);
+ }
+ }
+
+/*************************************************
+* Clean up Compression Context *
+*************************************************/
+void Bzip_Compression::clear()
+ {
+ if(!bz) return;
+ BZ2_bzCompressEnd(&(bz->stream));
+ delete bz;
+ bz = 0;
+ }
+
+/*************************************************
+* Bzip_Decompression Constructor *
+*************************************************/
+Bzip_Decompression::Bzip_Decompression(bool s) :
+ small_mem(s), buffer(DEFAULT_BUFFERSIZE)
+ {
+ no_writes = true;
+ bz = 0;
+ }
+
+/*************************************************
+* Decompress Input with Bzip *
+*************************************************/
+void Bzip_Decompression::write(const byte input_arr[], u32bit length)
+ {
+ if(length) no_writes = false;
+
+ char* input = reinterpret_cast<char*>(const_cast<byte*>(input_arr));
+
+ bz->stream.next_in = input;
+ bz->stream.avail_in = length;
+
+ while(bz->stream.avail_in != 0)
+ {
+ bz->stream.next_out = reinterpret_cast<char*>(buffer.begin());
+ bz->stream.avail_out = buffer.size();
+
+ int rc = BZ2_bzDecompress(&(bz->stream));
+
+ if(rc != BZ_OK && rc != BZ_STREAM_END)
+ {
+ clear();
+ if(rc == BZ_DATA_ERROR)
+ throw Decoding_Error("Bzip_Decompression: Data integrity error");
+ if(rc == BZ_DATA_ERROR_MAGIC)
+ throw Decoding_Error("Bzip_Decompression: Invalid input");
+ if(rc == BZ_MEM_ERROR)
+ throw Exception("Bzip_Decompression: Memory allocation error");
+ throw Exception("Bzip_Decompression: Unknown decompress error");
+ }
+
+ send(buffer, buffer.size() - bz->stream.avail_out);
+
+ if(rc == BZ_STREAM_END)
+ {
+ u32bit read_from_block = length - bz->stream.avail_in;
+ start_msg();
+ bz->stream.next_in = input + read_from_block;
+ bz->stream.avail_in = length - read_from_block;
+ input += read_from_block;
+ length -= read_from_block;
+ }
+ }
+ }
+
+/*************************************************
+* Start Decompressing with Bzip *
+*************************************************/
+void Bzip_Decompression::start_msg()
+ {
+ clear();
+ bz = new Bzip_Stream;
+
+ if(BZ2_bzDecompressInit(&(bz->stream), 0, small_mem) != BZ_OK)
+ throw Exception("Bzip_Decompression: Memory allocation error");
+
+ no_writes = true;
+ }
+
+/*************************************************
+* Finish Decompressing with Bzip *
+*************************************************/
+void Bzip_Decompression::end_msg()
+ {
+ if(no_writes) return;
+ bz->stream.next_in = 0;
+ bz->stream.avail_in = 0;
+
+ int rc = BZ_OK;
+ while(rc != BZ_STREAM_END)
+ {
+ bz->stream.next_out = reinterpret_cast<char*>(buffer.begin());
+ bz->stream.avail_out = buffer.size();
+ rc = BZ2_bzDecompress(&(bz->stream));
+
+ if(rc != BZ_OK && rc != BZ_STREAM_END)
+ {
+ clear();
+ throw Exception("Bzip_Decompression: Error finalizing decompression");
+ }
+
+ send(buffer, buffer.size() - bz->stream.avail_out);
+ }
+
+ clear();
+ }
+
+/*************************************************
+* Clean up Decompression Context *
+*************************************************/
+void Bzip_Decompression::clear()
+ {
+ if(!bz) return;
+ BZ2_bzDecompressEnd(&(bz->stream));
+ delete bz;
+ bz = 0;
+ }
+
+}
diff --git a/src/codec/bzip2/bzip2.h b/src/codec/bzip2/bzip2.h
new file mode 100644
index 000000000..1244924ca
--- /dev/null
+++ b/src/codec/bzip2/bzip2.h
@@ -0,0 +1,59 @@
+/*************************************************
+* Bzip Compressor Header File *
+* (C) 2001 Peter J Jones *
+* 2001-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_BZIP2_H__
+#define BOTAN_BZIP2_H__
+
+#include <botan/filter.h>
+
+namespace Botan {
+
+/*************************************************
+* Bzip Compression Filter *
+*************************************************/
+class Bzip_Compression : public Filter
+ {
+ public:
+ void write(const byte input[], u32bit length);
+ void start_msg();
+ void end_msg();
+
+ void flush();
+
+ Bzip_Compression(u32bit = 9);
+ ~Bzip_Compression() { clear(); }
+ private:
+ void clear();
+
+ const u32bit level;
+ SecureVector<byte> buffer;
+ class Bzip_Stream* bz;
+ };
+
+/*************************************************
+* Bzip Decompression Filter *
+*************************************************/
+class Bzip_Decompression : public Filter
+ {
+ public:
+ void write(const byte input[], u32bit length);
+ void start_msg();
+ void end_msg();
+
+ Bzip_Decompression(bool = false);
+ ~Bzip_Decompression() { clear(); }
+ private:
+ void clear();
+
+ const bool small_mem;
+ SecureVector<byte> buffer;
+ class Bzip_Stream* bz;
+ bool no_writes;
+ };
+
+}
+
+#endif
diff --git a/src/codec/bzip2/modinfo.txt b/src/codec/bzip2/modinfo.txt
new file mode 100644
index 000000000..efedc097f
--- /dev/null
+++ b/src/codec/bzip2/modinfo.txt
@@ -0,0 +1,17 @@
+# This module was written by Peter J. Jones
+
+realname "Bzip2 Compressor"
+
+define COMPRESSOR_BZIP2
+modset compression
+
+load_on request
+
+<add>
+bzip2.h
+bzip2.cpp
+</add>
+
+<libs>
+all -> bz2
+</libs>
diff --git a/src/codec/hex/hex.cpp b/src/codec/hex/hex.cpp
new file mode 100644
index 000000000..afb082f76
--- /dev/null
+++ b/src/codec/hex/hex.cpp
@@ -0,0 +1,188 @@
+/*************************************************
+* Hex Encoder/Decoder Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/hex.h>
+#include <botan/parsing.h>
+#include <botan/charset.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*************************************************
+* Hex_Encoder Constructor *
+*************************************************/
+Hex_Encoder::Hex_Encoder(bool breaks, u32bit length, Case c) :
+ casing(c), line_length(breaks ? length : 0)
+ {
+ in.create(64);
+ out.create(2*in.size());
+ counter = position = 0;
+ }
+
+/*************************************************
+* Hex_Encoder Constructor *
+*************************************************/
+Hex_Encoder::Hex_Encoder(Case c) : casing(c), line_length(0)
+ {
+ in.create(64);
+ out.create(2*in.size());
+ counter = position = 0;
+ }
+
+/*************************************************
+* Hex Encoding Operation *
+*************************************************/
+void Hex_Encoder::encode(byte in, byte out[2], Hex_Encoder::Case casing)
+ {
+ const byte* BIN_TO_HEX = ((casing == Uppercase) ? BIN_TO_HEX_UPPER :
+ BIN_TO_HEX_LOWER);
+
+ out[0] = BIN_TO_HEX[((in >> 4) & 0x0F)];
+ out[1] = BIN_TO_HEX[((in ) & 0x0F)];
+ }
+
+/*************************************************
+* Encode and send a block *
+*************************************************/
+void Hex_Encoder::encode_and_send(const byte block[], u32bit length)
+ {
+ for(u32bit j = 0; j != length; ++j)
+ encode(block[j], out + 2*j, casing);
+
+ if(line_length == 0)
+ send(out, 2*length);
+ else
+ {
+ u32bit remaining = 2*length, offset = 0;
+ while(remaining)
+ {
+ u32bit sent = std::min(line_length - counter, remaining);
+ send(out + offset, sent);
+ counter += sent;
+ remaining -= sent;
+ offset += sent;
+ if(counter == line_length)
+ {
+ send('\n');
+ counter = 0;
+ }
+ }
+ }
+ }
+
+/*************************************************
+* Convert some data into hex format *
+*************************************************/
+void Hex_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 Hex_Encoder::end_msg()
+ {
+ encode_and_send(in, position);
+ if(counter && line_length)
+ send('\n');
+ counter = position = 0;
+ }
+
+/*************************************************
+* Hex_Decoder Constructor *
+*************************************************/
+Hex_Decoder::Hex_Decoder(Decoder_Checking c) : checking(c)
+ {
+ in.create(64);
+ out.create(in.size() / 2);
+ position = 0;
+ }
+
+/*************************************************
+* Check if a character is a valid hex char *
+*************************************************/
+bool Hex_Decoder::is_valid(byte in)
+ {
+ return (HEX_TO_BIN[in] != 0x80);
+ }
+
+/*************************************************
+* Handle processing an invalid character *
+*************************************************/
+void Hex_Decoder::handle_bad_char(byte c)
+ {
+ if(checking == NONE)
+ return;
+
+ if((checking == IGNORE_WS) && Charset::is_space(c))
+ return;
+
+ throw Decoding_Error("Hex_Decoder: Invalid hex character: " +
+ to_string(c));
+ }
+
+/*************************************************
+* Hex Decoding Operation *
+*************************************************/
+byte Hex_Decoder::decode(const byte hex[2])
+ {
+ return ((HEX_TO_BIN[hex[0]] << 4) | HEX_TO_BIN[hex[1]]);
+ }
+
+/*************************************************
+* Decode and send a block *
+*************************************************/
+void Hex_Decoder::decode_and_send(const byte block[], u32bit length)
+ {
+ for(u32bit j = 0; j != length / 2; ++j)
+ out[j] = decode(block + 2*j);
+ send(out, length / 2);
+ }
+
+/*************************************************
+* Convert some data from hex format *
+*************************************************/
+void Hex_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 Hex_Decoder::end_msg()
+ {
+ decode_and_send(in, position);
+ position = 0;
+ }
+
+}
diff --git a/src/codec/hex/hex.h b/src/codec/hex/hex.h
new file mode 100644
index 000000000..0ecddb588
--- /dev/null
+++ b/src/codec/hex/hex.h
@@ -0,0 +1,64 @@
+/*************************************************
+* Hex Encoder/Decoder Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_HEX_H__
+#define BOTAN_HEX_H__
+
+#include <botan/filter.h>
+#include <botan/enums.h>
+
+namespace Botan {
+
+/*************************************************
+* Hex Encoder *
+*************************************************/
+class BOTAN_DLL Hex_Encoder : public Filter
+ {
+ public:
+ enum Case { Uppercase, Lowercase };
+ static void encode(byte, byte[2], Case = Uppercase);
+
+ void write(const byte[], u32bit);
+ void end_msg();
+
+ Hex_Encoder(Case);
+ Hex_Encoder(bool = false, u32bit = 72, Case = Uppercase);
+ private:
+ void encode_and_send(const byte[], u32bit);
+ static const byte BIN_TO_HEX_UPPER[16];
+ static const byte BIN_TO_HEX_LOWER[16];
+
+ const Case casing;
+ const u32bit line_length;
+ SecureVector<byte> in, out;
+ u32bit position, counter;
+ };
+
+/*************************************************
+* Hex Decoder *
+*************************************************/
+class BOTAN_DLL Hex_Decoder : public Filter
+ {
+ public:
+ static byte decode(const byte[2]);
+ static bool is_valid(byte);
+
+ void write(const byte[], u32bit);
+ void end_msg();
+
+ Hex_Decoder(Decoder_Checking = NONE);
+ private:
+ void decode_and_send(const byte[], u32bit);
+ void handle_bad_char(byte);
+ static const byte HEX_TO_BIN[256];
+
+ const Decoder_Checking checking;
+ SecureVector<byte> in, out;
+ u32bit position;
+ };
+
+}
+
+#endif
diff --git a/src/codec/hex/modinfo.txt b/src/codec/hex/modinfo.txt
new file mode 100644
index 000000000..e0b07a552
--- /dev/null
+++ b/src/codec/hex/modinfo.txt
@@ -0,0 +1,10 @@
+realname "Hex Codec"
+
+define HEX_CODEC
+
+load_on auto
+
+<add>
+hex.cpp
+hex.h
+</add>
diff --git a/src/codec/zlib/modinfo.txt b/src/codec/zlib/modinfo.txt
new file mode 100644
index 000000000..c1f1f998c
--- /dev/null
+++ b/src/codec/zlib/modinfo.txt
@@ -0,0 +1,19 @@
+realname "Zlib Compressor"
+#realname "Zlib/Gzip Compressor"
+
+define COMPRESSOR_ZLIB
+#define COMPRESSOR_ZLIB,COMPRESSOR_GZIP
+
+load_on request
+modset compression
+
+<add>
+zlib.h
+zlib.cpp
+#gzip.h
+#gzip.cpp
+</add>
+
+<libs>
+all -> z
+</libs>
diff --git a/src/codec/zlib/zlib.cpp b/src/codec/zlib/zlib.cpp
new file mode 100644
index 000000000..36a9640e3
--- /dev/null
+++ b/src/codec/zlib/zlib.cpp
@@ -0,0 +1,283 @@
+/*************************************************
+* Zlib Compressor Source File *
+* (C) 2001 Peter J Jones *
+* 2001-2007 Jack Lloyd *
+* 2006 Matt Johnston *
+*************************************************/
+
+#include <botan/zlib.h>
+#include <cstring>
+#include <map>
+#include <zlib.h>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Allocation Information for Zlib *
+*************************************************/
+class Zlib_Alloc_Info
+ {
+ public:
+ std::map<void*, u32bit> current_allocs;
+ Allocator* alloc;
+
+ Zlib_Alloc_Info() { alloc = Allocator::get(false); }
+ };
+
+/*************************************************
+* Allocation Function for Zlib *
+*************************************************/
+void* zlib_malloc(void* info_ptr, unsigned int n, unsigned int size)
+ {
+ Zlib_Alloc_Info* info = static_cast<Zlib_Alloc_Info*>(info_ptr);
+ void* ptr = info->alloc->allocate(n * size);
+ info->current_allocs[ptr] = n * size;
+ return ptr;
+ }
+
+/*************************************************
+* Allocation Function for Zlib *
+*************************************************/
+void zlib_free(void* info_ptr, void* ptr)
+ {
+ Zlib_Alloc_Info* info = static_cast<Zlib_Alloc_Info*>(info_ptr);
+ std::map<void*, u32bit>::const_iterator i = info->current_allocs.find(ptr);
+ if(i == info->current_allocs.end())
+ throw Invalid_Argument("zlib_free: Got pointer not allocated by us");
+ info->alloc->deallocate(ptr, i->second);
+ }
+
+}
+
+/*************************************************
+* Wrapper Type for Zlib z_stream *
+*************************************************/
+class Zlib_Stream
+ {
+ public:
+ z_stream stream;
+
+ Zlib_Stream()
+ {
+ std::memset(&stream, 0, sizeof(z_stream));
+ stream.zalloc = zlib_malloc;
+ stream.zfree = zlib_free;
+ stream.opaque = new Zlib_Alloc_Info;
+ }
+ ~Zlib_Stream()
+ {
+ Zlib_Alloc_Info* info = static_cast<Zlib_Alloc_Info*>(stream.opaque);
+ delete info;
+ std::memset(&stream, 0, sizeof(z_stream));
+ }
+ };
+
+/*************************************************
+* Zlib_Compression Constructor *
+*************************************************/
+Zlib_Compression::Zlib_Compression(u32bit l) :
+ level((l >= 9) ? 9 : l), buffer(DEFAULT_BUFFERSIZE)
+ {
+ zlib = 0;
+ }
+
+/*************************************************
+* Start Compressing with Zlib *
+*************************************************/
+void Zlib_Compression::start_msg()
+ {
+ clear();
+ zlib = new Zlib_Stream;
+ if(deflateInit(&(zlib->stream), level) != Z_OK)
+ throw Exception("Zlib_Compression: Memory allocation error");
+ }
+
+/*************************************************
+* Compress Input with Zlib *
+*************************************************/
+void Zlib_Compression::write(const byte input[], u32bit length)
+ {
+ zlib->stream.next_in = static_cast<Bytef*>(const_cast<byte*>(input));
+ zlib->stream.avail_in = length;
+
+ while(zlib->stream.avail_in != 0)
+ {
+ zlib->stream.next_out = static_cast<Bytef*>(buffer.begin());
+ zlib->stream.avail_out = buffer.size();
+ deflate(&(zlib->stream), Z_NO_FLUSH);
+ send(buffer.begin(), buffer.size() - zlib->stream.avail_out);
+ }
+ }
+
+/*************************************************
+* Finish Compressing with Zlib *
+*************************************************/
+void Zlib_Compression::end_msg()
+ {
+ zlib->stream.next_in = 0;
+ zlib->stream.avail_in = 0;
+
+ int rc = Z_OK;
+ while(rc != Z_STREAM_END)
+ {
+ zlib->stream.next_out = reinterpret_cast<Bytef*>(buffer.begin());
+ zlib->stream.avail_out = buffer.size();
+ rc = deflate(&(zlib->stream), Z_FINISH);
+ send(buffer.begin(), buffer.size() - zlib->stream.avail_out);
+ }
+ clear();
+ }
+
+/*************************************************
+* Flush the Zlib Compressor *
+*************************************************/
+void Zlib_Compression::flush()
+ {
+ zlib->stream.next_in = 0;
+ zlib->stream.avail_in = 0;
+
+ while(true)
+ {
+ zlib->stream.avail_out = buffer.size();
+
+ zlib->stream.next_out = reinterpret_cast<Bytef*>(buffer.begin());
+
+
+ deflate(&(zlib->stream), Z_FULL_FLUSH);
+ send(buffer.begin(), buffer.size() - zlib->stream.avail_out);
+ if(zlib->stream.avail_out == buffer.size()) break;
+ }
+ }
+
+/*************************************************
+* Clean up Compression Context *
+*************************************************/
+void Zlib_Compression::clear()
+ {
+ if(zlib)
+ {
+ deflateEnd(&(zlib->stream));
+ delete zlib;
+ zlib = 0;
+ }
+
+ buffer.clear();
+ }
+
+/*************************************************
+* Zlib_Decompression Constructor *
+*************************************************/
+Zlib_Decompression::Zlib_Decompression() : buffer(DEFAULT_BUFFERSIZE)
+ {
+ zlib = 0;
+ no_writes = true;
+ }
+
+/*************************************************
+* Start Decompressing with Zlib *
+*************************************************/
+void Zlib_Decompression::start_msg()
+ {
+ clear();
+ zlib = new Zlib_Stream;
+ if(inflateInit(&(zlib->stream)) != Z_OK)
+ throw Exception("Zlib_Decompression: Memory allocation error");
+ }
+
+/*************************************************
+* Decompress Input with Zlib *
+*************************************************/
+void Zlib_Decompression::write(const byte input_arr[], u32bit length)
+ {
+ if(length) no_writes = false;
+
+ // non-const needed by zlib api :(
+ Bytef* input = reinterpret_cast<Bytef*>(const_cast<byte*>(input_arr));
+
+ zlib->stream.next_in = input;
+ zlib->stream.avail_in = length;
+
+ while(zlib->stream.avail_in != 0)
+ {
+ zlib->stream.next_out = reinterpret_cast<Bytef*>(buffer.begin());
+ zlib->stream.avail_out = buffer.size();
+
+ int rc = inflate(&(zlib->stream), Z_SYNC_FLUSH);
+
+ if(rc != Z_OK && rc != Z_STREAM_END)
+ {
+ clear();
+ if(rc == Z_DATA_ERROR)
+ throw Decoding_Error("Zlib_Decompression: Data integrity error");
+ if(rc == Z_NEED_DICT)
+ throw Decoding_Error("Zlib_Decompression: Need preset dictionary");
+ if(rc == Z_MEM_ERROR)
+ throw Exception("Zlib_Decompression: Memory allocation error");
+ throw Exception("Zlib_Decompression: Unknown decompress error");
+ }
+
+ send(buffer.begin(), buffer.size() - zlib->stream.avail_out);
+
+ if(rc == Z_STREAM_END)
+ {
+ u32bit read_from_block = length - zlib->stream.avail_in;
+ start_msg();
+
+ zlib->stream.next_in = input + read_from_block;
+ zlib->stream.avail_in = length - read_from_block;
+
+ input += read_from_block;
+ length -= read_from_block;
+ }
+ }
+ }
+
+/*************************************************
+* Finish Decompressing with Zlib *
+*************************************************/
+void Zlib_Decompression::end_msg()
+ {
+ if(no_writes) return;
+ zlib->stream.next_in = 0;
+ zlib->stream.avail_in = 0;
+
+ int rc = Z_OK;
+
+ while(rc != Z_STREAM_END)
+ {
+ zlib->stream.next_out = reinterpret_cast<Bytef*>(buffer.begin());
+ zlib->stream.avail_out = buffer.size();
+ rc = inflate(&(zlib->stream), Z_SYNC_FLUSH);
+
+ if(rc != Z_OK && rc != Z_STREAM_END)
+ {
+ clear();
+ throw Exception("Zlib_Decompression: Error finalizing decompression");
+ }
+
+ send(buffer.begin(), buffer.size() - zlib->stream.avail_out);
+ }
+
+ clear();
+ }
+
+/*************************************************
+* Clean up Decompression Context *
+*************************************************/
+void Zlib_Decompression::clear()
+ {
+ no_writes = true;
+
+ if(zlib)
+ {
+ inflateEnd(&(zlib->stream));
+ delete zlib;
+ zlib = 0;
+ }
+
+ buffer.clear();
+ }
+
+}
diff --git a/src/codec/zlib/zlib.h b/src/codec/zlib/zlib.h
new file mode 100644
index 000000000..c3baea4ee
--- /dev/null
+++ b/src/codec/zlib/zlib.h
@@ -0,0 +1,56 @@
+/*************************************************
+* Zlib Compressor Header File *
+* (C) 2001 Peter J Jones *
+* 2001-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_ZLIB_H__
+#define BOTAN_ZLIB_H__
+
+#include <botan/filter.h>
+
+namespace Botan {
+
+/*************************************************
+* Zlib Compression Filter *
+*************************************************/
+class Zlib_Compression : public Filter
+ {
+ public:
+ void write(const byte input[], u32bit length);
+ void start_msg();
+ void end_msg();
+
+ void flush();
+
+ Zlib_Compression(u32bit = 6);
+ ~Zlib_Compression() { clear(); }
+ private:
+ void clear();
+ const u32bit level;
+ SecureVector<byte> buffer;
+ class Zlib_Stream* zlib;
+ };
+
+/*************************************************
+* Zlib Decompression Filter *
+*************************************************/
+class Zlib_Decompression : public Filter
+ {
+ public:
+ void write(const byte input[], u32bit length);
+ void start_msg();
+ void end_msg();
+
+ Zlib_Decompression();
+ ~Zlib_Decompression() { clear(); }
+ private:
+ void clear();
+ SecureVector<byte> buffer;
+ class Zlib_Stream* zlib;
+ bool no_writes;
+ };
+
+}
+
+#endif