aboutsummaryrefslogtreecommitdiffstats
path: root/src/tls
diff options
context:
space:
mode:
authorlloyd <[email protected]>2011-12-30 18:51:01 +0000
committerlloyd <[email protected]>2011-12-30 18:51:01 +0000
commit766f5eeb5c99936e7ddcf3e4c82095f087b6e928 (patch)
tree17b95459926b1064b538889a1b7c732ff2298470 /src/tls
parent07b11b4b3d9c7ef289050252c29bc8174d102148 (diff)
Add support for the maximum fragment length extension. No hooks for it
on the client side at the moment. Tested with gnutls-cli --recordsize. Save the fragment size and the secure renegotiation flags in the session state.
Diffstat (limited to 'src/tls')
-rw-r--r--src/tls/hello.cpp30
-rw-r--r--src/tls/rec_wri.cpp139
-rw-r--r--src/tls/tls_extensions.cpp59
-rw-r--r--src/tls/tls_extensions.h32
-rw-r--r--src/tls/tls_messages.h7
-rw-r--r--src/tls/tls_record.h19
-rw-r--r--src/tls/tls_server.cpp9
-rw-r--r--src/tls/tls_session_state.cpp68
-rw-r--r--src/tls/tls_session_state.h66
9 files changed, 288 insertions, 141 deletions
diff --git a/src/tls/hello.cpp b/src/tls/hello.cpp
index 5390b6071..fc19f6802 100644
--- a/src/tls/hello.cpp
+++ b/src/tls/hello.cpp
@@ -78,6 +78,7 @@ Client_Hello::Client_Hello(Record_Writer& writer,
comp_methods(policy.compression()),
requested_hostname(hostname),
requested_srp_id(srp_identifier),
+ m_fragment_size(0),
has_secure_renegotiation(true),
renegotiation_info_bits(reneg_info)
{
@@ -162,6 +163,8 @@ void Client_Hello::deserialize_sslv2(const MemoryRegion<byte>& buf)
has_secure_renegotiation =
value_exists(suites, static_cast<u16bit>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV));
+
+ m_fragment_size = 0;
}
/*
@@ -169,8 +172,6 @@ void Client_Hello::deserialize_sslv2(const MemoryRegion<byte>& buf)
*/
void Client_Hello::deserialize(const MemoryRegion<byte>& buf)
{
- has_secure_renegotiation = false;
-
if(buf.size() == 0)
throw Decoding_Error("Client_Hello: Packet corrupted");
@@ -188,6 +189,9 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf)
comp_methods = reader.get_range_vector<byte>(1, 1, 255);
+ has_secure_renegotiation = false;
+ m_fragment_size = 0;
+
TLS_Extensions extensions(reader);
for(size_t i = 0; i != extensions.count(); ++i)
@@ -195,9 +199,17 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf)
TLS_Extension* extn = extensions.at(i);
if(Server_Name_Indicator* sni = dynamic_cast<Server_Name_Indicator*>(extn))
+ {
requested_hostname = sni->host_name();
+ }
else if(SRP_Identifier* srp = dynamic_cast<SRP_Identifier*>(extn))
+ {
requested_srp_id = srp->identifier();
+ }
+ else if(Maximum_Fragment_Length* frag = dynamic_cast<Maximum_Fragment_Length*>(extn))
+ {
+ m_fragment_size = frag->fragment_size();
+ }
else if(Renegotation_Extension* reneg = dynamic_cast<Renegotation_Extension*>(extn))
{
// checked by TLS_Client / TLS_Server as they know the handshake state
@@ -254,6 +266,7 @@ Server_Hello::Server_Hello(Record_Writer& writer,
s_version(ver),
sess_id(session_id),
s_random(rng.random_vec(32)),
+ m_fragment_size(c_hello.fragment_size()),
has_secure_renegotiation(client_has_secure_renegotiation),
renegotiation_info_bits(reneg_info)
{
@@ -289,6 +302,7 @@ Server_Hello::Server_Hello(Record_Writer& writer,
bool client_has_secure_renegotiation,
const MemoryRegion<byte>& reneg_info,
const MemoryRegion<byte>& session_id,
+ size_t fragment_size,
u16bit ciphersuite,
byte compression,
Version_Code ver) :
@@ -297,6 +311,7 @@ Server_Hello::Server_Hello(Record_Writer& writer,
s_random(rng.random_vec(32)),
suite(ciphersuite),
comp_method(compression),
+ m_fragment_size(fragment_size),
has_secure_renegotiation(client_has_secure_renegotiation),
renegotiation_info_bits(reneg_info)
{
@@ -321,12 +336,15 @@ MemoryVector<byte> Server_Hello::serialize() const
buf.push_back(comp_method);
+ TLS_Extensions extensions;
+
if(has_secure_renegotiation)
- {
- TLS_Extensions extensions;
extensions.push_back(new Renegotation_Extension(renegotiation_info_bits));
- buf += extensions.serialize();
- }
+
+ if(m_fragment_size != 0)
+ extensions.push_back(new Maximum_Fragment_Length(m_fragment_size));
+
+ buf += extensions.serialize();
return buf;
}
diff --git a/src/tls/rec_wri.cpp b/src/tls/rec_wri.cpp
index a0c332c58..a9a5b4549 100644
--- a/src/tls/rec_wri.cpp
+++ b/src/tls/rec_wri.cpp
@@ -14,36 +14,47 @@
#include <botan/loadstor.h>
#include <botan/libstate.h>
+#include <stdio.h>
+
namespace Botan {
/*
* Record_Writer Constructor
*/
-Record_Writer::Record_Writer(std::tr1::function<void (const byte[], size_t)> out,
- size_t max_fragment) :
- output_fn(out),
- max_fragment(clamp(max_fragment, 128, MAX_PLAINTEXT_SIZE))
+Record_Writer::Record_Writer(std::tr1::function<void (const byte[], size_t)> out) :
+ m_output_fn(out), m_max_fragment(MAX_PLAINTEXT_SIZE)
{
- mac = 0;
+ m_mac = 0;
reset();
}
+void Record_Writer::set_maximum_fragment_size(size_t max_fragment)
+ {
+ if(max_fragment == 0)
+ m_max_fragment = MAX_PLAINTEXT_SIZE;
+ else
+ m_max_fragment = clamp(max_fragment, 128, MAX_PLAINTEXT_SIZE);
+
+ printf("Setting max fragment size to %d\n", m_max_fragment);
+ }
+
/*
* Reset the state
*/
void Record_Writer::reset()
{
- cipher.reset();
+ m_cipher.reset();
- delete mac;
- mac = 0;
+ delete m_mac;
+ m_mac = 0;
- major = minor = 0;
- block_size = 0;
- mac_size = 0;
- iv_size = 0;
+ m_major = 0;
+ m_minor = 0;
+ m_block_size = 0;
+ m_mac_size = 0;
+ m_iv_size = 0;
- seq_no = 0;
+ m_seq_no = 0;
}
/*
@@ -54,8 +65,8 @@ void Record_Writer::set_version(Version_Code version)
if(version != SSL_V3 && version != TLS_V10 && version != TLS_V11)
throw Invalid_Argument("Record_Writer: Invalid protocol version");
- major = (version >> 8) & 0xFF;
- minor = (version & 0xFF);
+ m_major = (version >> 8) & 0xFF;
+ m_minor = (version & 0xFF);
}
/*
@@ -65,9 +76,9 @@ void Record_Writer::set_keys(const CipherSuite& suite,
const SessionKeys& keys,
Connection_Side side)
{
- cipher.reset();
- delete mac;
- mac = 0;
+ m_cipher.reset();
+ delete m_mac;
+ m_mac = 0;
/*
RFC 4346:
@@ -75,7 +86,7 @@ void Record_Writer::set_keys(const CipherSuite& suite,
the first record transmitted under a particular connection state
MUST use sequence number 0
*/
- seq_no = 0;
+ m_seq_no = 0;
SymmetricKey mac_key, cipher_key;
InitializationVector iv;
@@ -98,22 +109,22 @@ void Record_Writer::set_keys(const CipherSuite& suite,
if(have_block_cipher(cipher_algo))
{
- cipher.append(get_cipher(
+ m_cipher.append(get_cipher(
cipher_algo + "/CBC/NoPadding",
cipher_key, iv, ENCRYPTION)
);
- block_size = block_size_of(cipher_algo);
+ m_block_size = block_size_of(cipher_algo);
- if(major > 3 || (major == 3 && minor >= 2))
- iv_size = block_size;
+ if(m_major > 3 || (m_major == 3 && m_minor >= 2))
+ m_iv_size = m_block_size;
else
- iv_size = 0;
+ m_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;
+ m_cipher.append(get_cipher(cipher_algo, cipher_key, ENCRYPTION));
+ m_block_size = 0;
+ m_iv_size = 0;
}
else
throw Invalid_Argument("Record_Writer: Unknown cipher " + cipher_algo);
@@ -122,13 +133,13 @@ void Record_Writer::set_keys(const CipherSuite& suite,
{
Algorithm_Factory& af = global_state().algorithm_factory();
- if(major == 3 && minor == 0)
- mac = af.make_mac("SSL3-MAC(" + mac_algo + ")");
+ if(m_major == 3 && m_minor == 0)
+ m_mac = af.make_mac("SSL3-MAC(" + mac_algo + ")");
else
- mac = af.make_mac("HMAC(" + mac_algo + ")");
+ m_mac = af.make_mac("HMAC(" + mac_algo + ")");
- mac->set_key(mac_key);
- mac_size = mac->output_length();
+ m_mac->set_key(mac_key);
+ m_mac_size = m_mac->output_length();
}
else
throw Invalid_Argument("Record_Writer: Unknown hash " + mac_algo);
@@ -153,7 +164,7 @@ void Record_Writer::send(byte type, const byte input[], size_t length)
*
* See http://www.openssl.org/~bodo/tls-cbc.txt for background.
*/
- if((type == APPLICATION) && (block_size > 0) && (iv_size == 0))
+ if((type == APPLICATION) && (m_block_size > 0) && (m_iv_size == 0))
{
send_record(type, &input[0], 1);
input += 1;
@@ -162,7 +173,7 @@ void Record_Writer::send(byte type, const byte input[], size_t length)
while(length)
{
- const size_t sending = std::min(length, max_fragment);
+ const size_t sending = std::min(length, m_max_fragment);
send_record(type, &input[0], sending);
input += sending;
@@ -179,38 +190,38 @@ void Record_Writer::send_record(byte type, const byte input[], size_t length)
throw TLS_Exception(INTERNAL_ERROR,
"Record_Writer: Compressed packet is too big");
- if(mac_size == 0)
+ if(m_mac_size == 0)
{
const byte header[5] = {
type,
- major,
- minor,
+ m_major,
+ m_minor,
get_byte<u16bit>(0, length),
get_byte<u16bit>(1, length)
};
- output_fn(header, 5);
- output_fn(input, length);
+ m_output_fn(header, 5);
+ m_output_fn(input, length);
}
else
{
- mac->update_be(seq_no);
- mac->update(type);
+ m_mac->update_be(m_seq_no);
+ m_mac->update(type);
- if(major > 3 || (major == 3 && minor != 0))
+ if(m_major > 3 || (m_major == 3 && m_minor != 0))
{
- mac->update(major);
- mac->update(minor);
+ m_mac->update(m_major);
+ m_mac->update(m_minor);
}
- mac->update(get_byte<u16bit>(0, length));
- mac->update(get_byte<u16bit>(1, length));
- mac->update(input, length);
+ m_mac->update(get_byte<u16bit>(0, length));
+ m_mac->update(get_byte<u16bit>(1, length));
+ m_mac->update(input, length);
- const size_t buf_size = round_up(iv_size + length +
- mac->output_length() +
- (block_size ? 1 : 0),
- block_size);
+ const size_t buf_size = round_up(m_iv_size + length +
+ m_mac->output_length() +
+ (m_block_size ? 1 : 0),
+ m_block_size);
if(buf_size >= MAX_CIPHERTEXT_SIZE)
throw TLS_Exception(INTERNAL_ERROR,
@@ -220,30 +231,30 @@ void Record_Writer::send_record(byte type, const byte input[], size_t length)
// TLS record header
buf[0] = type;
- buf[1] = major;
- buf[2] = minor;
+ buf[1] = m_major;
+ buf[2] = m_minor;
buf[3] = get_byte<u16bit>(0, buf_size);
buf[4] = get_byte<u16bit>(1, buf_size);
byte* buf_write_ptr = &buf[5];
- if(iv_size)
+ if(m_iv_size)
{
RandomNumberGenerator& rng = global_state().global_rng();
- rng.randomize(buf_write_ptr, iv_size);
- buf_write_ptr += iv_size;
+ rng.randomize(buf_write_ptr, m_iv_size);
+ buf_write_ptr += m_iv_size;
}
copy_mem(buf_write_ptr, input, length);
buf_write_ptr += length;
- mac->final(buf_write_ptr);
- buf_write_ptr += mac->output_length();
+ m_mac->final(buf_write_ptr);
+ buf_write_ptr += m_mac->output_length();
- if(block_size)
+ if(m_block_size)
{
const size_t pad_val =
- buf_size - (iv_size + length + mac->output_length() + 1);
+ buf_size - (m_iv_size + length + m_mac->output_length() + 1);
for(size_t i = 0; i != pad_val + 1; ++i)
{
@@ -253,13 +264,13 @@ void Record_Writer::send_record(byte type, const byte input[], size_t length)
}
// FIXME: this could be done in-place without copying
- cipher.process_msg(&buf[5], buf.size() - 5);
- size_t got_back = cipher.read(&buf[5], buf.size() - 5, Pipe::LAST_MESSAGE);
+ m_cipher.process_msg(&buf[5], buf.size() - 5);
+ size_t got_back = m_cipher.read(&buf[5], buf.size() - 5, Pipe::LAST_MESSAGE);
BOTAN_ASSERT_EQUAL(got_back, buf.size()-5, "CBC didn't encrypt full blocks");
- output_fn(&buf[0], buf.size());
+ m_output_fn(&buf[0], buf.size());
- seq_no++;
+ m_seq_no++;
}
}
diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp
index 1b3858a5a..b793971c5 100644
--- a/src/tls/tls_extensions.cpp
+++ b/src/tls/tls_extensions.cpp
@@ -13,15 +13,17 @@ namespace Botan {
namespace {
TLS_Extension* make_extension(TLS_Data_Reader& reader,
- u16bit extension_code,
- u16bit extension_size)
+ u16bit code,
+ u16bit size)
{
- if(extension_code == TLSEXT_SERVER_NAME_INDICATION)
- return new Server_Name_Indicator(reader, extension_size);
- else if(extension_code == TLSEXT_SRP_IDENTIFIER)
- return new SRP_Identifier(reader, extension_size);
- else if(extension_code == TLSEXT_SAFE_RENEGOTIATION)
- return new Renegotation_Extension(reader, extension_size);
+ if(code == TLSEXT_SERVER_NAME_INDICATION)
+ return new Server_Name_Indicator(reader, size);
+ else if(code == TLSEXT_MAX_FRAGMENT_LENGTH)
+ return new Maximum_Fragment_Length(reader, size);
+ else if(code == TLSEXT_SRP_IDENTIFIER)
+ return new SRP_Identifier(reader, size);
+ else if(code == TLSEXT_SAFE_RENEGOTIATION)
+ return new Renegotation_Extension(reader, size);
else
return 0; // not known
}
@@ -184,4 +186,45 @@ MemoryVector<byte> Renegotation_Extension::serialize() const
return buf;
}
+size_t Maximum_Fragment_Length::fragment_size() const
+ {
+ switch(val)
+ {
+ case 1:
+ return 512;
+ case 2:
+ return 1024;
+ case 3:
+ return 2048;
+ case 4:
+ return 4096;
+ default:
+ throw TLS_Exception(ILLEGAL_PARAMETER,
+ "Bad value in maximum fragment extension");
+ }
+ }
+
+Maximum_Fragment_Length::Maximum_Fragment_Length(size_t max_fragment)
+ {
+ if(max_fragment == 512)
+ val = 1;
+ else if(max_fragment == 1024)
+ val = 2;
+ else if(max_fragment == 2048)
+ val = 3;
+ else if(max_fragment == 4096)
+ val = 4;
+ else
+ throw std::invalid_argument("Bad setting " + to_string(max_fragment) +
+ " for maximum fragment size");
+ }
+
+Maximum_Fragment_Length::Maximum_Fragment_Length(TLS_Data_Reader& reader,
+ u16bit extension_size)
+ {
+ if(extension_size != 1)
+ throw Decoding_Error("Bad size for maximum fragment extension");
+ val = reader.get_byte();
+ }
+
}
diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h
index bbf4aa851..b1b2ca2e0 100644
--- a/src/tls/tls_extensions.h
+++ b/src/tls/tls_extensions.h
@@ -107,6 +107,38 @@ class Renegotation_Extension : public TLS_Extension
};
/**
+* Maximum Fragment Length Negotiation Extension (RFC 4366 sec 3.2)
+*/
+class Maximum_Fragment_Length : public TLS_Extension
+ {
+ public:
+ TLS_Handshake_Extension_Type type() const
+ { return TLSEXT_MAX_FRAGMENT_LENGTH; }
+
+ bool empty() const { return val != 0; }
+
+ size_t fragment_size() const;
+
+ MemoryVector<byte> serialize() const
+ {
+ return MemoryVector<byte>(&val, 1);
+ }
+
+ /**
+ * @param max_fragment specifies what maximum fragment size to
+ * advertise. Currently must be one of 512, 1024, 2048, or
+ * 4096.
+ */
+ Maximum_Fragment_Length(size_t max_fragment);
+
+ Maximum_Fragment_Length(TLS_Data_Reader& reader,
+ u16bit extension_size);
+
+ private:
+ byte val;
+ };
+
+/**
* Represents a block of extensions in a hello message
*/
class TLS_Extensions
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index cb56ead6c..8f9195412 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -72,6 +72,8 @@ class Client_Hello : public HandshakeMessage
bool offered_suite(u16bit ciphersuite) const;
+ size_t fragment_size() const { return m_fragment_size; }
+
Client_Hello(Record_Writer& writer,
TLS_Handshake_Hash& hash,
const TLS_Policy& policy,
@@ -101,6 +103,7 @@ class Client_Hello : public HandshakeMessage
std::string requested_hostname;
std::string requested_srp_id;
+ size_t m_fragment_size;
bool has_secure_renegotiation;
MemoryVector<byte> renegotiation_info_bits;
};
@@ -126,6 +129,8 @@ class Server_Hello : public HandshakeMessage
bool secure_renegotiation() const { return has_secure_renegotiation; }
+ size_t fragment_size() const { return m_fragment_size; }
+
const MemoryVector<byte>& renegotiation_info()
{ return renegotiation_info_bits; }
@@ -148,6 +153,7 @@ class Server_Hello : public HandshakeMessage
bool client_has_secure_renegotiation,
const MemoryRegion<byte>& reneg_info,
const MemoryRegion<byte>& session_id,
+ size_t max_fragment_size,
u16bit ciphersuite,
byte compression,
Version_Code ver);
@@ -162,6 +168,7 @@ class Server_Hello : public HandshakeMessage
u16bit suite;
byte comp_method;
+ size_t m_fragment_size;
bool has_secure_renegotiation;
MemoryVector<byte> renegotiation_info_bits;
};
diff --git a/src/tls/tls_record.h b/src/tls/tls_record.h
index 51a7cd310..55cb66034 100644
--- a/src/tls/tls_record.h
+++ b/src/tls/tls_record.h
@@ -53,22 +53,23 @@ class BOTAN_DLL Record_Writer
void reset();
- Record_Writer(std::tr1::function<void (const byte[], size_t)> output_fn,
- size_t max_fragment = MAX_PLAINTEXT_SIZE);
+ void set_maximum_fragment_size(size_t max_fragment);
- ~Record_Writer() { delete mac; }
+ Record_Writer(std::tr1::function<void (const byte[], size_t)> output_fn);
+
+ ~Record_Writer() { delete m_mac; }
private:
void send_record(byte type, const byte input[], size_t length);
- std::tr1::function<void (const byte[], size_t)> output_fn;
+ std::tr1::function<void (const byte[], size_t)> m_output_fn;
- Pipe cipher;
- MessageAuthenticationCode* mac;
+ Pipe m_cipher;
+ MessageAuthenticationCode* m_mac;
- size_t block_size, mac_size, iv_size, max_fragment;
+ size_t m_block_size, m_mac_size, m_iv_size, m_max_fragment;
- u64bit seq_no;
- byte major, minor;
+ u64bit m_seq_no;
+ byte m_major, m_minor;
};
/**
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index 3f65fa735..3077476e3 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -190,8 +190,12 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
session_info.session_id(),
session_info.ciphersuite(),
session_info.compression_method(),
+ session_info.fragment_size(),
Version_Code(session_info.version()));
+ if(session_info.fragment_size())
+ writer.set_maximum_fragment_size(session_info.fragment_size());
+
state->suite = CipherSuite(state->server_hello->ciphersuite());
state->keys = SessionKeys(state->suite, state->version,
@@ -224,6 +228,9 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
rng.random_vec(32),
state->version);
+ if(state->client_hello->fragment_size())
+ writer.set_maximum_fragment_size(state->client_hello->fragment_size());
+
state->suite = CipherSuite(state->server_hello->ciphersuite());
if(state->suite.sig_type() != TLS_ALGO_SIGNER_ANON)
@@ -376,6 +383,8 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
state->server_hello->ciphersuite(),
state->server_hello->compression_method(),
SERVER,
+ secure_renegotiation.supported(),
+ state->server_hello->fragment_size(),
peer_certs,
client_requested_hostname,
""
diff --git a/src/tls/tls_session_state.cpp b/src/tls/tls_session_state.cpp
index 9d8d4215d..bac24a5eb 100644
--- a/src/tls/tls_session_state.cpp
+++ b/src/tls/tls_session_state.cpp
@@ -19,22 +19,26 @@ TLS_Session_Params::TLS_Session_Params(const MemoryRegion<byte>& session_identif
u16bit ciphersuite,
byte compression_method,
Connection_Side side,
+ bool secure_renegotiation_supported,
+ size_t fragment_size,
const std::vector<X509_Certificate>& certs,
const std::string& sni_hostname,
const std::string& srp_identifier) :
- session_start_time(system_time()),
- session_identifier(session_identifier),
- session_master_secret(master_secret),
- session_version(version),
- session_ciphersuite(ciphersuite),
- session_compression_method(compression_method),
- session_connection_side(side),
- session_sni_hostname(sni_hostname),
- session_srp_identifier(srp_identifier)
+ m_start_time(system_time()),
+ m_identifier(session_identifier),
+ m_master_secret(master_secret),
+ m_version(version),
+ m_ciphersuite(ciphersuite),
+ m_compression_method(compression_method),
+ m_connection_side(side),
+ m_secure_renegotiation_supported(secure_renegotiation_supported),
+ m_fragment_size(fragment_size),
+ m_sni_hostname(sni_hostname),
+ m_srp_identifier(srp_identifier)
{
// FIXME: encode all of them?
if(certs.size())
- session_peer_certificate = certs[0].BER_encode();
+ m_peer_certificate = certs[0].BER_encode();
}
TLS_Session_Params::TLS_Session_Params(const byte ber[], size_t ber_len)
@@ -48,20 +52,22 @@ TLS_Session_Params::TLS_Session_Params(const byte ber[], size_t ber_len)
BER_Decoder(ber, ber_len)
.decode_and_check(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION),
"Unknown version in session structure")
- .decode(session_identifier, OCTET_STRING)
- .decode_integer_type(session_start_time)
- .decode_integer_type(session_version)
- .decode_integer_type(session_ciphersuite)
- .decode_integer_type(session_compression_method)
+ .decode(m_identifier, OCTET_STRING)
+ .decode_integer_type(m_start_time)
+ .decode_integer_type(m_version)
+ .decode_integer_type(m_ciphersuite)
+ .decode_integer_type(m_compression_method)
.decode_integer_type(side_code)
- .decode(session_master_secret, OCTET_STRING)
- .decode(session_peer_certificate, OCTET_STRING)
+ .decode_integer_type(m_fragment_size)
+ .decode(m_secure_renegotiation_supported)
+ .decode(m_master_secret, OCTET_STRING)
+ .decode(m_peer_certificate, OCTET_STRING)
.decode(sni_hostname_str)
.decode(srp_identifier_str);
- session_sni_hostname = sni_hostname_str.value();
- session_srp_identifier = srp_identifier_str.value();
- session_connection_side = static_cast<Connection_Side>(side_code);
+ m_sni_hostname = sni_hostname_str.value();
+ m_srp_identifier = srp_identifier_str.value();
+ m_connection_side = static_cast<Connection_Side>(side_code);
}
SecureVector<byte> TLS_Session_Params::BER_encode() const
@@ -69,16 +75,18 @@ SecureVector<byte> TLS_Session_Params::BER_encode() const
return DER_Encoder()
.start_cons(SEQUENCE)
.encode(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION))
- .encode(session_identifier, OCTET_STRING)
- .encode(static_cast<size_t>(session_start_time))
- .encode(static_cast<size_t>(session_version))
- .encode(static_cast<size_t>(session_ciphersuite))
- .encode(static_cast<size_t>(session_compression_method))
- .encode(static_cast<size_t>(session_connection_side))
- .encode(session_master_secret, OCTET_STRING)
- .encode(session_peer_certificate, OCTET_STRING)
- .encode(ASN1_String(session_sni_hostname, UTF8_STRING))
- .encode(ASN1_String(session_srp_identifier, UTF8_STRING))
+ .encode(m_identifier, OCTET_STRING)
+ .encode(static_cast<size_t>(m_start_time))
+ .encode(static_cast<size_t>(m_version))
+ .encode(static_cast<size_t>(m_ciphersuite))
+ .encode(static_cast<size_t>(m_compression_method))
+ .encode(static_cast<size_t>(m_connection_side))
+ .encode(static_cast<size_t>(m_fragment_size))
+ .encode(m_secure_renegotiation_supported)
+ .encode(m_master_secret, OCTET_STRING)
+ .encode(m_peer_certificate, OCTET_STRING)
+ .encode(ASN1_String(m_sni_hostname, UTF8_STRING))
+ .encode(ASN1_String(m_srp_identifier, UTF8_STRING))
.end_cons()
.get_contents();
}
diff --git a/src/tls/tls_session_state.h b/src/tls/tls_session_state.h
index 3f1b52a00..eefdc4b67 100644
--- a/src/tls/tls_session_state.h
+++ b/src/tls/tls_session_state.h
@@ -28,11 +28,13 @@ class BOTAN_DLL TLS_Session_Params
* Uninitialized session
*/
TLS_Session_Params() :
- session_start_time(0),
- session_version(0),
- session_ciphersuite(0),
- session_compression_method(0),
- session_connection_side(static_cast<Connection_Side>(0))
+ m_start_time(0),
+ m_version(0),
+ m_ciphersuite(0),
+ m_compression_method(0),
+ m_connection_side(static_cast<Connection_Side>(0)),
+ m_secure_renegotiation_supported(false),
+ m_fragment_size(0)
{}
/**
@@ -44,6 +46,8 @@ class BOTAN_DLL TLS_Session_Params
u16bit ciphersuite,
byte compression_method,
Connection_Side side,
+ bool secure_renegotiation_supported,
+ size_t fragment_size,
const std::vector<X509_Certificate>& peer_certs,
const std::string& sni_hostname = "",
const std::string& srp_identifier = "");
@@ -64,67 +68,81 @@ class BOTAN_DLL TLS_Session_Params
* Get the version of the saved session
*/
Version_Code version() const
- { return static_cast<Version_Code>(session_version); }
+ { return static_cast<Version_Code>(m_version); }
/**
* Get the ciphersuite of the saved session
*/
- u16bit ciphersuite() const { return session_ciphersuite; }
+ u16bit ciphersuite() const { return m_ciphersuite; }
/**
* Get the compression method used in the saved session
*/
- byte compression_method() const { return session_compression_method; }
+ byte compression_method() const { return m_compression_method; }
/**
* Get which side of the connection the resumed session we are/were
* acting as.
*/
- Connection_Side side() const { return session_connection_side; }
+ Connection_Side side() const { return m_connection_side; }
/**
* Get the SNI hostname (if sent by the client in the initial handshake)
*/
- std::string sni_hostname() const { return session_sni_hostname; }
+ std::string sni_hostname() const { return m_sni_hostname; }
/**
* Get the SRP identity (if sent by the client in the initial handshake)
*/
- std::string srp_identifier() const { return session_srp_identifier; }
+ std::string srp_identifier() const { return m_srp_identifier; }
/**
* Get the saved master secret
*/
const SecureVector<byte>& master_secret() const
- { return session_master_secret; }
+ { return m_master_secret; }
/**
* Get the session identifier
*/
const MemoryVector<byte>& session_id() const
- { return session_identifier; }
+ { return m_identifier; }
+
+ /**
+ * Get the negotiated maximum fragment size (or 0 if default)
+ */
+ size_t fragment_size() const { return m_fragment_size; }
+
+ /**
+ * Is secure negotiation supported?
+ */
+ bool secure_negotiation() const
+ { return m_secure_renegotiation_supported; }
/**
* Get the time this session began (seconds since Epoch)
*/
- u64bit start_time() const { return session_start_time; }
+ u64bit start_time() const { return m_start_time; }
private:
enum { TLS_SESSION_PARAM_STRUCT_VERSION = 1 };
- u64bit session_start_time;
+ u64bit m_start_time;
+
+ MemoryVector<byte> m_identifier;
+ SecureVector<byte> m_master_secret;
- MemoryVector<byte> session_identifier;
- SecureVector<byte> session_master_secret;
+ u16bit m_version;
+ u16bit m_ciphersuite;
+ byte m_compression_method;
+ Connection_Side m_connection_side;
- u16bit session_version;
- u16bit session_ciphersuite;
- byte session_compression_method;
- Connection_Side session_connection_side;
+ bool m_secure_renegotiation_supported;
+ size_t m_fragment_size;
- MemoryVector<byte> session_peer_certificate; // optional
- std::string session_sni_hostname; // optional
- std::string session_srp_identifier; // optional
+ MemoryVector<byte> m_peer_certificate; // optional
+ std::string m_sni_hostname; // optional
+ std::string m_srp_identifier; // optional
};
/**