Annotation of embedaddon/strongswan/src/libtls/tls_server.c, revision 1.1.1.1
1.1 misho 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 unacceptable");
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 unacceptable");
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: uint16_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(uint16_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(uint16_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: if (!this->dh->set_other_public_value(this->dh, pub))
498: {
499: DBG1(DBG_TLS, "applying DH public value failed");
500: this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
501: return NEED_MORE;
502: }
503: if (!this->dh->get_shared_secret(this->dh, &premaster))
504: {
505: DBG1(DBG_TLS, "calculating premaster from DH failed");
506: this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
507: return NEED_MORE;
508: }
509:
510: if (!this->crypto->derive_secrets(this->crypto, premaster,
511: this->session, this->peer,
512: chunk_from_thing(this->client_random),
513: chunk_from_thing(this->server_random)))
514: {
515: this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
516: chunk_clear(&premaster);
517: return NEED_MORE;
518: }
519: chunk_clear(&premaster);
520:
521: this->state = STATE_KEY_EXCHANGE_RECEIVED;
522: return NEED_MORE;
523: }
524:
525: /**
526: * Process Client Key Exchange
527: */
528: static status_t process_key_exchange(private_tls_server_t *this,
529: bio_reader_t *reader)
530: {
531: if (this->dh)
532: {
533: return process_key_exchange_dhe(this, reader);
534: }
535: return process_key_exchange_encrypted(this, reader);
536: }
537:
538: /**
539: * Process Certificate verify
540: */
541: static status_t process_cert_verify(private_tls_server_t *this,
542: bio_reader_t *reader)
543: {
544: bool verified = FALSE;
545: enumerator_t *enumerator;
546: public_key_t *public;
547: auth_cfg_t *auth;
548: bio_reader_t *sig;
549:
550: enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
551: KEY_ANY, this->peer, this->peer_auth, TRUE);
552: while (enumerator->enumerate(enumerator, &public, &auth))
553: {
554: sig = bio_reader_create(reader->peek(reader));
555: verified = this->crypto->verify_handshake(this->crypto, public, sig);
556: sig->destroy(sig);
557: if (verified)
558: {
559: this->peer_auth->merge(this->peer_auth, auth, FALSE);
560: break;
561: }
562: DBG1(DBG_TLS, "signature verification failed, trying another key");
563: }
564: enumerator->destroy(enumerator);
565:
566: if (!verified)
567: {
568: DBG1(DBG_TLS, "no trusted certificate found for '%Y' to verify TLS peer",
569: this->peer);
570: if (!this->peer_auth_optional)
571: { /* client authentication is required */
572: this->alert->add(this->alert, TLS_FATAL, TLS_CERTIFICATE_UNKNOWN);
573: return NEED_MORE;
574: }
575: /* reset peer identity, we couldn't authenticate it */
576: this->peer->destroy(this->peer);
577: this->peer = NULL;
578: this->state = STATE_KEY_EXCHANGE_RECEIVED;
579: }
580: else
581: {
582: this->state = STATE_CERT_VERIFY_RECEIVED;
583: }
584: this->crypto->append_handshake(this->crypto,
585: TLS_CERTIFICATE_VERIFY, reader->peek(reader));
586: return NEED_MORE;
587: }
588:
589: /**
590: * Process finished message
591: */
592: static status_t process_finished(private_tls_server_t *this,
593: bio_reader_t *reader)
594: {
595: chunk_t received;
596: char buf[12];
597:
598: if (!reader->read_data(reader, sizeof(buf), &received))
599: {
600: DBG1(DBG_TLS, "received client finished too short");
601: this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
602: return NEED_MORE;
603: }
604: if (!this->crypto->calculate_finished(this->crypto, "client finished", buf))
605: {
606: DBG1(DBG_TLS, "calculating client finished failed");
607: this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
608: return NEED_MORE;
609: }
610: if (!chunk_equals_const(received, chunk_from_thing(buf)))
611: {
612: DBG1(DBG_TLS, "received client finished invalid");
613: this->alert->add(this->alert, TLS_FATAL, TLS_DECRYPT_ERROR);
614: return NEED_MORE;
615: }
616:
617: this->crypto->append_handshake(this->crypto, TLS_FINISHED, received);
618: this->state = STATE_FINISHED_RECEIVED;
619: return NEED_MORE;
620: }
621:
622: METHOD(tls_handshake_t, process, status_t,
623: private_tls_server_t *this, tls_handshake_type_t type, bio_reader_t *reader)
624: {
625: tls_handshake_type_t expected;
626:
627: switch (this->state)
628: {
629: case STATE_INIT:
630: if (type == TLS_CLIENT_HELLO)
631: {
632: return process_client_hello(this, reader);
633: }
634: expected = TLS_CLIENT_HELLO;
635: break;
636: case STATE_HELLO_DONE:
637: if (type == TLS_CERTIFICATE)
638: {
639: return process_certificate(this, reader);
640: }
641: if (this->peer)
642: {
643: expected = TLS_CERTIFICATE;
644: break;
645: }
646: /* otherwise fall through to next state */
647: case STATE_CERT_RECEIVED:
648: if (type == TLS_CLIENT_KEY_EXCHANGE)
649: {
650: return process_key_exchange(this, reader);
651: }
652: expected = TLS_CLIENT_KEY_EXCHANGE;
653: break;
654: case STATE_KEY_EXCHANGE_RECEIVED:
655: if (type == TLS_CERTIFICATE_VERIFY)
656: {
657: return process_cert_verify(this, reader);
658: }
659: if (this->peer)
660: {
661: expected = TLS_CERTIFICATE_VERIFY;
662: break;
663: }
664: return INVALID_STATE;
665: case STATE_CIPHERSPEC_CHANGED_IN:
666: if (type == TLS_FINISHED)
667: {
668: return process_finished(this, reader);
669: }
670: expected = TLS_FINISHED;
671: break;
672: default:
673: DBG1(DBG_TLS, "TLS %N not expected in current state",
674: tls_handshake_type_names, type);
675: this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE);
676: return NEED_MORE;
677: }
678: DBG1(DBG_TLS, "TLS %N expected, but received %N",
679: tls_handshake_type_names, expected, tls_handshake_type_names, type);
680: this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE);
681: return NEED_MORE;
682: }
683:
684: /**
685: * Send ServerHello message
686: */
687: static status_t send_server_hello(private_tls_server_t *this,
688: tls_handshake_type_t *type, bio_writer_t *writer)
689: {
690: /* TLS version */
691: writer->write_uint16(writer, this->tls->get_version(this->tls));
692: writer->write_data(writer, chunk_from_thing(this->server_random));
693:
694: /* session identifier if we have one */
695: writer->write_data8(writer, this->session);
696:
697: /* add selected TLS cipher suite */
698: writer->write_uint16(writer, this->suite);
699:
700: /* NULL compression only */
701: writer->write_uint8(writer, 0);
702:
703: *type = TLS_SERVER_HELLO;
704: this->state = STATE_HELLO_SENT;
705: this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
706: return NEED_MORE;
707: }
708:
709: /**
710: * Send Certificate
711: */
712: static status_t send_certificate(private_tls_server_t *this,
713: tls_handshake_type_t *type, bio_writer_t *writer)
714: {
715: enumerator_t *enumerator;
716: certificate_t *cert;
717: auth_rule_t rule;
718: bio_writer_t *certs;
719: chunk_t data;
720:
721: /* generate certificate payload */
722: certs = bio_writer_create(256);
723: cert = this->server_auth->get(this->server_auth, AUTH_RULE_SUBJECT_CERT);
724: if (cert)
725: {
726: if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
727: {
728: DBG1(DBG_TLS, "sending TLS server certificate '%Y'",
729: cert->get_subject(cert));
730: certs->write_data24(certs, data);
731: free(data.ptr);
732: }
733: }
734: enumerator = this->server_auth->create_enumerator(this->server_auth);
735: while (enumerator->enumerate(enumerator, &rule, &cert))
736: {
737: if (rule == AUTH_RULE_IM_CERT)
738: {
739: if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
740: {
741: DBG1(DBG_TLS, "sending TLS intermediate certificate '%Y'",
742: cert->get_subject(cert));
743: certs->write_data24(certs, data);
744: free(data.ptr);
745: }
746: }
747: }
748: enumerator->destroy(enumerator);
749:
750: writer->write_data24(writer, certs->get_buf(certs));
751: certs->destroy(certs);
752:
753: *type = TLS_CERTIFICATE;
754: this->state = STATE_CERT_SENT;
755: this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
756: return NEED_MORE;
757: }
758:
759: /**
760: * Send Certificate Request
761: */
762: static status_t send_certificate_request(private_tls_server_t *this,
763: tls_handshake_type_t *type, bio_writer_t *writer)
764: {
765: bio_writer_t *authorities, *supported;
766: enumerator_t *enumerator;
767: certificate_t *cert;
768: x509_t *x509;
769: identification_t *id;
770:
771: supported = bio_writer_create(4);
772: /* we propose both RSA and ECDSA */
773: supported->write_uint8(supported, TLS_RSA_SIGN);
774: supported->write_uint8(supported, TLS_ECDSA_SIGN);
775: writer->write_data8(writer, supported->get_buf(supported));
776: supported->destroy(supported);
777: if (this->tls->get_version(this->tls) >= TLS_1_2)
778: {
779: this->crypto->get_signature_algorithms(this->crypto, writer);
780: }
781:
782: authorities = bio_writer_create(64);
783: enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
784: CERT_X509, KEY_RSA, NULL, TRUE);
785: while (enumerator->enumerate(enumerator, &cert))
786: {
787: x509 = (x509_t*)cert;
788: if (x509->get_flags(x509) & X509_CA)
789: {
790: id = cert->get_subject(cert);
791: DBG1(DBG_TLS, "sending TLS cert request for '%Y'", id);
792: authorities->write_data16(authorities, id->get_encoding(id));
793: }
794: }
795: enumerator->destroy(enumerator);
796: writer->write_data16(writer, authorities->get_buf(authorities));
797: authorities->destroy(authorities);
798:
799: *type = TLS_CERTIFICATE_REQUEST;
800: this->state = STATE_CERTREQ_SENT;
801: this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
802: return NEED_MORE;
803: }
804:
805: /**
806: * Get the TLS curve of a given EC DH group
807: */
808: static tls_named_curve_t ec_group_to_curve(private_tls_server_t *this,
809: diffie_hellman_group_t group)
810: {
811: diffie_hellman_group_t current;
812: tls_named_curve_t curve;
813: enumerator_t *enumerator;
814:
815: enumerator = this->crypto->create_ec_enumerator(this->crypto);
816: while (enumerator->enumerate(enumerator, ¤t, &curve))
817: {
818: if (current == group)
819: {
820: enumerator->destroy(enumerator);
821: return curve;
822: }
823: }
824: enumerator->destroy(enumerator);
825: return 0;
826: }
827:
828: /**
829: * Check if the peer supports a given TLS curve
830: */
831: bool peer_supports_curve(private_tls_server_t *this, tls_named_curve_t curve)
832: {
833: bio_reader_t *reader;
834: uint16_t current;
835:
836: if (!this->curves_received)
837: { /* none received, assume yes */
838: return TRUE;
839: }
840: reader = bio_reader_create(this->curves);
841: while (reader->remaining(reader) && reader->read_uint16(reader, ¤t))
842: {
843: if (current == curve)
844: {
845: reader->destroy(reader);
846: return TRUE;
847: }
848: }
849: reader->destroy(reader);
850: return FALSE;
851: }
852:
853: /**
854: * Try to find a curve supported by both, client and server
855: */
856: static bool find_supported_curve(private_tls_server_t *this,
857: tls_named_curve_t *curve)
858: {
859: tls_named_curve_t current;
860: enumerator_t *enumerator;
861:
862: enumerator = this->crypto->create_ec_enumerator(this->crypto);
863: while (enumerator->enumerate(enumerator, NULL, ¤t))
864: {
865: if (peer_supports_curve(this, current))
866: {
867: *curve = current;
868: enumerator->destroy(enumerator);
869: return TRUE;
870: }
871: }
872: enumerator->destroy(enumerator);
873: return FALSE;
874: }
875:
876: /**
877: * Send Server key Exchange
878: */
879: static status_t send_server_key_exchange(private_tls_server_t *this,
880: tls_handshake_type_t *type, bio_writer_t *writer,
881: diffie_hellman_group_t group)
882: {
883: diffie_hellman_params_t *params = NULL;
884: tls_named_curve_t curve;
885: chunk_t chunk;
886:
887: if (diffie_hellman_group_is_ec(group))
888: {
889: curve = ec_group_to_curve(this, group);
890: if (!curve || (!peer_supports_curve(this, curve) &&
891: !find_supported_curve(this, &curve)))
892: {
893: DBG1(DBG_TLS, "no EC group supported by client and server");
894: this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
895: return NEED_MORE;
896: }
897: DBG2(DBG_TLS, "selected ECDH group %N", tls_named_curve_names, curve);
898: writer->write_uint8(writer, TLS_ECC_NAMED_CURVE);
899: writer->write_uint16(writer, curve);
900: }
901: else
902: {
903: params = diffie_hellman_get_params(group);
904: if (!params)
905: {
906: DBG1(DBG_TLS, "no parameters found for DH group %N",
907: diffie_hellman_group_names, group);
908: this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
909: return NEED_MORE;
910: }
911: DBG2(DBG_TLS, "selected DH group %N", diffie_hellman_group_names, group);
912: writer->write_data16(writer, params->prime);
913: writer->write_data16(writer, params->generator);
914: }
915: this->dh = lib->crypto->create_dh(lib->crypto, group);
916: if (!this->dh)
917: {
918: DBG1(DBG_TLS, "DH group %N not supported",
919: diffie_hellman_group_names, group);
920: this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
921: return NEED_MORE;
922: }
923: if (!this->dh->get_my_public_value(this->dh, &chunk))
924: {
925: this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
926: return NEED_MORE;
927: }
928: if (params)
929: {
930: writer->write_data16(writer, chunk);
931: }
932: else
933: { /* ECP uses 8bit length header only, but a point format */
934: writer->write_uint8(writer, chunk.len + 1);
935: writer->write_uint8(writer, TLS_ANSI_UNCOMPRESSED);
936: writer->write_data(writer, chunk);
937: }
938: free(chunk.ptr);
939:
940: chunk = chunk_cat("ccc", chunk_from_thing(this->client_random),
941: chunk_from_thing(this->server_random), writer->get_buf(writer));
942: if (!this->private || !this->crypto->sign(this->crypto, this->private,
943: writer, chunk, this->hashsig))
944: {
945: DBG1(DBG_TLS, "signing DH parameters failed");
946: this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
947: free(chunk.ptr);
948: return NEED_MORE;
949: }
950: free(chunk.ptr);
951: *type = TLS_SERVER_KEY_EXCHANGE;
952: this->state = STATE_KEY_EXCHANGE_SENT;
953: this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
954: return NEED_MORE;
955: }
956:
957: /**
958: * Send Hello Done
959: */
960: static status_t send_hello_done(private_tls_server_t *this,
961: tls_handshake_type_t *type, bio_writer_t *writer)
962: {
963: *type = TLS_SERVER_HELLO_DONE;
964: this->state = STATE_HELLO_DONE;
965: this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
966: return NEED_MORE;
967: }
968:
969: /**
970: * Send Finished
971: */
972: static status_t send_finished(private_tls_server_t *this,
973: tls_handshake_type_t *type, bio_writer_t *writer)
974: {
975: char buf[12];
976:
977: if (!this->crypto->calculate_finished(this->crypto, "server finished", buf))
978: {
979: DBG1(DBG_TLS, "calculating server finished data failed");
980: this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
981: return FAILED;
982: }
983:
984: writer->write_data(writer, chunk_from_thing(buf));
985:
986: *type = TLS_FINISHED;
987: this->state = STATE_FINISHED_SENT;
988: this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
989:
990: return NEED_MORE;
991: }
992:
993: METHOD(tls_handshake_t, build, status_t,
994: private_tls_server_t *this, tls_handshake_type_t *type, bio_writer_t *writer)
995: {
996: diffie_hellman_group_t group;
997:
998: switch (this->state)
999: {
1000: case STATE_HELLO_RECEIVED:
1001: return send_server_hello(this, type, writer);
1002: case STATE_HELLO_SENT:
1003: return send_certificate(this, type, writer);
1004: case STATE_CERT_SENT:
1005: group = this->crypto->get_dh_group(this->crypto);
1006: if (group)
1007: {
1008: return send_server_key_exchange(this, type, writer, group);
1009: }
1010: /* otherwise fall through to next state */
1011: case STATE_KEY_EXCHANGE_SENT:
1012: return send_certificate_request(this, type, writer);
1013: case STATE_CERTREQ_SENT:
1014: return send_hello_done(this, type, writer);
1015: case STATE_CIPHERSPEC_CHANGED_OUT:
1016: return send_finished(this, type, writer);
1017: case STATE_FINISHED_SENT:
1018: return INVALID_STATE;
1019: default:
1020: return INVALID_STATE;
1021: }
1022: }
1023:
1024: METHOD(tls_handshake_t, cipherspec_changed, bool,
1025: private_tls_server_t *this, bool inbound)
1026: {
1027: if (inbound)
1028: {
1029: if (this->resume)
1030: {
1031: return this->state == STATE_FINISHED_SENT;
1032: }
1033: if (this->peer)
1034: {
1035: return this->state == STATE_CERT_VERIFY_RECEIVED;
1036: }
1037: return this->state == STATE_KEY_EXCHANGE_RECEIVED;
1038: }
1039: else
1040: {
1041: if (this->resume)
1042: {
1043: return this->state == STATE_HELLO_SENT;
1044: }
1045: return this->state == STATE_FINISHED_RECEIVED;
1046: }
1047: return FALSE;
1048: }
1049:
1050: METHOD(tls_handshake_t, change_cipherspec, void,
1051: private_tls_server_t *this, bool inbound)
1052: {
1053: this->crypto->change_cipher(this->crypto, inbound);
1054: if (inbound)
1055: {
1056: this->state = STATE_CIPHERSPEC_CHANGED_IN;
1057: }
1058: else
1059: {
1060: this->state = STATE_CIPHERSPEC_CHANGED_OUT;
1061: }
1062: }
1063:
1064: METHOD(tls_handshake_t, finished, bool,
1065: private_tls_server_t *this)
1066: {
1067: if (this->resume)
1068: {
1069: return this->state == STATE_FINISHED_RECEIVED;
1070: }
1071: return this->state == STATE_FINISHED_SENT;
1072: }
1073:
1074: METHOD(tls_handshake_t, get_peer_id, identification_t*,
1075: private_tls_server_t *this)
1076: {
1077: return this->peer;
1078: }
1079:
1080: METHOD(tls_handshake_t, get_server_id, identification_t*,
1081: private_tls_server_t *this)
1082: {
1083: return this->server;
1084: }
1085:
1086: METHOD(tls_handshake_t, get_auth, auth_cfg_t*,
1087: private_tls_server_t *this)
1088: {
1089: return this->peer_auth;
1090: }
1091:
1092: METHOD(tls_handshake_t, destroy, void,
1093: private_tls_server_t *this)
1094: {
1095: DESTROY_IF(this->private);
1096: DESTROY_IF(this->dh);
1097: DESTROY_IF(this->peer);
1098: this->server->destroy(this->server);
1099: this->peer_auth->destroy(this->peer_auth);
1100: this->server_auth->destroy(this->server_auth);
1101: free(this->hashsig.ptr);
1102: free(this->curves.ptr);
1103: free(this->session.ptr);
1104: free(this);
1105: }
1106:
1107: /**
1108: * See header
1109: */
1110: tls_server_t *tls_server_create(tls_t *tls,
1111: tls_crypto_t *crypto, tls_alert_t *alert,
1112: identification_t *server, identification_t *peer)
1113: {
1114: private_tls_server_t *this;
1115:
1116: INIT(this,
1117: .public = {
1118: .handshake = {
1119: .process = _process,
1120: .build = _build,
1121: .cipherspec_changed = _cipherspec_changed,
1122: .change_cipherspec = _change_cipherspec,
1123: .finished = _finished,
1124: .get_peer_id = _get_peer_id,
1125: .get_server_id = _get_server_id,
1126: .get_auth = _get_auth,
1127: .destroy = _destroy,
1128: },
1129: },
1130: .tls = tls,
1131: .crypto = crypto,
1132: .alert = alert,
1133: .server = server->clone(server),
1134: .peer = peer ? peer->clone(peer) : NULL,
1135: .state = STATE_INIT,
1136: .peer_auth = auth_cfg_create(),
1137: .server_auth = auth_cfg_create(),
1138: );
1139:
1140: return &this->public;
1141: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>