Implemented TLS Alert handling
[strongswan.git] / src / libtls / tls_peer.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "tls_peer.h"
17
18 #include <debug.h>
19
20 #include <time.h>
21
22 typedef struct private_tls_peer_t private_tls_peer_t;
23
24 typedef enum {
25 STATE_INIT,
26 STATE_HELLO_SENT,
27 STATE_HELLO_RECEIVED,
28 STATE_HELLO_DONE,
29 STATE_CERT_SENT,
30 STATE_CERT_RECEIVED,
31 STATE_CERTREQ_RECEIVED,
32 STATE_KEY_EXCHANGE_SENT,
33 STATE_VERIFY_SENT,
34 STATE_CIPHERSPEC_CHANGED_OUT,
35 STATE_FINISHED_SENT,
36 STATE_CIPHERSPEC_CHANGED_IN,
37 STATE_COMPLETE,
38 } peer_state_t;
39
40 /**
41 * Private data of an tls_peer_t object.
42 */
43 struct private_tls_peer_t {
44
45 /**
46 * Public tls_peer_t interface.
47 */
48 tls_peer_t public;
49
50 /**
51 * TLS stack
52 */
53 tls_t *tls;
54
55 /**
56 * TLS crypto context
57 */
58 tls_crypto_t *crypto;
59
60 /**
61 * TLS alert handler
62 */
63 tls_alert_t *alert;
64
65 /**
66 * Peer identity
67 */
68 identification_t *peer;
69
70 /**
71 * Server identity
72 */
73 identification_t *server;
74
75 /**
76 * State we are in
77 */
78 peer_state_t state;
79
80 /**
81 * Hello random data selected by client
82 */
83 char client_random[32];
84
85 /**
86 * Hello random data selected by server
87 */
88 char server_random[32];
89
90 /**
91 * Does the server request a peer authentication?
92 */
93 bool peer_auth_requested;
94
95 /**
96 * Auth helper for peer authentication
97 */
98 auth_cfg_t *peer_auth;
99
100 /**
101 * Auth helper for server authentication
102 */
103 auth_cfg_t *server_auth;
104
105 /**
106 * Peer private key
107 */
108 private_key_t *private;
109 };
110
111 /**
112 * Process a server hello message
113 */
114 static status_t process_server_hello(private_tls_peer_t *this,
115 tls_reader_t *reader)
116 {
117 u_int8_t compression;
118 u_int16_t version, cipher;
119 chunk_t random, session, ext = chunk_empty;
120 tls_cipher_suite_t suite;
121
122 this->crypto->append_handshake(this->crypto,
123 TLS_SERVER_HELLO, reader->peek(reader));
124
125 if (!reader->read_uint16(reader, &version) ||
126 !reader->read_data(reader, sizeof(this->server_random), &random) ||
127 !reader->read_data8(reader, &session) ||
128 !reader->read_uint16(reader, &cipher) ||
129 !reader->read_uint8(reader, &compression) ||
130 (reader->remaining(reader) && !reader->read_data16(reader, &ext)))
131 {
132 DBG1(DBG_TLS, "received invalid ServerHello");
133 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
134 return NEED_MORE;
135 }
136
137 memcpy(this->server_random, random.ptr, sizeof(this->server_random));
138
139 if (!this->tls->set_version(this->tls, version))
140 {
141 DBG1(DBG_TLS, "negotiated version %N not supported",
142 tls_version_names, version);
143 this->alert->add(this->alert, TLS_FATAL, TLS_PROTOCOL_VERSION);
144 return NEED_MORE;
145 }
146 suite = cipher;
147 if (!this->crypto->select_cipher_suite(this->crypto, &suite, 1))
148 {
149 DBG1(DBG_TLS, "received TLS cipher suite %N inacceptable",
150 tls_cipher_suite_names, suite);
151 this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
152 return NEED_MORE;
153 }
154 DBG1(DBG_TLS, "negotiated TLS version %N with suite %N",
155 tls_version_names, version, tls_cipher_suite_names, suite);
156 this->state = STATE_HELLO_RECEIVED;
157 return NEED_MORE;
158 }
159
160 /**
161 * Process a Certificate message
162 */
163 static status_t process_certificate(private_tls_peer_t *this,
164 tls_reader_t *reader)
165 {
166 certificate_t *cert;
167 tls_reader_t *certs;
168 chunk_t data;
169 bool first = TRUE;
170
171 this->crypto->append_handshake(this->crypto,
172 TLS_CERTIFICATE, reader->peek(reader));
173
174 if (!reader->read_data24(reader, &data))
175 {
176 DBG1(DBG_TLS, "certificate message header invalid");
177 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
178 return NEED_MORE;
179 }
180 certs = tls_reader_create(data);
181 while (certs->remaining(certs))
182 {
183 if (!certs->read_data24(certs, &data))
184 {
185 DBG1(DBG_TLS, "certificate message invalid");
186 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
187 certs->destroy(certs);
188 return NEED_MORE;
189 }
190 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
191 BUILD_BLOB_ASN1_DER, data, BUILD_END);
192 if (cert)
193 {
194 if (first)
195 {
196 this->server_auth->add(this->server_auth,
197 AUTH_HELPER_SUBJECT_CERT, cert);
198 DBG1(DBG_TLS, "received TLS server certificate '%Y'",
199 cert->get_subject(cert));
200 first = FALSE;
201 }
202 else
203 {
204 DBG1(DBG_TLS, "received TLS intermediate certificate '%Y'",
205 cert->get_subject(cert));
206 this->server_auth->add(this->server_auth,
207 AUTH_HELPER_IM_CERT, cert);
208 }
209 }
210 else
211 {
212 DBG1(DBG_TLS, "parsing TLS certificate failed, skipped");
213 this->alert->add(this->alert, TLS_WARNING, TLS_BAD_CERTIFICATE);
214 }
215 }
216 certs->destroy(certs);
217 this->state = STATE_CERT_RECEIVED;
218 return NEED_MORE;
219 }
220
221 /**
222 * Process a Certificate message
223 */
224 static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
225 {
226 chunk_t types, hashsig, data;
227 tls_reader_t *authorities;
228 identification_t *id;
229 certificate_t *cert;
230
231 this->crypto->append_handshake(this->crypto,
232 TLS_CERTIFICATE_REQUEST, reader->peek(reader));
233
234 if (!reader->read_data8(reader, &types))
235 {
236 DBG1(DBG_TLS, "certreq message header invalid");
237 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
238 return NEED_MORE;
239 }
240 if (this->tls->get_version(this->tls) >= TLS_1_2)
241 {
242 if (!reader->read_data16(reader, &hashsig))
243 {
244 DBG1(DBG_TLS, "certreq message invalid");
245 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
246 return NEED_MORE;
247 }
248 /* TODO: store supported hashsig algorithms */
249 }
250 if (!reader->read_data16(reader, &data))
251 {
252 DBG1(DBG_TLS, "certreq message invalid");
253 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
254 return NEED_MORE;
255 }
256 authorities = tls_reader_create(data);
257 while (authorities->remaining(authorities))
258 {
259 if (!authorities->read_data16(authorities, &data))
260 {
261 DBG1(DBG_TLS, "certreq message invalid");
262 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
263 authorities->destroy(authorities);
264 return NEED_MORE;
265 }
266 id = identification_create_from_encoding(ID_DER_ASN1_DN, data);
267 cert = lib->credmgr->get_cert(lib->credmgr,
268 CERT_X509, KEY_ANY, id, TRUE);
269 if (cert)
270 {
271 DBG1(DBG_TLS, "received TLS cert request for '%Y", id);
272 this->peer_auth->add(this->peer_auth, AUTH_RULE_CA_CERT, cert);
273 }
274 else
275 {
276 DBG1(DBG_TLS, "received TLS cert request for unknown CA '%Y'", id);
277 }
278 id->destroy(id);
279 }
280 authorities->destroy(authorities);
281 this->state = STATE_CERTREQ_RECEIVED;
282 return NEED_MORE;
283 }
284
285 /**
286 * Process Hello Done message
287 */
288 static status_t process_hello_done(private_tls_peer_t *this,
289 tls_reader_t *reader)
290 {
291 this->crypto->append_handshake(this->crypto,
292 TLS_SERVER_HELLO_DONE, reader->peek(reader));
293 this->state = STATE_HELLO_DONE;
294 return NEED_MORE;
295 }
296
297 /**
298 * Process finished message
299 */
300 static status_t process_finished(private_tls_peer_t *this, tls_reader_t *reader)
301 {
302 chunk_t received;
303 char buf[12];
304
305 if (!reader->read_data(reader, sizeof(buf), &received))
306 {
307 DBG1(DBG_TLS, "received server finished too short");
308 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
309 return NEED_MORE;
310 }
311 if (!this->crypto->calculate_finished(this->crypto, "server finished", buf))
312 {
313 DBG1(DBG_TLS, "calculating server finished failed");
314 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
315 return NEED_MORE;
316 }
317 if (!chunk_equals(received, chunk_from_thing(buf)))
318 {
319 DBG1(DBG_TLS, "received server finished invalid");
320 this->alert->add(this->alert, TLS_FATAL, TLS_DECRYPT_ERROR);
321 return NEED_MORE;
322 }
323 this->state = STATE_COMPLETE;
324 this->crypto->derive_eap_msk(this->crypto,
325 chunk_from_thing(this->client_random),
326 chunk_from_thing(this->server_random));
327 return NEED_MORE;
328 }
329
330 METHOD(tls_handshake_t, process, status_t,
331 private_tls_peer_t *this, tls_handshake_type_t type, tls_reader_t *reader)
332 {
333 tls_handshake_type_t expected;
334
335 switch (this->state)
336 {
337 case STATE_HELLO_SENT:
338 if (type == TLS_SERVER_HELLO)
339 {
340 return process_server_hello(this, reader);
341 }
342 expected = TLS_SERVER_HELLO;
343 break;
344 case STATE_HELLO_RECEIVED:
345 if (type == TLS_CERTIFICATE)
346 {
347 return process_certificate(this, reader);
348 }
349 expected = TLS_CERTIFICATE;
350 break;
351 case STATE_CERT_RECEIVED:
352 if (type == TLS_CERTIFICATE_REQUEST)
353 {
354 this->peer_auth_requested = TRUE;
355 return process_certreq(this, reader);
356 }
357 /* fall through since TLS_CERTIFICATE_REQUEST is optional */
358 case STATE_CERTREQ_RECEIVED:
359 if (type == TLS_SERVER_HELLO_DONE)
360 {
361 return process_hello_done(this, reader);
362 }
363 expected = TLS_SERVER_HELLO_DONE;
364 break;
365 case STATE_CIPHERSPEC_CHANGED_IN:
366 if (type == TLS_FINISHED)
367 {
368 return process_finished(this, reader);
369 }
370 expected = TLS_FINISHED;
371 break;
372 default:
373 DBG1(DBG_TLS, "TLS %N not expected in current state",
374 tls_handshake_type_names, type);
375 this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE);
376 return NEED_MORE;
377 }
378 DBG1(DBG_TLS, "TLS %N expected, but received %N",
379 tls_handshake_type_names, expected, tls_handshake_type_names, type);
380 this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE);
381 return NEED_MORE;
382 }
383
384 /**
385 * Send a client hello
386 */
387 static status_t send_client_hello(private_tls_peer_t *this,
388 tls_handshake_type_t *type, tls_writer_t *writer)
389 {
390 tls_cipher_suite_t *suites;
391 tls_version_t version;
392 int count, i;
393 rng_t *rng;
394
395 htoun32(&this->client_random, time(NULL));
396 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
397 if (!rng)
398 {
399 DBG1(DBG_TLS, "no suitable RNG found to generate client random");
400 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
401 return NEED_MORE;
402 }
403 rng->get_bytes(rng, sizeof(this->client_random) - 4, this->client_random + 4);
404 rng->destroy(rng);
405
406 /* TLS version */
407 version = this->tls->get_version(this->tls);
408 writer->write_uint16(writer, version);
409 writer->write_data(writer, chunk_from_thing(this->client_random));
410
411 /* session identifier => none */
412 writer->write_data8(writer, chunk_empty);
413
414 /* add TLS cipher suites */
415 count = this->crypto->get_cipher_suites(this->crypto, &suites);
416 DBG2(DBG_TLS, "sending %d TLS cipher suites:", count);
417 writer->write_uint16(writer, count * 2);
418 for (i = 0; i < count; i++)
419 {
420 DBG2(DBG_TLS, " %N", tls_cipher_suite_names, suites[i]);
421 writer->write_uint16(writer, suites[i]);
422 }
423
424 /* NULL compression only */
425 writer->write_uint8(writer, 1);
426 writer->write_uint8(writer, 0);
427
428 *type = TLS_CLIENT_HELLO;
429 this->state = STATE_HELLO_SENT;
430 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
431 return NEED_MORE;
432 }
433
434 /**
435 * Send Certificate
436 */
437 static status_t send_certificate(private_tls_peer_t *this,
438 tls_handshake_type_t *type, tls_writer_t *writer)
439 {
440 enumerator_t *enumerator;
441 certificate_t *cert;
442 auth_rule_t rule;
443 tls_writer_t *certs;
444 chunk_t data;
445
446 this->private = lib->credmgr->get_private(lib->credmgr,
447 KEY_ANY, this->peer, this->peer_auth);
448 if (!this->private)
449 {
450 DBG1(DBG_TLS, "no TLS peer certificate found for '%Y'", this->peer);
451 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
452 return NEED_MORE;
453 }
454
455 /* generate certificate payload */
456 certs = tls_writer_create(256);
457 cert = this->peer_auth->get(this->peer_auth, AUTH_RULE_SUBJECT_CERT);
458 if (cert)
459 {
460 if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
461 {
462 DBG1(DBG_TLS, "sending TLS peer certificate '%Y'",
463 cert->get_subject(cert));
464 certs->write_data24(certs, data);
465 free(data.ptr);
466 }
467 }
468 enumerator = this->peer_auth->create_enumerator(this->peer_auth);
469 while (enumerator->enumerate(enumerator, &rule, &cert))
470 {
471 if (rule == AUTH_RULE_IM_CERT)
472 {
473 if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
474 {
475 DBG1(DBG_TLS, "sending TLS intermediate certificate '%Y'",
476 cert->get_subject(cert));
477 certs->write_data24(certs, data);
478 free(data.ptr);
479 }
480 }
481 }
482 enumerator->destroy(enumerator);
483
484 writer->write_data24(writer, certs->get_buf(certs));
485 certs->destroy(certs);
486
487 *type = TLS_CERTIFICATE;
488 this->state = STATE_CERT_SENT;
489 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
490 return NEED_MORE;
491 }
492
493 /**
494 * Send client key exchange
495 */
496 static status_t send_key_exchange(private_tls_peer_t *this,
497 tls_handshake_type_t *type, tls_writer_t *writer)
498 {
499 public_key_t *public = NULL, *current;
500 certificate_t *cert;
501 enumerator_t *enumerator;
502 auth_cfg_t *auth;
503 rng_t *rng;
504 char premaster[48];
505 chunk_t encrypted;
506
507 rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
508 if (!rng)
509 {
510 DBG1(DBG_TLS, "no suitable RNG found for TLS premaster secret");
511 return FAILED;
512 }
513 rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2);
514 rng->destroy(rng);
515 htoun16(premaster, TLS_1_2);
516
517 this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
518 chunk_from_thing(this->client_random),
519 chunk_from_thing(this->server_random));
520
521 cert = this->server_auth->get(this->server_auth, AUTH_HELPER_SUBJECT_CERT);
522 if (cert)
523 {
524 enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
525 KEY_ANY, cert->get_subject(cert), this->server_auth);
526 while (enumerator->enumerate(enumerator, &current, &auth))
527 {
528 public = current->get_ref(current);
529 break;
530 }
531 enumerator->destroy(enumerator);
532 }
533 if (!public)
534 {
535 DBG1(DBG_TLS, "no TLS public key found for server '%Y'", this->server);
536 return FAILED;
537 }
538 if (!public->encrypt(public, ENCRYPT_RSA_PKCS1,
539 chunk_from_thing(premaster), &encrypted))
540 {
541 public->destroy(public);
542 DBG1(DBG_TLS, "encrypting TLS premaster secret failed");
543 return FAILED;
544 }
545
546 public->destroy(public);
547
548 writer->write_data16(writer, encrypted);
549 free(encrypted.ptr);
550
551 *type = TLS_CLIENT_KEY_EXCHANGE;
552 this->state = STATE_KEY_EXCHANGE_SENT;
553 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
554 return NEED_MORE;
555 }
556
557 /**
558 * Send certificate verify
559 */
560 static status_t send_certificate_verify(private_tls_peer_t *this,
561 tls_handshake_type_t *type, tls_writer_t *writer)
562 {
563 if (!this->private ||
564 !this->crypto->sign_handshake(this->crypto, this->private, writer))
565 {
566 DBG1(DBG_TLS, "creating TLS Certificate Verify signature failed");
567 return FAILED;
568 }
569
570 *type = TLS_CERTIFICATE_VERIFY;
571 this->state = STATE_VERIFY_SENT;
572 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
573 return NEED_MORE;
574 }
575
576 /**
577 * Send Finished
578 */
579 static status_t send_finished(private_tls_peer_t *this,
580 tls_handshake_type_t *type, tls_writer_t *writer)
581 {
582 char buf[12];
583
584 if (!this->crypto->calculate_finished(this->crypto, "client finished", buf))
585 {
586 DBG1(DBG_TLS, "calculating client finished data failed");
587 return FAILED;
588 }
589
590 writer->write_data(writer, chunk_from_thing(buf));
591
592 *type = TLS_FINISHED;
593 this->state = STATE_FINISHED_SENT;
594 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
595 return NEED_MORE;
596 }
597
598 METHOD(tls_handshake_t, build, status_t,
599 private_tls_peer_t *this, tls_handshake_type_t *type, tls_writer_t *writer)
600 {
601 switch (this->state)
602 {
603 case STATE_INIT:
604 return send_client_hello(this, type, writer);
605 case STATE_HELLO_DONE:
606 if (this->peer_auth_requested)
607 {
608 return send_certificate(this, type, writer);
609 }
610 /* otherwise fall through to next state */
611 case STATE_CERT_SENT:
612 return send_key_exchange(this, type, writer);
613 case STATE_KEY_EXCHANGE_SENT:
614 if (this->peer_auth_requested)
615 {
616 return send_certificate_verify(this, type, writer);
617 }
618 else
619 {
620 return INVALID_STATE;
621 }
622 case STATE_CIPHERSPEC_CHANGED_OUT:
623 return send_finished(this, type, writer);
624 default:
625 return INVALID_STATE;
626 }
627 }
628
629 METHOD(tls_handshake_t, cipherspec_changed, bool,
630 private_tls_peer_t *this)
631 {
632 if ((this->peer_auth_requested && this->state == STATE_VERIFY_SENT) ||
633 (!this->peer_auth_requested && this->state == STATE_KEY_EXCHANGE_SENT))
634 {
635 this->crypto->change_cipher(this->crypto, FALSE);
636 this->state = STATE_CIPHERSPEC_CHANGED_OUT;
637 return TRUE;
638 }
639 return FALSE;
640 }
641
642 METHOD(tls_handshake_t, change_cipherspec, bool,
643 private_tls_peer_t *this)
644 {
645 if (this->state == STATE_FINISHED_SENT)
646 {
647 this->crypto->change_cipher(this->crypto, TRUE);
648 this->state = STATE_CIPHERSPEC_CHANGED_IN;
649 return TRUE;
650 }
651 return FALSE;
652 }
653
654 METHOD(tls_handshake_t, finished, bool,
655 private_tls_peer_t *this)
656 {
657 return this->state == STATE_COMPLETE;
658 }
659
660 METHOD(tls_handshake_t, destroy, void,
661 private_tls_peer_t *this)
662 {
663 DESTROY_IF(this->private);
664 this->peer_auth->destroy(this->peer_auth);
665 this->server_auth->destroy(this->server_auth);
666 free(this);
667 }
668
669 /**
670 * See header
671 */
672 tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto, tls_alert_t *alert,
673 identification_t *peer, identification_t *server)
674 {
675 private_tls_peer_t *this;
676
677 INIT(this,
678 .public = {
679 .handshake = {
680 .process = _process,
681 .build = _build,
682 .cipherspec_changed = _cipherspec_changed,
683 .change_cipherspec = _change_cipherspec,
684 .finished = _finished,
685 .destroy = _destroy,
686 },
687 },
688 .state = STATE_INIT,
689 .tls = tls,
690 .crypto = crypto,
691 .alert = alert,
692 .peer = peer,
693 .server = server,
694 .peer_auth = auth_cfg_create(),
695 .server_auth = auth_cfg_create(),
696 );
697
698 return &this->public;
699 }