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