]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libtls/tls_server.c
df5d00ab53131bb5cdc345aaaa8add30e4e9acc8
[thirdparty/strongswan.git] / src / libtls / tls_server.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_server.h"
17
18 #include <time.h>
19
20 #include <utils/debug.h>
21 #include <credentials/certificates/x509.h>
22
23 typedef struct private_tls_server_t private_tls_server_t;
24
25 /**
26 * Size of a session ID
27 */
28 #define SESSION_ID_SIZE 16
29
30 typedef enum {
31 STATE_INIT,
32 STATE_HELLO_RECEIVED,
33 STATE_HELLO_SENT,
34 STATE_CERT_SENT,
35 STATE_KEY_EXCHANGE_SENT,
36 STATE_CERTREQ_SENT,
37 STATE_HELLO_DONE,
38 STATE_CERT_RECEIVED,
39 STATE_KEY_EXCHANGE_RECEIVED,
40 STATE_CERT_VERIFY_RECEIVED,
41 STATE_CIPHERSPEC_CHANGED_IN,
42 STATE_FINISHED_RECEIVED,
43 STATE_CIPHERSPEC_CHANGED_OUT,
44 STATE_FINISHED_SENT,
45 } server_state_t;
46
47 /**
48 * Private data of an tls_server_t object.
49 */
50 struct private_tls_server_t {
51
52 /**
53 * Public tls_server_t interface.
54 */
55 tls_server_t public;
56
57 /**
58 * TLS stack
59 */
60 tls_t *tls;
61
62 /**
63 * TLS crypto context
64 */
65 tls_crypto_t *crypto;
66
67 /**
68 * TLS alert handler
69 */
70 tls_alert_t *alert;
71
72 /**
73 * Server identity
74 */
75 identification_t *server;
76
77 /**
78 * Peer identity, NULL for no client authentication
79 */
80 identification_t *peer;
81
82 /**
83 * Is it acceptable if we couldn't verify the peer certificate?
84 */
85 bool peer_auth_optional;
86
87 /**
88 * State we are in
89 */
90 server_state_t state;
91
92 /**
93 * Hello random data selected by client
94 */
95 char client_random[32];
96
97 /**
98 * Hello random data selected by server
99 */
100 char server_random[32];
101
102 /**
103 * Auth helper for peer authentication
104 */
105 auth_cfg_t *peer_auth;
106
107 /**
108 * Auth helper for server authentication
109 */
110 auth_cfg_t *server_auth;
111
112 /**
113 * Peer private key
114 */
115 private_key_t *private;
116
117 /**
118 * DHE exchange
119 */
120 diffie_hellman_t *dh;
121
122 /**
123 * Selected TLS cipher suite
124 */
125 tls_cipher_suite_t suite;
126
127 /**
128 * Offered TLS version of the client
129 */
130 tls_version_t client_version;
131
132 /**
133 * TLS session identifier
134 */
135 chunk_t session;
136
137 /**
138 * Do we resume a session?
139 */
140 bool resume;
141
142 /**
143 * Hash and signature algorithms supported by peer
144 */
145 chunk_t hashsig;
146
147 /**
148 * Elliptic curves supported by peer
149 */
150 chunk_t curves;
151
152 /**
153 * Did we receive the curves from the client?
154 */
155 bool curves_received;
156 };
157
158 /**
159 * Find a cipher suite and a server key
160 */
161 static bool select_suite_and_key(private_tls_server_t *this,
162 tls_cipher_suite_t *suites, int count)
163 {
164 private_key_t *key;
165 key_type_t type;
166
167 key = lib->credmgr->get_private(lib->credmgr, KEY_ANY, this->server,
168 this->server_auth);
169 if (!key)
170 {
171 DBG1(DBG_TLS, "no usable TLS server certificate found for '%Y'",
172 this->server);
173 return FALSE;
174 }
175 this->suite = this->crypto->select_cipher_suite(this->crypto,
176 suites, count, key->get_type(key));
177 if (!this->suite)
178 { /* no match for this key, try to find another type */
179 if (key->get_type(key) == KEY_ECDSA)
180 {
181 type = KEY_RSA;
182 }
183 else
184 {
185 type = KEY_ECDSA;
186 }
187 key->destroy(key);
188
189 this->suite = this->crypto->select_cipher_suite(this->crypto,
190 suites, count, type);
191 if (!this->suite)
192 {
193 DBG1(DBG_TLS, "received cipher suites inacceptable");
194 return FALSE;
195 }
196 this->server_auth->destroy(this->server_auth);
197 this->server_auth = auth_cfg_create();
198 key = lib->credmgr->get_private(lib->credmgr, type, this->server,
199 this->server_auth);
200 if (!key)
201 {
202 DBG1(DBG_TLS, "received cipher suites inacceptable");
203 return FALSE;
204 }
205 }
206 this->private = key;
207 return TRUE;
208 }
209
210 /**
211 * Process client hello message
212 */
213 static status_t process_client_hello(private_tls_server_t *this,
214 bio_reader_t *reader)
215 {
216 u_int16_t version, extension;
217 chunk_t random, session, ciphers, compression, ext = chunk_empty;
218 bio_reader_t *extensions;
219 tls_cipher_suite_t *suites;
220 int count, i;
221 rng_t *rng;
222
223 this->crypto->append_handshake(this->crypto,
224 TLS_CLIENT_HELLO, reader->peek(reader));
225
226 if (!reader->read_uint16(reader, &version) ||
227 !reader->read_data(reader, sizeof(this->client_random), &random) ||
228 !reader->read_data8(reader, &session) ||
229 !reader->read_data16(reader, &ciphers) ||
230 !reader->read_data8(reader, &compression) ||
231 (reader->remaining(reader) && !reader->read_data16(reader, &ext)))
232 {
233 DBG1(DBG_TLS, "received invalid ClientHello");
234 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
235 return NEED_MORE;
236 }
237
238 if (ext.len)
239 {
240 extensions = bio_reader_create(ext);
241 while (extensions->remaining(extensions))
242 {
243 if (!extensions->read_uint16(extensions, &extension) ||
244 !extensions->read_data16(extensions, &ext))
245 {
246 DBG1(DBG_TLS, "received invalid ClientHello Extensions");
247 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
248 extensions->destroy(extensions);
249 return NEED_MORE;
250 }
251 DBG2(DBG_TLS, "received TLS '%N' extension",
252 tls_extension_names, extension);
253 DBG3(DBG_TLS, "%B", &ext);
254 switch (extension)
255 {
256 case TLS_EXT_SIGNATURE_ALGORITHMS:
257 this->hashsig = chunk_clone(ext);
258 break;
259 case TLS_EXT_ELLIPTIC_CURVES:
260 this->curves_received = TRUE;
261 this->curves = chunk_clone(ext);
262 break;
263 default:
264 break;
265 }
266 }
267 extensions->destroy(extensions);
268 }
269
270 memcpy(this->client_random, random.ptr, sizeof(this->client_random));
271
272 htoun32(&this->server_random, time(NULL));
273 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
274 if (!rng ||
275 !rng->get_bytes(rng, sizeof(this->server_random) - 4,
276 this->server_random + 4))
277 {
278 DBG1(DBG_TLS, "failed to generate server random");
279 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
280 DESTROY_IF(rng);
281 return NEED_MORE;
282 }
283 rng->destroy(rng);
284
285 if (!this->tls->set_version(this->tls, version))
286 {
287 DBG1(DBG_TLS, "negotiated version %N not supported",
288 tls_version_names, version);
289 this->alert->add(this->alert, TLS_FATAL, TLS_PROTOCOL_VERSION);
290 return NEED_MORE;
291 }
292
293 this->client_version = version;
294 this->suite = this->crypto->resume_session(this->crypto, session, this->peer,
295 chunk_from_thing(this->client_random),
296 chunk_from_thing(this->server_random));
297 if (this->suite)
298 {
299 this->session = chunk_clone(session);
300 this->resume = TRUE;
301 DBG1(DBG_TLS, "resumed %N using suite %N",
302 tls_version_names, this->tls->get_version(this->tls),
303 tls_cipher_suite_names, this->suite);
304 }
305 else
306 {
307 count = ciphers.len / sizeof(u_int16_t);
308 suites = alloca(count * sizeof(tls_cipher_suite_t));
309 DBG2(DBG_TLS, "received %d TLS cipher suites:", count);
310 for (i = 0; i < count; i++)
311 {
312 suites[i] = untoh16(&ciphers.ptr[i * sizeof(u_int16_t)]);
313 DBG2(DBG_TLS, " %N", tls_cipher_suite_names, suites[i]);
314 }
315 if (!select_suite_and_key(this, suites, count))
316 {
317 this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
318 return NEED_MORE;
319 }
320 rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
321 if (!rng || !rng->allocate_bytes(rng, SESSION_ID_SIZE, &this->session))
322 {
323 DBG1(DBG_TLS, "generating TLS session identifier failed, skipped");
324 }
325 DESTROY_IF(rng);
326 DBG1(DBG_TLS, "negotiated %N using suite %N",
327 tls_version_names, this->tls->get_version(this->tls),
328 tls_cipher_suite_names, this->suite);
329 }
330 this->state = STATE_HELLO_RECEIVED;
331 return NEED_MORE;
332 }
333
334 /**
335 * Process certificate
336 */
337 static status_t process_certificate(private_tls_server_t *this,
338 bio_reader_t *reader)
339 {
340 certificate_t *cert;
341 bio_reader_t *certs;
342 chunk_t data;
343 bool first = TRUE;
344
345 this->crypto->append_handshake(this->crypto,
346 TLS_CERTIFICATE, reader->peek(reader));
347
348 if (!reader->read_data24(reader, &data))
349 {
350 DBG1(DBG_TLS, "certificate message header invalid");
351 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
352 return NEED_MORE;
353 }
354 certs = bio_reader_create(data);
355 while (certs->remaining(certs))
356 {
357 if (!certs->read_data24(certs, &data))
358 {
359 DBG1(DBG_TLS, "certificate message invalid");
360 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
361 certs->destroy(certs);
362 return NEED_MORE;
363 }
364 cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
365 BUILD_BLOB_ASN1_DER, data, BUILD_END);
366 if (cert)
367 {
368 if (first)
369 {
370 this->peer_auth->add(this->peer_auth,
371 AUTH_HELPER_SUBJECT_CERT, cert);
372 DBG1(DBG_TLS, "received TLS peer certificate '%Y'",
373 cert->get_subject(cert));
374 first = FALSE;
375 if (this->peer == NULL)
376 { /* apply identity to authenticate */
377 this->peer = cert->get_subject(cert);
378 this->peer = this->peer->clone(this->peer);
379 this->peer_auth_optional = TRUE;
380 }
381 }
382 else
383 {
384 DBG1(DBG_TLS, "received TLS intermediate certificate '%Y'",
385 cert->get_subject(cert));
386 this->peer_auth->add(this->peer_auth, AUTH_HELPER_IM_CERT, cert);
387 }
388 }
389 else
390 {
391 DBG1(DBG_TLS, "parsing TLS certificate failed, skipped");
392 this->alert->add(this->alert, TLS_WARNING, TLS_BAD_CERTIFICATE);
393 }
394 }
395 certs->destroy(certs);
396 this->state = STATE_CERT_RECEIVED;
397 return NEED_MORE;
398 }
399
400 /**
401 * Process Client Key Exchange, using premaster encryption
402 */
403 static status_t process_key_exchange_encrypted(private_tls_server_t *this,
404 bio_reader_t *reader)
405 {
406 chunk_t encrypted, decrypted;
407 char premaster[48];
408 rng_t *rng;
409
410 this->crypto->append_handshake(this->crypto,
411 TLS_CLIENT_KEY_EXCHANGE, reader->peek(reader));
412
413 if (!reader->read_data16(reader, &encrypted))
414 {
415 DBG1(DBG_TLS, "received invalid Client Key Exchange");
416 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
417 return NEED_MORE;
418 }
419
420 htoun16(premaster, this->client_version);
421 /* pre-randomize premaster for failure cases */
422 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
423 if (!rng || !rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2))
424 {
425 DBG1(DBG_TLS, "failed to generate premaster secret");
426 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
427 DESTROY_IF(rng);
428 return NEED_MORE;
429 }
430 rng->destroy(rng);
431
432 if (this->private &&
433 this->private->decrypt(this->private,
434 ENCRYPT_RSA_PKCS1, encrypted, &decrypted))
435 {
436 if (decrypted.len == sizeof(premaster) &&
437 untoh16(decrypted.ptr) == this->client_version)
438 {
439 memcpy(premaster + 2, decrypted.ptr + 2, sizeof(premaster) - 2);
440 }
441 else
442 {
443 DBG1(DBG_TLS, "decrypted premaster has invalid length/version");
444 }
445 chunk_clear(&decrypted);
446 }
447 else
448 {
449 DBG1(DBG_TLS, "decrypting Client Key Exchange failed");
450 }
451
452 if (!this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
453 this->session, this->peer,
454 chunk_from_thing(this->client_random),
455 chunk_from_thing(this->server_random)))
456 {
457 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
458 return NEED_MORE;
459 }
460
461 this->state = STATE_KEY_EXCHANGE_RECEIVED;
462 return NEED_MORE;
463 }
464
465 /**
466 * Process client key exchange, using DHE exchange
467 */
468 static status_t process_key_exchange_dhe(private_tls_server_t *this,
469 bio_reader_t *reader)
470 {
471 chunk_t premaster, pub;
472 bool ec;
473
474 this->crypto->append_handshake(this->crypto,
475 TLS_CLIENT_KEY_EXCHANGE, reader->peek(reader));
476
477 ec = diffie_hellman_group_is_ec(this->dh->get_dh_group(this->dh));
478 if ((ec && !reader->read_data8(reader, &pub)) ||
479 (!ec && (!reader->read_data16(reader, &pub) || pub.len == 0)))
480 {
481 DBG1(DBG_TLS, "received invalid Client Key Exchange");
482 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
483 return NEED_MORE;
484 }
485
486 if (ec)
487 {
488 if (pub.ptr[0] != TLS_ANSI_UNCOMPRESSED)
489 {
490 DBG1(DBG_TLS, "DH point format '%N' not supported",
491 tls_ansi_point_format_names, pub.ptr[0]);
492 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
493 return NEED_MORE;
494 }
495 pub = chunk_skip(pub, 1);
496 }
497 this->dh->set_other_public_value(this->dh, pub);
498 if (!this->dh->get_shared_secret(this->dh, &premaster))
499 {
500 DBG1(DBG_TLS, "calculating premaster from DH failed");
501 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
502 return NEED_MORE;
503 }
504
505 if (!this->crypto->derive_secrets(this->crypto, premaster,
506 this->session, this->peer,
507 chunk_from_thing(this->client_random),
508 chunk_from_thing(this->server_random)))
509 {
510 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
511 chunk_clear(&premaster);
512 return NEED_MORE;
513 }
514 chunk_clear(&premaster);
515
516 this->state = STATE_KEY_EXCHANGE_RECEIVED;
517 return NEED_MORE;
518 }
519
520 /**
521 * Process Client Key Exchange
522 */
523 static status_t process_key_exchange(private_tls_server_t *this,
524 bio_reader_t *reader)
525 {
526 if (this->dh)
527 {
528 return process_key_exchange_dhe(this, reader);
529 }
530 return process_key_exchange_encrypted(this, reader);
531 }
532
533 /**
534 * Process Certificate verify
535 */
536 static status_t process_cert_verify(private_tls_server_t *this,
537 bio_reader_t *reader)
538 {
539 bool verified = FALSE;
540 enumerator_t *enumerator;
541 public_key_t *public;
542 auth_cfg_t *auth;
543 bio_reader_t *sig;
544
545 enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
546 KEY_ANY, this->peer, this->peer_auth);
547 while (enumerator->enumerate(enumerator, &public, &auth))
548 {
549 sig = bio_reader_create(reader->peek(reader));
550 verified = this->crypto->verify_handshake(this->crypto, public, sig);
551 sig->destroy(sig);
552 if (verified)
553 {
554 this->peer_auth->merge(this->peer_auth, auth, FALSE);
555 break;
556 }
557 DBG1(DBG_TLS, "signature verification failed, trying another key");
558 }
559 enumerator->destroy(enumerator);
560
561 if (!verified)
562 {
563 DBG1(DBG_TLS, "no trusted certificate found for '%Y' to verify TLS peer",
564 this->peer);
565 if (!this->peer_auth_optional)
566 { /* client authentication is required */
567 this->alert->add(this->alert, TLS_FATAL, TLS_CERTIFICATE_UNKNOWN);
568 return NEED_MORE;
569 }
570 /* reset peer identity, we couldn't authenticate it */
571 this->peer->destroy(this->peer);
572 this->peer = NULL;
573 this->state = STATE_KEY_EXCHANGE_RECEIVED;
574 }
575 else
576 {
577 this->state = STATE_CERT_VERIFY_RECEIVED;
578 }
579 this->crypto->append_handshake(this->crypto,
580 TLS_CERTIFICATE_VERIFY, reader->peek(reader));
581 return NEED_MORE;
582 }
583
584 /**
585 * Process finished message
586 */
587 static status_t process_finished(private_tls_server_t *this,
588 bio_reader_t *reader)
589 {
590 chunk_t received;
591 char buf[12];
592
593 if (!reader->read_data(reader, sizeof(buf), &received))
594 {
595 DBG1(DBG_TLS, "received client finished too short");
596 this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
597 return NEED_MORE;
598 }
599 if (!this->crypto->calculate_finished(this->crypto, "client finished", buf))
600 {
601 DBG1(DBG_TLS, "calculating client finished failed");
602 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
603 return NEED_MORE;
604 }
605 if (!chunk_equals(received, chunk_from_thing(buf)))
606 {
607 DBG1(DBG_TLS, "received client finished invalid");
608 this->alert->add(this->alert, TLS_FATAL, TLS_DECRYPT_ERROR);
609 return NEED_MORE;
610 }
611
612 this->crypto->append_handshake(this->crypto, TLS_FINISHED, received);
613 this->state = STATE_FINISHED_RECEIVED;
614 return NEED_MORE;
615 }
616
617 METHOD(tls_handshake_t, process, status_t,
618 private_tls_server_t *this, tls_handshake_type_t type, bio_reader_t *reader)
619 {
620 tls_handshake_type_t expected;
621
622 switch (this->state)
623 {
624 case STATE_INIT:
625 if (type == TLS_CLIENT_HELLO)
626 {
627 return process_client_hello(this, reader);
628 }
629 expected = TLS_CLIENT_HELLO;
630 break;
631 case STATE_HELLO_DONE:
632 if (type == TLS_CERTIFICATE)
633 {
634 return process_certificate(this, reader);
635 }
636 if (this->peer)
637 {
638 expected = TLS_CERTIFICATE;
639 break;
640 }
641 /* otherwise fall through to next state */
642 case STATE_CERT_RECEIVED:
643 if (type == TLS_CLIENT_KEY_EXCHANGE)
644 {
645 return process_key_exchange(this, reader);
646 }
647 expected = TLS_CLIENT_KEY_EXCHANGE;
648 break;
649 case STATE_KEY_EXCHANGE_RECEIVED:
650 if (type == TLS_CERTIFICATE_VERIFY)
651 {
652 return process_cert_verify(this, reader);
653 }
654 if (this->peer)
655 {
656 expected = TLS_CERTIFICATE_VERIFY;
657 break;
658 }
659 return INVALID_STATE;
660 case STATE_CIPHERSPEC_CHANGED_IN:
661 if (type == TLS_FINISHED)
662 {
663 return process_finished(this, reader);
664 }
665 expected = TLS_FINISHED;
666 break;
667 default:
668 DBG1(DBG_TLS, "TLS %N not expected in current state",
669 tls_handshake_type_names, type);
670 this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE);
671 return NEED_MORE;
672 }
673 DBG1(DBG_TLS, "TLS %N expected, but received %N",
674 tls_handshake_type_names, expected, tls_handshake_type_names, type);
675 this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE);
676 return NEED_MORE;
677 }
678
679 /**
680 * Send ServerHello message
681 */
682 static status_t send_server_hello(private_tls_server_t *this,
683 tls_handshake_type_t *type, bio_writer_t *writer)
684 {
685 /* TLS version */
686 writer->write_uint16(writer, this->tls->get_version(this->tls));
687 writer->write_data(writer, chunk_from_thing(this->server_random));
688
689 /* session identifier if we have one */
690 writer->write_data8(writer, this->session);
691
692 /* add selected TLS cipher suite */
693 writer->write_uint16(writer, this->suite);
694
695 /* NULL compression only */
696 writer->write_uint8(writer, 0);
697
698 *type = TLS_SERVER_HELLO;
699 this->state = STATE_HELLO_SENT;
700 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
701 return NEED_MORE;
702 }
703
704 /**
705 * Send Certificate
706 */
707 static status_t send_certificate(private_tls_server_t *this,
708 tls_handshake_type_t *type, bio_writer_t *writer)
709 {
710 enumerator_t *enumerator;
711 certificate_t *cert;
712 auth_rule_t rule;
713 bio_writer_t *certs;
714 chunk_t data;
715
716 /* generate certificate payload */
717 certs = bio_writer_create(256);
718 cert = this->server_auth->get(this->server_auth, AUTH_RULE_SUBJECT_CERT);
719 if (cert)
720 {
721 if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
722 {
723 DBG1(DBG_TLS, "sending TLS server certificate '%Y'",
724 cert->get_subject(cert));
725 certs->write_data24(certs, data);
726 free(data.ptr);
727 }
728 }
729 enumerator = this->server_auth->create_enumerator(this->server_auth);
730 while (enumerator->enumerate(enumerator, &rule, &cert))
731 {
732 if (rule == AUTH_RULE_IM_CERT)
733 {
734 if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
735 {
736 DBG1(DBG_TLS, "sending TLS intermediate certificate '%Y'",
737 cert->get_subject(cert));
738 certs->write_data24(certs, data);
739 free(data.ptr);
740 }
741 }
742 }
743 enumerator->destroy(enumerator);
744
745 writer->write_data24(writer, certs->get_buf(certs));
746 certs->destroy(certs);
747
748 *type = TLS_CERTIFICATE;
749 this->state = STATE_CERT_SENT;
750 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
751 return NEED_MORE;
752 }
753
754 /**
755 * Send Certificate Request
756 */
757 static status_t send_certificate_request(private_tls_server_t *this,
758 tls_handshake_type_t *type, bio_writer_t *writer)
759 {
760 bio_writer_t *authorities, *supported;
761 enumerator_t *enumerator;
762 certificate_t *cert;
763 x509_t *x509;
764 identification_t *id;
765
766 supported = bio_writer_create(4);
767 /* we propose both RSA and ECDSA */
768 supported->write_uint8(supported, TLS_RSA_SIGN);
769 supported->write_uint8(supported, TLS_ECDSA_SIGN);
770 writer->write_data8(writer, supported->get_buf(supported));
771 supported->destroy(supported);
772 if (this->tls->get_version(this->tls) >= TLS_1_2)
773 {
774 this->crypto->get_signature_algorithms(this->crypto, writer);
775 }
776
777 authorities = bio_writer_create(64);
778 enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
779 CERT_X509, KEY_RSA, NULL, TRUE);
780 while (enumerator->enumerate(enumerator, &cert))
781 {
782 x509 = (x509_t*)cert;
783 if (x509->get_flags(x509) & X509_CA)
784 {
785 id = cert->get_subject(cert);
786 DBG1(DBG_TLS, "sending TLS cert request for '%Y'", id);
787 authorities->write_data16(authorities, id->get_encoding(id));
788 }
789 }
790 enumerator->destroy(enumerator);
791 writer->write_data16(writer, authorities->get_buf(authorities));
792 authorities->destroy(authorities);
793
794 *type = TLS_CERTIFICATE_REQUEST;
795 this->state = STATE_CERTREQ_SENT;
796 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
797 return NEED_MORE;
798 }
799
800 /**
801 * Get the TLS curve of a given EC DH group
802 */
803 static tls_named_curve_t ec_group_to_curve(private_tls_server_t *this,
804 diffie_hellman_group_t group)
805 {
806 diffie_hellman_group_t current;
807 tls_named_curve_t curve;
808 enumerator_t *enumerator;
809
810 enumerator = this->crypto->create_ec_enumerator(this->crypto);
811 while (enumerator->enumerate(enumerator, &current, &curve))
812 {
813 if (current == group)
814 {
815 enumerator->destroy(enumerator);
816 return curve;
817 }
818 }
819 enumerator->destroy(enumerator);
820 return 0;
821 }
822
823 /**
824 * Check if the peer supports a given TLS curve
825 */
826 bool peer_supports_curve(private_tls_server_t *this, tls_named_curve_t curve)
827 {
828 bio_reader_t *reader;
829 u_int16_t current;
830
831 if (!this->curves_received)
832 { /* none received, assume yes */
833 return TRUE;
834 }
835 reader = bio_reader_create(this->curves);
836 while (reader->remaining(reader) && reader->read_uint16(reader, &current))
837 {
838 if (current == curve)
839 {
840 reader->destroy(reader);
841 return TRUE;
842 }
843 }
844 reader->destroy(reader);
845 return FALSE;
846 }
847
848 /**
849 * Try to find a curve supported by both, client and server
850 */
851 static bool find_supported_curve(private_tls_server_t *this,
852 tls_named_curve_t *curve)
853 {
854 tls_named_curve_t current;
855 enumerator_t *enumerator;
856
857 enumerator = this->crypto->create_ec_enumerator(this->crypto);
858 while (enumerator->enumerate(enumerator, NULL, &current))
859 {
860 if (peer_supports_curve(this, current))
861 {
862 *curve = current;
863 enumerator->destroy(enumerator);
864 return TRUE;
865 }
866 }
867 enumerator->destroy(enumerator);
868 return FALSE;
869 }
870
871 /**
872 * Send Server key Exchange
873 */
874 static status_t send_server_key_exchange(private_tls_server_t *this,
875 tls_handshake_type_t *type, bio_writer_t *writer,
876 diffie_hellman_group_t group)
877 {
878 diffie_hellman_params_t *params = NULL;
879 tls_named_curve_t curve;
880 chunk_t chunk;
881
882 if (diffie_hellman_group_is_ec(group))
883 {
884 curve = ec_group_to_curve(this, group);
885 if (!curve || (!peer_supports_curve(this, curve) &&
886 !find_supported_curve(this, &curve)))
887 {
888 DBG1(DBG_TLS, "no EC group supported by client and server");
889 this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
890 return NEED_MORE;
891 }
892 DBG2(DBG_TLS, "selected ECDH group %N", tls_named_curve_names, curve);
893 writer->write_uint8(writer, TLS_ECC_NAMED_CURVE);
894 writer->write_uint16(writer, curve);
895 }
896 else
897 {
898 params = diffie_hellman_get_params(group);
899 if (!params)
900 {
901 DBG1(DBG_TLS, "no parameters found for DH group %N",
902 diffie_hellman_group_names, group);
903 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
904 return NEED_MORE;
905 }
906 DBG2(DBG_TLS, "selected DH group %N", diffie_hellman_group_names, group);
907 writer->write_data16(writer, params->prime);
908 writer->write_data16(writer, params->generator);
909 }
910 this->dh = lib->crypto->create_dh(lib->crypto, group);
911 if (!this->dh)
912 {
913 DBG1(DBG_TLS, "DH group %N not supported",
914 diffie_hellman_group_names, group);
915 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
916 return NEED_MORE;
917 }
918 this->dh->get_my_public_value(this->dh, &chunk);
919 if (params)
920 {
921 writer->write_data16(writer, chunk);
922 }
923 else
924 { /* ECP uses 8bit length header only, but a point format */
925 writer->write_uint8(writer, chunk.len + 1);
926 writer->write_uint8(writer, TLS_ANSI_UNCOMPRESSED);
927 writer->write_data(writer, chunk);
928 }
929 free(chunk.ptr);
930
931 chunk = chunk_cat("ccc", chunk_from_thing(this->client_random),
932 chunk_from_thing(this->server_random), writer->get_buf(writer));
933 if (!this->private || !this->crypto->sign(this->crypto, this->private,
934 writer, chunk, this->hashsig))
935 {
936 DBG1(DBG_TLS, "signing DH parameters failed");
937 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
938 free(chunk.ptr);
939 return NEED_MORE;
940 }
941 free(chunk.ptr);
942 *type = TLS_SERVER_KEY_EXCHANGE;
943 this->state = STATE_KEY_EXCHANGE_SENT;
944 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
945 return NEED_MORE;
946 }
947
948 /**
949 * Send Hello Done
950 */
951 static status_t send_hello_done(private_tls_server_t *this,
952 tls_handshake_type_t *type, bio_writer_t *writer)
953 {
954 *type = TLS_SERVER_HELLO_DONE;
955 this->state = STATE_HELLO_DONE;
956 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
957 return NEED_MORE;
958 }
959
960 /**
961 * Send Finished
962 */
963 static status_t send_finished(private_tls_server_t *this,
964 tls_handshake_type_t *type, bio_writer_t *writer)
965 {
966 char buf[12];
967
968 if (!this->crypto->calculate_finished(this->crypto, "server finished", buf))
969 {
970 DBG1(DBG_TLS, "calculating server finished data failed");
971 this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
972 return FAILED;
973 }
974
975 writer->write_data(writer, chunk_from_thing(buf));
976
977 *type = TLS_FINISHED;
978 this->state = STATE_FINISHED_SENT;
979 this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
980
981 return NEED_MORE;
982 }
983
984 METHOD(tls_handshake_t, build, status_t,
985 private_tls_server_t *this, tls_handshake_type_t *type, bio_writer_t *writer)
986 {
987 diffie_hellman_group_t group;
988
989 switch (this->state)
990 {
991 case STATE_HELLO_RECEIVED:
992 return send_server_hello(this, type, writer);
993 case STATE_HELLO_SENT:
994 return send_certificate(this, type, writer);
995 case STATE_CERT_SENT:
996 group = this->crypto->get_dh_group(this->crypto);
997 if (group)
998 {
999 return send_server_key_exchange(this, type, writer, group);
1000 }
1001 /* otherwise fall through to next state */
1002 case STATE_KEY_EXCHANGE_SENT:
1003 return send_certificate_request(this, type, writer);
1004 case STATE_CERTREQ_SENT:
1005 return send_hello_done(this, type, writer);
1006 case STATE_CIPHERSPEC_CHANGED_OUT:
1007 return send_finished(this, type, writer);
1008 case STATE_FINISHED_SENT:
1009 return INVALID_STATE;
1010 default:
1011 return INVALID_STATE;
1012 }
1013 }
1014
1015 METHOD(tls_handshake_t, cipherspec_changed, bool,
1016 private_tls_server_t *this, bool inbound)
1017 {
1018 if (inbound)
1019 {
1020 if (this->resume)
1021 {
1022 return this->state == STATE_FINISHED_SENT;
1023 }
1024 if (this->peer)
1025 {
1026 return this->state == STATE_CERT_VERIFY_RECEIVED;
1027 }
1028 return this->state == STATE_KEY_EXCHANGE_RECEIVED;
1029 }
1030 else
1031 {
1032 if (this->resume)
1033 {
1034 return this->state == STATE_HELLO_SENT;
1035 }
1036 return this->state == STATE_FINISHED_RECEIVED;
1037 }
1038 return FALSE;
1039 }
1040
1041 METHOD(tls_handshake_t, change_cipherspec, void,
1042 private_tls_server_t *this, bool inbound)
1043 {
1044 this->crypto->change_cipher(this->crypto, inbound);
1045 if (inbound)
1046 {
1047 this->state = STATE_CIPHERSPEC_CHANGED_IN;
1048 }
1049 else
1050 {
1051 this->state = STATE_CIPHERSPEC_CHANGED_OUT;
1052 }
1053 }
1054
1055 METHOD(tls_handshake_t, finished, bool,
1056 private_tls_server_t *this)
1057 {
1058 if (this->resume)
1059 {
1060 return this->state == STATE_FINISHED_RECEIVED;
1061 }
1062 return this->state == STATE_FINISHED_SENT;
1063 }
1064
1065 METHOD(tls_handshake_t, get_peer_id, identification_t*,
1066 private_tls_server_t *this)
1067 {
1068 return this->peer;
1069 }
1070
1071 METHOD(tls_handshake_t, get_server_id, identification_t*,
1072 private_tls_server_t *this)
1073 {
1074 return this->server;
1075 }
1076
1077 METHOD(tls_handshake_t, get_auth, auth_cfg_t*,
1078 private_tls_server_t *this)
1079 {
1080 return this->peer_auth;
1081 }
1082
1083 METHOD(tls_handshake_t, destroy, void,
1084 private_tls_server_t *this)
1085 {
1086 DESTROY_IF(this->private);
1087 DESTROY_IF(this->dh);
1088 DESTROY_IF(this->peer);
1089 this->server->destroy(this->server);
1090 this->peer_auth->destroy(this->peer_auth);
1091 this->server_auth->destroy(this->server_auth);
1092 free(this->hashsig.ptr);
1093 free(this->curves.ptr);
1094 free(this->session.ptr);
1095 free(this);
1096 }
1097
1098 /**
1099 * See header
1100 */
1101 tls_server_t *tls_server_create(tls_t *tls,
1102 tls_crypto_t *crypto, tls_alert_t *alert,
1103 identification_t *server, identification_t *peer)
1104 {
1105 private_tls_server_t *this;
1106
1107 INIT(this,
1108 .public = {
1109 .handshake = {
1110 .process = _process,
1111 .build = _build,
1112 .cipherspec_changed = _cipherspec_changed,
1113 .change_cipherspec = _change_cipherspec,
1114 .finished = _finished,
1115 .get_peer_id = _get_peer_id,
1116 .get_server_id = _get_server_id,
1117 .get_auth = _get_auth,
1118 .destroy = _destroy,
1119 },
1120 },
1121 .tls = tls,
1122 .crypto = crypto,
1123 .alert = alert,
1124 .server = server->clone(server),
1125 .peer = peer ? peer->clone(peer) : NULL,
1126 .state = STATE_INIT,
1127 .peer_auth = auth_cfg_create(),
1128 .server_auth = auth_cfg_create(),
1129 );
1130
1131 return &this->public;
1132 }