diff options
author | lloyd <[email protected]> | 2012-01-11 20:01:33 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-01-11 20:01:33 +0000 |
commit | d146e65c66bc157c5a884d0ea5ac6cb167a4c929 (patch) | |
tree | 4a6eae6530c795a521e6ac1b2dbc37fb74f39e95 /src/tls/tls_session.cpp | |
parent | d6ec0f46e79f4b99194f8257e1f226b5ec05fe32 (diff) |
Outline of RFC 5077 session tickets
Diffstat (limited to 'src/tls/tls_session.cpp')
-rw-r--r-- | src/tls/tls_session.cpp | 92 |
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"); + } + } + + } |