aboutsummaryrefslogtreecommitdiffstats
path: root/src/tls/tls_session.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tls/tls_session.cpp')
-rw-r--r--src/tls/tls_session.cpp88
1 files changed, 48 insertions, 40 deletions
diff --git a/src/tls/tls_session.cpp b/src/tls/tls_session.cpp
index ddf0661c6..3d890210f 100644
--- a/src/tls/tls_session.cpp
+++ b/src/tls/tls_session.cpp
@@ -12,6 +12,7 @@
#include <botan/pem.h>
#include <botan/time.h>
#include <botan/lookup.h>
+#include <botan/loadstor.h>
#include <memory>
namespace Botan {
@@ -27,10 +28,12 @@ Session::Session(const MemoryRegion<byte>& session_identifier,
bool secure_renegotiation_supported,
size_t fragment_size,
const std::vector<X509_Certificate>& certs,
+ const MemoryRegion<byte>& ticket,
const std::string& sni_hostname,
const std::string& srp_identifier) :
m_start_time(system_time()),
m_identifier(session_identifier),
+ m_session_ticket(ticket),
m_master_secret(master_secret),
m_version(version),
m_ciphersuite(ciphersuite),
@@ -44,6 +47,13 @@ Session::Session(const MemoryRegion<byte>& session_identifier,
{
}
+Session::Session(const std::string& pem)
+ {
+ SecureVector<byte> der = PEM_Code::decode_check_label(pem, "SSL SESSION");
+
+ *this = Session(&der[0], der.size());
+ }
+
Session::Session(const byte ber[], size_t ber_len)
{
BER_Decoder decoder(ber, ber_len);
@@ -60,10 +70,11 @@ Session::Session(const byte ber[], size_t ber_len)
.start_cons(SEQUENCE)
.decode_and_check(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION),
"Unknown version in session structure")
- .decode(m_identifier, OCTET_STRING)
.decode_integer_type(m_start_time)
.decode_integer_type(major_version)
.decode_integer_type(minor_version)
+ .decode(m_identifier, OCTET_STRING)
+ .decode(m_session_ticket, OCTET_STRING)
.decode_integer_type(m_ciphersuite)
.decode_integer_type(m_compression_method)
.decode_integer_type(side_code)
@@ -90,13 +101,6 @@ Session::Session(const byte ber[], size_t ber_len)
}
}
-Session::Session(const std::string& pem)
- {
- SecureVector<byte> der = PEM_Code::decode_check_label(pem, "SSL SESSION");
-
- *this = Session(&der[0], der.size());
- }
-
SecureVector<byte> Session::DER_encode() const
{
MemoryVector<byte> peer_cert_bits;
@@ -106,10 +110,11 @@ SecureVector<byte> Session::DER_encode() const
return DER_Encoder()
.start_cons(SEQUENCE)
.encode(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION))
- .encode(m_identifier, OCTET_STRING)
.encode(static_cast<size_t>(m_start_time))
.encode(static_cast<size_t>(m_version.major_version()))
.encode(static_cast<size_t>(m_version.minor_version()))
+ .encode(m_identifier, OCTET_STRING)
+ .encode(m_session_ticket, OCTET_STRING)
.encode(static_cast<size_t>(m_ciphersuite))
.encode(static_cast<size_t>(m_compression_method))
.encode(static_cast<size_t>(m_connection_side))
@@ -128,25 +133,23 @@ std::string Session::PEM_encode() const
return PEM_Code::encode(this->DER_encode(), "SSL SESSION");
}
+namespace {
+
+const u64bit ENCRYPTED_SESSION_MAGIC = 0xACE4480800000000;
+
+}
+
MemoryVector<byte>
Session::encrypt(const SymmetricKey& master_key,
- const MemoryRegion<byte>& key_name,
RandomNumberGenerator& rng)
{
- if(key_name.size() != 16)
- throw Encoding_Error("Bad length " + to_string(key_name.size()) +
- " for key_name in TLS_Session::encrypt");
-
- if(master_key.length() == 0)
- throw Decoding_Error("Session encryption key not set");
-
std::auto_ptr<KDF> kdf(get_kdf("KDF2(SHA-256)"));
SymmetricKey aes_key = kdf->derive_key(32, master_key.bits_of(),
- "session-ticket.cipher-key");
+ "tls.session.cipher-key");
SymmetricKey hmac_key = kdf->derive_key(32, master_key.bits_of(),
- "session-ticket.hmac-key");
+ "tls.session.hmac-key");
InitializationVector aes_iv(rng, 16);
@@ -157,8 +160,8 @@ Session::encrypt(const SymmetricKey& master_key,
pipe.process_msg(this->DER_encode());
MemoryVector<byte> ctext = pipe.read_all(0);
- MemoryVector<byte> out;
- out += key_name;
+ MemoryVector<byte> out(8);
+ store_be(ENCRYPTED_SESSION_MAGIC, &out[0]);
out += aes_iv.bits_of();
out += ctext;
@@ -169,25 +172,24 @@ Session::encrypt(const SymmetricKey& master_key,
}
Session Session::decrypt(const MemoryRegion<byte>& buf,
- const SymmetricKey& master_key,
- const MemoryRegion<byte>& key_name)
+ const SymmetricKey& master_key)
{
try
{
- if(buf.size() < (16 + 16 + 32 + 1))
- throw Decoding_Error("Encrypted TLS_Session too short to be real");
-
- if(master_key.length() == 0)
- throw Decoding_Error("Session master_key not set");
-
- if(key_name.size() != 16)
- throw Decoding_Error("Bad length " + to_string(key_name.size()) +
- " for key_name");
+ /*
+ 8 bytes header
+ 16 bytes IV
+ 32 bytes MAC
+ 16 bytes per AES block * 4 blocks (absolute min amount due to
+ 48 bytes master secret)
+ */
+ if(buf.size() < (8 + 16 + 32 + 4*16))
+ throw Decoding_Error("Encrypted TLS session too short to be valid");
std::auto_ptr<KDF> kdf(get_kdf("KDF2(SHA-256)"));
SymmetricKey hmac_key = kdf->derive_key(32, master_key.bits_of(),
- "session-ticket.hmac-key");
+ "tls.session.mac-key");
std::auto_ptr<MessageAuthenticationCode> mac(get_mac("HMAC(SHA-256)"));
mac->set_key(hmac_key);
@@ -196,22 +198,28 @@ Session Session::decrypt(const MemoryRegion<byte>& buf,
MemoryVector<byte> computed_mac = mac->final();
if(!same_mem(&buf[buf.size() - 32], &computed_mac[0], computed_mac.size()))
- throw Decoding_Error("MAC verification failed");
+ throw Decoding_Error("MAC verification failed for encrypted session");
+
+ const u64bit header = load_be<u64bit>(buf, 0);
+
+ if(header != ENCRYPTED_SESSION_MAGIC)
+ throw Decoding_Error("Unknown header value in encrypted session");
SymmetricKey aes_key = kdf->derive_key(32, master_key.bits_of(),
- "session-ticket.cipher-key");
+ "tls.session.cipher-key");
- InitializationVector aes_iv(&buf[16], 16);
+ InitializationVector aes_iv(&buf[8], 16);
Pipe pipe(get_cipher("AES-256/CBC", aes_key, aes_iv, DECRYPTION));
- pipe.process_msg(&buf[16], buf.size() - (16 + 32));
- MemoryVector<byte> ber = pipe.read_all();
+ pipe.process_msg(&buf[8+16], buf.size() - (32 + 8 + 16));
+ SecureVector<byte> ber = pipe.read_all();
return Session(&ber[0], ber.size());
}
- catch(...)
+ catch(std::exception& e)
{
- throw Decoding_Error("Failed to decrypt encrypted session");
+ throw Decoding_Error("Failed to decrypt encrypted session -" +
+ std::string(e.what()));
}
}