From d146e65c66bc157c5a884d0ea5ac6cb167a4c929 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 11 Jan 2012 20:01:33 +0000 Subject: Outline of RFC 5077 session tickets --- src/tls/tls_extensions.cpp | 2 + src/tls/tls_extensions.h | 37 ++++++++++++++++++- src/tls/tls_messages.h | 28 ++++++++++++++ src/tls/tls_session.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++- src/tls/tls_session.h | 14 ++++++- 5 files changed, 170 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index c57f7cc81..8f60b5e9b 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -25,6 +25,8 @@ TLS_Extension* make_extension(TLS_Data_Reader& reader, return new SRP_Identifier(reader, size); else if(code == TLSEXT_SAFE_RENEGOTIATION) return new Renegotation_Extension(reader, size); + else if(code == TLSEXT_SESSION_TICKET) + return new Session_Ticket(reader, size); else if(code == TLSEXT_NEXT_PROTOCOL) return new Next_Protocol_Notification(reader, size); else diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index 62f179998..526436862 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -1,6 +1,6 @@ /* * TLS Extensions -* (C) 2011 Jack Lloyd +* (C) 2011-2012 Jack Lloyd * * Released under the terms of the Botan license */ @@ -15,6 +15,7 @@ namespace Botan { +class TLS_Session; class TLS_Data_Reader; /** @@ -176,6 +177,40 @@ class Next_Protocol_Notification : public TLS_Extension std::vector m_protocols; }; +class Session_Ticket : public TLS_Extension + { + public: + TLS_Handshake_Extension_Type type() const + { return TLSEXT_SESSION_TICKET; } + + /* + * Decrypt the session ticket and return the session info; + * used by server. + */ + TLS_Session decrypt(const SymmetricKey& key, + const MemoryRegion& key_name); + + /** + * Create empty extension, used by both client and server + */ + Session_Ticket() {} + + /** + * Extension with ticket, used by client + */ + Session_Ticket(const MemoryRegion& session_ticket) : + m_contents(session_ticket); + + /** + * Deserialize a session ticket + */ + Session_Ticket(const TLS_Data_Reader& reader, u16ibt extension_size); + + MemoryVector serialize() const { return m_contents; } + private: + MemoryVector m_contents; + }; + /** * Represents a block of extensions in a hello message */ diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index 6c2749e42..ed8073bda 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -79,6 +79,10 @@ class Client_Hello : public Handshake_Message size_t fragment_size() const { return m_fragment_size; } + bool supports_session_ticket() const { returnm m_supports_session_ticket; } + + const MemoryRegion session_ticket() const { return m_session_ticket; } + Client_Hello(Record_Writer& writer, TLS_Handshake_Hash& hash, const TLS_Policy& policy, @@ -431,6 +435,30 @@ class Next_Protocol : public Handshake_Message std::string m_protocol; }; +class New_Session_Ticket : public Handshake_Message + { + public: + Handshake_Type type() const { return NEW_SESSION_TICKET; } + + static TLS_Session decrypt(const MemoryRegion& ctext, + const SymmetricKey& key, + const MemoryRegion& key_name); + + const MemoryVector& contents() const { return m_contents; } + + New_Session_Ticket(const TLS_Session& session_info, + const SymmetricKey& key, + const MemoryRegion& key_name, + RandomNumberGenerator& rng); + + New_Session_Ticket(const MemoryRegion& buf) { deserialize(buf); } + private: + MemoryVector serialize() const; + void deserialize(const MemoryRegion&); + + MemoryVector m_contents; + }; + } #endif 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 #include #include +#include +#include namespace Botan { @@ -91,4 +93,92 @@ SecureVector TLS_Session::BER_encode() const .get_contents(); } +MemoryVector +TLS_Session::encrypt(const SymmetricKey& master_key, + const MemoryRegion& 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(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 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 ctext = pipe.read_all(0); + + MemoryVector 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& buf, + const SymmetricKey& master_key, + const MemoryRegion& 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(get_kdf("KDF2(SHA-256)")); + + SymmetricKey hmac_key = kdf->derive_key(32, master_key.bits_of(), + "session-ticket.hmac-key"); + + std::auto_ptr mac(get_mac("HMAC(SHA-256)")); + mac->set_key(hmac_key); + + mac->update(&buf[0], buf.size() - 32); + MemoryVector 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 ber = pipe.read_all(); + + return TLS_Session(&ber[0], ber.size()); + } + catch(...) + { + throw Decoding_Error("Failed to decrypt encrypted session"); + } + } + + } diff --git a/src/tls/tls_session.h b/src/tls/tls_session.h index b4b3861ed..4a8d50e26 100644 --- a/src/tls/tls_session.h +++ b/src/tls/tls_session.h @@ -1,6 +1,6 @@ /* * TLS Session -* (C) 2011 Jack Lloyd +* (C) 2011-2012 Jack Lloyd * * Released under the terms of the Botan license */ @@ -11,6 +11,7 @@ #include #include #include +#include namespace Botan { @@ -54,6 +55,17 @@ class BOTAN_DLL TLS_Session */ TLS_Session(const byte ber[], size_t ber_len); + /** + * Encrypt a session (useful for serialization or session tickets) + */ + MemoryVector encrypt(const SymmetricKey& key, + const MemoryRegion& key_name, + RandomNumberGenerator& rng); + + static TLS_Session decrypt(const MemoryRegion& ctext, + const SymmetricKey& key, + const MemoryRegion& key_name); + /** * Encode this session data for storage * @warning if the master secret is compromised so is the -- cgit v1.2.3 From 4c6327c95bd01de54487b3159b77a5152ed39564 Mon Sep 17 00:00:00 2001 From: lloyd Date: Wed, 11 Jan 2012 20:49:17 +0000 Subject: Build fixes --- src/build-data/cc/gcc.txt | 4 +++- src/tls/c_hello.cpp | 6 ++++++ src/tls/tls_extensions.h | 13 +++++-------- src/tls/tls_messages.h | 8 ++++++-- 4 files changed, 20 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt index 0852e5be1..3bc4cc5da 100644 --- a/src/build-data/cc/gcc.txt +++ b/src/build-data/cc/gcc.txt @@ -49,7 +49,9 @@ i586 -> "-mtune=generic -momit-leaf-frame-pointer" # Translate to GCC-speak nehalem -> "-march=corei7 -momit-leaf-frame-pointer" -westmere -> "-march=corei7 -maes -momit-leaf-frame-pointer" +#westmere -> "-march=corei7 -maes -momit-leaf-frame-pointer" +westmere -> "-march=core2 -msse4.1 -msse4.2 -maes -momit-leaf-frame-pointer" + sandybridge -> "-march=corei7-avx -momit-leaf-frame-pointer" atom32 -> "-march=atom -momit-leaf-frame-pointer" diff --git a/src/tls/c_hello.cpp b/src/tls/c_hello.cpp index 6c4964fb1..2455eae3b 100644 --- a/src/tls/c_hello.cpp +++ b/src/tls/c_hello.cpp @@ -204,6 +204,7 @@ void Client_Hello::deserialize_sslv2(const MemoryRegion& buf) m_fragment_size = 0; m_next_protocol = false; + m_supports_session_ticket = false; } /* @@ -257,6 +258,11 @@ void Client_Hello::deserialize(const MemoryRegion& buf) { m_fragment_size = frag->fragment_size(); } + else if(Session_Ticket* ticket = dynamic_cast(extn)) + { + m_supports_session_ticket = true; + m_session_ticket = ticket->contents(); + } else if(Renegotation_Extension* reneg = dynamic_cast(extn)) { // checked by TLS_Client / TLS_Server as they know the handshake state diff --git a/src/tls/tls_extensions.h b/src/tls/tls_extensions.h index 526436862..6d4e40434 100644 --- a/src/tls/tls_extensions.h +++ b/src/tls/tls_extensions.h @@ -183,12 +183,7 @@ class Session_Ticket : public TLS_Extension TLS_Handshake_Extension_Type type() const { return TLSEXT_SESSION_TICKET; } - /* - * Decrypt the session ticket and return the session info; - * used by server. - */ - TLS_Session decrypt(const SymmetricKey& key, - const MemoryRegion& key_name); + const MemoryVector& contents() const { return m_contents; } /** * Create empty extension, used by both client and server @@ -199,14 +194,16 @@ class Session_Ticket : public TLS_Extension * Extension with ticket, used by client */ Session_Ticket(const MemoryRegion& session_ticket) : - m_contents(session_ticket); + m_contents(session_ticket) {} /** * Deserialize a session ticket */ - Session_Ticket(const TLS_Data_Reader& reader, u16ibt extension_size); + Session_Ticket(const TLS_Data_Reader& reader, u16bit extension_size); MemoryVector serialize() const { return m_contents; } + + bool empty() const { return false; } private: MemoryVector m_contents; }; diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index ed8073bda..94e17cb9b 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -79,9 +79,10 @@ class Client_Hello : public Handshake_Message size_t fragment_size() const { return m_fragment_size; } - bool supports_session_ticket() const { returnm m_supports_session_ticket; } + bool supports_session_ticket() const { return m_supports_session_ticket; } - const MemoryRegion session_ticket() const { return m_session_ticket; } + const MemoryRegion& session_ticket() const + { return m_session_ticket; } Client_Hello(Record_Writer& writer, TLS_Handshake_Hash& hash, @@ -123,6 +124,9 @@ class Client_Hello : public Handshake_Message size_t m_fragment_size; bool m_secure_renegotiation; MemoryVector m_renegotiation_info; + + bool m_supports_session_ticket; + MemoryVector m_session_ticket; }; /** -- cgit v1.2.3