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
,
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 * List of server-supported hashsig algorithms
118 * List of server-supported client certificate types
124 * Process a server hello message
126 static status_t
process_server_hello(private_tls_peer_t
*this,
127 bio_reader_t
*reader
)
129 u_int8_t compression
;
130 u_int16_t version
, cipher
;
131 chunk_t random
, session
, ext
= chunk_empty
;
132 tls_cipher_suite_t suite
;
134 this->crypto
->append_handshake(this->crypto
,
135 TLS_SERVER_HELLO
, reader
->peek(reader
));
137 if (!reader
->read_uint16(reader
, &version
) ||
138 !reader
->read_data(reader
, sizeof(this->server_random
), &random
) ||
139 !reader
->read_data8(reader
, &session
) ||
140 !reader
->read_uint16(reader
, &cipher
) ||
141 !reader
->read_uint8(reader
, &compression
) ||
142 (reader
->remaining(reader
) && !reader
->read_data16(reader
, &ext
)))
144 DBG1(DBG_TLS
, "received invalid ServerHello");
145 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
149 memcpy(this->server_random
, random
.ptr
, sizeof(this->server_random
));
151 if (!this->tls
->set_version(this->tls
, version
))
153 DBG1(DBG_TLS
, "negotiated version %N not supported",
154 tls_version_names
, version
);
155 this->alert
->add(this->alert
, TLS_FATAL
, TLS_PROTOCOL_VERSION
);
159 if (!this->crypto
->select_cipher_suite(this->crypto
, &suite
, 1, KEY_ANY
))
161 DBG1(DBG_TLS
, "received TLS cipher suite %N inacceptable",
162 tls_cipher_suite_names
, suite
);
163 this->alert
->add(this->alert
, TLS_FATAL
, TLS_HANDSHAKE_FAILURE
);
166 DBG1(DBG_TLS
, "negotiated TLS version %N with suite %N",
167 tls_version_names
, version
, tls_cipher_suite_names
, suite
);
168 this->state
= STATE_HELLO_RECEIVED
;
173 * Check if a server certificate is acceptable for the given server identity
175 static bool check_certificate(private_tls_peer_t
*this, certificate_t
*cert
)
177 identification_t
*id
;
179 if (cert
->has_subject(cert
, this->server
))
183 id
= cert
->get_subject(cert
);
184 if (id
->matches(id
, this->server
))
188 if (cert
->get_type(cert
) == CERT_X509
)
190 x509_t
*x509
= (x509_t
*)cert
;
191 enumerator_t
*enumerator
;
193 enumerator
= x509
->create_subjectAltName_enumerator(x509
);
194 while (enumerator
->enumerate(enumerator
, &id
))
196 if (id
->matches(id
, this->server
))
198 enumerator
->destroy(enumerator
);
202 enumerator
->destroy(enumerator
);
204 DBG1(DBG_TLS
, "server certificate does not match to '%Y'", this->server
);
209 * Process a Certificate message
211 static status_t
process_certificate(private_tls_peer_t
*this,
212 bio_reader_t
*reader
)
219 this->crypto
->append_handshake(this->crypto
,
220 TLS_CERTIFICATE
, reader
->peek(reader
));
222 if (!reader
->read_data24(reader
, &data
))
224 DBG1(DBG_TLS
, "certificate message header invalid");
225 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
228 certs
= bio_reader_create(data
);
229 while (certs
->remaining(certs
))
231 if (!certs
->read_data24(certs
, &data
))
233 DBG1(DBG_TLS
, "certificate message invalid");
234 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
235 certs
->destroy(certs
);
238 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, CERT_X509
,
239 BUILD_BLOB_ASN1_DER
, data
, BUILD_END
);
244 if (!check_certificate(this, cert
))
247 certs
->destroy(certs
);
248 this->alert
->add(this->alert
, TLS_FATAL
, TLS_ACCESS_DENIED
);
251 this->server_auth
->add(this->server_auth
,
252 AUTH_HELPER_SUBJECT_CERT
, cert
);
253 DBG1(DBG_TLS
, "received TLS server certificate '%Y'",
254 cert
->get_subject(cert
));
259 DBG1(DBG_TLS
, "received TLS intermediate certificate '%Y'",
260 cert
->get_subject(cert
));
261 this->server_auth
->add(this->server_auth
,
262 AUTH_HELPER_IM_CERT
, cert
);
267 DBG1(DBG_TLS
, "parsing TLS certificate failed, skipped");
268 this->alert
->add(this->alert
, TLS_WARNING
, TLS_BAD_CERTIFICATE
);
271 certs
->destroy(certs
);
272 this->state
= STATE_CERT_RECEIVED
;
277 * Find a trusted public key to encrypt/verify key exchange data
279 static public_key_t
*find_public_key(private_tls_peer_t
*this)
281 public_key_t
*public = NULL
, *current
;
283 enumerator_t
*enumerator
;
286 cert
= this->server_auth
->get(this->server_auth
, AUTH_HELPER_SUBJECT_CERT
);
289 enumerator
= lib
->credmgr
->create_public_enumerator(lib
->credmgr
,
290 KEY_ANY
, cert
->get_subject(cert
), this->server_auth
);
291 while (enumerator
->enumerate(enumerator
, ¤t
, &auth
))
293 public = current
->get_ref(current
);
296 enumerator
->destroy(enumerator
);
302 * Process a Key Exchange message using MODP Diffie Hellman
304 static status_t
process_modp_key_exchange(private_tls_peer_t
*this,
305 bio_reader_t
*reader
)
307 chunk_t prime
, generator
, pub
, chunk
;
308 public_key_t
*public;
310 chunk
= reader
->peek(reader
);
311 if (!reader
->read_data16(reader
, &prime
) ||
312 !reader
->read_data16(reader
, &generator
) ||
313 !reader
->read_data16(reader
, &pub
))
315 DBG1(DBG_TLS
, "received invalid Server Key Exchange");
316 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
319 public = find_public_key(this);
322 DBG1(DBG_TLS
, "no TLS public key found for server '%Y'", this->server
);
323 this->alert
->add(this->alert
, TLS_FATAL
, TLS_CERTIFICATE_UNKNOWN
);
327 chunk
.len
= 2 + prime
.len
+ 2 + generator
.len
+ 2 + pub
.len
;
328 chunk
= chunk_cat("ccc", chunk_from_thing(this->client_random
),
329 chunk_from_thing(this->server_random
), chunk
);
330 if (!this->crypto
->verify(this->crypto
, public, reader
, chunk
))
332 public->destroy(public);
334 DBG1(DBG_TLS
, "verifying DH parameters failed");
335 this->alert
->add(this->alert
, TLS_FATAL
, TLS_BAD_CERTIFICATE
);
338 public->destroy(public);
341 this->dh
= lib
->crypto
->create_dh(lib
->crypto
, MODP_CUSTOM
,
345 DBG1(DBG_TLS
, "custom DH parameters not supported");
346 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
349 this->dh
->set_other_public_value(this->dh
, pub
);
351 this->state
= STATE_KEY_EXCHANGE_RECEIVED
;
356 * Get the EC group for a TLS named curve
358 static diffie_hellman_group_t
curve_to_ec_group(private_tls_peer_t
*this,
359 tls_named_curve_t curve
)
361 diffie_hellman_group_t group
;
362 tls_named_curve_t current
;
363 enumerator_t
*enumerator
;
365 enumerator
= this->crypto
->create_ec_enumerator(this->crypto
);
366 while (enumerator
->enumerate(enumerator
, &group
, ¤t
))
368 if (current
== curve
)
370 enumerator
->destroy(enumerator
);
374 enumerator
->destroy(enumerator
);
379 * Process a Key Exchange message using EC Diffie Hellman
381 static status_t
process_ec_key_exchange(private_tls_peer_t
*this,
382 bio_reader_t
*reader
)
384 diffie_hellman_group_t group
;
385 public_key_t
*public;
390 chunk
= reader
->peek(reader
);
391 if (!reader
->read_uint8(reader
, &type
))
393 DBG1(DBG_TLS
, "received invalid Server Key Exchange");
394 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
397 if (type
!= TLS_ECC_NAMED_CURVE
)
399 DBG1(DBG_TLS
, "ECDH curve type %N not supported",
400 tls_ecc_curve_type_names
, type
);
401 this->alert
->add(this->alert
, TLS_FATAL
, TLS_HANDSHAKE_FAILURE
);
404 if (!reader
->read_uint16(reader
, &curve
) ||
405 !reader
->read_data8(reader
, &pub
) || pub
.len
== 0)
407 DBG1(DBG_TLS
, "received invalid Server Key Exchange");
408 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
412 group
= curve_to_ec_group(this, curve
);
415 DBG1(DBG_TLS
, "ECDH curve %N not supported",
416 tls_named_curve_names
, curve
);
417 this->alert
->add(this->alert
, TLS_FATAL
, TLS_HANDSHAKE_FAILURE
);
421 public = find_public_key(this);
424 DBG1(DBG_TLS
, "no TLS public key found for server '%Y'", this->server
);
425 this->alert
->add(this->alert
, TLS_FATAL
, TLS_CERTIFICATE_UNKNOWN
);
429 chunk
.len
= 4 + pub
.len
;
430 chunk
= chunk_cat("ccc", chunk_from_thing(this->client_random
),
431 chunk_from_thing(this->server_random
), chunk
);
432 if (!this->crypto
->verify(this->crypto
, public, reader
, chunk
))
434 public->destroy(public);
436 DBG1(DBG_TLS
, "verifying DH parameters failed");
437 this->alert
->add(this->alert
, TLS_FATAL
, TLS_BAD_CERTIFICATE
);
440 public->destroy(public);
443 this->dh
= lib
->crypto
->create_dh(lib
->crypto
, group
);
446 DBG1(DBG_TLS
, "DH group %N not supported",
447 diffie_hellman_group_names
, group
);
448 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
452 if (pub
.ptr
[0] != TLS_ANSI_UNCOMPRESSED
)
454 DBG1(DBG_TLS
, "DH point format '%N' not supported",
455 tls_ansi_point_format_names
, pub
.ptr
[0]);
456 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
459 this->dh
->set_other_public_value(this->dh
, chunk_skip(pub
, 1));
461 this->state
= STATE_KEY_EXCHANGE_RECEIVED
;
466 * Process a Server Key Exchange
468 static status_t
process_key_exchange(private_tls_peer_t
*this,
469 bio_reader_t
*reader
)
471 diffie_hellman_group_t group
;
473 this->crypto
->append_handshake(this->crypto
,
474 TLS_SERVER_KEY_EXCHANGE
, reader
->peek(reader
));
476 group
= this->crypto
->get_dh_group(this->crypto
);
477 if (group
== MODP_NONE
)
479 DBG1(DBG_TLS
, "received Server Key Exchange, but not required "
480 "for current suite");
481 this->alert
->add(this->alert
, TLS_FATAL
, TLS_HANDSHAKE_FAILURE
);
484 if (diffie_hellman_group_is_ec(group
))
486 return process_ec_key_exchange(this, reader
);
488 return process_modp_key_exchange(this, reader
);
492 * Process a Certificate Request message
494 static status_t
process_certreq(private_tls_peer_t
*this, bio_reader_t
*reader
)
496 chunk_t types
, hashsig
, data
;
497 bio_reader_t
*authorities
;
498 identification_t
*id
;
503 DBG1(DBG_TLS
, "server requested a certificate, but client "
504 "authentication disabled");
506 this->crypto
->append_handshake(this->crypto
,
507 TLS_CERTIFICATE_REQUEST
, reader
->peek(reader
));
509 if (!reader
->read_data8(reader
, &types
))
511 DBG1(DBG_TLS
, "certreq message header invalid");
512 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
515 this->cert_types
= chunk_clone(types
);
516 if (this->tls
->get_version(this->tls
) >= TLS_1_2
)
518 if (!reader
->read_data16(reader
, &hashsig
))
520 DBG1(DBG_TLS
, "certreq message invalid");
521 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
524 this->hashsig
= chunk_clone(hashsig
);
526 if (!reader
->read_data16(reader
, &data
))
528 DBG1(DBG_TLS
, "certreq message invalid");
529 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
532 authorities
= bio_reader_create(data
);
533 while (authorities
->remaining(authorities
))
535 if (!authorities
->read_data16(authorities
, &data
))
537 DBG1(DBG_TLS
, "certreq message invalid");
538 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
539 authorities
->destroy(authorities
);
544 id
= identification_create_from_encoding(ID_DER_ASN1_DN
, data
);
545 cert
= lib
->credmgr
->get_cert(lib
->credmgr
,
546 CERT_X509
, KEY_ANY
, id
, TRUE
);
549 DBG1(DBG_TLS
, "received TLS cert request for '%Y", id
);
550 this->peer_auth
->add(this->peer_auth
, AUTH_RULE_CA_CERT
, cert
);
554 DBG1(DBG_TLS
, "received TLS cert request for unknown CA '%Y'", id
);
559 authorities
->destroy(authorities
);
560 this->state
= STATE_CERTREQ_RECEIVED
;
565 * Process Hello Done message
567 static status_t
process_hello_done(private_tls_peer_t
*this,
568 bio_reader_t
*reader
)
570 this->crypto
->append_handshake(this->crypto
,
571 TLS_SERVER_HELLO_DONE
, reader
->peek(reader
));
572 this->state
= STATE_HELLO_DONE
;
577 * Process finished message
579 static status_t
process_finished(private_tls_peer_t
*this, bio_reader_t
*reader
)
584 if (!reader
->read_data(reader
, sizeof(buf
), &received
))
586 DBG1(DBG_TLS
, "received server finished too short");
587 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECODE_ERROR
);
590 if (!this->crypto
->calculate_finished(this->crypto
, "server finished", buf
))
592 DBG1(DBG_TLS
, "calculating server finished failed");
593 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
596 if (!chunk_equals(received
, chunk_from_thing(buf
)))
598 DBG1(DBG_TLS
, "received server finished invalid");
599 this->alert
->add(this->alert
, TLS_FATAL
, TLS_DECRYPT_ERROR
);
602 this->state
= STATE_COMPLETE
;
603 this->crypto
->derive_eap_msk(this->crypto
,
604 chunk_from_thing(this->client_random
),
605 chunk_from_thing(this->server_random
));
609 METHOD(tls_handshake_t
, process
, status_t
,
610 private_tls_peer_t
*this, tls_handshake_type_t type
, bio_reader_t
*reader
)
612 tls_handshake_type_t expected
;
616 case STATE_HELLO_SENT
:
617 if (type
== TLS_SERVER_HELLO
)
619 return process_server_hello(this, reader
);
621 expected
= TLS_SERVER_HELLO
;
623 case STATE_HELLO_RECEIVED
:
624 if (type
== TLS_CERTIFICATE
)
626 return process_certificate(this, reader
);
628 expected
= TLS_CERTIFICATE
;
630 case STATE_CERT_RECEIVED
:
631 if (type
== TLS_SERVER_KEY_EXCHANGE
)
633 return process_key_exchange(this, reader
);
635 /* fall through since TLS_SERVER_KEY_EXCHANGE is optional */
636 case STATE_KEY_EXCHANGE_RECEIVED
:
637 if (type
== TLS_CERTIFICATE_REQUEST
)
639 return process_certreq(this, reader
);
642 /* fall through since TLS_CERTIFICATE_REQUEST is optional */
643 case STATE_CERTREQ_RECEIVED
:
644 if (type
== TLS_SERVER_HELLO_DONE
)
646 return process_hello_done(this, reader
);
648 expected
= TLS_SERVER_HELLO_DONE
;
650 case STATE_CIPHERSPEC_CHANGED_IN
:
651 if (type
== TLS_FINISHED
)
653 return process_finished(this, reader
);
655 expected
= TLS_FINISHED
;
658 DBG1(DBG_TLS
, "TLS %N not expected in current state",
659 tls_handshake_type_names
, type
);
660 this->alert
->add(this->alert
, TLS_FATAL
, TLS_UNEXPECTED_MESSAGE
);
663 DBG1(DBG_TLS
, "TLS %N expected, but received %N",
664 tls_handshake_type_names
, expected
, tls_handshake_type_names
, type
);
665 this->alert
->add(this->alert
, TLS_FATAL
, TLS_UNEXPECTED_MESSAGE
);
670 * Send a client hello
672 static status_t
send_client_hello(private_tls_peer_t
*this,
673 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
675 tls_cipher_suite_t
*suites
;
676 bio_writer_t
*extensions
, *curves
= NULL
;
677 tls_version_t version
;
678 tls_named_curve_t curve
;
679 enumerator_t
*enumerator
;
683 htoun32(&this->client_random
, time(NULL
));
684 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_WEAK
);
687 DBG1(DBG_TLS
, "no suitable RNG found to generate client random");
688 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
691 rng
->get_bytes(rng
, sizeof(this->client_random
) - 4, this->client_random
+ 4);
695 version
= this->tls
->get_version(this->tls
);
696 writer
->write_uint16(writer
, version
);
697 writer
->write_data(writer
, chunk_from_thing(this->client_random
));
699 /* session identifier => none */
700 writer
->write_data8(writer
, chunk_empty
);
702 /* add TLS cipher suites */
703 count
= this->crypto
->get_cipher_suites(this->crypto
, &suites
);
704 writer
->write_uint16(writer
, count
* 2);
705 for (i
= 0; i
< count
; i
++)
707 writer
->write_uint16(writer
, suites
[i
]);
710 /* NULL compression only */
711 writer
->write_uint8(writer
, 1);
712 writer
->write_uint8(writer
, 0);
714 extensions
= bio_writer_create(32);
716 extensions
->write_uint16(extensions
, TLS_EXT_SIGNATURE_ALGORITHMS
);
717 this->crypto
->get_signature_algorithms(this->crypto
, extensions
);
719 /* add supported Elliptic Curves, if any */
720 enumerator
= this->crypto
->create_ec_enumerator(this->crypto
);
721 while (enumerator
->enumerate(enumerator
, NULL
, &curve
))
725 extensions
->write_uint16(extensions
, TLS_EXT_ELLIPTIC_CURVES
);
726 curves
= bio_writer_create(16);
728 curves
->write_uint16(curves
, curve
);
730 enumerator
->destroy(enumerator
);
733 extensions
->write_data16(extensions
, curves
->get_buf(curves
));
734 curves
->destroy(curves
);
736 /* if we support curves, add point format extension */
737 extensions
->write_uint16(extensions
, TLS_EXT_EC_POINT_FORMATS
);
738 extensions
->write_uint16(extensions
, 2);
739 extensions
->write_uint8(extensions
, 1);
740 extensions
->write_uint8(extensions
, TLS_EC_POINT_UNCOMPRESSED
);
742 if (this->server
->get_type(this->server
) == ID_FQDN
)
746 DBG2(DBG_TLS
, "sending Server Name Indication for '%Y'", this->server
);
748 names
= bio_writer_create(8);
749 names
->write_uint8(names
, TLS_NAME_TYPE_HOST_NAME
);
750 names
->write_data16(names
, this->server
->get_encoding(this->server
));
751 names
->wrap16(names
);
752 extensions
->write_uint16(extensions
, TLS_EXT_SERVER_NAME
);
753 extensions
->write_data16(extensions
, names
->get_buf(names
));
754 names
->destroy(names
);
757 writer
->write_data16(writer
, extensions
->get_buf(extensions
));
758 extensions
->destroy(extensions
);
760 *type
= TLS_CLIENT_HELLO
;
761 this->state
= STATE_HELLO_SENT
;
762 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
767 * Find a private key suitable to sign Certificate Verify
769 static private_key_t
*find_private_key(private_tls_peer_t
*this)
771 private_key_t
*key
= NULL
;
772 bio_reader_t
*reader
;
780 reader
= bio_reader_create(this->cert_types
);
781 while (reader
->remaining(reader
) && reader
->read_uint8(reader
, &cert
))
794 key
= lib
->credmgr
->get_private(lib
->credmgr
, type
,
795 this->peer
, this->peer_auth
);
801 reader
->destroy(reader
);
808 static status_t
send_certificate(private_tls_peer_t
*this,
809 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
811 enumerator_t
*enumerator
;
817 this->private = find_private_key(this);
820 DBG1(DBG_TLS
, "no TLS peer certificate found for '%Y', "
821 "skipping client authentication", this->peer
);
825 /* generate certificate payload */
826 certs
= bio_writer_create(256);
829 cert
= this->peer_auth
->get(this->peer_auth
, AUTH_RULE_SUBJECT_CERT
);
832 if (cert
->get_encoding(cert
, CERT_ASN1_DER
, &data
))
834 DBG1(DBG_TLS
, "sending TLS peer certificate '%Y'",
835 cert
->get_subject(cert
));
836 certs
->write_data24(certs
, data
);
840 enumerator
= this->peer_auth
->create_enumerator(this->peer_auth
);
841 while (enumerator
->enumerate(enumerator
, &rule
, &cert
))
843 if (rule
== AUTH_RULE_IM_CERT
)
845 if (cert
->get_encoding(cert
, CERT_ASN1_DER
, &data
))
847 DBG1(DBG_TLS
, "sending TLS intermediate certificate '%Y'",
848 cert
->get_subject(cert
));
849 certs
->write_data24(certs
, data
);
854 enumerator
->destroy(enumerator
);
857 writer
->write_data24(writer
, certs
->get_buf(certs
));
858 certs
->destroy(certs
);
860 *type
= TLS_CERTIFICATE
;
861 this->state
= STATE_CERT_SENT
;
862 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
867 * Send client key exchange, using premaster encryption
869 static status_t
send_key_exchange_encrypt(private_tls_peer_t
*this,
870 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
872 public_key_t
*public;
877 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_STRONG
);
880 DBG1(DBG_TLS
, "no suitable RNG found for TLS premaster secret");
881 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
884 rng
->get_bytes(rng
, sizeof(premaster
) - 2, premaster
+ 2);
886 htoun16(premaster
, TLS_1_2
);
888 this->crypto
->derive_secrets(this->crypto
, chunk_from_thing(premaster
),
889 chunk_from_thing(this->client_random
),
890 chunk_from_thing(this->server_random
));
892 public = find_public_key(this);
895 DBG1(DBG_TLS
, "no TLS public key found for server '%Y'", this->server
);
896 this->alert
->add(this->alert
, TLS_FATAL
, TLS_CERTIFICATE_UNKNOWN
);
899 if (!public->encrypt(public, ENCRYPT_RSA_PKCS1
,
900 chunk_from_thing(premaster
), &encrypted
))
902 public->destroy(public);
903 DBG1(DBG_TLS
, "encrypting TLS premaster secret failed");
904 this->alert
->add(this->alert
, TLS_FATAL
, TLS_BAD_CERTIFICATE
);
907 public->destroy(public);
909 writer
->write_data16(writer
, encrypted
);
912 *type
= TLS_CLIENT_KEY_EXCHANGE
;
913 this->state
= STATE_KEY_EXCHANGE_SENT
;
914 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
919 * Send client key exchange, using DHE exchange
921 static status_t
send_key_exchange_dhe(private_tls_peer_t
*this,
922 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
924 chunk_t premaster
, pub
;
926 if (this->dh
->get_shared_secret(this->dh
, &premaster
) != SUCCESS
)
928 DBG1(DBG_TLS
, "calculating premaster from DH failed");
929 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
932 this->crypto
->derive_secrets(this->crypto
, premaster
,
933 chunk_from_thing(this->client_random
),
934 chunk_from_thing(this->server_random
));
935 chunk_clear(&premaster
);
937 this->dh
->get_my_public_value(this->dh
, &pub
);
938 if (this->dh
->get_dh_group(this->dh
) == MODP_CUSTOM
)
940 writer
->write_data16(writer
, pub
);
943 { /* ECP uses 8bit length header only, but a point format */
944 writer
->write_uint8(writer
, pub
.len
+ 1);
945 writer
->write_uint8(writer
, TLS_ANSI_UNCOMPRESSED
);
946 writer
->write_data(writer
, pub
);
950 *type
= TLS_CLIENT_KEY_EXCHANGE
;
951 this->state
= STATE_KEY_EXCHANGE_SENT
;
952 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
957 * Send client key exchange, depending on suite
959 static status_t
send_key_exchange(private_tls_peer_t
*this,
960 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
964 return send_key_exchange_dhe(this, type
, writer
);
966 return send_key_exchange_encrypt(this, type
, writer
);
970 * Send certificate verify
972 static status_t
send_certificate_verify(private_tls_peer_t
*this,
973 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
975 if (!this->private ||
976 !this->crypto
->sign_handshake(this->crypto
, this->private,
977 writer
, this->hashsig
))
979 DBG1(DBG_TLS
, "creating TLS Certificate Verify signature failed");
980 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
984 *type
= TLS_CERTIFICATE_VERIFY
;
985 this->state
= STATE_VERIFY_SENT
;
986 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
993 static status_t
send_finished(private_tls_peer_t
*this,
994 tls_handshake_type_t
*type
, bio_writer_t
*writer
)
998 if (!this->crypto
->calculate_finished(this->crypto
, "client finished", buf
))
1000 DBG1(DBG_TLS
, "calculating client finished data failed");
1001 this->alert
->add(this->alert
, TLS_FATAL
, TLS_INTERNAL_ERROR
);
1005 writer
->write_data(writer
, chunk_from_thing(buf
));
1007 *type
= TLS_FINISHED
;
1008 this->state
= STATE_FINISHED_SENT
;
1009 this->crypto
->append_handshake(this->crypto
, *type
, writer
->get_buf(writer
));
1013 METHOD(tls_handshake_t
, build
, status_t
,
1014 private_tls_peer_t
*this, tls_handshake_type_t
*type
, bio_writer_t
*writer
)
1016 switch (this->state
)
1019 return send_client_hello(this, type
, writer
);
1020 case STATE_HELLO_DONE
:
1023 return send_certificate(this, type
, writer
);
1025 /* otherwise fall through to next state */
1026 case STATE_CERT_SENT
:
1027 return send_key_exchange(this, type
, writer
);
1028 case STATE_KEY_EXCHANGE_SENT
:
1031 return send_certificate_verify(this, type
, writer
);
1035 return INVALID_STATE
;
1037 case STATE_CIPHERSPEC_CHANGED_OUT
:
1038 return send_finished(this, type
, writer
);
1040 return INVALID_STATE
;
1044 METHOD(tls_handshake_t
, cipherspec_changed
, bool,
1045 private_tls_peer_t
*this, bool inbound
)
1049 return this->state
== STATE_FINISHED_SENT
;
1055 return this->state
== STATE_VERIFY_SENT
;
1057 return this->state
== STATE_KEY_EXCHANGE_SENT
;
1061 METHOD(tls_handshake_t
, change_cipherspec
, void,
1062 private_tls_peer_t
*this, bool inbound
)
1064 this->crypto
->change_cipher(this->crypto
, inbound
);
1067 this->state
= STATE_CIPHERSPEC_CHANGED_IN
;
1071 this->state
= STATE_CIPHERSPEC_CHANGED_OUT
;
1075 METHOD(tls_handshake_t
, finished
, bool,
1076 private_tls_peer_t
*this)
1078 return this->state
== STATE_COMPLETE
;
1081 METHOD(tls_handshake_t
, destroy
, void,
1082 private_tls_peer_t
*this)
1084 DESTROY_IF(this->private);
1085 DESTROY_IF(this->dh
);
1086 this->peer_auth
->destroy(this->peer_auth
);
1087 this->server_auth
->destroy(this->server_auth
);
1088 free(this->hashsig
.ptr
);
1089 free(this->cert_types
.ptr
);
1096 tls_peer_t
*tls_peer_create(tls_t
*tls
, tls_crypto_t
*crypto
, tls_alert_t
*alert
,
1097 identification_t
*peer
, identification_t
*server
)
1099 private_tls_peer_t
*this;
1104 .process
= _process
,
1106 .cipherspec_changed
= _cipherspec_changed
,
1107 .change_cipherspec
= _change_cipherspec
,
1108 .finished
= _finished
,
1109 .destroy
= _destroy
,
1112 .state
= STATE_INIT
,
1118 .peer_auth
= auth_cfg_create(),
1119 .server_auth
= auth_cfg_create(),
1122 return &this->public;