Send TLS alerts for errors in TLS handshake building
[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, NULL for no client authentication
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 * Auth helper for peer authentication
92 */
93 auth_cfg_t *peer_auth;
94
95 /**
96 * Auth helper for server authentication
97 */
98 auth_cfg_t *server_auth;
99
100 /**
101 * Peer private key
102 */
103 private_key_t *private;
104 };
105
106 /**
107 * Process a server hello message
108 */
109 static status_t process_server_hello(private_tls_peer_t *this,
110 tls_reader_t *reader)
111 {
112 u_int8_t compression;
113 u_int16_t version, cipher;
114 chunk_t random, session, ext = chunk_empty;
115 tls_cipher_suite_t suite;
116
117 this->crypto->append_handshake(this->crypto,
118 TLS_SERVER_HELLO, reader->peek(reader));
119
120 if (!reader->read_uint16(reader, &version) ||
121 !reader->read_data(reader, sizeof(this->server_random), &random) ||
122 !reader->read_data8(reader, &session) ||
123 !reader->read_uint16(reader, &cipher) ||
124 !reader->read_uint8(reader, &compression) ||
125 (reader->remaining(reader) && !reader->read_data16(reader, &ext)))
126 {
127 DBG1(DBG_TLS, "received invalid ServerHello");
128 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
129 return NEED_MORE;
130 }
131
132 memcpy(this->server_random, random.ptr, sizeof(this->server_random));
133
134 if (!this->tls->set_version(this->tls, version))
135 {
136 DBG1(DBG_TLS, "negotiated version %N not supported",
137 tls_version_names, version);
138 this->alert->add(this->alert, TLS_FATAL, TLS_PROTOCOL_VERSION);
139 return NEED_MORE;
140 }
141 suite = cipher;
142 if (!this->crypto->select_cipher_suite(this->crypto, &suite, 1))
143 {
144 DBG1(DBG_TLS, "received TLS cipher suite %N inacceptable",
145 tls_cipher_suite_names, suite);
146 this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
147 return NEED_MORE;
148 }
149 DBG1(DBG_TLS, "negotiated TLS version %N with suite %N",
150 tls_version_names, version, tls_cipher_suite_names, suite);
151 this->state = STATE_HELLO_RECEIVED;
152 return NEED_MORE;
153 }
154
155 /**
156 * Process a Certificate message
157 */
158 static status_t process_certificate(private_tls_peer_t *this,
159 tls_reader_t *reader)
160 {
161 certificate_t *cert;
162 tls_reader_t *certs;
163 chunk_t data;
164 bool first = TRUE;
165
166 this->crypto->append_handshake(this->crypto,
167 TLS_CERTIFICATE, reader->peek(reader));
168
169 if (!reader->read_data24(reader, &data))
170 {
171 DBG1(DBG_TLS, "certificate message header invalid");
172 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
173 return NEED_MORE;
174 }
175 certs = tls_reader_create(data);
176 while (certs->remaining(certs))
177 {
178 if (!certs->read_data24(certs, &data))
179 {
180 DBG1(DBG_TLS, "certificate message invalid");
181 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
182 certs->destroy(certs);
183 return NEED_MORE;
184 }
185 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
186 BUILD_BLOB_ASN1_DER, data, BUILD_END);
187 if (cert)
188 {
189 if (first)
190 {
191 this->server_auth->add(this->server_auth,
192 AUTH_HELPER_SUBJECT_CERT, cert);
193 DBG1(DBG_TLS, "received TLS server certificate '%Y'",
194 cert->get_subject(cert));
195 first = FALSE;
196 }
197 else
198 {
199 DBG1(DBG_TLS, "received TLS intermediate certificate '%Y'",
200 cert->get_subject(cert));
201 this->server_auth->add(this->server_auth,
202 AUTH_HELPER_IM_CERT, cert);
203 }
204 }
205 else
206 {
207 DBG1(DBG_TLS, "parsing TLS certificate failed, skipped");
208 this->alert->add(this->alert, TLS_WARNING, TLS_BAD_CERTIFICATE);
209 }
210 }
211 certs->destroy(certs);
212 this->state = STATE_CERT_RECEIVED;
213 return NEED_MORE;
214 }
215
216 /**
217 * Process a Certificate Request message
218 */
219 static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
220 {
221 chunk_t types, hashsig, data;
222 tls_reader_t *authorities;
223 identification_t *id;
224 certificate_t *cert;
225
226 if (!this->peer)
227 {
228 DBG1(DBG_TLS, "server requested a certificate, but client "
229 "authentication disabled");
230 this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
231 return NEED_MORE;
232 }
233 this->crypto->append_handshake(this->crypto,
234 TLS_CERTIFICATE_REQUEST, reader->peek(reader));
235
236 if (!reader->read_data8(reader, &types))
237 {
238 DBG1(DBG_TLS, "certreq message header invalid");
239 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
240 return NEED_MORE;
241 }
242 if (this->tls->get_version(this->tls) >= TLS_1_2)
243 {
244 if (!reader->read_data16(reader, &hashsig))
245 {
246 DBG1(DBG_TLS, "certreq message invalid");
247 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
248 return NEED_MORE;
249 }
250 /* TODO: store supported hashsig algorithms */
251 }
252 if (!reader->read_data16(reader, &data))
253 {
254 DBG1(DBG_TLS, "certreq message invalid");
255 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
256 return NEED_MORE;
257 }
258 authorities = tls_reader_create(data);
259 while (authorities->remaining(authorities))
260 {
261 if (!authorities->read_data16(authorities, &data))
262 {
263 DBG1(DBG_TLS, "certreq message invalid");
264 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
265 authorities->destroy(authorities);
266 return NEED_MORE;
267 }
268 id = identification_create_from_encoding(ID_DER_ASN1_DN, data);
269 cert = lib->credmgr->get_cert(lib->credmgr,
270 CERT_X509, KEY_ANY, id, TRUE);
271 if (cert)
272 {
273 DBG1(DBG_TLS, "received TLS cert request for '%Y", id);
274 this->peer_auth->add(this->peer_auth, AUTH_RULE_CA_CERT, cert);
275 }
276 else
277 {
278 DBG1(DBG_TLS, "received TLS cert request for unknown CA '%Y'", id);
279 }
280 id->destroy(id);
281 }
282 authorities->destroy(authorities);
283 this->state = STATE_CERTREQ_RECEIVED;
284 return NEED_MORE;
285 }
286
287 /**
288 * Process Hello Done message
289 */
290 static status_t process_hello_done(private_tls_peer_t *this,
291 tls_reader_t *reader)
292 {
293 this->crypto->append_handshake(this->crypto,
294 TLS_SERVER_HELLO_DONE, reader->peek(reader));
295 this->state = STATE_HELLO_DONE;
296 return NEED_MORE;
297 }
298
299 /**
300 * Process finished message
301 */
302 static status_t process_finished(private_tls_peer_t *this, tls_reader_t *reader)
303 {
304 chunk_t received;
305 char buf[12];
306
307 if (!reader->read_data(reader, sizeof(buf), &received))
308 {
309 DBG1(DBG_TLS, "received server finished too short");
310 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
311 return NEED_MORE;
312 }
313 if (!this->crypto->calculate_finished(this->crypto, "server finished", buf))
314 {
315 DBG1(DBG_TLS, "calculating server finished failed");
316 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
317 return NEED_MORE;
318 }
319 if (!chunk_equals(received, chunk_from_thing(buf)))
320 {
321 DBG1(DBG_TLS, "received server finished invalid");
322 this->alert->add(this->alert, TLS_FATAL, TLS_DECRYPT_ERROR);
323 return NEED_MORE;
324 }
325 this->state = STATE_COMPLETE;
326 this->crypto->derive_eap_msk(this->crypto,
327 chunk_from_thing(this->client_random),
328 chunk_from_thing(this->server_random));
329 return NEED_MORE;
330 }
331
332 METHOD(tls_handshake_t, process, status_t,
333 private_tls_peer_t *this, tls_handshake_type_t type, tls_reader_t *reader)
334 {
335 tls_handshake_type_t expected;
336
337 switch (this->state)
338 {
339 case STATE_HELLO_SENT:
340 if (type == TLS_SERVER_HELLO)
341 {
342 return process_server_hello(this, reader);
343 }
344 expected = TLS_SERVER_HELLO;
345 break;
346 case STATE_HELLO_RECEIVED:
347 if (type == TLS_CERTIFICATE)
348 {
349 return process_certificate(this, reader);
350 }
351 expected = TLS_CERTIFICATE;
352 break;
353 case STATE_CERT_RECEIVED:
354 if (type == TLS_CERTIFICATE_REQUEST)
355 {
356 return process_certreq(this, reader);
357 }
358 this->peer = NULL;
359 /* fall through since TLS_CERTIFICATE_REQUEST is optional */
360 case STATE_CERTREQ_RECEIVED:
361 if (type == TLS_SERVER_HELLO_DONE)
362 {
363 return process_hello_done(this, reader);
364 }
365 expected = TLS_SERVER_HELLO_DONE;
366 break;
367 case STATE_CIPHERSPEC_CHANGED_IN:
368 if (type == TLS_FINISHED)
369 {
370 return process_finished(this, reader);
371 }
372 expected = TLS_FINISHED;
373 break;
374 default:
375 DBG1(DBG_TLS, "TLS %N not expected in current state",
376 tls_handshake_type_names, type);
377 this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE);
378 return NEED_MORE;
379 }
380 DBG1(DBG_TLS, "TLS %N expected, but received %N",
381 tls_handshake_type_names, expected, tls_handshake_type_names, type);
382 this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE);
383 return NEED_MORE;
384 }
385
386 /**
387 * Send a client hello
388 */
389 static status_t send_client_hello(private_tls_peer_t *this,
390 tls_handshake_type_t *type, tls_writer_t *writer)
391 {
392 tls_cipher_suite_t *suites;
393 tls_version_t version;
394 int count, i;
395 rng_t *rng;
396
397 htoun32(&this->client_random, time(NULL));
398 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
399 if (!rng)
400 {
401 DBG1(DBG_TLS, "no suitable RNG found to generate client random");
402 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
403 return NEED_MORE;
404 }
405 rng->get_bytes(rng, sizeof(this->client_random) - 4, this->client_random + 4);
406 rng->destroy(rng);
407
408 /* TLS version */
409 version = this->tls->get_version(this->tls);
410 writer->write_uint16(writer, version);
411 writer->write_data(writer, chunk_from_thing(this->client_random));
412
413 /* session identifier => none */
414 writer->write_data8(writer, chunk_empty);
415
416 /* add TLS cipher suites */
417 count = this->crypto->get_cipher_suites(this->crypto, &suites);
418 writer->write_uint16(writer, count * 2);
419 for (i = 0; i < count; i++)
420 {
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 if (this->peer)
447 {
448 this->private = lib->credmgr->get_private(lib->credmgr,
449 KEY_ANY, this->peer, this->peer_auth);
450 }
451 if (!this->private)
452 {
453 DBG1(DBG_TLS, "no TLS peer certificate found for '%Y'", this->peer);
454 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
455 return FAILED;
456 }
457
458 /* generate certificate payload */
459 certs = tls_writer_create(256);
460 cert = this->peer_auth->get(this->peer_auth, AUTH_RULE_SUBJECT_CERT);
461 if (cert)
462 {
463 if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
464 {
465 DBG1(DBG_TLS, "sending TLS peer certificate '%Y'",
466 cert->get_subject(cert));
467 certs->write_data24(certs, data);
468 free(data.ptr);
469 }
470 }
471 enumerator = this->peer_auth->create_enumerator(this->peer_auth);
472 while (enumerator->enumerate(enumerator, &rule, &cert))
473 {
474 if (rule == AUTH_RULE_IM_CERT)
475 {
476 if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
477 {
478 DBG1(DBG_TLS, "sending TLS intermediate certificate '%Y'",
479 cert->get_subject(cert));
480 certs->write_data24(certs, data);
481 free(data.ptr);
482 }
483 }
484 }
485 enumerator->destroy(enumerator);
486
487 writer->write_data24(writer, certs->get_buf(certs));
488 certs->destroy(certs);
489
490 *type = TLS_CERTIFICATE;
491 this->state = STATE_CERT_SENT;
492 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
493 return NEED_MORE;
494 }
495
496 /**
497 * Send client key exchange
498 */
499 static status_t send_key_exchange(private_tls_peer_t *this,
500 tls_handshake_type_t *type, tls_writer_t *writer)
501 {
502 public_key_t *public = NULL, *current;
503 certificate_t *cert;
504 enumerator_t *enumerator;
505 auth_cfg_t *auth;
506 rng_t *rng;
507 char premaster[48];
508 chunk_t encrypted;
509
510 rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
511 if (!rng)
512 {
513 DBG1(DBG_TLS, "no suitable RNG found for TLS premaster secret");
514 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
515 return FAILED;
516 }
517 rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2);
518 rng->destroy(rng);
519 htoun16(premaster, TLS_1_2);
520
521 this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
522 chunk_from_thing(this->client_random),
523 chunk_from_thing(this->server_random));
524
525 cert = this->server_auth->get(this->server_auth, AUTH_HELPER_SUBJECT_CERT);
526 if (cert)
527 {
528 enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
529 KEY_ANY, cert->get_subject(cert), this->server_auth);
530 while (enumerator->enumerate(enumerator, &current, &auth))
531 {
532 public = current->get_ref(current);
533 break;
534 }
535 enumerator->destroy(enumerator);
536 }
537 if (!public)
538 {
539 DBG1(DBG_TLS, "no TLS public key found for server '%Y'", this->server);
540 this->alert->add(this->alert, TLS_FATAL, TLS_CERTIFICATE_UNKNOWN);
541 return FAILED;
542 }
543 if (!public->encrypt(public, ENCRYPT_RSA_PKCS1,
544 chunk_from_thing(premaster), &encrypted))
545 {
546 public->destroy(public);
547 DBG1(DBG_TLS, "encrypting TLS premaster secret failed");
548 this->alert->add(this->alert, TLS_FATAL, TLS_BAD_CERTIFICATE);
549 return FAILED;
550 }
551
552 public->destroy(public);
553
554 writer->write_data16(writer, encrypted);
555 free(encrypted.ptr);
556
557 *type = TLS_CLIENT_KEY_EXCHANGE;
558 this->state = STATE_KEY_EXCHANGE_SENT;
559 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
560 return NEED_MORE;
561 }
562
563 /**
564 * Send certificate verify
565 */
566 static status_t send_certificate_verify(private_tls_peer_t *this,
567 tls_handshake_type_t *type, tls_writer_t *writer)
568 {
569 if (!this->private ||
570 !this->crypto->sign_handshake(this->crypto, this->private, writer))
571 {
572 DBG1(DBG_TLS, "creating TLS Certificate Verify signature failed");
573 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
574 return FAILED;
575 }
576
577 *type = TLS_CERTIFICATE_VERIFY;
578 this->state = STATE_VERIFY_SENT;
579 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
580 return NEED_MORE;
581 }
582
583 /**
584 * Send Finished
585 */
586 static status_t send_finished(private_tls_peer_t *this,
587 tls_handshake_type_t *type, tls_writer_t *writer)
588 {
589 char buf[12];
590
591 if (!this->crypto->calculate_finished(this->crypto, "client finished", buf))
592 {
593 DBG1(DBG_TLS, "calculating client finished data failed");
594 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
595 return FAILED;
596 }
597
598 writer->write_data(writer, chunk_from_thing(buf));
599
600 *type = TLS_FINISHED;
601 this->state = STATE_FINISHED_SENT;
602 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
603 return NEED_MORE;
604 }
605
606 METHOD(tls_handshake_t, build, status_t,
607 private_tls_peer_t *this, tls_handshake_type_t *type, tls_writer_t *writer)
608 {
609 switch (this->state)
610 {
611 case STATE_INIT:
612 return send_client_hello(this, type, writer);
613 case STATE_HELLO_DONE:
614 if (this->peer)
615 {
616 return send_certificate(this, type, writer);
617 }
618 /* otherwise fall through to next state */
619 case STATE_CERT_SENT:
620 return send_key_exchange(this, type, writer);
621 case STATE_KEY_EXCHANGE_SENT:
622 if (this->peer)
623 {
624 return send_certificate_verify(this, type, writer);
625 }
626 else
627 {
628 return INVALID_STATE;
629 }
630 case STATE_CIPHERSPEC_CHANGED_OUT:
631 return send_finished(this, type, writer);
632 default:
633 return INVALID_STATE;
634 }
635 }
636
637 METHOD(tls_handshake_t, cipherspec_changed, bool,
638 private_tls_peer_t *this)
639 {
640 if ((this->peer && this->state == STATE_VERIFY_SENT) ||
641 (!this->peer && this->state == STATE_KEY_EXCHANGE_SENT))
642 {
643 this->crypto->change_cipher(this->crypto, FALSE);
644 this->state = STATE_CIPHERSPEC_CHANGED_OUT;
645 return TRUE;
646 }
647 return FALSE;
648 }
649
650 METHOD(tls_handshake_t, change_cipherspec, bool,
651 private_tls_peer_t *this)
652 {
653 if (this->state == STATE_FINISHED_SENT)
654 {
655 this->crypto->change_cipher(this->crypto, TRUE);
656 this->state = STATE_CIPHERSPEC_CHANGED_IN;
657 return TRUE;
658 }
659 return FALSE;
660 }
661
662 METHOD(tls_handshake_t, finished, bool,
663 private_tls_peer_t *this)
664 {
665 return this->state == STATE_COMPLETE;
666 }
667
668 METHOD(tls_handshake_t, destroy, void,
669 private_tls_peer_t *this)
670 {
671 DESTROY_IF(this->private);
672 this->peer_auth->destroy(this->peer_auth);
673 this->server_auth->destroy(this->server_auth);
674 free(this);
675 }
676
677 /**
678 * See header
679 */
680 tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto, tls_alert_t *alert,
681 identification_t *peer, identification_t *server)
682 {
683 private_tls_peer_t *this;
684
685 INIT(this,
686 .public = {
687 .handshake = {
688 .process = _process,
689 .build = _build,
690 .cipherspec_changed = _cipherspec_changed,
691 .change_cipherspec = _change_cipherspec,
692 .finished = _finished,
693 .destroy = _destroy,
694 },
695 },
696 .state = STATE_INIT,
697 .tls = tls,
698 .crypto = crypto,
699 .alert = alert,
700 .peer = peer,
701 .server = server,
702 .peer_auth = auth_cfg_create(),
703 .server_auth = auth_cfg_create(),
704 );
705
706 return &this->public;
707 }