Botan
1.11.15
|
00001 /* 00002 * TLS Session State 00003 * (C) 2011-2012,2015 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/tls_session.h> 00009 #include <botan/der_enc.h> 00010 #include <botan/ber_dec.h> 00011 #include <botan/asn1_str.h> 00012 #include <botan/pem.h> 00013 #include <botan/aead.h> 00014 #include <botan/sha2_32.h> 00015 #include <botan/hmac.h> 00016 00017 namespace Botan { 00018 00019 namespace TLS { 00020 00021 Session::Session(const std::vector<byte>& session_identifier, 00022 const secure_vector<byte>& master_secret, 00023 Protocol_Version version, 00024 u16bit ciphersuite, 00025 byte compression_method, 00026 Connection_Side side, 00027 size_t fragment_size, 00028 const std::vector<X509_Certificate>& certs, 00029 const std::vector<byte>& ticket, 00030 const Server_Information& server_info, 00031 const std::string& srp_identifier, 00032 u16bit srtp_profile) : 00033 m_start_time(std::chrono::system_clock::now()), 00034 m_identifier(session_identifier), 00035 m_session_ticket(ticket), 00036 m_master_secret(master_secret), 00037 m_version(version), 00038 m_ciphersuite(ciphersuite), 00039 m_compression_method(compression_method), 00040 m_connection_side(side), 00041 m_srtp_profile(srtp_profile), 00042 m_fragment_size(fragment_size), 00043 m_peer_certs(certs), 00044 m_server_info(server_info), 00045 m_srp_identifier(srp_identifier) 00046 { 00047 } 00048 00049 Session::Session(const std::string& pem) 00050 { 00051 secure_vector<byte> der = PEM_Code::decode_check_label(pem, "TLS SESSION"); 00052 00053 *this = Session(&der[0], der.size()); 00054 } 00055 00056 Session::Session(const byte ber[], size_t ber_len) 00057 { 00058 byte side_code = 0; 00059 00060 ASN1_String server_hostname; 00061 ASN1_String server_service; 00062 size_t server_port; 00063 00064 ASN1_String srp_identifier_str; 00065 00066 byte major_version = 0, minor_version = 0; 00067 std::vector<byte> peer_cert_bits; 00068 00069 size_t start_time = 0; 00070 size_t srtp_profile = 0; 00071 00072 BER_Decoder(ber, ber_len) 00073 .start_cons(SEQUENCE) 00074 .decode_and_check(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION), 00075 "Unknown version in serialized TLS session") 00076 .decode_integer_type(start_time) 00077 .decode_integer_type(major_version) 00078 .decode_integer_type(minor_version) 00079 .decode(m_identifier, OCTET_STRING) 00080 .decode(m_session_ticket, OCTET_STRING) 00081 .decode_integer_type(m_ciphersuite) 00082 .decode_integer_type(m_compression_method) 00083 .decode_integer_type(side_code) 00084 .decode_integer_type(m_fragment_size) 00085 .decode(m_master_secret, OCTET_STRING) 00086 .decode(peer_cert_bits, OCTET_STRING) 00087 .decode(server_hostname) 00088 .decode(server_service) 00089 .decode(server_port) 00090 .decode(srp_identifier_str) 00091 .decode(srtp_profile) 00092 .end_cons() 00093 .verify_end(); 00094 00095 m_version = Protocol_Version(major_version, minor_version); 00096 m_start_time = std::chrono::system_clock::from_time_t(start_time); 00097 m_connection_side = static_cast<Connection_Side>(side_code); 00098 m_srtp_profile = srtp_profile; 00099 00100 m_server_info = Server_Information(server_hostname.value(), 00101 server_service.value(), 00102 server_port); 00103 00104 m_srp_identifier = srp_identifier_str.value(); 00105 00106 if(!peer_cert_bits.empty()) 00107 { 00108 DataSource_Memory certs(&peer_cert_bits[0], peer_cert_bits.size()); 00109 00110 while(!certs.end_of_data()) 00111 m_peer_certs.push_back(X509_Certificate(certs)); 00112 } 00113 } 00114 00115 secure_vector<byte> Session::DER_encode() const 00116 { 00117 std::vector<byte> peer_cert_bits; 00118 for(size_t i = 0; i != m_peer_certs.size(); ++i) 00119 peer_cert_bits += m_peer_certs[i].BER_encode(); 00120 00121 return DER_Encoder() 00122 .start_cons(SEQUENCE) 00123 .encode(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION)) 00124 .encode(static_cast<size_t>(std::chrono::system_clock::to_time_t(m_start_time))) 00125 .encode(static_cast<size_t>(m_version.major_version())) 00126 .encode(static_cast<size_t>(m_version.minor_version())) 00127 .encode(m_identifier, OCTET_STRING) 00128 .encode(m_session_ticket, OCTET_STRING) 00129 .encode(static_cast<size_t>(m_ciphersuite)) 00130 .encode(static_cast<size_t>(m_compression_method)) 00131 .encode(static_cast<size_t>(m_connection_side)) 00132 .encode(static_cast<size_t>(m_fragment_size)) 00133 .encode(m_master_secret, OCTET_STRING) 00134 .encode(peer_cert_bits, OCTET_STRING) 00135 .encode(ASN1_String(m_server_info.hostname(), UTF8_STRING)) 00136 .encode(ASN1_String(m_server_info.service(), UTF8_STRING)) 00137 .encode(static_cast<size_t>(m_server_info.port())) 00138 .encode(ASN1_String(m_srp_identifier, UTF8_STRING)) 00139 .encode(static_cast<size_t>(m_srtp_profile)) 00140 .end_cons() 00141 .get_contents(); 00142 } 00143 00144 std::string Session::PEM_encode() const 00145 { 00146 return PEM_Code::encode(this->DER_encode(), "TLS SESSION"); 00147 } 00148 00149 std::chrono::seconds Session::session_age() const 00150 { 00151 return std::chrono::duration_cast<std::chrono::seconds>( 00152 std::chrono::system_clock::now() - m_start_time); 00153 } 00154 00155 std::vector<byte> 00156 Session::encrypt(const SymmetricKey& key, RandomNumberGenerator& rng) const 00157 { 00158 std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/GCM", ENCRYPTION)); 00159 const size_t nonce_len = aead->default_nonce_length(); 00160 00161 const secure_vector<byte> nonce = rng.random_vec(nonce_len); 00162 const secure_vector<byte> bits = this->DER_encode(); 00163 00164 // Support any length key for input 00165 HMAC hmac(new SHA_256); 00166 hmac.set_key(key); 00167 hmac.update(nonce); 00168 aead->set_key(hmac.final()); 00169 00170 secure_vector<byte> buf = nonce; 00171 buf += bits; 00172 aead->start(&buf[0], nonce_len); 00173 aead->finish(buf, nonce_len); 00174 return unlock(buf); 00175 } 00176 00177 Session Session::decrypt(const byte in[], size_t in_len, const SymmetricKey& key) 00178 { 00179 try 00180 { 00181 std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/GCM", DECRYPTION)); 00182 const size_t nonce_len = aead->default_nonce_length(); 00183 00184 if(in_len < nonce_len + aead->tag_size()) 00185 throw Decoding_Error("Encrypted session too short to be valid"); 00186 00187 // Support any length key for input 00188 HMAC hmac(new SHA_256); 00189 hmac.set_key(key); 00190 hmac.update(in, nonce_len); // nonce bytes 00191 aead->set_key(hmac.final()); 00192 00193 aead->start(in, nonce_len); 00194 secure_vector<byte> buf(in + nonce_len, in + in_len); 00195 aead->finish(buf, 0); 00196 00197 return Session(&buf[0], buf.size()); 00198 } 00199 catch(std::exception& e) 00200 { 00201 throw Decoding_Error("Failed to decrypt serialized TLS session: " + 00202 std::string(e.what())); 00203 } 00204 } 00205 00206 } 00207 00208 } 00209