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
22 typedef struct private_tls_peer_t private_tls_peer_t
;
29 STATE_KEY_EXCHANGE_SENT
,
31 STATE_CIPHERSPEC_CHANGED
,
36 * Private data of an tls_peer_t object.
38 struct private_tls_peer_t
{
41 * Public tls_peer_t interface.
58 identification_t
*peer
;
63 identification_t
*server
;
71 * All handshake data concatentated
76 * Hello random data selected by client
78 char client_random
[32];
81 * Hello random data selected by server
83 char server_random
[32];
86 * Auth helper for peer authentication
88 auth_cfg_t
*peer_auth
;
91 * Auth helper for server authentication
93 auth_cfg_t
*server_auth
;
98 private_key_t
*private;
102 * Append a handshake message to the handshake data buffer
104 static void append_handshake(private_tls_peer_t
*this,
105 tls_handshake_type_t type
, chunk_t data
)
109 /* reconstruct handshake header */
110 header
= htonl(data
.len
| (type
<< 24));
111 this->handshake
= chunk_cat("mcc", this->handshake
,
112 chunk_from_thing(header
), data
);
116 * Process a server hello message
118 static status_t
process_server_hello(private_tls_peer_t
*this,
119 tls_reader_t
*reader
)
121 u_int8_t compression
;
122 u_int16_t version
, cipher
;
123 chunk_t random
, session
, ext
= chunk_empty
;
124 tls_cipher_suite_t suite
;
126 append_handshake(this, TLS_SERVER_HELLO
, reader
->peek(reader
));
128 if (!reader
->read_uint16(reader
, &version
) ||
129 !reader
->read_data(reader
, sizeof(this->server_random
), &random
) ||
130 !reader
->read_data8(reader
, &session
) ||
131 !reader
->read_uint16(reader
, &cipher
) ||
132 !reader
->read_uint8(reader
, &compression
) ||
133 (reader
->remaining(reader
) && !reader
->read_data16(reader
, &ext
)))
135 DBG1(DBG_IKE
, "received invalid ServerHello");
139 memcpy(this->server_random
, random
.ptr
, sizeof(this->server_random
));
141 if (version
< this->tls
->get_version(this->tls
))
143 this->tls
->set_version(this->tls
, version
);
146 if (!this->crypto
->select_cipher_suite(this->crypto
, &suite
, 1))
148 DBG1(DBG_IKE
, "received cipher suite inacceptable");
155 * Process a Certificate message
157 static status_t
process_certificate(private_tls_peer_t
*this,
158 tls_reader_t
*reader
)
165 append_handshake(this, TLS_CERTIFICATE
, reader
->peek(reader
));
167 if (!reader
->read_data24(reader
, &data
))
171 certs
= tls_reader_create(data
);
172 while (certs
->remaining(certs
))
174 if (!certs
->read_data24(certs
, &data
))
176 certs
->destroy(certs
);
179 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, CERT_X509
,
180 BUILD_BLOB_ASN1_DER
, data
, BUILD_END
);
185 this->server_auth
->add(this->server_auth
,
186 AUTH_RULE_SUBJECT_CERT
, cert
);
187 DBG1(DBG_IKE
, "received TLS server certificate '%Y'",
188 cert
->get_subject(cert
));
193 DBG1(DBG_IKE
, "received TLS intermediate certificate '%Y'",
194 cert
->get_subject(cert
));
195 this->server_auth
->add(this->server_auth
,
196 AUTH_RULE_IM_CERT
, cert
);
201 DBG1(DBG_IKE
, "parsing TLS certificate failed, skipped");
204 certs
->destroy(certs
);
209 * Process a Certificate message
211 static status_t
process_certreq(private_tls_peer_t
*this, tls_reader_t
*reader
)
213 chunk_t types
, hashsig
, data
;
214 tls_reader_t
*authorities
;
215 identification_t
*id
;
218 append_handshake(this, TLS_CERTIFICATE_REQUEST
, reader
->peek(reader
));
220 if (!reader
->read_data8(reader
, &types
))
224 if (this->tls
->get_version(this->tls
) >= TLS_1_2
)
226 if (!reader
->read_data16(reader
, &hashsig
))
230 /* TODO: store supported hashsig algorithms */
232 if (!reader
->read_data16(reader
, &data
))
236 authorities
= tls_reader_create(data
);
237 while (authorities
->remaining(authorities
))
239 if (!authorities
->read_data16(authorities
, &data
))
241 authorities
->destroy(authorities
);
244 id
= identification_create_from_encoding(ID_DER_ASN1_DN
, data
);
245 cert
= charon
->credentials
->get_cert(charon
->credentials
,
246 CERT_X509
, KEY_ANY
, id
, TRUE
);
249 DBG1(DBG_IKE
, "received cert request for '%Y", id
);
250 this->peer_auth
->add(this->peer_auth
, AUTH_RULE_CA_CERT
, cert
);
254 DBG1(DBG_IKE
, "received cert request for unknown CA '%Y'", id
);
258 authorities
->destroy(authorities
);
263 * Process Hello Done message
265 static status_t
process_hello_done(private_tls_peer_t
*this,
266 tls_reader_t
*reader
)
268 append_handshake(this, TLS_SERVER_HELLO_DONE
, reader
->peek(reader
));
269 this->state
= STATE_HELLO_DONE
;
273 METHOD(tls_handshake_t
, process
, status_t
,
274 private_tls_peer_t
*this, tls_handshake_type_t type
, tls_reader_t
*reader
)
278 case STATE_HELLO_SENT
:
281 case TLS_SERVER_HELLO
:
282 return process_server_hello(this, reader
);
283 case TLS_CERTIFICATE
:
284 return process_certificate(this, reader
);
285 case TLS_CERTIFICATE_REQUEST
:
286 return process_certreq(this, reader
);
287 case TLS_SERVER_HELLO_DONE
:
288 return process_hello_done(this, reader
);
296 DBG1(DBG_IKE
, "received TLS handshake message %N, ignored",
297 tls_handshake_type_names
, type
);
302 * Send a client hello
304 static status_t
send_hello(private_tls_peer_t
*this,
305 tls_handshake_type_t
*type
, tls_writer_t
*writer
)
307 tls_cipher_suite_t
*suite
;
311 htoun32(&this->client_random
, time(NULL
));
312 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_WEAK
);
317 rng
->get_bytes(rng
, sizeof(this->client_random
) - 4, this->client_random
+ 4);
320 writer
->write_uint16(writer
, this->tls
->get_version(this->tls
));
321 writer
->write_data(writer
, chunk_from_thing(this->client_random
));
322 /* session identifier => none */
323 writer
->write_data8(writer
, chunk_empty
);
325 count
= this->crypto
->get_cipher_suites(this->crypto
, &suite
);
326 writer
->write_uint16(writer
, count
* 2);
327 for (i
= 0; i
< count
; i
++)
329 writer
->write_uint16(writer
, suite
[i
]);
331 /* NULL compression only */
332 writer
->write_uint8(writer
, 1);
333 writer
->write_uint8(writer
, 0);
335 *type
= TLS_CLIENT_HELLO
;
336 this->state
= STATE_HELLO_SENT
;
337 append_handshake(this, *type
, writer
->get_buf(writer
));
344 static status_t
send_certificate(private_tls_peer_t
*this,
345 tls_handshake_type_t
*type
, tls_writer_t
*writer
)
347 enumerator_t
*enumerator
;
353 this->private = charon
->credentials
->get_private(charon
->credentials
,
354 KEY_ANY
, this->peer
, this->peer_auth
);
357 DBG1(DBG_IKE
, "no TLS peer certificate found for '%Y'", this->peer
);
361 /* generate certificate payload */
362 certs
= tls_writer_create(256);
363 cert
= this->peer_auth
->get(this->peer_auth
, AUTH_RULE_SUBJECT_CERT
);
366 DBG1(DBG_IKE
, "sending TLS peer certificate '%Y'",
367 cert
->get_subject(cert
));
368 data
= cert
->get_encoding(cert
);
369 certs
->write_data24(certs
, data
);
372 enumerator
= this->peer_auth
->create_enumerator(this->peer_auth
);
373 while (enumerator
->enumerate(enumerator
, &rule
, &cert
))
375 if (rule
== AUTH_RULE_IM_CERT
)
377 DBG1(DBG_IKE
, "sending TLS intermediate certificate '%Y'",
378 cert
->get_subject(cert
));
379 data
= cert
->get_encoding(cert
);
380 certs
->write_data24(certs
, data
);
384 enumerator
->destroy(enumerator
);
386 writer
->write_data24(writer
, certs
->get_buf(certs
));
387 certs
->destroy(certs
);
389 *type
= TLS_CERTIFICATE
;
390 this->state
= STATE_CERT_SENT
;
391 append_handshake(this, *type
, writer
->get_buf(writer
));
396 * Send client key exchange
398 static status_t
send_key_exchange(private_tls_peer_t
*this,
399 tls_handshake_type_t
*type
, tls_writer_t
*writer
)
401 public_key_t
*public = NULL
, *current
;
402 enumerator_t
*enumerator
;
408 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_STRONG
);
411 DBG1(DBG_IKE
, "no suitable RNG found for TLS premaster secret");
414 rng
->get_bytes(rng
, sizeof(premaster
) - 2, premaster
+ 2);
416 htoun16(premaster
, TLS_1_2
);
418 this->crypto
->derive_master_secret(this->crypto
, chunk_from_thing(premaster
),
419 chunk_from_thing(this->client_random
),
420 chunk_from_thing(this->server_random
));
422 enumerator
= charon
->credentials
->create_public_enumerator(
423 charon
->credentials
, KEY_ANY
, this->server
, this->server_auth
);
424 while (enumerator
->enumerate(enumerator
, ¤t
, &auth
))
426 public = current
->get_ref(current
);
429 enumerator
->destroy(enumerator
);
433 DBG1(DBG_IKE
, "no TLS public key found for server '%Y'", this->server
);
436 if (!public->encrypt(public, chunk_from_thing(premaster
), &encrypted
))
438 public->destroy(public);
439 DBG1(DBG_IKE
, "encrypting TLS premaster secret failed");
442 public->destroy(public);
444 writer
->write_data16(writer
, encrypted
);
447 *type
= TLS_CLIENT_KEY_EXCHANGE
;
448 this->state
= STATE_KEY_EXCHANGE_SENT
;
449 append_handshake(this, *type
, writer
->get_buf(writer
));
454 * Send certificate verify
456 static status_t
send_certificate_verify(private_tls_peer_t
*this,
457 tls_handshake_type_t
*type
, tls_writer_t
*writer
)
466 if (this->tls
->get_version(this->tls
) >= TLS_1_2
)
468 if (!this->private->sign(this->private, SIGN_RSA_EMSA_PKCS1_SHA1
,
469 this->handshake
, &signature
))
471 DBG1(DBG_IKE
, "creating TLS Certificate Verify signature failed");
474 /* TODO: signature scheme to hashsign algorithm mapping */
475 writer
->write_uint8(writer
, 2); /* sha1 */
476 writer
->write_uint8(writer
, 1); /* RSA */
480 hasher_t
*md5
, *sha1
;
481 char buf
[HASH_SIZE_MD5
+ HASH_SIZE_SHA1
];
483 md5
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_MD5
);
486 DBG1(DBG_IKE
, "unable to sign %N Verify, MD5 not supported",
487 tls_version_names
, this->tls
->get_version(this->tls
));
490 md5
->get_hash(md5
, this->handshake
, buf
);
492 sha1
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
495 DBG1(DBG_IKE
, "unable to sign %N Verify, SHA1 not supported",
496 tls_version_names
, this->tls
->get_version(this->tls
));
499 sha1
->get_hash(sha1
, this->handshake
, buf
+ HASH_SIZE_MD5
);
502 if (!this->private->sign(this->private, SIGN_RSA_EMSA_PKCS1_NULL
,
503 chunk_from_thing(buf
), &signature
))
505 DBG1(DBG_IKE
, "creating TLS Certificate Verify signature failed");
509 writer
->write_data16(writer
, signature
);
512 *type
= TLS_CERTIFICATE_VERIFY
;
513 this->state
= STATE_VERIFY_SENT
;
514 append_handshake(this, *type
, writer
->get_buf(writer
));
521 static status_t
send_finished(private_tls_peer_t
*this,
522 tls_handshake_type_t
*type
, tls_writer_t
*writer
)
528 if (this->tls
->get_version(this->tls
) >= TLS_1_2
)
530 /* TODO: use hash of cipher suite only */
535 hasher_t
*md5
, *sha1
;
536 char buf
[HASH_SIZE_MD5
+ HASH_SIZE_SHA1
];
538 md5
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_MD5
);
541 DBG1(DBG_IKE
, "unable to create %N Finished, MD5 not supported",
542 tls_version_names
, this->tls
->get_version(this->tls
));
545 md5
->get_hash(md5
, this->handshake
, buf
);
547 sha1
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
550 DBG1(DBG_IKE
, "unable to sign %N Finished, SHA1 not supported",
551 tls_version_names
, this->tls
->get_version(this->tls
));
554 sha1
->get_hash(sha1
, this->handshake
, buf
+ HASH_SIZE_MD5
);
557 seed
= chunk_clonea(chunk_from_thing(buf
));
560 prf
= this->crypto
->get_prf(this->crypto
);
565 prf
->get_bytes(prf
, "client finished", seed
, sizeof(data
), data
);
567 writer
->write_data(writer
, chunk_from_thing(data
));
569 *type
= TLS_FINISHED
;
570 this->state
= STATE_FINISHED_SENT
;
574 METHOD(tls_handshake_t
, build
, status_t
,
575 private_tls_peer_t
*this, tls_handshake_type_t
*type
, tls_writer_t
*writer
)
580 return send_hello(this, type
, writer
);
581 case STATE_HELLO_DONE
:
582 return send_certificate(this, type
, writer
);
583 case STATE_CERT_SENT
:
584 return send_key_exchange(this, type
, writer
);
585 case STATE_KEY_EXCHANGE_SENT
:
586 return send_certificate_verify(this, type
, writer
);
587 case STATE_CIPHERSPEC_CHANGED
:
588 return send_finished(this, type
, writer
);
590 return INVALID_STATE
;
594 METHOD(tls_handshake_t
, cipherspec_changed
, bool,
595 private_tls_peer_t
*this)
597 if (this->state
== STATE_VERIFY_SENT
)
599 this->crypto
->change_cipher(this->crypto
, FALSE
);
600 this->state
= STATE_CIPHERSPEC_CHANGED
;
606 METHOD(tls_handshake_t
, change_cipherspec
, void,
607 private_tls_peer_t
*this)
612 METHOD(tls_handshake_t
, destroy
, void,
613 private_tls_peer_t
*this)
615 DESTROY_IF(this->private);
616 free(this->handshake
.ptr
);
617 this->peer_auth
->destroy(this->peer_auth
);
618 this->server_auth
->destroy(this->server_auth
);
625 tls_peer_t
*tls_peer_create(tls_t
*tls
, tls_crypto_t
*crypto
,
626 identification_t
*peer
, identification_t
*server
)
628 private_tls_peer_t
*this;
631 .public.handshake
= {
634 .cipherspec_changed
= _cipherspec_changed
,
635 .change_cipherspec
= _change_cipherspec
,
643 .peer_auth
= auth_cfg_create(),
644 .server_auth
= auth_cfg_create(),
647 return &this->public;