1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
|
/*
* TLS Session
* (C) 2011-2012,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_TLS_SESSION_STATE_H__
#define BOTAN_TLS_SESSION_STATE_H__
#include <botan/x509cert.h>
#include <botan/tls_version.h>
#include <botan/tls_ciphersuite.h>
#include <botan/tls_magic.h>
#include <botan/tls_server_info.h>
#include <botan/secmem.h>
#include <botan/symkey.h>
#include <chrono>
namespace Botan {
namespace TLS {
/**
* Class representing a TLS session state
*/
class BOTAN_DLL Session
{
public:
/**
* Uninitialized session
*/
Session() :
m_start_time(std::chrono::system_clock::time_point::min()),
m_version(),
m_ciphersuite(0),
m_compression_method(0),
m_connection_side(static_cast<Connection_Side>(0)),
m_srtp_profile(0),
m_extended_master_secret(false),
m_encrypt_then_mac(false)
{}
/**
* New session (sets session start time)
*/
Session(const std::vector<byte>& session_id,
const secure_vector<byte>& master_secret,
Protocol_Version version,
u16bit ciphersuite,
byte compression_method,
Connection_Side side,
bool supports_extended_master_secret,
bool supports_encrypt_then_mac,
const std::vector<X509_Certificate>& peer_certs,
const std::vector<byte>& session_ticket,
const Server_Information& server_info,
const std::string& srp_identifier,
u16bit srtp_profile);
/**
* Load a session from DER representation (created by DER_encode)
* @param ber DER representation buffer
* @param ber_len size of buffer in bytes
*/
Session(const byte ber[], size_t ber_len);
/**
* Load a session from PEM representation (created by PEM_encode)
* @param pem PEM representation
*/
explicit Session(const std::string& pem);
/**
* Encode this session data for storage
* @warning if the master secret is compromised so is the
* session traffic
*/
secure_vector<byte> DER_encode() const;
/**
* Encrypt a session (useful for serialization or session tickets)
*/
std::vector<byte> encrypt(const SymmetricKey& key,
RandomNumberGenerator& rng) const;
/**
* Decrypt a session created by encrypt
* @param ctext the ciphertext returned by encrypt
* @param ctext_size the size of ctext in bytes
* @param key the same key used by the encrypting side
*/
static Session decrypt(const byte ctext[],
size_t ctext_size,
const SymmetricKey& key);
/**
* Decrypt a session created by encrypt
* @param ctext the ciphertext returned by encrypt
* @param key the same key used by the encrypting side
*/
static inline Session decrypt(const std::vector<byte>& ctext,
const SymmetricKey& key)
{
return Session::decrypt(ctext.data(), ctext.size(), key);
}
/**
* Encode this session data for storage
* @warning if the master secret is compromised so is the
* session traffic
*/
std::string PEM_encode() const;
/**
* Get the version of the saved session
*/
Protocol_Version version() const { return m_version; }
/**
* Get the ciphersuite code of the saved session
*/
u16bit ciphersuite_code() const { return m_ciphersuite; }
/**
* Get the ciphersuite info of the saved session
*/
Ciphersuite ciphersuite() const { return Ciphersuite::by_id(m_ciphersuite); }
/**
* Get the compression method used in the saved session
*/
byte compression_method() const { return m_compression_method; }
/**
* Get which side of the connection the resumed session we are/were
* acting as.
*/
Connection_Side side() const { return m_connection_side; }
/**
* Get the SRP identity (if sent by the client in the initial handshake)
*/
const std::string& srp_identifier() const { return m_srp_identifier; }
/**
* Get the saved master secret
*/
const secure_vector<byte>& master_secret() const { return m_master_secret; }
/**
* Get the session identifier
*/
const std::vector<byte>& session_id() const { return m_identifier; }
/**
* Get the negotiated DTLS-SRTP algorithm (RFC 5764)
*/
u16bit dtls_srtp_profile() const { return m_srtp_profile; }
bool supports_extended_master_secret() const { return m_extended_master_secret; }
bool supports_encrypt_then_mac() const { return m_encrypt_then_mac; }
/**
* Return the certificate chain of the peer (possibly empty)
*/
const std::vector<X509_Certificate>& peer_certs() const { return m_peer_certs; }
/**
* Get the wall clock time this session began
*/
std::chrono::system_clock::time_point start_time() const { return m_start_time; }
/**
* Return how long this session has existed (in seconds)
*/
std::chrono::seconds session_age() const;
/**
* Return the session ticket the server gave us
*/
const std::vector<byte>& session_ticket() const { return m_session_ticket; }
/**
* @return information about the TLS server
*/
const Server_Information& server_info() const { return m_server_info; }
private:
enum { TLS_SESSION_PARAM_STRUCT_VERSION = 20160812};
std::chrono::system_clock::time_point m_start_time;
std::vector<byte> m_identifier;
std::vector<byte> m_session_ticket; // only used by client side
secure_vector<byte> m_master_secret;
Protocol_Version m_version;
u16bit m_ciphersuite;
byte m_compression_method;
Connection_Side m_connection_side;
u16bit m_srtp_profile;
bool m_extended_master_secret;
bool m_encrypt_then_mac;
std::vector<X509_Certificate> m_peer_certs;
Server_Information m_server_info; // optional
std::string m_srp_identifier; // optional
};
}
}
#endif
|