Botan: src/ssl/tls_server.cpp Source File

Botan 1.10.12

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

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
15 namespace Botan {
16
17 namespace {
18
19 /*
20 * Choose what version to respond with
21 */
22 Version_Code choose_version(Version_Code client, Version_Code minimum)
23 {
24 if(client < minimum)
25 throw TLS_Exception(PROTOCOL_VERSION,
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 */
37 void 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 */
88 TLS_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,
91 RandomNumberGenerator& rng,
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 */
127 TLS_Server::~TLS_Server()
128 {
129 close();
130 delete private_key;
131 delete state;
132 }
133
134 /*
135 * Return the peer's certificate chain
136 */
137 std::vector<X509_Certificate> TLS_Server::peer_cert_chain() const
138 {
139 return peer_certs;
140 }
141
142 /*
143 * Write to a TLS connection
144 */
145 void 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 */
156 size_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 */
178 bool TLS_Server::is_closed() const
179 {
180 if(!active)
181 return true;
182 return false;
183 }
184
185 /*
186 * Close a TLS connection
187 */
188 void TLS_Server::close()
189 {
190 close(WARNING, CLOSE_NOTIFY);
191 }
192
193 /*
194 * Close a TLS connection
195 */
196 void 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 */
212 void 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 */
271 void 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 {
283 Handshake_Type type = HANDSHAKE_NONE;
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 */
327 void 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))
457 throw TLS_Exception(DECRYPT_ERROR,
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 */
488 void 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 }
Botan::Stream_IO_Error
Definition: exceptn.h:165
Botan::TLS_Policy::require_client_auth
virtual bool require_client_auth() const
Definition: tls_policy.h:37
Botan::MemoryRegion::resize
void resize(size_t n)
Definition: secmem.h:211
Botan::TLS_Server::read
size_t read(byte buf[], size_t buf_len)
Definition: tls_server.cpp:156
Botan::Alert::type
Alert_Type type() const
Definition: tls_alerts.h:29
Botan::Client_Key_Exchange
Definition: tls_messages.h:86
Botan::Record_Reader::get_record
size_t get_record(byte &msg_type, MemoryRegion< byte > &buffer)
Definition: rec_read.cpp:119
Botan::ALERT
Definition: tls_magic.h:35
Botan::SecureQueue::read
size_t read(byte[], size_t)
Definition: secqueue.cpp:137
Botan::RandomNumberGenerator::add_entropy
virtual void add_entropy(const byte in[], size_t length)=0
Botan::RandomNumberGenerator
Definition: rng.h:20
Botan::TLS_ALGO_KEYEXCH_NOKEX
Definition: tls_magic.h:153
Botan::TLS_Policy::min_version
virtual Version_Code min_version() const
Definition: tls_policy.h:45
Botan::Private_Key
Definition: pk_keys.h:86
Botan::Record_Reader::add_input
void add_input(const byte input[], size_t input_size)
Definition: rec_read.cpp:111
Botan::TLS_Server::~TLS_Server
~TLS_Server()
Definition: tls_server.cpp:127
Botan::SERVER
Definition: tls_magic.h:29
Botan::TLS_Server::peer_cert_chain
std::vector< X509_Certificate > peer_cert_chain() const
Definition: tls_server.cpp:137
Botan::Internal_Error
Definition: exceptn.h:45
Botan::HANDSHAKE_FAILURE
Definition: tls_magic.h:69
Botan::FINISHED
Definition: tls_magic.h:51
Botan::Record_Writer::set_version
void set_version(Version_Code)
Definition: rec_wri.cpp:51
Botan::WARNING
Definition: tls_magic.h:58
Botan::HANDSHAKE
Definition: tls_magic.h:36
Botan::TLS_Exception
Definition: tls_exceptn.h:19
Botan::TLS_V10
Definition: tls_magic.h:25
Botan::Record_Writer::set_keys
void set_keys(const CipherSuite &, const SessionKeys &, Connection_Side)
Definition: rec_wri.cpp:63
Botan::Alert::is_fatal
bool is_fatal() const
Definition: tls_alerts.h:24
Botan::CLIENT_HELLO_SSLV2
Definition: tls_magic.h:43
Botan::Handshake_Type
Handshake_Type
Definition: tls_magic.h:40
Botan::TLS_Policy::dh_group
virtual DL_Group dh_group() const
Definition: tls_policy.cpp:115
Botan::Record_Reader::set_version
void set_version(Version_Code version)
Definition: rec_read.cpp:34
Botan::byte
unsigned char byte
Definition: types.h:22
Botan::Alert_Level
Alert_Level
Definition: tls_magic.h:57
Botan::Client_Hello
Definition: tls_messages.h:41
Botan::X509_Certificate
Definition: x509cert.h:23
Botan::TLS_Server::write
void write(const byte buf[], size_t buf_len)
Definition: tls_server.cpp:145
Botan::Certificate
Definition: tls_messages.h:118
Botan::Record_Reader::reset
void reset()
Definition: rec_read.cpp:17
Botan::PROTOCOL_VERSION
Definition: tls_magic.h:81
Botan::DECRYPT_ERROR
Definition: tls_magic.h:79
Botan::SessionKeys
Definition: tls_session_key.h:20
Botan::CLOSE_NOTIFY
Definition: tls_magic.h:63
Botan::Decoding_Error
Definition: exceptn.h:138
Botan::Version_Code
Version_Code
Definition: tls_magic.h:22
Botan::NO_RENEGOTIATION
Definition: tls_magic.h:85
Botan::Record_Reader::set_keys
void set_keys(const CipherSuite &suite, const SessionKeys &keys, Connection_Side side)
Definition: rec_read.cpp:46
Botan::RSA_PrivateKey
Definition: rsa.h:47
Botan::PKCS8::copy_key
Private_Key * copy_key(const Private_Key &key, RandomNumberGenerator &rng)
Definition: pkcs8.cpp:250
Botan::TLS_ALGO_SIGNER_ANON
Definition: tls_magic.h:147
Botan::MemoryRegion::size
size_t size() const
Definition: secmem.h:29
Botan::MemoryRegion< byte >
Botan::TLS_Server::close
void close()
Definition: tls_server.cpp:188
Botan
Definition: algo_base.h:14
Botan::SSL_V3
Definition: tls_magic.h:24
Botan::Finished
Definition: tls_messages.h:185
Botan::Record_Writer::flush
void flush()
Definition: rec_wri.cpp:162
Botan::SecureQueue::write
void write(const byte[], size_t)
Definition: secqueue.cpp:117
Botan::Server_Hello
Definition: tls_messages.h:226
Botan::TLS_ALGO_KEYEXCH_DH
Definition: tls_magic.h:155
Botan::Alert_Type
Alert_Type
Definition: tls_magic.h:62
Botan::HANDSHAKE_CCS
Definition: tls_magic.h:53
Botan::CERTIFICATE
Definition: tls_magic.h:45
Botan::SecureQueue::size
size_t size() const
Definition: secqueue.cpp:190
Botan::CLIENT_KEX
Definition: tls_magic.h:50
Botan::APPLICATION_DATA
Definition: tls_magic.h:37
Botan::TLS_Server::is_closed
bool is_closed() const
Definition: tls_server.cpp:178
Botan::TLS_Server::TLS_Server
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)
Definition: tls_server.cpp:88
Botan::CipherSuite
Definition: tls_suites.h:20
Botan::CONNECTION_CLOSED
Definition: tls_magic.h:32
Botan::Alert
Definition: tls_alerts.h:18
Botan::TLS_V11
Definition: tls_magic.h:26
Botan::TLS_Policy
Definition: tls_policy.h:22
Botan::CLIENT_HELLO
Definition: tls_magic.h:42
Botan::Record_Writer::alert
void alert(Alert_Level, Alert_Type)
Definition: rec_wri.cpp:264
Botan::SecureVector< byte >
Botan::make_u32bit
u32bit make_u32bit(byte i0, byte i1, byte i2, byte i3)
Definition: loadstor.h:60
Botan::TLS_Policy::rsa_export_keysize
virtual size_t rsa_export_keysize() const
Definition: tls_policy.h:40
Botan::DH_PrivateKey
Definition: dh.h:48
Botan::FATAL
Definition: tls_magic.h:59
Botan::CHANGE_CIPHER_SPEC
Definition: tls_magic.h:34
Botan::Server_Key_Exchange
Definition: tls_messages.h:256
Botan::TLS_ALGO_KEYEXCH_RSA
Definition: tls_magic.h:154
Botan::HANDSHAKE_NONE
Definition: tls_magic.h:54
Botan::Handshake_State
Definition: tls_state.h:19
Botan::Unexpected_Message
Definition: tls_exceptn.h:35
Botan::Server_Hello_Done
Definition: tls_messages.h:283
Botan::Handshake_State::queue
SecureQueue queue
Definition: tls_state.h:42
Botan::Record_Writer::reset
void reset()
Definition: rec_wri.cpp:30
Botan::CLIENT
Definition: tls_magic.h:29
Botan::CERTIFICATE_VERIFY
Definition: tls_magic.h:49
Botan::Record_Writer::send
void send(byte type, const byte input[], size_t length)
Definition: rec_wri.cpp:131