2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
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>.
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
19 #include <credentials/certificates/x509.h>
23 typedef struct private_tls_peer_t private_tls_peer_t
;
32 STATE_KEY_EXCHANGE_RECEIVED
,
33 STATE_CERTREQ_RECEIVED
,
34 STATE_KEY_EXCHANGE_SENT
,
36 STATE_CIPHERSPEC_CHANGED_OUT
,
38 STATE_CIPHERSPEC_CHANGED_IN
,
39 STATE_FINISHED_RECEIVED
,
43 * Private data of an tls_peer_t object.
45 struct private_tls_peer_t
{
48 * Public tls_peer_t interface.
68 * Peer identity, NULL for no client authentication
70 identification_t
*peer
;
75 identification_t
*server
;
83 * Hello random data selected by client
85 char client_random
[32];
88 * Hello random data selected by server
90 char server_random
[32];
93 * Auth helper for peer authentication
95 auth_cfg_t
*peer_auth
;
98 * Auth helper for server authentication
100 auth_cfg_t
*server_auth
;
105 private_key_t
*private;
110 diffie_hellman_t
*dh
;
113 * Resuming a session?
118 * TLS session identifier
123 * List of server-supported hashsig algorithms
128 * List of server-supported client certificate types
134 * Process a server hello message
136 static status_t
process_server_hello(private_tls_peer_t
*this,
137 bio_reader_t
*reader
)
139 u_int8_t compression
;
140 u_int16_t version
, cipher
;
141 chunk_t random
, session
, ext
= chunk_empty
;
142 tls_cipher_suite_t suite
= 0;
144 this->crypto
->append_handshake(this->crypto
,
145 TLS_SERVER_HELLO
, reader
->peek(reader
));
147 if (!reader
->read_uint16(reader
, &version
) ||
148 !reader
->read_data(reader
, sizeof(this->server_random
), &random
) ||
149 !reader
->read_data8(reader
, &session
) ||
150 !reader
->read_uint16(reader
, &cipher
) ||
151 !reader
->read_uint8(reader
, &compression
) ||
152 (reader
->remaining(reader
) && !reader
->read_data16(reader
, &ext
)))
154 DBG1(DBG_TLS
, "received invalid ServerHello");
155 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
159 memcpy(this->server_random
, random
.ptr
, sizeof(this->server_random
));
161 if (!this->tls
->set_version(this->tls
, version
))
163 DBG1(DBG_TLS
, "negotiated version %N not supported",
164 tls_version_names
, version
);
165 this->alert
->add(this->alert
, TLS_FATAL
, TLS_PROTOCOL_VERSION
);
169 if (chunk_equals(this->session
, session
))
171 suite
= this->crypto
->resume_session(this->crypto
, session
, this->server
,
172 chunk_from_thing(this->client_random
),
173 chunk_from_thing(this->server_random
));
176 DBG1(DBG_TLS
, "resumed %N using suite %N",
177 tls_version_names
, version
, tls_cipher_suite_names
, suite
);
184 if (!this->crypto
->select_cipher_suite(this->crypto
, &suite
, 1, KEY_ANY
))
186 DBG1(DBG_TLS
, "received TLS cipher suite %N inacceptable",
187 tls_cipher_suite_names
, suite
);
188 this->alert
->add(this->alert
, TLS_FATAL
, TLS_HANDSHAKE_FAILURE
);
191 DBG1(DBG_TLS
, "negotiated %N using suite %N",
192 tls_version_names
, version
, tls_cipher_suite_names
, suite
);
193 free(this->session
.ptr
);
194 this->session
= chunk_clone(session
);
196 this->state
= STATE_HELLO_RECEIVED
;
201 * Check if a server certificate is acceptable for the given server identity
203 static bool check_certificate(private_tls_peer_t
*this, certificate_t
*cert
)
205 identification_t
*id
;
207 if (cert
->has_subject(cert
, this->server
))
211 id
= cert
->get_subject(cert
);
212 if (id
->matches(id
, this->server
))
216 if (cert
->get_type(cert
) == CERT_X509
)
218 x509_t
*x509
= (x509_t
*)cert
;
219 enumerator_t
*enumerator
;
221 enumerator
= x509
->create_subjectAltName_enumerator(x509
);
222 while (enumerator
->enumerate(enumerator
, &id
))
224 if (id
->matches(id
, this->server
))
226 enumerator
->destroy(enumerator
);
230 enumerator
->destroy(enumerator
);
232 DBG1(DBG_TLS
, "server certificate does not match to '%Y'", this->server
);
237 * Process a Certificate message
239 static status_t
process_certificate(private_tls_peer_t
*this,
240 bio_reader_t
*reader
)
247 this->crypto
->append_handshake(this->crypto
,
248 TLS_CERTIFICATE
, reader
->peek(reader
));
250 if (!reader
->read_data24(reader
, &data
))
252 DBG1(DBG_TLS
, "certificate message header invalid");
253 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
256 certs
= bio_reader_create(data
);
257 while (certs
->remaining(certs
))
259 if (!certs
->read_data24(certs
, &data
))
261 DBG1(DBG_TLS
, "certificate message invalid");
262 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
263 certs
->destroy(certs
);
266 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, CERT_X509
,
267 BUILD_BLOB_ASN1_DER
, data
, BUILD_END
);
272 if (!check_certificate(this, cert
))
275 certs
->destroy(certs
);
276 this->alert
->add(this->alert
, TLS_FATAL
, TLS_ACCESS_DENIED
);
279 this->server_auth
->add(this->server_auth
,
280 AUTH_HELPER_SUBJECT_CERT
, cert
);
281 DBG1(DBG_TLS
, "received TLS server certificate '%Y'",
282 cert
->get_subject(cert
));
287 DBG1(DBG_TLS
, "received TLS intermediate certificate '%Y'",
288 cert
->get_subject(cert
));
289 this->server_auth
->add(this->server_auth
,
290 AUTH_HELPER_IM_CERT
, cert
);
295 DBG1(DBG_TLS
, "parsing TLS certificate failed, skipped");
296 this->alert
->add(this->alert
, TLS_WARNING
, TLS_BAD_CERTIFICATE
);
299 certs
->destroy(certs
);
300 this->state
= STATE_CERT_RECEIVED
;
305 * Find a trusted public key to encrypt/verify key exchange data
307 static public_key_t
*find_public_key(private_tls_peer_t
*this)
309 public_key_t
*public = NULL
, *current
;
311 enumerator_t
*enumerator
;
314 cert
= this->server_auth
->get(this->server_auth
, AUTH_HELPER_SUBJECT_CERT
);
317 enumerator
= lib
->credmgr
->create_public_enumerator(lib
->credmgr
,
318 KEY_ANY
, cert
->get_subject(cert
), this->server_auth
);
319 while (enumerator
->enumerate(enumerator
, ¤t
, &auth
))
321 public = current
->get_ref(current
);
324 enumerator
->destroy(enumerator
);
330 * Process a Key Exchange message using MODP Diffie Hellman
332 static status_t
process_modp_key_exchange(private_tls_peer_t
*this,
333 bio_reader_t
*reader
)
335 chunk_t prime
, generator
, pub
, chunk
;
336 public_key_t
*public;
338 chunk
= reader
->peek(reader
);
339 if (!reader
->read_data16(reader
, &prime
) ||
340 !reader
->read_data16(reader
, &generator
) ||
341 !reader
->read_data16(reader
, &pub
))
343 DBG1(DBG_TLS
, "received invalid Server Key Exchange");
344 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
347 public = find_public_key(this);
350 DBG1(DBG_TLS
, "no TLS public key found for server '%Y'", this->server
);
351 this->alert
->add(this->alert
, TLS_FATAL
, TLS_CERTIFICATE_UNKNOWN
);
355 chunk
.len
= 2 + prime
.len
+ 2 + generator
.len
+ 2 + pub
.len
;
356 chunk
= chunk_cat("ccc", chunk_from_thing(this->client_random
),
357 chunk_from_thing(this->server_random
), chunk
);
358 if (!this->crypto
->verify(this->crypto
, public, reader
, chunk
))
360 public->destroy(public);
362 DBG1(DBG_TLS
, "verifying DH parameters failed");
363 this->alert
->add(this->alert
, TLS_FATAL
, TLS_BAD_CERTIFICATE
);
366 public->destroy(public);
369 this->dh
= lib
->crypto
->create_dh(lib
->crypto
, MODP_CUSTOM
,
373 DBG1(DBG_TLS
, "custom DH parameters not supported");
374 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
377 this->dh
->set_other_public_value(this->dh
, pub
);
379 this->state
= STATE_KEY_EXCHANGE_RECEIVED
;
384 * Get the EC group for a TLS named curve
386 static diffie_hellman_group_t
curve_to_ec_group(private_tls_peer_t
*this,
387 tls_named_curve_t curve
)
389 diffie_hellman_group_t group
;
390 tls_named_curve_t current
;
391 enumerator_t
*enumerator
;
393 enumerator
= this->crypto
->create_ec_enumerator(this->crypto
);
394 while (enumerator
->enumerate(enumerator
, &group
, ¤t
))
396 if (current
== curve
)
398 enumerator
->destroy(enumerator
);
402 enumerator
->destroy(enumerator
);
407 * Process a Key Exchange message using EC Diffie Hellman
409 static status_t
process_ec_key_exchange(private_tls_peer_t
*this,
410 bio_reader_t
*reader
)
412 diffie_hellman_group_t group
;
413 public_key_t
*public;
418 chunk
= reader
->peek(reader
);
419 if (!reader
->read_uint8(reader
, &type
))
421 DBG1(DBG_TLS
, "received invalid Server Key Exchange");
422 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
425 if (type
!= TLS_ECC_NAMED_CURVE
)
427 DBG1(DBG_TLS
, "ECDH curve type %N not supported",
428 tls_ecc_curve_type_names
, type
);
429 this->alert
->add(this->alert
, TLS_FATAL
, TLS_HANDSHAKE_FAILURE
);
432 if (!reader
->read_uint16(reader
, &curve
) ||
433 !reader
->read_data8(reader
, &pub
) || pub
.len
== 0)
435 DBG1(DBG_TLS
, "received invalid Server Key Exchange");
436 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
440 group
= curve_to_ec_group(this, curve
);
443 DBG1(DBG_TLS
, "ECDH curve %N not supported",
444 tls_named_curve_names
, curve
);
445 this->alert
->add(this->alert
, TLS_FATAL
, TLS_HANDSHAKE_FAILURE
);
449 public = find_public_key(this);
452 DBG1(DBG_TLS
, "no TLS public key found for server '%Y'", this->server
);
453 this->alert
->add(this->alert
, TLS_FATAL
, TLS_CERTIFICATE_UNKNOWN
);
457 chunk
.len
= 4 + pub
.len
;
458 chunk
= chunk_cat("ccc", chunk_from_thing(this->client_random
),
459 chunk_from_thing(this->server_random
), chunk
);
460 if (!this->crypto
->verify(this->crypto
, public, reader
, chunk
))
462 public->destroy(public);
464 DBG1(DBG_TLS
, "verifying DH parameters failed");
465 this->alert
->add(this->alert
, TLS_FATAL
, TLS_BAD_CERTIFICATE
);
468 public->destroy(public);
471 this->dh
= lib
->crypto
->create_dh(lib
->crypto
, group
);
474 DBG1(DBG_TLS
, "DH group %N not supported",
475 diffie_hellman_group_names
, group
);
476 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
480 if (pub
.ptr
[0] != TLS_ANSI_UNCOMPRESSED
)
482 DBG1(DBG_TLS
, "DH point format '%N' not supported",
483 tls_ansi_point_format_names
, pub
.ptr
[0]);
484 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
487 this->dh
->set_other_public_value(this->dh
, chunk_skip(pub
, 1));
489 this->state
= STATE_KEY_EXCHANGE_RECEIVED
;
494 * Process a Server Key Exchange
496 static status_t
process_key_exchange(private_tls_peer_t
*this,
497 bio_reader_t
*reader
)
499 diffie_hellman_group_t group
;
501 this->crypto
->append_handshake(this->crypto
,
502 TLS_SERVER_KEY_EXCHANGE
, reader
->peek(reader
));
504 group
= this->crypto
->get_dh_group(this->crypto
);
505 if (group
== MODP_NONE
)
507 DBG1(DBG_TLS
, "received Server Key Exchange, but not required "
508 "for current suite");
509 this->alert
->add(this->alert
, TLS_FATAL
, TLS_HANDSHAKE_FAILURE
);
512 if (diffie_hellman_group_is_ec(group
))
514 return process_ec_key_exchange(this, reader
);
516 return process_modp_key_exchange(this, reader
);
520 * Process a Certificate Request message
522 static status_t
process_certreq(private_tls_peer_t
*this, bio_reader_t
*reader
)
524 chunk_t types
, hashsig
, data
;
525 bio_reader_t
*authorities
;
526 identification_t
*id
;
531 DBG1(DBG_TLS
, "server requested a certificate, but client "
532 "authentication disabled");
534 this->crypto
->append_handshake(this->crypto
,
535 TLS_CERTIFICATE_REQUEST
, reader
->peek(reader
));
537 if (!reader
->read_data8(reader
, &types
))
539 DBG1(DBG_TLS
, "certreq message header invalid");
540 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
543 this->cert_types
= chunk_clone(types
);
544 if (this->tls
->get_version(this->tls
) >= TLS_1_2
)
546 if (!reader
->read_data16(reader
, &hashsig
))
548 DBG1(DBG_TLS
, "certreq message invalid");
549 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
552 this->hashsig
= chunk_clone(hashsig
);
554 if (!reader
->read_data16(reader
, &data
))
556 DBG1(DBG_TLS
, "certreq message invalid");
557 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
560 authorities
= bio_reader_create(data
);
561 while (authorities
->remaining(authorities
))
563 if (!authorities
->read_data16(authorities
, &data
))
565 DBG1(DBG_TLS
, "certreq message invalid");
566 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
567 authorities
->destroy(authorities
);
572 id
= identification_create_from_encoding(ID_DER_ASN1_DN
, data
);
573 cert
= lib
->credmgr
->get_cert(lib
->credmgr
,
574 CERT_X509
, KEY_ANY
, id
, TRUE
);
577 DBG1(DBG_TLS
, "received TLS cert request for '%Y", id
);
578 this->peer_auth
->add(this->peer_auth
, AUTH_RULE_CA_CERT
, cert
);
582 DBG1(DBG_TLS
, "received TLS cert request for unknown CA '%Y'", id
);
587 authorities
->destroy(authorities
);
588 this->state
= STATE_CERTREQ_RECEIVED
;
593 * Process Hello Done message
595 static status_t
process_hello_done(private_tls_peer_t
*this,
596 bio_reader_t
*reader
)
598 this->crypto
->append_handshake(this->crypto
,
599 TLS_SERVER_HELLO_DONE
, reader
->peek(reader
));
600 this->state
= STATE_HELLO_DONE
;
605 * Process finished message
607 static status_t
process_finished(private_tls_peer_t
*this, bio_reader_t
*reader
)
612 if (!reader
->read_data(reader
, sizeof(buf
), &received
))
614 DBG1(DBG_TLS
, "received server finished too short");
615 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
618 if (!this->crypto
->calculate_finished(this->crypto
, "server finished", buf
))
620 DBG1(DBG_TLS
, "calculating server finished failed");
621 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
624 if (!chunk_equals(received
, chunk_from_thing(buf
)))
626 DBG1(DBG_TLS
, "received server finished invalid");
627 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECRYPT_ERROR
);
630 this->state
= STATE_FINISHED_RECEIVED
;
631 this->crypto
->append_handshake(this->crypto
, TLS_FINISHED
, received
);
636 METHOD(tls_handshake_t
, process
, status_t
,
637 private_tls_peer_t
*this, tls_handshake_type_t type
, bio_reader_t
*reader
)
639 tls_handshake_type_t expected
;
643 case STATE_HELLO_SENT
:
644 if (type
== TLS_SERVER_HELLO
)
646 return process_server_hello(this, reader
);
648 expected
= TLS_SERVER_HELLO
;
650 case STATE_HELLO_RECEIVED
:
651 if (type
== TLS_CERTIFICATE
)
653 return process_certificate(this, reader
);
655 expected
= TLS_CERTIFICATE
;
657 case STATE_CERT_RECEIVED
:
658 if (type
== TLS_SERVER_KEY_EXCHANGE
)
660 return process_key_exchange(this, reader
);
662 /* fall through since TLS_SERVER_KEY_EXCHANGE is optional */
663 case STATE_KEY_EXCHANGE_RECEIVED
:
664 if (type
== TLS_CERTIFICATE_REQUEST
)
666 return process_certreq(this, reader
);
669 /* fall through since TLS_CERTIFICATE_REQUEST is optional */
670 case STATE_CERTREQ_RECEIVED
:
671 if (type
== TLS_SERVER_HELLO_DONE
)
673 return process_hello_done(this, reader
);
675 expected
= TLS_SERVER_HELLO_DONE
;
677 case STATE_CIPHERSPEC_CHANGED_IN
:
678 if (type
== TLS_FINISHED
)
680 return process_finished(this, reader
);
682 expected
= TLS_FINISHED
;
685 DBG1(DBG_TLS
, "TLS %N not expected in current state",
686 tls_handshake_type_names
, type
);
687 this->alert
->add(this->alert
, TLS_FATAL
, TLS_UNEXPECTED_MESSAGE
);
690 DBG1(DBG_TLS
, "TLS %N expected, but received %N",
691 tls_handshake_type_names
, expected
, tls_handshake_type_names
, type
);
692 this->alert
->add(this->alert
, TLS_FATAL
, TLS_UNEXPECTED_MESSAGE
);
697 * Send a client hello
699 static status_t
send_client_hello(private_tls_peer_t
*this,
700 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
702 tls_cipher_suite_t
*suites
;
703 bio_writer_t
*extensions
, *curves
= NULL
;
704 tls_version_t version
;
705 tls_named_curve_t curve
;
706 enumerator_t
*enumerator
;
710 htoun32(&this->client_random
, time(NULL
));
711 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_WEAK
);
713 !rng
->get_bytes(rng
, sizeof(this->client_random
) - 4,
714 this->client_random
+ 4))
716 DBG1(DBG_TLS
, "failed to generate client random");
717 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
724 version
= this->tls
->get_version(this->tls
);
725 writer
->write_uint16(writer
, version
);
726 writer
->write_data(writer
, chunk_from_thing(this->client_random
));
728 /* session identifier */
729 this->session
= this->crypto
->get_session(this->crypto
, this->server
);
730 writer
->write_data8(writer
, this->session
);
732 /* add TLS cipher suites */
733 count
= this->crypto
->get_cipher_suites(this->crypto
, &suites
);
734 writer
->write_uint16(writer
, count
* 2);
735 for (i
= 0; i
< count
; i
++)
737 writer
->write_uint16(writer
, suites
[i
]);
740 /* NULL compression only */
741 writer
->write_uint8(writer
, 1);
742 writer
->write_uint8(writer
, 0);
744 extensions
= bio_writer_create(32);
746 extensions
->write_uint16(extensions
, TLS_EXT_SIGNATURE_ALGORITHMS
);
747 this->crypto
->get_signature_algorithms(this->crypto
, extensions
);
749 /* add supported Elliptic Curves, if any */
750 enumerator
= this->crypto
->create_ec_enumerator(this->crypto
);
751 while (enumerator
->enumerate(enumerator
, NULL
, &curve
))
755 extensions
->write_uint16(extensions
, TLS_EXT_ELLIPTIC_CURVES
);
756 curves
= bio_writer_create(16);
758 curves
->write_uint16(curves
, curve
);
760 enumerator
->destroy(enumerator
);
763 extensions
->write_data16(extensions
, curves
->get_buf(curves
));
764 curves
->destroy(curves
);
766 /* if we support curves, add point format extension */
767 extensions
->write_uint16(extensions
, TLS_EXT_EC_POINT_FORMATS
);
768 extensions
->write_uint16(extensions
, 2);
769 extensions
->write_uint8(extensions
, 1);
770 extensions
->write_uint8(extensions
, TLS_EC_POINT_UNCOMPRESSED
);
772 if (this->server
->get_type(this->server
) == ID_FQDN
)
776 DBG2(DBG_TLS
, "sending Server Name Indication for '%Y'", this->server
);
778 names
= bio_writer_create(8);
779 names
->write_uint8(names
, TLS_NAME_TYPE_HOST_NAME
);
780 names
->write_data16(names
, this->server
->get_encoding(this->server
));
781 names
->wrap16(names
);
782 extensions
->write_uint16(extensions
, TLS_EXT_SERVER_NAME
);
783 extensions
->write_data16(extensions
, names
->get_buf(names
));
784 names
->destroy(names
);
787 writer
->write_data16(writer
, extensions
->get_buf(extensions
));
788 extensions
->destroy(extensions
);
790 *type
= TLS_CLIENT_HELLO
;
791 this->state
= STATE_HELLO_SENT
;
792 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
797 * Find a private key suitable to sign Certificate Verify
799 static private_key_t
*find_private_key(private_tls_peer_t
*this)
801 private_key_t
*key
= NULL
;
802 bio_reader_t
*reader
;
810 reader
= bio_reader_create(this->cert_types
);
811 while (reader
->remaining(reader
) && reader
->read_uint8(reader
, &cert
))
824 key
= lib
->credmgr
->get_private(lib
->credmgr
, type
,
825 this->peer
, this->peer_auth
);
831 reader
->destroy(reader
);
838 static status_t
send_certificate(private_tls_peer_t
*this,
839 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
841 enumerator_t
*enumerator
;
847 this->private = find_private_key(this);
850 DBG1(DBG_TLS
, "no TLS peer certificate found for '%Y', "
851 "skipping client authentication", this->peer
);
855 /* generate certificate payload */
856 certs
= bio_writer_create(256);
859 cert
= this->peer_auth
->get(this->peer_auth
, AUTH_RULE_SUBJECT_CERT
);
862 if (cert
->get_encoding(cert
, CERT_ASN1_DER
, &data
))
864 DBG1(DBG_TLS
, "sending TLS peer certificate '%Y'",
865 cert
->get_subject(cert
));
866 certs
->write_data24(certs
, data
);
870 enumerator
= this->peer_auth
->create_enumerator(this->peer_auth
);
871 while (enumerator
->enumerate(enumerator
, &rule
, &cert
))
873 if (rule
== AUTH_RULE_IM_CERT
)
875 if (cert
->get_encoding(cert
, CERT_ASN1_DER
, &data
))
877 DBG1(DBG_TLS
, "sending TLS intermediate certificate '%Y'",
878 cert
->get_subject(cert
));
879 certs
->write_data24(certs
, data
);
884 enumerator
->destroy(enumerator
);
887 writer
->write_data24(writer
, certs
->get_buf(certs
));
888 certs
->destroy(certs
);
890 *type
= TLS_CERTIFICATE
;
891 this->state
= STATE_CERT_SENT
;
892 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
897 * Send client key exchange, using premaster encryption
899 static status_t
send_key_exchange_encrypt(private_tls_peer_t
*this,
900 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
902 public_key_t
*public;
907 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_STRONG
);
908 if (!rng
|| !rng
->get_bytes(rng
, sizeof(premaster
) - 2, premaster
+ 2))
910 DBG1(DBG_TLS
, "failed to generate TLS premaster secret");
911 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
916 htoun16(premaster
, TLS_1_2
);
918 if (!this->crypto
->derive_secrets(this->crypto
, chunk_from_thing(premaster
),
919 this->session
, this->server
,
920 chunk_from_thing(this->client_random
),
921 chunk_from_thing(this->server_random
)))
923 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
927 public = find_public_key(this);
930 DBG1(DBG_TLS
, "no TLS public key found for server '%Y'", this->server
);
931 this->alert
->add(this->alert
, TLS_FATAL
, TLS_CERTIFICATE_UNKNOWN
);
934 if (!public->encrypt(public, ENCRYPT_RSA_PKCS1
,
935 chunk_from_thing(premaster
), &encrypted
))
937 public->destroy(public);
938 DBG1(DBG_TLS
, "encrypting TLS premaster secret failed");
939 this->alert
->add(this->alert
, TLS_FATAL
, TLS_BAD_CERTIFICATE
);
942 public->destroy(public);
944 writer
->write_data16(writer
, encrypted
);
947 *type
= TLS_CLIENT_KEY_EXCHANGE
;
948 this->state
= STATE_KEY_EXCHANGE_SENT
;
949 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
954 * Send client key exchange, using DHE exchange
956 static status_t
send_key_exchange_dhe(private_tls_peer_t
*this,
957 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
959 chunk_t premaster
, pub
;
961 if (this->dh
->get_shared_secret(this->dh
, &premaster
) != SUCCESS
)
963 DBG1(DBG_TLS
, "calculating premaster from DH failed");
964 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
967 if (!this->crypto
->derive_secrets(this->crypto
, premaster
,
968 this->session
, this->server
,
969 chunk_from_thing(this->client_random
),
970 chunk_from_thing(this->server_random
)))
972 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
973 chunk_clear(&premaster
);
976 chunk_clear(&premaster
);
978 this->dh
->get_my_public_value(this->dh
, &pub
);
979 if (this->dh
->get_dh_group(this->dh
) == MODP_CUSTOM
)
981 writer
->write_data16(writer
, pub
);
984 { /* ECP uses 8bit length header only, but a point format */
985 writer
->write_uint8(writer
, pub
.len
+ 1);
986 writer
->write_uint8(writer
, TLS_ANSI_UNCOMPRESSED
);
987 writer
->write_data(writer
, pub
);
991 *type
= TLS_CLIENT_KEY_EXCHANGE
;
992 this->state
= STATE_KEY_EXCHANGE_SENT
;
993 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
998 * Send client key exchange, depending on suite
1000 static status_t
send_key_exchange(private_tls_peer_t
*this,
1001 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
1005 return send_key_exchange_dhe(this, type
, writer
);
1007 return send_key_exchange_encrypt(this, type
, writer
);
1011 * Send certificate verify
1013 static status_t
send_certificate_verify(private_tls_peer_t
*this,
1014 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
1016 if (!this->private ||
1017 !this->crypto
->sign_handshake(this->crypto
, this->private,
1018 writer
, this->hashsig
))
1020 DBG1(DBG_TLS
, "creating TLS Certificate Verify signature failed");
1021 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
1025 *type
= TLS_CERTIFICATE_VERIFY
;
1026 this->state
= STATE_VERIFY_SENT
;
1027 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
1034 static status_t
send_finished(private_tls_peer_t
*this,
1035 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
1039 if (!this->crypto
->calculate_finished(this->crypto
, "client finished", buf
))
1041 DBG1(DBG_TLS
, "calculating client finished data failed");
1042 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
1046 writer
->write_data(writer
, chunk_from_thing(buf
));
1048 *type
= TLS_FINISHED
;
1049 this->state
= STATE_FINISHED_SENT
;
1050 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
1054 METHOD(tls_handshake_t
, build
, status_t
,
1055 private_tls_peer_t
*this, tls_handshake_type_t
*type
, bio_writer_t
*writer
)
1057 switch (this->state
)
1060 return send_client_hello(this, type
, writer
);
1061 case STATE_HELLO_DONE
:
1064 return send_certificate(this, type
, writer
);
1066 /* otherwise fall through to next state */
1067 case STATE_CERT_SENT
:
1068 return send_key_exchange(this, type
, writer
);
1069 case STATE_KEY_EXCHANGE_SENT
:
1072 return send_certificate_verify(this, type
, writer
);
1076 return INVALID_STATE
;
1078 case STATE_CIPHERSPEC_CHANGED_OUT
:
1079 return send_finished(this, type
, writer
);
1081 return INVALID_STATE
;
1085 METHOD(tls_handshake_t
, cipherspec_changed
, bool,
1086 private_tls_peer_t
*this, bool inbound
)
1092 return this->state
== STATE_HELLO_RECEIVED
;
1094 return this->state
== STATE_FINISHED_SENT
;
1100 return this->state
== STATE_FINISHED_RECEIVED
;
1104 return this->state
== STATE_VERIFY_SENT
;
1106 return this->state
== STATE_KEY_EXCHANGE_SENT
;
1110 METHOD(tls_handshake_t
, change_cipherspec
, void,
1111 private_tls_peer_t
*this, bool inbound
)
1113 this->crypto
->change_cipher(this->crypto
, inbound
);
1116 this->state
= STATE_CIPHERSPEC_CHANGED_IN
;
1120 this->state
= STATE_CIPHERSPEC_CHANGED_OUT
;
1124 METHOD(tls_handshake_t
, finished
, bool,
1125 private_tls_peer_t
*this)
1129 return this->state
== STATE_FINISHED_SENT
;
1131 return this->state
== STATE_FINISHED_RECEIVED
;
1134 METHOD(tls_handshake_t
, destroy
, void,
1135 private_tls_peer_t
*this)
1137 DESTROY_IF(this->private);
1138 DESTROY_IF(this->dh
);
1139 this->peer_auth
->destroy(this->peer_auth
);
1140 this->server_auth
->destroy(this->server_auth
);
1141 free(this->hashsig
.ptr
);
1142 free(this->cert_types
.ptr
);
1143 free(this->session
.ptr
);
1150 tls_peer_t
*tls_peer_create(tls_t
*tls
, tls_crypto_t
*crypto
, tls_alert_t
*alert
,
1151 identification_t
*peer
, identification_t
*server
)
1153 private_tls_peer_t
*this;
1158 .process
= _process
,
1160 .cipherspec_changed
= _cipherspec_changed
,
1161 .change_cipherspec
= _change_cipherspec
,
1162 .finished
= _finished
,
1163 .destroy
= _destroy
,
1166 .state
= STATE_INIT
,
1172 .peer_auth
= auth_cfg_create(),
1173 .server_auth
= auth_cfg_create(),
1176 return &this->public;