summaryrefslogtreecommitdiffstats
path: root/botan/src/codec/hex
diff options
context:
space:
mode:
Diffstat (limited to 'botan/src/codec/hex')
-rw-r--r--botan/src/codec/hex/hex.cpp191
-rw-r--r--botan/src/codec/hex/hex.h90
-rw-r--r--botan/src/codec/hex/hex_char.cpp48
-rw-r--r--botan/src/codec/hex/info.txt15
4 files changed, 344 insertions, 0 deletions
diff --git a/botan/src/codec/hex/hex.cpp b/botan/src/codec/hex/hex.cpp
new file mode 100644
index 0000000..fbacc27
--- /dev/null
+++ b/botan/src/codec/hex/hex.cpp
@@ -0,0 +1,191 @@
+/*
+* Hex Encoder/Decoder
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/hex.h>
+#include <botan/parsing.h>
+#include <botan/charset.h>
+#include <botan/exceptn.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/botan/src/codec/hex/hex.h b/botan/src/codec/hex/hex.h
new file mode 100644
index 0000000..035bf4e
--- /dev/null
+++ b/botan/src/codec/hex/hex.h
@@ -0,0 +1,90 @@
+/*
+* Hex Encoder/Decoder
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_HEX_H__
+#define BOTAN_HEX_H__
+
+#include <botan/filter.h>
+
+namespace Botan {
+
+/**
+* This class represents a hex encoder. It encodes byte arrays to hex strings.
+*/
+class BOTAN_DLL Hex_Encoder : public Filter
+ {
+ public:
+ /**
+ * Whether to use uppercase or lowercase letters for the encoded string.
+ */
+ enum Case { Uppercase, Lowercase };
+
+ /**
+ Encode a single byte into two hex characters
+ */
+ static void encode(byte in, byte out[2], Case the_case = Uppercase);
+
+ void write(const byte in[], u32bit length);
+ void end_msg();
+
+ /**
+ * Create a hex encoder.
+ * @param the_case the case to use in the encoded strings.
+ */
+ Hex_Encoder(Case the_case);
+
+ /**
+ * Create a hex encoder.
+ * @param newlines should newlines be used
+ * @param line_length if newlines are used, how long are lines
+ * @param the_case the case to use in the encoded strings
+ */
+ Hex_Encoder(bool newlines = false,
+ u32bit line_length = 72,
+ Case the_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;
+ };
+
+/**
+* This class represents a hex decoder. It converts hex strings to byte arrays.
+*/
+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();
+
+ /**
+ * Construct a Hex Decoder using the specified
+ * character checking.
+ * @param checking the checking to use during decoding.
+ */
+ Hex_Decoder(Decoder_Checking 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/botan/src/codec/hex/hex_char.cpp b/botan/src/codec/hex/hex_char.cpp
new file mode 100644
index 0000000..c28efc5
--- /dev/null
+++ b/botan/src/codec/hex/hex_char.cpp
@@ -0,0 +1,48 @@
+/*
+* Hex Character Table
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/hex.h>
+
+namespace Botan {
+
+/*
+* Hex Encoder Lookup Tables
+*/
+const byte Hex_Encoder::BIN_TO_HEX_UPPER[16] = {
+0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43,
+0x44, 0x45, 0x46 };
+
+const byte Hex_Encoder::BIN_TO_HEX_LOWER[16] = {
+0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63,
+0x64, 0x65, 0x66 };
+
+/*
+* Hex Decoder Lookup Table
+*/
+const byte Hex_Decoder::HEX_TO_BIN[256] = {
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x01, 0x02, 0x03,
+0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
+
+}
diff --git a/botan/src/codec/hex/info.txt b/botan/src/codec/hex/info.txt
new file mode 100644
index 0000000..512a5de
--- /dev/null
+++ b/botan/src/codec/hex/info.txt
@@ -0,0 +1,15 @@
+realname "Hex Codec"
+
+define HEX_CODEC
+
+load_on auto
+
+<add>
+hex.cpp
+hex_char.cpp
+hex.h
+</add>
+
+<requires>
+filters
+</requires>