2 * Copyright (C) 2000, 2001, 2004, 2005, 2006, 2008, 2010 Free Software
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
26 /* This file contains functions which are wrappers for the key exchange
27 * part of TLS. They are called by the handshake functions (gnutls_handshake)
30 #include "gnutls_int.h"
31 #include "gnutls_handshake.h"
32 #include "gnutls_kx.h"
33 #include "gnutls_dh.h"
34 #include "gnutls_errors.h"
35 #include "gnutls_algorithms.h"
37 #include "gnutls_mpi.h"
38 #include <gnutls_state.h>
39 #include <gnutls_datum.h>
40 #include <gnutls_rsa_export.h>
41 #include <gnutls_mbuffers.h>
43 /* This is a temporary function to be used before the generate_*
44 internal API is changed to use mbuffers. For now we don't avoid the
45 extra alloc + memcpy. */
47 send_handshake (gnutls_session_t session
, opaque
* data
, size_t size
,
48 gnutls_handshake_description_t type
)
52 if (data
== NULL
&& size
== 0)
53 return _gnutls_send_handshake (session
, NULL
, type
);
55 if (data
== NULL
&& size
> 0)
58 return GNUTLS_E_INVALID_REQUEST
;
61 bufel
= _gnutls_handshake_alloc(session
, size
, size
);
65 return GNUTLS_E_MEMORY_ERROR
;
68 _mbuffer_set_udata (bufel
, data
, size
);
70 return _gnutls_send_handshake (session
, bufel
, type
);
74 /* This file contains important thing for the TLS handshake procedure.
77 #define MASTER_SECRET "master secret"
78 #define MASTER_SECRET_SIZE (sizeof(MASTER_SECRET)-1)
79 static int generate_normal_master (gnutls_session_t session
, int);
82 _gnutls_generate_master (gnutls_session_t session
, int keep_premaster
)
84 if (session
->internals
.resumed
== RESUME_FALSE
)
85 return generate_normal_master (session
, keep_premaster
);
89 /* here we generate the TLS Master secret.
91 #define PREMASTER session->key->key
93 generate_normal_master (gnutls_session_t session
, int keep_premaster
)
98 _gnutls_hard_log ("INT: PREMASTER SECRET[%d]: %s\n", PREMASTER
.size
,
99 _gnutls_bin2hex (PREMASTER
.data
, PREMASTER
.size
, buf
,
100 sizeof (buf
), NULL
));
101 _gnutls_hard_log ("INT: CLIENT RANDOM[%d]: %s\n", 32,
102 _gnutls_bin2hex (session
->
103 security_parameters
.client_random
, 32,
104 buf
, sizeof (buf
), NULL
));
105 _gnutls_hard_log ("INT: SERVER RANDOM[%d]: %s\n", 32,
106 _gnutls_bin2hex (session
->
107 security_parameters
.server_random
, 32,
108 buf
, sizeof (buf
), NULL
));
110 if (gnutls_protocol_get_version (session
) == GNUTLS_SSL3
)
112 opaque rnd
[2 * GNUTLS_RANDOM_SIZE
+ 1];
114 memcpy (rnd
, session
->security_parameters
.client_random
,
116 memcpy (&rnd
[GNUTLS_RANDOM_SIZE
],
117 session
->security_parameters
.server_random
, GNUTLS_RANDOM_SIZE
);
120 _gnutls_ssl3_generate_random (PREMASTER
.data
, PREMASTER
.size
,
121 rnd
, 2 * GNUTLS_RANDOM_SIZE
,
124 security_parameters
.master_secret
);
129 opaque rnd
[2 * GNUTLS_RANDOM_SIZE
+ 1];
131 memcpy (rnd
, session
->security_parameters
.client_random
,
133 memcpy (&rnd
[GNUTLS_RANDOM_SIZE
],
134 session
->security_parameters
.server_random
, GNUTLS_RANDOM_SIZE
);
137 _gnutls_PRF (session
, PREMASTER
.data
, PREMASTER
.size
,
138 MASTER_SECRET
, MASTER_SECRET_SIZE
,
139 rnd
, 2 * GNUTLS_RANDOM_SIZE
, GNUTLS_MASTER_SIZE
,
140 session
->security_parameters
.master_secret
);
144 _gnutls_free_datum (&PREMASTER
);
149 _gnutls_hard_log ("INT: MASTER SECRET: %s\n",
150 _gnutls_bin2hex (session
->
151 security_parameters
.master_secret
,
152 GNUTLS_MASTER_SIZE
, buf
, sizeof (buf
),
159 /* This is called when we want to receive the key exchange message of the
160 * server. It does nothing if this type of message is not required
161 * by the selected ciphersuite.
164 _gnutls_send_server_kx_message (gnutls_session_t session
, int again
)
166 gnutls_buffer_st data
;
169 if (session
->internals
.auth_struct
->gnutls_generate_server_kx
== NULL
)
172 _gnutls_buffer_init( &data
);
177 session
->internals
.auth_struct
->gnutls_generate_server_kx (session
,
180 if (ret
== GNUTLS_E_INT_RET_0
)
194 ret
= send_handshake (session
, data
.data
, data
.length
,
195 GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE
);
202 _gnutls_buffer_clear (&data
);
206 /* This function sends a certificate request message to the
210 _gnutls_send_server_certificate_request (gnutls_session_t session
, int again
)
212 gnutls_buffer_st data
;
215 if (session
->internals
.
216 auth_struct
->gnutls_generate_server_certificate_request
== NULL
)
219 if (session
->internals
.send_cert_req
<= 0)
222 _gnutls_buffer_init( &data
);
228 auth_struct
->gnutls_generate_server_certificate_request (session
,
238 ret
= send_handshake (session
, data
.data
, data
.length
,
239 GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST
);
246 _gnutls_buffer_clear (&data
);
251 /* This is the function for the client to send the key
255 _gnutls_send_client_kx_message (gnutls_session_t session
, int again
)
257 gnutls_buffer_st data
;
260 if (session
->internals
.auth_struct
->gnutls_generate_client_kx
== NULL
)
263 _gnutls_buffer_init( &data
);
268 session
->internals
.auth_struct
->gnutls_generate_client_kx (session
,
276 ret
= send_handshake (session
, data
.data
, data
.length
,
277 GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE
);
284 _gnutls_buffer_clear (&data
);
289 /* This is the function for the client to send the certificate
293 _gnutls_send_client_certificate_verify (gnutls_session_t session
, int again
)
295 gnutls_buffer_st data
;
298 /* This is a packet that is only sent by the client
300 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
303 /* if certificate verify is not needed just exit
305 if (session
->key
->certificate_requested
== 0)
309 if (session
->internals
.auth_struct
->gnutls_generate_client_cert_vrfy
==
313 return 0; /* this algorithm does not support cli_cert_vrfy
317 _gnutls_buffer_init( &data
);
323 auth_struct
->gnutls_generate_client_cert_vrfy (session
, &data
);
334 ret
= send_handshake (session
, data
.data
, data
.length
,
335 GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY
);
343 _gnutls_buffer_clear (&data
);
347 /* This is called when we want send our certificate
350 _gnutls_send_client_certificate (gnutls_session_t session
, int again
)
352 gnutls_buffer_st data
;
356 if (session
->key
->certificate_requested
== 0)
359 if (session
->internals
.auth_struct
->gnutls_generate_client_certificate
==
363 _gnutls_buffer_init( &data
);
367 if (gnutls_protocol_get_version (session
) != GNUTLS_SSL3
||
368 session
->internals
.selected_cert_list_length
> 0)
370 /* TLS 1.0 or SSL 3.0 with a valid certificate
374 auth_struct
->gnutls_generate_client_certificate (session
, &data
);
384 /* In the SSL 3.0 protocol we need to send a
385 * no certificate alert instead of an
388 if (gnutls_protocol_get_version (session
) == GNUTLS_SSL3
&&
389 session
->internals
.selected_cert_list_length
== 0)
392 gnutls_alert_send (session
, GNUTLS_AL_WARNING
,
393 GNUTLS_A_SSL3_NO_CERTIFICATE
);
397 { /* TLS 1.0 or SSL 3.0 with a valid certificate
399 ret
= send_handshake (session
, data
.data
, data
.length
,
400 GNUTLS_HANDSHAKE_CERTIFICATE_PKT
);
404 _gnutls_buffer_clear (&data
);
409 /* This is called when we want send our certificate
412 _gnutls_send_server_certificate (gnutls_session_t session
, int again
)
414 gnutls_buffer_st data
;
418 if (session
->internals
.auth_struct
->gnutls_generate_server_certificate
==
422 _gnutls_buffer_init( &data
);
428 auth_struct
->gnutls_generate_server_certificate (session
, &data
);
436 ret
= send_handshake (session
, data
.data
, data
.length
,
437 GNUTLS_HANDSHAKE_CERTIFICATE_PKT
);
444 _gnutls_buffer_clear (&data
);
450 _gnutls_recv_server_kx_message (gnutls_session_t session
)
452 uint8_t *data
= NULL
;
455 optional_t optflag
= MANDATORY_PACKET
;
457 if (session
->internals
.auth_struct
->gnutls_process_server_kx
!= NULL
)
460 /* EXCEPTION FOR RSA_EXPORT cipher suite
462 if (_gnutls_session_is_export (session
) != 0 &&
463 _gnutls_peers_cert_less_512 (session
) != 0)
469 /* Server key exchange packet is optional for PSK. */
470 if (_gnutls_session_is_psk (session
))
471 optflag
= OPTIONAL_PACKET
;
474 _gnutls_recv_handshake (session
, &data
,
476 GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE
,
485 session
->internals
.auth_struct
->gnutls_process_server_kx (session
,
501 _gnutls_recv_server_certificate_request (gnutls_session_t session
)
507 if (session
->internals
.
508 auth_struct
->gnutls_process_server_certificate_request
!= NULL
)
512 _gnutls_recv_handshake (session
, &data
,
514 GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST
,
519 if (ret
== 0 && datasize
== 0)
520 return 0; /* ignored */
524 auth_struct
->gnutls_process_server_certificate_request (session
, data
,
535 _gnutls_recv_client_kx_message (gnutls_session_t session
)
542 /* Do key exchange only if the algorithm permits it */
543 if (session
->internals
.auth_struct
->gnutls_process_client_kx
!= NULL
)
547 _gnutls_recv_handshake (session
, &data
,
549 GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE
,
555 session
->internals
.auth_struct
->gnutls_process_client_kx (session
,
571 _gnutls_recv_client_certificate (gnutls_session_t session
)
578 if (session
->internals
.auth_struct
->gnutls_process_client_certificate
!=
582 /* if we have not requested a certificate then just return
584 if (session
->internals
.send_cert_req
== 0)
589 if (session
->internals
.send_cert_req
== GNUTLS_CERT_REQUIRE
)
590 optional
= MANDATORY_PACKET
;
592 optional
= OPTIONAL_PACKET
;
595 _gnutls_recv_handshake (session
, &data
,
597 GNUTLS_HANDSHAKE_CERTIFICATE_PKT
, optional
);
601 /* Handle the case of old SSL3 clients who send
602 * a warning alert instead of an empty certificate to indicate
605 if (optional
== OPTIONAL_PACKET
&&
606 ret
== GNUTLS_E_WARNING_ALERT_RECEIVED
&&
607 gnutls_protocol_get_version (session
) == GNUTLS_SSL3
&&
608 gnutls_alert_get (session
) == GNUTLS_A_SSL3_NO_CERTIFICATE
)
611 /* SSL3 does not send an empty certificate,
612 * but this alert. So we just ignore it.
618 /* certificate was required
620 if ((ret
== GNUTLS_E_WARNING_ALERT_RECEIVED
621 || ret
== GNUTLS_E_FATAL_ALERT_RECEIVED
)
622 && optional
== MANDATORY_PACKET
)
625 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
631 if (ret
== 0 && datasize
== 0 && optional
== OPTIONAL_PACKET
)
633 /* Client has not sent the certificate message.
634 * well I'm not sure we should accept this
642 auth_struct
->gnutls_process_client_certificate (session
, data
,
646 if (ret
< 0 && ret
!= GNUTLS_E_NO_CERTIFICATE_FOUND
)
652 /* ok we should expect a certificate verify message now
654 if (ret
== GNUTLS_E_NO_CERTIFICATE_FOUND
&& optional
== OPTIONAL_PACKET
)
657 session
->key
->certificate_requested
= 1;
665 _gnutls_recv_server_certificate (gnutls_session_t session
)
671 if (session
->internals
.auth_struct
->gnutls_process_server_certificate
!=
676 _gnutls_recv_handshake (session
, &data
,
678 GNUTLS_HANDSHAKE_CERTIFICATE_PKT
,
688 auth_struct
->gnutls_process_server_certificate (session
, data
,
702 /* Recv the client certificate verify. This packet may not
703 * arrive if the peer did not send us a certificate.
706 _gnutls_recv_client_certificate_verify_message (gnutls_session_t session
)
713 if (session
->internals
.auth_struct
->gnutls_process_client_cert_vrfy
!= NULL
)
716 if (session
->internals
.send_cert_req
== 0 ||
717 session
->key
->certificate_requested
== 0)
723 _gnutls_recv_handshake (session
, &data
,
725 GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY
,
730 if (ret
== 0 && datasize
== 0
731 && session
->internals
.send_cert_req
== GNUTLS_CERT_REQUIRE
)
733 /* certificate was required */
735 return GNUTLS_E_NO_CERTIFICATE_FOUND
;
740 auth_struct
->gnutls_process_client_cert_vrfy (session
, data
,