1 /*
2 * TLS Session State
3 * (C) 2011-2012,2015,2019 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/tls_session.h>
9 #include <botan/loadstor.h>
10 #include <botan/der_enc.h>
11 #include <botan/ber_dec.h>
12 #include <botan/asn1_obj.h>
13 #include <botan/pem.h>
14 #include <botan/aead.h>
15 #include <botan/mac.h>
16 #include <botan/rng.h>
17
18 namespace Botan {
19
20 namespace TLS {
21
Session(const std::vector<uint8_t> & session_identifier,const secure_vector<uint8_t> & master_secret,Protocol_Version version,uint16_t ciphersuite,Connection_Side side,bool extended_master_secret,bool encrypt_then_mac,const std::vector<X509_Certificate> & certs,const std::vector<uint8_t> & ticket,const Server_Information & server_info,const std::string & srp_identifier,uint16_t srtp_profile)22 Session::Session(const std::vector<uint8_t>& session_identifier,
23 const secure_vector<uint8_t>& master_secret,
24 Protocol_Version version,
25 uint16_t ciphersuite,
26 Connection_Side side,
27 bool extended_master_secret,
28 bool encrypt_then_mac,
29 const std::vector<X509_Certificate>& certs,
30 const std::vector<uint8_t>& ticket,
31 const Server_Information& server_info,
32 const std::string& srp_identifier,
33 uint16_t srtp_profile) :
34 m_start_time(std::chrono::system_clock::now()),
35 m_identifier(session_identifier),
36 m_session_ticket(ticket),
37 m_master_secret(master_secret),
38 m_version(version),
39 m_ciphersuite(ciphersuite),
40 m_connection_side(side),
41 m_srtp_profile(srtp_profile),
42 m_extended_master_secret(extended_master_secret),
43 m_encrypt_then_mac(encrypt_then_mac),
44 m_peer_certs(certs),
45 m_server_info(server_info),
46 m_srp_identifier(srp_identifier)
47 {
48 }
49
Session(const std::string & pem)50 Session::Session(const std::string& pem)
51 {
52 secure_vector<uint8_t> der = PEM_Code::decode_check_label(pem, "TLS SESSION");
53
54 *this = Session(der.data(), der.size());
55 }
56
Session(const uint8_t ber[],size_t ber_len)57 Session::Session(const uint8_t ber[], size_t ber_len)
58 {
59 uint8_t side_code = 0;
60
61 ASN1_String server_hostname;
62 ASN1_String server_service;
63 size_t server_port;
64
65 ASN1_String srp_identifier_str;
66
67 uint8_t major_version = 0, minor_version = 0;
68 std::vector<uint8_t> peer_cert_bits;
69
70 size_t start_time = 0;
71 size_t srtp_profile = 0;
72 size_t fragment_size = 0;
73 size_t compression_method = 0;
74
75 BER_Decoder(ber, ber_len)
76 .start_cons(SEQUENCE)
77 .decode_and_check(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION),
78 "Unknown version in serialized TLS session")
79 .decode_integer_type(start_time)
80 .decode_integer_type(major_version)
81 .decode_integer_type(minor_version)
82 .decode(m_identifier, OCTET_STRING)
83 .decode(m_session_ticket, OCTET_STRING)
84 .decode_integer_type(m_ciphersuite)
85 .decode_integer_type(compression_method)
86 .decode_integer_type(side_code)
87 .decode_integer_type(fragment_size)
88 .decode(m_extended_master_secret)
89 .decode(m_encrypt_then_mac)
90 .decode(m_master_secret, OCTET_STRING)
91 .decode(peer_cert_bits, OCTET_STRING)
92 .decode(server_hostname)
93 .decode(server_service)
94 .decode(server_port)
95 .decode(srp_identifier_str)
96 .decode(srtp_profile)
97 .end_cons()
98 .verify_end();
99
100 /*
101 * Compression is not supported and must be zero
102 */
103 if(compression_method != 0)
104 {
105 throw Decoding_Error("Serialized TLS session contains non-null compression method");
106 }
107
108 /*
109 Fragment size is not supported anymore, but the field is still
110 set in the session object.
111 */
112 if(fragment_size != 0)
113 {
114 throw Decoding_Error("Serialized TLS session used maximum fragment length which is "
115 " no longer supported");
116 }
117
118 m_version = Protocol_Version(major_version, minor_version);
119 m_start_time = std::chrono::system_clock::from_time_t(start_time);
120 m_connection_side = static_cast<Connection_Side>(side_code);
121 m_srtp_profile = static_cast<uint16_t>(srtp_profile);
122
123 m_server_info = Server_Information(server_hostname.value(),
124 server_service.value(),
125 static_cast<uint16_t>(server_port));
126
127 m_srp_identifier = srp_identifier_str.value();
128
129 if(!peer_cert_bits.empty())
130 {
131 DataSource_Memory certs(peer_cert_bits.data(), peer_cert_bits.size());
132
133 while(!certs.end_of_data())
134 m_peer_certs.push_back(X509_Certificate(certs));
135 }
136 }
137
DER_encode() const138 secure_vector<uint8_t> Session::DER_encode() const
139 {
140 std::vector<uint8_t> peer_cert_bits;
141 for(size_t i = 0; i != m_peer_certs.size(); ++i)
142 peer_cert_bits += m_peer_certs[i].BER_encode();
143
144 return DER_Encoder()
145 .start_cons(SEQUENCE)
146 .encode(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION))
147 .encode(static_cast<size_t>(std::chrono::system_clock::to_time_t(m_start_time)))
148 .encode(static_cast<size_t>(m_version.major_version()))
149 .encode(static_cast<size_t>(m_version.minor_version()))
150 .encode(m_identifier, OCTET_STRING)
151 .encode(m_session_ticket, OCTET_STRING)
152 .encode(static_cast<size_t>(m_ciphersuite))
153 .encode(static_cast<size_t>(/*old compression method*/0))
154 .encode(static_cast<size_t>(m_connection_side))
155 .encode(static_cast<size_t>(/*old fragment size*/0))
156 .encode(m_extended_master_secret)
157 .encode(m_encrypt_then_mac)
158 .encode(m_master_secret, OCTET_STRING)
159 .encode(peer_cert_bits, OCTET_STRING)
160 .encode(ASN1_String(m_server_info.hostname(), UTF8_STRING))
161 .encode(ASN1_String(m_server_info.service(), UTF8_STRING))
162 .encode(static_cast<size_t>(m_server_info.port()))
163 .encode(ASN1_String(m_srp_identifier, UTF8_STRING))
164 .encode(static_cast<size_t>(m_srtp_profile))
165 .end_cons()
166 .get_contents();
167 }
168
PEM_encode() const169 std::string Session::PEM_encode() const
170 {
171 return PEM_Code::encode(this->DER_encode(), "TLS SESSION");
172 }
173
session_age() const174 std::chrono::seconds Session::session_age() const
175 {
176 return std::chrono::duration_cast<std::chrono::seconds>(
177 std::chrono::system_clock::now() - m_start_time);
178 }
179
180 namespace {
181
182 // The output length of the HMAC must be a valid keylength for the AEAD
183 const char* TLS_SESSION_CRYPT_HMAC = "HMAC(SHA-512-256)";
184 // SIV would be better, but we can't assume it is available
185 const char* TLS_SESSION_CRYPT_AEAD = "AES-256/GCM";
186 const char* TLS_SESSION_CRYPT_KEY_NAME = "BOTAN TLS SESSION KEY NAME";
187 const uint64_t TLS_SESSION_CRYPT_MAGIC = 0x068B5A9D396C0000;
188 const size_t TLS_SESSION_CRYPT_MAGIC_LEN = 8;
189 const size_t TLS_SESSION_CRYPT_KEY_NAME_LEN = 4;
190 const size_t TLS_SESSION_CRYPT_AEAD_NONCE_LEN = 12;
191 const size_t TLS_SESSION_CRYPT_AEAD_KEY_SEED_LEN = 16;
192 const size_t TLS_SESSION_CRYPT_AEAD_TAG_SIZE = 16;
193
194 const size_t TLS_SESSION_CRYPT_HDR_LEN =
195 TLS_SESSION_CRYPT_MAGIC_LEN +
196 TLS_SESSION_CRYPT_KEY_NAME_LEN +
197 TLS_SESSION_CRYPT_AEAD_NONCE_LEN +
198 TLS_SESSION_CRYPT_AEAD_KEY_SEED_LEN;
199
200 const size_t TLS_SESSION_CRYPT_OVERHEAD =
201 TLS_SESSION_CRYPT_HDR_LEN + TLS_SESSION_CRYPT_AEAD_TAG_SIZE;
202
203 }
204
205 std::vector<uint8_t>
encrypt(const SymmetricKey & key,RandomNumberGenerator & rng) const206 Session::encrypt(const SymmetricKey& key, RandomNumberGenerator& rng) const
207 {
208 auto hmac = MessageAuthenticationCode::create_or_throw(TLS_SESSION_CRYPT_HMAC);
209 hmac->set_key(key);
210
211 // First derive the "key name"
212 std::vector<uint8_t> key_name(hmac->output_length());
213 hmac->update(TLS_SESSION_CRYPT_KEY_NAME);
214 hmac->final(key_name.data());
215 key_name.resize(TLS_SESSION_CRYPT_KEY_NAME_LEN);
216
217 std::vector<uint8_t> aead_nonce;
218 std::vector<uint8_t> key_seed;
219
220 rng.random_vec(aead_nonce, TLS_SESSION_CRYPT_AEAD_NONCE_LEN);
221 rng.random_vec(key_seed, TLS_SESSION_CRYPT_AEAD_KEY_SEED_LEN);
222
223 hmac->update(key_seed);
224 const secure_vector<uint8_t> aead_key = hmac->final();
225
226 secure_vector<uint8_t> bits = this->DER_encode();
227
228 // create the header
229 std::vector<uint8_t> buf;
230 buf.reserve(TLS_SESSION_CRYPT_OVERHEAD + bits.size());
231 buf.resize(TLS_SESSION_CRYPT_MAGIC_LEN);
232 store_be(TLS_SESSION_CRYPT_MAGIC, &buf[0]);
233 buf += key_name;
234 buf += key_seed;
235 buf += aead_nonce;
236
237 std::unique_ptr<AEAD_Mode> aead = AEAD_Mode::create_or_throw(TLS_SESSION_CRYPT_AEAD, ENCRYPTION);
238 BOTAN_ASSERT_NOMSG(aead->valid_nonce_length(TLS_SESSION_CRYPT_AEAD_NONCE_LEN));
239 BOTAN_ASSERT_NOMSG(aead->tag_size() == TLS_SESSION_CRYPT_AEAD_TAG_SIZE);
240 aead->set_key(aead_key);
241 aead->set_associated_data_vec(buf);
242 aead->start(aead_nonce);
243 aead->finish(bits, 0);
244
245 // append the ciphertext
246 buf += bits;
247 return buf;
248 }
249
decrypt(const uint8_t in[],size_t in_len,const SymmetricKey & key)250 Session Session::decrypt(const uint8_t in[], size_t in_len, const SymmetricKey& key)
251 {
252 try
253 {
254 const size_t min_session_size = 48 + 4; // serious under-estimate
255 if(in_len < TLS_SESSION_CRYPT_OVERHEAD + min_session_size)
256 throw Decoding_Error("Encrypted session too short to be valid");
257
258 const uint8_t* magic = &in[0];
259 const uint8_t* key_name = magic + TLS_SESSION_CRYPT_MAGIC_LEN;
260 const uint8_t* key_seed = key_name + TLS_SESSION_CRYPT_KEY_NAME_LEN;
261 const uint8_t* aead_nonce = key_seed + TLS_SESSION_CRYPT_AEAD_KEY_SEED_LEN;
262 const uint8_t* ctext = aead_nonce + TLS_SESSION_CRYPT_AEAD_NONCE_LEN;
263 const size_t ctext_len = in_len - TLS_SESSION_CRYPT_HDR_LEN; // includes the tag
264
265 if(load_be<uint64_t>(magic, 0) != TLS_SESSION_CRYPT_MAGIC)
266 throw Decoding_Error("Missing expected magic numbers");
267
268 auto hmac = MessageAuthenticationCode::create_or_throw(TLS_SESSION_CRYPT_HMAC);
269 hmac->set_key(key);
270
271 // First derive and check the "key name"
272 std::vector<uint8_t> cmp_key_name(hmac->output_length());
273 hmac->update(TLS_SESSION_CRYPT_KEY_NAME);
274 hmac->final(cmp_key_name.data());
275
276 if(same_mem(cmp_key_name.data(), key_name, TLS_SESSION_CRYPT_KEY_NAME_LEN) == false)
277 throw Decoding_Error("Wrong key name for encrypted session");
278
279 hmac->update(key_seed, TLS_SESSION_CRYPT_AEAD_KEY_SEED_LEN);
280 const secure_vector<uint8_t> aead_key = hmac->final();
281
282 auto aead = AEAD_Mode::create_or_throw(TLS_SESSION_CRYPT_AEAD, DECRYPTION);
283 aead->set_key(aead_key);
284 aead->set_associated_data(in, TLS_SESSION_CRYPT_HDR_LEN);
285 aead->start(aead_nonce, TLS_SESSION_CRYPT_AEAD_NONCE_LEN);
286 secure_vector<uint8_t> buf(ctext, ctext + ctext_len);
287 aead->finish(buf, 0);
288 return Session(buf.data(), buf.size());
289 }
290 catch(std::exception& e)
291 {
292 throw Decoding_Error("Failed to decrypt serialized TLS session: " +
293 std::string(e.what()));
294 }
295 }
296
297 }
298
299 }
300