aboutsummaryrefslogtreecommitdiffstats
path: root/src/ssl
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-03-30 02:50:15 +0000
committerlloyd <[email protected]>2010-03-30 02:50:15 +0000
commit2c0cd825b6368f61afdba0eab8c8697d25451787 (patch)
tree2217e60d38aa34d9bf8fde1f3e17bc48d5e8303c /src/ssl
parent6d141cd765d840d8bbfdaaa8154494d3c9ecce50 (diff)
Add support for TLS v1.1's per-record random IV. Tested against GnuTLS server.
Diffstat (limited to 'src/ssl')
-rw-r--r--src/ssl/finished.cpp2
-rw-r--r--src/ssl/hello.cpp6
-rw-r--r--src/ssl/rec_read.cpp17
-rw-r--r--src/ssl/rec_wri.cpp22
-rw-r--r--src/ssl/tls_policy.h2
-rw-r--r--src/ssl/tls_record.h7
-rw-r--r--src/ssl/tls_session_key.cpp2
7 files changed, 46 insertions, 12 deletions
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..e4a04dfa7 100644
--- a/src/ssl/hello.cpp
+++ b/src/ssl/hello.cpp
@@ -219,9 +219,13 @@ void Server_Hello::deserialize(const MemoryRegion<byte>& buf)
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)
+ 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);
diff --git a/src/ssl/rec_read.cpp b/src/ssl/rec_read.cpp
index 4a042c28b..4f030cf1e 100644
--- a/src/ssl/rec_read.cpp
+++ b/src/ssl/rec_read.cpp
@@ -21,6 +21,7 @@ void Record_Reader::reset()
mac.reset();
mac_size = 0;
block_size = 0;
+ iv_size = 0;
major = minor = 0;
seq_no = 0;
}
@@ -30,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;
@@ -72,11 +73,17 @@ void Record_Reader::set_keys(const CipherSuite& suite, const SessionKeys& keys,
cipher_key, iv, DECRYPTION)
);
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));
block_size = 0;
+ iv_size = 0;
}
else
throw Invalid_Argument("Record_Reader: Unknown cipher " + cipher_algo);
@@ -171,14 +178,14 @@ u32bit Record_Reader::get_record(byte& msg_type,
}
}
- 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++)
@@ -191,7 +198,7 @@ u32bit 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;
@@ -202,7 +209,7 @@ u32bit Record_Reader::get_record(byte& msg_type,
throw TLS_Exception(BAD_RECORD_MAC, "Record_Reader: MAC failure");
msg_type = header[0];
- output.set(plaintext, mac_offset);
+ output.set(&plaintext[iv_size], plain_length);
return 0;
}
diff --git a/src/ssl/rec_wri.cpp b/src/ssl/rec_wri.cpp
index dc51a06b0..092ecdfe1 100644
--- a/src/ssl/rec_wri.cpp
+++ b/src/ssl/rec_wri.cpp
@@ -9,6 +9,7 @@
#include <botan/handshake_hash.h>
#include <botan/lookup.h>
#include <botan/loadstor.h>
+#include <botan/libstate.h>
namespace Botan {
@@ -35,6 +36,7 @@ void Record_Writer::reset()
major = minor = buf_type = 0;
block_size = 0;
mac_size = 0;
+ iv_size = 0;
seq_no = 0;
}
@@ -44,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;
@@ -86,11 +88,17 @@ void Record_Writer::set_keys(const CipherSuite& suite, const SessionKeys& keys,
cipher_key, iv, ENCRYPTION)
);
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));
block_size = 0;
+ iv_size = 0;
}
else
throw Invalid_Argument("Record_Writer: Unknown cipher " + cipher_algo);
@@ -202,6 +210,18 @@ void Record_Writer::send_record(byte type, const byte buf[], u32bit length)
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);
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_record.h b/src/ssl/tls_record.h
index c3bfcc14e..2058933d0 100644
--- a/src/ssl/tls_record.h
+++ b/src/ssl/tls_record.h
@@ -44,7 +44,10 @@ class BOTAN_DLL Record_Writer
Socket& socket;
Pipe cipher, mac;
SecureVector<byte> buffer;
- u32bit block_size, mac_size, buf_pos;
+ u32bit buf_pos;
+
+ u32bit block_size, mac_size, iv_size;
+
u64bit seq_no;
byte major, minor, buf_type;
};
@@ -80,7 +83,7 @@ class BOTAN_DLL Record_Reader
SecureQueue input_queue;
Pipe cipher, mac;
- u32bit block_size, mac_size;
+ u32bit block_size, mac_size, iv_size;
u64bit seq_no;
byte major, minor;
};
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());