Botan: src/ssl/hello.cpp Source File

Botan 1.10.17

hello.cpp
Go to the documentation of this file.
1 /*
2 * TLS Hello Messages
3 * (C) 2004-2010 Jack Lloyd
4 *
5 * Released under the terms of the Botan license
6 */
7
8 #include <botan/internal/tls_messages.h>
9 #include <botan/internal/tls_reader.h>
10
11 namespace Botan {
12
13 /*
14 * Encode and send a Handshake message
15 */
16 void HandshakeMessage::send(Record_Writer& writer, HandshakeHash& hash) const
17 {
18 SecureVector<byte> buf = serialize();
19 SecureVector<byte> send_buf(4);
20
21 const size_t buf_size = buf.size();
22
23 send_buf[0] = type();
24
25 for(size_t i = 1; i != 4; ++i)
26 send_buf[i] = get_byte<u32bit>(i, buf_size);
27
28 send_buf += buf;
29
30 hash.update(send_buf);
31
32 writer.send(HANDSHAKE, &send_buf[0], send_buf.size());
33 writer.flush();
34 }
35
36 /*
37 * Create a new Hello Request message
38 */
39 Hello_Request::Hello_Request(Record_Writer& writer)
40 {
41 HandshakeHash dummy; // FIXME: *UGLY*
42 send(writer, dummy);
43 }
44
45 /*
46 * Serialize a Hello Request message
47 */
48 SecureVector<byte> Hello_Request::serialize() const
49 {
50 return SecureVector<byte>();
51 }
52
53 /*
54 * Deserialize a Hello Request message
55 */
56 void Hello_Request::deserialize(const MemoryRegion<byte>& buf)
57 {
58 if(buf.size())
59 throw Decoding_Error("Hello_Request: Must be empty, and is not");
60 }
61
62 /*
63 * Create a new Client Hello message
64 */
65 Client_Hello::Client_Hello(RandomNumberGenerator& rng,
66 Record_Writer& writer,
67 const TLS_Policy& policy,
68 HandshakeHash& hash)
69 {
70 c_random = rng.random_vec(32);
71
72 suites = policy.ciphersuites();
73 comp_algos = policy.compression();
74 c_version = policy.pref_version();
75
76 send(writer, hash);
77 }
78
79 /*
80 * Serialize a Client Hello message
81 */
82 SecureVector<byte> Client_Hello::serialize() const
83 {
84 SecureVector<byte> buf;
85
86 buf.push_back(static_cast<byte>(c_version >> 8));
87 buf.push_back(static_cast<byte>(c_version ));
88 buf += c_random;
89
90 append_tls_length_value(buf, sess_id, 1);
91 append_tls_length_value(buf, suites, 2);
92 append_tls_length_value(buf, comp_algos, 1);
93
94 return buf;
95 }
96
97 void Client_Hello::deserialize_sslv2(const MemoryRegion<byte>& buf)
98 {
99 if(buf.size() < 12 || buf[0] != 1)
100 throw Decoding_Error("Client_Hello: SSLv2 hello corrupted");
101
102 const size_t cipher_spec_len = make_u16bit(buf[3], buf[4]);
103 const size_t sess_id_len = make_u16bit(buf[5], buf[6]);
104 const size_t challenge_len = make_u16bit(buf[7], buf[8]);
105
106 const size_t expected_size =
107 (9 + sess_id_len + cipher_spec_len + challenge_len);
108
109 if(buf.size() != expected_size)
110 throw Decoding_Error("Client_Hello: SSLv2 hello corrupted");
111
112 if(sess_id_len != 0 || cipher_spec_len % 3 != 0 ||
113 (challenge_len < 16 || challenge_len > 32))
114 {
115 throw Decoding_Error("Client_Hello: SSLv2 hello corrupted");
116 }
117
118 for(size_t i = 9; i != 9 + cipher_spec_len; i += 3)
119 {
120 if(buf[i] != 0) // a SSLv2 cipherspec; ignore it
121 continue;
122
123 suites.push_back(make_u16bit(buf[i+1], buf[i+2]));
124 }
125
126 c_version = static_cast<Version_Code>(make_u16bit(buf[1], buf[2]));
127
128 c_random.resize(challenge_len);
129 copy_mem(&c_random[0], &buf[9+cipher_spec_len+sess_id_len], challenge_len);
130 }
131
132 /*
133 * Deserialize a Client Hello message
134 */
135 void Client_Hello::deserialize(const MemoryRegion<byte>& buf)
136 {
137 if(buf.size() == 0)
138 throw Decoding_Error("Client_Hello: Packet corrupted");
139
140 if(buf.size() < 41)
141 throw Decoding_Error("Client_Hello: Packet corrupted");
142
143 TLS_Data_Reader reader(buf);
144
145 c_version = static_cast<Version_Code>(reader.get_u16bit());
146 c_random = reader.get_fixed<byte>(32);
147
148 sess_id = reader.get_range<byte>(1, 0, 32);
149
150 suites = reader.get_range_vector<u16bit>(2, 1, 32767);
151
152 comp_algos = reader.get_range_vector<byte>(1, 1, 255);
153
154 if(reader.has_remaining())
155 {
156 const u16bit all_extn_size = reader.get_u16bit();
157
158 if(reader.remaining_bytes() != all_extn_size)
159 throw Decoding_Error("Client_Hello: Bad extension size");
160
161 while(reader.has_remaining())
162 {
163 const u16bit extension_code = reader.get_u16bit();
164 const u16bit extension_size = reader.get_u16bit();
165
166 if(extension_code == TLSEXT_SERVER_NAME_INDICATION)
167 {
168 u16bit name_bytes = reader.get_u16bit();
169
170 while(name_bytes)
171 {
172 byte name_type = reader.get_byte();
173 name_bytes--;
174
175 if(name_type == 0) // DNS
176 {
177 std::vector<byte> name =
178 reader.get_range_vector<byte>(2, 1, 65535);
179
180 requested_hostname.assign(
181 reinterpret_cast<const char*>(&name[0]),
182 name.size());
183
184 name_bytes -= (2 + name.size());
185 }
186 else
187 {
188 reader.discard_next(name_bytes);
189 name_bytes = 0;
190 }
191 }
192 }
193 else if(extension_code == TLSEXT_SRP_IDENTIFIER)
194 {
195 std::vector<byte> name = reader.get_range_vector<byte>(1, 1, 255);
196
197 requested_srp_id.assign(
198 reinterpret_cast<char*>(&name[0]),
199 name.size());
200 }
201 else
202 {
203 reader.discard_next(extension_size);
204 }
205 }
206 }
207 }
208
209 /*
210 * Check if we offered this ciphersuite
211 */
212 bool Client_Hello::offered_suite(u16bit ciphersuite) const
213 {
214 for(size_t i = 0; i != suites.size(); ++i)
215 if(suites[i] == ciphersuite)
216 return true;
217 return false;
218 }
219
220 /*
221 * Create a new Server Hello message
222 */
223 Server_Hello::Server_Hello(RandomNumberGenerator& rng,
224 Record_Writer& writer,
225 const TLS_Policy& policy,
226 const std::vector<X509_Certificate>& certs,
227 const Client_Hello& c_hello,
228 Version_Code ver,
229 HandshakeHash& hash)
230 {
231 bool have_rsa = false, have_dsa = false;
232
233 for(size_t i = 0; i != certs.size(); ++i)
234 {
235 Public_Key* key = certs[i].subject_public_key();
236 if(key->algo_name() == "RSA")
237 have_rsa = true;
238
239 if(key->algo_name() == "DSA")
240 have_dsa = true;
241 }
242
243 suite = policy.choose_suite(c_hello.ciphersuites(), have_rsa, have_dsa);
244
245 if(suite == 0)
246 throw TLS_Exception(PROTOCOL_VERSION,
247 "Can't agree on a ciphersuite with client");
248
249 comp_algo = policy.choose_compression(c_hello.compression_algos());
250
251 s_version = ver;
252 s_random = rng.random_vec(32);
253
254 send(writer, hash);
255 }
256
257 /*
258 * Serialize a Server Hello message
259 */
260 SecureVector<byte> Server_Hello::serialize() const
261 {
262 SecureVector<byte> buf;
263
264 buf.push_back(static_cast<byte>(s_version >> 8));
265 buf.push_back(static_cast<byte>(s_version ));
266 buf += s_random;
267
268 append_tls_length_value(buf, sess_id, 1);
269
270 buf.push_back(get_byte(0, suite));
271 buf.push_back(get_byte(1, suite));
272
273 buf.push_back(comp_algo);
274
275 return buf;
276 }
277
278 /*
279 * Deserialize a Server Hello message
280 */
281 void Server_Hello::deserialize(const MemoryRegion<byte>& buf)
282 {
283 if(buf.size() < 38)
284 throw Decoding_Error("Server_Hello: Packet corrupted");
285
286 TLS_Data_Reader reader(buf);
287
288 s_version = static_cast<Version_Code>(reader.get_u16bit());
289
290 if(s_version != SSL_V3 && s_version != TLS_V10 && s_version != TLS_V11)
291 {
292 throw TLS_Exception(PROTOCOL_VERSION,
293 "Server_Hello: Unsupported server version");
294 }
295
296 s_random = reader.get_fixed<byte>(32);
297
298 sess_id = reader.get_range<byte>(1, 0, 32);
299
300 suite = reader.get_u16bit();
301
302 comp_algo = reader.get_byte();
303 }
304
305 /*
306 * Create a new Server Hello Done message
307 */
308 Server_Hello_Done::Server_Hello_Done(Record_Writer& writer,
309 HandshakeHash& hash)
310 {
311 send(writer, hash);
312 }
313
314 /*
315 * Serialize a Server Hello Done message
316 */
317 SecureVector<byte> Server_Hello_Done::serialize() const
318 {
319 return SecureVector<byte>();
320 }
321
322 /*
323 * Deserialize a Server Hello Done message
324 */
325 void Server_Hello_Done::deserialize(const MemoryRegion<byte>& buf)
326 {
327 if(buf.size())
328 throw Decoding_Error("Server_Hello_Done: Must be empty, and is not");
329 }
330
331 }
Botan::append_tls_length_value
void append_tls_length_value(MemoryRegion< byte > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition: tls_reader.h:145
Botan::MemoryRegion::resize
void resize(size_t n)
Definition: secmem.h:217
Botan::Client_Hello::compression_algos
std::vector< byte > compression_algos() const
Definition: tls_messages.h:48
Botan::HandshakeMessage::send
void send(Record_Writer &, HandshakeHash &) const
Definition: hello.cpp:16
Botan::RandomNumberGenerator
Definition: rng.h:20
Botan::TLS_Policy::compression
virtual std::vector< byte > compression() const
Definition: tls_policy.cpp:68
Botan::MemoryRegion::push_back
void push_back(T x)
Definition: secmem.h:149
Botan::Public_Key::algo_name
virtual std::string algo_name() const =0
Botan::HANDSHAKE
Definition: tls_magic.h:36
Botan::TLS_Exception
Definition: tls_exceptn.h:19
Botan::get_byte
byte get_byte(size_t byte_num, T input)
Definition: get_byte.h:21
Botan::TLS_V10
Definition: tls_magic.h:25
Botan::TLS_Policy::pref_version
virtual Version_Code pref_version() const
Definition: tls_policy.h:50
Botan::HandshakeMessage::type
virtual Handshake_Type type() const =0
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::Client_Hello
Definition: tls_messages.h:41
Botan::Client_Hello::ciphersuites
std::vector< u16bit > ciphersuites() const
Definition: tls_messages.h:47
Botan::Client_Hello::offered_suite
bool offered_suite(u16bit) const
Definition: hello.cpp:212
Botan::TLS_Policy::ciphersuites
std::vector< u16bit > ciphersuites() const
Definition: tls_policy.cpp:16
Botan::Server_Hello::Server_Hello
Server_Hello(RandomNumberGenerator &rng, Record_Writer &, const TLS_Policy &, const std::vector< X509_Certificate > &, const Client_Hello &, Version_Code, HandshakeHash &)
Definition: hello.cpp:223
Botan::u16bit
unsigned short u16bit
Definition: types.h:27
Botan::Hello_Request::Hello_Request
Hello_Request(Record_Writer &)
Definition: hello.cpp:39
Botan::PROTOCOL_VERSION
Definition: tls_magic.h:81
Botan::Version_Code
Version_Code
Definition: tls_magic.h:22
Botan::HandshakeHash::update
void update(const byte in[], size_t length)
Definition: tls_handshake_hash.h:23
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:22
Botan
Definition: algo_base.h:14
Botan::SSL_V3
Definition: tls_magic.h:24
Botan::Record_Writer
Definition: tls_record.h:39
Botan::Record_Writer::flush
void flush()
Definition: rec_wri.cpp:162
Botan::Public_Key
Definition: pk_keys.h:21
Botan::TLS_Policy::choose_suite
virtual u16bit choose_suite(const std::vector< u16bit > &client_suites, bool rsa_ok, bool dsa_ok) const
Definition: tls_policy.cpp:78
Botan::MemoryRegion::size
size_t size() const
Definition: secmem.h:29
Botan::Server_Hello_Done::Server_Hello_Done
Server_Hello_Done(Record_Writer &, HandshakeHash &)
Definition: hello.cpp:308
Botan::TLSEXT_SRP_IDENTIFIER
Definition: tls_magic.h:186
Botan::make_u16bit
u16bit make_u16bit(byte i0, byte i1)
Definition: loadstor.h:47
Botan::TLS_V11
Definition: tls_magic.h:26
Botan::TLS_Policy
Definition: tls_policy.h:22
Botan::HandshakeHash
Definition: tls_handshake_hash.h:20
Botan::SecureVector< byte >
Botan::TLSEXT_SERVER_NAME_INDICATION
Definition: tls_magic.h:177
Botan::TLS_Policy::choose_compression
virtual byte choose_compression(const std::vector< byte > &client) const
Definition: tls_policy.cpp:100
Botan::Client_Hello::Client_Hello
Client_Hello(RandomNumberGenerator &rng, Record_Writer &, const TLS_Policy &, HandshakeHash &)
Definition: hello.cpp:65
Botan::Record_Writer::send
void send(byte type, const byte input[], size_t length)
Definition: rec_wri.cpp:131