Implemented key derivation, output record signing and encryption
[strongswan.git] / src / charon / plugins / eap_tls / tls / 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 <daemon.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_DONE,
28 STATE_CERT_SENT,
29 STATE_KEY_EXCHANGE_SENT,
30 STATE_VERIFY_SENT,
31 STATE_CIPHERSPEC_CHANGED,
32 STATE_FINISHED_SENT,
33 } peer_state_t;
34
35 /**
36 * Private data of an tls_peer_t object.
37 */
38 struct private_tls_peer_t {
39
40 /**
41 * Public tls_peer_t interface.
42 */
43 tls_peer_t public;
44
45 /**
46 * TLS stack
47 */
48 tls_t *tls;
49
50 /**
51 * TLS crypto context
52 */
53 tls_crypto_t *crypto;
54
55 /**
56 * Peer identity
57 */
58 identification_t *peer;
59
60 /**
61 * Server identity
62 */
63 identification_t *server;
64
65 /**
66 * State we are in
67 */
68 peer_state_t state;
69
70 /**
71 * All handshake data concatentated
72 */
73 chunk_t handshake;
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 * Append a handshake message to the handshake data buffer
103 */
104 static void append_handshake(private_tls_peer_t *this,
105 tls_handshake_type_t type, chunk_t data)
106 {
107 u_int32_t header;
108
109 /* reconstruct handshake header */
110 header = htonl(data.len | (type << 24));
111 this->handshake = chunk_cat("mcc", this->handshake,
112 chunk_from_thing(header), data);
113 }
114
115 /**
116 * Process a server hello message
117 */
118 static status_t process_server_hello(private_tls_peer_t *this,
119 tls_reader_t *reader)
120 {
121 u_int8_t compression;
122 u_int16_t version, cipher;
123 chunk_t random, session, ext = chunk_empty;
124 tls_cipher_suite_t suite;
125
126 append_handshake(this, TLS_SERVER_HELLO, reader->peek(reader));
127
128 if (!reader->read_uint16(reader, &version) ||
129 !reader->read_data(reader, sizeof(this->server_random), &random) ||
130 !reader->read_data8(reader, &session) ||
131 !reader->read_uint16(reader, &cipher) ||
132 !reader->read_uint8(reader, &compression) ||
133 (reader->remaining(reader) && !reader->read_data16(reader, &ext)))
134 {
135 DBG1(DBG_IKE, "received invalid ServerHello");
136 return FAILED;
137 }
138
139 memcpy(this->server_random, random.ptr, sizeof(this->server_random));
140
141 if (version < this->tls->get_version(this->tls))
142 {
143 this->tls->set_version(this->tls, version);
144 }
145 suite = cipher;
146 if (!this->crypto->select_cipher_suite(this->crypto, &suite, 1))
147 {
148 DBG1(DBG_IKE, "received cipher suite inacceptable");
149 return FAILED;
150 }
151 return NEED_MORE;
152 }
153
154 /**
155 * Process a Certificate message
156 */
157 static status_t process_certificate(private_tls_peer_t *this,
158 tls_reader_t *reader)
159 {
160 certificate_t *cert;
161 tls_reader_t *certs;
162 chunk_t data;
163 bool first = TRUE;
164
165 append_handshake(this, TLS_CERTIFICATE, reader->peek(reader));
166
167 if (!reader->read_data24(reader, &data))
168 {
169 return FAILED;
170 }
171 certs = tls_reader_create(data);
172 while (certs->remaining(certs))
173 {
174 if (!certs->read_data24(certs, &data))
175 {
176 certs->destroy(certs);
177 return FAILED;
178 }
179 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
180 BUILD_BLOB_ASN1_DER, data, BUILD_END);
181 if (cert)
182 {
183 if (first)
184 {
185 this->server_auth->add(this->server_auth,
186 AUTH_RULE_SUBJECT_CERT, cert);
187 DBG1(DBG_IKE, "received TLS server certificate '%Y'",
188 cert->get_subject(cert));
189 first = FALSE;
190 }
191 else
192 {
193 DBG1(DBG_IKE, "received TLS intermediate certificate '%Y'",
194 cert->get_subject(cert));
195 this->server_auth->add(this->server_auth,
196 AUTH_RULE_IM_CERT, cert);
197 }
198 }
199 else
200 {
201 DBG1(DBG_IKE, "parsing TLS certificate failed, skipped");
202 }
203 }
204 certs->destroy(certs);
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 append_handshake(this, TLS_CERTIFICATE_REQUEST, reader->peek(reader));
219
220 if (!reader->read_data8(reader, &types))
221 {
222 return FAILED;
223 }
224 if (this->tls->get_version(this->tls) >= TLS_1_2)
225 {
226 if (!reader->read_data16(reader, &hashsig))
227 {
228 return FAILED;
229 }
230 /* TODO: store supported hashsig algorithms */
231 }
232 if (!reader->read_data16(reader, &data))
233 {
234 return FAILED;
235 }
236 authorities = tls_reader_create(data);
237 while (authorities->remaining(authorities))
238 {
239 if (!authorities->read_data16(authorities, &data))
240 {
241 authorities->destroy(authorities);
242 return FAILED;
243 }
244 id = identification_create_from_encoding(ID_DER_ASN1_DN, data);
245 cert = charon->credentials->get_cert(charon->credentials,
246 CERT_X509, KEY_ANY, id, TRUE);
247 if (cert)
248 {
249 DBG1(DBG_IKE, "received cert request for '%Y", id);
250 this->peer_auth->add(this->peer_auth, AUTH_RULE_CA_CERT, cert);
251 }
252 else
253 {
254 DBG1(DBG_IKE, "received cert request for unknown CA '%Y'", id);
255 }
256 id->destroy(id);
257 }
258 authorities->destroy(authorities);
259 return NEED_MORE;
260 }
261
262 /**
263 * Process Hello Done message
264 */
265 static status_t process_hello_done(private_tls_peer_t *this,
266 tls_reader_t *reader)
267 {
268 append_handshake(this, TLS_SERVER_HELLO_DONE, reader->peek(reader));
269 this->state = STATE_HELLO_DONE;
270 return NEED_MORE;
271 }
272
273 METHOD(tls_handshake_t, process, status_t,
274 private_tls_peer_t *this, tls_handshake_type_t type, tls_reader_t *reader)
275 {
276 switch (this->state)
277 {
278 case STATE_HELLO_SENT:
279 switch (type)
280 {
281 case TLS_SERVER_HELLO:
282 return process_server_hello(this, reader);
283 case TLS_CERTIFICATE:
284 return process_certificate(this, reader);
285 case TLS_CERTIFICATE_REQUEST:
286 return process_certreq(this, reader);
287 case TLS_SERVER_HELLO_DONE:
288 return process_hello_done(this, reader);
289 default:
290 break;
291 }
292 break;
293 default:
294 break;
295 }
296 DBG1(DBG_IKE, "received TLS handshake message %N, ignored",
297 tls_handshake_type_names, type);
298 return NEED_MORE;
299 }
300
301 /**
302 * Send a client hello
303 */
304 static status_t send_hello(private_tls_peer_t *this,
305 tls_handshake_type_t *type, tls_writer_t *writer)
306 {
307 tls_cipher_suite_t *suite;
308 int count, i;
309 rng_t *rng;
310
311 htoun32(&this->client_random, time(NULL));
312 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
313 if (!rng)
314 {
315 return FAILED;
316 }
317 rng->get_bytes(rng, sizeof(this->client_random) - 4, this->client_random + 4);
318 rng->destroy(rng);
319
320 writer->write_uint16(writer, this->tls->get_version(this->tls));
321 writer->write_data(writer, chunk_from_thing(this->client_random));
322 /* session identifier => none */
323 writer->write_data8(writer, chunk_empty);
324
325 count = this->crypto->get_cipher_suites(this->crypto, &suite);
326 writer->write_uint16(writer, count * 2);
327 for (i = 0; i < count; i++)
328 {
329 writer->write_uint16(writer, suite[i]);
330 }
331 /* NULL compression only */
332 writer->write_uint8(writer, 1);
333 writer->write_uint8(writer, 0);
334
335 *type = TLS_CLIENT_HELLO;
336 this->state = STATE_HELLO_SENT;
337 append_handshake(this, *type, writer->get_buf(writer));
338 return NEED_MORE;
339 }
340
341 /**
342 * Send Certificate
343 */
344 static status_t send_certificate(private_tls_peer_t *this,
345 tls_handshake_type_t *type, tls_writer_t *writer)
346 {
347 enumerator_t *enumerator;
348 certificate_t *cert;
349 auth_rule_t rule;
350 tls_writer_t *certs;
351 chunk_t data;
352
353 this->private = charon->credentials->get_private(charon->credentials,
354 KEY_ANY, this->peer, this->peer_auth);
355 if (!this->private)
356 {
357 DBG1(DBG_IKE, "no TLS peer certificate found for '%Y'", this->peer);
358 return FAILED;
359 }
360
361 /* generate certificate payload */
362 certs = tls_writer_create(256);
363 cert = this->peer_auth->get(this->peer_auth, AUTH_RULE_SUBJECT_CERT);
364 if (cert)
365 {
366 DBG1(DBG_IKE, "sending TLS peer certificate '%Y'",
367 cert->get_subject(cert));
368 data = cert->get_encoding(cert);
369 certs->write_data24(certs, data);
370 free(data.ptr);
371 }
372 enumerator = this->peer_auth->create_enumerator(this->peer_auth);
373 while (enumerator->enumerate(enumerator, &rule, &cert))
374 {
375 if (rule == AUTH_RULE_IM_CERT)
376 {
377 DBG1(DBG_IKE, "sending TLS intermediate certificate '%Y'",
378 cert->get_subject(cert));
379 data = cert->get_encoding(cert);
380 certs->write_data24(certs, data);
381 free(data.ptr);
382 }
383 }
384 enumerator->destroy(enumerator);
385
386 writer->write_data24(writer, certs->get_buf(certs));
387 certs->destroy(certs);
388
389 *type = TLS_CERTIFICATE;
390 this->state = STATE_CERT_SENT;
391 append_handshake(this, *type, writer->get_buf(writer));
392 return NEED_MORE;
393 }
394
395 /**
396 * Send client key exchange
397 */
398 static status_t send_key_exchange(private_tls_peer_t *this,
399 tls_handshake_type_t *type, tls_writer_t *writer)
400 {
401 public_key_t *public = NULL, *current;
402 enumerator_t *enumerator;
403 auth_cfg_t *auth;
404 rng_t *rng;
405 char premaster[48];
406 chunk_t encrypted;
407
408 rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
409 if (!rng)
410 {
411 DBG1(DBG_IKE, "no suitable RNG found for TLS premaster secret");
412 return FAILED;
413 }
414 rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2);
415 rng->destroy(rng);
416 htoun16(premaster, TLS_1_2);
417
418 this->crypto->derive_master_secret(this->crypto, chunk_from_thing(premaster),
419 chunk_from_thing(this->client_random),
420 chunk_from_thing(this->server_random));
421
422 enumerator = charon->credentials->create_public_enumerator(
423 charon->credentials, KEY_ANY, this->server, this->server_auth);
424 while (enumerator->enumerate(enumerator, &current, &auth))
425 {
426 public = current->get_ref(current);
427 break;
428 }
429 enumerator->destroy(enumerator);
430
431 if (!public)
432 {
433 DBG1(DBG_IKE, "no TLS public key found for server '%Y'", this->server);
434 return FAILED;
435 }
436 if (!public->encrypt(public, chunk_from_thing(premaster), &encrypted))
437 {
438 public->destroy(public);
439 DBG1(DBG_IKE, "encrypting TLS premaster secret failed");
440 return FAILED;
441 }
442 public->destroy(public);
443
444 writer->write_data16(writer, encrypted);
445 free(encrypted.ptr);
446
447 *type = TLS_CLIENT_KEY_EXCHANGE;
448 this->state = STATE_KEY_EXCHANGE_SENT;
449 append_handshake(this, *type, writer->get_buf(writer));
450 return NEED_MORE;
451 }
452
453 /**
454 * Send certificate verify
455 */
456 static status_t send_certificate_verify(private_tls_peer_t *this,
457 tls_handshake_type_t *type, tls_writer_t *writer)
458 {
459 chunk_t signature;
460
461 if (!this->private)
462 {
463 return FAILED;
464 }
465
466 if (this->tls->get_version(this->tls) >= TLS_1_2)
467 {
468 if (!this->private->sign(this->private, SIGN_RSA_EMSA_PKCS1_SHA1,
469 this->handshake, &signature))
470 {
471 DBG1(DBG_IKE, "creating TLS Certificate Verify signature failed");
472 return FAILED;
473 }
474 /* TODO: signature scheme to hashsign algorithm mapping */
475 writer->write_uint8(writer, 2); /* sha1 */
476 writer->write_uint8(writer, 1); /* RSA */
477 }
478 else
479 {
480 hasher_t *md5, *sha1;
481 char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1];
482
483 md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
484 if (!md5)
485 {
486 DBG1(DBG_IKE, "unable to sign %N Verify, MD5 not supported",
487 tls_version_names, this->tls->get_version(this->tls));
488 return FAILED;
489 }
490 md5->get_hash(md5, this->handshake, buf);
491 md5->destroy(md5);
492 sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
493 if (!sha1)
494 {
495 DBG1(DBG_IKE, "unable to sign %N Verify, SHA1 not supported",
496 tls_version_names, this->tls->get_version(this->tls));
497 return FAILED;
498 }
499 sha1->get_hash(sha1, this->handshake, buf + HASH_SIZE_MD5);
500 sha1->destroy(sha1);
501
502 if (!this->private->sign(this->private, SIGN_RSA_EMSA_PKCS1_NULL,
503 chunk_from_thing(buf), &signature))
504 {
505 DBG1(DBG_IKE, "creating TLS Certificate Verify signature failed");
506 return FAILED;
507 }
508 }
509 writer->write_data16(writer, signature);
510 free(signature.ptr);
511
512 *type = TLS_CERTIFICATE_VERIFY;
513 this->state = STATE_VERIFY_SENT;
514 append_handshake(this, *type, writer->get_buf(writer));
515 return NEED_MORE;
516 }
517
518 /**
519 * Send Finished
520 */
521 static status_t send_finished(private_tls_peer_t *this,
522 tls_handshake_type_t *type, tls_writer_t *writer)
523 {
524 chunk_t seed;
525 tls_prf_t *prf;
526 char data[12];
527
528 if (this->tls->get_version(this->tls) >= TLS_1_2)
529 {
530 /* TODO: use hash of cipher suite only */
531 seed = chunk_empty;
532 }
533 else
534 {
535 hasher_t *md5, *sha1;
536 char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1];
537
538 md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
539 if (!md5)
540 {
541 DBG1(DBG_IKE, "unable to create %N Finished, MD5 not supported",
542 tls_version_names, this->tls->get_version(this->tls));
543 return FAILED;
544 }
545 md5->get_hash(md5, this->handshake, buf);
546 md5->destroy(md5);
547 sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
548 if (!sha1)
549 {
550 DBG1(DBG_IKE, "unable to sign %N Finished, SHA1 not supported",
551 tls_version_names, this->tls->get_version(this->tls));
552 return FAILED;
553 }
554 sha1->get_hash(sha1, this->handshake, buf + HASH_SIZE_MD5);
555 sha1->destroy(sha1);
556
557 seed = chunk_clonea(chunk_from_thing(buf));
558 }
559
560 prf = this->crypto->get_prf(this->crypto);
561 if (!prf)
562 {
563 return FAILED;
564 }
565 prf->get_bytes(prf, "client finished", seed, sizeof(data), data);
566
567 writer->write_data(writer, chunk_from_thing(data));
568
569 *type = TLS_FINISHED;
570 this->state = STATE_FINISHED_SENT;
571 return NEED_MORE;
572 }
573
574 METHOD(tls_handshake_t, build, status_t,
575 private_tls_peer_t *this, tls_handshake_type_t *type, tls_writer_t *writer)
576 {
577 switch (this->state)
578 {
579 case STATE_INIT:
580 return send_hello(this, type, writer);
581 case STATE_HELLO_DONE:
582 return send_certificate(this, type, writer);
583 case STATE_CERT_SENT:
584 return send_key_exchange(this, type, writer);
585 case STATE_KEY_EXCHANGE_SENT:
586 return send_certificate_verify(this, type, writer);
587 case STATE_CIPHERSPEC_CHANGED:
588 return send_finished(this, type, writer);
589 default:
590 return INVALID_STATE;
591 }
592 }
593
594 METHOD(tls_handshake_t, cipherspec_changed, bool,
595 private_tls_peer_t *this)
596 {
597 if (this->state == STATE_VERIFY_SENT)
598 {
599 this->crypto->change_cipher(this->crypto, FALSE);
600 this->state = STATE_CIPHERSPEC_CHANGED;
601 return TRUE;
602 }
603 return FALSE;
604 }
605
606 METHOD(tls_handshake_t, change_cipherspec, void,
607 private_tls_peer_t *this)
608 {
609
610 }
611
612 METHOD(tls_handshake_t, destroy, void,
613 private_tls_peer_t *this)
614 {
615 DESTROY_IF(this->private);
616 free(this->handshake.ptr);
617 this->peer_auth->destroy(this->peer_auth);
618 this->server_auth->destroy(this->server_auth);
619 free(this);
620 }
621
622 /**
623 * See header
624 */
625 tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto,
626 identification_t *peer, identification_t *server)
627 {
628 private_tls_peer_t *this;
629
630 INIT(this,
631 .public.handshake = {
632 .process = _process,
633 .build = _build,
634 .cipherspec_changed = _cipherspec_changed,
635 .change_cipherspec = _change_cipherspec,
636 .destroy = _destroy,
637 },
638 .state = STATE_INIT,
639 .tls = tls,
640 .crypto = crypto,
641 .peer = peer,
642 .server = server,
643 .peer_auth = auth_cfg_create(),
644 .server_auth = auth_cfg_create(),
645 );
646
647 return &this->public;
648 }