Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

tls_session.cpp
Go to the documentation of this file.
1 /*
2 * TLS Session State
3 * (C) 2011-2012,2015 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/der_enc.h>
10 #include <botan/ber_dec.h>
11 #include <botan/asn1_str.h>
12 #include <botan/pem.h>
13 #include <botan/aead.h>
14 #include <botan/mac.h>
15
16 namespace Botan {
17
18 namespace TLS {
19
20 Session::Session(const std::vector<uint8_t>& session_identifier,
21 const secure_vector<uint8_t>& master_secret,
22 Protocol_Version version,
23 uint16_t ciphersuite,
24 uint8_t compression_method,
25 Connection_Side side,
26 bool extended_master_secret,
27 bool encrypt_then_mac,
28 const std::vector<X509_Certificate>& certs,
29 const std::vector<uint8_t>& ticket,
30 const Server_Information& server_info,
31 const std::string& srp_identifier,
32 uint16_t srtp_profile) :
33 m_start_time(std::chrono::system_clock::now()),
34 m_identifier(session_identifier),
35 m_session_ticket(ticket),
36 m_master_secret(master_secret),
37 m_version(version),
38 m_ciphersuite(ciphersuite),
39 m_compression_method(compression_method),
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
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
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
74 BER_Decoder(ber, ber_len)
75 .start_cons(SEQUENCE)
76 .decode_and_check(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION),
77 "Unknown version in serialized TLS session")
78 .decode_integer_type(start_time)
79 .decode_integer_type(major_version)
80 .decode_integer_type(minor_version)
81 .decode(m_identifier, OCTET_STRING)
82 .decode(m_session_ticket, OCTET_STRING)
83 .decode_integer_type(m_ciphersuite)
84 .decode_integer_type(m_compression_method)
85 .decode_integer_type(side_code)
86 .decode_integer_type(fragment_size)
87 .decode(m_extended_master_secret)
88 .decode(m_encrypt_then_mac)
89 .decode(m_master_secret, OCTET_STRING)
90 .decode(peer_cert_bits, OCTET_STRING)
91 .decode(server_hostname)
92 .decode(server_service)
93 .decode(server_port)
94 .decode(srp_identifier_str)
95 .decode(srtp_profile)
96 .end_cons()
97 .verify_end();
98
99 /*
100 Fragment size is not supported anymore, but the field is still
101 set in the session object.
102 */
103 if(fragment_size != 0)
104 {
105 throw Decoding_Error("Serialized TLS session used maximum fragment length which is "
106 " no longer supported");
107 }
108
109 m_version = Protocol_Version(major_version, minor_version);
110 m_start_time = std::chrono::system_clock::from_time_t(start_time);
111 m_connection_side = static_cast<Connection_Side>(side_code);
112 m_srtp_profile = static_cast<uint16_t>(srtp_profile);
113
114 m_server_info = Server_Information(server_hostname.value(),
115 server_service.value(),
116 static_cast<uint16_t>(server_port));
117
118 m_srp_identifier = srp_identifier_str.value();
119
120 if(!peer_cert_bits.empty())
121 {
122 DataSource_Memory certs(peer_cert_bits.data(), peer_cert_bits.size());
123
124 while(!certs.end_of_data())
125 m_peer_certs.push_back(X509_Certificate(certs));
126 }
127 }
128
129 secure_vector<uint8_t> Session::DER_encode() const
130 {
131 std::vector<uint8_t> peer_cert_bits;
132 for(size_t i = 0; i != m_peer_certs.size(); ++i)
133 peer_cert_bits += m_peer_certs[i].BER_encode();
134
135 return DER_Encoder()
136 .start_cons(SEQUENCE)
137 .encode(static_cast<size_t>(TLS_SESSION_PARAM_STRUCT_VERSION))
138 .encode(static_cast<size_t>(std::chrono::system_clock::to_time_t(m_start_time)))
139 .encode(static_cast<size_t>(m_version.major_version()))
140 .encode(static_cast<size_t>(m_version.minor_version()))
141 .encode(m_identifier, OCTET_STRING)
142 .encode(m_session_ticket, OCTET_STRING)
143 .encode(static_cast<size_t>(m_ciphersuite))
144 .encode(static_cast<size_t>(m_compression_method))
145 .encode(static_cast<size_t>(m_connection_side))
146 .encode(static_cast<size_t>(/*old fragment size*/0))
147 .encode(m_extended_master_secret)
148 .encode(m_encrypt_then_mac)
149 .encode(m_master_secret, OCTET_STRING)
150 .encode(peer_cert_bits, OCTET_STRING)
151 .encode(ASN1_String(m_server_info.hostname(), UTF8_STRING))
152 .encode(ASN1_String(m_server_info.service(), UTF8_STRING))
153 .encode(static_cast<size_t>(m_server_info.port()))
154 .encode(ASN1_String(m_srp_identifier, UTF8_STRING))
155 .encode(static_cast<size_t>(m_srtp_profile))
156 .end_cons()
157 .get_contents();
158 }
159
160 std::string Session::PEM_encode() const
161 {
162 return PEM_Code::encode(this->DER_encode(), "TLS SESSION");
163 }
164
165 std::chrono::seconds Session::session_age() const
166 {
167 return std::chrono::duration_cast<std::chrono::seconds>(
168 std::chrono::system_clock::now() - m_start_time);
169 }
170
171 std::vector<uint8_t>
172 Session::encrypt(const SymmetricKey& key, RandomNumberGenerator& rng) const
173 {
174 std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/GCM", ENCRYPTION));
175 const size_t nonce_len = aead->default_nonce_length();
176
177 const secure_vector<uint8_t> nonce = rng.random_vec(nonce_len);
178 const secure_vector<uint8_t> bits = this->DER_encode();
179
180 // Support any length key for input
181 std::unique_ptr<MessageAuthenticationCode> hmac(MessageAuthenticationCode::create("HMAC(SHA-256)"));
182 hmac->set_key(key);
183 hmac->update(nonce);
184 aead->set_key(hmac->final());
185
186 secure_vector<uint8_t> buf = nonce;
187 buf += bits;
188 aead->start(buf.data(), nonce_len);
189 aead->finish(buf, nonce_len);
190 return unlock(buf);
191 }
192
193 Session Session::decrypt(const uint8_t in[], size_t in_len, const SymmetricKey& key)
194 {
195 try
196 {
197 std::unique_ptr<AEAD_Mode> aead(get_aead("AES-256/GCM", DECRYPTION));
198 const size_t nonce_len = aead->default_nonce_length();
199
200 if(in_len < nonce_len + aead->tag_size())
201 throw Decoding_Error("Encrypted session too short to be valid");
202
203 // Support any length key for input
204 std::unique_ptr<MessageAuthenticationCode> hmac(MessageAuthenticationCode::create("HMAC(SHA-256)"));
205 hmac->set_key(key);
206 hmac->update(in, nonce_len); // nonce bytes
207 aead->set_key(hmac->final());
208
209 aead->start(in, nonce_len);
210 secure_vector<uint8_t> buf(in + nonce_len, in + in_len);
211 aead->finish(buf, 0);
212
213 return Session(buf.data(), buf.size());
214 }
215 catch(std::exception& e)
216 {
217 throw Decoding_Error("Failed to decrypt serialized TLS session: " +
218 std::string(e.what()));
219 }
220 }
221
222 }
223
224 }
Botan::TLS::Protocol_Version::minor_version
uint8_t minor_version() const
Definition: tls_version.h:82
Botan::TLS::Session
Definition: tls_session.h:27
Botan::TLS::Session::decrypt
static Session decrypt(const uint8_t ctext[], size_t ctext_size, const SymmetricKey &key)
Definition: tls_session.cpp:193
Botan::TLS::Session::start_time
std::chrono::system_clock::time_point start_time() const
Definition: tls_session.h:175
Botan::ASN1_String::value
std::string value() const
Definition: asn1_str.cpp:99
Botan::MessageAuthenticationCode::create
static std::unique_ptr< MessageAuthenticationCode > create(const std::string &algo_spec, const std::string &provider="")
Definition: mac.cpp:43
Botan::OctetString
Definition: symkey.h:19
Botan::RandomNumberGenerator::random_vec
secure_vector< uint8_t > random_vec(size_t bytes)
Definition: rng.h:133
Botan::BER_Decoder::decode_integer_type
BER_Decoder & decode_integer_type(T &out)
Definition: ber_dec.h:111
Botan::RandomNumberGenerator
Definition: rng.h:25
Botan::ENCRYPTION
Definition: cipher_mode.h:212
Botan::TLS::Server_Information::service
std::string service() const
Definition: tls_server_info.h:59
Botan::TLS::Session::DER_encode
secure_vector< uint8_t > DER_encode() const
Definition: tls_session.cpp:129
Botan::PEM_Code::encode
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
Botan::BER_Decoder::decode_and_check
BER_Decoder & decode_and_check(const T &expected, const std::string &error_msg)
Definition: ber_dec.h:146
Botan::PKCS8::BER_encode
secure_vector< uint8_t > BER_encode(const Private_Key &key)
Definition: pkcs8.cpp:130
Botan::DER_Encoder::get_contents
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:124
std
Definition: bigint.h:619
Botan::TLS::Session::encrypt
std::vector< uint8_t > encrypt(const SymmetricKey &key, RandomNumberGenerator &rng) const
Definition: tls_session.cpp:172
Botan::BER_Decoder::decode
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:376
Botan::TLS::Server_Information::port
uint16_t port() const
Definition: tls_server_info.h:64
Botan::TLS::Protocol_Version
Definition: tls_version.h:21
Botan::DER_Encoder::end_cons
DER_Encoder & end_cons()
Definition: der_enc.cpp:147
Botan::TLS::Session::Session
Session()
Definition: tls_session.h:34
Botan::TLS::Connection_Side
Connection_Side
Definition: tls_magic.h:27
Botan::DECRYPTION
Definition: cipher_mode.h:212
Botan::ASN1_String
Definition: asn1_str.h:18
Botan::TLS::Server_Information::hostname
std::string hostname() const
Definition: tls_server_info.h:53
Botan::DER_Encoder::encode
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:216
Botan::OCTET_STRING
Definition: asn1_obj.h:35
Botan::DER_Encoder
Definition: der_enc.h:22
Botan::X509_Certificate
Definition: x509cert.h:36
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
Botan::BER_Decoder::end_cons
BER_Decoder & end_cons()
Definition: ber_dec.cpp:272
Botan::TLS::Protocol_Version::major_version
uint8_t major_version() const
Definition: tls_version.h:77
Botan::Decoding_Error
Definition: exceptn.h:189
Botan::get_aead
AEAD_Mode * get_aead(const std::string &algo, Cipher_Dir dir)
Definition: aead.cpp:41
Botan::SEQUENCE
Definition: asn1_obj.h:39
Botan::BER_Decoder::start_cons
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: ber_dec.cpp:258
Botan::TLS::Server_Information
Definition: tls_server_info.h:21
Botan
Definition: alg_id.cpp:13
Botan::TLS::Session::session_age
std::chrono::seconds session_age() const
Definition: tls_session.cpp:165
Botan::unlock
std::vector< T > unlock(const secure_vector< T > &in)
Definition: secmem.h:125
Botan::PEM_Code::decode_check_label
secure_vector< uint8_t > decode_check_label(DataSource &source, const std::string &label_want)
Definition: pem.cpp:54
Botan::BER_Decoder::verify_end
BER_Decoder & verify_end()
Definition: ber_dec.cpp:168
Botan::DataSource_Memory
Definition: data_src.h:98
Botan::UTF8_STRING
Definition: asn1_obj.h:42
Botan::DER_Encoder::start_cons
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:137
Botan::TLS::Session::PEM_encode
std::string PEM_encode() const
Definition: tls_session.cpp:160
Botan::BER_Decoder
Definition: ber_dec.h:19