diff options
author | lloyd <[email protected]> | 2010-03-30 02:50:15 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-03-30 02:50:15 +0000 |
commit | 2c0cd825b6368f61afdba0eab8c8697d25451787 (patch) | |
tree | 2217e60d38aa34d9bf8fde1f3e17bc48d5e8303c /src/ssl | |
parent | 6d141cd765d840d8bbfdaaa8154494d3c9ecce50 (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.cpp | 2 | ||||
-rw-r--r-- | src/ssl/hello.cpp | 6 | ||||
-rw-r--r-- | src/ssl/rec_read.cpp | 17 | ||||
-rw-r--r-- | src/ssl/rec_wri.cpp | 22 | ||||
-rw-r--r-- | src/ssl/tls_policy.h | 2 | ||||
-rw-r--r-- | src/ssl/tls_record.h | 7 | ||||
-rw-r--r-- | src/ssl/tls_session_key.cpp | 2 |
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()); |