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