aboutsummaryrefslogtreecommitdiffstats
path: root/src/tls/tls_session.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-01-11 20:01:33 +0000
committerlloyd <[email protected]>2012-01-11 20:01:33 +0000
commitd146e65c66bc157c5a884d0ea5ac6cb167a4c929 (patch)
tree4a6eae6530c795a521e6ac1b2dbc37fb74f39e95 /src/tls/tls_session.cpp
parentd6ec0f46e79f4b99194f8257e1f226b5ec05fe32 (diff)
Outline of RFC 5077 session tickets
Diffstat (limited to 'src/tls/tls_session.cpp')
-rw-r--r--src/tls/tls_session.cpp92
1 files changed, 91 insertions, 1 deletions
diff --git a/src/tls/tls_session.cpp b/src/tls/tls_session.cpp
index deaddb227..c40e9d79e 100644
--- a/src/tls/tls_session.cpp
+++ b/src/tls/tls_session.cpp
@@ -1,6 +1,6 @@
/*
* TLS Session State
-* (C) 2011 Jack Lloyd
+* (C) 2011-2012 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -10,6 +10,8 @@
#include <botan/ber_dec.h>
#include <botan/asn1_str.h>
#include <botan/time.h>
+#include <botan/lookup.h>
+#include <memory>
namespace Botan {
@@ -91,4 +93,92 @@ SecureVector<byte> TLS_Session::BER_encode() const
.get_contents();
}
+MemoryVector<byte>
+TLS_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("TLS_Session master_key not set");
+
+ std::auto_ptr<KDF> kdf(get_kdf("KDF2(SHA-256)"));
+
+ SymmetricKey aes_key = kdf->derive_key(16, master_key.bits_of(),
+ "session-ticket.cipher-key");
+
+ SymmetricKey hmac_key = kdf->derive_key(32, master_key.bits_of(),
+ "session-ticket.hmac-key");
+
+ InitializationVector aes_iv(rng, 16);
+
+ std::auto_ptr<MessageAuthenticationCode> mac(get_mac("HMAC(SHA-256)"));
+ mac->set_key(hmac_key);
+
+ Pipe pipe(get_cipher("AES-128/CBC", aes_key, aes_iv, ENCRYPTION));
+ pipe.process_msg(BER_encode());
+ MemoryVector<byte> ctext = pipe.read_all(0);
+
+ MemoryVector<byte> out;
+ out += key_name;
+ out += aes_iv.bits_of();
+ out += ctext;
+
+ mac->update(out);
+
+ out += mac->final();
+ return out;
+ }
+
+TLS_Session TLS_Session::decrypt(const MemoryRegion<byte>& buf,
+ const SymmetricKey& master_key,
+ const MemoryRegion<byte>& key_name)
+ {
+ 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("TLS_Session master_key not set");
+
+ if(key_name.size() != 16)
+ throw Decoding_Error("Bad length " + to_string(key_name.size()) +
+ " for key_name");
+
+ 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");
+
+ std::auto_ptr<MessageAuthenticationCode> mac(get_mac("HMAC(SHA-256)"));
+ mac->set_key(hmac_key);
+
+ mac->update(&buf[0], buf.size() - 32);
+ 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");
+
+ SymmetricKey aes_key = kdf->derive_key(16, master_key.bits_of(),
+ "session-ticket.cipher-key");
+
+ InitializationVector aes_iv(&buf[16], 16);
+
+ Pipe pipe(get_cipher("AES-128/CBC", aes_key, aes_iv, DECRYPTION));
+ pipe.process_msg(&buf[16], buf.size() - (16 + 32));
+ MemoryVector<byte> ber = pipe.read_all();
+
+ return TLS_Session(&ber[0], ber.size());
+ }
+ catch(...)
+ {
+ throw Decoding_Error("Failed to decrypt encrypted session");
+ }
+ }
+
+
}