Added support for an old version of the DTLS protocol
[gnutls.git] / lib / gnutls_handshake.c
blob8256e141d03f016c3a94fa59d740aa6ee06d3d19
1 /*
2 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* Functions that relate to the TLS handshake procedure.
26 #include "gnutls_int.h"
27 #include "gnutls_errors.h"
28 #include "gnutls_dh.h"
29 #include "debug.h"
30 #include "algorithms.h"
31 #include "gnutls_compress.h"
32 #include "gnutls_cipher.h"
33 #include "gnutls_buffers.h"
34 #include "gnutls_mbuffers.h"
35 #include "gnutls_kx.h"
36 #include "gnutls_handshake.h"
37 #include "gnutls_num.h"
38 #include "gnutls_hash_int.h"
39 #include "gnutls_db.h"
40 #include "gnutls_extensions.h"
41 #include "gnutls_supplemental.h"
42 #include "gnutls_auth.h"
43 #include "gnutls_v2_compat.h"
44 #include <auth/cert.h>
45 #include "gnutls_constate.h"
46 #include <gnutls_record.h>
47 #include <gnutls_state.h>
48 #include <ext/srp.h>
49 #include <ext/session_ticket.h>
50 #include <ext/safe_renegotiation.h>
51 #include <gnutls_rsa_export.h> /* for gnutls_get_rsa_params() */
52 #include <auth/anon.h> /* for gnutls_anon_server_credentials_t */
53 #include <auth/psk.h> /* for gnutls_psk_server_credentials_t */
54 #include <random.h>
55 #include <gnutls_dtls.h>
57 #ifdef HANDSHAKE_DEBUG
58 #define ERR(x, y) _gnutls_handshake_log("HSK[%p]: %s (%d)\n", session, x,y)
59 #else
60 #define ERR(x, y)
61 #endif
63 #define TRUE 1
64 #define FALSE 0
66 static int _gnutls_server_select_comp_method (gnutls_session_t session,
67 uint8_t * data, int datalen);
68 static int
69 _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session,
70 uint8_t * cipher_suites,
71 int cipher_suites_size,
72 gnutls_pk_algorithm_t *pk_algos,
73 size_t pk_algos_size);
75 /* Empties but does not free the buffer
77 static inline void
78 _gnutls_handshake_hash_buffer_empty (gnutls_session_t session)
81 _gnutls_buffers_log ("BUF[HSK]: Emptied buffer\n");
83 session->internals.handshake_hash_buffer_prev_len = 0;
84 session->internals.handshake_hash_buffer.length = 0;
85 return;
88 static int
89 _gnutls_handshake_hash_add_recvd (gnutls_session_t session,
90 gnutls_handshake_description_t recv_type,
91 uint8_t * header, uint16_t header_size,
92 uint8_t * dataptr, uint32_t datalen);
94 static int
95 _gnutls_handshake_hash_add_sent (gnutls_session_t session,
96 gnutls_handshake_description_t type,
97 uint8_t * dataptr, uint32_t datalen);
99 static int
100 _gnutls_recv_hello_verify_request (gnutls_session_t session,
101 uint8_t * data, int datalen);
104 /* Clears the handshake hash buffers and handles.
106 void
107 _gnutls_handshake_hash_buffers_clear (gnutls_session_t session)
109 session->internals.handshake_hash_buffer_prev_len = 0;
110 _gnutls_buffer_clear(&session->internals.handshake_hash_buffer);
113 /* this will copy the required values for resuming to
114 * internals, and to security_parameters.
115 * this will keep as less data to security_parameters.
117 static void
118 resume_copy_required_values (gnutls_session_t session)
120 /* get the new random values */
121 memcpy (session->internals.resumed_security_parameters.server_random,
122 session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
123 memcpy (session->internals.resumed_security_parameters.client_random,
124 session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
126 /* keep the ciphersuite and compression
127 * That is because the client must see these in our
128 * hello message.
130 memcpy (session->security_parameters.cipher_suite,
131 session->internals.resumed_security_parameters.cipher_suite, 2);
132 session->security_parameters.compression_method = session->internals.resumed_security_parameters.compression_method;
134 _gnutls_epoch_set_cipher_suite (session, EPOCH_NEXT,
135 session->
136 internals.resumed_security_parameters.cipher_suite);
137 _gnutls_epoch_set_compression (session, EPOCH_NEXT,
138 session->
139 internals.resumed_security_parameters.compression_method);
141 /* or write_compression_algorithm
142 * they are the same
145 session->security_parameters.entity =
146 session->internals.resumed_security_parameters.entity;
148 _gnutls_set_current_version (session,
149 session->internals.resumed_security_parameters.
150 version);
152 session->security_parameters.cert_type =
153 session->internals.resumed_security_parameters.cert_type;
155 memcpy (session->security_parameters.session_id,
156 session->internals.resumed_security_parameters.session_id,
157 sizeof (session->security_parameters.session_id));
158 session->security_parameters.session_id_size =
159 session->internals.resumed_security_parameters.session_id_size;
163 void
164 _gnutls_set_server_random (gnutls_session_t session, uint8_t * rnd)
166 memcpy (session->security_parameters.server_random, rnd,
167 GNUTLS_RANDOM_SIZE);
170 void
171 _gnutls_set_client_random (gnutls_session_t session, uint8_t * rnd)
173 memcpy (session->security_parameters.client_random, rnd,
174 GNUTLS_RANDOM_SIZE);
177 /* Calculate The SSL3 Finished message
179 #define SSL3_CLIENT_MSG "CLNT"
180 #define SSL3_SERVER_MSG "SRVR"
181 #define SSL_MSG_LEN 4
182 static int
183 _gnutls_ssl3_finished (gnutls_session_t session, int type, uint8_t * ret, int sending)
185 digest_hd_st td_md5;
186 digest_hd_st td_sha;
187 const char *mesg;
188 int rc, len;
190 if (sending)
191 len = session->internals.handshake_hash_buffer.length;
192 else
193 len = session->internals.handshake_hash_buffer_prev_len;
195 rc = _gnutls_hash_init (&td_sha, GNUTLS_DIG_SHA1);
196 if (rc < 0)
197 return gnutls_assert_val(rc);
199 rc = _gnutls_hash_init (&td_md5, GNUTLS_DIG_MD5);
200 if (rc < 0)
202 _gnutls_hash_deinit (&td_sha, NULL);
203 return gnutls_assert_val(rc);
206 _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, len);
207 _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, len);
209 if (type == GNUTLS_SERVER)
210 mesg = SSL3_SERVER_MSG;
211 else
212 mesg = SSL3_CLIENT_MSG;
214 _gnutls_hash (&td_md5, mesg, SSL_MSG_LEN);
215 _gnutls_hash (&td_sha, mesg, SSL_MSG_LEN);
217 rc = _gnutls_mac_deinit_ssl3_handshake (&td_md5, ret,
218 session->
219 security_parameters.master_secret,
220 GNUTLS_MASTER_SIZE);
221 if (rc < 0)
223 _gnutls_hash_deinit (&td_md5, NULL);
224 _gnutls_hash_deinit (&td_sha, NULL);
225 return gnutls_assert_val(rc);
228 rc = _gnutls_mac_deinit_ssl3_handshake (&td_sha, &ret[16],
229 session->
230 security_parameters.master_secret,
231 GNUTLS_MASTER_SIZE);
232 if (rc < 0)
234 _gnutls_hash_deinit (&td_sha, NULL);
235 return gnutls_assert_val(rc);
238 return 0;
241 /* Hash the handshake messages as required by TLS 1.0
243 #define SERVER_MSG "server finished"
244 #define CLIENT_MSG "client finished"
245 #define TLS_MSG_LEN 15
246 static int
247 _gnutls_finished (gnutls_session_t session, int type, void *ret, int sending)
249 const int siz = TLS_MSG_LEN;
250 uint8_t concat[MAX_HASH_SIZE + 16 /*MD5 */ ];
251 size_t hash_len;
252 const char *mesg;
253 int rc, len;
255 if (sending)
256 len = session->internals.handshake_hash_buffer.length;
257 else
258 len = session->internals.handshake_hash_buffer_prev_len;
260 if (!_gnutls_version_has_selectable_prf (gnutls_protocol_get_version(session)))
262 rc = _gnutls_hash_fast( GNUTLS_DIG_SHA1, session->internals.handshake_hash_buffer.data, len, &concat[16]);
263 if (rc < 0)
264 return gnutls_assert_val(rc);
266 rc = _gnutls_hash_fast( GNUTLS_DIG_MD5, session->internals.handshake_hash_buffer.data, len, concat);
267 if (rc < 0)
268 return gnutls_assert_val(rc);
270 hash_len = 20 + 16;
272 else
274 int algorithm = _gnutls_cipher_suite_get_prf(session->security_parameters.cipher_suite);
276 rc = _gnutls_hash_fast( algorithm, session->internals.handshake_hash_buffer.data, len, concat);
277 if (rc < 0)
278 return gnutls_assert_val(rc);
280 hash_len = _gnutls_hash_get_algo_len (algorithm);
283 if (type == GNUTLS_SERVER)
285 mesg = SERVER_MSG;
287 else
289 mesg = CLIENT_MSG;
292 return _gnutls_PRF (session, session->security_parameters.master_secret,
293 GNUTLS_MASTER_SIZE, mesg, siz, concat, hash_len, 12, ret);
296 /* this function will produce GNUTLS_RANDOM_SIZE==32 bytes of random data
297 * and put it to dst.
300 _gnutls_tls_create_random (uint8_t * dst)
302 uint32_t tim;
303 int ret;
305 /* Use weak random numbers for the most of the
306 * buffer except for the first 4 that are the
307 * system's time.
310 tim = gnutls_time (NULL);
311 /* generate server random value */
312 _gnutls_write_uint32 (tim, dst);
314 ret = _gnutls_rnd (GNUTLS_RND_NONCE, &dst[4], GNUTLS_RANDOM_SIZE - 4);
315 if (ret < 0)
317 gnutls_assert ();
318 return ret;
321 return 0;
324 /* returns the 0 on success or a negative error code.
327 _gnutls_negotiate_version (gnutls_session_t session,
328 gnutls_protocol_t adv_version)
330 int ret;
332 /* if we do not support that version */
333 if (_gnutls_version_is_supported (session, adv_version) == 0)
335 /* If he requested something we do not support
336 * then we send him the highest we support.
338 ret = _gnutls_version_max (session);
339 if (ret == GNUTLS_VERSION_UNKNOWN)
341 /* this check is not really needed.
343 gnutls_assert ();
344 return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
347 else
349 ret = adv_version;
352 _gnutls_set_current_version (session, ret);
354 return ret;
358 _gnutls_user_hello_func (gnutls_session_t session,
359 gnutls_protocol_t adv_version)
361 int ret;
363 if (session->internals.user_hello_func != NULL)
365 ret = session->internals.user_hello_func (session);
366 if (ret < 0)
368 gnutls_assert ();
369 return ret;
371 /* Here we need to renegotiate the version since the callee might
372 * have disabled some TLS versions.
374 ret = _gnutls_negotiate_version (session, adv_version);
375 if (ret < 0)
377 gnutls_assert ();
378 return ret;
381 return 0;
384 /* Read a client hello packet.
385 * A client hello must be a known version client hello
386 * or version 2.0 client hello (only for compatibility
387 * since SSL version 2.0 is not supported).
389 static int
390 _gnutls_read_client_hello (gnutls_session_t session, uint8_t * data,
391 int datalen)
393 uint8_t session_id_len;
394 int pos = 0, ret;
395 uint16_t suite_size, comp_size;
396 gnutls_protocol_t adv_version;
397 int neg_version;
398 int len = datalen;
399 uint8_t rnd[GNUTLS_RANDOM_SIZE], *suite_ptr, *comp_ptr, *session_id;
401 DECR_LEN (len, 2);
403 _gnutls_handshake_log ("HSK[%p]: Client's version: %d.%d\n", session,
404 data[pos], data[pos + 1]);
406 adv_version = _gnutls_version_get (data[pos], data[pos + 1]);
407 set_adv_version (session, data[pos], data[pos + 1]);
408 pos += 2;
410 neg_version = _gnutls_negotiate_version (session, adv_version);
411 if (neg_version < 0)
413 gnutls_assert ();
414 return neg_version;
417 /* Read client random value.
419 DECR_LEN (len, GNUTLS_RANDOM_SIZE);
420 _gnutls_set_client_random (session, &data[pos]);
421 pos += GNUTLS_RANDOM_SIZE;
423 _gnutls_tls_create_random (rnd);
424 _gnutls_set_server_random (session, rnd);
426 session->security_parameters.timestamp = gnutls_time (NULL);
428 DECR_LEN (len, 1);
429 session_id_len = data[pos++];
431 /* RESUME SESSION
433 if (session_id_len > TLS_MAX_SESSION_ID_SIZE)
435 gnutls_assert ();
436 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
438 DECR_LEN (len, session_id_len);
439 session_id = &data[pos];
440 pos += session_id_len;
442 if (IS_DTLS(session))
444 int cookie_size;
446 DECR_LEN (len, 1);
447 cookie_size = data[pos++];
448 DECR_LEN (len, cookie_size);
449 pos+=cookie_size;
452 ret = _gnutls_server_restore_session (session, session_id, session_id_len);
454 if (session_id_len > 0) session->internals.resumption_requested = 1;
456 if (ret == 0)
457 { /* resumed using default TLS resumption! */
458 /* Parse only the safe renegotiation extension
459 * We don't want to parse any other extensions since
460 * we don't want new extension values to overwrite the
461 * resumed ones.
464 /* move forward to extensions */
465 DECR_LEN (len, 2);
466 suite_size = _gnutls_read_uint16 (&data[pos]);
467 pos += 2;
469 DECR_LEN (len, suite_size);
470 pos += suite_size;
472 DECR_LEN (len, 1);
473 comp_size = data[pos++]; /* z is the number of compression methods */
474 DECR_LEN (len, comp_size);
475 pos += comp_size;
477 ret = _gnutls_parse_extensions (session, GNUTLS_EXT_MANDATORY,
478 &data[pos], len);
479 if (ret < 0)
481 gnutls_assert ();
482 return ret;
485 resume_copy_required_values (session);
486 session->internals.resumed = RESUME_TRUE;
488 return _gnutls_user_hello_func (session, adv_version);
490 else
492 _gnutls_generate_session_id (session->security_parameters.session_id,
493 &session->
494 security_parameters.session_id_size);
496 session->internals.resumed = RESUME_FALSE;
499 /* Remember ciphersuites for later
501 DECR_LEN (len, 2);
502 suite_size = _gnutls_read_uint16 (&data[pos]);
503 pos += 2;
505 DECR_LEN (len, suite_size);
506 suite_ptr = &data[pos];
507 pos += suite_size;
509 /* Point to the compression methods
511 DECR_LEN (len, 1);
512 comp_size = data[pos++]; /* z is the number of compression methods */
514 DECR_LEN (len, comp_size);
515 comp_ptr = &data[pos];
516 pos += comp_size;
518 /* Parse the extensions (if any)
520 * Unconditionally try to parse extensions; safe renegotiation uses them in
521 * sslv3 and higher, even though sslv3 doesn't officially support them.
523 ret = _gnutls_parse_extensions (session, GNUTLS_EXT_APPLICATION,
524 &data[pos], len);
525 /* len is the rest of the parsed length */
526 if (ret < 0)
528 gnutls_assert ();
529 return ret;
532 ret = _gnutls_user_hello_func (session, adv_version);
533 if (ret < 0)
535 gnutls_assert ();
536 return ret;
539 ret = _gnutls_parse_extensions (session, GNUTLS_EXT_MANDATORY,
540 &data[pos], len);
541 if (ret < 0)
543 gnutls_assert ();
544 return ret;
547 ret = _gnutls_parse_extensions (session, GNUTLS_EXT_TLS, &data[pos], len);
548 if (ret < 0)
550 gnutls_assert ();
551 return ret;
554 /* resumed by session_ticket extension */
555 if (session->internals.resumed != RESUME_FALSE)
557 /* to indicate the client that the current session is resumed */
558 memcpy (session->internals.resumed_security_parameters.session_id,
559 session_id, session_id_len);
560 session->internals.resumed_security_parameters.session_id_size =
561 session_id_len;
563 session->internals.resumed_security_parameters.max_record_recv_size =
564 session->security_parameters.max_record_recv_size;
565 session->internals.resumed_security_parameters.max_record_send_size =
566 session->security_parameters.max_record_send_size;
568 resume_copy_required_values (session);
570 return _gnutls_user_hello_func (session, adv_version);
573 /* select an appropriate cipher suite
575 ret = _gnutls_server_select_suite (session, suite_ptr, suite_size);
576 if (ret < 0)
578 gnutls_assert ();
579 return ret;
582 /* select appropriate compression method */
583 ret = _gnutls_server_select_comp_method (session, comp_ptr, comp_size);
584 if (ret < 0)
586 gnutls_assert ();
587 return ret;
590 return 0;
593 /* This is to be called after sending CHANGE CIPHER SPEC packet
594 * and initializing encryption. This is the first encrypted message
595 * we send.
597 static int
598 _gnutls_send_finished (gnutls_session_t session, int again)
600 mbuffer_st *bufel;
601 uint8_t *data;
602 int ret;
603 size_t vdata_size = 0;
605 if (again == 0)
607 bufel = _gnutls_handshake_alloc (session, MAX_VERIFY_DATA_SIZE, MAX_VERIFY_DATA_SIZE);
608 if (bufel == NULL)
610 gnutls_assert ();
611 return GNUTLS_E_MEMORY_ERROR;
613 data = _mbuffer_get_udata_ptr (bufel);
615 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
617 ret =
618 _gnutls_ssl3_finished (session,
619 session->security_parameters.entity, data, 1);
620 _mbuffer_set_udata_size (bufel, 36);
622 else
623 { /* TLS 1.0+ */
624 ret = _gnutls_finished (session,
625 session->security_parameters.entity, data, 1);
626 _mbuffer_set_udata_size (bufel, 12);
629 if (ret < 0)
631 gnutls_assert ();
632 return ret;
635 vdata_size = _mbuffer_get_udata_size (bufel);
637 ret = _gnutls_ext_sr_finished (session, data, vdata_size, 0);
638 if (ret < 0)
640 gnutls_assert ();
641 return ret;
644 if ((session->internals.resumed == RESUME_FALSE
645 && session->security_parameters.entity == GNUTLS_CLIENT)
646 || (session->internals.resumed != RESUME_FALSE
647 && session->security_parameters.entity == GNUTLS_SERVER))
649 /* if we are a client not resuming - or we are a server resuming */
650 _gnutls_handshake_log ("HSK[%p]: recording tls-unique CB (send)\n",
651 session);
652 memcpy (session->internals.cb_tls_unique, data, vdata_size);
653 session->internals.cb_tls_unique_len = vdata_size;
656 ret =
657 _gnutls_send_handshake (session, bufel, GNUTLS_HANDSHAKE_FINISHED);
659 else
661 ret = _gnutls_send_handshake (session, NULL, GNUTLS_HANDSHAKE_FINISHED);
664 return ret;
667 /* This is to be called after sending our finished message. If everything
668 * went fine we have negotiated a secure connection
670 static int
671 _gnutls_recv_finished (gnutls_session_t session)
673 uint8_t data[MAX_VERIFY_DATA_SIZE], *vrfy;
674 gnutls_buffer_st buf;
675 int data_size;
676 int ret;
677 int vrfy_size;
679 ret =
680 _gnutls_recv_handshake (session, GNUTLS_HANDSHAKE_FINISHED,
681 0, &buf);
682 if (ret < 0)
684 ERR ("recv finished int", ret);
685 gnutls_assert ();
686 return ret;
689 vrfy = buf.data;
690 vrfy_size = buf.length;
692 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
694 data_size = 36;
696 else
698 data_size = 12;
701 if (vrfy_size != data_size)
703 gnutls_assert ();
704 ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
705 goto cleanup;
708 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
710 ret =
711 _gnutls_ssl3_finished (session,
712 (session->security_parameters.entity + 1) % 2,
713 data, 0);
715 else
716 { /* TLS 1.0 */
717 ret =
718 _gnutls_finished (session,
719 (session->security_parameters.entity +
720 1) % 2, data, 0);
723 if (ret < 0)
725 gnutls_assert ();
726 goto cleanup;
729 if (memcmp (vrfy, data, data_size) != 0)
731 gnutls_assert ();
732 ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
733 goto cleanup;
736 ret = _gnutls_ext_sr_finished (session, data, data_size, 1);
737 if (ret < 0)
739 gnutls_assert ();
740 goto cleanup;
743 if ((session->internals.resumed != RESUME_FALSE
744 && session->security_parameters.entity == GNUTLS_CLIENT)
745 || (session->internals.resumed == RESUME_FALSE
746 && session->security_parameters.entity == GNUTLS_SERVER))
748 /* if we are a client resuming - or we are a server not resuming */
749 _gnutls_handshake_log ("HSK[%p]: recording tls-unique CB (recv)\n",
750 session);
751 memcpy (session->internals.cb_tls_unique, data, data_size);
752 session->internals.cb_tls_unique_len = data_size;
756 session->internals.initial_negotiation_completed = 1;
758 cleanup:
759 _gnutls_buffer_clear(&buf);
761 return ret;
764 /* returns PK_RSA if the given cipher suite list only supports,
765 * RSA algorithms, PK_DSA if DSS, and PK_ANY for both or PK_NONE for none.
767 static int
768 server_find_pk_algos_in_ciphersuites (const uint8_t *
769 data, unsigned int datalen,
770 gnutls_pk_algorithm_t * algos,
771 size_t* algos_size)
773 unsigned int j;
774 gnutls_kx_algorithm_t kx;
775 unsigned int max = *algos_size;
777 if (datalen % 2 != 0)
779 gnutls_assert ();
780 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
783 *algos_size = 0;
784 for (j = 0; j < datalen; j += 2)
786 kx = _gnutls_cipher_suite_get_kx_algo (&data[j]);
787 if (_gnutls_map_kx_get_cred (kx, 1) == GNUTLS_CRD_CERTIFICATE)
789 algos[(*algos_size)++] = _gnutls_map_pk_get_pk (kx);
791 if ((*algos_size) >= max)
792 return 0;
796 return 0;
799 /* This selects the best supported ciphersuite from the given ones. Then
800 * it adds the suite to the session and performs some checks.
803 _gnutls_server_select_suite (gnutls_session_t session, uint8_t * data,
804 unsigned int datalen)
806 int ret;
807 unsigned int i, j, cipher_suites_size;
808 size_t pk_algos_size;
809 uint8_t cipher_suites[MAX_CIPHERSUITE_SIZE];
810 int retval, err;
811 gnutls_pk_algorithm_t pk_algos[MAX_ALGOS]; /* will hold the pk algorithms
812 * supported by the peer.
815 /* First, check for safe renegotiation SCSV.
817 if (session->internals.priorities.sr != SR_DISABLED)
819 unsigned int offset;
821 for (offset = 0; offset < datalen; offset += 2)
823 /* TLS_RENEGO_PROTECTION_REQUEST = { 0x00, 0xff } */
824 if (data[offset] == GNUTLS_RENEGO_PROTECTION_REQUEST_MAJOR &&
825 data[offset + 1] == GNUTLS_RENEGO_PROTECTION_REQUEST_MINOR)
827 _gnutls_handshake_log
828 ("HSK[%p]: Received safe renegotiation CS\n", session);
829 retval = _gnutls_ext_sr_recv_cs (session);
830 if (retval < 0)
832 gnutls_assert ();
833 return retval;
835 break;
840 pk_algos_size = MAX_ALGOS;
841 ret = server_find_pk_algos_in_ciphersuites (data, datalen, pk_algos, &pk_algos_size);
842 if (ret < 0)
843 return gnutls_assert_val(ret);
845 ret = _gnutls_supported_ciphersuites (session, cipher_suites, sizeof(cipher_suites));
846 if (ret < 0)
847 return gnutls_assert_val(ret);
849 cipher_suites_size = ret;
851 /* Here we remove any ciphersuite that does not conform
852 * the certificate requested, or to the
853 * authentication requested (e.g. SRP).
855 ret = _gnutls_remove_unwanted_ciphersuites (session, cipher_suites, cipher_suites_size, pk_algos, pk_algos_size);
856 if (ret <= 0)
858 gnutls_assert ();
859 if (ret < 0)
860 return ret;
861 else
862 return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
865 cipher_suites_size = ret;
867 /* Data length should be zero mod 2 since
868 * every ciphersuite is 2 bytes. (this check is needed
869 * see below).
871 if (datalen % 2 != 0)
873 gnutls_assert ();
874 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
877 memset (session->security_parameters.cipher_suite, 0, 2);
879 retval = GNUTLS_E_UNKNOWN_CIPHER_SUITE;
881 _gnutls_handshake_log ("HSK[%p]: Requested cipher suites[size: %d]: \n", session, (int)datalen);
883 if (session->internals.priorities.server_precedence == 0)
885 for (j = 0; j < datalen; j += 2)
887 _gnutls_handshake_log ("\t0x%.2x, 0x%.2x %s\n", data[j], data[j+1], _gnutls_cipher_suite_get_name (&data[j]));
888 for (i = 0; i < cipher_suites_size; i+=2)
890 if (memcmp (&cipher_suites[i], &data[j], 2) == 0)
892 _gnutls_handshake_log
893 ("HSK[%p]: Selected cipher suite: %s\n", session,
894 _gnutls_cipher_suite_get_name (&data[j]));
895 memcpy (session->security_parameters.cipher_suite,
896 &cipher_suites[i], 2);
897 _gnutls_epoch_set_cipher_suite (session, EPOCH_NEXT,
898 session->
899 security_parameters.cipher_suite);
902 retval = 0;
903 goto finish;
908 else /* server selects */
910 for (i = 0; i < cipher_suites_size; i+=2)
912 for (j = 0; j < datalen; j += 2)
914 if (memcmp (&cipher_suites[i], &data[j], 2) == 0)
916 _gnutls_handshake_log
917 ("HSK[%p]: Selected cipher suite: %s\n", session,
918 _gnutls_cipher_suite_get_name (&data[j]));
919 memcpy (session->security_parameters.cipher_suite,
920 &cipher_suites[i], 2);
921 _gnutls_epoch_set_cipher_suite (session, EPOCH_NEXT,
922 session->
923 security_parameters.cipher_suite);
926 retval = 0;
927 goto finish;
932 finish:
934 if (retval != 0)
936 gnutls_assert ();
937 return retval;
940 /* check if the credentials (username, public key etc.) are ok
942 if (_gnutls_get_kx_cred
943 (session,
944 _gnutls_cipher_suite_get_kx_algo (session->
945 security_parameters.cipher_suite),
946 &err) == NULL && err != 0)
948 gnutls_assert ();
949 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
953 /* set the mod_auth_st to the appropriate struct
954 * according to the KX algorithm. This is needed since all the
955 * handshake functions are read from there;
957 session->internals.auth_struct =
958 _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo
959 (session->
960 security_parameters.cipher_suite));
961 if (session->internals.auth_struct == NULL)
964 _gnutls_handshake_log
965 ("HSK[%p]: Cannot find the appropriate handler for the KX algorithm\n",
966 session);
967 gnutls_assert ();
968 return GNUTLS_E_INTERNAL_ERROR;
971 return 0;
976 /* This selects the best supported compression method from the ones provided
978 static int
979 _gnutls_server_select_comp_method (gnutls_session_t session,
980 uint8_t * data, int datalen)
982 int x, i, j;
983 uint8_t comps[MAX_ALGOS];
985 x = _gnutls_supported_compression_methods (session, comps, MAX_ALGOS);
986 if (x < 0)
988 gnutls_assert ();
989 return x;
992 if (session->internals.priorities.server_precedence == 0)
994 for (j = 0; j < datalen; j++)
996 for (i = 0; i < x; i++)
998 if (comps[i] == data[j])
1000 gnutls_compression_method_t method =
1001 _gnutls_compression_get_id (comps[i]);
1003 _gnutls_epoch_set_compression (session, EPOCH_NEXT, method);
1004 session->security_parameters.compression_method = method;
1006 _gnutls_handshake_log
1007 ("HSK[%p]: Selected Compression Method: %s\n", session,
1008 gnutls_compression_get_name (method));
1009 return 0;
1014 else
1016 for (i = 0; i < x; i++)
1018 for (j = 0; j < datalen; j++)
1020 if (comps[i] == data[j])
1022 gnutls_compression_method_t method =
1023 _gnutls_compression_get_id (comps[i]);
1025 _gnutls_epoch_set_compression (session, EPOCH_NEXT, method);
1026 session->security_parameters.compression_method = method;
1028 _gnutls_handshake_log
1029 ("HSK[%p]: Selected Compression Method: %s\n", session,
1030 gnutls_compression_get_name (method));
1031 return 0;
1037 /* we were not able to find a compatible compression
1038 * algorithm
1040 gnutls_assert ();
1041 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
1045 /* This function sends an empty handshake packet. (like hello request).
1046 * If the previous _gnutls_send_empty_handshake() returned
1047 * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
1048 * (until it returns ok), with NULL parameters.
1050 static int
1051 _gnutls_send_empty_handshake (gnutls_session_t session,
1052 gnutls_handshake_description_t type, int again)
1054 mbuffer_st *bufel;
1056 if (again == 0)
1058 bufel = _gnutls_handshake_alloc (session, 0, 0);
1059 if (bufel == NULL)
1061 gnutls_assert ();
1062 return GNUTLS_E_MEMORY_ERROR;
1065 else
1066 bufel = NULL;
1068 return _gnutls_send_handshake (session, bufel, type);
1074 /* This function sends a handshake message of type 'type' containing the
1075 * data specified here. If the previous _gnutls_send_handshake() returned
1076 * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
1077 * (until it returns ok), with NULL parameters.
1080 _gnutls_send_handshake (gnutls_session_t session, mbuffer_st * bufel,
1081 gnutls_handshake_description_t type)
1083 int ret;
1084 uint8_t *data;
1085 uint32_t datasize, i_datasize;
1086 int pos = 0;
1088 if (bufel == NULL)
1090 /* we are resuming a previously interrupted
1091 * send.
1093 ret = _gnutls_handshake_io_write_flush (session);
1094 return ret;
1098 /* first run */
1099 data = _mbuffer_get_uhead_ptr (bufel);
1100 i_datasize = _mbuffer_get_udata_size(bufel);
1101 datasize = i_datasize + _mbuffer_get_uhead_size (bufel);
1103 data[pos++] = (uint8_t) type;
1104 _gnutls_write_uint24 (_mbuffer_get_udata_size (bufel), &data[pos]);
1105 pos += 3;
1107 /* Add DTLS handshake fragment headers. The message will be
1108 * fragmented later by the fragmentation sub-layer. All fields must
1109 * be set properly for HMAC. The HMAC requires we pretend that the
1110 * message was sent in a single fragment. */
1111 if (IS_DTLS(session))
1113 _gnutls_write_uint16 (session->internals.dtls.hsk_write_seq++, &data[pos]);
1114 pos += 2;
1116 /* Fragment offset */
1117 _gnutls_write_uint24 (0, &data[pos]);
1118 pos += 3;
1120 /* Fragment length */
1121 _gnutls_write_uint24 (i_datasize, &data[pos]);
1122 pos += 3;
1125 _gnutls_handshake_log ("HSK[%p]: %s was queued [%ld bytes]\n",
1126 session, _gnutls_handshake2str (type),
1127 (long) datasize);
1129 /* Here we keep the handshake messages in order to hash them...
1131 if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
1132 if ((ret =
1133 _gnutls_handshake_hash_add_sent (session, type, data, datasize)) < 0)
1135 gnutls_assert ();
1136 _mbuffer_xfree(&bufel);
1137 return ret;
1140 session->internals.last_handshake_out = type;
1142 ret = _gnutls_handshake_io_cache_int (session, type, bufel);
1143 if (ret < 0)
1145 _mbuffer_xfree(&bufel);
1146 gnutls_assert();
1147 return ret;
1150 switch (type)
1152 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT: /* this one is followed by ServerHelloDone
1153 * or ClientKeyExchange always.
1155 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE: /* as above */
1156 case GNUTLS_HANDSHAKE_SERVER_HELLO: /* as above */
1157 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST: /* as above */
1158 case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: /* followed by ChangeCipherSpec */
1160 /* now for client Certificate, ClientKeyExchange and
1161 * CertificateVerify are always followed by ChangeCipherSpec
1163 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
1164 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
1165 ret = 0;
1166 break;
1167 default:
1168 /* send cached messages */
1169 ret = _gnutls_handshake_io_write_flush (session);
1170 break;
1173 return ret;
1176 #define CHECK_SIZE(ll) \
1177 if ((session->internals.max_handshake_data_buffer_size > 0) && \
1178 (((ll) + session->internals.handshake_hash_buffer.length) > \
1179 session->internals.max_handshake_data_buffer_size)) \
1180 return gnutls_assert_val(GNUTLS_E_HANDSHAKE_TOO_LARGE)
1182 /* This function add the handshake headers and the
1183 * handshake data to the handshake hash buffers. Needed
1184 * for the finished messages calculations.
1186 static int
1187 _gnutls_handshake_hash_add_recvd (gnutls_session_t session,
1188 gnutls_handshake_description_t recv_type,
1189 uint8_t * header, uint16_t header_size,
1190 uint8_t * dataptr, uint32_t datalen)
1192 int ret;
1194 if ((gnutls_protocol_get_version (session) != GNUTLS_DTLS0_9 &&
1195 recv_type == GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST) ||
1196 recv_type == GNUTLS_HANDSHAKE_HELLO_REQUEST)
1197 return 0;
1199 CHECK_SIZE(header_size + datalen);
1201 session->internals.handshake_hash_buffer_prev_len = session->internals.handshake_hash_buffer.length;
1203 if (gnutls_protocol_get_version (session) != GNUTLS_DTLS0_9)
1205 ret = _gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
1206 header, header_size);
1207 if (ret < 0)
1208 return gnutls_assert_val(ret);
1210 if (datalen > 0)
1212 ret = _gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
1213 dataptr, datalen);
1214 if (ret < 0)
1215 return gnutls_assert_val(ret);
1218 return 0;
1221 /* This function will store the handshake message we sent.
1223 static int
1224 _gnutls_handshake_hash_add_sent (gnutls_session_t session,
1225 gnutls_handshake_description_t type,
1226 uint8_t * dataptr, uint32_t datalen)
1228 int ret;
1230 /* We don't check for GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST because it
1231 * is not sent via that channel.
1233 if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
1235 CHECK_SIZE(datalen);
1237 if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9)
1239 /* Old DTLS doesn't include the header in the MAC */
1240 if (datalen <= 12)
1242 gnutls_assert ();
1243 return GNUTLS_E_INVALID_REQUEST;
1245 dataptr += 12;
1246 datalen -= 12;
1249 ret = _gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
1250 dataptr, datalen);
1251 if (ret < 0)
1252 return gnutls_assert_val(ret);
1254 return 0;
1257 return 0;
1261 /* This function will receive handshake messages of the given types,
1262 * and will pass the message to the right place in order to be processed.
1263 * E.g. for the SERVER_HELLO message (if it is expected), it will be
1264 * passed to _gnutls_recv_hello().
1267 _gnutls_recv_handshake (gnutls_session_t session,
1268 gnutls_handshake_description_t type,
1269 unsigned int optional, gnutls_buffer_st* buf)
1271 int ret;
1272 handshake_buffer_st hsk;
1274 ret =
1275 _gnutls_handshake_io_recv_int (session, type, &hsk, optional);
1276 if (ret < 0)
1278 if (optional != 0 && ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET)
1280 if (buf) _gnutls_buffer_init(buf);
1281 return 0;
1284 return gnutls_assert_val_fatal(ret);
1287 ret = _gnutls_handshake_hash_add_recvd (session, hsk.htype,
1288 hsk.header, hsk.header_size,
1289 hsk.data.data, hsk.data.length);
1290 if (ret < 0)
1292 gnutls_assert ();
1293 goto cleanup;
1296 switch (hsk.htype)
1298 case GNUTLS_HANDSHAKE_CLIENT_HELLO_V2:
1299 case GNUTLS_HANDSHAKE_CLIENT_HELLO:
1300 case GNUTLS_HANDSHAKE_SERVER_HELLO:
1301 if (hsk.htype == GNUTLS_HANDSHAKE_CLIENT_HELLO_V2)
1302 ret = _gnutls_read_client_hello_v2 (session, hsk.data.data, hsk.data.length);
1303 else
1304 ret = _gnutls_recv_hello (session, hsk.data.data, hsk.data.length);
1306 if (ret < 0)
1308 gnutls_assert();
1309 goto cleanup;
1312 goto cleanup; /* caller doesn't need dataptr */
1314 break;
1315 case GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST:
1316 ret = _gnutls_recv_hello_verify_request (session, hsk.data.data, hsk.data.length);
1317 if (ret < 0)
1319 gnutls_assert();
1320 goto cleanup;
1322 else
1323 /* Signal our caller we have received a verification cookie
1324 and ClientHello needs to be sent again. */
1325 ret = 1;
1327 goto cleanup; /* caller doesn't need dataptr */
1329 break;
1330 case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
1331 if (hsk.data.length == 0)
1332 ret = 0;
1333 else
1335 gnutls_assert();
1336 ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1337 goto cleanup;
1339 break;
1340 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
1341 case GNUTLS_HANDSHAKE_FINISHED:
1342 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
1343 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
1344 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
1345 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
1346 case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
1347 case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET:
1348 ret = hsk.data.length;
1349 break;
1350 default:
1351 gnutls_assert ();
1352 /* we shouldn't actually arrive here in any case .
1353 * unexpected messages should be catched after _gnutls_handshake_io_recv_int()
1355 ret = GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
1356 goto cleanup;
1359 if (buf)
1361 *buf = hsk.data;
1362 return ret;
1365 cleanup:
1366 _gnutls_handshake_buffer_clear (&hsk);
1367 return ret;
1370 /* This function checks if the given cipher suite is supported, and sets it
1371 * to the session;
1373 static int
1374 _gnutls_client_set_ciphersuite (gnutls_session_t session, uint8_t suite[2])
1376 uint8_t z;
1377 uint8_t cipher_suites[MAX_CIPHERSUITE_SIZE];
1378 int cipher_suite_size;
1379 int i, err;
1381 z = 1;
1382 cipher_suite_size = _gnutls_supported_ciphersuites (session, cipher_suites, sizeof(cipher_suites));
1383 if (cipher_suite_size < 0)
1385 gnutls_assert ();
1386 return cipher_suite_size;
1389 for (i = 0; i < cipher_suite_size; i+=2)
1391 if (memcmp (&cipher_suites[i], suite, 2) == 0)
1393 z = 0;
1394 break;
1398 if (z != 0)
1400 gnutls_assert ();
1401 _gnutls_handshake_log("HSK[%p]: unsupported cipher suite %.2X.%.2X\n", session,
1402 (unsigned int)suite[0], (unsigned int)suite[1]);
1403 return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
1406 memcpy (session->security_parameters.cipher_suite, suite, 2);
1407 _gnutls_epoch_set_cipher_suite (session, EPOCH_NEXT,
1408 session->
1409 security_parameters.cipher_suite);
1411 _gnutls_handshake_log ("HSK[%p]: Selected cipher suite: %s\n", session,
1412 _gnutls_cipher_suite_get_name
1413 (session->
1414 security_parameters.cipher_suite));
1417 /* check if the credentials (username, public key etc.) are ok.
1418 * Actually checks if they exist.
1420 if (!session->internals.premaster_set &&
1421 _gnutls_get_kx_cred
1422 (session,
1423 _gnutls_cipher_suite_get_kx_algo
1424 (session->security_parameters.cipher_suite), &err) == NULL
1425 && err != 0)
1427 gnutls_assert ();
1428 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1432 /* set the mod_auth_st to the appropriate struct
1433 * according to the KX algorithm. This is needed since all the
1434 * handshake functions are read from there;
1436 session->internals.auth_struct =
1437 _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo
1438 (session->
1439 security_parameters.cipher_suite));
1441 if (session->internals.auth_struct == NULL)
1444 _gnutls_handshake_log
1445 ("HSK[%p]: Cannot find the appropriate handler for the KX algorithm\n",
1446 session);
1447 gnutls_assert ();
1448 return GNUTLS_E_INTERNAL_ERROR;
1452 return 0;
1455 /* This function sets the given comp method to the session.
1457 static int
1458 _gnutls_client_set_comp_method (gnutls_session_t session, uint8_t comp_method)
1460 int comp_methods_num;
1461 uint8_t compression_methods[MAX_ALGOS];
1462 int id = _gnutls_compression_get_id(comp_method);
1463 int i;
1465 _gnutls_handshake_log ("HSK[%p]: Selected compression method: %s (%d)\n", session,
1466 gnutls_compression_get_name(id), (int)comp_method);
1468 comp_methods_num = _gnutls_supported_compression_methods (session,
1469 compression_methods, MAX_ALGOS);
1470 if (comp_methods_num < 0)
1472 gnutls_assert ();
1473 return comp_methods_num;
1476 for (i = 0; i < comp_methods_num; i++)
1478 if (compression_methods[i] == comp_method)
1480 comp_methods_num = 0;
1481 break;
1485 if (comp_methods_num != 0)
1487 gnutls_assert ();
1488 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
1491 session->security_parameters.compression_method = id;
1492 _gnutls_epoch_set_compression (session, EPOCH_NEXT, id);
1494 return 0;
1497 /* This function returns 0 if we are resuming a session or -1 otherwise.
1498 * This also sets the variables in the session. Used only while reading a server
1499 * hello.
1501 static int
1502 _gnutls_client_check_if_resuming (gnutls_session_t session,
1503 uint8_t * session_id, int session_id_len)
1505 char buf[2 * TLS_MAX_SESSION_ID_SIZE + 1];
1507 _gnutls_handshake_log ("HSK[%p]: SessionID length: %d\n", session,
1508 session_id_len);
1509 _gnutls_handshake_log ("HSK[%p]: SessionID: %s\n", session,
1510 _gnutls_bin2hex (session_id, session_id_len, buf,
1511 sizeof (buf), NULL));
1513 if (session_id_len > 0 &&
1514 session->internals.resumed_security_parameters.session_id_size ==
1515 session_id_len
1516 && memcmp (session_id,
1517 session->internals.resumed_security_parameters.session_id,
1518 session_id_len) == 0)
1520 /* resume session */
1521 memcpy (session->internals.resumed_security_parameters.server_random,
1522 session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
1523 memcpy (session->internals.resumed_security_parameters.client_random,
1524 session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
1526 _gnutls_epoch_set_cipher_suite
1527 (session, EPOCH_NEXT,
1528 session->internals.
1529 resumed_security_parameters.cipher_suite);
1530 _gnutls_epoch_set_compression (session, EPOCH_NEXT,
1531 session->
1532 internals.resumed_security_parameters.compression_method);
1534 session->internals.resumed = RESUME_TRUE; /* we are resuming */
1536 return 0;
1538 else
1540 /* keep the new session id */
1541 session->internals.resumed = RESUME_FALSE; /* we are not resuming */
1542 session->security_parameters.session_id_size = session_id_len;
1543 memcpy (session->security_parameters.session_id,
1544 session_id, session_id_len);
1546 return -1;
1551 /* This function reads and parses the server hello handshake message.
1552 * This function also restores resumed parameters if we are resuming a
1553 * session.
1555 static int
1556 _gnutls_read_server_hello (gnutls_session_t session,
1557 uint8_t * data, int datalen)
1559 uint8_t session_id_len = 0;
1560 int pos = 0;
1561 int ret = 0;
1562 gnutls_protocol_t version;
1563 int len = datalen;
1565 if (datalen < 38)
1567 gnutls_assert ();
1568 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1571 _gnutls_handshake_log ("HSK[%p]: Server's version: %d.%d\n",
1572 session, data[pos], data[pos + 1]);
1574 DECR_LEN (len, 2);
1575 version = _gnutls_version_get (data[pos], data[pos + 1]);
1576 if (_gnutls_version_is_supported (session, version) == 0)
1578 gnutls_assert ();
1579 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
1581 else
1583 _gnutls_set_current_version (session, version);
1586 pos += 2;
1588 DECR_LEN (len, GNUTLS_RANDOM_SIZE);
1589 _gnutls_set_server_random (session, &data[pos]);
1590 pos += GNUTLS_RANDOM_SIZE;
1593 /* Read session ID
1595 DECR_LEN (len, 1);
1596 session_id_len = data[pos++];
1598 if (len < session_id_len)
1600 gnutls_assert ();
1601 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
1603 DECR_LEN (len, session_id_len);
1605 /* check if we are resuming and set the appropriate
1606 * values;
1608 if (_gnutls_client_check_if_resuming
1609 (session, &data[pos], session_id_len) == 0)
1611 pos += session_id_len + 2 + 1;
1612 DECR_LEN (len, 2 + 1);
1614 ret = _gnutls_parse_extensions (session, GNUTLS_EXT_MANDATORY,
1615 &data[pos], len);
1616 if (ret < 0)
1618 gnutls_assert ();
1619 return ret;
1621 return 0;
1624 pos += session_id_len;
1626 /* Check if the given cipher suite is supported and copy
1627 * it to the session.
1630 DECR_LEN (len, 2);
1631 ret = _gnutls_client_set_ciphersuite (session, &data[pos]);
1632 if (ret < 0)
1634 gnutls_assert ();
1635 return ret;
1637 pos += 2;
1639 /* move to compression
1641 DECR_LEN (len, 1);
1643 ret = _gnutls_client_set_comp_method (session, data[pos++]);
1644 if (ret < 0)
1646 gnutls_assert ();
1647 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
1650 /* Parse extensions.
1652 ret = _gnutls_parse_extensions (session, GNUTLS_EXT_ANY, &data[pos], len);
1653 if (ret < 0)
1655 gnutls_assert ();
1656 return ret;
1659 return ret;
1663 /* This function copies the appropriate ciphersuites to a locally allocated buffer
1664 * Needed in client hello messages. Returns the new data length. If add_scsv is
1665 * true, add the special safe renegotiation CS.
1667 static int
1668 _gnutls_copy_ciphersuites (gnutls_session_t session,
1669 gnutls_buffer_st * cdata,
1670 int add_scsv)
1672 int ret;
1673 uint8_t cipher_suites[MAX_CIPHERSUITE_SIZE+2];
1674 int cipher_suites_size;
1675 size_t init_length = cdata->length;
1677 ret = _gnutls_supported_ciphersuites (session, cipher_suites, sizeof(cipher_suites)-2);
1678 if (ret < 0)
1679 return gnutls_assert_val(ret);
1681 /* Here we remove any ciphersuite that does not conform
1682 * the certificate requested, or to the
1683 * authentication requested (eg SRP).
1685 ret =
1686 _gnutls_remove_unwanted_ciphersuites (session, cipher_suites, ret, NULL, 0);
1687 if (ret < 0)
1688 return gnutls_assert_val(ret);
1690 /* If no cipher suites were enabled.
1692 if (ret == 0)
1693 return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
1695 cipher_suites_size = ret;
1696 if (add_scsv)
1698 cipher_suites[cipher_suites_size] = 0x00;
1699 cipher_suites[cipher_suites_size+1] = 0xff;
1700 cipher_suites_size += 2;
1702 ret = _gnutls_ext_sr_send_cs (session);
1703 if (ret < 0)
1704 return gnutls_assert_val(ret);
1707 ret = _gnutls_buffer_append_data_prefix(cdata, 16, cipher_suites, cipher_suites_size);
1708 if (ret < 0)
1709 return gnutls_assert_val(ret);
1711 ret = cdata->length - init_length;
1713 return ret;
1717 /* This function copies the appropriate compression methods, to a locally allocated buffer
1718 * Needed in hello messages. Returns the new data length.
1720 static int
1721 _gnutls_copy_comp_methods (gnutls_session_t session,
1722 gnutls_buffer_st * cdata)
1724 int ret;
1725 uint8_t compression_methods[MAX_ALGOS], comp_num;
1726 size_t init_length = cdata->length;
1728 ret = _gnutls_supported_compression_methods (session, compression_methods, MAX_ALGOS);
1729 if (ret < 0)
1730 return gnutls_assert_val(ret);
1732 comp_num = ret;
1734 /* put the number of compression methods */
1735 ret = _gnutls_buffer_append_prefix(cdata, 8, comp_num);
1736 if (ret < 0)
1737 return gnutls_assert_val(ret);
1739 ret = _gnutls_buffer_append_data(cdata, compression_methods, comp_num);
1740 if (ret < 0)
1741 return gnutls_assert_val(ret);
1743 ret = cdata->length - init_length;
1745 return ret;
1748 /* This should be sufficient by now. It should hold all the extensions
1749 * plus the headers in a hello message.
1751 #define MAX_EXT_DATA_LENGTH 32*1024
1753 /* This function sends the client hello handshake message.
1755 static int
1756 _gnutls_send_client_hello (gnutls_session_t session, int again)
1758 mbuffer_st *bufel = NULL;
1759 uint8_t *data = NULL;
1760 int pos = 0, type;
1761 int datalen = 0, ret = 0;
1762 uint8_t rnd[GNUTLS_RANDOM_SIZE];
1763 gnutls_protocol_t hver;
1764 gnutls_buffer_st extdata;
1765 int rehandshake = 0;
1766 uint8_t session_id_len =
1767 session->internals.resumed_security_parameters.session_id_size;
1768 uint8_t cookie_len;
1770 _gnutls_buffer_init(&extdata);
1772 /* note that rehandshake is different than resuming
1774 if (session->security_parameters.session_id_size)
1775 rehandshake = 1;
1777 if (again == 0)
1779 if(IS_DTLS(session))
1781 cookie_len = session->internals.dtls.cookie_len + 1;
1783 else
1785 cookie_len = 0;
1788 datalen = 2 + (session_id_len + 1) + GNUTLS_RANDOM_SIZE + cookie_len;
1789 /* 2 for version, (4 for unix time + 28 for random bytes==GNUTLS_RANDOM_SIZE)
1792 bufel = _gnutls_handshake_alloc (session, datalen, datalen+MAX_EXT_DATA_LENGTH);
1793 if (bufel == NULL)
1795 gnutls_assert ();
1796 return GNUTLS_E_MEMORY_ERROR;
1798 data = _mbuffer_get_udata_ptr (bufel);
1800 /* if we are resuming a session then we set the
1801 * version number to the previously established.
1803 if (session_id_len == 0)
1805 if (rehandshake) /* already negotiated version thus version_max == negotiated version */
1806 hver = session->security_parameters.version;
1807 else /* new handshake. just get the max */
1808 hver = _gnutls_version_max (session);
1810 else
1812 /* we are resuming a session */
1813 hver = session->internals.resumed_security_parameters.version;
1816 if (hver == GNUTLS_VERSION_UNKNOWN || hver == 0)
1818 gnutls_assert ();
1819 gnutls_free (bufel);
1820 return GNUTLS_E_INTERNAL_ERROR;
1823 data[pos++] = _gnutls_version_get_major (hver);
1824 data[pos++] = _gnutls_version_get_minor (hver);
1826 /* Set the version we advertized as maximum
1827 * (RSA uses it).
1829 _gnutls_set_adv_version (session, hver);
1830 _gnutls_set_current_version (session, hver);
1832 if (session->internals.priorities.ssl3_record_version != 0)
1834 /* Advertize the SSL 3.0 record packet version in
1835 * record packets during the handshake.
1836 * That is to avoid confusing implementations
1837 * that do not support TLS 1.2 and don't know
1838 * how 3,3 version of record packets look like.
1840 if (!IS_DTLS(session))
1841 _gnutls_record_set_default_version (session, 3, 0);
1842 else if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9)
1843 _gnutls_record_set_default_version (session, 1, 0);
1844 else
1845 _gnutls_record_set_default_version (session, 254, 255);
1848 /* In order to know when this session was initiated.
1850 session->security_parameters.timestamp = gnutls_time (NULL);
1852 /* Generate random data
1854 if (!IS_DTLS (session)
1855 || session->internals.dtls.hsk_hello_verify_requests == 0)
1857 _gnutls_tls_create_random (rnd);
1858 _gnutls_set_client_random (session, rnd);
1860 memcpy (&data[pos], rnd, GNUTLS_RANDOM_SIZE);
1862 else
1863 memcpy (&data[pos], session->security_parameters.client_random, GNUTLS_RANDOM_SIZE);
1865 pos += GNUTLS_RANDOM_SIZE;
1867 /* Copy the Session ID
1869 data[pos++] = session_id_len;
1871 if (session_id_len > 0)
1873 memcpy (&data[pos],
1874 session->internals.resumed_security_parameters.session_id,
1875 session_id_len);
1876 pos += session_id_len;
1879 /* Copy the DTLS cookie
1881 if (IS_DTLS(session))
1883 data[pos++] = session->internals.dtls.cookie_len;
1884 memcpy(&data[pos], &session->internals.dtls.cookie, session->internals.dtls.cookie_len);
1885 pos += session->internals.dtls.cookie_len;
1888 /* Copy the ciphersuites.
1890 * If using SSLv3 Send TLS_RENEGO_PROTECTION_REQUEST SCSV for MITM
1891 * prevention on initial negotiation (but not renegotiation; that's
1892 * handled with the RI extension below).
1894 if (!session->internals.initial_negotiation_completed &&
1895 session->security_parameters.entity == GNUTLS_CLIENT &&
1896 (gnutls_protocol_get_version (session) == GNUTLS_SSL3 ||
1897 session->internals.priorities.no_extensions != 0))
1899 ret =
1900 _gnutls_copy_ciphersuites (session, &extdata, TRUE);
1901 _gnutls_extension_list_add (session,
1902 GNUTLS_EXTENSION_SAFE_RENEGOTIATION);
1904 else
1905 ret = _gnutls_copy_ciphersuites (session, &extdata, FALSE);
1907 if (ret < 0)
1909 gnutls_assert();
1910 goto cleanup;
1913 /* Copy the compression methods.
1915 ret = _gnutls_copy_comp_methods (session, &extdata);
1916 if (ret < 0)
1918 gnutls_assert();
1919 goto cleanup;
1922 /* Generate and copy TLS extensions.
1924 if (session->internals.priorities.no_extensions == 0)
1926 if (_gnutls_version_has_extensions (hver))
1927 type = GNUTLS_EXT_ANY;
1928 else
1930 if (session->internals.initial_negotiation_completed != 0)
1931 type = GNUTLS_EXT_MANDATORY;
1932 else
1933 type = GNUTLS_EXT_NONE;
1936 ret = _gnutls_gen_extensions (session, &extdata, type);
1937 if (ret < 0)
1939 gnutls_assert();
1940 goto cleanup;
1945 ret = _mbuffer_append_data (bufel, extdata.data, extdata.length);
1946 if (ret < 0)
1948 gnutls_assert ();
1949 goto cleanup;
1953 _gnutls_buffer_clear(&extdata);
1955 return
1956 _gnutls_send_handshake (session, bufel, GNUTLS_HANDSHAKE_CLIENT_HELLO);
1958 cleanup:
1959 _mbuffer_xfree(&bufel);
1960 _gnutls_buffer_clear(&extdata);
1961 return ret;
1964 static int
1965 _gnutls_send_server_hello (gnutls_session_t session, int again)
1967 mbuffer_st *bufel = NULL;
1968 uint8_t *data = NULL;
1969 gnutls_buffer_st extdata;
1970 int pos = 0;
1971 int datalen, ret = 0;
1972 uint8_t comp;
1973 uint8_t session_id_len = session->security_parameters.session_id_size;
1974 char buf[2 * TLS_MAX_SESSION_ID_SIZE + 1];
1976 datalen = 0;
1978 _gnutls_buffer_init(&extdata);
1980 if (again == 0)
1982 datalen = 2 + session_id_len + 1 + GNUTLS_RANDOM_SIZE + 3;
1983 ret =
1984 _gnutls_gen_extensions (session, &extdata, GNUTLS_EXT_ANY);
1985 if (ret < 0)
1987 gnutls_assert ();
1988 goto fail;
1991 bufel = _gnutls_handshake_alloc (session, datalen + extdata.length, datalen + extdata.length);
1992 if (bufel == NULL)
1994 gnutls_assert ();
1995 ret = GNUTLS_E_MEMORY_ERROR;
1996 goto fail;
1998 data = _mbuffer_get_udata_ptr (bufel);
2000 data[pos++] =
2001 _gnutls_version_get_major (session->security_parameters.version);
2002 data[pos++] =
2003 _gnutls_version_get_minor (session->security_parameters.version);
2005 memcpy (&data[pos],
2006 session->security_parameters.server_random, GNUTLS_RANDOM_SIZE);
2007 pos += GNUTLS_RANDOM_SIZE;
2009 data[pos++] = session_id_len;
2010 if (session_id_len > 0)
2012 memcpy (&data[pos], session->security_parameters.session_id,
2013 session_id_len);
2015 pos += session_id_len;
2017 _gnutls_handshake_log ("HSK[%p]: SessionID: %s\n", session,
2018 _gnutls_bin2hex (session->security_parameters.
2019 session_id, session_id_len, buf,
2020 sizeof (buf), NULL));
2022 memcpy (&data[pos],
2023 session->security_parameters.cipher_suite, 2);
2024 pos += 2;
2026 comp = _gnutls_compression_get_num ( session->security_parameters.compression_method);
2027 data[pos++] = comp;
2029 if (extdata.length > 0)
2031 datalen += extdata.length;
2032 memcpy (&data[pos], extdata.data, extdata.length);
2036 ret =
2037 _gnutls_send_handshake (session, bufel, GNUTLS_HANDSHAKE_SERVER_HELLO);
2039 fail:
2040 _gnutls_buffer_clear(&extdata);
2041 return ret;
2045 _gnutls_send_hello (gnutls_session_t session, int again)
2047 int ret;
2049 if (session->security_parameters.entity == GNUTLS_CLIENT)
2051 ret = _gnutls_send_client_hello (session, again);
2054 else
2055 { /* SERVER */
2056 ret = _gnutls_send_server_hello (session, again);
2059 return ret;
2062 /* RECEIVE A HELLO MESSAGE. This should be called from gnutls_recv_handshake_int only if a
2063 * hello message is expected. It uses the security_parameters.cipher_suite
2064 * and internals.compression_method.
2067 _gnutls_recv_hello (gnutls_session_t session, uint8_t * data, int datalen)
2069 int ret;
2071 if (session->security_parameters.entity == GNUTLS_CLIENT)
2073 ret = _gnutls_read_server_hello (session, data, datalen);
2074 if (ret < 0)
2076 gnutls_assert ();
2077 return ret;
2080 else
2081 { /* Server side reading a client hello */
2083 ret = _gnutls_read_client_hello (session, data, datalen);
2084 if (ret < 0)
2086 gnutls_assert ();
2087 return ret;
2091 ret = _gnutls_ext_sr_verify (session);
2092 if (ret < 0)
2094 gnutls_assert ();
2095 return ret;
2098 return 0;
2101 static int
2102 _gnutls_recv_hello_verify_request (gnutls_session_t session,
2103 uint8_t * data, int datalen)
2105 ssize_t len = datalen;
2106 size_t pos = 0;
2107 uint8_t cookie_len;
2108 unsigned int nb_verifs;
2110 if (!IS_DTLS (session)
2111 || session->security_parameters.entity == GNUTLS_SERVER)
2113 gnutls_assert ();
2114 return GNUTLS_E_INTERNAL_ERROR;
2117 nb_verifs = ++session->internals.dtls.hsk_hello_verify_requests;
2118 if (nb_verifs >= MAX_HANDSHAKE_HELLO_VERIFY_REQUESTS)
2120 /* The server is either buggy, malicious or changing cookie
2121 secrets _way_ too fast. */
2122 gnutls_assert ();
2123 return GNUTLS_E_UNEXPECTED_PACKET;
2126 /* TODO: determine if we need to do anything with the server version field */
2127 DECR_LEN (len, 2);
2128 pos += 2;
2130 DECR_LEN (len, 1);
2131 cookie_len = data[pos];
2132 pos++;
2134 if (cookie_len > DTLS_MAX_COOKIE_SIZE)
2136 gnutls_assert ();
2137 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
2140 DECR_LEN (len, cookie_len);
2142 session->internals.dtls.cookie_len = cookie_len;
2143 memcpy (session->internals.dtls.cookie, &data[pos], cookie_len);
2145 pos += cookie_len;
2147 if (len != 0)
2149 gnutls_assert ();
2150 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
2153 /* reset handshake hash buffers */
2154 _gnutls_handshake_hash_buffer_empty (session);
2156 return 0;
2159 /* The packets in gnutls_handshake (it's more broad than original TLS handshake)
2161 * Client Server
2163 * ClientHello -------->
2164 * <-------- ServerHello
2166 * Certificate*
2167 * ServerKeyExchange*
2168 * <-------- CertificateRequest*
2170 * <-------- ServerHelloDone
2171 * Certificate*
2172 * ClientKeyExchange
2173 * CertificateVerify*
2174 * [ChangeCipherSpec]
2175 * Finished -------->
2176 * NewSessionTicket
2177 * [ChangeCipherSpec]
2178 * <-------- Finished
2180 * (*): means optional packet.
2183 /* Handshake when resumming session:
2184 * Client Server
2186 * ClientHello -------->
2187 * ServerHello
2188 * [ChangeCipherSpec]
2189 * <-------- Finished
2190 * [ChangeCipherSpec]
2191 * Finished -------->
2196 * gnutls_rehandshake:
2197 * @session: is a #gnutls_session_t structure.
2199 * This function will renegotiate security parameters with the
2200 * client. This should only be called in case of a server.
2202 * This message informs the peer that we want to renegotiate
2203 * parameters (perform a handshake).
2205 * If this function succeeds (returns 0), you must call the
2206 * gnutls_handshake() function in order to negotiate the new
2207 * parameters.
2209 * Since TLS is full duplex some application data might have been
2210 * sent during peer's processing of this message. In that case
2211 * one should call gnutls_record_recv() until GNUTLS_E_REHANDSHAKE
2212 * is returned to clear any pending data. Care must be taken if
2213 * rehandshake is mandatory to terminate if it does not start after
2214 * some threshold.
2216 * If the client does not wish to renegotiate parameters he will
2217 * should with an alert message, thus the return code will be
2218 * %GNUTLS_E_WARNING_ALERT_RECEIVED and the alert will be
2219 * %GNUTLS_A_NO_RENEGOTIATION. A client may also choose to ignore
2220 * this message.
2222 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
2225 gnutls_rehandshake (gnutls_session_t session)
2227 int ret;
2229 /* only server sends that handshake packet */
2230 if (session->security_parameters.entity == GNUTLS_CLIENT)
2231 return GNUTLS_E_INVALID_REQUEST;
2233 _dtls_async_timer_delete(session);
2235 ret =
2236 _gnutls_send_empty_handshake (session, GNUTLS_HANDSHAKE_HELLO_REQUEST,
2237 AGAIN (STATE50));
2238 STATE = STATE50;
2240 if (ret < 0)
2242 gnutls_assert ();
2243 return ret;
2245 STATE = STATE0;
2247 return 0;
2250 inline static int
2251 _gnutls_abort_handshake (gnutls_session_t session, int ret)
2253 if (((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) &&
2254 (gnutls_alert_get (session) == GNUTLS_A_NO_RENEGOTIATION))
2255 || ret == GNUTLS_E_GOT_APPLICATION_DATA)
2256 return 0;
2258 /* this doesn't matter */
2259 return GNUTLS_E_INTERNAL_ERROR;
2264 static int
2265 _gnutls_send_supplemental (gnutls_session_t session, int again)
2267 mbuffer_st *bufel;
2268 int ret = 0;
2270 _gnutls_debug_log ("EXT[%p]: Sending supplemental data\n", session);
2272 if (again)
2273 ret =
2274 _gnutls_send_handshake (session, NULL, GNUTLS_HANDSHAKE_SUPPLEMENTAL);
2275 else
2277 gnutls_buffer_st buf;
2278 _gnutls_buffer_init (&buf);
2280 ret = _gnutls_gen_supplemental (session, &buf);
2281 if (ret < 0)
2283 gnutls_assert ();
2284 return ret;
2287 bufel = _gnutls_handshake_alloc(session, buf.length, buf.length);
2288 if (bufel == NULL)
2290 gnutls_assert ();
2291 return GNUTLS_E_MEMORY_ERROR;
2294 _mbuffer_set_udata (bufel, buf.data, buf.length);
2295 _gnutls_buffer_clear (&buf);
2297 ret = _gnutls_send_handshake (session, bufel,
2298 GNUTLS_HANDSHAKE_SUPPLEMENTAL);
2301 return ret;
2304 static int
2305 _gnutls_recv_supplemental (gnutls_session_t session)
2307 gnutls_buffer_st buf;
2308 int ret;
2310 _gnutls_debug_log ("EXT[%p]: Expecting supplemental data\n", session);
2312 ret = _gnutls_recv_handshake (session, GNUTLS_HANDSHAKE_SUPPLEMENTAL,
2313 1, &buf);
2314 if (ret < 0)
2316 gnutls_assert ();
2317 return ret;
2320 ret = _gnutls_parse_supplemental (session, buf.data, buf.length);
2321 if (ret < 0)
2323 gnutls_assert ();
2324 goto cleanup;
2327 cleanup:
2328 _gnutls_buffer_clear(&buf);
2330 return ret;
2334 * gnutls_handshake:
2335 * @session: is a #gnutls_session_t structure.
2337 * This function does the handshake of the TLS/SSL protocol, and
2338 * initializes the TLS connection.
2340 * This function will fail if any problem is encountered, and will
2341 * return a negative error code. In case of a client, if the client
2342 * has asked to resume a session, but the server couldn't, then a
2343 * full handshake will be performed.
2345 * The non-fatal errors such as %GNUTLS_E_AGAIN and
2346 * %GNUTLS_E_INTERRUPTED interrupt the handshake procedure, which
2347 * should be resumed later. Call this function again, until it
2348 * returns 0; cf. gnutls_record_get_direction() and
2349 * gnutls_error_is_fatal().
2351 * If this function is called by a server after a rehandshake request
2352 * then %GNUTLS_E_GOT_APPLICATION_DATA or
2353 * %GNUTLS_E_WARNING_ALERT_RECEIVED may be returned. Note that these
2354 * are non fatal errors, only in the specific case of a rehandshake.
2355 * Their meaning is that the client rejected the rehandshake request or
2356 * in the case of %GNUTLS_E_GOT_APPLICATION_DATA it might also mean that
2357 * some data were pending.
2359 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
2362 gnutls_handshake (gnutls_session_t session)
2364 int ret;
2365 record_parameters_st *params;
2367 /* sanity check. Verify that there are priorities setup.
2369 if (session->internals.priorities.protocol.algorithms == 0)
2370 return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET);
2372 ret = _gnutls_epoch_get (session, session->security_parameters.epoch_next,
2373 &params);
2374 if (ret < 0)
2376 /* We assume the epoch is not allocated if _gnutls_epoch_get fails. */
2377 ret =
2378 _gnutls_epoch_alloc (session, session->security_parameters.epoch_next,
2379 NULL);
2380 if (ret < 0)
2381 return gnutls_assert_val(ret);
2384 if (session->security_parameters.entity == GNUTLS_CLIENT)
2388 ret = _gnutls_handshake_client (session);
2389 } while (ret == 1);
2391 else
2393 ret = _gnutls_handshake_server (session);
2395 if (ret < 0)
2397 /* In the case of a rehandshake abort
2398 * we should reset the handshake's internal state.
2400 if (_gnutls_abort_handshake (session, ret) == 0)
2401 STATE = STATE0;
2403 return ret;
2406 ret = _gnutls_handshake_common (session);
2408 if (ret < 0)
2410 if (_gnutls_abort_handshake (session, ret) == 0)
2411 STATE = STATE0;
2413 return ret;
2416 STATE = STATE0;
2418 if (IS_DTLS(session)==0)
2420 _gnutls_handshake_io_buffer_clear (session);
2422 else
2424 _dtls_async_timer_init(session);
2427 _gnutls_handshake_internal_state_clear (session);
2429 session->security_parameters.epoch_next++;
2431 return 0;
2435 #define IMED_RET( str, ret, allow_alert) do { \
2436 if (ret < 0) { \
2437 /* EAGAIN and INTERRUPTED are always non-fatal */ \
2438 if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) \
2439 return ret; \
2440 /* a warning alert might interrupt handshake */ \
2441 if (allow_alert != 0 && ret==GNUTLS_E_WARNING_ALERT_RECEIVED) return ret; \
2442 gnutls_assert(); \
2443 ERR( str, ret); \
2444 _gnutls_handshake_hash_buffers_clear(session); \
2445 return ret; \
2446 } } while (0)
2451 * _gnutls_handshake_client
2452 * This function performs the client side of the handshake of the TLS/SSL protocol.
2455 _gnutls_handshake_client (gnutls_session_t session)
2457 int ret = 0;
2459 #ifdef HANDSHAKE_DEBUG
2460 char buf[64];
2462 if (session->internals.resumed_security_parameters.session_id_size > 0)
2463 _gnutls_handshake_log ("HSK[%p]: Ask to resume: %s\n", session,
2464 _gnutls_bin2hex (session->
2465 internals.resumed_security_parameters.session_id,
2466 session->
2467 internals.resumed_security_parameters.session_id_size,
2468 buf, sizeof (buf), NULL));
2469 #endif
2471 switch (STATE)
2473 case STATE0:
2474 case STATE1:
2475 ret = _gnutls_send_hello (session, AGAIN (STATE1));
2476 STATE = STATE1;
2477 IMED_RET ("send hello", ret, 1);
2479 case STATE11:
2480 if (IS_DTLS (session))
2482 ret =
2483 _gnutls_recv_handshake (session,
2484 GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST,
2485 1, NULL);
2486 STATE = STATE11;
2487 IMED_RET ("recv hello verify", ret, 1);
2489 if (ret == 1)
2491 STATE = STATE0;
2492 return 1;
2495 case STATE2:
2496 /* receive the server hello */
2497 ret =
2498 _gnutls_recv_handshake (session,
2499 GNUTLS_HANDSHAKE_SERVER_HELLO,
2500 0, NULL);
2501 STATE = STATE2;
2502 IMED_RET ("recv hello", ret, 1);
2504 case STATE70:
2505 if (session->security_parameters.do_recv_supplemental)
2507 ret = _gnutls_recv_supplemental (session);
2508 STATE = STATE70;
2509 IMED_RET ("recv supplemental", ret, 1);
2512 case STATE3:
2513 /* RECV CERTIFICATE */
2514 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2515 ret = _gnutls_recv_server_certificate (session);
2516 STATE = STATE3;
2517 IMED_RET ("recv server certificate", ret, 1);
2519 case STATE4:
2520 /* receive the server key exchange */
2521 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2522 ret = _gnutls_recv_server_kx_message (session);
2523 STATE = STATE4;
2524 IMED_RET ("recv server kx message", ret, 1);
2526 case STATE5:
2527 /* receive the server certificate request - if any
2530 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2531 ret = _gnutls_recv_server_crt_request (session);
2532 STATE = STATE5;
2533 IMED_RET ("recv server certificate request message", ret, 1);
2535 case STATE6:
2536 /* receive the server hello done */
2537 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2538 ret =
2539 _gnutls_recv_handshake (session,
2540 GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
2541 0, NULL);
2542 STATE = STATE6;
2543 IMED_RET ("recv server hello done", ret, 1);
2544 case STATE71:
2545 if (session->security_parameters.do_send_supplemental)
2547 ret = _gnutls_send_supplemental (session, AGAIN (STATE71));
2548 STATE = STATE71;
2549 IMED_RET ("send supplemental", ret, 0);
2552 case STATE7:
2553 /* send our certificate - if any and if requested
2555 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2556 ret = _gnutls_send_client_certificate (session, AGAIN (STATE7));
2557 STATE = STATE7;
2558 IMED_RET ("send client certificate", ret, 0);
2560 case STATE8:
2561 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2562 ret = _gnutls_send_client_kx_message (session, AGAIN (STATE8));
2563 STATE = STATE8;
2564 IMED_RET ("send client kx", ret, 0);
2566 case STATE9:
2567 /* send client certificate verify */
2568 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2569 ret =
2570 _gnutls_send_client_certificate_verify (session, AGAIN (STATE9));
2571 STATE = STATE9;
2572 IMED_RET ("send client certificate verify", ret, 1);
2574 STATE = STATE0;
2575 default:
2576 break;
2580 return 0;
2585 /* This function is to be called if the handshake was successfully
2586 * completed. This sends a Change Cipher Spec packet to the peer.
2588 static ssize_t
2589 send_change_cipher_spec (gnutls_session_t session, int again)
2591 uint8_t* data;
2592 mbuffer_st * bufel;
2593 int ret;
2595 if (again == 0)
2597 bufel = _gnutls_handshake_alloc (session, 1, 1);
2598 if (bufel == NULL)
2599 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2601 if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9)
2602 _mbuffer_set_uhead_size(bufel, 3);
2603 else
2604 _mbuffer_set_uhead_size(bufel, 1);
2605 _mbuffer_set_udata_size(bufel, 0);
2607 data = _mbuffer_get_uhead_ptr (bufel);
2609 data[0] = 1;
2610 if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9)
2612 _gnutls_write_uint16 (session->internals.dtls.hsk_write_seq, &data[1]);
2613 session->internals.dtls.hsk_write_seq++;
2616 ret = _gnutls_handshake_io_cache_int (session, GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC, bufel);
2617 if (ret < 0)
2619 _mbuffer_xfree(&bufel);
2620 return gnutls_assert_val(ret);
2623 _gnutls_handshake_log ("REC[%p]: Sent ChangeCipherSpec\n", session);
2626 return 0;
2629 /* This function sends the final handshake packets and initializes connection
2631 static int
2632 _gnutls_send_handshake_final (gnutls_session_t session, int init)
2634 int ret = 0;
2636 /* Send the CHANGE CIPHER SPEC PACKET */
2638 switch (STATE)
2640 case STATE0:
2641 case STATE20:
2642 ret = send_change_cipher_spec (session, AGAIN (STATE20));
2643 STATE = STATE0;
2645 if (ret < 0)
2647 ERR ("send ChangeCipherSpec", ret);
2648 gnutls_assert ();
2649 return ret;
2651 /* Initialize the connection session (start encryption) - in case of client
2653 if (init == TRUE)
2655 ret = _gnutls_connection_state_init (session);
2656 if (ret < 0)
2658 gnutls_assert ();
2659 return ret;
2663 ret = _gnutls_write_connection_state_init (session);
2664 if (ret < 0)
2666 gnutls_assert ();
2667 return ret;
2670 case STATE21:
2671 /* send the finished message */
2672 ret = _gnutls_send_finished (session, AGAIN (STATE21));
2673 STATE = STATE21;
2674 if (ret < 0)
2676 ERR ("send Finished", ret);
2677 gnutls_assert ();
2678 return ret;
2681 STATE = STATE0;
2682 default:
2683 break;
2686 return 0;
2689 /* This function receives the final handshake packets
2690 * And executes the appropriate function to initialize the
2691 * read session.
2693 static int
2694 _gnutls_recv_handshake_final (gnutls_session_t session, int init)
2696 int ret = 0;
2697 uint8_t ch;
2698 unsigned int ccs_len = 1;
2700 switch (STATE)
2702 case STATE0:
2703 case STATE30:
2704 STATE = STATE30;
2706 /* This is the last flight and peer cannot be sure
2707 * we have received it unless we notify him. So we
2708 * wait for a message and retransmit if needed. */
2709 if (IS_DTLS(session) && !_dtls_is_async(session) &&
2710 (gnutls_record_check_pending (session) +
2711 record_check_unprocessed (session)) == 0)
2713 ret = _dtls_wait_and_retransmit(session);
2714 if (ret < 0)
2715 return gnutls_assert_val(ret);
2718 if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9)
2719 ccs_len = 3;
2721 ret = _gnutls_recv_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, &ch, ccs_len, NULL);
2722 if (ret <= 0)
2724 ERR ("recv ChangeCipherSpec", ret);
2725 gnutls_assert ();
2726 return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
2729 if (gnutls_protocol_get_version (session) == GNUTLS_DTLS0_9)
2730 session->internals.dtls.hsk_read_seq++;
2732 /* Initialize the connection session (start encryption) - in case of server */
2733 if (init == TRUE)
2735 ret = _gnutls_connection_state_init (session);
2736 if (ret < 0)
2738 gnutls_assert ();
2739 return ret;
2743 ret = _gnutls_read_connection_state_init (session);
2744 if (ret < 0)
2746 gnutls_assert ();
2747 return ret;
2750 case STATE31:
2751 STATE = STATE31;
2753 if (IS_DTLS(session) && !_dtls_is_async(session) &&
2754 (gnutls_record_check_pending( session) +
2755 record_check_unprocessed (session)) == 0)
2757 ret = _dtls_wait_and_retransmit(session);
2758 if (ret < 0)
2759 return gnutls_assert_val(ret);
2762 ret = _gnutls_recv_finished (session);
2763 if (ret < 0)
2765 ERR ("recv finished", ret);
2766 gnutls_assert ();
2767 return ret;
2769 STATE = STATE0;
2770 default:
2771 break;
2775 return 0;
2779 * _gnutls_handshake_server
2780 * This function does the server stuff of the handshake protocol.
2783 _gnutls_handshake_server (gnutls_session_t session)
2785 int ret = 0;
2787 switch (STATE)
2789 case STATE0:
2790 case STATE1:
2791 ret =
2792 _gnutls_recv_handshake (session,
2793 GNUTLS_HANDSHAKE_CLIENT_HELLO,
2794 0, NULL);
2795 STATE = STATE1;
2796 IMED_RET ("recv hello", ret, 1);
2798 case STATE2:
2799 ret = _gnutls_send_hello (session, AGAIN (STATE2));
2800 STATE = STATE2;
2801 IMED_RET ("send hello", ret, 1);
2803 case STATE70:
2804 if (session->security_parameters.do_send_supplemental)
2806 ret = _gnutls_send_supplemental (session, AGAIN (STATE70));
2807 STATE = STATE70;
2808 IMED_RET ("send supplemental data", ret, 0);
2811 /* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
2812 case STATE3:
2813 /* NOTE: these should not be send if we are resuming */
2815 if (session->internals.resumed == RESUME_FALSE)
2816 ret = _gnutls_send_server_certificate (session, AGAIN (STATE3));
2817 STATE = STATE3;
2818 IMED_RET ("send server certificate", ret, 0);
2820 case STATE4:
2821 /* send server key exchange (A) */
2822 if (session->internals.resumed == RESUME_FALSE)
2823 ret = _gnutls_send_server_kx_message (session, AGAIN (STATE4));
2824 STATE = STATE4;
2825 IMED_RET ("send server kx", ret, 0);
2827 case STATE5:
2828 /* Send certificate request - if requested to */
2829 if (session->internals.resumed == RESUME_FALSE)
2830 ret =
2831 _gnutls_send_server_crt_request (session, AGAIN (STATE5));
2832 STATE = STATE5;
2833 IMED_RET ("send server cert request", ret, 0);
2835 case STATE6:
2836 /* send the server hello done */
2837 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2838 ret =
2839 _gnutls_send_empty_handshake (session,
2840 GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
2841 AGAIN (STATE6));
2842 STATE = STATE6;
2843 IMED_RET ("send server hello done", ret, 1);
2845 case STATE71:
2846 if (session->security_parameters.do_recv_supplemental)
2848 ret = _gnutls_recv_supplemental (session);
2849 STATE = STATE71;
2850 IMED_RET ("recv client supplemental", ret, 1);
2853 /* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_VERIFY */
2854 case STATE7:
2855 /* receive the client certificate message */
2856 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2857 ret = _gnutls_recv_client_certificate (session);
2858 STATE = STATE7;
2859 IMED_RET ("recv client certificate", ret, 1);
2861 case STATE8:
2862 /* receive the client key exchange message */
2863 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2864 ret = _gnutls_recv_client_kx_message (session);
2865 STATE = STATE8;
2866 IMED_RET ("recv client kx", ret, 1);
2868 case STATE9:
2869 /* receive the client certificate verify message */
2870 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2871 ret = _gnutls_recv_client_certificate_verify_message (session);
2872 STATE = STATE9;
2873 IMED_RET ("recv client certificate verify", ret, 1);
2875 STATE = STATE0; /* finished thus clear session */
2876 default:
2877 break;
2880 return 0;
2884 _gnutls_handshake_common (gnutls_session_t session)
2886 int ret = 0;
2888 /* send and recv the change cipher spec and finished messages */
2889 if ((session->internals.resumed != RESUME_FALSE
2890 && session->security_parameters.entity == GNUTLS_CLIENT)
2891 || (session->internals.resumed == RESUME_FALSE
2892 && session->security_parameters.entity == GNUTLS_SERVER))
2894 /* if we are a client resuming - or we are a server not resuming */
2895 ret = _gnutls_recv_handshake_final (session, TRUE);
2896 IMED_RET ("recv handshake final", ret, 1);
2898 switch (STATE)
2900 case STATE0:
2901 case STATE40:
2902 ret = _gnutls_send_new_session_ticket (session, AGAIN (STATE40));
2903 STATE = STATE40;
2904 IMED_RET ("send handshake new session ticket", ret, 0);
2905 STATE = STATE0;
2906 default:
2907 break;
2910 ret = _gnutls_send_handshake_final (session, FALSE);
2911 IMED_RET ("send handshake final", ret, 1);
2913 /* only store if we are not resuming a session and we didn't previously send a ticket
2915 if (session->security_parameters.entity == GNUTLS_SERVER && session->internals.ticket_sent == 0)
2917 /* in order to support session resuming */
2918 _gnutls_server_register_current_session (session);
2921 else
2922 { /* if we are a client not resuming - or we are a server resuming */
2924 ret = _gnutls_send_handshake_final (session, TRUE);
2925 IMED_RET ("send handshake final 2", ret, 1);
2927 switch (STATE)
2929 case STATE0:
2930 case STATE41:
2931 ret = _gnutls_recv_new_session_ticket (session);
2932 STATE = STATE41;
2933 IMED_RET ("recv handshake new session ticket", ret, 1);
2934 STATE = STATE0;
2935 default:
2936 break;
2939 ret = _gnutls_recv_handshake_final (session, FALSE);
2940 IMED_RET ("recv handshake final 2", ret, 1);
2945 /* clear handshake buffer */
2946 _gnutls_handshake_hash_buffers_clear (session);
2947 return ret;
2952 _gnutls_generate_session_id (uint8_t * session_id, uint8_t * len)
2954 int ret;
2956 *len = TLS_MAX_SESSION_ID_SIZE;
2958 ret = _gnutls_rnd (GNUTLS_RND_NONCE, session_id, *len);
2959 if (ret < 0)
2961 gnutls_assert ();
2962 return ret;
2965 return 0;
2969 _gnutls_recv_hello_request (gnutls_session_t session, void *data,
2970 uint32_t data_size)
2972 uint8_t type;
2974 if (session->security_parameters.entity == GNUTLS_SERVER)
2976 gnutls_assert ();
2977 return GNUTLS_E_UNEXPECTED_PACKET;
2979 if (data_size < 1)
2981 gnutls_assert ();
2982 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
2984 type = ((uint8_t *) data)[0];
2985 if (type == GNUTLS_HANDSHAKE_HELLO_REQUEST)
2987 if (IS_DTLS(session))
2988 session->internals.dtls.hsk_read_seq++;
2989 return GNUTLS_E_REHANDSHAKE;
2991 else
2993 gnutls_assert ();
2994 return GNUTLS_E_UNEXPECTED_PACKET;
2998 /* Returns 1 if the given KX has not the corresponding parameters
2999 * (DH or RSA) set up. Otherwise returns 0.
3001 inline static int
3002 check_server_params (gnutls_session_t session,
3003 gnutls_kx_algorithm_t kx,
3004 gnutls_kx_algorithm_t * alg, int alg_size)
3006 int cred_type;
3007 gnutls_dh_params_t dh_params = NULL;
3008 gnutls_rsa_params_t rsa_params = NULL;
3009 int j;
3011 cred_type = _gnutls_map_kx_get_cred (kx, 1);
3013 /* Read the Diffie-Hellman parameters, if any.
3015 if (cred_type == GNUTLS_CRD_CERTIFICATE)
3017 int delete;
3018 gnutls_certificate_credentials_t x509_cred =
3019 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
3020 cred_type, NULL);
3022 if (x509_cred != NULL)
3024 dh_params =
3025 _gnutls_get_dh_params (x509_cred->dh_params,
3026 x509_cred->params_func, session);
3027 rsa_params =
3028 _gnutls_certificate_get_rsa_params (x509_cred->rsa_params,
3029 x509_cred->params_func,
3030 session);
3033 /* Check also if the certificate supports the
3034 * KX method.
3036 delete = 1;
3037 for (j = 0; j < alg_size; j++)
3039 if (alg[j] == kx)
3041 delete = 0;
3042 break;
3046 if (delete == 1)
3047 return 1;
3049 #ifdef ENABLE_ANON
3051 else if (cred_type == GNUTLS_CRD_ANON)
3053 gnutls_anon_server_credentials_t anon_cred =
3054 (gnutls_anon_server_credentials_t) _gnutls_get_cred (session->key,
3055 cred_type, NULL);
3057 if (anon_cred != NULL)
3059 dh_params =
3060 _gnutls_get_dh_params (anon_cred->dh_params,
3061 anon_cred->params_func, session);
3063 #endif
3064 #ifdef ENABLE_PSK
3066 else if (cred_type == GNUTLS_CRD_PSK)
3068 gnutls_psk_server_credentials_t psk_cred =
3069 (gnutls_psk_server_credentials_t) _gnutls_get_cred (session->key,
3070 cred_type, NULL);
3072 if (psk_cred != NULL)
3074 dh_params =
3075 _gnutls_get_dh_params (psk_cred->dh_params, psk_cred->params_func,
3076 session);
3078 #endif
3080 else
3081 return 0; /* no need for params */
3084 /* If the key exchange method needs RSA or DH params,
3085 * but they are not set then remove it.
3087 if (_gnutls_kx_needs_rsa_params (kx) != 0)
3089 /* needs rsa params. */
3090 if (_gnutls_rsa_params_to_mpi (rsa_params) == NULL)
3092 gnutls_assert ();
3093 return 1;
3097 if (_gnutls_kx_needs_dh_params (kx) != 0)
3099 /* needs DH params. */
3100 if (_gnutls_dh_params_to_mpi (dh_params) == NULL)
3102 gnutls_assert ();
3103 return 1;
3107 return 0;
3110 /* This function will remove algorithms that are not supported by
3111 * the requested authentication method. We remove an algorithm if
3112 * we have a certificate with keyUsage bits set.
3114 * This does a more high level check than gnutls_supported_ciphersuites(),
3115 * by checking certificates etc.
3117 static int
3118 _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session,
3119 uint8_t * cipher_suites,
3120 int cipher_suites_size,
3121 gnutls_pk_algorithm_t *pk_algos,
3122 size_t pk_algos_size)
3125 int ret = 0;
3126 int i, new_suites_size;
3127 gnutls_certificate_credentials_t cert_cred;
3128 gnutls_kx_algorithm_t kx;
3129 int server = session->security_parameters.entity == GNUTLS_SERVER ? 1 : 0;
3130 gnutls_kx_algorithm_t alg[MAX_ALGOS];
3131 int alg_size = MAX_ALGOS;
3133 /* if we should use a specific certificate,
3134 * we should remove all algorithms that are not supported
3135 * by that certificate and are on the same authentication
3136 * method (CERTIFICATE).
3139 cert_cred =
3140 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
3141 GNUTLS_CRD_CERTIFICATE,
3142 NULL);
3144 /* If there are certificate credentials, find an appropriate certificate
3145 * or disable them;
3147 if (session->security_parameters.entity == GNUTLS_SERVER
3148 && cert_cred != NULL && pk_algos_size > 0)
3150 ret = _gnutls_server_select_cert (session, pk_algos, pk_algos_size);
3151 if (ret < 0)
3153 gnutls_assert ();
3154 _gnutls_debug_log ("Could not find an appropriate certificate: %s\n",
3155 gnutls_strerror (ret));
3159 /* get all the key exchange algorithms that are
3160 * supported by the X509 certificate parameters.
3162 if ((ret =
3163 _gnutls_selected_cert_supported_kx (session, alg, &alg_size)) < 0)
3165 gnutls_assert ();
3166 return ret;
3169 new_suites_size = 0;
3171 /* now removes ciphersuites based on the KX algorithm
3173 for (i = 0; i < cipher_suites_size; i+=2)
3175 int delete = 0;
3177 /* finds the key exchange algorithm in
3178 * the ciphersuite
3180 kx = _gnutls_cipher_suite_get_kx_algo (&cipher_suites[i]);
3182 /* if it is defined but had no credentials
3184 if (!session->internals.premaster_set &&
3185 _gnutls_get_kx_cred (session, kx, NULL) == NULL)
3187 delete = 1;
3189 else
3191 delete = 0;
3193 if (server)
3194 delete = check_server_params (session, kx, alg, alg_size);
3197 /* If we have not agreed to a common curve with the peer don't bother
3198 * negotiating ECDH.
3200 if (server != 0 && _gnutls_kx_is_ecc(kx))
3202 if (_gnutls_session_ecc_curve_get(session) == GNUTLS_ECC_CURVE_INVALID)
3204 delete = 1;
3208 /* These two SRP kx's are marked to require a CRD_CERTIFICATE,
3209 (see cred_mappings in gnutls_algorithms.c), but it also
3210 requires a SRP credential. Don't use SRP kx unless we have a
3211 SRP credential too. */
3212 if (kx == GNUTLS_KX_SRP_RSA || kx == GNUTLS_KX_SRP_DSS)
3214 if (!_gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL))
3216 delete = 1;
3220 if (delete == 0)
3223 _gnutls_handshake_log ("HSK[%p]: Keeping ciphersuite: %s (%.2X.%.2X)\n",
3224 session,
3225 _gnutls_cipher_suite_get_name (&cipher_suites[i]),
3226 cipher_suites[i], cipher_suites[i+1]);
3228 if (i != new_suites_size)
3229 memmove( &cipher_suites[new_suites_size], &cipher_suites[i], 2);
3230 new_suites_size+=2;
3232 else
3234 _gnutls_handshake_log ("HSK[%p]: Removing ciphersuite: %s\n",
3235 session,
3236 _gnutls_cipher_suite_get_name (&cipher_suites[i]));
3241 ret = new_suites_size;
3243 return ret;
3248 * gnutls_handshake_set_max_packet_length:
3249 * @session: is a #gnutls_session_t structure.
3250 * @max: is the maximum number.
3252 * This function will set the maximum size of all handshake messages.
3253 * Handshakes over this size are rejected with
3254 * %GNUTLS_E_HANDSHAKE_TOO_LARGE error code. The default value is
3255 * 48kb which is typically large enough. Set this to 0 if you do not
3256 * want to set an upper limit.
3258 * The reason for restricting the handshake message sizes are to
3259 * limit Denial of Service attacks.
3261 void
3262 gnutls_handshake_set_max_packet_length (gnutls_session_t session, size_t max)
3264 session->internals.max_handshake_data_buffer_size = max;
3267 void
3268 _gnutls_set_adv_version (gnutls_session_t session, gnutls_protocol_t ver)
3270 set_adv_version (session, _gnutls_version_get_major (ver),
3271 _gnutls_version_get_minor (ver));
3274 gnutls_protocol_t
3275 _gnutls_get_adv_version (gnutls_session_t session)
3277 return _gnutls_version_get (_gnutls_get_adv_version_major (session),
3278 _gnutls_get_adv_version_minor (session));
3282 * gnutls_handshake_get_last_in:
3283 * @session: is a #gnutls_session_t structure.
3285 * This function is only useful to check where the last performed
3286 * handshake failed. If the previous handshake succeed or was not
3287 * performed at all then no meaningful value will be returned.
3289 * Check %gnutls_handshake_description_t in gnutls.h for the
3290 * available handshake descriptions.
3292 * Returns: the last handshake message type received, a
3293 * %gnutls_handshake_description_t.
3295 gnutls_handshake_description_t
3296 gnutls_handshake_get_last_in (gnutls_session_t session)
3298 return session->internals.last_handshake_in;
3302 * gnutls_handshake_get_last_out:
3303 * @session: is a #gnutls_session_t structure.
3305 * This function is only useful to check where the last performed
3306 * handshake failed. If the previous handshake succeed or was not
3307 * performed at all then no meaningful value will be returned.
3309 * Check %gnutls_handshake_description_t in gnutls.h for the
3310 * available handshake descriptions.
3312 * Returns: the last handshake message type sent, a
3313 * %gnutls_handshake_description_t.
3315 gnutls_handshake_description_t
3316 gnutls_handshake_get_last_out (gnutls_session_t session)
3318 return session->internals.last_handshake_out;