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