added memory handling section
[gnutls.git] / lib / gnutls_handshake.c
blob9106d3b0ef35557d86a08c41ba03083d15f18350
1 /*
2 * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * The GNUTLS library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "gnutls_int.h"
23 #include "gnutls_errors.h"
24 #include "gnutls_dh.h"
25 #include "debug.h"
26 #include "gnutls_algorithms.h"
27 #include "gnutls_compress.h"
28 #include "gnutls_cipher.h"
29 #include "gnutls_buffers.h"
30 #include "gnutls_kx.h"
31 #include "gnutls_handshake.h"
32 #include "gnutls_num.h"
33 #include "gnutls_hash_int.h"
34 #include "gnutls_db.h"
35 #include "gnutls_extensions.h"
36 #include "gnutls_random.h"
37 #include "gnutls_auth_int.h"
38 #include "gnutls_v2_compat.h"
39 #include "auth_cert.h"
40 #include "gnutls_cert.h"
41 #include "gnutls_constate.h"
42 #include <gnutls_record.h>
43 #include <gnutls_alert.h>
44 #include <gnutls_state.h>
46 #ifdef HANDSHAKE_DEBUG
47 #define ERR(x, y) _gnutls_handshake_log( "HSK: %s (%d)\n", x,y)
48 #else
49 #define ERR(x, y)
50 #endif
52 #define TRUE 1
53 #define FALSE 0
55 int _gnutls_server_select_comp_method(GNUTLS_STATE state,
56 opaque * data, int datalen);
59 /* Clears the handshake hash buffers and handles.
61 inline static
62 void _gnutls_handshake_hash_buffers_clear( GNUTLS_STATE state) {
63 _gnutls_hash_deinit( state->gnutls_internals.handshake_mac_handle_md5, NULL);
64 _gnutls_hash_deinit( state->gnutls_internals.handshake_mac_handle_sha, NULL);
65 state->gnutls_internals.handshake_mac_handle_md5 = NULL;
66 state->gnutls_internals.handshake_mac_handle_sha = NULL;
67 _gnutls_handshake_buffer_clear( state);
70 /* this will copy the required values for resuming to
71 * gnutls_internals, and to security_parameters.
72 * this will keep as less data to security_parameters.
74 static void resume_copy_required_values(GNUTLS_STATE state)
76 /* get the new random values */
77 memcpy(state->gnutls_internals.resumed_security_parameters.
78 server_random,
79 state->security_parameters.server_random, TLS_RANDOM_SIZE);
80 memcpy(state->gnutls_internals.resumed_security_parameters.
81 client_random,
82 state->security_parameters.client_random, TLS_RANDOM_SIZE);
84 /* keep the ciphersuite and compression
85 * That is because the client must see these in our
86 * hello message.
88 memcpy(state->security_parameters.current_cipher_suite.
89 CipherSuite,
90 state->gnutls_internals.resumed_security_parameters.
91 current_cipher_suite.CipherSuite, 2);
93 state->gnutls_internals.compression_method = state->gnutls_internals.resumed_security_parameters.read_compression_algorithm; /* or write_compression_algorithm
94 * they are the same
97 state->security_parameters.entity =
98 state->gnutls_internals.resumed_security_parameters.entity;
100 _gnutls_set_current_version( state, state->gnutls_internals.resumed_security_parameters.version);
102 state->security_parameters.cert_type =
103 state->gnutls_internals.resumed_security_parameters.cert_type;
105 memcpy(state->security_parameters.session_id,
106 state->gnutls_internals.resumed_security_parameters.
107 session_id, sizeof(state->security_parameters.session_id));
108 state->security_parameters.session_id_size =
109 state->gnutls_internals.resumed_security_parameters.
110 session_id_size;
112 return;
115 void _gnutls_set_server_random(GNUTLS_STATE state, uint8 * random)
117 memcpy(state->security_parameters.server_random, random,
118 TLS_RANDOM_SIZE);
121 void _gnutls_set_client_random(GNUTLS_STATE state, uint8 * random)
123 memcpy(state->security_parameters.client_random, random,
124 TLS_RANDOM_SIZE);
127 /* Calculate The SSL3 Finished message */
128 #define SSL3_CLIENT_MSG "CLNT"
129 #define SSL3_SERVER_MSG "SRVR"
130 #define SSL_MSG_LEN 4
131 static int _gnutls_ssl3_finished(GNUTLS_STATE state, int type, opaque * ret)
133 const int siz = SSL_MSG_LEN;
134 GNUTLS_MAC_HANDLE td_md5;
135 GNUTLS_MAC_HANDLE td_sha;
136 char *mesg;
138 td_md5 = _gnutls_hash_copy( state->gnutls_internals.handshake_mac_handle_md5);
139 if (td_md5 == NULL) {
140 gnutls_assert();
141 return GNUTLS_E_HASH_FAILED;
144 td_sha = _gnutls_hash_copy( state->gnutls_internals.handshake_mac_handle_sha);
145 if (td_sha == NULL) {
146 gnutls_assert();
147 _gnutls_hash_deinit( td_md5, NULL);
148 return GNUTLS_E_HASH_FAILED;
151 if (type == GNUTLS_SERVER) {
152 mesg = SSL3_SERVER_MSG;
153 } else {
154 mesg = SSL3_CLIENT_MSG;
157 _gnutls_hash(td_md5, mesg, siz);
158 _gnutls_hash(td_sha, mesg, siz);
160 _gnutls_mac_deinit_ssl3_handshake(td_md5, ret, state->security_parameters.master_secret, TLS_MASTER_SIZE);
161 _gnutls_mac_deinit_ssl3_handshake(td_sha, &ret[16], state->security_parameters.master_secret, TLS_MASTER_SIZE);
163 return 0;
166 /* Hash the handshake messages as required by TLS 1.0 */
167 #define SERVER_MSG "server finished"
168 #define CLIENT_MSG "client finished"
169 #define TLS_MSG_LEN 15
170 int _gnutls_finished(GNUTLS_STATE state, int type, void *ret)
172 const int siz = TLS_MSG_LEN;
173 opaque concat[36];
174 opaque *mesg;
175 GNUTLS_MAC_HANDLE td_md5;
176 GNUTLS_MAC_HANDLE td_sha;
179 td_md5 = _gnutls_hash_copy( state->gnutls_internals.handshake_mac_handle_md5);
180 if (td_md5 == NULL) {
181 gnutls_assert();
182 return GNUTLS_E_HASH_FAILED;
185 td_sha = _gnutls_hash_copy( state->gnutls_internals.handshake_mac_handle_sha);
186 if (td_sha == NULL) {
187 gnutls_assert();
188 _gnutls_hash_deinit( td_md5, NULL);
189 return GNUTLS_E_HASH_FAILED;
193 _gnutls_hash_deinit(td_md5, concat);
194 _gnutls_hash_deinit(td_sha, &concat[16]);
196 if (type == GNUTLS_SERVER) {
197 mesg = SERVER_MSG;
198 } else {
199 mesg = CLIENT_MSG;
202 return _gnutls_PRF(state->security_parameters.master_secret,
203 TLS_MASTER_SIZE, mesg, siz, concat, 36,
204 12, ret);
207 /* this function will produce TLS_RANDOM_SIZE bytes of random data
208 * and put it to dst.
210 int _gnutls_create_random(opaque * dst)
212 uint32 tim;
213 opaque rand[TLS_RANDOM_SIZE - 4];
215 tim = time(NULL);
216 /* generate server random value */
217 _gnutls_write_uint32(tim, dst);
219 if (_gnutls_get_random
220 (rand, TLS_RANDOM_SIZE - 4, GNUTLS_STRONG_RANDOM) < 0) {
221 gnutls_assert();
222 return GNUTLS_E_MEMORY_ERROR;
224 memcpy(&dst[4], rand, 28);
226 return 0;
229 /* Read a client hello
230 * client hello must be a known version client hello
231 * or version 2.0 client hello (only for compatibility
232 * since SSL version 2.0 is not supported).
235 int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data,
236 int datalen)
238 uint8 session_id_len = 0, z;
239 int pos = 0;
240 int ret = 0;
241 uint16 sizeOfSuites;
242 GNUTLS_Version version;
243 int len = datalen;
244 opaque random[TLS_RANDOM_SIZE], *suite_ptr;
245 GNUTLS_Version ver;
247 if (state->gnutls_internals.v2_hello != 0) { /* version 2.0 */
248 return _gnutls_read_client_hello_v2(state, data, datalen);
250 DECR_LEN(len, 2);
252 _gnutls_handshake_log("HSK: Client's version: %d.%d\n", data[pos], data[pos + 1]);
254 version = _gnutls_version_get(data[pos], data[pos + 1]);
255 set_adv_version(state, data[pos], data[pos + 1]);
256 pos += 2;
258 /* if we do not support that version */
259 if (_gnutls_version_is_supported(state, version) == 0) {
260 /* If he requested something we do not support
261 * then we send him the lowest we support.
263 ver = _gnutls_version_lowest(state);
264 } else {
265 ver = version;
268 /* he should have send us the highest version
269 * he supports.
271 if (ver == GNUTLS_VERSION_UNKNOWN || ver > version) {
272 gnutls_assert();
273 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
275 _gnutls_set_current_version(state, ver);
277 /* Read client random value.
279 DECR_LEN(len, TLS_RANDOM_SIZE);
280 _gnutls_set_client_random(state, &data[pos]);
281 pos += TLS_RANDOM_SIZE;
283 _gnutls_create_random(random);
284 _gnutls_set_server_random(state, random);
286 state->security_parameters.timestamp = time(NULL);
288 DECR_LEN(len, 1);
289 session_id_len = data[pos++];
291 /* RESUME SESSION
293 if (session_id_len > TLS_MAX_SESSION_ID_SIZE) {
294 gnutls_assert();
295 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
297 DECR_LEN(len, session_id_len);
298 ret = _gnutls_server_restore_session(state, &data[pos], session_id_len);
299 pos += session_id_len;
301 if (ret == 0) { /* resumed! */
302 resume_copy_required_values(state);
304 state->gnutls_internals.resumed = RESUME_TRUE;
305 return 0;
306 } else {
307 _gnutls_generate_session_id(state->security_parameters.
308 session_id,
309 &state->security_parameters.
310 session_id_size);
312 state->gnutls_internals.resumed = RESUME_FALSE;
315 /* Select a ciphersuite
317 DECR_LEN(len, 2);
318 sizeOfSuites = _gnutls_read_uint16(&data[pos]);
319 pos += 2;
321 DECR_LEN(len, sizeOfSuites);
322 suite_ptr = &data[pos];
323 pos += sizeOfSuites;
325 /* Select an appropriate compression method
327 DECR_LEN(len, 1);
328 z = data[pos++]; /* z is the number of compression methods */
330 DECR_LEN(len, z);
331 ret = _gnutls_server_select_comp_method(state, &data[pos], z);
332 pos += z;
334 if (ret < 0) {
335 gnutls_assert();
336 return ret;
339 /* Parse the extensions (if any)
341 if (ver >= GNUTLS_TLS1) {
342 ret = _gnutls_parse_extensions(state, &data[pos], len); /* len is the rest of the parsed length */
343 if (ret < 0) {
344 gnutls_assert();
345 return ret;
349 /* select an appropriate cipher suite
351 ret = _gnutls_server_select_suite(state, suite_ptr, sizeOfSuites);
352 if (ret < 0) {
353 gnutls_assert();
354 return ret;
357 return 0;
360 /* here we hash all pending data.
362 inline static int
363 _gnutls_handshake_hash_pending( GNUTLS_STATE state) {
364 int siz, ret;
365 char * data;
367 if (state->gnutls_internals.handshake_mac_handle_sha==NULL ||
368 state->gnutls_internals.handshake_mac_handle_md5==NULL) {
369 gnutls_assert();
370 return GNUTLS_E_INTERNAL_ERROR;
373 /* We check if there are pending data to hash.
375 if ((ret=_gnutls_handshake_buffer_get_ptr(state, &data, &siz)) < 0) {
376 gnutls_assert();
377 return ret;
380 if (siz > 0) {
381 _gnutls_hash( state->gnutls_internals.handshake_mac_handle_sha, data, siz);
382 _gnutls_hash( state->gnutls_internals.handshake_mac_handle_md5, data, siz);
385 _gnutls_handshake_buffer_empty( state);
387 return 0;
391 /* This is to be called after sending CHANGE CIPHER SPEC packet
392 * and initializing encryption. This is the first encrypted message
393 * we send.
395 int _gnutls_send_finished(GNUTLS_STATE state, int again)
397 uint8 data[36];
398 int ret=0;
399 int data_size = 0;
402 if (again == 0) {
404 /* This needed in order to hash all the required
405 * messages.
407 if ((ret=_gnutls_handshake_hash_pending(state)) < 0) {
408 gnutls_assert();
409 return ret;
412 if (gnutls_protocol_get_version( state) == GNUTLS_SSL3) {
413 ret =
414 _gnutls_ssl3_finished(state,
415 state->
416 security_parameters.
417 entity, data);
418 data_size = 36;
419 } else { /* TLS 1.0 */
420 ret =
421 _gnutls_finished(state,
422 state->security_parameters.
423 entity, data);
424 data_size = 12;
428 if (ret < 0) {
429 gnutls_assert();
430 return ret;
433 ret =
434 _gnutls_send_handshake(state, data, data_size,
435 GNUTLS_FINISHED);
437 return ret;
440 /* This is to be called after sending our finished message. If everything
441 * went fine we have negotiated a secure connection
443 int _gnutls_recv_finished(GNUTLS_STATE state)
445 uint8 data[36], *vrfy;
446 int data_size;
447 int ret;
448 int vrfysize;
450 ret = 0;
452 ret =
453 _gnutls_recv_handshake(state, &vrfy, &vrfysize,
454 GNUTLS_FINISHED, MANDATORY_PACKET);
455 if (ret < 0) {
456 ERR("recv finished int", ret);
457 gnutls_assert();
458 return ret;
462 if ( gnutls_protocol_get_version( state) == GNUTLS_SSL3) {
463 data_size = 36;
464 } else {
465 data_size = 12;
468 if (vrfysize != data_size) {
469 gnutls_assert();
470 return GNUTLS_E_ERROR_IN_FINISHED_PACKET;
473 if (gnutls_protocol_get_version( state) == GNUTLS_SSL3) {
474 ret =
475 _gnutls_ssl3_finished(state,
476 (state->security_parameters.
477 entity + 1) % 2, data);
478 } else { /* TLS 1.0 */
479 ret =
480 _gnutls_finished(state,
481 (state->security_parameters.entity +
482 1) % 2, data);
485 if (ret < 0) {
486 gnutls_assert();
487 return ret;
490 if (memcmp(vrfy, data, data_size) != 0) {
491 gnutls_assert();
492 ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
494 gnutls_free(vrfy);
496 return ret;
499 /* returns PK_RSA if the given cipher suite list only supports,
500 * RSA algorithms, PK_DSA if DSS, and -1 if both or none.
502 int _gnutls_find_pk_algos_in_ciphersuites( opaque* data, int datalen) {
503 int j;
504 PKAlgorithm algo=-1, prev_algo = 0;
505 KXAlgorithm kx;
507 for (j = 0; j < datalen; j += 2) {
508 kx = _gnutls_cipher_suite_get_kx_algo(*((GNUTLS_CipherSuite *) & data[j]));
510 if ( _gnutls_map_kx_get_cred( kx) == GNUTLS_CRD_CERTIFICATE) {
511 algo = _gnutls_map_pk_get_pk( kx);
513 if (algo!=prev_algo && prev_algo!=0) return -1;
514 prev_algo = algo;
518 return algo;
522 /* This selects the best supported ciphersuite from the ones supported. Then
523 * it adds the suite into the state and performs some checks.
525 int _gnutls_server_select_suite(GNUTLS_STATE state, opaque *data, int datalen)
527 int x, i, j;
528 GNUTLS_CipherSuite *ciphers;
529 int retval, err;
530 PKAlgorithm pk_algo; /* will hold the pk algorithms
531 * supported by the peer.
534 pk_algo = _gnutls_find_pk_algos_in_ciphersuites( data, datalen);
536 x = _gnutls_supported_ciphersuites(state, &ciphers);
537 if (x<=0) {
538 gnutls_assert();
539 if (x<0) return x;
540 else return GNUTLS_E_INVALID_REQUEST;
543 /* Here we remove any ciphersuite that does not conform
544 * the certificate requested, or to the
545 * authentication requested (eg SRP).
547 x = _gnutls_remove_unwanted_ciphersuites(state, &ciphers, x, pk_algo);
548 if (x<=0) {
549 gnutls_assert();
550 if (x<0) return x;
551 else return GNUTLS_E_INSUFICIENT_CRED;
554 #ifdef HANDSHAKE_DEBUG
555 _gnutls_handshake_log("HSK: Requested cipher suites: \n");
556 for (j = 0; j < datalen; j += 2)
557 _gnutls_handshake_log("\t%s\n",
558 _gnutls_cipher_suite_get_name(*
559 ((GNUTLS_CipherSuite *) & data[j])));
560 _gnutls_handshake_log("HSK: Supported cipher suites: \n");
561 for (j = 0; j < x; j++)
562 _gnutls_handshake_log("\t%s\n",
563 _gnutls_cipher_suite_get_name(ciphers[j]));
564 #endif
565 memset(state->security_parameters.current_cipher_suite.CipherSuite, '\0', 2);
567 retval = GNUTLS_E_UNKNOWN_CIPHER_SUITE;
569 for (j = 0; j < datalen; j += 2) {
570 for (i = 0; i < x; i++) {
571 if (memcmp(ciphers[i].CipherSuite, &data[j], 2) ==
572 0) {
573 _gnutls_handshake_log("HSK: Selected cipher suite: ");
574 _gnutls_handshake_log("%s\n",
575 _gnutls_cipher_suite_get_name(*
576 ((GNUTLS_CipherSuite *) & data[j])));
577 memcpy(state->security_parameters.current_cipher_suite.CipherSuite, ciphers[i].CipherSuite, 2);
578 retval = 0;
579 goto finish;
584 finish:
585 gnutls_free(ciphers);
587 if (retval != 0) {
588 gnutls_assert();
589 return retval;
592 /* check if the credentials (username, public key etc. are ok)
594 if (_gnutls_get_kx_cred
595 (state->gnutls_key,
596 _gnutls_cipher_suite_get_kx_algo(state->security_parameters.
597 current_cipher_suite),
598 &err) == NULL && err != 0) {
599 gnutls_assert();
600 return GNUTLS_E_INSUFICIENT_CRED;
604 /* set the MOD_AUTH_STRUCT to the appropriate struct
605 * according to the KX algorithm. This is needed since all the
606 * handshake functions are read from there;
608 state->gnutls_internals.auth_struct =
609 _gnutls_kx_auth_struct(_gnutls_cipher_suite_get_kx_algo
610 (state->security_parameters.
611 current_cipher_suite));
612 if (state->gnutls_internals.auth_struct == NULL) {
614 _gnutls_handshake_log
615 ("HSK: Cannot find the appropriate handler for the KX algorithm\n");
616 gnutls_assert();
617 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
620 return 0;
625 /* This selects the best supported compression method from the ones provided */
626 int _gnutls_server_select_comp_method(GNUTLS_STATE state, opaque * data,
627 int datalen)
629 int x, i, j;
630 uint8 *ciphers;
632 x = _gnutls_supported_compression_methods(state, &ciphers);
633 memset( &state->gnutls_internals.compression_method, '\0', sizeof(CompressionMethod));
635 for (j = 0; j < datalen; j++) {
636 for (i = 0; i < x; i++) {
637 if (ciphers[i] == data[j]) {
638 state->gnutls_internals.compression_method =
639 _gnutls_compression_get_id(ciphers[i]);
640 gnutls_free(ciphers);
642 _gnutls_handshake_log("HSK: Selected Compression Method: %s\n",
643 gnutls_compression_get_name(state->gnutls_internals.
644 compression_method));
647 return 0;
652 /* we were not able to find a compatible compression
653 * algorithm
655 gnutls_free(ciphers);
656 gnutls_assert();
657 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
661 /* This function sends an empty handshake packet. (like hello request).
662 * If the previous _gnutls_send_empty_handshake() returned
663 * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
664 * (until it returns ok), with NULL parameters.
666 int _gnutls_send_empty_handshake(GNUTLS_STATE state, HandshakeType type,
667 int again)
669 opaque data = 0;
670 opaque *ptr;
672 if (again == 0)
673 ptr = &data;
674 else
675 ptr = NULL;
677 return _gnutls_send_handshake(state, ptr, 0, type);
681 /* This function will hash the handshake message we sent.
683 static
684 int _gnutls_handshake_hash_add_sent( GNUTLS_STATE state, HandshakeType type,
685 opaque* dataptr, uint32 datalen) {
686 int ret;
688 if ( (ret=_gnutls_handshake_hash_pending( state)) < 0) {
689 gnutls_assert();
690 return ret;
693 if ( type != GNUTLS_HELLO_REQUEST) {
694 _gnutls_hash( state->gnutls_internals.handshake_mac_handle_sha, dataptr, datalen);
695 _gnutls_hash( state->gnutls_internals.handshake_mac_handle_md5, dataptr, datalen);
698 return 0;
702 /* This function sends a handshake message of type 'type' containing the
703 * data specified here. If the previous _gnutls_send_handshake() returned
704 * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
705 * (until it returns ok), with NULL parameters.
707 int _gnutls_send_handshake(GNUTLS_STATE state, void *i_data,
708 uint32 i_datasize, HandshakeType type)
710 int ret;
711 uint8 *data;
712 uint32 datasize;
713 int pos = 0;
715 if (i_data == NULL && i_datasize == 0) {
716 /* we are resuming a previously interrupted
717 * send.
719 ret = _gnutls_handshake_io_write_flush(state);
720 return ret;
724 if (i_data == NULL && i_datasize > 0) {
725 gnutls_assert();
726 return GNUTLS_E_INVALID_PARAMETERS;
729 /* first run */
730 datasize = i_datasize + HANDSHAKE_HEADER_SIZE;
731 data = gnutls_alloca(datasize);
732 if (data == NULL) {
733 gnutls_assert();
734 return GNUTLS_E_MEMORY_ERROR;
737 data[pos++] = (uint8) type;
738 _gnutls_write_uint24(i_datasize, &data[pos]);
739 pos += 3;
741 if (i_datasize > 0)
742 memcpy(&data[pos], i_data, i_datasize);
744 _gnutls_handshake_log("HSK: %s was send [%ld bytes]\n",
745 _gnutls_handshake2str(type), datasize);
748 /* Here we keep the handshake messages in order to hash them...
750 if ( type != GNUTLS_HELLO_REQUEST)
751 if ( (ret= _gnutls_handshake_hash_add_sent( state, type, data, datasize)) < 0) {
752 gnutls_assert();
753 gnutls_afree(data);
754 return ret;
757 ret =
758 _gnutls_handshake_io_send_int(state, GNUTLS_HANDSHAKE, type,
759 data, datasize);
761 gnutls_afree(data);
763 return ret;
766 /* This function will read the handshake header, and return it to the called. If the
767 * received handshake packet is not the one expected then it buffers the header, and
768 * returns UNEXPECTED_HANDSHAKE_PACKET.
770 * FIXME: This function is complex.
772 #define SSL2_HEADERS 1
773 static int _gnutls_recv_handshake_header(GNUTLS_STATE state,
774 HandshakeType type,
775 HandshakeType * recv_type)
777 int ret;
778 uint32 length32 = 0;
779 uint8 *dataptr = NULL; /* for realloc */
780 int handshake_header_size = HANDSHAKE_HEADER_SIZE;
782 /* if we have data into the buffer then return them, do not read the next packet.
783 * In order to return we need a full TLS handshake header, or in case of a version 2
784 * packet, then we return the first byte.
786 if (state->gnutls_internals.handshake_header_buffer.header_size ==
787 handshake_header_size || (state->gnutls_internals.v2_hello != 0
788 && type == GNUTLS_CLIENT_HELLO
789 && state->gnutls_internals.
790 handshake_header_buffer.
791 packet_length > 0)) {
793 *recv_type =
794 state->gnutls_internals.handshake_header_buffer.
795 recv_type;
797 return state->gnutls_internals.handshake_header_buffer.
798 packet_length;
801 /* Note: SSL2_HEADERS == 1 */
803 dataptr = state->gnutls_internals.handshake_header_buffer.header;
805 /* If we haven't already read the handshake headers.
807 if (state->gnutls_internals.handshake_header_buffer.header_size <
808 SSL2_HEADERS) {
809 ret =
810 _gnutls_handshake_io_recv_int(state, GNUTLS_HANDSHAKE,
811 type, dataptr,
812 SSL2_HEADERS);
814 if (ret < 0) {
815 gnutls_assert();
816 return (ret <
817 0) ? ret :
818 GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
821 if (ret != SSL2_HEADERS) {
822 gnutls_assert();
823 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
825 state->gnutls_internals.handshake_header_buffer.
826 header_size = SSL2_HEADERS;
829 if (state->gnutls_internals.v2_hello == 0
830 || type != GNUTLS_CLIENT_HELLO) {
831 ret =
832 _gnutls_handshake_io_recv_int(state, GNUTLS_HANDSHAKE,
833 type,
834 &dataptr[state->
835 gnutls_internals.
836 handshake_header_buffer.
837 header_size],
838 HANDSHAKE_HEADER_SIZE -
839 state->gnutls_internals.
840 handshake_header_buffer.
841 header_size);
842 if (ret <= 0) {
843 gnutls_assert();
844 return (ret <
845 0) ? ret :
846 GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
848 if (ret !=
849 HANDSHAKE_HEADER_SIZE -
850 state->gnutls_internals.handshake_header_buffer.
851 header_size) {
852 gnutls_assert();
853 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
855 *recv_type = dataptr[0];
857 /* we do not use DECR_LEN because we know
858 * that the packet has enough data.
860 length32 = _gnutls_read_uint24(&dataptr[1]);
861 handshake_header_size = HANDSHAKE_HEADER_SIZE;
863 _gnutls_handshake_log("HSK: %s was received [%ld bytes]\n",
864 _gnutls_handshake2str(dataptr[0]),
865 length32 + HANDSHAKE_HEADER_SIZE);
867 } else { /* v2 hello */
868 length32 = state->gnutls_internals.v2_hello - SSL2_HEADERS; /* we've read the first byte */
870 handshake_header_size = SSL2_HEADERS; /* we've already read one byte */
872 *recv_type = dataptr[0];
874 _gnutls_handshake_log("HSK: %s(v2) was received [%ld bytes]\n",
875 _gnutls_handshake2str(*recv_type),
876 length32 + handshake_header_size);
878 if (*recv_type != GNUTLS_CLIENT_HELLO) { /* it should be one or nothing */
879 gnutls_assert();
880 return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
884 /* put the packet into the buffer */
885 state->gnutls_internals.handshake_header_buffer.header_size =
886 handshake_header_size;
887 state->gnutls_internals.handshake_header_buffer.packet_length =
888 length32;
889 state->gnutls_internals.handshake_header_buffer.recv_type =
890 *recv_type;
892 if (*recv_type != type) {
893 gnutls_assert();
894 return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
897 return length32;
900 #define _gnutls_handshake_header_buffer_clear( state) state->gnutls_internals.handshake_header_buffer.header_size = 0
904 /* This function will hash the handshake headers and the
905 * handshake data.
907 static
908 int _gnutls_handshake_hash_add_recvd( GNUTLS_STATE state, HandshakeType recv_type,
909 opaque* header, uint16 header_size, opaque* dataptr, uint32 datalen) {
910 int ret;
912 /* The idea here is to hash the previous message we received,
913 * and add the one we just received into the handshake_hash_buffer.
916 if ( (ret=_gnutls_handshake_hash_pending( state)) < 0) {
917 gnutls_assert();
918 return ret;
921 /* here we buffer the handshake messages - needed at Finished message */
922 if ( recv_type != GNUTLS_HELLO_REQUEST) {
924 if ((ret =
925 _gnutls_handshake_buffer_put(state,
926 header, header_size)) < 0) {
927 gnutls_assert();
928 return ret;
931 if ( datalen > 0) {
932 if ((ret =
933 _gnutls_handshake_buffer_put(state, dataptr,
934 datalen)) < 0) {
935 gnutls_assert();
936 return ret;
941 return 0;
945 /* This function will receive handshake messages of the given types,
946 * and will pass the message to the right place in order to be processed.
947 * Eg. for the SERVER_HELLO message (if it is expected), it will be
948 * send to _gnutls_recv_hello().
950 int _gnutls_recv_handshake(GNUTLS_STATE state, uint8 ** data,
951 int *datalen, HandshakeType type,
952 Optional optional)
954 int ret;
955 uint32 length32 = 0;
956 opaque *dataptr = NULL;
957 HandshakeType recv_type;
959 ret = _gnutls_recv_handshake_header(state, type, &recv_type);
960 if (ret < 0) {
961 if (ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET
962 && optional == OPTIONAL_PACKET) {
963 gnutls_assert();
964 *datalen = 0;
965 *data = NULL;
966 return 0; /* ok just ignore the packet */
968 gnutls_assert();
969 return ret;
973 length32 = ret;
975 if (length32 > 0)
976 dataptr = gnutls_malloc(length32);
977 else if (recv_type != GNUTLS_SERVER_HELLO_DONE) {
978 gnutls_assert();
979 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
982 if (dataptr == NULL && length32 > 0) {
983 gnutls_assert();
984 return GNUTLS_E_MEMORY_ERROR;
987 if (datalen != NULL)
988 *datalen = length32;
990 if (length32 > 0) {
991 ret =
992 _gnutls_handshake_io_recv_int(state, GNUTLS_HANDSHAKE,
993 type, dataptr, length32);
994 if (ret <= 0) {
995 gnutls_assert();
996 gnutls_free(dataptr);
997 return (ret ==
998 0) ? GNUTLS_E_UNEXPECTED_PACKET_LENGTH :
999 ret;
1004 ret = GNUTLS_E_UNKNOWN_ERROR;
1006 if (data != NULL && length32 > 0)
1007 *data = dataptr;
1010 if ( (ret=_gnutls_handshake_hash_add_recvd( state, recv_type,
1011 state->gnutls_internals.handshake_header_buffer.header,
1012 state->gnutls_internals.handshake_header_buffer.header_size,
1013 dataptr, length32)) < 0) {
1014 gnutls_assert();
1015 _gnutls_handshake_header_buffer_clear(state);
1016 return ret;
1019 /* If we fail before this then we will reuse the handshake header
1020 * have have received above. if we get here the we clear the handshake
1021 * header we received.
1023 _gnutls_handshake_header_buffer_clear(state);
1025 switch (recv_type) {
1026 case GNUTLS_CLIENT_HELLO:
1027 case GNUTLS_SERVER_HELLO:
1028 ret = _gnutls_recv_hello(state, dataptr, length32);
1029 /* dataptr is freed because the called does not
1030 * need it */
1031 gnutls_free(dataptr);
1032 break;
1033 case GNUTLS_CERTIFICATE_PKT:
1034 ret = length32;
1035 break;
1036 case GNUTLS_SERVER_HELLO_DONE:
1037 if (length32==0) ret = 0;
1038 else ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1039 break;
1040 case GNUTLS_FINISHED:
1041 ret = length32;
1042 break;
1043 case GNUTLS_SERVER_KEY_EXCHANGE:
1044 ret = length32;
1045 break;
1046 case GNUTLS_CLIENT_KEY_EXCHANGE:
1047 ret = length32;
1048 break;
1049 case GNUTLS_CERTIFICATE_REQUEST:
1050 ret = length32;
1051 break;
1052 case GNUTLS_CERTIFICATE_VERIFY:
1053 ret = length32;
1054 break;
1055 default:
1056 gnutls_assert();
1057 gnutls_free(dataptr);
1058 ret = GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
1061 return ret;
1064 /* This function checks if the given cipher suite is supported, and sets it
1065 * to the state;
1067 static int _gnutls_client_set_ciphersuite(GNUTLS_STATE state,
1068 opaque suite[2])
1070 uint8 z;
1071 GNUTLS_CipherSuite *cipher_suites;
1072 uint16 x;
1073 int i, err;
1075 z = 1;
1076 x = _gnutls_supported_ciphersuites(state, &cipher_suites);
1077 for (i = 0; i < x; i++) {
1078 if (memcmp(&cipher_suites[i], suite, 2) == 0) {
1079 z = 0;
1083 gnutls_free(cipher_suites);
1085 if (z != 0) {
1086 gnutls_assert();
1087 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
1090 memcpy(state->security_parameters.
1091 current_cipher_suite.CipherSuite, suite, 2);
1093 _gnutls_handshake_log("HSK: Selected cipher suite: ");
1094 _gnutls_handshake_log("%s\n",
1095 _gnutls_cipher_suite_get_name(state->
1096 security_parameters.
1097 current_cipher_suite));
1100 /* check if the credentials (username, public key etc. are ok).
1101 * Actually checks if they exist.
1103 if (_gnutls_get_kx_cred
1104 (state->gnutls_key,
1105 _gnutls_cipher_suite_get_kx_algo(state->
1106 security_parameters.
1107 current_cipher_suite),
1108 &err) == NULL && err != 0) {
1109 gnutls_assert();
1110 return GNUTLS_E_INSUFICIENT_CRED;
1114 /* set the MOD_AUTH_STRUCT to the appropriate struct
1115 * according to the KX algorithm. This is needed since all the
1116 * handshake functions are read from there;
1118 state->gnutls_internals.auth_struct =
1119 _gnutls_kx_auth_struct(_gnutls_cipher_suite_get_kx_algo
1120 (state->security_parameters.
1121 current_cipher_suite));
1123 if (state->gnutls_internals.auth_struct == NULL) {
1125 _gnutls_handshake_log
1126 ("HSK: Cannot find the appropriate handler for the KX algorithm\n");
1127 gnutls_assert();
1128 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
1132 return 0;
1135 /* This function sets the given comp method to the state.
1137 static int _gnutls_client_set_comp_method(GNUTLS_STATE state,
1138 opaque comp_method)
1140 uint8 z;
1141 uint8 *compression_methods;
1142 int i;
1144 z = _gnutls_supported_compression_methods(state,
1145 &compression_methods);
1146 for (i = 0; i < z; i++) {
1147 if (compression_methods[i] == comp_method) {
1148 z = 0;
1152 gnutls_free(compression_methods);
1154 if (z != 0) {
1155 gnutls_assert();
1156 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
1159 state->gnutls_internals.compression_method =
1160 _gnutls_compression_get_id(comp_method);
1163 return 0;
1166 /* This function returns 0 if we are resuming a session or -1 otherwise.
1167 * This also sets the variables in the state. Used only while reading a server
1168 * hello.
1170 static int _gnutls_client_check_if_resuming(GNUTLS_STATE state,
1171 opaque * session_id,
1172 int session_id_len)
1175 _gnutls_handshake_log("HSK: SessionID length: %d\n", session_id_len);
1176 _gnutls_handshake_log("HSK: SessionID: %s\n",
1177 _gnutls_bin2hex(session_id, session_id_len));
1179 if ((state->gnutls_internals.resumed_security_parameters.
1180 session_id_size > 0)
1181 && memcmp(session_id,
1182 state->gnutls_internals.
1183 resumed_security_parameters.session_id,
1184 session_id_len) == 0) {
1185 /* resume session */
1186 memcpy(state->gnutls_internals.
1187 resumed_security_parameters.server_random,
1188 state->security_parameters.server_random,
1189 TLS_RANDOM_SIZE);
1190 memcpy(state->gnutls_internals.
1191 resumed_security_parameters.client_random,
1192 state->security_parameters.client_random,
1193 TLS_RANDOM_SIZE);
1194 state->gnutls_internals.resumed = RESUME_TRUE; /* we are resuming */
1196 return 0;
1197 } else {
1198 /* keep the new session id */
1199 state->gnutls_internals.resumed = RESUME_FALSE; /* we are not resuming */
1200 state->security_parameters.session_id_size =
1201 session_id_len;
1202 memcpy(state->security_parameters.session_id,
1203 session_id, session_id_len);
1205 return -1;
1210 /* This function read and parse the server hello handshake message.
1211 * This function also restores resumed parameters if we are resuming a
1212 * session.
1214 static int _gnutls_read_server_hello(GNUTLS_STATE state, char *data,
1215 int datalen)
1217 uint8 session_id_len = 0;
1218 int pos = 0;
1219 int ret = 0;
1220 GNUTLS_Version version;
1221 int len = datalen;
1223 if (datalen < 38) {
1224 gnutls_assert();
1225 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1228 _gnutls_handshake_log("HSK: Server's version: %d.%d\n", data[pos], data[pos + 1]);
1230 DECR_LEN(len, 2);
1231 version = _gnutls_version_get(data[pos], data[pos + 1]);
1232 if (_gnutls_version_is_supported(state, version) == 0) {
1233 gnutls_assert();
1234 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
1235 } else {
1236 _gnutls_set_current_version(state, version);
1239 pos += 2;
1241 DECR_LEN(len, TLS_RANDOM_SIZE);
1242 _gnutls_set_server_random(state, &data[pos]);
1243 pos += TLS_RANDOM_SIZE;
1246 /* Read session ID
1248 DECR_LEN(len, 1);
1249 session_id_len = data[pos++];
1251 if (len < session_id_len) {
1252 gnutls_assert();
1253 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
1255 DECR_LEN(len, session_id_len);
1258 /* check if we are resuming and set the appropriate
1259 * values;
1261 if (_gnutls_client_check_if_resuming
1262 (state, &data[pos], session_id_len) == 0)
1263 return 0;
1264 pos += session_id_len;
1267 /* Check if the given cipher suite is supported and copy
1268 * it to the state.
1271 DECR_LEN(len, 2);
1272 ret = _gnutls_client_set_ciphersuite(state, &data[pos]);
1273 if (ret < 0) {
1274 gnutls_assert();
1275 return ret;
1277 pos += 2;
1281 /* move to compression
1283 DECR_LEN(len, 1);
1285 ret = _gnutls_client_set_comp_method(state, data[pos++]);
1286 if (ret < 0) {
1287 gnutls_assert();
1288 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
1291 /* Parse extensions.
1293 if (version >= GNUTLS_TLS1) {
1294 ret = _gnutls_parse_extensions(state, &data[pos], len); /* len is the rest of the parsed length */
1295 if (ret < 0) {
1296 gnutls_assert();
1297 return ret;
1300 return ret;
1303 /* This function copies the appropriate ciphersuites, to a localy allocated buffer
1304 * Needed in client hello messages. Returns the new data length.
1306 static int _gnutls_copy_ciphersuites(GNUTLS_STATE state,
1307 opaque ** ret_data)
1309 int ret, i;
1310 GNUTLS_CipherSuite *cipher_suites;
1311 uint16 x;
1312 int datalen, pos;
1314 ret = _gnutls_supported_ciphersuites_sorted(state, &cipher_suites);
1315 if (ret <= 0) {
1316 gnutls_assert();
1317 if (ret==0) return GNUTLS_E_INVALID_REQUEST;
1318 else return ret;
1321 /* Here we remove any ciphersuite that does not conform
1322 * the certificate requested, or to the
1323 * authentication requested (eg SRP).
1325 ret =
1326 _gnutls_remove_unwanted_ciphersuites(state, &cipher_suites,
1327 ret, -1);
1328 if (ret < 0) {
1329 gnutls_assert();
1330 return ret;
1332 if (ret==0) {
1333 gnutls_assert();
1334 return GNUTLS_E_INSUFICIENT_CRED;
1338 x = ret;
1339 x *= sizeof(uint16); /* in order to get bytes */
1341 datalen = pos = 0;
1343 datalen += sizeof(uint16) + x;
1345 *ret_data = gnutls_malloc(datalen);
1348 if (*ret_data == NULL) {
1349 gnutls_assert();
1350 return GNUTLS_E_MEMORY_ERROR;
1354 _gnutls_write_uint16(x, *ret_data);
1355 pos += 2;
1357 for (i = 0; i < x / 2; i++) {
1358 memcpy(&(*ret_data)[pos], cipher_suites[i].CipherSuite, 2);
1359 pos += 2;
1361 gnutls_free(cipher_suites);
1363 return datalen;
1367 /* This function copies the appropriate compression methods, to a localy allocated buffer
1368 * Needed in hello messages. Returns the new data length.
1370 static int _gnutls_copy_comp_methods(GNUTLS_STATE state,
1371 opaque ** ret_data)
1373 int ret, i;
1374 uint8 *compression_methods, z;
1375 int datalen, pos;
1377 ret =
1378 _gnutls_supported_compression_methods(state,
1379 &compression_methods);
1380 if (ret < 0) {
1381 gnutls_assert();
1382 return ret;
1385 z = ret;
1387 datalen = pos = 0;
1388 datalen += z + 1;
1390 *ret_data = gnutls_malloc(datalen);
1391 if (*ret_data == NULL) {
1392 gnutls_assert();
1393 return GNUTLS_E_MEMORY_ERROR;
1396 (*ret_data)[pos++] = z; /* put the number of compression methods */
1398 for (i = 0; i < z; i++) {
1399 (*ret_data)[pos++] = compression_methods[i];
1402 gnutls_free(compression_methods);
1404 return datalen;
1407 /* This function sends the client hello handshake message.
1409 static int _gnutls_send_client_hello(GNUTLS_STATE state, int again)
1411 opaque *data = NULL;
1412 opaque *extdata;
1413 int extdatalen;
1414 int pos = 0;
1415 int datalen, ret = 0;
1416 opaque random[TLS_RANDOM_SIZE];
1417 GNUTLS_Version hver;
1419 opaque *SessionID =
1420 state->gnutls_internals.resumed_security_parameters.session_id;
1421 uint8 session_id_len =
1422 state->gnutls_internals.resumed_security_parameters.
1423 session_id_size;
1425 if (SessionID == NULL || session_id_len == 0) {
1426 session_id_len = 0;
1427 SessionID = NULL;
1430 data = NULL;
1431 datalen = 0;
1432 if (again == 0) {
1434 datalen = 2 + (session_id_len + 1) + TLS_RANDOM_SIZE;
1435 /* 2 for version, (4 for unix time + 28 for random bytes==TLS_RANDOM_SIZE)
1438 data = gnutls_malloc(datalen + 16); /* 16 is added to avoid realloc
1439 * if no much data are added.
1441 if (data == NULL) {
1442 gnutls_assert();
1443 return GNUTLS_E_MEMORY_ERROR;
1446 /* if we are resuming a session then we set the
1447 * version number to the previously established.
1449 if (SessionID == NULL)
1450 hver = _gnutls_version_max(state);
1451 else { /* we are resuming a session */
1452 hver =
1453 state->gnutls_internals.
1454 resumed_security_parameters.version;
1457 if (hver <= 0) {
1458 if (hver == 0)
1459 hver = GNUTLS_E_UNKNOWN_ERROR;
1460 gnutls_assert();
1461 return hver;
1464 data[pos++] = _gnutls_version_get_major(hver);
1465 data[pos++] = _gnutls_version_get_minor(hver);
1467 /* Set the version we advertized as maximum
1468 * (RSA uses it).
1470 _gnutls_set_adv_version( state, hver);
1472 /* Some implementations do not interoperate if we send a
1473 * different version in the record layer.
1474 * It seems they prefer to read the record's version
1475 * as the one we actually requested.
1476 * The proper behaviour is to use the one in the client hello
1477 * handshake packet and ignore the one in the packet's record
1478 * header.
1480 if (state->gnutls_internals.default_record_version==0)
1481 _gnutls_set_current_version(state, hver);
1482 else _gnutls_set_current_version(state,
1483 state->gnutls_internals.default_record_version);
1485 /* In order to know when this session was initiated.
1487 state->security_parameters.timestamp = time(NULL);
1489 /* Generate random data
1491 _gnutls_create_random(random);
1492 _gnutls_set_client_random(state, random);
1494 memcpy(&data[pos], random, TLS_RANDOM_SIZE);
1495 pos += TLS_RANDOM_SIZE;
1497 /* Copy the Session ID
1499 data[pos++] = session_id_len;
1501 if (session_id_len > 0) {
1502 memcpy(&data[pos], SessionID, session_id_len);
1504 pos += session_id_len;
1507 /* Copy the ciphersuites.
1509 extdatalen = _gnutls_copy_ciphersuites(state, &extdata);
1510 if (extdatalen > 0) {
1511 datalen += extdatalen;
1512 data = gnutls_realloc(data, datalen);
1513 if (data == NULL) {
1514 gnutls_assert();
1515 gnutls_free(extdata);
1516 return GNUTLS_E_MEMORY_ERROR;
1519 memcpy(&data[pos], extdata, extdatalen);
1520 gnutls_free(extdata);
1521 pos += extdatalen;
1523 } else {
1524 if (extdatalen == 0)
1525 extdatalen = GNUTLS_E_UNKNOWN_ERROR;
1526 gnutls_free(data);
1527 gnutls_assert();
1528 return extdatalen;
1532 /* Copy the compression methods.
1534 extdatalen = _gnutls_copy_comp_methods(state, &extdata);
1535 if (extdatalen > 0) {
1536 datalen += extdatalen;
1537 data = gnutls_realloc(data, datalen);
1538 if (data == NULL) {
1539 gnutls_assert();
1540 gnutls_free(extdata);
1541 return GNUTLS_E_MEMORY_ERROR;
1544 memcpy(&data[pos], extdata, extdatalen);
1545 gnutls_free(extdata);
1546 pos += extdatalen;
1548 } else {
1549 if (extdatalen == 0)
1550 extdatalen = GNUTLS_E_UNKNOWN_ERROR;
1551 gnutls_free(data);
1552 gnutls_assert();
1553 return extdatalen;
1556 /* Generate and copy TLS extensions.
1558 if (hver >= GNUTLS_TLS1) {
1559 extdatalen = _gnutls_gen_extensions(state, &extdata);
1560 if (extdatalen > 0) {
1561 datalen += extdatalen;
1562 data = gnutls_realloc(data, datalen);
1563 if (data == NULL) {
1564 gnutls_assert();
1565 gnutls_free(extdata);
1566 return GNUTLS_E_MEMORY_ERROR;
1569 memcpy(&data[pos], extdata, extdatalen);
1570 gnutls_free(extdata);
1575 ret =
1576 _gnutls_send_handshake(state, data, datalen,
1577 GNUTLS_CLIENT_HELLO);
1578 gnutls_free(data);
1580 return ret;
1583 static int _gnutls_send_server_hello(GNUTLS_STATE state, int again)
1585 opaque *data;
1586 opaque *extdata;
1587 int extdatalen;
1588 int pos = 0;
1589 int datalen, ret = 0;
1590 uint8 comp;
1591 opaque *SessionID = state->security_parameters.session_id;
1592 uint8 session_id_len = state->security_parameters.session_id_size;
1594 if (SessionID == NULL)
1595 session_id_len = 0;
1597 data = NULL;
1598 datalen = 0;
1600 if (again == 0) {
1601 datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE + 3;
1602 extdatalen = _gnutls_gen_extensions(state, &extdata);
1604 data = gnutls_alloca(datalen + extdatalen);
1605 if (data == NULL) {
1606 gnutls_assert();
1607 gnutls_free(extdata);
1608 return GNUTLS_E_MEMORY_ERROR;
1611 data[pos++] =
1612 _gnutls_version_get_major(state->security_parameters.
1613 version);
1614 data[pos++] =
1615 _gnutls_version_get_minor(state->security_parameters.
1616 version);
1618 memcpy(&data[pos],
1619 state->security_parameters.server_random,
1620 TLS_RANDOM_SIZE);
1621 pos += TLS_RANDOM_SIZE;
1623 data[pos++] = session_id_len;
1624 if (session_id_len > 0) {
1625 memcpy(&data[pos], SessionID, session_id_len);
1627 pos += session_id_len;
1629 _gnutls_handshake_log("HSK: SessionID: %s\n",
1630 _gnutls_bin2hex(SessionID, session_id_len));
1632 memcpy(&data[pos],
1633 state->security_parameters.
1634 current_cipher_suite.CipherSuite, 2);
1635 pos += 2;
1637 comp =
1638 (uint8) _gnutls_compression_get_num(state->
1639 gnutls_internals.
1640 compression_method);
1641 data[pos++] = comp;
1644 if (extdatalen > 0) {
1645 datalen += extdatalen;
1647 memcpy(&data[pos], extdata, extdatalen);
1648 gnutls_free(extdata);
1652 ret =
1653 _gnutls_send_handshake(state, data, datalen,
1654 GNUTLS_SERVER_HELLO);
1655 gnutls_afree(data);
1657 return ret;
1660 int _gnutls_send_hello(GNUTLS_STATE state, int again)
1662 int ret;
1664 if (state->security_parameters.entity == GNUTLS_CLIENT) {
1665 ret = _gnutls_send_client_hello(state, again);
1667 } else { /* SERVER */
1668 ret = _gnutls_send_server_hello(state, again);
1671 return ret;
1674 /* RECEIVE A HELLO MESSAGE. This should be called from gnutls_recv_handshake_int only if a
1675 * hello message is expected. It uses the security_parameters.current_cipher_suite
1676 * and gnutls_internals.compression_method.
1678 int _gnutls_recv_hello(GNUTLS_STATE state, char *data, int datalen)
1680 int ret;
1682 if (state->security_parameters.entity == GNUTLS_CLIENT) {
1683 ret = _gnutls_read_server_hello(state, data, datalen);
1684 if (ret < 0) {
1685 gnutls_assert();
1686 return ret;
1688 } else { /* Server side reading a client hello */
1690 ret = _gnutls_read_client_hello(state, data, datalen);
1691 if (ret < 0) {
1692 gnutls_assert();
1693 return ret;
1697 return ret;
1700 /* The packets in gnutls_handshake (it's more broad than original TLS handshake)
1702 * Client Server
1704 * ClientHello -------->
1705 * <-------- ServerHello
1707 * Certificate*
1708 * ServerKeyExchange*
1709 * Client Key Exchange0 -------->
1710 * <-------- CertificateRequest*
1712 * <-------- Server Key Exchange2
1713 * <-------- ServerHelloDone
1714 * Certificate*
1715 * ClientKeyExchange
1716 * CertificateVerify*
1717 * [ChangeCipherSpec]
1718 * Finished -------->
1719 * [ChangeCipherSpec]
1720 * <-------- Finished
1722 * (*): means optional packet.
1726 * gnutls_rehandshake - This function will renegotiate security parameters
1727 * @state: is a a &GNUTLS_STATE structure.
1729 * This function will renegotiate security parameters with the
1730 * client. This should only be called in case of a server.
1732 * This message informs the peer that we want to renegotiate
1733 * parameters (perform a handshake).
1735 * If this function succeeds (returns 0), you must call
1736 * the gnutls_handshake() function in order to negotiate
1737 * the new parameters.
1739 * If the client does not wish to renegotiate parameters he
1740 * will reply with an alert message, thus the return code will be
1741 * GNUTLS_E_WARNING_ALERT_RECEIVED and the alert will be
1742 * GNUTLS_A_NO_RENEGOTIATION.
1744 int gnutls_rehandshake(GNUTLS_STATE state)
1746 int ret;
1748 /* only server sends that handshake packet */
1749 if (state->security_parameters.entity == GNUTLS_CLIENT)
1750 return GNUTLS_E_INVALID_REQUEST;
1752 ret =
1753 _gnutls_send_empty_handshake(state, GNUTLS_HELLO_REQUEST,
1754 AGAIN(STATE50));
1755 STATE = STATE50;
1757 if (ret < 0) {
1758 gnutls_assert();
1759 return ret;
1761 STATE = STATE0;
1763 return 0;
1766 static int _gnutls_abort_handshake( GNUTLS_STATE state, int ret) {
1767 if ( ((ret==GNUTLS_E_WARNING_ALERT_RECEIVED) &&
1768 ( gnutls_alert_get(state) == GNUTLS_A_NO_RENEGOTIATION))
1769 || ret==GNUTLS_E_GOT_APPLICATION_DATA)
1770 return 0;
1772 /* this doesn't matter */
1773 return GNUTLS_E_UNKNOWN_ERROR;
1777 /* This function initialized the handshake hash state.
1778 * required for finished messages.
1780 inline
1781 static int _gnutls_handshake_hash_init( GNUTLS_STATE state) {
1783 if ( state->gnutls_internals.handshake_mac_handle_md5==NULL) {
1784 state->gnutls_internals.handshake_mac_handle_md5 = _gnutls_hash_init( GNUTLS_MAC_MD5);
1786 if (state->gnutls_internals.handshake_mac_handle_md5==GNUTLS_HASH_FAILED) {
1787 gnutls_assert();
1788 return GNUTLS_E_MEMORY_ERROR;
1792 if ( state->gnutls_internals.handshake_mac_handle_sha==NULL) {
1793 state->gnutls_internals.handshake_mac_handle_sha = _gnutls_hash_init( GNUTLS_MAC_SHA);
1794 if (state->gnutls_internals.handshake_mac_handle_sha==GNUTLS_HASH_FAILED) {
1795 gnutls_assert();
1796 return GNUTLS_E_MEMORY_ERROR;
1800 return 0;
1804 * gnutls_handshake - This the main function in the handshake protocol.
1805 * @state: is a a &GNUTLS_STATE structure.
1807 * This function does the handshake of the TLS/SSL protocol,
1808 * and initializes the TLS connection.
1810 * This function will fail if any problem is encountered,
1811 * and will return a negative error code. In case of a client,
1812 * if it has been asked to resume a session, but the server didn't, then
1813 * a full handshake will be performed.
1815 * This function may also return the non-fatal errors GNUTLS_E_AGAIN, or
1816 * GNUTLS_E_INTERRUPTED. In that case you may resume the handshake
1817 * (call this function again, until it returns ok)
1819 * If this function is called by a server after a rehandshake request then
1820 * GNUTLS_E_GOT_APPLICATION_DATA or GNUTLS_E_WARNING_ALERT_RECEIVED
1821 * may be returned. Note that these are non fatal errors, only in the
1822 * case of a rehandshake. In that case they mean that the client
1823 * rejected the rehandshake request.
1826 int gnutls_handshake(GNUTLS_STATE state)
1828 int ret;
1830 if ( (ret=_gnutls_handshake_hash_init( state)) < 0) {
1831 gnutls_assert();
1832 return ret;
1835 if (state->security_parameters.entity == GNUTLS_CLIENT) {
1836 ret = gnutls_handshake_client(state);
1837 } else {
1838 ret = gnutls_handshake_server(state);
1840 if (ret < 0) {
1841 /* In the case of a rehandshake abort
1842 * we should reset the handshake's state
1844 if (_gnutls_abort_handshake( state, ret) == 0)
1845 STATE = STATE0;
1846 return ret;
1849 ret = gnutls_handshake_common(state);
1851 if (ret < 0) {
1852 if (_gnutls_abort_handshake( state, ret) == 0)
1853 STATE = STATE0;
1854 return ret;
1857 STATE = STATE0;
1859 _gnutls_handshake_io_buffer_clear(state);
1860 _gnutls_handshake_internal_state_clear(state);
1862 return 0;
1865 #define IMED_RET( str, ret) \
1866 if (ret < 0) { \
1867 if (gnutls_error_is_fatal(ret)==0) return ret; \
1868 gnutls_assert(); \
1869 ERR( str, ret); \
1870 _gnutls_handshake_hash_buffers_clear(state); \
1871 return ret; \
1877 * gnutls_handshake_client
1878 * This function performs the client side of the handshake of the TLS/SSL protocol.
1880 int gnutls_handshake_client(GNUTLS_STATE state)
1882 int ret = 0;
1884 #ifdef HANDSHAKE_DEBUG
1885 if (state->gnutls_internals.resumed_security_parameters.
1886 session_id_size > 0)
1887 _gnutls_handshake_log("HSK: Ask to resume: %s\n",
1888 _gnutls_bin2hex(state->gnutls_internals.
1889 resumed_security_parameters.
1890 session_id,
1891 state->gnutls_internals.
1892 resumed_security_parameters.
1893 session_id_size));
1894 #endif
1896 switch (STATE) {
1897 case STATE0:
1898 case STATE1:
1899 ret = _gnutls_send_hello(state, AGAIN(STATE1));
1900 STATE = STATE1;
1901 IMED_RET("send hello", ret);
1903 case STATE2:
1904 /* receive the server hello */
1905 ret =
1906 _gnutls_recv_handshake(state, NULL, NULL,
1907 GNUTLS_SERVER_HELLO,
1908 MANDATORY_PACKET);
1909 STATE = STATE2;
1910 IMED_RET("recv hello", ret);
1912 case STATE3:
1913 /* RECV CERTIFICATE */
1914 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
1915 ret = _gnutls_recv_server_certificate(state);
1916 STATE = STATE3;
1917 IMED_RET("recv server certificate", ret);
1919 case STATE4:
1920 /* receive the server key exchange */
1921 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
1922 ret = _gnutls_recv_server_kx_message(state);
1923 STATE = STATE4;
1924 IMED_RET("recv server kx message", ret);
1926 case STATE5:
1927 /* Added for SRP,
1928 * send the client key exchange for SRP
1930 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
1931 ret =
1932 _gnutls_send_client_kx_message0(state,
1933 AGAIN(STATE5));
1934 STATE = STATE5;
1935 IMED_RET("send client kx0", ret);
1937 case STATE6:
1938 /* receive the server certificate request - if any
1941 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
1942 ret =
1943 _gnutls_recv_server_certificate_request(state);
1944 STATE = STATE6;
1945 IMED_RET("recv server certificate request message", ret);
1947 case STATE7:
1948 /* receive the server key exchange (B) (SRP only)
1951 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
1952 ret = _gnutls_recv_server_kx_message2(state);
1953 STATE = STATE7;
1954 IMED_RET("recv server kx message2", ret);
1956 case STATE8:
1957 /* receive the server hello done */
1958 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
1959 ret =
1960 _gnutls_recv_handshake(state, NULL, NULL,
1961 GNUTLS_SERVER_HELLO_DONE,
1962 MANDATORY_PACKET);
1963 STATE = STATE8;
1964 IMED_RET("recv server hello done", ret);
1966 case STATE9:
1967 /* send our certificate - if any and if requested
1969 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
1970 ret =
1971 _gnutls_send_client_certificate(state,
1972 AGAIN(STATE9));
1973 STATE = STATE9;
1974 IMED_RET("send client certificate", ret);
1976 case STATE10:
1977 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
1978 ret =
1979 _gnutls_send_client_kx_message(state,
1980 AGAIN(STATE10));
1981 STATE = STATE10;
1982 IMED_RET("send client kx", ret);
1984 case STATE11:
1985 /* send client certificate verify */
1986 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
1987 ret =
1988 _gnutls_send_client_certificate_verify(state,
1989 AGAIN
1990 (STATE11));
1991 STATE = STATE11;
1992 IMED_RET("send client certificate verify", ret);
1994 STATE = STATE0;
1998 return 0;
2001 /* This function sends the final handshake packets and initializes connection
2003 static int _gnutls_send_handshake_final(GNUTLS_STATE state, int init)
2005 int ret = 0;
2007 /* Send the CHANGE CIPHER SPEC PACKET */
2009 switch (STATE) {
2010 case STATE0:
2011 case STATE20:
2012 ret =
2013 _gnutls_send_change_cipher_spec(state, AGAIN(STATE20));
2014 STATE = STATE20;
2015 if (ret < 0) {
2016 ERR("send ChangeCipherSpec", ret);
2017 gnutls_assert();
2018 return ret;
2021 /* Initialize the connection state (start encryption) - in case of client
2023 if (init == TRUE) {
2024 ret = _gnutls_connection_state_init(state);
2025 if (ret < 0) {
2026 gnutls_assert();
2027 return ret;
2031 ret = _gnutls_write_connection_state_init(state);
2032 if (ret < 0) {
2033 gnutls_assert();
2034 return ret;
2037 case STATE21:
2038 /* send the finished message */
2039 ret = _gnutls_send_finished(state, AGAIN(STATE21));
2040 STATE = STATE21;
2041 if (ret < 0) {
2042 ERR("send Finished", ret);
2043 gnutls_assert();
2044 return ret;
2047 STATE = STATE0;
2050 return 0;
2053 /* This function receives the final handshake packets
2054 * And executes the appropriate function to initialize the
2055 * read state.
2057 static int _gnutls_recv_handshake_final(GNUTLS_STATE state, int init)
2059 int ret = 0;
2060 uint8 ch;
2062 switch (STATE) {
2063 case STATE0:
2064 case STATE30:
2065 ret =
2066 gnutls_recv_int(state, GNUTLS_CHANGE_CIPHER_SPEC, -1,
2067 &ch, 1);
2068 STATE = STATE30;
2069 if (ret <= 0) {
2070 ERR("recv ChangeCipherSpec", ret);
2071 gnutls_assert();
2072 return (ret <
2073 0) ? ret :
2074 GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
2077 /* Initialize the connection state (start encryption) - in case of server */
2078 if (init == TRUE) {
2079 ret = _gnutls_connection_state_init(state);
2080 if (ret < 0) {
2081 gnutls_assert();
2082 return ret;
2086 ret = _gnutls_read_connection_state_init(state);
2087 if (ret < 0) {
2088 gnutls_assert();
2089 return ret;
2092 case STATE31:
2093 ret = _gnutls_recv_finished(state);
2094 STATE = STATE31;
2095 if (ret < 0) {
2096 ERR("recv finished", ret);
2097 gnutls_assert();
2098 return ret;
2100 STATE = STATE0;
2104 return 0;
2108 * gnutls_handshake_server
2109 * This function does the server stuff of the handshake protocol.
2112 int gnutls_handshake_server(GNUTLS_STATE state)
2114 int ret = 0;
2116 switch (STATE) {
2117 case STATE0:
2118 case STATE1:
2119 ret =
2120 _gnutls_recv_handshake(state, NULL, NULL,
2121 GNUTLS_CLIENT_HELLO,
2122 MANDATORY_PACKET);
2123 STATE = STATE1;
2124 IMED_RET("recv hello", ret);
2126 case STATE2:
2127 ret = _gnutls_send_hello(state, AGAIN(STATE2));
2128 STATE = STATE2;
2129 IMED_RET("send hello", ret);
2131 /* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
2132 case STATE3:
2133 /* NOTE: these should not be send if we are resuming */
2135 if (state->gnutls_internals.resumed == RESUME_FALSE)
2136 ret =
2137 _gnutls_send_server_certificate(state,
2138 AGAIN(STATE3));
2139 STATE = STATE3;
2140 IMED_RET("send server certificate", ret);
2142 case STATE4:
2143 /* send server key exchange (A) */
2144 if (state->gnutls_internals.resumed == RESUME_FALSE)
2145 ret =
2146 _gnutls_send_server_kx_message(state,
2147 AGAIN(STATE4));
2148 STATE = STATE4;
2149 IMED_RET("send server kx", ret);
2151 case STATE5:
2152 /* Send certificate request - if requested to */
2153 if (state->gnutls_internals.resumed == RESUME_FALSE)
2154 ret =
2155 _gnutls_send_server_certificate_request(state,
2156 AGAIN
2157 (STATE5));
2158 STATE = STATE5;
2159 IMED_RET("send server cert request", ret);
2161 case STATE6:
2162 /* Added for SRP which uses a different handshake */
2163 /* receive the client key exchange message */
2165 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
2166 ret = _gnutls_recv_client_kx_message0(state);
2167 STATE = STATE6;
2168 IMED_RET("recv client kx0", ret);
2170 case STATE7:
2171 /* send server key exchange (B) */
2172 if (state->gnutls_internals.resumed == RESUME_FALSE)
2173 ret =
2174 _gnutls_send_server_kx_message2(state,
2175 AGAIN(STATE7));
2176 STATE = STATE7;
2177 IMED_RET("send server kx2", ret);
2179 case STATE8:
2180 /* send the server hello done */
2181 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
2182 ret =
2183 _gnutls_send_empty_handshake(state,
2184 GNUTLS_SERVER_HELLO_DONE,
2185 AGAIN(STATE8));
2186 STATE = STATE8;
2187 IMED_RET("send server hello done", ret);
2190 /* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_VERIFY */
2191 case STATE9:
2192 /* receive the client certificate message */
2193 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
2194 ret = _gnutls_recv_client_certificate(state);
2195 STATE = STATE9;
2196 IMED_RET("recv client certificate", ret);
2198 case STATE10:
2199 /* receive the client key exchange message */
2200 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
2201 ret = _gnutls_recv_client_kx_message(state);
2202 STATE = STATE10;
2203 IMED_RET("recv client kx", ret);
2205 case STATE11:
2206 /* receive the client certificate verify message */
2207 if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */
2208 ret =
2209 _gnutls_recv_client_certificate_verify_message
2210 (state);
2211 STATE = STATE11;
2212 IMED_RET("recv client certificate verify", ret);
2214 STATE = STATE0; /* finished thus clear state */
2217 return 0;
2220 int gnutls_handshake_common(GNUTLS_STATE state)
2222 int ret = 0;
2225 /* send and recv the change cipher spec and finished messages */
2226 if ((state->gnutls_internals.resumed == RESUME_TRUE
2227 && state->security_parameters.entity == GNUTLS_CLIENT)
2228 || (state->gnutls_internals.resumed == RESUME_FALSE
2229 && state->security_parameters.entity == GNUTLS_SERVER)) {
2230 /* if we are a client resuming - or we are a server not resuming */
2232 ret = _gnutls_recv_handshake_final(state, TRUE);
2233 IMED_RET("recv handshake final", ret);
2235 ret = _gnutls_send_handshake_final(state, FALSE);
2236 IMED_RET("send handshake final", ret);
2237 } else { /* if we are a client not resuming - or we are a server resuming */
2239 ret = _gnutls_send_handshake_final(state, TRUE);
2240 IMED_RET("send handshake final 2", ret);
2242 ret = _gnutls_recv_handshake_final(state, FALSE);
2243 IMED_RET("recv handshake final 2", ret);
2246 if (state->security_parameters.entity == GNUTLS_SERVER) {
2247 /* in order to support session resuming */
2248 _gnutls_server_register_current_session(state);
2251 /* clear handshake buffer */
2252 _gnutls_handshake_hash_buffers_clear(state);
2253 return ret;
2257 int _gnutls_generate_session_id(char *session_id, uint8 * len)
2259 opaque rand[TLS_RANDOM_SIZE];
2260 if (_gnutls_get_random(rand, TLS_RANDOM_SIZE, GNUTLS_WEAK_RANDOM) <
2261 0) {
2262 gnutls_assert();
2263 return GNUTLS_E_MEMORY_ERROR;
2265 memcpy(session_id, rand, TLS_RANDOM_SIZE);
2266 *len = TLS_RANDOM_SIZE;
2268 _gnutls_handshake_log("HSK: Generated SessionID: %s\n",
2269 _gnutls_bin2hex(session_id, TLS_RANDOM_SIZE));
2271 return 0;
2274 int _gnutls_recv_hello_request(GNUTLS_STATE state, void *data,
2275 uint32 data_size)
2277 uint8 type;
2279 if (state->security_parameters.entity == GNUTLS_SERVER) {
2280 gnutls_assert();
2281 return GNUTLS_E_UNEXPECTED_PACKET;
2283 if (data_size < 1) {
2284 gnutls_assert();
2285 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
2287 type = ((uint8 *) data)[0];
2288 if (type == GNUTLS_HELLO_REQUEST)
2289 return GNUTLS_E_REHANDSHAKE;
2290 else {
2291 gnutls_assert();
2292 return GNUTLS_E_UNEXPECTED_PACKET;
2296 /* This function will remove algorithms that are not supported by
2297 * the requested authentication method. We remove algorithm if
2298 * we have a certificate with keyUsage bits set.
2300 * This does a more high level check than gnutls_supported_ciphersuites(),
2301 * by checking certificates etc.
2303 int _gnutls_remove_unwanted_ciphersuites(GNUTLS_STATE state,
2304 GNUTLS_CipherSuite **
2305 cipherSuites, int numCipherSuites,
2306 PKAlgorithm requested_pk_algo)
2309 int ret = 0;
2310 GNUTLS_CipherSuite *newSuite;
2311 int newSuiteSize = 0, i, j, keep;
2312 const GNUTLS_CERTIFICATE_CREDENTIALS x509_cred;
2313 const gnutls_cert *cert = NULL;
2314 KXAlgorithm *alg;
2315 int alg_size;
2316 KXAlgorithm kx;
2319 /* if we should use a specific certificate,
2320 * we should remove all algorithms that are not supported
2321 * by that certificate and are on the same authentication
2322 * method (CERTIFICATE).
2325 x509_cred =
2326 _gnutls_get_cred(state->gnutls_key, GNUTLS_CRD_CERTIFICATE, NULL);
2328 /* if x509_cred==NULL we should remove all X509 ciphersuites
2331 cert = NULL;
2332 if (state->security_parameters.entity == GNUTLS_SERVER)
2333 cert = _gnutls_server_find_cert(state, requested_pk_algo);
2335 if (cert == NULL) {
2336 /* No certificate was found
2338 gnutls_assert();
2339 alg_size = 0;
2340 alg = NULL;
2341 } else {
2342 /* get all the key exchange algorithms that are
2343 * supported by the X509 certificate parameters.
2345 if ((ret =
2346 _gnutls_cert_supported_kx(cert, &alg,
2347 &alg_size)) < 0) {
2348 gnutls_assert();
2349 return ret;
2353 newSuite =
2354 gnutls_malloc(numCipherSuites * sizeof(GNUTLS_CipherSuite));
2355 if (newSuite == NULL) {
2356 gnutls_assert();
2357 gnutls_free(alg);
2358 return GNUTLS_E_MEMORY_ERROR;
2361 /* now removes ciphersuites based on the KX algorithm
2363 for (i = 0; i < numCipherSuites; i++) {
2364 /* finds the key exchange algorithm in
2365 * the ciphersuite
2367 kx = _gnutls_cipher_suite_get_kx_algo((*cipherSuites)[i]);
2369 keep = 0;
2371 /* if it is defined but had no credentials
2373 if (_gnutls_get_kx_cred
2374 (state->gnutls_key, kx, NULL) == NULL) {
2375 keep = 1;
2376 } else
2377 /* If there was no credentials to use with the specified
2378 * key exchange method, then just remove it.
2380 if (_gnutls_map_kx_get_cred(kx) == GNUTLS_CRD_CERTIFICATE) {
2381 keep = 1; /* do not keep */
2382 if (x509_cred != NULL) {
2383 if (state->security_parameters.entity ==
2384 GNUTLS_SERVER) {
2385 /* here we check if the KX algorithm
2386 * is compatible with the certificate.
2388 for (j = 0; j < alg_size; j++) {
2389 if (alg[j] == kx) {
2390 keep = 0;
2391 break;
2394 } else /* CLIENT */
2395 keep = 0;
2399 if (keep == 0) {
2401 _gnutls_handshake_log("HSK: Keeping ciphersuite: ");
2402 _gnutls_handshake_log("%s\n",
2403 _gnutls_cipher_suite_get_name(*
2404 ((GNUTLS_CipherSuite *) & (*cipherSuites)[i].CipherSuite)));
2406 memcpy(newSuite[newSuiteSize].CipherSuite,
2407 (*cipherSuites)[i].CipherSuite, 2);
2408 newSuiteSize++;
2409 } else {
2410 _gnutls_handshake_log("HSK: Removing ciphersuite: ");
2411 _gnutls_handshake_log("%s\n",
2412 _gnutls_cipher_suite_get_name(*
2413 ((GNUTLS_CipherSuite *) & (*cipherSuites)[i].CipherSuite)));
2418 gnutls_free(alg);
2419 gnutls_free(*cipherSuites);
2420 *cipherSuites = newSuite;
2422 ret = newSuiteSize;
2424 return ret;
2429 * gnutls_handshake_set_max_packet_length - This function will set the maximum length of a handshake message
2430 * @state: is a a &GNUTLS_STATE structure.
2431 * @max: is the maximum number.
2433 * This function will set the maximum size of a handshake message.
2434 * Handshake messages over this size are rejected.
2435 * The default value is 16kb which is large enough. Set this to 0 if you do not want
2436 * to set an upper limit.
2439 void gnutls_handshake_set_max_packet_length(GNUTLS_STATE state, int max)
2441 state->gnutls_internals.max_handshake_data_buffer_size = max;
2444 void _gnutls_set_adv_version( GNUTLS_STATE state, GNUTLS_Version ver) {
2445 set_adv_version( state, _gnutls_version_get_major(ver), _gnutls_version_get_minor(ver));
2448 GNUTLS_Version _gnutls_get_adv_version( GNUTLS_STATE state) {
2449 return _gnutls_version_get( _gnutls_get_adv_version_major( state),
2450 _gnutls_get_adv_version_minor( state));