Botan 1.10.17
tls_server.cpp
Go to the documentation of this file.
1/*
2* TLS Server
3* (C) 2004-2010 Jack Lloyd
4*
5* Released under the terms of the Botan license
6*/
7
8#include <botan/tls_server.h>
9#include <botan/internal/tls_alerts.h>
10#include <botan/internal/tls_state.h>
11#include <botan/loadstor.h>
12#include <botan/rsa.h>
13#include <botan/dh.h>
14
15namespace Botan {
16
17namespace {
18
19/*
20* Choose what version to respond with
21*/
22Version_Code choose_version(Version_Code client, Version_Code minimum)
23 {
24 if(client < minimum)
26 "Client version is unacceptable by policy");
27
28 if(client == SSL_V3 || client == TLS_V10 || client == TLS_V11)
29 return client;
30 return TLS_V11;
31 }
32
33// FIXME: checks are wrong for session reuse (add a flag for that)
34/*
35* Verify the state transition is allowed
36*/
37void server_check_state(Handshake_Type new_msg, Handshake_State* state)
38 {
39 class State_Transition_Error : public Unexpected_Message
40 {
41 public:
42 State_Transition_Error(const std::string& err) :
43 Unexpected_Message("State transition error from " + err) {}
44 };
45
46 if(new_msg == CLIENT_HELLO || new_msg == CLIENT_HELLO_SSLV2)
47 {
48 if(state->server_hello)
49 throw State_Transition_Error("ClientHello");
50 }
51 else if(new_msg == CERTIFICATE)
52 {
53 if(!state->do_client_auth || !state->cert_req ||
54 !state->server_hello_done || state->client_kex)
55 throw State_Transition_Error("ClientCertificate");
56 }
57 else if(new_msg == CLIENT_KEX)
58 {
59 if(!state->server_hello_done || state->client_verify ||
60 state->got_client_ccs)
61 throw State_Transition_Error("ClientKeyExchange");
62 }
63 else if(new_msg == CERTIFICATE_VERIFY)
64 {
65 if(!state->cert_req || !state->client_certs || !state->client_kex ||
66 state->got_client_ccs)
67 throw State_Transition_Error("CertificateVerify");
68 }
69 else if(new_msg == HANDSHAKE_CCS)
70 {
71 if(!state->client_kex || state->client_finished)
72 throw State_Transition_Error("ClientChangeCipherSpec");
73 }
74 else if(new_msg == FINISHED)
75 {
76 if(!state->got_client_ccs)
77 throw State_Transition_Error("ClientFinished");
78 }
79 else
80 throw Unexpected_Message("Unexpected message in handshake");
81 }
82
83}
84
85/*
86* TLS Server Constructor
87*/
88TLS_Server::TLS_Server(std::tr1::function<size_t (byte[], size_t)> input_fn,
89 std::tr1::function<void (const byte[], size_t)> output_fn,
90 const TLS_Policy& policy,
92 const X509_Certificate& cert,
93 const Private_Key& cert_key) :
94 input_fn(input_fn),
95 policy(policy),
96 rng(rng),
97 writer(output_fn)
98 {
99 state = 0;
100
101 cert_chain.push_back(cert);
102 private_key = PKCS8::copy_key(cert_key, rng);
103
104 try {
105 active = false;
106 writer.set_version(TLS_V10);
107 do_handshake();
108 active = true;
109 }
110 catch(std::exception& e)
111 {
112 if(state)
113 {
114 delete state;
115 state = 0;
116 }
117
118 writer.alert(FATAL, HANDSHAKE_FAILURE);
119 throw Stream_IO_Error(std::string("TLS_Server: Handshake failed: ") +
120 e.what());
121 }
122 }
123
124/*
125* TLS Server Destructor
126*/
128 {
129 close();
130 delete private_key;
131 delete state;
132 }
133
134/*
135* Return the peer's certificate chain
136*/
137std::vector<X509_Certificate> TLS_Server::peer_cert_chain() const
138 {
139 return peer_certs;
140 }
141
142/*
143* Write to a TLS connection
144*/
145void TLS_Server::write(const byte buf[], size_t length)
146 {
147 if(!active)
148 throw Internal_Error("TLS_Server::write called while closed");
149
150 writer.send(APPLICATION_DATA, buf, length);
151 }
152
153/*
154* Read from a TLS connection
155*/
156size_t TLS_Server::read(byte out[], size_t length)
157 {
158 if(!active)
159 throw Internal_Error("TLS_Server::read called while closed");
160
161 writer.flush();
162
163 while(read_buf.size() == 0)
164 {
165 state_machine();
166 if(active == false)
167 break;
168 }
169
170 size_t got = std::min<size_t>(read_buf.size(), length);
171 read_buf.read(out, got);
172 return got;
173 }
174
175/*
176* Check connection status
177*/
179 {
180 if(!active)
181 return true;
182 return false;
183 }
184
185/*
186* Close a TLS connection
187*/
189 {
191 }
192
193/*
194* Close a TLS connection
195*/
196void TLS_Server::close(Alert_Level level, Alert_Type alert_code)
197 {
198 if(active)
199 {
200 try {
201 active = false;
202 writer.alert(level, alert_code);
203 writer.flush();
204 }
205 catch(...) {}
206 }
207 }
208
209/*
210* Iterate the TLS state machine
211*/
212void TLS_Server::state_machine()
213 {
214 byte rec_type = CONNECTION_CLOSED;
215 SecureVector<byte> record(1024);
216
217 size_t bytes_needed = reader.get_record(rec_type, record);
218
219 while(bytes_needed)
220 {
221 size_t to_get = std::min<size_t>(record.size(), bytes_needed);
222 size_t got = input_fn(&record[0], to_get);
223
224 if(got == 0)
225 {
226 rec_type = CONNECTION_CLOSED;
227 break;
228 }
229
230 reader.add_input(&record[0], got);
231
232 bytes_needed = reader.get_record(rec_type, record);
233 }
234
235 if(rec_type == CONNECTION_CLOSED)
236 {
237 active = false;
238 reader.reset();
239 writer.reset();
240 }
241 else if(rec_type == APPLICATION_DATA)
242 {
243 if(active)
244 read_buf.write(&record[0], record.size());
245 else
246 throw Unexpected_Message("Application data before handshake done");
247 }
248 else if(rec_type == HANDSHAKE || rec_type == CHANGE_CIPHER_SPEC)
249 read_handshake(rec_type, record);
250 else if(rec_type == ALERT)
251 {
252 Alert alert(record);
253
254 if(alert.is_fatal() || alert.type() == CLOSE_NOTIFY)
255 {
256 if(alert.type() == CLOSE_NOTIFY)
257 writer.alert(WARNING, CLOSE_NOTIFY);
258
259 reader.reset();
260 writer.reset();
261 active = false;
262 }
263 }
264 else
265 throw Unexpected_Message("Unknown message type received");
266 }
267
268/*
269* Split up and process handshake messages
270*/
271void TLS_Server::read_handshake(byte rec_type,
272 const MemoryRegion<byte>& rec_buf)
273 {
274 if(rec_type == HANDSHAKE)
275 {
276 if(!state)
277 state = new Handshake_State;
278 state->queue.write(&rec_buf[0], rec_buf.size());
279 }
280
281 while(true)
282 {
284 SecureVector<byte> contents;
285
286 if(rec_type == HANDSHAKE)
287 {
288 if(state->queue.size() >= 4)
289 {
290 byte head[4] = { 0 };
291 state->queue.peek(head, 4);
292
293 const size_t length = make_u32bit(0, head[1], head[2], head[3]);
294
295 if(state->queue.size() >= length + 4)
296 {
297 type = static_cast<Handshake_Type>(head[0]);
298 contents.resize(length);
299 state->queue.read(head, 4);
300 state->queue.read(&contents[0], contents.size());
301 }
302 }
303 }
304 else if(rec_type == CHANGE_CIPHER_SPEC)
305 {
306 if(state->queue.size() == 0 && rec_buf.size() == 1 && rec_buf[0] == 1)
307 type = HANDSHAKE_CCS;
308 else
309 throw Decoding_Error("Malformed ChangeCipherSpec message");
310 }
311 else
312 throw Decoding_Error("Unknown message type in handshake processing");
313
314 if(type == HANDSHAKE_NONE)
315 break;
316
317 process_handshake_msg(type, contents);
318
319 if(type == HANDSHAKE_CCS || !state)
320 break;
321 }
322 }
323
324/*
325* Process a handshake message
326*/
327void TLS_Server::process_handshake_msg(Handshake_Type type,
328 const MemoryRegion<byte>& contents)
329 {
330 rng.add_entropy(&contents[0], contents.size());
331
332 if(state == 0)
333 throw Unexpected_Message("Unexpected handshake message");
334
335 if(active && (type == CLIENT_HELLO || type == CLIENT_HELLO_SSLV2))
336 {
337 delete state;
338 state = 0;
339 writer.alert(WARNING, NO_RENEGOTIATION);
340 return;
341 }
342
343 if(type != HANDSHAKE_CCS && type != FINISHED)
344 {
345 if(type != CLIENT_HELLO_SSLV2)
346 {
347 state->hash.update(static_cast<byte>(type));
348
349 const size_t record_length = contents.size();
350 for(size_t i = 0; i != 3; i++)
351 state->hash.update(get_byte<u32bit>(i+1, record_length));
352 }
353
354 state->hash.update(contents);
355 }
356
357 if(type == CLIENT_HELLO || type == CLIENT_HELLO_SSLV2)
358 {
359 server_check_state(type, state);
360
361 state->client_hello = new Client_Hello(contents, type);
362
363 client_requested_hostname = state->client_hello->hostname();
364
365 state->version = choose_version(state->client_hello->version(),
366 policy.min_version());
367
368 writer.set_version(state->version);
369 reader.set_version(state->version);
370
371 state->server_hello = new Server_Hello(rng, writer,
372 policy, cert_chain,
373 *(state->client_hello),
374 state->version, state->hash);
375
376 state->suite = CipherSuite(state->server_hello->ciphersuite());
377
378 if(state->suite.sig_type() != TLS_ALGO_SIGNER_ANON)
379 {
380 // FIXME: should choose certs based on sig type
381 state->server_certs = new Certificate(writer, cert_chain,
382 state->hash);
383 }
384
385 state->kex_priv = PKCS8::copy_key(*private_key, rng);
386 if(state->suite.kex_type() != TLS_ALGO_KEYEXCH_NOKEX)
387 {
388 if(state->suite.kex_type() == TLS_ALGO_KEYEXCH_RSA)
389 {
390 state->kex_priv = new RSA_PrivateKey(rng,
391 policy.rsa_export_keysize());
392 }
393 else if(state->suite.kex_type() == TLS_ALGO_KEYEXCH_DH)
394 {
395 state->kex_priv = new DH_PrivateKey(rng, policy.dh_group());
396 }
397 else
398 throw Internal_Error("TLS_Server: Unknown ciphersuite kex type");
399
400 state->server_kex =
401 new Server_Key_Exchange(rng, writer,
402 state->kex_priv, private_key,
403 state->client_hello->random(),
404 state->server_hello->random(),
405 state->hash);
406 }
407
408 if(policy.require_client_auth())
409 {
410 state->do_client_auth = true;
411 throw Internal_Error("Client auth not implemented");
412 // FIXME: send client auth request here
413 }
414
415 state->server_hello_done = new Server_Hello_Done(writer, state->hash);
416 }
417 else if(type == CERTIFICATE)
418 {
419 server_check_state(type, state);
420 // FIXME: process this
421 }
422 else if(type == CLIENT_KEX)
423 {
424 server_check_state(type, state);
425
426 state->client_kex = new Client_Key_Exchange(contents, state->suite,
427 state->version);
428
429 SecureVector<byte> pre_master =
430 state->client_kex->pre_master_secret(rng, state->kex_priv,
431 state->server_hello->version());
432
433 state->keys = SessionKeys(state->suite, state->version, pre_master,
434 state->client_hello->random(),
435 state->server_hello->random());
436 }
437 else if(type == CERTIFICATE_VERIFY)
438 {
439 server_check_state(type, state);
440 // FIXME: process this
441 }
442 else if(type == HANDSHAKE_CCS)
443 {
444 server_check_state(type, state);
445
446 reader.set_keys(state->suite, state->keys, SERVER);
447 state->got_client_ccs = true;
448 }
449 else if(type == FINISHED)
450 {
451 server_check_state(type, state);
452
453 state->client_finished = new Finished(contents);
454
455 if(!state->client_finished->verify(state->keys.master_secret(),
456 state->version, state->hash, CLIENT))
458 "Finished message didn't verify");
459
460 state->hash.update(static_cast<byte>(type));
461
462 const size_t record_length = contents.size();
463 for(size_t i = 0; i != 3; i++)
464 state->hash.update(get_byte<u32bit>(i+1, record_length));
465
466 state->hash.update(contents);
467
468 writer.send(CHANGE_CIPHER_SPEC, 1);
469 writer.flush();
470
471 writer.set_keys(state->suite, state->keys, SERVER);
472
473 state->server_finished = new Finished(writer, state->version, SERVER,
474 state->keys.master_secret(),
475 state->hash);
476
477 delete state;
478 state = 0;
479 active = true;
480 }
481 else
482 throw Unexpected_Message("Unknown handshake message received");
483 }
484
485/*
486* Perform a server-side TLS handshake
487*/
488void TLS_Server::do_handshake()
489 {
490 while(true)
491 {
492 if(active && !state)
493 break;
494
495 state_machine();
496
497 if(!active && !state)
498 throw TLS_Exception(HANDSHAKE_FAILURE, "TLS_Server: Handshake failed");
499 }
500 }
501
502}
Certificate(Record_Writer &, const std::vector< X509_Certificate > &, HandshakeHash &)
Definition cert_req.cpp:86
Client_Hello(RandomNumberGenerator &rng, Record_Writer &, const TLS_Policy &, HandshakeHash &)
Definition hello.cpp:65
Client_Key_Exchange(RandomNumberGenerator &rng, Record_Writer &output, HandshakeHash &hash, const Public_Key *my_key, Version_Code using_version, Version_Code pref_version)
Definition c_kex.cpp:22
DH_PrivateKey(const AlgorithmIdentifier &alg_id, const MemoryRegion< byte > &key_bits, RandomNumberGenerator &rng)
Definition dh.cpp:60
Finished(Record_Writer &, Version_Code, Connection_Side, const MemoryRegion< byte > &, HandshakeHash &)
Definition finished.cpp:16
RSA_PrivateKey(const AlgorithmIdentifier &alg_id, const MemoryRegion< byte > &key_bits, RandomNumberGenerator &rng)
Definition rsa.h:53
void alert(Alert_Level, Alert_Type)
Definition rec_wri.cpp:264
Server_Hello_Done(Record_Writer &, HandshakeHash &)
Definition hello.cpp:308
Server_Hello(RandomNumberGenerator &rng, Record_Writer &, const TLS_Policy &, const std::vector< X509_Certificate > &, const Client_Hello &, Version_Code, HandshakeHash &)
Definition hello.cpp:223
Server_Key_Exchange(RandomNumberGenerator &rng, Record_Writer &, const Public_Key *, const Private_Key *, const MemoryRegion< byte > &, const MemoryRegion< byte > &, HandshakeHash &)
Definition s_kex.cpp:22
TLS_Exception(Alert_Type type, const std::string &err_msg="Unknown error")
Definition tls_exceptn.h:24
bool is_closed() const
std::vector< X509_Certificate > peer_cert_chain() const
void write(const byte buf[], size_t buf_len)
TLS_Server(std::tr1::function< size_t(byte[], size_t)> input_fn, std::tr1::function< void(const byte[], size_t)> output_fn, const TLS_Policy &policy, RandomNumberGenerator &rng, const X509_Certificate &cert, const Private_Key &cert_key)
size_t read(byte buf[], size_t buf_len)
Private_Key * copy_key(const Private_Key &key, RandomNumberGenerator &rng)
Definition pkcs8.cpp:250
Alert_Type
Definition tls_magic.h:62
@ PROTOCOL_VERSION
Definition tls_magic.h:81
@ HANDSHAKE_FAILURE
Definition tls_magic.h:69
@ NO_RENEGOTIATION
Definition tls_magic.h:85
@ DECRYPT_ERROR
Definition tls_magic.h:79
@ CLOSE_NOTIFY
Definition tls_magic.h:63
byte get_byte(size_t byte_num, T input)
Definition get_byte.h:21
@ SERVER
Definition tls_magic.h:29
@ CLIENT
Definition tls_magic.h:29
u32bit make_u32bit(byte i0, byte i1, byte i2, byte i3)
Definition loadstor.h:60
@ TLS_ALGO_KEYEXCH_DH
Definition tls_magic.h:155
@ TLS_ALGO_SIGNER_ANON
Definition tls_magic.h:147
@ TLS_ALGO_KEYEXCH_NOKEX
Definition tls_magic.h:153
@ TLS_ALGO_KEYEXCH_RSA
Definition tls_magic.h:154
@ ALERT
Definition tls_magic.h:35
@ APPLICATION_DATA
Definition tls_magic.h:37
@ HANDSHAKE
Definition tls_magic.h:36
@ CONNECTION_CLOSED
Definition tls_magic.h:32
@ CHANGE_CIPHER_SPEC
Definition tls_magic.h:34
Handshake_Type
Definition tls_magic.h:40
@ CLIENT_HELLO
Definition tls_magic.h:42
@ CLIENT_HELLO_SSLV2
Definition tls_magic.h:43
@ CERTIFICATE_VERIFY
Definition tls_magic.h:49
@ FINISHED
Definition tls_magic.h:51
@ HANDSHAKE_NONE
Definition tls_magic.h:54
@ HANDSHAKE_CCS
Definition tls_magic.h:53
@ CERTIFICATE
Definition tls_magic.h:45
@ CLIENT_KEX
Definition tls_magic.h:50
Alert_Level
Definition tls_magic.h:57
@ WARNING
Definition tls_magic.h:58
@ FATAL
Definition tls_magic.h:59
Version_Code
Definition tls_magic.h:22
@ SSL_V3
Definition tls_magic.h:24
@ TLS_V10
Definition tls_magic.h:25
@ TLS_V11
Definition tls_magic.h:26
Decoding_Error(const std::string &name)
Definition exceptn.h:140
Internal_Error(const std::string &err)
Definition exceptn.h:47
Stream_IO_Error(const std::string &err)
Definition exceptn.h:167
Unexpected_Message(const std::string &err)
Definition tls_exceptn.h:37