aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/algo_factory/algo_factory.cpp9
-rw-r--r--src/algo_factory/algo_factory.h8
-rw-r--r--src/alloc/secmem.h57
-rw-r--r--src/block/aes/aes.cpp2
-rw-r--r--src/block/aes/aes.h8
-rw-r--r--src/block/aes_intel/aes_intel.h6
-rw-r--r--src/block/blowfish/blowfish.h4
-rw-r--r--src/block/cast/cast128.cpp4
-rw-r--r--src/block/cast/cast128.h2
-rw-r--r--src/block/cast/cast256.cpp2
-rw-r--r--src/block/cast/cast256.h4
-rw-r--r--src/block/des/des.h4
-rw-r--r--src/block/des/desx.h2
-rw-r--r--src/block/gost_28147/gost_28147.h6
-rw-r--r--src/block/idea/idea.h2
-rw-r--r--src/block/kasumi/kasumi.cpp2
-rw-r--r--src/block/kasumi/kasumi.h2
-rw-r--r--src/block/mars/mars.cpp2
-rw-r--r--src/block/mars/mars.h2
-rw-r--r--src/block/misty1/misty1.cpp2
-rw-r--r--src/block/misty1/misty1.h2
-rw-r--r--src/block/noekeon/noekeon.h2
-rw-r--r--src/block/rc2/rc2.cpp2
-rw-r--r--src/block/rc2/rc2.h2
-rw-r--r--src/block/rc5/rc5.cpp2
-rw-r--r--src/block/rc6/rc6.cpp2
-rw-r--r--src/block/rc6/rc6.h2
-rw-r--r--src/block/safer/safer_sk.cpp2
-rw-r--r--src/block/seed/seed.cpp2
-rw-r--r--src/block/seed/seed.h2
-rw-r--r--src/block/serpent/serpent.cpp2
-rw-r--r--src/block/serpent/serpent.h2
-rw-r--r--src/block/serpent_ia32/serp_ia32.cpp2
-rw-r--r--src/block/skipjack/skipjack.h2
-rw-r--r--src/block/square/square.cpp2
-rw-r--r--src/block/square/square.h4
-rw-r--r--src/block/tea/tea.h2
-rw-r--r--src/block/twofish/twofish.cpp2
-rw-r--r--src/block/twofish/twofish.h4
-rw-r--r--src/block/xtea/xtea.cpp2
-rw-r--r--src/block/xtea/xtea.h2
-rw-r--r--src/filters/base64/base64.cpp4
-rw-r--r--src/filters/secqueue.cpp2
-rw-r--r--src/hash/bmw/bmw_512.h4
-rw-r--r--src/hash/fork256/fork256.h4
-rw-r--r--src/hash/gost_3411/gost_3411.cpp4
-rw-r--r--src/hash/gost_3411/gost_3411.h6
-rw-r--r--src/hash/has160/has160.h4
-rw-r--r--src/hash/md2/md2.h4
-rw-r--r--src/hash/md4/md4.h4
-rw-r--r--src/hash/md5/md5.h4
-rw-r--r--src/hash/rmd128/rmd128.h4
-rw-r--r--src/hash/rmd160/rmd160.h4
-rw-r--r--src/hash/sha1/sha160.h2
-rw-r--r--src/hash/sha2/sha2_32.h4
-rw-r--r--src/hash/sha2/sha2_64.h4
-rw-r--r--src/hash/skein/skein_512.cpp2
-rw-r--r--src/hash/skein/skein_512.h6
-rw-r--r--src/hash/tiger/tiger.h4
-rw-r--r--src/hash/whirlpool/whrlpool.h2
-rw-r--r--src/libstate/libstate.cpp25
-rw-r--r--src/mac/x919_mac/x919_mac.h2
-rw-r--r--src/rng/auto_rng/auto_rng.h1
-rw-r--r--src/ssl/c_kex.cpp11
-rw-r--r--src/ssl/cert_ver.cpp11
-rw-r--r--src/ssl/finished.cpp2
-rw-r--r--src/ssl/hello.cpp126
-rw-r--r--src/ssl/info.txt39
-rw-r--r--src/ssl/rec_read.cpp120
-rw-r--r--src/ssl/rec_wri.cpp56
-rw-r--r--src/ssl/s_kex.cpp2
-rw-r--r--src/ssl/socket.h7
-rw-r--r--src/ssl/tls_client.cpp32
-rw-r--r--src/ssl/tls_client.h2
-rw-r--r--src/ssl/tls_magic.h11
-rw-r--r--src/ssl/tls_messages.h3
-rw-r--r--src/ssl/tls_policy.h2
-rw-r--r--src/ssl/tls_reader.h140
-rw-r--r--src/ssl/tls_record.h46
-rw-r--r--src/ssl/tls_server.cpp46
-rw-r--r--src/ssl/tls_server.h6
-rw-r--r--src/ssl/tls_session_key.cpp2
-rw-r--r--src/ssl/unix_socket/unx_sock.cpp8
-rw-r--r--src/ssl/unix_socket/unx_sock.h4
-rw-r--r--src/stream/arc4/arc4.h4
-rw-r--r--src/stream/salsa20/salsa20.h4
-rw-r--r--src/stream/turing/turing.h6
-rw-r--r--src/stream/wid_wake/wid_wake.h8
88 files changed, 623 insertions, 351 deletions
diff --git a/src/algo_factory/algo_factory.cpp b/src/algo_factory/algo_factory.cpp
index 05de330c3..07a072f22 100644
--- a/src/algo_factory/algo_factory.cpp
+++ b/src/algo_factory/algo_factory.cpp
@@ -83,10 +83,8 @@ const T* factory_prototype(const std::string& algo_spec,
/**
* Setup caches
*/
-Algorithm_Factory::Algorithm_Factory(const std::vector<Engine*>& engines_in)
+Algorithm_Factory::Algorithm_Factory()
{
- engines = engines_in;
-
block_cipher_cache = new Algorithm_Cache<BlockCipher>();
stream_cipher_cache = new Algorithm_Cache<StreamCipher>();
hash_cache = new Algorithm_Cache<HashFunction>();
@@ -107,6 +105,11 @@ Algorithm_Factory::~Algorithm_Factory()
delete mac_cache;
}
+void Algorithm_Factory::add_engine(Engine* engine)
+ {
+ engines.push_back(engine);
+ }
+
/**
* Set the preferred provider for an algorithm
*/
diff --git a/src/algo_factory/algo_factory.h b/src/algo_factory/algo_factory.h
index 8c1c47060..92653ab66 100644
--- a/src/algo_factory/algo_factory.h
+++ b/src/algo_factory/algo_factory.h
@@ -34,10 +34,9 @@ class BOTAN_DLL Algorithm_Factory
public:
/**
* Constructor
- * @param engines_in the list of engines to use
* @param mf a mutex factory
*/
- Algorithm_Factory(const std::vector<Engine*>& engines_in);
+ Algorithm_Factory();
/**
* Destructor
@@ -45,6 +44,11 @@ class BOTAN_DLL Algorithm_Factory
~Algorithm_Factory();
/**
+ * @param engine to add (Algorithm_Factory takes ownership)
+ */
+ void add_engine(class Engine* engine);
+
+ /**
* @param algo_spec the algorithm we are querying
* @returns list of providers of this algorithm
*/
diff --git a/src/alloc/secmem.h b/src/alloc/secmem.h
index 42b5c7a2d..c50df924d 100644
--- a/src/alloc/secmem.h
+++ b/src/alloc/secmem.h
@@ -179,11 +179,13 @@ class MemoryRegion
void resize(u32bit n);
/**
- * Preallocate memory, so that this buffer can grow up to size n without
- * having to perform any actual memory allocations. (This is
- * the same principle as for std::vector::reserve().)
+ * Change the size to n elements. If n is >= size(), preexisting
+ * elements remain unchanged, with later elements
+ * zero-initialized. If n < size(), then the last (size() - N)
+ * elements are removed.
+ * @param n the new size
*/
- void grow_to(u32bit N);
+ void grow_to(u32bit n);
/**
* Swap this buffer with another object.
@@ -333,11 +335,9 @@ class MemoryVector : public MemoryRegion<T>
* This class represents variable length buffers using the operating
* systems capability to lock memory, i.e. keeping it from being
* swapped out to disk. In this way, a security hole allowing attackers
-* to find swapped out secret keys is closed. Please refer to
-* Botan::InitializerOptions::secure_memory() for restrictions and
-* further details.
+* to find swapped out secret keys is closed.
*/
-template<typename T>
+template<typename T, u32bit INITIAL_LEN = 0>
class SecureVector : public MemoryRegion<T>
{
public:
@@ -353,7 +353,8 @@ class SecureVector : public MemoryRegion<T>
* Create a buffer of the specified length.
* @param n the length of the buffer to create.
*/
- SecureVector(u32bit n = 0) { MemoryRegion<T>::init(true, n); }
+ SecureVector(u32bit n = INITIAL_LEN)
+ { MemoryRegion<T>::init(true, n); }
/**
* Create a buffer with the specified contents.
@@ -382,44 +383,6 @@ class SecureVector : public MemoryRegion<T>
{ MemoryRegion<T>::init(true); set(in1); append(in2); }
};
-/**
-* This class represents fixed length buffers using the operating
-* systems capability to lock memory, i.e. keeping it from being
-* swapped out to disk. In this way, a security hole allowing attackers
-* to find swapped out secret keys is closed. Please refer to
-* Botan::InitializerOptions::secure_memory() for restrictions and
-* further details.
-*/
-template<typename T, u32bit L>
-class SecureBuffer : public MemoryRegion<T>
- {
- public:
- /**
- * Copy the contents of another buffer into this buffer.
- * @param in the buffer to copy the contents from
- * @return a reference to *this
- */
- SecureBuffer<T,L>& operator=(const SecureBuffer<T,L>& in)
- { if(this != &in) set(in); return (*this); }
-
- /**
- * Create a buffer of the length L.
- */
- SecureBuffer() { MemoryRegion<T>::init(true, L); }
-
- /**
- * Create a buffer of size L with the specified contents.
- * @param in the array containing the data to be initially copied
- * into the newly created buffer
- * @param n the size of the array in
- */
- SecureBuffer(const T in[], u32bit n)
- { MemoryRegion<T>::init(true, L); copy(in, n); }
- private:
- SecureBuffer<T, L>& operator=(const MemoryRegion<T>& in)
- { if(this != &in) set(in); return (*this); }
- };
-
}
#endif
diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp
index 721c4ac75..df2674f34 100644
--- a/src/block/aes/aes.cpp
+++ b/src/block/aes/aes.cpp
@@ -594,7 +594,7 @@ void AES::key_schedule(const byte key[], u32bit length)
ROUNDS = (length / 4) + 6;
- SecureBuffer<u32bit, 64> XEK, XDK;
+ SecureVector<u32bit, 64> XEK, XDK;
const u32bit X = length / 4;
for(u32bit j = 0; j != X; ++j)
diff --git a/src/block/aes/aes.h b/src/block/aes/aes.h
index 4ff3360de..45026f732 100644
--- a/src/block/aes/aes.h
+++ b/src/block/aes/aes.h
@@ -33,11 +33,11 @@ class BOTAN_DLL AES : public BlockCipher
u32bit ROUNDS;
- SecureBuffer<u32bit, 56> EK;
- SecureBuffer<byte, 16> ME;
+ SecureVector<u32bit, 56> EK;
+ SecureVector<byte, 16> ME;
- SecureBuffer<u32bit, 56> DK;
- SecureBuffer<byte, 16> MD;
+ SecureVector<u32bit, 56> DK;
+ SecureVector<byte, 16> MD;
};
/**
diff --git a/src/block/aes_intel/aes_intel.h b/src/block/aes_intel/aes_intel.h
index 239516e24..a3ebf153b 100644
--- a/src/block/aes_intel/aes_intel.h
+++ b/src/block/aes_intel/aes_intel.h
@@ -31,7 +31,7 @@ class BOTAN_DLL AES_128_Intel : public BlockCipher
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u32bit, 44> EK, DK;
+ SecureVector<u32bit, 44> EK, DK;
};
/**
@@ -53,7 +53,7 @@ class BOTAN_DLL AES_192_Intel : public BlockCipher
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u32bit, 52> EK, DK;
+ SecureVector<u32bit, 52> EK, DK;
};
/**
@@ -75,7 +75,7 @@ class BOTAN_DLL AES_256_Intel : public BlockCipher
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u32bit, 60> EK, DK;
+ SecureVector<u32bit, 60> EK, DK;
};
}
diff --git a/src/block/blowfish/blowfish.h b/src/block/blowfish/blowfish.h
index 5419308ca..2306f0e37 100644
--- a/src/block/blowfish/blowfish.h
+++ b/src/block/blowfish/blowfish.h
@@ -33,8 +33,8 @@ class BOTAN_DLL Blowfish : public BlockCipher
static const u32bit P_INIT[18];
static const u32bit S_INIT[1024];
- SecureBuffer<u32bit, 1024> S;
- SecureBuffer<u32bit, 18> P;
+ SecureVector<u32bit, 1024> S;
+ SecureVector<u32bit, 18> P;
};
}
diff --git a/src/block/cast/cast128.cpp b/src/block/cast/cast128.cpp
index 887dcf994..cabde4b4f 100644
--- a/src/block/cast/cast128.cpp
+++ b/src/block/cast/cast128.cpp
@@ -119,7 +119,7 @@ void CAST_128::decrypt_n(const byte in[], byte out[], u32bit blocks) const
void CAST_128::key_schedule(const byte key[], u32bit length)
{
clear();
- SecureBuffer<u32bit, 4> X;
+ SecureVector<u32bit, 4> X;
for(u32bit j = 0; j != length; ++j)
X[j/4] = (X[j/4] << 8) + key[j];
@@ -144,7 +144,7 @@ void CAST_128::key_schedule(u32bit K[16], u32bit X[4])
const u32bit* X;
};
- SecureBuffer<u32bit, 4> Z;
+ SecureVector<u32bit, 4> Z;
ByteReader x(X), z(Z);
Z[0] = X[0] ^ S5[x(13)] ^ S6[x(15)] ^ S7[x(12)] ^ S8[x(14)] ^ S7[x( 8)];
diff --git a/src/block/cast/cast128.h b/src/block/cast/cast128.h
index caffb97ea..048d2e43c 100644
--- a/src/block/cast/cast128.h
+++ b/src/block/cast/cast128.h
@@ -36,7 +36,7 @@ class BOTAN_DLL CAST_128 : public BlockCipher
static const u32bit S7[256];
static const u32bit S8[256];
- SecureBuffer<u32bit, 16> MK, RK;
+ SecureVector<u32bit, 16> MK, RK;
};
extern const u32bit CAST_SBOX1[256];
diff --git a/src/block/cast/cast256.cpp b/src/block/cast/cast256.cpp
index 7a4a4e805..8aaf8009f 100644
--- a/src/block/cast/cast256.cpp
+++ b/src/block/cast/cast256.cpp
@@ -138,7 +138,7 @@ void CAST_256::decrypt_n(const byte in[], byte out[], u32bit blocks) const
*/
void CAST_256::key_schedule(const byte key[], u32bit length)
{
- SecureBuffer<u32bit, 8> TMP;
+ SecureVector<u32bit, 8> TMP;
for(u32bit j = 0; j != length; ++j)
TMP[j/4] = (TMP[j/4] << 8) + key[j];
diff --git a/src/block/cast/cast256.h b/src/block/cast/cast256.h
index 0db3682ba..170d94e77 100644
--- a/src/block/cast/cast256.h
+++ b/src/block/cast/cast256.h
@@ -32,8 +32,8 @@ class BOTAN_DLL CAST_256 : public BlockCipher
static const u32bit KEY_MASK[192];
static const byte KEY_ROT[32];
- SecureBuffer<u32bit, 48> MK;
- SecureBuffer<byte, 48> RK;
+ SecureVector<u32bit, 48> MK;
+ SecureVector<byte, 48> RK;
};
extern const u32bit CAST_SBOX1[256];
diff --git a/src/block/des/des.h b/src/block/des/des.h
index b28990178..32dd3daf6 100644
--- a/src/block/des/des.h
+++ b/src/block/des/des.h
@@ -29,7 +29,7 @@ class BOTAN_DLL DES : public BlockCipher
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u32bit, 32> round_key;
+ SecureVector<u32bit, 32> round_key;
};
/*
@@ -49,7 +49,7 @@ class BOTAN_DLL TripleDES : public BlockCipher
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u32bit, 96> round_key;
+ SecureVector<u32bit, 96> round_key;
};
/*
diff --git a/src/block/des/desx.h b/src/block/des/desx.h
index 89664d064..440574e9d 100644
--- a/src/block/des/desx.h
+++ b/src/block/des/desx.h
@@ -28,7 +28,7 @@ class BOTAN_DLL DESX : public BlockCipher
DESX() : BlockCipher(8, 24) {}
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<byte, 8> K1, K2;
+ SecureVector<byte, 8> K1, K2;
DES des;
};
diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h
index 2b7daaf6a..2ccb3214d 100644
--- a/src/block/gost_28147/gost_28147.h
+++ b/src/block/gost_28147/gost_28147.h
@@ -52,13 +52,13 @@ class BOTAN_DLL GOST_28147_89 : public BlockCipher
GOST_28147_89(const GOST_28147_89_Params& params);
private:
- GOST_28147_89(const SecureBuffer<u32bit, 1024>& other_SBOX) :
+ GOST_28147_89(const SecureVector<u32bit, 1024>& other_SBOX) :
BlockCipher(8, 32), SBOX(other_SBOX) {}
void key_schedule(const byte[], u32bit);
- SecureBuffer<u32bit, 1024> SBOX;
- SecureBuffer<u32bit, 8> EK;
+ SecureVector<u32bit, 1024> SBOX;
+ SecureVector<u32bit, 8> EK;
};
}
diff --git a/src/block/idea/idea.h b/src/block/idea/idea.h
index 89ec117e3..1a9644d4e 100644
--- a/src/block/idea/idea.h
+++ b/src/block/idea/idea.h
@@ -28,7 +28,7 @@ class BOTAN_DLL IDEA : public BlockCipher
IDEA() : BlockCipher(8, 16) {}
protected:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u16bit, 52> EK, DK;
+ SecureVector<u16bit, 52> EK, DK;
};
}
diff --git a/src/block/kasumi/kasumi.cpp b/src/block/kasumi/kasumi.cpp
index dff6db13c..d7f981b20 100644
--- a/src/block/kasumi/kasumi.cpp
+++ b/src/block/kasumi/kasumi.cpp
@@ -204,7 +204,7 @@ void KASUMI::key_schedule(const byte key[], u32bit)
static const u16bit RC[] = { 0x0123, 0x4567, 0x89AB, 0xCDEF,
0xFEDC, 0xBA98, 0x7654, 0x3210 };
- SecureBuffer<u16bit, 16> K;
+ SecureVector<u16bit, 16> K;
for(u32bit j = 0; j != 8; ++j)
{
K[j] = load_be<u16bit>(key, j);
diff --git a/src/block/kasumi/kasumi.h b/src/block/kasumi/kasumi.h
index c3db1cb05..827989a57 100644
--- a/src/block/kasumi/kasumi.h
+++ b/src/block/kasumi/kasumi.h
@@ -29,7 +29,7 @@ class BOTAN_DLL KASUMI : public BlockCipher
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u16bit, 64> EK;
+ SecureVector<u16bit, 64> EK;
};
}
diff --git a/src/block/mars/mars.cpp b/src/block/mars/mars.cpp
index 6b73ea054..57a224fac 100644
--- a/src/block/mars/mars.cpp
+++ b/src/block/mars/mars.cpp
@@ -320,7 +320,7 @@ void MARS::decrypt_n(const byte in[], byte out[], u32bit blocks) const
*/
void MARS::key_schedule(const byte key[], u32bit length)
{
- SecureBuffer<u32bit, 15> T;
+ SecureVector<u32bit, 15> T;
for(u32bit j = 0; j != length / 4; ++j)
T[j] = load_le<u32bit>(key, j);
T[length / 4] = length / 4;
diff --git a/src/block/mars/mars.h b/src/block/mars/mars.h
index 7a598d2bd..f2a6d0197 100644
--- a/src/block/mars/mars.h
+++ b/src/block/mars/mars.h
@@ -26,7 +26,7 @@ class BOTAN_DLL MARS : public BlockCipher
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u32bit, 40> EK;
+ SecureVector<u32bit, 40> EK;
};
}
diff --git a/src/block/misty1/misty1.cpp b/src/block/misty1/misty1.cpp
index 56cd7446c..bc85d71f9 100644
--- a/src/block/misty1/misty1.cpp
+++ b/src/block/misty1/misty1.cpp
@@ -204,7 +204,7 @@ void MISTY1::decrypt_n(const byte in[], byte out[], u32bit blocks) const
*/
void MISTY1::key_schedule(const byte key[], u32bit length)
{
- SecureBuffer<u16bit, 32> KS;
+ SecureVector<u16bit, 32> KS;
for(u32bit j = 0; j != length / 2; ++j)
KS[j] = load_be<u16bit>(key, j);
diff --git a/src/block/misty1/misty1.h b/src/block/misty1/misty1.h
index 000830915..7b4d91def 100644
--- a/src/block/misty1/misty1.h
+++ b/src/block/misty1/misty1.h
@@ -29,7 +29,7 @@ class BOTAN_DLL MISTY1 : public BlockCipher
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u16bit, 100> EK, DK;
+ SecureVector<u16bit, 100> EK, DK;
};
}
diff --git a/src/block/noekeon/noekeon.h b/src/block/noekeon/noekeon.h
index 22ef65342..abeecbc64 100644
--- a/src/block/noekeon/noekeon.h
+++ b/src/block/noekeon/noekeon.h
@@ -31,7 +31,7 @@ class BOTAN_DLL Noekeon : public BlockCipher
static const byte RC[17];
- SecureBuffer<u32bit, 4> EK, DK;
+ SecureVector<u32bit, 4> EK, DK;
};
}
diff --git a/src/block/rc2/rc2.cpp b/src/block/rc2/rc2.cpp
index b5e4a7d50..3114c6055 100644
--- a/src/block/rc2/rc2.cpp
+++ b/src/block/rc2/rc2.cpp
@@ -124,7 +124,7 @@ void RC2::key_schedule(const byte key[], u32bit length)
0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, 0x0A, 0xA6, 0x20, 0x68,
0xFE, 0x7F, 0xC1, 0xAD };
- SecureBuffer<byte, 128> L;
+ SecureVector<byte, 128> L;
L.copy(key, length);
for(u32bit j = length; j != 128; ++j)
diff --git a/src/block/rc2/rc2.h b/src/block/rc2/rc2.h
index c6e4946f9..dd0295572 100644
--- a/src/block/rc2/rc2.h
+++ b/src/block/rc2/rc2.h
@@ -31,7 +31,7 @@ class BOTAN_DLL RC2 : public BlockCipher
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u16bit, 64> K;
+ SecureVector<u16bit, 64> K;
};
}
diff --git a/src/block/rc5/rc5.cpp b/src/block/rc5/rc5.cpp
index 1b71de85a..6c712db9a 100644
--- a/src/block/rc5/rc5.cpp
+++ b/src/block/rc5/rc5.cpp
@@ -82,7 +82,7 @@ void RC5::key_schedule(const byte key[], u32bit length)
for(u32bit j = 1; j != S.size(); ++j)
S[j] = S[j-1] + 0x9E3779B9;
- SecureBuffer<u32bit, 8> K;
+ SecureVector<u32bit, 8> K;
for(s32bit j = length-1; j >= 0; --j)
K[j/4] = (K[j/4] << 8) + key[j];
for(u32bit j = 0, A = 0, B = 0; j != MIX_ROUNDS; ++j)
diff --git a/src/block/rc6/rc6.cpp b/src/block/rc6/rc6.cpp
index 8bda62259..ff846f006 100644
--- a/src/block/rc6/rc6.cpp
+++ b/src/block/rc6/rc6.cpp
@@ -119,7 +119,7 @@ void RC6::key_schedule(const byte key[], u32bit length)
for(u32bit j = 1; j != S.size(); ++j)
S[j] = S[j-1] + 0x9E3779B9;
- SecureBuffer<u32bit, 8> K;
+ SecureVector<u32bit, 8> K;
for(s32bit j = length-1; j >= 0; --j)
K[j/4] = (K[j/4] << 8) + key[j];
for(u32bit j = 0, A = 0, B = 0; j != MIX_ROUNDS; ++j)
diff --git a/src/block/rc6/rc6.h b/src/block/rc6/rc6.h
index 6cd0f54db..cc1534ee2 100644
--- a/src/block/rc6/rc6.h
+++ b/src/block/rc6/rc6.h
@@ -29,7 +29,7 @@ class BOTAN_DLL RC6 : public BlockCipher
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u32bit, 44> S;
+ SecureVector<u32bit, 44> S;
};
}
diff --git a/src/block/safer/safer_sk.cpp b/src/block/safer/safer_sk.cpp
index fcbe84c8b..84ad9523b 100644
--- a/src/block/safer/safer_sk.cpp
+++ b/src/block/safer/safer_sk.cpp
@@ -91,7 +91,7 @@ void SAFER_SK::decrypt_n(const byte in[], byte out[], u32bit blocks) const
*/
void SAFER_SK::key_schedule(const byte key[], u32bit)
{
- SecureBuffer<byte, 18> KB;
+ SecureVector<byte, 18> KB;
for(u32bit j = 0; j != 8; ++j)
{
diff --git a/src/block/seed/seed.cpp b/src/block/seed/seed.cpp
index 378be16e4..651233bdb 100644
--- a/src/block/seed/seed.cpp
+++ b/src/block/seed/seed.cpp
@@ -111,7 +111,7 @@ void SEED::key_schedule(const byte key[], u32bit)
0x779B99E3, 0xEF3733C6, 0xDE6E678D, 0xBCDCCF1B
};
- SecureBuffer<u32bit, 4> WK;
+ SecureVector<u32bit, 4> WK;
for(u32bit j = 0; j != 4; ++j)
WK[j] = load_be<u32bit>(key, j);
diff --git a/src/block/seed/seed.h b/src/block/seed/seed.h
index 5a4b44057..e56b77dbb 100644
--- a/src/block/seed/seed.h
+++ b/src/block/seed/seed.h
@@ -37,7 +37,7 @@ class BOTAN_DLL SEED : public BlockCipher
static const u32bit S0[256], S1[256], S2[256], S3[256];
};
- SecureBuffer<u32bit, 32> K;
+ SecureVector<u32bit, 32> K;
};
}
diff --git a/src/block/serpent/serpent.cpp b/src/block/serpent/serpent.cpp
index e16afc89c..b93326e58 100644
--- a/src/block/serpent/serpent.cpp
+++ b/src/block/serpent/serpent.cpp
@@ -355,7 +355,7 @@ void Serpent::key_schedule(const byte key[], u32bit length)
{
const u32bit PHI = 0x9E3779B9;
- SecureBuffer<u32bit, 140> W;
+ SecureVector<u32bit, 140> W;
for(u32bit j = 0; j != length / 4; ++j)
W[j] = load_le<u32bit>(key, j);
diff --git a/src/block/serpent/serpent.h b/src/block/serpent/serpent.h
index 4fa7451b9..37ce10c7b 100644
--- a/src/block/serpent/serpent.h
+++ b/src/block/serpent/serpent.h
@@ -28,7 +28,7 @@ class BOTAN_DLL Serpent : public BlockCipher
protected:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u32bit, 132> round_key;
+ SecureVector<u32bit, 132> round_key;
};
}
diff --git a/src/block/serpent_ia32/serp_ia32.cpp b/src/block/serpent_ia32/serp_ia32.cpp
index 721584b18..ff454ab4c 100644
--- a/src/block/serpent_ia32/serp_ia32.cpp
+++ b/src/block/serpent_ia32/serp_ia32.cpp
@@ -49,7 +49,7 @@ void Serpent_IA32::decrypt_n(const byte in[], byte out[], u32bit blocks) const
*/
void Serpent_IA32::key_schedule(const byte key[], u32bit length)
{
- SecureBuffer<u32bit, 140> W;
+ SecureVector<u32bit, 140> W;
for(u32bit j = 0; j != length / 4; ++j)
W[j] = load_le<u32bit>(key, j);
W[length / 4] |= u32bit(1) << ((length%4)*8);
diff --git a/src/block/skipjack/skipjack.h b/src/block/skipjack/skipjack.h
index b701e2091..d481aee08 100644
--- a/src/block/skipjack/skipjack.h
+++ b/src/block/skipjack/skipjack.h
@@ -29,7 +29,7 @@ class BOTAN_DLL Skipjack : public BlockCipher
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<byte, 2560> FTAB;
+ SecureVector<byte, 2560> FTAB;
};
}
diff --git a/src/block/square/square.cpp b/src/block/square/square.cpp
index 892568655..adcf18611 100644
--- a/src/block/square/square.cpp
+++ b/src/block/square/square.cpp
@@ -140,7 +140,7 @@ void Square::decrypt_n(const byte in[], byte out[], u32bit blocks) const
*/
void Square::key_schedule(const byte key[], u32bit)
{
- SecureBuffer<u32bit, 36> XEK, XDK;
+ SecureVector<u32bit, 36> XEK, XDK;
for(u32bit i = 0; i != 4; ++i)
XEK[i] = load_be<u32bit>(key, i);
diff --git a/src/block/square/square.h b/src/block/square/square.h
index 088122181..8e1f7f815 100644
--- a/src/block/square/square.h
+++ b/src/block/square/square.h
@@ -45,8 +45,8 @@ class BOTAN_DLL Square : public BlockCipher
static const u32bit TD2[256];
static const u32bit TD3[256];
- SecureBuffer<u32bit, 28> EK, DK;
- SecureBuffer<byte, 32> ME, MD;
+ SecureVector<u32bit, 28> EK, DK;
+ SecureVector<byte, 32> ME, MD;
};
}
diff --git a/src/block/tea/tea.h b/src/block/tea/tea.h
index c19f272a6..152c9a905 100644
--- a/src/block/tea/tea.h
+++ b/src/block/tea/tea.h
@@ -28,7 +28,7 @@ class BOTAN_DLL TEA : public BlockCipher
TEA() : BlockCipher(8, 16) {}
private:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u32bit, 4> K;
+ SecureVector<u32bit, 4> K;
};
}
diff --git a/src/block/twofish/twofish.cpp b/src/block/twofish/twofish.cpp
index 3136837aa..a183821b2 100644
--- a/src/block/twofish/twofish.cpp
+++ b/src/block/twofish/twofish.cpp
@@ -118,7 +118,7 @@ void Twofish::decrypt_n(const byte in[], byte out[], u32bit blocks) const
*/
void Twofish::key_schedule(const byte key[], u32bit length)
{
- SecureBuffer<byte, 16> S;
+ SecureVector<byte, 16> S;
for(u32bit j = 0; j != length; ++j)
rs_mul(S + 4*(j/8), key[j], j);
diff --git a/src/block/twofish/twofish.h b/src/block/twofish/twofish.h
index 71a1e8781..7600abca8 100644
--- a/src/block/twofish/twofish.h
+++ b/src/block/twofish/twofish.h
@@ -41,8 +41,8 @@ class BOTAN_DLL Twofish : public BlockCipher
static const byte EXP_TO_POLY[255];
static const byte POLY_TO_EXP[255];
- SecureBuffer<u32bit, 256> SBox0, SBox1, SBox2, SBox3;
- SecureBuffer<u32bit, 40> round_key;
+ SecureVector<u32bit, 256> SBox0, SBox1, SBox2, SBox3;
+ SecureVector<u32bit, 40> round_key;
};
}
diff --git a/src/block/xtea/xtea.cpp b/src/block/xtea/xtea.cpp
index fc14c0a57..bb1a30374 100644
--- a/src/block/xtea/xtea.cpp
+++ b/src/block/xtea/xtea.cpp
@@ -121,7 +121,7 @@ void XTEA::decrypt_n(const byte in[], byte out[], u32bit blocks) const
*/
void XTEA::key_schedule(const byte key[], u32bit)
{
- SecureBuffer<u32bit, 4> UK;
+ SecureVector<u32bit, 4> UK;
for(u32bit i = 0; i != 4; ++i)
UK[i] = load_be<u32bit>(key, i);
diff --git a/src/block/xtea/xtea.h b/src/block/xtea/xtea.h
index 9982d0712..940992dfa 100644
--- a/src/block/xtea/xtea.h
+++ b/src/block/xtea/xtea.h
@@ -28,7 +28,7 @@ class BOTAN_DLL XTEA : public BlockCipher
XTEA() : BlockCipher(8, 16) {}
protected:
void key_schedule(const byte[], u32bit);
- SecureBuffer<u32bit, 64> EK;
+ SecureVector<u32bit, 64> EK;
};
}
diff --git a/src/filters/base64/base64.cpp b/src/filters/base64/base64.cpp
index 9110dc57e..e342f7109 100644
--- a/src/filters/base64/base64.cpp
+++ b/src/filters/base64/base64.cpp
@@ -107,7 +107,7 @@ void Base64_Encoder::end_msg()
if(left_over)
{
- SecureBuffer<byte, 3> remainder(in + start_of_last_block, left_over);
+ SecureVector<byte, 3> remainder(in + start_of_last_block, left_over);
encode(remainder, out);
@@ -217,7 +217,7 @@ void Base64_Decoder::end_msg()
if(left_over)
{
- SecureBuffer<byte, 4> remainder(in + start_of_last_block, left_over);
+ SecureVector<byte, 4> remainder(in + start_of_last_block, left_over);
decode(remainder, out);
send(out, ((left_over == 1) ? (1) : (left_over - 1)));
}
diff --git a/src/filters/secqueue.cpp b/src/filters/secqueue.cpp
index f63ef898c..c8d1c5fbf 100644
--- a/src/filters/secqueue.cpp
+++ b/src/filters/secqueue.cpp
@@ -44,7 +44,7 @@ class SecureQueueNode
private:
friend class SecureQueue;
SecureQueueNode* next;
- SecureBuffer<byte, DEFAULT_BUFFERSIZE> buffer;
+ SecureVector<byte, DEFAULT_BUFFERSIZE> buffer;
u32bit start, end;
};
diff --git a/src/hash/bmw/bmw_512.h b/src/hash/bmw/bmw_512.h
index 8130a88e4..c1c5238bd 100644
--- a/src/hash/bmw/bmw_512.h
+++ b/src/hash/bmw/bmw_512.h
@@ -23,8 +23,8 @@ class BOTAN_DLL BMW_512 : public MDx_HashFunction
void compress_n(const byte input[], u32bit blocks);
void copy_out(byte output[]);
- SecureBuffer<u64bit, 16> H, M;
- SecureBuffer<u64bit, 32> Q;
+ SecureVector<u64bit, 16> H, M;
+ SecureVector<u64bit, 32> Q;
};
}
diff --git a/src/hash/fork256/fork256.h b/src/hash/fork256/fork256.h
index f535370e6..ed945b9d8 100644
--- a/src/hash/fork256/fork256.h
+++ b/src/hash/fork256/fork256.h
@@ -26,8 +26,8 @@ class BOTAN_DLL FORK_256 : public MDx_HashFunction
void compress_n(const byte[], u32bit blocks);
void copy_out(byte[]);
- SecureBuffer<u32bit, 8> digest;
- SecureBuffer<u32bit, 16> M;
+ SecureVector<u32bit, 8> digest;
+ SecureVector<u32bit, 16> M;
};
}
diff --git a/src/hash/gost_3411/gost_3411.cpp b/src/hash/gost_3411/gost_3411.cpp
index 244a3fddf..f09b0fc60 100644
--- a/src/hash/gost_3411/gost_3411.cpp
+++ b/src/hash/gost_3411/gost_3411.cpp
@@ -223,11 +223,11 @@ void GOST_34_11::final_result(byte out[])
compress_n(buffer, 1);
}
- SecureBuffer<byte, 32> length_buf;
+ SecureVector<byte, 32> length_buf;
const u64bit bit_count = count * 8;
store_le(bit_count, length_buf);
- SecureBuffer<byte, 32> sum_buf(sum);
+ SecureVector<byte, 32> sum_buf(sum);
compress_n(length_buf, 1);
compress_n(sum_buf, 1);
diff --git a/src/hash/gost_3411/gost_3411.h b/src/hash/gost_3411/gost_3411.h
index 7b17bdc1f..d2bada7ab 100644
--- a/src/hash/gost_3411/gost_3411.h
+++ b/src/hash/gost_3411/gost_3411.h
@@ -31,9 +31,9 @@ class BOTAN_DLL GOST_34_11 : public HashFunction
void final_result(byte[]);
GOST_28147_89 cipher;
- SecureBuffer<byte, 32> buffer;
- SecureBuffer<byte, 32> sum;
- SecureBuffer<byte, 32> hash;
+ SecureVector<byte, 32> buffer;
+ SecureVector<byte, 32> sum;
+ SecureVector<byte, 32> hash;
u64bit count;
u32bit position;
};
diff --git a/src/hash/has160/has160.h b/src/hash/has160/has160.h
index cae66c93a..210145484 100644
--- a/src/hash/has160/has160.h
+++ b/src/hash/has160/has160.h
@@ -26,8 +26,8 @@ class BOTAN_DLL HAS_160 : public MDx_HashFunction
void compress_n(const byte[], u32bit blocks);
void copy_out(byte[]);
- SecureBuffer<u32bit, 20> X;
- SecureBuffer<u32bit, 5> digest;
+ SecureVector<u32bit, 20> X;
+ SecureVector<u32bit, 5> digest;
};
}
diff --git a/src/hash/md2/md2.h b/src/hash/md2/md2.h
index 0a7125759..df056dc12 100644
--- a/src/hash/md2/md2.h
+++ b/src/hash/md2/md2.h
@@ -27,8 +27,8 @@ class BOTAN_DLL MD2 : public HashFunction
void hash(const byte[]);
void final_result(byte[]);
- SecureBuffer<byte, 48> X;
- SecureBuffer<byte, 16> checksum, buffer;
+ SecureVector<byte, 48> X;
+ SecureVector<byte, 16> checksum, buffer;
u32bit position;
};
diff --git a/src/hash/md4/md4.h b/src/hash/md4/md4.h
index 0bff5a4ce..843727f6d 100644
--- a/src/hash/md4/md4.h
+++ b/src/hash/md4/md4.h
@@ -27,8 +27,8 @@ class BOTAN_DLL MD4 : public MDx_HashFunction
void hash_old(const byte[]);
void copy_out(byte[]);
- SecureBuffer<u32bit, 16> M;
- SecureBuffer<u32bit, 4> digest;
+ SecureVector<u32bit, 16> M;
+ SecureVector<u32bit, 4> digest;
};
}
diff --git a/src/hash/md5/md5.h b/src/hash/md5/md5.h
index 456a02c28..d1f294a87 100644
--- a/src/hash/md5/md5.h
+++ b/src/hash/md5/md5.h
@@ -26,8 +26,8 @@ class BOTAN_DLL MD5 : public MDx_HashFunction
void compress_n(const byte[], u32bit blocks);
void copy_out(byte[]);
- SecureBuffer<u32bit, 16> M;
- SecureBuffer<u32bit, 4> digest;
+ SecureVector<u32bit, 16> M;
+ SecureVector<u32bit, 4> digest;
};
}
diff --git a/src/hash/rmd128/rmd128.h b/src/hash/rmd128/rmd128.h
index d9cb4ebb4..9ae43483c 100644
--- a/src/hash/rmd128/rmd128.h
+++ b/src/hash/rmd128/rmd128.h
@@ -26,8 +26,8 @@ class BOTAN_DLL RIPEMD_128 : public MDx_HashFunction
void compress_n(const byte[], u32bit blocks);
void copy_out(byte[]);
- SecureBuffer<u32bit, 16> M;
- SecureBuffer<u32bit, 4> digest;
+ SecureVector<u32bit, 16> M;
+ SecureVector<u32bit, 4> digest;
};
}
diff --git a/src/hash/rmd160/rmd160.h b/src/hash/rmd160/rmd160.h
index aee007b98..399d5a7c3 100644
--- a/src/hash/rmd160/rmd160.h
+++ b/src/hash/rmd160/rmd160.h
@@ -26,8 +26,8 @@ class BOTAN_DLL RIPEMD_160 : public MDx_HashFunction
void compress_n(const byte[], u32bit blocks);
void copy_out(byte[]);
- SecureBuffer<u32bit, 16> M;
- SecureBuffer<u32bit, 5> digest;
+ SecureVector<u32bit, 16> M;
+ SecureVector<u32bit, 5> digest;
};
}
diff --git a/src/hash/sha1/sha160.h b/src/hash/sha1/sha160.h
index 142c6bf17..cb7e63821 100644
--- a/src/hash/sha1/sha160.h
+++ b/src/hash/sha1/sha160.h
@@ -29,7 +29,7 @@ class BOTAN_DLL SHA_160 : public MDx_HashFunction
void compress_n(const byte[], u32bit blocks);
void copy_out(byte[]);
- SecureBuffer<u32bit, 5> digest;
+ SecureVector<u32bit, 5> digest;
SecureVector<u32bit> W;
};
diff --git a/src/hash/sha2/sha2_32.h b/src/hash/sha2/sha2_32.h
index 313eec676..e157fd657 100644
--- a/src/hash/sha2/sha2_32.h
+++ b/src/hash/sha2/sha2_32.h
@@ -23,8 +23,8 @@ class BOTAN_DLL SHA_224_256_BASE : public MDx_HashFunction
SHA_224_256_BASE(u32bit out) :
MDx_HashFunction(out, 64, true, true) { clear(); }
- SecureBuffer<u32bit, 64> W;
- SecureBuffer<u32bit, 8> digest;
+ SecureVector<u32bit, 64> W;
+ SecureVector<u32bit, 8> digest;
private:
void compress_n(const byte[], u32bit blocks);
void copy_out(byte[]);
diff --git a/src/hash/sha2/sha2_64.h b/src/hash/sha2/sha2_64.h
index 8e4d171f8..ed261b1c2 100644
--- a/src/hash/sha2/sha2_64.h
+++ b/src/hash/sha2/sha2_64.h
@@ -23,12 +23,12 @@ class BOTAN_DLL SHA_384_512_BASE : public MDx_HashFunction
SHA_384_512_BASE(u32bit out) :
MDx_HashFunction(out, 128, true, true, 16) {}
- SecureBuffer<u64bit, 8> digest;
+ SecureVector<u64bit, 8> digest;
private:
void compress_n(const byte[], u32bit blocks);
void copy_out(byte[]);
- SecureBuffer<u64bit, 80> W;
+ SecureVector<u64bit, 80> W;
};
/*
diff --git a/src/hash/skein/skein_512.cpp b/src/hash/skein/skein_512.cpp
index 869257567..42fc4ba37 100644
--- a/src/hash/skein/skein_512.cpp
+++ b/src/hash/skein/skein_512.cpp
@@ -234,7 +234,7 @@ void Skein_512::final_result(byte out[])
u32bit out_bytes = output_bits / 8;
- SecureBuffer<u64bit, 9> H_out;
+ SecureVector<u64bit, 9> H_out;
while(out_bytes)
{
diff --git a/src/hash/skein/skein_512.h b/src/hash/skein/skein_512.h
index db8d3c8b7..222db5d68 100644
--- a/src/hash/skein/skein_512.h
+++ b/src/hash/skein/skein_512.h
@@ -29,10 +29,10 @@ class BOTAN_DLL Skein_512 : public HashFunction
std::string personalization;
u32bit output_bits;
- SecureBuffer<u64bit, 9> H;
- SecureBuffer<u64bit, 3> T;
+ SecureVector<u64bit, 9> H;
+ SecureVector<u64bit, 3> T;
- SecureBuffer<byte, 64> buffer;
+ SecureVector<byte, 64> buffer;
u32bit buf_pos;
};
diff --git a/src/hash/tiger/tiger.h b/src/hash/tiger/tiger.h
index 20dcf99ff..918e2de3c 100644
--- a/src/hash/tiger/tiger.h
+++ b/src/hash/tiger/tiger.h
@@ -33,8 +33,8 @@ class BOTAN_DLL Tiger : public MDx_HashFunction
static const u64bit SBOX3[256];
static const u64bit SBOX4[256];
- SecureBuffer<u64bit, 8> X;
- SecureBuffer<u64bit, 3> digest;
+ SecureVector<u64bit, 8> X;
+ SecureVector<u64bit, 3> digest;
const u32bit PASS;
};
diff --git a/src/hash/whirlpool/whrlpool.h b/src/hash/whirlpool/whrlpool.h
index 34b4d2302..4711fafa3 100644
--- a/src/hash/whirlpool/whrlpool.h
+++ b/src/hash/whirlpool/whrlpool.h
@@ -34,7 +34,7 @@ class BOTAN_DLL Whirlpool : public MDx_HashFunction
static const u64bit C5[256];
static const u64bit C6[256];
static const u64bit C7[256];
- SecureBuffer<u64bit, 8> M, digest;
+ SecureVector<u64bit, 8> M, digest;
};
}
diff --git a/src/libstate/libstate.cpp b/src/libstate/libstate.cpp
index 943a7c2e6..e37617c94 100644
--- a/src/libstate/libstate.cpp
+++ b/src/libstate/libstate.cpp
@@ -237,36 +237,33 @@ void Library_State::initialize()
load_default_config();
- std::vector<Engine*> engines = {
+ m_algorithm_factory = new Algorithm_Factory(*mutex_factory);
#if defined(BOTAN_HAS_ENGINE_GNU_MP)
- new GMP_Engine,
+ algorithm_factory().add_engine(new GMP_Engine);
#endif
#if defined(BOTAN_HAS_ENGINE_OPENSSL)
- new OpenSSL_Engine,
+ algorithm_factory().add_engine(new OpenSSL_Engine);
#endif
#if defined(BOTAN_HAS_ENGINE_AES_ISA)
- new AES_ISA_Engine,
+ algorithm_factory().add_engine(new AES_ISA_Engine);
#endif
#if defined(BOTAN_HAS_ENGINE_SIMD)
- new SIMD_Engine,
+ algorithm_factory().add_engine(new SIMD_Engine);
#endif
#if defined(BOTAN_HAS_ENGINE_AMD64_ASSEMBLER)
- new AMD64_Assembler_Engine,
+ algorithm_factory().add_engine(new AMD64_Assembler_Engine);
#endif
#if defined(BOTAN_HAS_ENGINE_IA32_ASSEMBLER)
- new IA32_Assembler_Engine,
+ algorithm_factory().add_engine(new IA32_Assembler_Engine);
#endif
- new Default_Engine
- };
-
- m_algorithm_factory = new Algorithm_Factory(engines);
+ algorithm_factory().add_engine(new Default_Engine);
#if defined(BOTAN_HAS_SELFTESTS)
confirm_startup_self_tests(algorithm_factory());
@@ -280,6 +277,8 @@ Library_State::Library_State()
{
cached_default_allocator = 0;
m_algorithm_factory = 0;
+
+ global_rng_ptr = 0;
}
/*
@@ -290,6 +289,10 @@ Library_State::~Library_State()
delete m_algorithm_factory;
m_algorithm_factory = 0;
+ delete global_rng_ptr;
+ global_rng_ptr = 0;
+
+
cached_default_allocator = 0;
for(u32bit j = 0; j != allocators.size(); ++j)
diff --git a/src/mac/x919_mac/x919_mac.h b/src/mac/x919_mac/x919_mac.h
index a4690fdcd..abd149ecd 100644
--- a/src/mac/x919_mac/x919_mac.h
+++ b/src/mac/x919_mac/x919_mac.h
@@ -32,7 +32,7 @@ class BOTAN_DLL ANSI_X919_MAC : public MessageAuthenticationCode
BlockCipher* e;
BlockCipher* d;
- SecureBuffer<byte, 8> state;
+ SecureVector<byte, 8> state;
u32bit position;
};
diff --git a/src/rng/auto_rng/auto_rng.h b/src/rng/auto_rng/auto_rng.h
index 9a93fee8f..90f342a50 100644
--- a/src/rng/auto_rng/auto_rng.h
+++ b/src/rng/auto_rng/auto_rng.h
@@ -35,7 +35,6 @@ class BOTAN_DLL AutoSeeded_RNG : public RandomNumberGenerator
{ rng->add_entropy(in, len); }
AutoSeeded_RNG() { rng = &global_state().global_rng(); }
- ~AutoSeeded_RNG() { delete rng; }
private:
RandomNumberGenerator* rng;
};
diff --git a/src/ssl/c_kex.cpp b/src/ssl/c_kex.cpp
index 9e59beefc..e09e18ce1 100644
--- a/src/ssl/c_kex.cpp
+++ b/src/ssl/c_kex.cpp
@@ -6,6 +6,7 @@
*/
#include <botan/tls_messages.h>
+#include <botan/internal/tls_reader.h>
#include <botan/pubkey.h>
#include <botan/dh.h>
#include <botan/rsa.h>
@@ -99,14 +100,8 @@ void Client_Key_Exchange::deserialize(const MemoryRegion<byte>& buf)
{
if(include_length)
{
- if(buf.size() < 2)
- throw Decoding_Error("Client_Key_Exchange: Packet corrupted");
-
- u32bit size = make_u16bit(buf[0], buf[1]);
- if(size + 2 != buf.size())
- throw Decoding_Error("Client_Key_Exchange: Packet corrupted");
-
- key_material.set(buf + 2, size);
+ TLS_Data_Reader reader(buf);
+ key_material = reader.get_range<byte>(2, 0, 65535);
}
else
key_material = buf;
diff --git a/src/ssl/cert_ver.cpp b/src/ssl/cert_ver.cpp
index 0bf6c85be..3edf4266d 100644
--- a/src/ssl/cert_ver.cpp
+++ b/src/ssl/cert_ver.cpp
@@ -6,6 +6,7 @@
*/
#include <botan/tls_messages.h>
+#include <botan/internal/tls_reader.h>
#include <botan/pubkey.h>
#include <botan/rsa.h>
#include <botan/dsa.h>
@@ -62,14 +63,8 @@ SecureVector<byte> Certificate_Verify::serialize() const
*/
void Certificate_Verify::deserialize(const MemoryRegion<byte>& buf)
{
- if(buf.size() < 2)
- throw Decoding_Error("Certificate_Verify: Corrupted packet");
-
- u32bit sig_len = make_u16bit(buf[0], buf[1]);
- if(buf.size() != 2 + sig_len)
- throw Decoding_Error("Certificate_Verify: Corrupted packet");
-
- signature.set(buf + 2, sig_len);
+ TLS_Data_Reader reader(buf);
+ signature = reader.get_range<byte>(2, 0, 65535);
}
/**
diff --git a/src/ssl/finished.cpp b/src/ssl/finished.cpp
index edbd4a3fe..b0f6abd25 100644
--- a/src/ssl/finished.cpp
+++ b/src/ssl/finished.cpp
@@ -72,7 +72,7 @@ SecureVector<byte> Finished::compute_verify(const MemoryRegion<byte>& secret,
return hash.final_ssl3(secret);
}
- else if(version == TLS_V10)
+ else if(version == TLS_V10 || version == TLS_V11)
{
const byte TLS_CLIENT_LABEL[] = {
0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x69,
diff --git a/src/ssl/hello.cpp b/src/ssl/hello.cpp
index 53f680fba..a23d51c24 100644
--- a/src/ssl/hello.cpp
+++ b/src/ssl/hello.cpp
@@ -1,12 +1,12 @@
/**
* TLS Hello Messages
-* (C) 2004-2006 Jack Lloyd
+* (C) 2004-2010 Jack Lloyd
*
* Released under the terms of the Botan license
*/
#include <botan/tls_messages.h>
-#include <botan/loadstor.h>
+#include <botan/internal/tls_reader.h>
namespace Botan {
@@ -93,15 +93,15 @@ SecureVector<byte> Client_Hello::serialize() const
buf.append(get_byte(0, suites_size));
buf.append(get_byte(1, suites_size));
- for(u32bit j = 0; j != suites.size(); j++)
+ for(u32bit i = 0; i != suites.size(); i++)
{
- buf.append(get_byte(0, suites[j]));
- buf.append(get_byte(1, suites[j]));
+ buf.append(get_byte(0, suites[i]));
+ buf.append(get_byte(1, suites[i]));
}
buf.append(static_cast<byte>(comp_algos.size()));
- for(u32bit j = 0; j != comp_algos.size(); j++)
- buf.append(comp_algos[j]);
+ for(u32bit i = 0; i != comp_algos.size(); i++)
+ buf.append(comp_algos[i]);
return buf;
}
@@ -117,38 +117,61 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf)
if(buf.size() < 41)
throw Decoding_Error("Client_Hello: Packet corrupted");
- c_version = static_cast<Version_Code>(make_u16bit(buf[0], buf[1]));
- if(c_version != SSL_V3 && c_version != TLS_V10)
- throw TLS_Exception(PROTOCOL_VERSION, "Client_Hello: Bad version code");
+ TLS_Data_Reader reader(buf);
- c_random.set(buf + 2, 32);
+ c_version = static_cast<Version_Code>(reader.get_u16bit());
+ c_random = reader.get_fixed<byte>(32);
- u32bit session_id_len = buf[34];
- if(session_id_len > 32 || session_id_len + 41 > buf.size())
- throw Decoding_Error("Client_Hello: Packet corrupted");
- sess_id.copy(buf + 35, session_id_len);
+ sess_id = reader.get_range<byte>(1, 0, 32);
- u32bit offset = 2+32+1+session_id_len;
+ suites = reader.get_range_vector<u16bit>(2, 1, 32767);
- u16bit suites_size = make_u16bit(buf[offset], buf[offset+1]);
- offset += 2;
- if(suites_size % 2 == 1 || offset + suites_size + 2 > buf.size())
- throw Decoding_Error("Client_Hello: Packet corrupted");
+ comp_algos = reader.get_range_vector<byte>(1, 1, 255);
- for(u32bit j = 0; j != suites_size; j += 2)
+ if(reader.has_remaining())
{
- u16bit suite = make_u16bit(buf[offset+j], buf[offset+j+1]);
- suites.push_back(suite);
+ const u16bit all_extn_size = reader.get_u16bit();
+
+ if(reader.remaining_bytes() != all_extn_size)
+ throw Decoding_Error("Client_Hello: Bad extension size");
+
+ while(reader.has_remaining())
+ {
+ const u16bit extension_code = reader.get_u16bit();
+ const u16bit extension_size = reader.get_u16bit();
+
+ if(extension_code == TLSEXT_SERVER_NAME_INDICATION)
+ {
+ u16bit name_bytes = reader.get_u16bit();
+
+ while(name_bytes)
+ {
+ byte name_type = reader.get_byte();
+ name_bytes--;
+
+ if(name_type == 0) // DNS
+ {
+ std::vector<byte> name =
+ reader.get_range_vector<byte>(2, 1, 65535);
+
+ requested_hostname.assign((const char*)&name[0],
+ name.size());
+
+ name_bytes -= (2 + name.size());
+ }
+ else
+ {
+ reader.discard_next(name_bytes);
+ name_bytes = 0;
+ }
+ }
+ }
+ else
+ {
+ reader.discard_next(extension_size);
+ }
+ }
}
- offset += suites_size;
-
- byte comp_algo_size = buf[offset];
- offset += 1;
- if(offset + comp_algo_size > buf.size())
- throw Decoding_Error("Client_Hello: Packet corrupted");
-
- for(u32bit j = 0; j != comp_algo_size; j++)
- comp_algos.push_back(buf[offset+j]);
}
/**
@@ -156,8 +179,8 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf)
*/
bool Client_Hello::offered_suite(u16bit ciphersuite) const
{
- for(u32bit j = 0; j != suites.size(); j++)
- if(suites[j] == ciphersuite)
+ for(u32bit i = 0; i != suites.size(); i++)
+ if(suites[i] == ciphersuite)
return true;
return false;
}
@@ -172,11 +195,15 @@ Server_Hello::Server_Hello(RandomNumberGenerator& rng,
HandshakeHash& hash)
{
bool have_rsa = false, have_dsa = false;
- for(u32bit j = 0; j != certs.size(); j++)
+
+ for(u32bit i = 0; i != certs.size(); i++)
{
- Public_Key* key = certs[j].subject_public_key();
- if(key->algo_name() == "RSA") have_rsa = true;
- if(key->algo_name() == "DSA") have_dsa = true;
+ Public_Key* key = certs[i].subject_public_key();
+ if(key->algo_name() == "RSA")
+ have_rsa = true;
+
+ if(key->algo_name() == "DSA")
+ have_dsa = true;
}
suite = policy->choose_suite(c_hello.ciphersuites(), have_rsa, have_dsa);
@@ -218,23 +245,24 @@ void Server_Hello::deserialize(const MemoryRegion<byte>& buf)
if(buf.size() < 38)
throw Decoding_Error("Server_Hello: Packet corrupted");
- s_version = static_cast<Version_Code>(make_u16bit(buf[0], buf[1]));
- if(s_version != SSL_V3 && s_version != TLS_V10)
+ TLS_Data_Reader reader(buf);
+
+ s_version = static_cast<Version_Code>(reader.get_u16bit());
+
+ if(s_version != SSL_V3 && s_version != TLS_V10 && s_version != TLS_V11)
+ {
throw TLS_Exception(PROTOCOL_VERSION,
"Server_Hello: Unsupported server version");
+ }
- s_random.set(buf + 2, 32);
+ s_random = reader.get_fixed<byte>(32);
- u32bit session_id_len = buf[2+32];
- if(session_id_len > 32 || session_id_len + 38 != buf.size())
- throw Decoding_Error("Server_Hello: Packet corrupted");
- sess_id.copy(buf + 2 + 32 + 1, session_id_len);
+ sess_id = reader.get_range<byte>(1, 0, 32);
- suite = make_u16bit(buf[2+32+1+session_id_len],
- buf[2+32+1+session_id_len+1]);
- comp_algo = buf[2+32+1+session_id_len+2];
- }
+ suite = reader.get_u16bit();
+ comp_algo = reader.get_byte();
+ }
/**
* Create a new Server Hello Done message
diff --git a/src/ssl/info.txt b/src/ssl/info.txt
index 73e4207d8..1d28cf4f8 100644
--- a/src/ssl/info.txt
+++ b/src/ssl/info.txt
@@ -1 +1,40 @@
define SSL_TLS
+
+<header:public>
+handshake_hash.h
+socket.h
+tls_alerts.h
+tls_client.h
+tls_connection.h
+tls_exceptn.h
+tls_magic.h
+tls_messages.h
+tls_policy.h
+tls_record.h
+tls_server.h
+tls_session_key.h
+tls_state.h
+tls_suites.h
+</header:public>
+
+<header:internal>
+tls_reader.h
+</header:internal>
+
+<source>
+c_kex.cpp
+cert_req.cpp
+cert_ver.cpp
+finished.cpp
+handshake_hash.cpp
+handshake_state.cpp
+hello.cpp
+rec_read.cpp
+rec_wri.cpp
+s_kex.cpp
+tls_client.cpp
+tls_policy.cpp
+tls_server.cpp
+tls_session_key.cpp
+tls_suites.cpp
+</source>
diff --git a/src/ssl/rec_read.cpp b/src/ssl/rec_read.cpp
index 95059dbf2..8f8e5dc1e 100644
--- a/src/ssl/rec_read.cpp
+++ b/src/ssl/rec_read.cpp
@@ -1,6 +1,6 @@
/**
-* TLS Record Reading
-* (C) 2004-2006 Jack Lloyd
+* TLS Record Reading
+* (C) 2004-2010 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -13,23 +13,15 @@
namespace Botan {
/**
-* Record_Reader Constructor
-*/
-Record_Reader::Record_Reader(Socket& sock) : socket(sock)
- {
- reset();
- }
-
-/**
* Reset the state
*/
void Record_Reader::reset()
{
- compress.reset();
cipher.reset();
mac.reset();
- do_compress = false;
- mac_size = pad_amount = 0;
+ mac_size = 0;
+ block_size = 0;
+ iv_size = 0;
major = minor = 0;
seq_no = 0;
}
@@ -39,7 +31,7 @@ void Record_Reader::reset()
*/
void Record_Reader::set_version(Version_Code version)
{
- if(version != SSL_V3 && version != TLS_V10)
+ if(version != SSL_V3 && version != TLS_V10 && version != TLS_V11)
throw Invalid_Argument("Record_Reader: Invalid protocol version");
major = (version >> 8) & 0xFF;
@@ -47,15 +39,6 @@ void Record_Reader::set_version(Version_Code version)
}
/**
-* Set the compression algorithm
-*/
-void Record_Reader::set_compressor(Filter* compressor)
- {
- compress.append(compressor);
- do_compress = true;
- }
-
-/**
* Set the keys for reading
*/
void Record_Reader::set_keys(const CipherSuite& suite, const SessionKeys& keys,
@@ -89,12 +72,18 @@ void Record_Reader::set_keys(const CipherSuite& suite, const SessionKeys& keys,
cipher_algo + "/CBC/NoPadding",
cipher_key, iv, DECRYPTION)
);
- pad_amount = block_size_of(cipher_algo);
+ block_size = block_size_of(cipher_algo);
+
+ if(major == 3 && minor >= 2)
+ iv_size = block_size;
+ else
+ iv_size = 0;
}
else if(have_stream_cipher(cipher_algo))
{
cipher.append(get_cipher(cipher_algo, cipher_key, DECRYPTION));
- pad_amount = 0;
+ block_size = 0;
+ iv_size = 0;
}
else
throw Invalid_Argument("Record_Reader: Unknown cipher " + cipher_algo);
@@ -112,75 +101,102 @@ void Record_Reader::set_keys(const CipherSuite& suite, const SessionKeys& keys,
throw Invalid_Argument("Record_Reader: Unknown hash " + mac_algo);
}
+void Record_Reader::add_input(const byte input[], u32bit input_size)
+ {
+ input_queue.write(input, input_size);
+ }
+
/**
* Retrieve the next record
*/
-SecureVector<byte> Record_Reader::get_record(byte& msg_type)
+u32bit Record_Reader::get_record(byte& msg_type,
+ MemoryRegion<byte>& output)
{
byte header[5] = { 0 };
- u32bit got = socket.read(header, sizeof(header));
+ const u32bit have_in_queue = input_queue.size();
- if(got == 0)
- {
- msg_type = CONNECTION_CLOSED;
- return SecureVector<byte>();
- }
- else if(got != sizeof(header))
- throw Decoding_Error("Record_Reader: Record truncated");
+ if(have_in_queue < sizeof(header))
+ return (sizeof(header) - have_in_queue);
- msg_type = header[0];
+ /*
+ * We peek first to make sure we have the full record
+ */
+ input_queue.peek(header, sizeof(header));
- const u16bit version = make_u16bit(header[1], header[2]);
+ const u16bit version = make_u16bit(header[1], header[2]);
+ const u16bit record_len = make_u16bit(header[3], header[4]);
if(major && (header[1] != major || header[2] != minor))
throw TLS_Exception(PROTOCOL_VERSION,
"Record_Reader: Got unexpected version");
- SecureVector<byte> buffer(make_u16bit(header[3], header[4]));
- if(socket.read(buffer, buffer.size()) != buffer.size())
- throw Decoding_Error("Record_Reader: Record truncated");
+ // If insufficient data, return without doing anything
+ if(have_in_queue < (sizeof(header) + record_len))
+ return (sizeof(header) + record_len - have_in_queue);
+
+ SecureVector<byte> buffer(record_len);
+ input_queue.read(header, sizeof(header)); // pull off the header
+ input_queue.read(buffer, buffer.size());
+
+ /*
+ * We are handshaking, no crypto to do so return as-is
+ * TODO: Check msg_type to confirm a handshake?
+ */
if(mac_size == 0)
- return buffer;
+ {
+ msg_type = header[0];
+ output = buffer;
+ return 0; // got a full record
+ }
+
+ // Otherwise, decrypt, check MAC, return plaintext
cipher.process_msg(buffer);
SecureVector<byte> plaintext = cipher.read_all(Pipe::LAST_MESSAGE);
u32bit pad_size = 0;
- if(pad_amount)
+
+ if(block_size)
{
byte pad_value = plaintext[plaintext.size()-1];
pad_size = pad_value + 1;
+ /*
+ * Check the padding; if it is wrong, then say we have 0 bytes of
+ * padding, which should ensure that the MAC check below does not
+ * suceed. This hides a timing channel.
+ *
+ * This particular countermeasure is recommended in the TLS 1.2
+ * spec (RFC 5246) in section 6.2.3.2
+ */
if(version == SSL_V3)
{
- if(pad_value > pad_amount)
- throw TLS_Exception(BAD_RECORD_MAC,
- "Record_Reader: Bad padding");
+ if(pad_value > block_size)
+ pad_size = 0;
}
else
{
for(u32bit j = 0; j != pad_size; j++)
if(plaintext[plaintext.size()-j-1] != pad_value)
- throw TLS_Exception(BAD_RECORD_MAC,
- "Record_Reader: Bad padding");
+ pad_size = 0;
}
}
- if(plaintext.size() < mac_size + pad_size)
+ if(plaintext.size() < mac_size + pad_size + iv_size)
throw Decoding_Error("Record_Reader: Record truncated");
const u32bit mac_offset = plaintext.size() - (mac_size + pad_size);
SecureVector<byte> recieved_mac(plaintext.begin() + mac_offset,
mac_size);
- const u16bit plain_length = plaintext.size() - (mac_size + pad_size);
+ const u16bit plain_length = plaintext.size() - (mac_size + pad_size + iv_size);
mac.start_msg();
for(u32bit j = 0; j != 8; j++)
mac.write(get_byte(j, seq_no));
- mac.write(msg_type);
+ mac.write(header[0]); // msg_type
if(version != SSL_V3)
for(u32bit j = 0; j != 2; j++)
@@ -188,7 +204,7 @@ SecureVector<byte> Record_Reader::get_record(byte& msg_type)
for(u32bit j = 0; j != 2; j++)
mac.write(get_byte(j, plain_length));
- mac.write(plaintext, plain_length);
+ mac.write(&plaintext[iv_size], plain_length);
mac.end_msg();
++seq_no;
@@ -198,7 +214,9 @@ SecureVector<byte> Record_Reader::get_record(byte& msg_type)
if(recieved_mac != computed_mac)
throw TLS_Exception(BAD_RECORD_MAC, "Record_Reader: MAC failure");
- return SecureVector<byte>(plaintext, mac_offset);
+ msg_type = header[0];
+ output.set(&plaintext[iv_size], plain_length);
+ return 0;
}
}
diff --git a/src/ssl/rec_wri.cpp b/src/ssl/rec_wri.cpp
index 842b2698c..f8079c235 100644
--- a/src/ssl/rec_wri.cpp
+++ b/src/ssl/rec_wri.cpp
@@ -1,6 +1,6 @@
/**
-* TLS Record Writing
-* (C) 2004-2006 Jack Lloyd
+* TLS Record Writing
+* (C) 2004-2010 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -9,6 +9,7 @@
#include <botan/handshake_hash.h>
#include <botan/lookup.h>
#include <botan/loadstor.h>
+#include <botan/libstate.h>
namespace Botan {
@@ -26,13 +27,17 @@ Record_Writer::Record_Writer(Socket& sock) :
*/
void Record_Writer::reset()
{
- compress.reset();
cipher.reset();
mac.reset();
+
buffer.clear();
- do_compress = false;
+ buf_pos = 0;
+
major = minor = buf_type = 0;
- pad_amount = mac_size = buf_pos = 0;
+ block_size = 0;
+ mac_size = 0;
+ iv_size = 0;
+
seq_no = 0;
}
@@ -41,7 +46,7 @@ void Record_Writer::reset()
*/
void Record_Writer::set_version(Version_Code version)
{
- if(version != SSL_V3 && version != TLS_V10)
+ if(version != SSL_V3 && version != TLS_V10 && version != TLS_V11)
throw Invalid_Argument("Record_Writer: Invalid protocol version");
major = (version >> 8) & 0xFF;
@@ -49,15 +54,6 @@ void Record_Writer::set_version(Version_Code version)
}
/**
-* Set the compression algorithm
-*/
-void Record_Writer::set_compressor(Filter* compressor)
- {
- throw TLS_Exception(INTERNAL_ERROR, "Compression not implemented (FIXME)");
- compress.append(compressor);
- }
-
-/**
* Set the keys for writing
*/
void Record_Writer::set_keys(const CipherSuite& suite, const SessionKeys& keys,
@@ -91,12 +87,18 @@ void Record_Writer::set_keys(const CipherSuite& suite, const SessionKeys& keys,
cipher_algo + "/CBC/NoPadding",
cipher_key, iv, ENCRYPTION)
);
- pad_amount = block_size_of(cipher_algo);
+ block_size = block_size_of(cipher_algo);
+
+ if(major == 3 && minor >= 2)
+ iv_size = block_size;
+ else
+ iv_size = 0;
}
else if(have_stream_cipher(cipher_algo))
{
cipher.append(get_cipher(cipher_algo, cipher_key, ENCRYPTION));
- pad_amount = 0;
+ block_size = 0;
+ iv_size = 0;
}
else
throw Invalid_Argument("Record_Writer: Unknown cipher " + cipher_algo);
@@ -203,15 +205,30 @@ void Record_Writer::send_record(byte type, const byte buf[], u32bit length)
mac.write(buf, length);
mac.end_msg();
+ // TODO: This could all use a single buffer
+
SecureVector<byte> buf_mac = mac.read_all(Pipe::LAST_MESSAGE);
cipher.start_msg();
+
+ if(iv_size)
+ {
+ RandomNumberGenerator& rng = global_state().global_rng();
+
+ SecureVector<byte> random_iv(iv_size);
+
+ rng.randomize(&random_iv[0], random_iv.size());
+
+ cipher.write(random_iv);
+ }
+
cipher.write(buf, length);
cipher.write(buf_mac);
- if(pad_amount)
+
+ if(block_size)
{
u32bit pad_val =
- (pad_amount - (1 + length + buf_mac.size())) % pad_amount;
+ (block_size - (1 + length + buf_mac.size())) % block_size;
for(u32bit j = 0; j != pad_val + 1; j++)
cipher.write(pad_val);
@@ -240,7 +257,6 @@ void Record_Writer::send_record(byte type, byte major, byte minor,
for(u32bit j = 0; j != 2; j++)
header[j+3] = get_byte<u16bit>(j, length);
- // FIXME: tradoff of TCP/syscall overhead vs copy overhead
socket.write(header, 5);
socket.write(out, length);
}
diff --git a/src/ssl/s_kex.cpp b/src/ssl/s_kex.cpp
index 3223adc5b..9b8a3171d 100644
--- a/src/ssl/s_kex.cpp
+++ b/src/ssl/s_kex.cpp
@@ -51,7 +51,7 @@ Server_Key_Exchange::Server_Key_Exchange(RandomNumberGenerator& rng,
padding = "EMSA3(TLS.Digest.0)";
else if(priv_key->algo_name() == "DSA")
{
- padding == "EMSA1(SHA-1)";
+ padding = "EMSA1(SHA-1)";
format = DER_SEQUENCE;
}
else
diff --git a/src/ssl/socket.h b/src/ssl/socket.h
index 3d893ea77..62ceed028 100644
--- a/src/ssl/socket.h
+++ b/src/ssl/socket.h
@@ -19,11 +19,8 @@ namespace Botan {
class BOTAN_DLL Socket
{
public:
- virtual u32bit read(byte[], u32bit) = 0;
- virtual void write(const byte[], u32bit) = 0;
-
- u32bit read(byte& x) { return read(&x, 1); }
- void write(byte x) { write(&x, 1); }
+ virtual size_t read(byte[], size_t) = 0;
+ virtual void write(const byte[], size_t) = 0;
virtual std::string peer_id() const = 0;
diff --git a/src/ssl/tls_client.cpp b/src/ssl/tls_client.cpp
index ce33573f5..fbad1f838 100644
--- a/src/ssl/tls_client.cpp
+++ b/src/ssl/tls_client.cpp
@@ -1,6 +1,6 @@
/**
-* TLS Client
-* (C) 2004-2006 Jack Lloyd
+* TLS Client
+* (C) 2004-2010 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -83,7 +83,7 @@ void client_check_state(Handshake_Type new_msg, Handshake_State* state)
*/
TLS_Client::TLS_Client(RandomNumberGenerator& r,
Socket& sock, const TLS_Policy* pol) :
- rng(r), writer(sock), reader(sock), policy(pol ? pol : new TLS_Policy)
+ rng(r), peer(sock), writer(sock), policy(pol ? pol : new TLS_Policy)
{
peer_id = sock.peer_id();
@@ -96,7 +96,7 @@ TLS_Client::TLS_Client(RandomNumberGenerator& r,
TLS_Client::TLS_Client(RandomNumberGenerator& r,
Socket& sock, const X509_Certificate& cert,
const Private_Key& key, const TLS_Policy* pol) :
- rng(r), writer(sock), reader(sock), policy(pol ? pol : new TLS_Policy)
+ rng(r), peer(sock), writer(sock), policy(pol ? pol : new TLS_Policy)
{
peer_id = sock.peer_id();
@@ -243,8 +243,26 @@ void TLS_Client::close(Alert_Level level, Alert_Type alert_code)
*/
void TLS_Client::state_machine()
{
- byte rec_type;
- SecureVector<byte> record = reader.get_record(rec_type);
+ byte rec_type = CONNECTION_CLOSED;
+ SecureVector<byte> record(1024);
+
+ u32bit bytes_needed = reader.get_record(rec_type, record);
+
+ while(bytes_needed)
+ {
+ u32bit to_get = std::min<u32bit>(record.size(), bytes_needed);
+ u32bit got = peer.read(&record[0], to_get);
+
+ if(got == 0)
+ {
+ rec_type = CONNECTION_CLOSED;
+ break;
+ }
+
+ reader.add_input(&record[0], got);
+
+ bytes_needed = reader.get_record(rec_type, record);
+ }
if(rec_type == CONNECTION_CLOSED)
{
@@ -562,7 +580,7 @@ void TLS_Client::do_handshake()
if(active && !state)
break;
if(!active && !state)
- throw TLS_Exception(HANDSHAKE_FAILURE, "TLS_Client: Handshake failed");
+ throw TLS_Exception(HANDSHAKE_FAILURE, "TLS_Client: Handshake failed (do_handshake)");
state_machine();
}
diff --git a/src/ssl/tls_client.h b/src/ssl/tls_client.h
index 896decdf9..2439a58f0 100644
--- a/src/ssl/tls_client.h
+++ b/src/ssl/tls_client.h
@@ -60,6 +60,8 @@ class BOTAN_DLL TLS_Client : public TLS_Connection
RandomNumberGenerator& rng;
+ Socket& peer;
+
Record_Writer writer;
Record_Reader reader;
const TLS_Policy* policy;
diff --git a/src/ssl/tls_magic.h b/src/ssl/tls_magic.h
index 41fb756e9..a6ca1f8d6 100644
--- a/src/ssl/tls_magic.h
+++ b/src/ssl/tls_magic.h
@@ -115,6 +115,17 @@ enum Compression_Algo {
NO_COMPRESSION = 0x00
};
+enum TLS_Handshake_Extension_Type {
+ TLSEXT_SERVER_NAME_INDICATION = 0,
+ TLSEXT_MAX_FRAGMENT_LENGTH = 1,
+ TLSEXT_CLIENT_CERT_URL = 2,
+ TLSEXT_TRUSTED_CA_KEYS = 3,
+ TLSEXT_TRUNCATED_HMAC = 4,
+
+ TLSEXT_CERTIFICATE_TYPES = 9,
+ TLSEXT_SESSION_TICKET = 35,
+};
+
}
#endif
diff --git a/src/ssl/tls_messages.h b/src/ssl/tls_messages.h
index 4b512a963..1f72c05f7 100644
--- a/src/ssl/tls_messages.h
+++ b/src/ssl/tls_messages.h
@@ -49,6 +49,8 @@ class BOTAN_DLL Client_Hello : public HandshakeMessage
SecureVector<byte> random() const { return c_random; }
+ std::string hostname() const { return requested_hostname; }
+
bool offered_suite(u16bit) const;
Client_Hello(RandomNumberGenerator& rng,
@@ -63,6 +65,7 @@ class BOTAN_DLL Client_Hello : public HandshakeMessage
SecureVector<byte> sess_id, c_random;
std::vector<u16bit> suites;
std::vector<byte> comp_algos;
+ std::string requested_hostname;
};
/**
diff --git a/src/ssl/tls_policy.h b/src/ssl/tls_policy.h
index 98297181c..75d6d7663 100644
--- a/src/ssl/tls_policy.h
+++ b/src/ssl/tls_policy.h
@@ -40,7 +40,7 @@ class BOTAN_DLL TLS_Policy
virtual u32bit rsa_export_keysize() const { return 512; }
virtual Version_Code min_version() const { return SSL_V3; }
- virtual Version_Code pref_version() const { return TLS_V10; }
+ virtual Version_Code pref_version() const { return TLS_V11; }
virtual bool check_cert(const std::vector<X509_Certificate>&,
const std::string&) const;
diff --git a/src/ssl/tls_reader.h b/src/ssl/tls_reader.h
new file mode 100644
index 000000000..ff3e63ae8
--- /dev/null
+++ b/src/ssl/tls_reader.h
@@ -0,0 +1,140 @@
+/*
+* TLS Data Reader
+* (C) 2010 Jack Lloyd
+*
+* Released under the terms of the Botan license
+*/
+
+#ifndef BOTAN_TLS_READER_H__
+#define BOTAN_TLS_READER_H__
+
+#include <botan/secmem.h>
+#include <botan/loadstor.h>
+
+namespace Botan {
+
+class TLS_Data_Reader
+ {
+ public:
+ TLS_Data_Reader(const MemoryRegion<byte>& buf_in) :
+ buf(buf_in), offset(0) {}
+
+ u32bit remaining_bytes() const
+ {
+ return buf.size() - offset;
+ }
+
+ bool has_remaining() const
+ {
+ return (remaining_bytes() > 0);
+ }
+
+ void discard_next(u32bit bytes)
+ {
+ assert_at_least(bytes);
+ offset += bytes;
+ }
+
+ u16bit get_u16bit()
+ {
+ assert_at_least(2);
+ u16bit result = make_u16bit(buf[offset], buf[offset+1]);
+ offset += 2;
+ return result;
+ }
+
+ byte get_byte()
+ {
+ assert_at_least(1);
+ byte result = buf[offset];
+ offset += 1;
+ return result;
+ }
+
+ template<typename T, typename Container>
+ Container get_elem(u32bit num_elems)
+ {
+ assert_at_least(num_elems * sizeof(T));
+
+ Container result(num_elems);
+
+ for(u32bit i = 0; i != num_elems; ++i)
+ result[i] = load_be<T>(&buf[offset], i);
+
+ offset += num_elems * sizeof(T);
+
+ return result;
+ }
+
+ template<typename T>
+ SecureVector<T> get_range(u32bit len_bytes,
+ u32bit min_elems,
+ u32bit max_elems)
+ {
+ const u32bit num_elems =
+ get_num_elems(len_bytes, sizeof(T), min_elems, max_elems);
+
+ return get_elem<T, SecureVector<T> >(num_elems);
+ }
+
+ template<typename T>
+ std::vector<T> get_range_vector(u32bit len_bytes,
+ u32bit min_elems,
+ u32bit max_elems)
+ {
+ const u32bit num_elems =
+ get_num_elems(len_bytes, sizeof(T), min_elems, max_elems);
+
+ return get_elem<T, std::vector<T> >(num_elems);
+ }
+
+ template<typename T>
+ SecureVector<T> get_fixed(u32bit size)
+ {
+ return get_elem<T, SecureVector<T> >(size);
+ }
+
+ private:
+ u32bit get_length_field(u32bit len_bytes)
+ {
+ assert_at_least(len_bytes);
+
+ if(len_bytes == 1)
+ return get_byte();
+ else if(len_bytes == 2)
+ return get_u16bit();
+
+ throw Decoding_Error("TLS_Data_Reader: Bad length size");
+ }
+
+ u32bit get_num_elems(u32bit len_bytes,
+ u32bit T_size,
+ u32bit min_elems,
+ u32bit max_elems)
+ {
+ const u32bit byte_length = get_length_field(len_bytes);
+
+ if(byte_length % T_size != 0)
+ throw Decoding_Error("TLS_Data_Reader: Size isn't multiple of T");
+
+ const u32bit num_elems = byte_length / T_size;
+
+ if(num_elems < min_elems || num_elems > max_elems)
+ throw Decoding_Error("TLS_Data_Reader: Range outside paramaters");
+
+ return num_elems;
+ }
+
+ void assert_at_least(u32bit n) const
+ {
+ if(buf.size() - offset < n)
+ throw Decoding_Error("TLS_Data_Reader: Corrupt packet");
+ }
+
+ const MemoryRegion<byte>& buf;
+ u32bit offset;
+ };
+
+}
+
+#endif
diff --git a/src/ssl/tls_record.h b/src/ssl/tls_record.h
index 3bec2e8ef..2058933d0 100644
--- a/src/ssl/tls_record.h
+++ b/src/ssl/tls_record.h
@@ -1,6 +1,6 @@
/**
-* TLS Record Handling
-* (C) 2004-2006 Jack Lloyd
+* TLS Record Handling
+* (C) 2004-2010 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -12,6 +12,7 @@
#include <botan/socket.h>
#include <botan/tls_suites.h>
#include <botan/pipe.h>
+#include <botan/secqueue.h>
#include <vector>
namespace Botan {
@@ -29,24 +30,26 @@ class BOTAN_DLL Record_Writer
void alert(Alert_Level, Alert_Type);
void set_keys(const CipherSuite&, const SessionKeys&, Connection_Side);
- void set_compressor(Filter*);
void set_version(Version_Code);
void reset();
- Record_Writer(Socket&);
+ Record_Writer(Socket& socket);
+
private:
void send_record(byte, const byte[], u32bit);
void send_record(byte, byte, byte, const byte[], u32bit);
Socket& socket;
- Pipe compress, cipher, mac;
+ Pipe cipher, mac;
SecureVector<byte> buffer;
- u32bit pad_amount, mac_size, buf_pos;
+ u32bit buf_pos;
+
+ u32bit block_size, mac_size, iv_size;
+
u64bit seq_no;
byte major, minor, buf_type;
- bool do_compress;
};
/**
@@ -55,23 +58,34 @@ class BOTAN_DLL Record_Writer
class BOTAN_DLL Record_Reader
{
public:
- SecureVector<byte> get_record(byte&);
+ void add_input(const byte input[], u32bit input_size);
- void set_keys(const CipherSuite&, const SessionKeys&, Connection_Side);
- void set_compressor(Filter*);
+ /**
+ * @param msg_type (output variable)
+ * @param buffer (output variable)
+ * @return Number of bytes still needed (minimum), or 0 if success
+ */
+ u32bit get_record(byte& msg_type,
+ MemoryRegion<byte>& buffer);
- void set_version(Version_Code);
+ SecureVector<byte> get_record(byte& msg_type);
+
+ void set_keys(const CipherSuite& suite,
+ const SessionKeys& keys,
+ Connection_Side side);
+
+ void set_version(Version_Code version);
void reset();
- Record_Reader(Socket&);
+ Record_Reader() { reset(); }
private:
- Socket& socket;
- Pipe compress, cipher, mac;
- u32bit pad_amount, mac_size;
+ SecureQueue input_queue;
+
+ Pipe cipher, mac;
+ u32bit block_size, mac_size, iv_size;
u64bit seq_no;
byte major, minor;
- bool do_compress;
};
}
diff --git a/src/ssl/tls_server.cpp b/src/ssl/tls_server.cpp
index 37d9dbcd1..47902a71c 100644
--- a/src/ssl/tls_server.cpp
+++ b/src/ssl/tls_server.cpp
@@ -25,9 +25,9 @@ Version_Code choose_version(Version_Code client, Version_Code minimum)
throw TLS_Exception(PROTOCOL_VERSION,
"Client version is unacceptable by policy");
- if(client == SSL_V3 || client == TLS_V10)
+ if(client == SSL_V3 || client == TLS_V10 || client == TLS_V11)
return client;
- return TLS_V10;
+ return TLS_V11;
}
// FIXME: checks are wrong for session reuse (add a flag for that)
@@ -88,7 +88,8 @@ void server_check_state(Handshake_Type new_msg, Handshake_State* state)
TLS_Server::TLS_Server(RandomNumberGenerator& r,
Socket& sock, const X509_Certificate& cert,
const Private_Key& key, const TLS_Policy* pol) :
- rng(r), writer(sock), reader(sock), policy(pol ? pol : new TLS_Policy)
+ rng(r), peer(sock),
+ writer(sock), policy(pol ? pol : new TLS_Policy)
{
peer_id = sock.peer_id();
@@ -112,7 +113,8 @@ TLS_Server::TLS_Server(RandomNumberGenerator& r,
}
writer.alert(FATAL, HANDSHAKE_FAILURE);
- throw Stream_IO_Error("TLS_Server: Handshake failed");
+ throw Stream_IO_Error(std::string("TLS_Server: Handshake failed: ") +
+ e.what());
}
}
@@ -207,8 +209,26 @@ void TLS_Server::close(Alert_Level level, Alert_Type alert_code)
*/
void TLS_Server::state_machine()
{
- byte rec_type;
- SecureVector<byte> record = reader.get_record(rec_type);
+ byte rec_type = CONNECTION_CLOSED;
+ SecureVector<byte> record(1024);
+
+ u32bit bytes_needed = reader.get_record(rec_type, record);
+
+ while(bytes_needed)
+ {
+ u32bit to_get = std::min<u32bit>(record.size(), bytes_needed);
+ u32bit got = peer.read(&record[0], to_get);
+
+ if(got == 0)
+ {
+ rec_type = CONNECTION_CLOSED;
+ break;
+ }
+
+ reader.add_input(&record[0], got);
+
+ bytes_needed = reader.get_record(rec_type, record);
+ }
if(rec_type == CONNECTION_CLOSED)
{
@@ -250,7 +270,11 @@ void TLS_Server::read_handshake(byte rec_type,
const MemoryRegion<byte>& rec_buf)
{
if(rec_type == HANDSHAKE)
+ {
+ if(!state)
+ state = new Handshake_State;
state->queue.write(rec_buf, rec_buf.size());
+ }
while(true)
{
@@ -301,14 +325,6 @@ void TLS_Server::read_handshake(byte rec_type,
void TLS_Server::process_handshake_msg(Handshake_Type type,
const MemoryRegion<byte>& contents)
{
- if(type == CLIENT_HELLO)
- {
- if(state == 0)
- state = new Handshake_State();
- else
- return;
- }
-
if(state == 0)
throw Unexpected_Message("Unexpected handshake message");
@@ -327,6 +343,8 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
state->client_hello = new Client_Hello(contents);
+ client_requested_hostname = state->client_hello->hostname();
+
state->version = choose_version(state->client_hello->version(),
policy->min_version());
diff --git a/src/ssl/tls_server.h b/src/ssl/tls_server.h
index 683c3413a..5cf830a64 100644
--- a/src/ssl/tls_server.h
+++ b/src/ssl/tls_server.h
@@ -26,6 +26,9 @@ class BOTAN_DLL TLS_Server : public TLS_Connection
std::vector<X509_Certificate> peer_cert_chain() const;
+ std::string requested_hostname() const
+ { return client_requested_hostname; }
+
void close();
bool is_closed() const;
@@ -49,6 +52,8 @@ class BOTAN_DLL TLS_Server : public TLS_Connection
RandomNumberGenerator& rng;
+ Socket& peer;
+
Record_Writer writer;
Record_Reader reader;
const TLS_Policy* policy;
@@ -61,6 +66,7 @@ class BOTAN_DLL TLS_Server : public TLS_Connection
SecureVector<byte> session_id;
SecureQueue read_buf;
std::string peer_id;
+ std::string client_requested_hostname;
bool active;
};
diff --git a/src/ssl/tls_session_key.cpp b/src/ssl/tls_session_key.cpp
index 83c06ba07..13575adac 100644
--- a/src/ssl/tls_session_key.cpp
+++ b/src/ssl/tls_session_key.cpp
@@ -131,7 +131,7 @@ SessionKeys::SessionKeys(const CipherSuite& suite, Version_Code version,
const MemoryRegion<byte>& c_random,
const MemoryRegion<byte>& s_random)
{
- if(version != SSL_V3 && version != TLS_V10)
+ if(version != SSL_V3 && version != TLS_V10 && version != TLS_V11)
throw Invalid_Argument("SessionKeys: Unknown version code");
const u32bit mac_keylen = output_length_of(suite.mac_algo());
diff --git a/src/ssl/unix_socket/unx_sock.cpp b/src/ssl/unix_socket/unx_sock.cpp
index 0552a33b6..f9d9629fb 100644
--- a/src/ssl/unix_socket/unx_sock.cpp
+++ b/src/ssl/unix_socket/unx_sock.cpp
@@ -64,12 +64,12 @@ Unix_Socket::Unix_Socket(int fd, const std::string& peer_id)
/**
* Read from a Unix socket
*/
-u32bit Unix_Socket::read(byte buf[], u32bit length)
+size_t Unix_Socket::read(byte buf[], size_t length)
{
if(sockfd == -1)
throw Stream_IO_Error("Unix_Socket::read: Socket not connected");
- u32bit got = 0;
+ size_t got = 0;
while(length)
{
@@ -95,12 +95,12 @@ u32bit Unix_Socket::read(byte buf[], u32bit length)
/**
* Write to a Unix socket
*/
-void Unix_Socket::write(const byte buf[], u32bit length)
+void Unix_Socket::write(const byte buf[], size_t length)
{
if(sockfd == -1)
throw Stream_IO_Error("Unix_Socket::write: Socket not connected");
- u32bit offset = 0;
+ size_t offset = 0;
while(length)
{
ssize_t sent = ::send(sockfd, buf + offset, length, MSG_NOSIGNAL);
diff --git a/src/ssl/unix_socket/unx_sock.h b/src/ssl/unix_socket/unx_sock.h
index c1ff53ae3..58c7ada69 100644
--- a/src/ssl/unix_socket/unx_sock.h
+++ b/src/ssl/unix_socket/unx_sock.h
@@ -28,8 +28,8 @@ namespace Botan {
class BOTAN_DLL Unix_Socket : public Socket
{
public:
- u32bit read(byte[], u32bit);
- void write(const byte[], u32bit);
+ size_t read(byte[], size_t);
+ void write(const byte[], size_t);
std::string peer_id() const;
diff --git a/src/stream/arc4/arc4.h b/src/stream/arc4/arc4.h
index ae37cb165..07633f9ef 100644
--- a/src/stream/arc4/arc4.h
+++ b/src/stream/arc4/arc4.h
@@ -34,8 +34,8 @@ class BOTAN_DLL ARC4 : public StreamCipher
const u32bit SKIP;
- SecureBuffer<byte, DEFAULT_BUFFERSIZE> buffer;
- SecureBuffer<u32bit, 256> state;
+ SecureVector<byte, DEFAULT_BUFFERSIZE> buffer;
+ SecureVector<u32bit, 256> state;
u32bit X, Y, position;
};
diff --git a/src/stream/salsa20/salsa20.h b/src/stream/salsa20/salsa20.h
index af7ddd145..67fe54dda 100644
--- a/src/stream/salsa20/salsa20.h
+++ b/src/stream/salsa20/salsa20.h
@@ -34,8 +34,8 @@ class BOTAN_DLL Salsa20 : public StreamCipher
private:
void key_schedule(const byte key[], u32bit key_len);
- SecureBuffer<u32bit, 16> state;
- SecureBuffer<byte, 64> buffer;
+ SecureVector<u32bit, 16> state;
+ SecureVector<byte, 64> buffer;
u32bit position;
};
diff --git a/src/stream/turing/turing.h b/src/stream/turing/turing.h
index 7291647ea..19d151fca 100644
--- a/src/stream/turing/turing.h
+++ b/src/stream/turing/turing.h
@@ -37,10 +37,10 @@ class BOTAN_DLL Turing : public StreamCipher
static const u32bit Q_BOX[256];
static const byte SBOX[256];
- SecureBuffer<u32bit, 256> S0, S1, S2, S3;
- SecureBuffer<u32bit, 17> R;
+ SecureVector<u32bit, 256> S0, S1, S2, S3;
+ SecureVector<u32bit, 17> R;
SecureVector<u32bit> K;
- SecureBuffer<byte, 340> buffer;
+ SecureVector<byte, 340> buffer;
u32bit position;
};
diff --git a/src/stream/wid_wake/wid_wake.h b/src/stream/wid_wake/wid_wake.h
index 23e1eacab..1c52e8ba1 100644
--- a/src/stream/wid_wake/wid_wake.h
+++ b/src/stream/wid_wake/wid_wake.h
@@ -33,10 +33,10 @@ class BOTAN_DLL WiderWake_41_BE : public StreamCipher
void generate(u32bit);
- SecureBuffer<byte, DEFAULT_BUFFERSIZE> buffer;
- SecureBuffer<u32bit, 256> T;
- SecureBuffer<u32bit, 5> state;
- SecureBuffer<u32bit, 4> t_key;
+ SecureVector<byte, DEFAULT_BUFFERSIZE> buffer;
+ SecureVector<u32bit, 256> T;
+ SecureVector<u32bit, 5> state;
+ SecureVector<u32bit, 4> t_key;
u32bit position;
};