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