Bug Summary

File:lib/gnutls_handshake.c
Location:line 1959, column 3
Description:Value stored to 'datalen' is never read

Annotated Source Code

1/*
2 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GnuTLS.
7 *
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.
12 *
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.
17 *
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/>
20 *
21 */
22
23/* Functions that relate to the TLS handshake procedure.
24 */
25
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>
56
57#ifdef HANDSHAKE_DEBUG
58#define ERR(x, y) _gnutls_handshake_log("HSK[%p]: %s (%d)\n", session, x,y)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: %s (%d)\n", session, x,y); } while(0)
59#else
60#define ERR(x, y)
61#endif
62
63#define TRUE1 1
64#define FALSE0 0
65
66static int _gnutls_server_select_comp_method (gnutls_session_t session,
67 opaque * data, int datalen);
68static 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);
74
75/* Empties but does not free the buffer
76 */
77static inline void
78_gnutls_handshake_hash_buffer_empty (gnutls_session_t session)
79{
80
81 _gnutls_buffers_log ("BUF[HSK]: Emptied buffer\n")do { if (__builtin_expect((_gnutls_log_level == 6 || _gnutls_log_level
> 9), 0)) _gnutls_log( 6, "BUF[HSK]: Emptied buffer\n"); }
while(0)
;
82
83 session->internals.handshake_hash_buffer_prev_len = 0;
84 session->internals.handshake_hash_buffer.length = 0;
85 return;
86}
87
88static int
89_gnutls_handshake_hash_add_recvd (gnutls_session_t session,
90 gnutls_handshake_description_t recv_type,
91 opaque * header, uint16_t header_size,
92 opaque * dataptr, uint32_t datalen);
93
94static int
95_gnutls_handshake_hash_add_sent (gnutls_session_t session,
96 gnutls_handshake_description_t type,
97 opaque * dataptr, uint32_t datalen);
98
99static int
100_gnutls_recv_hello_verify_request (gnutls_session_t session,
101 opaque * data, int datalen);
102
103
104/* Clears the handshake hash buffers and handles.
105 */
106void
107_gnutls_handshake_hash_buffers_clear (gnutls_session_t session)
108{
109 session->internals.handshake_hash_buffer_prev_len = 0;
110 _gnutls_buffer_clear(&session->internals.handshake_hash_buffer);
111}
112
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.
116 */
117static void
118resume_copy_required_values (gnutls_session_t session)
119{
120 /* get the new random values */
121 memcpy (session->internals.resumed_security_parameters.server_random,
122 session->security_parameters.server_random, GNUTLS_RANDOM_SIZE32);
123 memcpy (session->internals.resumed_security_parameters.client_random,
124 session->security_parameters.client_random, GNUTLS_RANDOM_SIZE32);
125
126 /* keep the ciphersuite and compression
127 * That is because the client must see these in our
128 * hello message.
129 */
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;
133
134 _gnutls_epoch_set_cipher_suite (session, EPOCH_NEXT70002,
135 session->
136 internals.resumed_security_parameters.cipher_suite);
137 _gnutls_epoch_set_compression (session, EPOCH_NEXT70002,
138 session->
139 internals.resumed_security_parameters.compression_method);
140
141 /* or write_compression_algorithm
142 * they are the same
143 */
144
145 session->security_parameters.entity =
146 session->internals.resumed_security_parameters.entity;
147
148 _gnutls_set_current_version (session,
149 session->internals.resumed_security_parameters.
150 version);
151
152 session->security_parameters.cert_type =
153 session->internals.resumed_security_parameters.cert_type;
154
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;
160
161}
162
163void
164_gnutls_set_server_random (gnutls_session_t session, uint8_t * rnd)
165{
166 memcpy (session->security_parameters.server_random, rnd,
167 GNUTLS_RANDOM_SIZE32);
168}
169
170void
171_gnutls_set_client_random (gnutls_session_t session, uint8_t * rnd)
172{
173 memcpy (session->security_parameters.client_random, rnd,
174 GNUTLS_RANDOM_SIZE32);
175}
176
177/* Calculate The SSL3 Finished message
178 */
179#define SSL3_CLIENT_MSG"CLNT" "CLNT"
180#define SSL3_SERVER_MSG"SRVR" "SRVR"
181#define SSL_MSG_LEN4 4
182static int
183_gnutls_ssl3_finished (gnutls_session_t session, int type, opaque * ret, int sending)
184{
185 digest_hd_st td_md5;
186 digest_hd_st td_sha;
187 const char *mesg;
188 int rc, len;
189
190 if (sending)
191 len = session->internals.handshake_hash_buffer.length;
192 else
193 len = session->internals.handshake_hash_buffer_prev_len;
194
195 rc = _gnutls_hash_init (&td_sha, GNUTLS_DIG_SHA1);
196 if (rc < 0)
197 return gnutls_assert_val(rc)gnutls_assert_val_int(rc, "gnutls_handshake.c", 197);
198
199 rc = _gnutls_hash_init (&td_md5, GNUTLS_DIG_MD5);
200 if (rc < 0)
201 {
202 _gnutls_hash_deinit (&td_sha, NULL((void*)0));
203 return gnutls_assert_val(rc)gnutls_assert_val_int(rc, "gnutls_handshake.c", 203);
204 }
205
206 _gnutls_hash(&td_sha, session->internals.handshake_hash_buffer.data, len);
207 _gnutls_hash(&td_md5, session->internals.handshake_hash_buffer.data, len);
208
209 if (type == GNUTLS_SERVER1)
210 mesg = SSL3_SERVER_MSG"SRVR";
211 else
212 mesg = SSL3_CLIENT_MSG"CLNT";
213
214 _gnutls_hash (&td_md5, mesg, SSL_MSG_LEN4);
215 _gnutls_hash (&td_sha, mesg, SSL_MSG_LEN4);
216
217 rc = _gnutls_mac_deinit_ssl3_handshake (&td_md5, ret,
218 session->
219 security_parameters.master_secret,
220 GNUTLS_MASTER_SIZE48);
221 if (rc < 0)
222 {
223 _gnutls_hash_deinit (&td_md5, NULL((void*)0));
224 _gnutls_hash_deinit (&td_sha, NULL((void*)0));
225 return gnutls_assert_val(rc)gnutls_assert_val_int(rc, "gnutls_handshake.c", 225);
226 }
227
228 rc = _gnutls_mac_deinit_ssl3_handshake (&td_sha, &ret[16],
229 session->
230 security_parameters.master_secret,
231 GNUTLS_MASTER_SIZE48);
232 if (rc < 0)
233 {
234 _gnutls_hash_deinit (&td_sha, NULL((void*)0));
235 return gnutls_assert_val(rc)gnutls_assert_val_int(rc, "gnutls_handshake.c", 235);
236 }
237
238 return 0;
239}
240
241/* Hash the handshake messages as required by TLS 1.0
242 */
243#define SERVER_MSG"server finished" "server finished"
244#define CLIENT_MSG"client finished" "client finished"
245#define TLS_MSG_LEN15 15
246static int
247_gnutls_finished (gnutls_session_t session, int type, void *ret, int sending)
248{
249 const int siz = TLS_MSG_LEN15;
250 opaque concat[MAX_HASH_SIZE64 + 16 /*MD5 */ ];
251 size_t hash_len;
252 const char *mesg;
253 int rc, len;
254
255 if (sending)
256 len = session->internals.handshake_hash_buffer.length;
257 else
258 len = session->internals.handshake_hash_buffer_prev_len;
259
260 if (!_gnutls_version_has_selectable_prf (gnutls_protocol_get_version_gnutls_protocol_get_version(session)))
261 {
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)gnutls_assert_val_int(rc, "gnutls_handshake.c", 264);
265
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)gnutls_assert_val_int(rc, "gnutls_handshake.c", 268);
269
270 hash_len = 20 + 16;
271 }
272 else
273 {
274 int algorithm = _gnutls_cipher_suite_get_prf(session->security_parameters.cipher_suite);
275
276 rc = _gnutls_hash_fast( algorithm, session->internals.handshake_hash_buffer.data, len, concat);
277 if (rc < 0)
278 return gnutls_assert_val(rc)gnutls_assert_val_int(rc, "gnutls_handshake.c", 278);
279
280 hash_len = _gnutls_hash_get_algo_len (algorithm);
281 }
282
283 if (type == GNUTLS_SERVER1)
284 {
285 mesg = SERVER_MSG"server finished";
286 }
287 else
288 {
289 mesg = CLIENT_MSG"client finished";
290 }
291
292 return _gnutls_PRF (session, session->security_parameters.master_secret,
293 GNUTLS_MASTER_SIZE48, mesg, siz, concat, hash_len, 12, ret);
294}
295
296/* this function will produce GNUTLS_RANDOM_SIZE==32 bytes of random data
297 * and put it to dst.
298 */
299int
300_gnutls_tls_create_random (opaque * dst)
301{
302 uint32_t tim;
303 int ret;
304
305 /* Use weak random numbers for the most of the
306 * buffer except for the first 4 that are the
307 * system's time.
308 */
309
310 tim = gnutls_time (NULL((void*)0));
311 /* generate server random value */
312 _gnutls_write_uint32 (tim, dst);
313
314 ret = _gnutls_rnd (GNUTLS_RND_NONCE, &dst[4], GNUTLS_RANDOM_SIZE32 - 4);
315 if (ret < 0)
316 {
317 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",317); } while(0)
;
;
318 return ret;
319 }
320
321 return 0;
322}
323
324/* returns the 0 on success or a negative error code.
325 */
326int
327_gnutls_negotiate_version (gnutls_session_t session,
328 gnutls_protocol_t adv_version)
329{
330 int ret;
331
332 /* if we do not support that version */
333 if (_gnutls_version_is_supported (session, adv_version) == 0)
334 {
335 /* If he requested something we do not support
336 * then we send him the highest we support.
337 */
338 ret = _gnutls_version_max (session);
339 if (ret == GNUTLS_VERSION_UNKNOWN)
340 {
341 /* this check is not really needed.
342 */
343 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",343); } while(0)
;
;
344 return GNUTLS_E_UNKNOWN_CIPHER_SUITE-21;
345 }
346 }
347 else
348 {
349 ret = adv_version;
350 }
351
352 _gnutls_set_current_version (session, ret);
353
354 return ret;
355}
356
357int
358_gnutls_user_hello_func (gnutls_session_t session,
359 gnutls_protocol_t adv_version)
360{
361 int ret;
362
363 if (session->internals.user_hello_func != NULL((void*)0))
364 {
365 ret = session->internals.user_hello_func (session);
366 if (ret < 0)
367 {
368 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",368); } while(0)
;
;
369 return ret;
370 }
371 /* Here we need to renegotiate the version since the callee might
372 * have disabled some TLS versions.
373 */
374 ret = _gnutls_negotiate_version (session, adv_version);
375 if (ret < 0)
376 {
377 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",377); } while(0)
;
;
378 return ret;
379 }
380 }
381 return 0;
382}
383
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).
388 */
389static int
390_gnutls_read_client_hello (gnutls_session_t session, opaque * data,
391 int datalen)
392{
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 opaque rnd[GNUTLS_RANDOM_SIZE32], *suite_ptr, *comp_ptr, *session_id;
400
401 DECR_LEN (len, 2)do { len-=2; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,401); } while(0);; return -9;} } while (0)
;
402
403 _gnutls_handshake_log ("HSK[%p]: Client's version: %d.%d\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Client's version: %d.%d\n", session, data[pos]
, data[pos + 1]); } while(0)
404 data[pos], data[pos + 1])do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Client's version: %d.%d\n", session, data[pos]
, data[pos + 1]); } while(0)
;
405
406 adv_version = _gnutls_version_get (data[pos], data[pos + 1]);
407 set_adv_version (session, data[pos], data[pos + 1])session->internals.adv_version_major = data[pos]; session->
internals.adv_version_minor = data[pos + 1]
;
408 pos += 2;
409
410 neg_version = _gnutls_negotiate_version (session, adv_version);
411 if (neg_version < 0)
412 {
413 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",413); } while(0)
;
;
414 return neg_version;
415 }
416
417 /* Read client random value.
418 */
419 DECR_LEN (len, GNUTLS_RANDOM_SIZE)do { len-=32; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,419); } while(0);; return -9;} } while (0)
;
420 _gnutls_set_client_random (session, &data[pos]);
421 pos += GNUTLS_RANDOM_SIZE32;
422
423 _gnutls_tls_create_random (rnd);
424 _gnutls_set_server_random (session, rnd);
425
426 session->security_parameters.timestamp = gnutls_time (NULL((void*)0));
427
428 DECR_LEN (len, 1)do { len-=1; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,428); } while(0);; return -9;} } while (0)
;
429 session_id_len = data[pos++];
430
431 /* RESUME SESSION
432 */
433 if (session_id_len > TLS_MAX_SESSION_ID_SIZE32)
434 {
435 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",435); } while(0)
;
;
436 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
437 }
438 DECR_LEN (len, session_id_len)do { len-=session_id_len; if (len<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",438); } while(0);; return -9;} } while
(0)
;
439
440 session_id = &data[pos];
441 ret = _gnutls_server_restore_session (session, session_id, session_id_len);
442 pos += session_id_len;
443
444 if (session_id_len > 0) session->internals.resumption_requested = 1;
445
446 if (ret == 0)
447 { /* resumed using default TLS resumption! */
448 /* Parse only the safe renegotiation extension
449 * We don't want to parse any other extensions since
450 * we don't want new extension values to overwrite the
451 * resumed ones.
452 */
453
454 /* move forward to extensions */
455 DECR_LEN (len, 2)do { len-=2; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,455); } while(0);; return -9;} } while (0)
;
456 suite_size = _gnutls_read_uint16 (&data[pos]);
457 pos += 2;
458
459 DECR_LEN (len, suite_size)do { len-=suite_size; if (len<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",459); } while(0);; return -9;} } while
(0)
;
460 pos += suite_size;
461
462 DECR_LEN (len, 1)do { len-=1; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,462); } while(0);; return -9;} } while (0)
;
463 comp_size = data[pos++]; /* z is the number of compression methods */
464 DECR_LEN (len, comp_size)do { len-=comp_size; if (len<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",464); } while(0);; return -9;} } while
(0)
;
465 pos += comp_size;
466
467 ret = _gnutls_parse_extensions (session, GNUTLS_EXT_MANDATORY,
468 &data[pos], len);
469 if (ret < 0)
470 {
471 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",471); } while(0)
;
;
472 return ret;
473 }
474
475 resume_copy_required_values (session);
476 session->internals.resumed = RESUME_TRUE1;
477
478 return _gnutls_user_hello_func (session, adv_version);
479 }
480 else
481 {
482 _gnutls_generate_session_id (session->security_parameters.session_id,
483 &session->
484 security_parameters.session_id_size);
485
486 session->internals.resumed = RESUME_FALSE0;
487 }
488
489 if (IS_DTLS(session)(session->internals.transport == GNUTLS_DGRAM))
490 {
491 int cookie_size;
492
493 DECR_LEN (len, 1)do { len-=1; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,493); } while(0);; return -9;} } while (0)
;
494 cookie_size = data[pos++];
495 DECR_LEN (len, cookie_size)do { len-=cookie_size; if (len<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",495); } while(0);; return -9;} } while
(0)
;
496 pos+=cookie_size;
497 }
498
499 /* Remember ciphersuites for later
500 */
501 DECR_LEN (len, 2)do { len-=2; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,501); } while(0);; return -9;} } while (0)
;
502 suite_size = _gnutls_read_uint16 (&data[pos]);
503 pos += 2;
504
505 DECR_LEN (len, suite_size)do { len-=suite_size; if (len<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",505); } while(0);; return -9;} } while
(0)
;
506 suite_ptr = &data[pos];
507 pos += suite_size;
508
509 /* Point to the compression methods
510 */
511 DECR_LEN (len, 1)do { len-=1; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,511); } while(0);; return -9;} } while (0)
;
512 comp_size = data[pos++]; /* z is the number of compression methods */
513
514 DECR_LEN (len, comp_size)do { len-=comp_size; if (len<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",514); } while(0);; return -9;} } while
(0)
;
515 comp_ptr = &data[pos];
516 pos += comp_size;
517
518 /* Parse the extensions (if any)
519 *
520 * Unconditionally try to parse extensions; safe renegotiation uses them in
521 * sslv3 and higher, even though sslv3 doesn't officially support them.
522 */
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)
527 {
528 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",528); } while(0)
;
;
529 return ret;
530 }
531
532 ret = _gnutls_user_hello_func (session, adv_version);
533 if (ret < 0)
534 {
535 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",535); } while(0)
;
;
536 return ret;
537 }
538
539 ret = _gnutls_parse_extensions (session, GNUTLS_EXT_MANDATORY,
540 &data[pos], len);
541 if (ret < 0)
542 {
543 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",543); } while(0)
;
;
544 return ret;
545 }
546
547 ret = _gnutls_parse_extensions (session, GNUTLS_EXT_TLS, &data[pos], len);
548 if (ret < 0)
549 {
550 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",550); } while(0)
;
;
551 return ret;
552 }
553
554 /* resumed by session_ticket extension */
555 if (session->internals.resumed != RESUME_FALSE0)
556 {
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;
562
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;
567
568 resume_copy_required_values (session);
569
570 return _gnutls_user_hello_func (session, adv_version);
571 }
572
573 /* select an appropriate cipher suite
574 */
575 ret = _gnutls_server_select_suite (session, suite_ptr, suite_size);
576 if (ret < 0)
577 {
578 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",578); } while(0)
;
;
579 return ret;
580 }
581
582 /* select appropriate compression method */
583 ret = _gnutls_server_select_comp_method (session, comp_ptr, comp_size);
584 if (ret < 0)
585 {
586 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",586); } while(0)
;
;
587 return ret;
588 }
589
590 return 0;
591}
592
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.
596 */
597static int
598_gnutls_send_finished (gnutls_session_t session, int again)
599{
600 mbuffer_st *bufel;
601 opaque *data;
602 int ret;
603 size_t vdata_size = 0;
604
605 if (again == 0)
606 {
607 bufel = _gnutls_handshake_alloc (session, MAX_VERIFY_DATA_SIZE36, MAX_VERIFY_DATA_SIZE36);
608 if (bufel == NULL((void*)0))
609 {
610 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",610); } while(0)
;
;
611 return GNUTLS_E_MEMORY_ERROR-25;
612 }
613 data = _mbuffer_get_udata_ptr (bufel);
614
615 if (gnutls_protocol_get_version_gnutls_protocol_get_version (session) == GNUTLS_SSL3)
616 {
617 ret =
618 _gnutls_ssl3_finished (session,
619 session->security_parameters.entity, data, 1);
620 _mbuffer_set_udata_size (bufel, 36);
621 }
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);
627 }
628
629 if (ret < 0)
630 {
631 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",631); } while(0)
;
;
632 return ret;
633 }
634
635 vdata_size = _mbuffer_get_udata_size (bufel);
636
637 ret = _gnutls_ext_sr_finished (session, data, vdata_size, 0);
638 if (ret < 0)
639 {
640 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",640); } while(0)
;
;
641 return ret;
642 }
643
644 if ((session->internals.resumed == RESUME_FALSE0
645 && session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
646 || (session->internals.resumed != RESUME_FALSE0
647 && session->security_parameters.entity == GNUTLS_SERVER1))
648 {
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",do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: recording tls-unique CB (send)\n", session); }
while(0)
651 session)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: recording tls-unique CB (send)\n", session); }
while(0)
;
652 memcpy (session->internals.cb_tls_unique, data, vdata_size);
653 session->internals.cb_tls_unique_len = vdata_size;
654 }
655
656 ret =
657 _gnutls_send_handshake (session, bufel, GNUTLS_HANDSHAKE_FINISHED);
658 }
659 else
660 {
661 ret = _gnutls_send_handshake (session, NULL((void*)0), GNUTLS_HANDSHAKE_FINISHED);
662 }
663
664 return ret;
665}
666
667/* This is to be called after sending our finished message. If everything
668 * went fine we have negotiated a secure connection
669 */
670static int
671_gnutls_recv_finished (gnutls_session_t session)
672{
673 uint8_t data[MAX_VERIFY_DATA_SIZE36], *vrfy;
674 gnutls_buffer_st buf;
675 int data_size;
676 int ret;
677 int vrfy_size;
678
679 ret =
680 _gnutls_recv_handshake (session, GNUTLS_HANDSHAKE_FINISHED,
681 MANDATORY_PACKET, &buf);
682 if (ret < 0)
683 {
684 ERR ("recv finished int", ret);
685 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",685); } while(0)
;
;
686 return ret;
687 }
688
689 vrfy = buf.data;
690 vrfy_size = buf.length;
691
692 if (gnutls_protocol_get_version_gnutls_protocol_get_version (session) == GNUTLS_SSL3)
693 {
694 data_size = 36;
695 }
696 else
697 {
698 data_size = 12;
699 }
700
701 if (vrfy_size != data_size)
702 {
703 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",703); } while(0)
;
;
704 ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET-18;
705 goto cleanup;
706 }
707
708 if (gnutls_protocol_get_version_gnutls_protocol_get_version (session) == GNUTLS_SSL3)
709 {
710 ret =
711 _gnutls_ssl3_finished (session,
712 (session->security_parameters.entity + 1) % 2,
713 data, 0);
714 }
715 else
716 { /* TLS 1.0 */
717 ret =
718 _gnutls_finished (session,
719 (session->security_parameters.entity +
720 1) % 2, data, 0);
721 }
722
723 if (ret < 0)
724 {
725 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",725); } while(0)
;
;
726 goto cleanup;
727 }
728
729 if (memcmp (vrfy, data, data_size) != 0)
730 {
731 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",731); } while(0)
;
;
732 ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET-18;
733 goto cleanup;
734 }
735
736 ret = _gnutls_ext_sr_finished (session, data, data_size, 1);
737 if (ret < 0)
738 {
739 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",739); } while(0)
;
;
740 goto cleanup;
741 }
742
743 if ((session->internals.resumed != RESUME_FALSE0
744 && session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
745 || (session->internals.resumed == RESUME_FALSE0
746 && session->security_parameters.entity == GNUTLS_SERVER1))
747 {
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",do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: recording tls-unique CB (recv)\n", session); }
while(0)
750 session)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: recording tls-unique CB (recv)\n", session); }
while(0)
;
751 memcpy (session->internals.cb_tls_unique, data, data_size);
752 session->internals.cb_tls_unique_len = data_size;
753 }
754
755
756 session->internals.initial_negotiation_completed = 1;
757
758cleanup:
759 _gnutls_buffer_clear(&buf);
760
761 return ret;
762}
763
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.
766 */
767static int
768server_find_pk_algos_in_ciphersuites (const opaque *
769 data, unsigned int datalen,
770 gnutls_pk_algorithm_t * algos,
771 size_t* algos_size)
772{
773 unsigned int j;
774 gnutls_kx_algorithm_t kx;
775 int max = *algos_size;
776
777 if (datalen % 2 != 0)
778 {
779 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",779); } while(0)
;
;
780 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
781 }
782
783 *algos_size = 0;
784 for (j = 0; j < datalen; j += 2)
785 {
786 kx = _gnutls_cipher_suite_get_kx_algo (&data[j]);
787 if (_gnutls_map_kx_get_cred (kx, 1) == GNUTLS_CRD_CERTIFICATE)
788 {
789 algos[(*algos_size)++] = _gnutls_map_pk_get_pk (kx);
790
791 if ((*algos_size) >= max)
792 return 0;
793 }
794 }
795
796 return 0;
797}
798
799/* This selects the best supported ciphersuite from the given ones. Then
800 * it adds the suite to the session and performs some checks.
801 */
802int
803_gnutls_server_select_suite (gnutls_session_t session, opaque * data,
804 int datalen)
805{
806 int i, j, ret, cipher_suites_size;
807 size_t pk_algos_size;
808 uint8_t cipher_suites[MAX_CIPHERSUITE_SIZE512];
809 int retval, err;
810 gnutls_pk_algorithm_t pk_algos[MAX_ALGOS32]; /* will hold the pk algorithms
811 * supported by the peer.
812 */
813
814 /* First, check for safe renegotiation SCSV.
815 */
816 if (session->internals.priorities.sr != SR_DISABLED)
817 {
818 int offset;
819
820 for (offset = 0; offset < datalen; offset += 2)
821 {
822 /* TLS_RENEGO_PROTECTION_REQUEST = { 0x00, 0xff } */
823 if (data[offset] == GNUTLS_RENEGO_PROTECTION_REQUEST_MAJOR0x00 &&
824 data[offset + 1] == GNUTLS_RENEGO_PROTECTION_REQUEST_MINOR0xFF)
825 {
826 _gnutls_handshake_logdo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Received safe renegotiation CS\n", session); }
while(0)
827 ("HSK[%p]: Received safe renegotiation CS\n", session)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Received safe renegotiation CS\n", session); }
while(0)
;
828 retval = _gnutls_ext_sr_recv_cs (session);
829 if (retval < 0)
830 {
831 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",831); } while(0)
;
;
832 return retval;
833 }
834 break;
835 }
836 }
837 }
838
839 pk_algos_size = MAX_ALGOS32;
840 ret = server_find_pk_algos_in_ciphersuites (data, datalen, pk_algos, &pk_algos_size);
841 if (ret < 0)
842 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 842);
843
844 ret = _gnutls_supported_ciphersuites (session, cipher_suites, sizeof(cipher_suites));
845 if (ret < 0)
846 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 846);
847
848 cipher_suites_size = ret;
849
850 /* Here we remove any ciphersuite that does not conform
851 * the certificate requested, or to the
852 * authentication requested (e.g. SRP).
853 */
854 ret = _gnutls_remove_unwanted_ciphersuites (session, cipher_suites, cipher_suites_size, pk_algos, pk_algos_size);
855 if (ret <= 0)
856 {
857 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",857); } while(0)
;
;
858 if (ret < 0)
859 return ret;
860 else
861 return GNUTLS_E_UNKNOWN_CIPHER_SUITE-21;
862 }
863
864 cipher_suites_size = ret;
865
866 /* Data length should be zero mod 2 since
867 * every ciphersuite is 2 bytes. (this check is needed
868 * see below).
869 */
870 if (datalen % 2 != 0)
871 {
872 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",872); } while(0)
;
;
873 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
874 }
875
876 memset (session->security_parameters.cipher_suite, 0, 2);
877
878 retval = GNUTLS_E_UNKNOWN_CIPHER_SUITE-21;
879
880 _gnutls_handshake_log ("HSK[%p]: Requested cipher suites[size: %d]: \n", session, (int)datalen)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Requested cipher suites[size: %d]: \n", session
, (int)datalen); } while(0)
;
881
882 if (session->internals.priorities.server_precedence == 0)
883 {
884 for (j = 0; j < datalen; j += 2)
885 {
886 _gnutls_handshake_log ("\t0x%.2x, 0x%.2x %s\n", data[j], data[j+1], _gnutls_cipher_suite_get_name (&data[j]))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "\t0x%.2x, 0x%.2x %s\n", data[j], data[j+1], _gnutls_cipher_suite_get_name
(&data[j])); } while(0)
;
887 for (i = 0; i < cipher_suites_size; i+=2)
888 {
889 if (memcmp (&cipher_suites[i], &data[j], 2) == 0)
890 {
891 _gnutls_handshake_logdo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected cipher suite: %s\n", session, _gnutls_cipher_suite_get_name
(&data[j])); } while(0)
892 ("HSK[%p]: Selected cipher suite: %s\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected cipher suite: %s\n", session, _gnutls_cipher_suite_get_name
(&data[j])); } while(0)
893 _gnutls_cipher_suite_get_name (&data[j]))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected cipher suite: %s\n", session, _gnutls_cipher_suite_get_name
(&data[j])); } while(0)
;
894 memcpy (session->security_parameters.cipher_suite,
895 &cipher_suites[i], 2);
896 _gnutls_epoch_set_cipher_suite (session, EPOCH_NEXT70002,
897 session->
898 security_parameters.cipher_suite);
899
900
901 retval = 0;
902 goto finish;
903 }
904 }
905 }
906 }
907 else /* server selects */
908 {
909 for (i = 0; i < cipher_suites_size; i+=2)
910 {
911 for (j = 0; j < datalen; j += 2)
912 {
913 if (memcmp (&cipher_suites[i], &data[j], 2) == 0)
914 {
915 _gnutls_handshake_logdo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected cipher suite: %s\n", session, _gnutls_cipher_suite_get_name
(&data[j])); } while(0)
916 ("HSK[%p]: Selected cipher suite: %s\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected cipher suite: %s\n", session, _gnutls_cipher_suite_get_name
(&data[j])); } while(0)
917 _gnutls_cipher_suite_get_name (&data[j]))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected cipher suite: %s\n", session, _gnutls_cipher_suite_get_name
(&data[j])); } while(0)
;
918 memcpy (session->security_parameters.cipher_suite,
919 &cipher_suites[i], 2);
920 _gnutls_epoch_set_cipher_suite (session, EPOCH_NEXT70002,
921 session->
922 security_parameters.cipher_suite);
923
924
925 retval = 0;
926 goto finish;
927 }
928 }
929 }
930 }
931finish:
932
933 if (retval != 0)
934 {
935 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",935); } while(0)
;
;
936 return retval;
937 }
938
939 /* check if the credentials (username, public key etc.) are ok
940 */
941 if (_gnutls_get_kx_cred
942 (session,
943 _gnutls_cipher_suite_get_kx_algo (session->
944 security_parameters.cipher_suite),
945 &err) == NULL((void*)0) && err != 0)
946 {
947 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",947); } while(0)
;
;
948 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
949 }
950
951
952 /* set the mod_auth_st to the appropriate struct
953 * according to the KX algorithm. This is needed since all the
954 * handshake functions are read from there;
955 */
956 session->internals.auth_struct =
957 _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo
958 (session->
959 security_parameters.cipher_suite));
960 if (session->internals.auth_struct == NULL((void*)0))
961 {
962
963 _gnutls_handshake_logdo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cannot find the appropriate handler for the KX algorithm\n"
, session); } while(0)
964 ("HSK[%p]: Cannot find the appropriate handler for the KX algorithm\n",do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cannot find the appropriate handler for the KX algorithm\n"
, session); } while(0)
965 session)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cannot find the appropriate handler for the KX algorithm\n"
, session); } while(0)
;
966 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",966); } while(0)
;
;
967 return GNUTLS_E_INTERNAL_ERROR-59;
968 }
969
970 return 0;
971
972}
973
974
975/* This selects the best supported compression method from the ones provided
976 */
977static int
978_gnutls_server_select_comp_method (gnutls_session_t session,
979 opaque * data, int datalen)
980{
981 int x, i, j;
982 uint8_t comps[MAX_ALGOS32];
983
984 x = _gnutls_supported_compression_methods (session, comps, MAX_ALGOS32);
985 if (x < 0)
986 {
987 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",987); } while(0)
;
;
988 return x;
989 }
990
991 if (session->internals.priorities.server_precedence == 0)
992 {
993 for (j = 0; j < datalen; j++)
994 {
995 for (i = 0; i < x; i++)
996 {
997 if (comps[i] == data[j])
998 {
999 gnutls_compression_method_t method =
1000 _gnutls_compression_get_id (comps[i]);
1001
1002 _gnutls_epoch_set_compression (session, EPOCH_NEXT70002, method);
1003 session->security_parameters.compression_method = method;
1004
1005 _gnutls_handshake_logdo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected Compression Method: %s\n", session, gnutls_compression_get_name
(method)); } while(0)
1006 ("HSK[%p]: Selected Compression Method: %s\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected Compression Method: %s\n", session, gnutls_compression_get_name
(method)); } while(0)
1007 gnutls_compression_get_name (method))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected Compression Method: %s\n", session, gnutls_compression_get_name
(method)); } while(0)
;
1008 return 0;
1009 }
1010 }
1011 }
1012 }
1013 else
1014 {
1015 for (i = 0; i < x; i++)
1016 {
1017 for (j = 0; j < datalen; j++)
1018 {
1019 if (comps[i] == data[j])
1020 {
1021 gnutls_compression_method_t method =
1022 _gnutls_compression_get_id (comps[i]);
1023
1024 _gnutls_epoch_set_compression (session, EPOCH_NEXT70002, method);
1025 session->security_parameters.compression_method = method;
1026
1027 _gnutls_handshake_logdo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected Compression Method: %s\n", session, gnutls_compression_get_name
(method)); } while(0)
1028 ("HSK[%p]: Selected Compression Method: %s\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected Compression Method: %s\n", session, gnutls_compression_get_name
(method)); } while(0)
1029 gnutls_compression_get_name (method))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected Compression Method: %s\n", session, gnutls_compression_get_name
(method)); } while(0)
;
1030 return 0;
1031 }
1032 }
1033 }
1034 }
1035
1036 /* we were not able to find a compatible compression
1037 * algorithm
1038 */
1039 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1039); } while(0
);
;
1040 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM-3;
1041
1042}
1043
1044/* This function sends an empty handshake packet. (like hello request).
1045 * If the previous _gnutls_send_empty_handshake() returned
1046 * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
1047 * (until it returns ok), with NULL parameters.
1048 */
1049static int
1050_gnutls_send_empty_handshake (gnutls_session_t session,
1051 gnutls_handshake_description_t type, int again)
1052{
1053 mbuffer_st *bufel;
1054
1055 if (again == 0)
1056 {
1057 bufel = _gnutls_handshake_alloc (session, 0, 0);
1058 if (bufel == NULL((void*)0))
1059 {
1060 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1060); } while(0
);
;
1061 return GNUTLS_E_MEMORY_ERROR-25;
1062 }
1063 }
1064 else
1065 bufel = NULL((void*)0);
1066
1067 return _gnutls_send_handshake (session, bufel, type);
1068}
1069
1070
1071
1072
1073/* This function sends a handshake message of type 'type' containing the
1074 * data specified here. If the previous _gnutls_send_handshake() returned
1075 * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
1076 * (until it returns ok), with NULL parameters.
1077 */
1078int
1079_gnutls_send_handshake (gnutls_session_t session, mbuffer_st * bufel,
1080 gnutls_handshake_description_t type)
1081{
1082 int ret;
1083 uint8_t *data;
1084 uint32_t datasize, i_datasize;
1085 int pos = 0;
1086
1087 if (bufel == NULL((void*)0))
1088 {
1089 /* we are resuming a previously interrupted
1090 * send.
1091 */
1092 ret = _gnutls_handshake_io_write_flush (session);
1093 return ret;
1094
1095 }
1096
1097 /* first run */
1098 data = _mbuffer_get_uhead_ptr (bufel);
1099 i_datasize = _mbuffer_get_udata_size(bufel);
1100 datasize = i_datasize + _mbuffer_get_uhead_size (bufel);
1101
1102 data[pos++] = (uint8_t) type;
1103 _gnutls_write_uint24 (_mbuffer_get_udata_size (bufel), &data[pos]);
1104 pos += 3;
1105
1106 /* Add DTLS handshake fragment headers. The message will be
1107 * fragmented later by the fragmentation sub-layer. All fields must
1108 * be set properly for HMAC. The HMAC requires we pretend that the
1109 * message was sent in a single fragment. */
1110 if (IS_DTLS(session)(session->internals.transport == GNUTLS_DGRAM))
1111 {
1112 _gnutls_write_uint16 (session->internals.dtls.hsk_write_seq++, &data[pos]);
1113 pos += 2;
1114
1115 /* Fragment offset */
1116 _gnutls_write_uint24 (0, &data[pos]);
1117 pos += 3;
1118
1119 /* Fragment length */
1120 _gnutls_write_uint24 (i_datasize, &data[pos]);
1121 pos += 3;
1122 }
1123
1124 _gnutls_handshake_log ("HSK[%p]: %s was queued [%ld bytes]\n",do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: %s was queued [%ld bytes]\n", session, _gnutls_handshake2str
(type), (long) datasize); } while(0)
1125 session, _gnutls_handshake2str (type),do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: %s was queued [%ld bytes]\n", session, _gnutls_handshake2str
(type), (long) datasize); } while(0)
1126 (long) datasize)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: %s was queued [%ld bytes]\n", session, _gnutls_handshake2str
(type), (long) datasize); } while(0)
;
1127
1128 /* Here we keep the handshake messages in order to hash them...
1129 */
1130 if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
1131 if ((ret =
1132 _gnutls_handshake_hash_add_sent (session, type, data, datasize)) < 0)
1133 {
1134 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1134); } while(0
);
;
1135 _mbuffer_xfree(&bufel);
1136 return ret;
1137 }
1138
1139 session->internals.last_handshake_out = type;
1140
1141 ret = _gnutls_handshake_io_cache_int (session, type, bufel);
1142 if (ret < 0)
1143 {
1144 _mbuffer_xfree(&bufel);
1145 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1145); } while(0
);
;
1146 return ret;
1147 }
1148
1149 switch (type)
1150 {
1151 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT: /* this one is followed by ServerHelloDone
1152 * or ClientKeyExchange always.
1153 */
1154 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE: /* as above */
1155 case GNUTLS_HANDSHAKE_SERVER_HELLO: /* as above */
1156 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST: /* as above */
1157 case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: /* followed by ChangeCipherSpec */
1158
1159 /* now for client Certificate, ClientKeyExchange and
1160 * CertificateVerify are always followed by ChangeCipherSpec
1161 */
1162 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
1163 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
1164 ret = 0;
1165 break;
1166 default:
1167 /* send cached messages */
1168 ret = _gnutls_handshake_io_write_flush (session);
1169 break;
1170 }
1171
1172 return ret;
1173}
1174
1175#define CHECK_SIZE(ll)if ((session->internals.max_handshake_data_buffer_size >
0) && (((ll) + session->internals.handshake_hash_buffer
.length) > session->internals.max_handshake_data_buffer_size
)) return gnutls_assert_val_int(-210, "gnutls_handshake.c", 1175
)
\
1176 if ((session->internals.max_handshake_data_buffer_size > 0) && \
1177 (((ll) + session->internals.handshake_hash_buffer.length) > \
1178 session->internals.max_handshake_data_buffer_size)) \
1179 return gnutls_assert_val(GNUTLS_E_HANDSHAKE_TOO_LARGE)gnutls_assert_val_int(-210, "gnutls_handshake.c", 1179)
1180
1181/* This function add the handshake headers and the
1182 * handshake data to the handshake hash buffers. Needed
1183 * for the finished messages calculations.
1184 */
1185static int
1186_gnutls_handshake_hash_add_recvd (gnutls_session_t session,
1187 gnutls_handshake_description_t recv_type,
1188 opaque * header, uint16_t header_size,
1189 opaque * dataptr, uint32_t datalen)
1190{
1191 int ret;
1192
1193 if (recv_type == GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST ||
1194 recv_type == GNUTLS_HANDSHAKE_HELLO_REQUEST)
1195 return 0;
1196
1197 CHECK_SIZE(header_size + datalen)if ((session->internals.max_handshake_data_buffer_size >
0) && (((header_size + datalen) + session->internals
.handshake_hash_buffer.length) > session->internals.max_handshake_data_buffer_size
)) return gnutls_assert_val_int(-210, "gnutls_handshake.c", 1197
)
;
1198
1199 session->internals.handshake_hash_buffer_prev_len = session->internals.handshake_hash_buffer.length;
1200
1201 ret = _gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
1202 header, header_size);
1203 if (ret < 0)
1204 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 1204);
1205
1206 if (datalen > 0)
1207 {
1208 ret = _gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
1209 dataptr, datalen);
1210 if (ret < 0)
1211 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 1211);
1212 }
1213
1214 return 0;
1215}
1216
1217/* This function will store the handshake message we sent.
1218 */
1219static int
1220_gnutls_handshake_hash_add_sent (gnutls_session_t session,
1221 gnutls_handshake_description_t type,
1222 opaque * dataptr, uint32_t datalen)
1223{
1224 int ret;
1225
1226 /* We don't check for GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST because it
1227 * is not sent via that channel.
1228 */
1229 if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
1230 {
1231 CHECK_SIZE(datalen)if ((session->internals.max_handshake_data_buffer_size >
0) && (((datalen) + session->internals.handshake_hash_buffer
.length) > session->internals.max_handshake_data_buffer_size
)) return gnutls_assert_val_int(-210, "gnutls_handshake.c", 1231
)
;
1232
1233 ret = _gnutls_buffer_append_data(&session->internals.handshake_hash_buffer,
1234 dataptr, datalen);
1235 if (ret < 0)
1236 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 1236);
1237
1238 return 0;
1239 }
1240
1241 return 0;
1242}
1243
1244
1245/* This function will receive handshake messages of the given types,
1246 * and will pass the message to the right place in order to be processed.
1247 * E.g. for the SERVER_HELLO message (if it is expected), it will be
1248 * passed to _gnutls_recv_hello().
1249 */
1250int
1251_gnutls_recv_handshake (gnutls_session_t session,
1252 gnutls_handshake_description_t type,
1253 optional_t optional, gnutls_buffer_st* buf)
1254{
1255 int ret;
1256 handshake_buffer_st hsk;
1257
1258 ret =
1259 _gnutls_handshake_io_recv_int (session, type, &hsk);
1260 if (ret < 0)
1261 {
1262 if (optional == OPTIONAL_PACKET && ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET-19)
1263 {
1264 if (buf) _gnutls_buffer_init(buf);
1265 return 0;
1266 }
1267
1268 if (ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET-19)
1269 _gnutls_audit_log(session, "Received unexpected handshake message '%s' (%d). Expected '%s' (%d)\n",
1270 _gnutls_handshake2str(hsk.htype), (int)hsk.htype, _gnutls_handshake2str(type), (int)type);
1271
1272 return gnutls_assert_val_fatal(ret)(((ret)!=-28 && (ret)!=-52)?gnutls_assert_val_int(ret
, "gnutls_handshake.c", 1272):(ret))
;
1273 }
1274
1275 ret = _gnutls_handshake_hash_add_recvd (session, hsk.htype,
1276 hsk.header, hsk.header_size,
1277 hsk.data.data, hsk.data.length);
1278 if (ret < 0)
1279 {
1280 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1280); } while(0
);
;
1281 goto cleanup;
1282 }
1283
1284 switch (hsk.htype)
1285 {
1286 case GNUTLS_HANDSHAKE_CLIENT_HELLO_V2:
1287 case GNUTLS_HANDSHAKE_CLIENT_HELLO:
1288 case GNUTLS_HANDSHAKE_SERVER_HELLO:
1289 if (hsk.htype == GNUTLS_HANDSHAKE_CLIENT_HELLO_V2)
1290 ret = _gnutls_read_client_hello_v2 (session, hsk.data.data, hsk.data.length);
1291 else
1292 ret = _gnutls_recv_hello (session, hsk.data.data, hsk.data.length);
1293
1294 if (ret < 0)
1295 {
1296 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1296); } while(0
);
;
1297 goto cleanup;
1298 }
1299
1300 goto cleanup; /* caller doesn't need dataptr */
1301
1302 break;
1303 case GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST:
1304 ret = _gnutls_recv_hello_verify_request (session, hsk.data.data, hsk.data.length);
1305 if (ret < 0)
1306 {
1307 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1307); } while(0
);
;
1308 goto cleanup;
1309 }
1310 else
1311 /* Signal our caller we have received a verification cookie
1312 and ClientHello needs to be sent again. */
1313 ret = 1;
1314
1315 goto cleanup; /* caller doesn't need dataptr */
1316
1317 break;
1318 case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
1319 if (hsk.data.length == 0)
1320 ret = 0;
1321 else
1322 {
1323 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1323); } while(0
);
;
1324 ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
1325 goto cleanup;
1326 }
1327 break;
1328 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
1329 case GNUTLS_HANDSHAKE_FINISHED:
1330 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
1331 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
1332 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
1333 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
1334 case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
1335 case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET:
1336 ret = hsk.data.length;
1337 break;
1338 default:
1339 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1339); } while(0
);
;
1340 /* we shouldn't actually arrive here in any case .
1341 * unexpected messages should be catched after _gnutls_handshake_io_recv_int()
1342 */
1343 ret = GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET-19;
1344 goto cleanup;
1345 }
1346
1347 if (buf)
1348 {
1349 *buf = hsk.data;
1350 return ret;
1351 }
1352
1353cleanup:
1354 _gnutls_handshake_buffer_clear (&hsk);
1355 return ret;
1356}
1357
1358/* This function checks if the given cipher suite is supported, and sets it
1359 * to the session;
1360 */
1361static int
1362_gnutls_client_set_ciphersuite (gnutls_session_t session, opaque suite[2])
1363{
1364 uint8_t z;
1365 uint8_t cipher_suites[MAX_CIPHERSUITE_SIZE512];
1366 int cipher_suite_size;
1367 int i, err;
1368
1369 z = 1;
1370 cipher_suite_size = _gnutls_supported_ciphersuites (session, cipher_suites, sizeof(cipher_suites));
1371 if (cipher_suite_size < 0)
1372 {
1373 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1373); } while(0
);
;
1374 return cipher_suite_size;
1375 }
1376
1377 for (i = 0; i < cipher_suite_size; i+=2)
1378 {
1379 if (memcmp (&cipher_suites[i], suite, 2) == 0)
1380 {
1381 z = 0;
1382 break;
1383 }
1384 }
1385
1386 if (z != 0)
1387 {
1388 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1388); } while(0
);
;
1389 return GNUTLS_E_UNKNOWN_CIPHER_SUITE-21;
1390 }
1391
1392 memcpy (session->security_parameters.cipher_suite, suite, 2);
1393 _gnutls_epoch_set_cipher_suite (session, EPOCH_NEXT70002,
1394 session->
1395 security_parameters.cipher_suite);
1396
1397 _gnutls_handshake_log ("HSK[%p]: Selected cipher suite: %s\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected cipher suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
1398 _gnutls_cipher_suite_get_namedo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected cipher suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
1399 (session->do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected cipher suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
1400 security_parameters.cipher_suite))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected cipher suite: %s\n", session, _gnutls_cipher_suite_get_name
(session-> security_parameters.cipher_suite)); } while(0)
;
1401
1402
1403 /* check if the credentials (username, public key etc.) are ok.
1404 * Actually checks if they exist.
1405 */
1406 if (_gnutls_get_kx_cred
1407 (session,
1408 _gnutls_cipher_suite_get_kx_algo
1409 (session->security_parameters.cipher_suite), &err) == NULL((void*)0)
1410 && err != 0)
1411 {
1412 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1412); } while(0
);
;
1413 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
1414 }
1415
1416
1417 /* set the mod_auth_st to the appropriate struct
1418 * according to the KX algorithm. This is needed since all the
1419 * handshake functions are read from there;
1420 */
1421 session->internals.auth_struct =
1422 _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo
1423 (session->
1424 security_parameters.cipher_suite));
1425
1426 if (session->internals.auth_struct == NULL((void*)0))
1427 {
1428
1429 _gnutls_handshake_logdo { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cannot find the appropriate handler for the KX algorithm\n"
, session); } while(0)
1430 ("HSK[%p]: Cannot find the appropriate handler for the KX algorithm\n",do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cannot find the appropriate handler for the KX algorithm\n"
, session); } while(0)
1431 session)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Cannot find the appropriate handler for the KX algorithm\n"
, session); } while(0)
;
1432 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1432); } while(0
);
;
1433 return GNUTLS_E_INTERNAL_ERROR-59;
1434 }
1435
1436
1437 return 0;
1438}
1439
1440/* This function sets the given comp method to the session.
1441 */
1442static int
1443_gnutls_client_set_comp_method (gnutls_session_t session, opaque comp_method)
1444{
1445 int comp_methods_num;
1446 uint8_t compression_methods[MAX_ALGOS32];
1447 int id = _gnutls_compression_get_id(comp_method);
1448 int i;
1449
1450 _gnutls_handshake_log ("HSK[%p]: Selected compression method: %s (%d)\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected compression method: %s (%d)\n", session
, gnutls_compression_get_name(id), (int)comp_method); } while
(0)
1451 gnutls_compression_get_name(id), (int)comp_method)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Selected compression method: %s (%d)\n", session
, gnutls_compression_get_name(id), (int)comp_method); } while
(0)
;
1452
1453 comp_methods_num = _gnutls_supported_compression_methods (session,
1454 compression_methods, MAX_ALGOS32);
1455 if (comp_methods_num < 0)
1456 {
1457 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1457); } while(0
);
;
1458 return comp_methods_num;
1459 }
1460
1461 for (i = 0; i < comp_methods_num; i++)
1462 {
1463 if (compression_methods[i] == comp_method)
1464 {
1465 comp_methods_num = 0;
1466 break;
1467 }
1468 }
1469
1470 if (comp_methods_num != 0)
1471 {
1472 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1472); } while(0
);
;
1473 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM-3;
1474 }
1475
1476 session->security_parameters.compression_method = id;
1477 _gnutls_epoch_set_compression (session, EPOCH_NEXT70002, id);
1478
1479 return 0;
1480}
1481
1482/* This function returns 0 if we are resuming a session or -1 otherwise.
1483 * This also sets the variables in the session. Used only while reading a server
1484 * hello.
1485 */
1486static int
1487_gnutls_client_check_if_resuming (gnutls_session_t session,
1488 opaque * session_id, int session_id_len)
1489{
1490 opaque buf[2 * TLS_MAX_SESSION_ID_SIZE32 + 1];
1491
1492 _gnutls_handshake_log ("HSK[%p]: SessionID length: %d\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: SessionID length: %d\n", session, session_id_len
); } while(0)
1493 session_id_len)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: SessionID length: %d\n", session, session_id_len
); } while(0)
;
1494 _gnutls_handshake_log ("HSK[%p]: SessionID: %s\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: SessionID: %s\n", session, _gnutls_bin2hex (session_id
, session_id_len, buf, sizeof (buf), ((void*)0))); } while(0)
1495 _gnutls_bin2hex (session_id, session_id_len, buf,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: SessionID: %s\n", session, _gnutls_bin2hex (session_id
, session_id_len, buf, sizeof (buf), ((void*)0))); } while(0)
1496 sizeof (buf), NULL))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: SessionID: %s\n", session, _gnutls_bin2hex (session_id
, session_id_len, buf, sizeof (buf), ((void*)0))); } while(0)
;
1497
1498 if (session_id_len > 0 &&
1499 session->internals.resumed_security_parameters.session_id_size ==
1500 session_id_len
1501 && memcmp (session_id,
1502 session->internals.resumed_security_parameters.session_id,
1503 session_id_len) == 0)
1504 {
1505 /* resume session */
1506 memcpy (session->internals.resumed_security_parameters.server_random,
1507 session->security_parameters.server_random, GNUTLS_RANDOM_SIZE32);
1508 memcpy (session->internals.resumed_security_parameters.client_random,
1509 session->security_parameters.client_random, GNUTLS_RANDOM_SIZE32);
1510
1511 _gnutls_epoch_set_cipher_suite
1512 (session, EPOCH_NEXT70002,
1513 session->internals.
1514 resumed_security_parameters.cipher_suite);
1515 _gnutls_epoch_set_compression (session, EPOCH_NEXT70002,
1516 session->
1517 internals.resumed_security_parameters.compression_method);
1518
1519 session->internals.resumed = RESUME_TRUE1; /* we are resuming */
1520
1521 return 0;
1522 }
1523 else
1524 {
1525 /* keep the new session id */
1526 session->internals.resumed = RESUME_FALSE0; /* we are not resuming */
1527 session->security_parameters.session_id_size = session_id_len;
1528 memcpy (session->security_parameters.session_id,
1529 session_id, session_id_len);
1530
1531 return -1;
1532 }
1533}
1534
1535
1536/* This function reads and parses the server hello handshake message.
1537 * This function also restores resumed parameters if we are resuming a
1538 * session.
1539 */
1540static int
1541_gnutls_read_server_hello (gnutls_session_t session,
1542 opaque * data, int datalen)
1543{
1544 uint8_t session_id_len = 0;
1545 int pos = 0;
1546 int ret = 0;
1547 gnutls_protocol_t version;
1548 int len = datalen;
1549
1550 if (datalen < 38)
1551 {
1552 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1552); } while(0
);
;
1553 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
1554 }
1555
1556 _gnutls_handshake_log ("HSK[%p]: Server's version: %d.%d\n",do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Server's version: %d.%d\n", session, data[pos]
, data[pos + 1]); } while(0)
1557 session, data[pos], data[pos + 1])do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Server's version: %d.%d\n", session, data[pos]
, data[pos + 1]); } while(0)
;
1558
1559 DECR_LEN (len, 2)do { len-=2; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,1559); } while(0);; return -9;} } while (0)
;
1560 version = _gnutls_version_get (data[pos], data[pos + 1]);
1561 if (_gnutls_version_is_supported (session, version) == 0)
1562 {
1563 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1563); } while(0
);
;
1564 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET-8;
1565 }
1566 else
1567 {
1568 _gnutls_set_current_version (session, version);
1569 }
1570
1571 pos += 2;
1572
1573 DECR_LEN (len, GNUTLS_RANDOM_SIZE)do { len-=32; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,1573); } while(0);; return -9;} } while (0)
;
1574 _gnutls_set_server_random (session, &data[pos]);
1575 pos += GNUTLS_RANDOM_SIZE32;
1576
1577
1578 /* Read session ID
1579 */
1580 DECR_LEN (len, 1)do { len-=1; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,1580); } while(0);; return -9;} } while (0)
;
1581 session_id_len = data[pos++];
1582
1583 if (len < session_id_len)
1584 {
1585 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1585); } while(0
);
;
1586 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET-8;
1587 }
1588 DECR_LEN (len, session_id_len)do { len-=session_id_len; if (len<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",1588); } while(0);; return -9;} } while
(0)
;
1589
1590 /* check if we are resuming and set the appropriate
1591 * values;
1592 */
1593 if (_gnutls_client_check_if_resuming
1594 (session, &data[pos], session_id_len) == 0)
1595 {
1596 pos += session_id_len + 2 + 1;
1597 DECR_LEN (len, 2 + 1)do { len-=2 + 1; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,1597); } while(0);; return -9;} } while (0)
;
1598
1599 ret = _gnutls_parse_extensions (session, GNUTLS_EXT_MANDATORY,
1600 &data[pos], len);
1601 if (ret < 0)
1602 {
1603 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1603); } while(0
);
;
1604 return ret;
1605 }
1606 return 0;
1607 }
1608
1609 pos += session_id_len;
1610
1611 /* Check if the given cipher suite is supported and copy
1612 * it to the session.
1613 */
1614
1615 DECR_LEN (len, 2)do { len-=2; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,1615); } while(0);; return -9;} } while (0)
;
1616 ret = _gnutls_client_set_ciphersuite (session, &data[pos]);
1617 if (ret < 0)
1618 {
1619 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1619); } while(0
);
;
1620 return ret;
1621 }
1622 pos += 2;
1623
1624 /* move to compression
1625 */
1626 DECR_LEN (len, 1)do { len-=1; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,1626); } while(0);; return -9;} } while (0)
;
1627
1628 ret = _gnutls_client_set_comp_method (session, data[pos++]);
1629 if (ret < 0)
1630 {
1631 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1631); } while(0
);
;
1632 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM-3;
1633 }
1634
1635 /* Parse extensions.
1636 */
1637 ret = _gnutls_parse_extensions (session, GNUTLS_EXT_ANY, &data[pos], len);
1638 if (ret < 0)
1639 {
1640 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1640); } while(0
);
;
1641 return ret;
1642 }
1643
1644 return ret;
1645}
1646
1647
1648/* This function copies the appropriate ciphersuites to a locally allocated buffer
1649 * Needed in client hello messages. Returns the new data length. If add_scsv is
1650 * true, add the special safe renegotiation CS.
1651 */
1652static int
1653_gnutls_copy_ciphersuites (gnutls_session_t session,
1654 gnutls_buffer_st * cdata,
1655 int add_scsv)
1656{
1657 int ret;
1658 uint8_t cipher_suites[MAX_CIPHERSUITE_SIZE512+2];
1659 int cipher_suites_size;
1660 size_t init_length = cdata->length;
1661
1662 ret = _gnutls_supported_ciphersuites (session, cipher_suites, sizeof(cipher_suites)-2);
1663 if (ret < 0)
1664 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 1664);
1665
1666 /* Here we remove any ciphersuite that does not conform
1667 * the certificate requested, or to the
1668 * authentication requested (eg SRP).
1669 */
1670 ret =
1671 _gnutls_remove_unwanted_ciphersuites (session, cipher_suites, ret, NULL((void*)0), 0);
1672 if (ret < 0)
1673 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 1673);
1674
1675 /* If no cipher suites were enabled.
1676 */
1677 if (ret == 0)
1678 return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS)gnutls_assert_val_int(-32, "gnutls_handshake.c", 1678);
1679
1680 cipher_suites_size = ret;
1681 if (add_scsv)
1682 {
1683 cipher_suites[cipher_suites_size] = 0x00;
1684 cipher_suites[cipher_suites_size+1] = 0xff;
1685 cipher_suites_size += 2;
1686
1687 ret = _gnutls_ext_sr_send_cs (session);
1688 if (ret < 0)
1689 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 1689);
1690 }
1691
1692 ret = _gnutls_buffer_append_data_prefix(cdata, 16, cipher_suites, cipher_suites_size);
1693 if (ret < 0)
1694 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 1694);
1695
1696 ret = cdata->length - init_length;
1697
1698 return ret;
1699}
1700
1701
1702/* This function copies the appropriate compression methods, to a locally allocated buffer
1703 * Needed in hello messages. Returns the new data length.
1704 */
1705static int
1706_gnutls_copy_comp_methods (gnutls_session_t session,
1707 gnutls_buffer_st * cdata)
1708{
1709 int ret;
1710 uint8_t compression_methods[MAX_ALGOS32], comp_num;
1711 size_t init_length = cdata->length;
1712
1713 ret = _gnutls_supported_compression_methods (session, compression_methods, MAX_ALGOS32);
1714 if (ret < 0)
1715 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 1715);
1716
1717 comp_num = ret;
1718
1719 /* put the number of compression methods */
1720 ret = _gnutls_buffer_append_prefix(cdata, 8, comp_num);
1721 if (ret < 0)
1722 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 1722);
1723
1724 ret = _gnutls_buffer_append_data(cdata, compression_methods, comp_num);
1725 if (ret < 0)
1726 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 1726);
1727
1728 ret = cdata->length - init_length;
1729
1730 return ret;
1731}
1732
1733/* This should be sufficient by now. It should hold all the extensions
1734 * plus the headers in a hello message.
1735 */
1736#define MAX_EXT_DATA_LENGTH32*1024 32*1024
1737
1738/* This function sends the client hello handshake message.
1739 */
1740static int
1741_gnutls_send_client_hello (gnutls_session_t session, int again)
1742{
1743 mbuffer_st *bufel = NULL((void*)0);
1744 opaque *data = NULL((void*)0);
1745 int pos = 0, type;
1746 int datalen = 0, ret = 0;
1747 opaque rnd[GNUTLS_RANDOM_SIZE32];
1748 gnutls_protocol_t hver;
1749 gnutls_buffer_st extdata;
1750 int rehandshake = 0;
1751 uint8_t session_id_len =
1752 session->internals.resumed_security_parameters.session_id_size;
1753 uint8_t cookie_len;
1754
1755 _gnutls_buffer_init(&extdata);
1756
1757 /* note that rehandshake is different than resuming
1758 */
1759 if (session->security_parameters.session_id_size)
1760 rehandshake = 1;
1761
1762 if (again == 0)
1763 {
1764 if(IS_DTLS(session)(session->internals.transport == GNUTLS_DGRAM))
1765 {
1766 cookie_len = session->internals.dtls.cookie_len + 1;
1767 }
1768 else
1769 {
1770 cookie_len = 0;
1771 }
1772
1773 datalen = 2 + (session_id_len + 1) + GNUTLS_RANDOM_SIZE32 + cookie_len;
1774 /* 2 for version, (4 for unix time + 28 for random bytes==GNUTLS_RANDOM_SIZE)
1775 */
1776
1777 bufel = _gnutls_handshake_alloc (session, datalen, datalen+MAX_EXT_DATA_LENGTH32*1024);
1778 if (bufel == NULL((void*)0))
1779 {
1780 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1780); } while(0
);
;
1781 return GNUTLS_E_MEMORY_ERROR-25;
1782 }
1783 data = _mbuffer_get_udata_ptr (bufel);
1784
1785 /* if we are resuming a session then we set the
1786 * version number to the previously established.
1787 */
1788 if (session_id_len == 0)
1789 {
1790 if (rehandshake) /* already negotiated version thus version_max == negotiated version */
1791 hver = session->security_parameters.version;
1792 else /* new handshake. just get the max */
1793 hver = _gnutls_version_max (session);
1794 }
1795 else
1796 {
1797 /* we are resuming a session */
1798 hver = session->internals.resumed_security_parameters.version;
1799 }
1800
1801 if (hver == GNUTLS_VERSION_UNKNOWN || hver == 0)
1802 {
1803 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1803); } while(0
);
;
1804 gnutls_free (bufel);
1805 return GNUTLS_E_INTERNAL_ERROR-59;
1806 }
1807
1808 data[pos++] = _gnutls_version_get_major (hver);
1809 data[pos++] = _gnutls_version_get_minor (hver);
1810
1811 /* Set the version we advertized as maximum
1812 * (RSA uses it).
1813 */
1814 _gnutls_set_adv_version (session, hver);
1815 _gnutls_set_current_version (session, hver);
1816
1817 if (session->internals.priorities.ssl3_record_version != 0)
1818 {
1819 /* Advertize the SSL 3.0 record packet version in
1820 * record packets during the handshake.
1821 * That is to avoid confusing implementations
1822 * that do not support TLS 1.2 and don't know
1823 * how 3,3 version of record packets look like.
1824 */
1825 if (!IS_DTLS(session)(session->internals.transport == GNUTLS_DGRAM))
1826 _gnutls_record_set_default_version (session, 3, 0);
1827 else
1828 _gnutls_record_set_default_version (session, 254, 255);
1829 }
1830
1831 /* In order to know when this session was initiated.
1832 */
1833 session->security_parameters.timestamp = gnutls_time (NULL((void*)0));
1834
1835 /* Generate random data
1836 */
1837 if (!IS_DTLS (session)(session->internals.transport == GNUTLS_DGRAM)
1838 || session->internals.dtls.hsk_hello_verify_requests == 0)
1839 {
1840 _gnutls_tls_create_random (rnd);
1841 _gnutls_set_client_random (session, rnd);
1842
1843 memcpy (&data[pos], rnd, GNUTLS_RANDOM_SIZE32);
1844 }
1845 else
1846 memcpy (&data[pos], session->security_parameters.client_random, GNUTLS_RANDOM_SIZE32);
1847
1848 pos += GNUTLS_RANDOM_SIZE32;
1849
1850 /* Copy the Session ID
1851 */
1852 data[pos++] = session_id_len;
1853
1854 if (session_id_len > 0)
1855 {
1856 memcpy (&data[pos],
1857 session->internals.resumed_security_parameters.session_id,
1858 session_id_len);
1859 pos += session_id_len;
1860 }
1861
1862 /* Copy the DTLS cookie
1863 */
1864 if (IS_DTLS(session)(session->internals.transport == GNUTLS_DGRAM))
1865 {
1866 data[pos++] = session->internals.dtls.cookie_len;
1867 memcpy(&data[pos], &session->internals.dtls.cookie, session->internals.dtls.cookie_len);
1868 pos += session->internals.dtls.cookie_len;
1869 }
1870
1871 /* Copy the ciphersuites.
1872 *
1873 * If using SSLv3 Send TLS_RENEGO_PROTECTION_REQUEST SCSV for MITM
1874 * prevention on initial negotiation (but not renegotiation; that's
1875 * handled with the RI extension below).
1876 */
1877 if (!session->internals.initial_negotiation_completed &&
1878 session->security_parameters.entity == GNUTLS_CLIENT(1<<1) &&
1879 (gnutls_protocol_get_version_gnutls_protocol_get_version (session) == GNUTLS_SSL3 ||
1880 session->internals.priorities.no_extensions != 0))
1881 {
1882 ret =
1883 _gnutls_copy_ciphersuites (session, &extdata, TRUE1);
1884 _gnutls_extension_list_add (session,
1885 GNUTLS_EXTENSION_SAFE_RENEGOTIATION);
1886 }
1887 else
1888 ret = _gnutls_copy_ciphersuites (session, &extdata, FALSE0);
1889
1890 if (ret < 0)
1891 {
1892 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1892); } while(0
);
;
1893 goto cleanup;
1894 }
1895
1896 /* Copy the compression methods.
1897 */
1898 ret = _gnutls_copy_comp_methods (session, &extdata);
1899 if (ret < 0)
1900 {
1901 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1901); } while(0
);
;
1902 goto cleanup;
1903 }
1904
1905 /* Generate and copy TLS extensions.
1906 */
1907 if (session->internals.priorities.no_extensions == 0)
1908 {
1909 if (_gnutls_version_has_extensions (hver))
1910 type = GNUTLS_EXT_ANY;
1911 else
1912 {
1913 if (session->internals.initial_negotiation_completed != 0)
1914 type = GNUTLS_EXT_MANDATORY;
1915 else
1916 type = GNUTLS_EXT_NONE;
1917 }
1918
1919 ret = _gnutls_gen_extensions (session, &extdata, type);
1920 if (ret < 0)
1921 {
1922 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1922); } while(0
);
;
1923 goto cleanup;
1924 }
1925
1926 }
1927
1928 ret = _mbuffer_append_data (bufel, extdata.data, extdata.length);
1929 if (ret < 0)
1930 {
1931 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1931); } while(0
);
;
1932 goto cleanup;
1933 }
1934 }
1935
1936 _gnutls_buffer_clear(&extdata);
1937
1938 return
1939 _gnutls_send_handshake (session, bufel, GNUTLS_HANDSHAKE_CLIENT_HELLO);
1940
1941cleanup:
1942 _mbuffer_xfree(&bufel);
1943 _gnutls_buffer_clear(&extdata);
1944 return ret;
1945}
1946
1947static int
1948_gnutls_send_server_hello (gnutls_session_t session, int again)
1949{
1950 mbuffer_st *bufel = NULL((void*)0);
1951 opaque *data = NULL((void*)0);
1952 gnutls_buffer_st extdata;
1953 int pos = 0;
1954 int datalen, ret = 0;
1955 uint8_t comp;
1956 uint8_t session_id_len = session->security_parameters.session_id_size;
1957 opaque buf[2 * TLS_MAX_SESSION_ID_SIZE32 + 1];
1958
1959 datalen = 0;
Value stored to 'datalen' is never read
1960
1961 _gnutls_buffer_init(&extdata);
1962
1963 if (again == 0)
1964 {
1965 datalen = 2 + session_id_len + 1 + GNUTLS_RANDOM_SIZE32 + 3;
1966 ret =
1967 _gnutls_gen_extensions (session, &extdata, GNUTLS_EXT_ANY);
1968 if (ret < 0)
1969 {
1970 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1970); } while(0
);
;
1971 goto fail;
1972 }
1973
1974 bufel = _gnutls_handshake_alloc (session, datalen + extdata.length, datalen + extdata.length);
1975 if (bufel == NULL((void*)0))
1976 {
1977 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",1977); } while(0
);
;
1978 ret = GNUTLS_E_MEMORY_ERROR-25;
1979 goto fail;
1980 }
1981 data = _mbuffer_get_udata_ptr (bufel);
1982
1983 data[pos++] =
1984 _gnutls_version_get_major (session->security_parameters.version);
1985 data[pos++] =
1986 _gnutls_version_get_minor (session->security_parameters.version);
1987
1988 memcpy (&data[pos],
1989 session->security_parameters.server_random, GNUTLS_RANDOM_SIZE32);
1990 pos += GNUTLS_RANDOM_SIZE32;
1991
1992 data[pos++] = session_id_len;
1993 if (session_id_len > 0)
1994 {
1995 memcpy (&data[pos], session->security_parameters.session_id,
1996 session_id_len);
1997 }
1998 pos += session_id_len;
1999
2000 _gnutls_handshake_log ("HSK[%p]: SessionID: %s\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: SessionID: %s\n", session, _gnutls_bin2hex (session
->security_parameters. session_id, session_id_len, buf, sizeof
(buf), ((void*)0))); } while(0)
2001 _gnutls_bin2hex (session->security_parameters.do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: SessionID: %s\n", session, _gnutls_bin2hex (session
->security_parameters. session_id, session_id_len, buf, sizeof
(buf), ((void*)0))); } while(0)
2002 session_id, session_id_len, buf,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: SessionID: %s\n", session, _gnutls_bin2hex (session
->security_parameters. session_id, session_id_len, buf, sizeof
(buf), ((void*)0))); } while(0)
2003 sizeof (buf), NULL))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: SessionID: %s\n", session, _gnutls_bin2hex (session
->security_parameters. session_id, session_id_len, buf, sizeof
(buf), ((void*)0))); } while(0)
;
2004
2005 memcpy (&data[pos],
2006 session->security_parameters.cipher_suite, 2);
2007 pos += 2;
2008
2009 comp = _gnutls_compression_get_num ( session->security_parameters.compression_method);
2010 data[pos++] = comp;
2011
2012 if (extdata.length > 0)
2013 {
2014 datalen += extdata.length;
2015 memcpy (&data[pos], extdata.data, extdata.length);
2016 }
2017 }
2018
2019 ret =
2020 _gnutls_send_handshake (session, bufel, GNUTLS_HANDSHAKE_SERVER_HELLO);
2021
2022fail:
2023 _gnutls_buffer_clear(&extdata);
2024 return ret;
2025}
2026
2027int
2028_gnutls_send_hello (gnutls_session_t session, int again)
2029{
2030 int ret;
2031
2032 if (session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
2033 {
2034 ret = _gnutls_send_client_hello (session, again);
2035
2036 }
2037 else
2038 { /* SERVER */
2039 ret = _gnutls_send_server_hello (session, again);
2040 }
2041
2042 return ret;
2043}
2044
2045/* RECEIVE A HELLO MESSAGE. This should be called from gnutls_recv_handshake_int only if a
2046 * hello message is expected. It uses the security_parameters.cipher_suite
2047 * and internals.compression_method.
2048 */
2049int
2050_gnutls_recv_hello (gnutls_session_t session, opaque * data, int datalen)
2051{
2052 int ret;
2053
2054 if (session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
2055 {
2056 ret = _gnutls_read_server_hello (session, data, datalen);
2057 if (ret < 0)
2058 {
2059 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2059); } while(0
);
;
2060 return ret;
2061 }
2062 }
2063 else
2064 { /* Server side reading a client hello */
2065
2066 ret = _gnutls_read_client_hello (session, data, datalen);
2067 if (ret < 0)
2068 {
2069 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2069); } while(0
);
;
2070 return ret;
2071 }
2072 }
2073
2074 ret = _gnutls_ext_sr_verify (session);
2075 if (ret < 0)
2076 {
2077 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2077); } while(0
);
;
2078 return ret;
2079 }
2080
2081 return 0;
2082}
2083
2084static int
2085_gnutls_recv_hello_verify_request (gnutls_session_t session,
2086 opaque * data, int datalen)
2087{
2088 ssize_t len = datalen;
2089 size_t pos = 0;
2090 uint8_t cookie_len;
2091 unsigned int nb_verifs;
2092
2093 if (!IS_DTLS (session)(session->internals.transport == GNUTLS_DGRAM)
2094 || session->security_parameters.entity == GNUTLS_SERVER1)
2095 {
2096 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2096); } while(0
);
;
2097 return GNUTLS_E_INTERNAL_ERROR-59;
2098 }
2099
2100 nb_verifs = ++session->internals.dtls.hsk_hello_verify_requests;
2101 if (nb_verifs >= MAX_HANDSHAKE_HELLO_VERIFY_REQUESTS5)
2102 {
2103 /* The server is either buggy, malicious or changing cookie
2104 secrets _way_ too fast. */
2105 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2105); } while(0
);
;
2106 return GNUTLS_E_UNEXPECTED_PACKET-15;
2107 }
2108
2109 /* TODO: determine if we need to do anything with the server version field */
2110 DECR_LEN (len, 2)do { len-=2; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,2110); } while(0);; return -9;} } while (0)
;
2111 pos += 2;
2112
2113 DECR_LEN (len, 1)do { len-=1; if (len<0) {do { if (__builtin_expect((_gnutls_log_level
>= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c"
,2113); } while(0);; return -9;} } while (0)
;
2114 cookie_len = data[pos];
2115 pos++;
2116
2117 if (cookie_len > DTLS_MAX_COOKIE_SIZE32)
2118 {
2119 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2119); } while(0
);
;
2120 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
2121 }
2122
2123 DECR_LEN (len, cookie_len)do { len-=cookie_len; if (len<0) {do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2123); } while(0);; return -9;} } while
(0)
;
2124
2125 session->internals.dtls.cookie_len = cookie_len;
2126 memcpy (session->internals.dtls.cookie, &data[pos], cookie_len);
2127
2128 pos += cookie_len;
2129
2130 if (len != 0)
2131 {
2132 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2132); } while(0
);
;
2133 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
2134 }
2135
2136 /* reset handshake hash buffers */
2137 _gnutls_handshake_hash_buffer_empty (session);
2138
2139 return 0;
2140}
2141
2142/* The packets in gnutls_handshake (it's more broad than original TLS handshake)
2143 *
2144 * Client Server
2145 *
2146 * ClientHello -------->
2147 * <-------- ServerHello
2148 *
2149 * Certificate*
2150 * ServerKeyExchange*
2151 * <-------- CertificateRequest*
2152 *
2153 * <-------- ServerHelloDone
2154 * Certificate*
2155 * ClientKeyExchange
2156 * CertificateVerify*
2157 * [ChangeCipherSpec]
2158 * Finished -------->
2159 * NewSessionTicket
2160 * [ChangeCipherSpec]
2161 * <-------- Finished
2162 *
2163 * (*): means optional packet.
2164 */
2165
2166/* Handshake when resumming session:
2167 * Client Server
2168 *
2169 * ClientHello -------->
2170 * ServerHello
2171 * [ChangeCipherSpec]
2172 * <-------- Finished
2173 * [ChangeCipherSpec]
2174 * Finished -------->
2175 *
2176 */
2177
2178/**
2179 * gnutls_rehandshake:
2180 * @session: is a #gnutls_session_t structure.
2181 *
2182 * This function will renegotiate security parameters with the
2183 * client. This should only be called in case of a server.
2184 *
2185 * This message informs the peer that we want to renegotiate
2186 * parameters (perform a handshake).
2187 *
2188 * If this function succeeds (returns 0), you must call the
2189 * gnutls_handshake() function in order to negotiate the new
2190 * parameters.
2191 *
2192 * Since TLS is full duplex some application data might have been
2193 * sent during peer's processing of this message. In that case
2194 * one should call gnutls_record_recv() until GNUTLS_E_REHANDSHAKE
2195 * is returned to clear any pending data. Care must be taken if
2196 * rehandshake is mandatory to terminate if it does not start after
2197 * some threshold.
2198 *
2199 * If the client does not wish to renegotiate parameters he will
2200 * should with an alert message, thus the return code will be
2201 * %GNUTLS_E_WARNING_ALERT_RECEIVED and the alert will be
2202 * %GNUTLS_A_NO_RENEGOTIATION. A client may also choose to ignore
2203 * this message.
2204 *
2205 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
2206 **/
2207int
2208gnutls_rehandshake (gnutls_session_t session)
2209{
2210 int ret;
2211
2212 /* only server sends that handshake packet */
2213 if (session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
2214 return GNUTLS_E_INVALID_REQUEST-50;
2215
2216 ret =
2217 _gnutls_send_empty_handshake (session, GNUTLS_HANDSHAKE_HELLO_REQUEST,
2218 AGAIN (STATE50)(session->internals.handshake_state==STATE50?1:0));
2219 STATEsession->internals.handshake_state = STATE50;
2220
2221 if (ret < 0)
2222 {
2223 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2223); } while(0
);
;
2224 return ret;
2225 }
2226 STATEsession->internals.handshake_state = STATE0;
2227
2228 return 0;
2229}
2230
2231inline static int
2232_gnutls_abort_handshake (gnutls_session_t session, int ret)
2233{
2234 if (((ret == GNUTLS_E_WARNING_ALERT_RECEIVED-16) &&
2235 (gnutls_alert_get (session) == GNUTLS_A_NO_RENEGOTIATION))
2236 || ret == GNUTLS_E_GOT_APPLICATION_DATA-38)
2237 return 0;
2238
2239 /* this doesn't matter */
2240 return GNUTLS_E_INTERNAL_ERROR-59;
2241}
2242
2243
2244
2245static int
2246_gnutls_send_supplemental (gnutls_session_t session, int again)
2247{
2248 mbuffer_st *bufel;
2249 int ret = 0;
2250
2251 _gnutls_debug_log ("EXT[%p]: Sending supplemental data\n", session)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "EXT[%p]: Sending supplemental data\n", session); } while
(0)
;
2252
2253 if (again)
2254 ret =
2255 _gnutls_send_handshake (session, NULL((void*)0), GNUTLS_HANDSHAKE_SUPPLEMENTAL);
2256 else
2257 {
2258 gnutls_buffer_st buf;
2259 _gnutls_buffer_init (&buf);
2260
2261 ret = _gnutls_gen_supplemental (session, &buf);
2262 if (ret < 0)
2263 {
2264 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2264); } while(0
);
;
2265 return ret;
2266 }
2267
2268 bufel = _gnutls_handshake_alloc(session, buf.length, buf.length);
2269 if (bufel == NULL((void*)0))
2270 {
2271 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2271); } while(0
);
;
2272 return GNUTLS_E_MEMORY_ERROR-25;
2273 }
2274
2275 _mbuffer_set_udata (bufel, buf.data, buf.length);
2276 _gnutls_buffer_clear (&buf);
2277
2278 ret = _gnutls_send_handshake (session, bufel,
2279 GNUTLS_HANDSHAKE_SUPPLEMENTAL);
2280 }
2281
2282 return ret;
2283}
2284
2285static int
2286_gnutls_recv_supplemental (gnutls_session_t session)
2287{
2288 gnutls_buffer_st buf;
2289 int ret;
2290
2291 _gnutls_debug_log ("EXT[%p]: Expecting supplemental data\n", session)do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "EXT[%p]: Expecting supplemental data\n", session); } while
(0)
;
2292
2293 ret = _gnutls_recv_handshake (session, GNUTLS_HANDSHAKE_SUPPLEMENTAL,
2294 OPTIONAL_PACKET, &buf);
2295 if (ret < 0)
2296 {
2297 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2297); } while(0
);
;
2298 return ret;
2299 }
2300
2301 ret = _gnutls_parse_supplemental (session, buf.data, buf.length);
2302 if (ret < 0)
2303 {
2304 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2304); } while(0
);
;
2305 goto cleanup;
2306 }
2307
2308cleanup:
2309 _gnutls_buffer_clear(&buf);
2310
2311 return ret;
2312}
2313
2314/**
2315 * gnutls_handshake:
2316 * @session: is a #gnutls_session_t structure.
2317 *
2318 * This function does the handshake of the TLS/SSL protocol, and
2319 * initializes the TLS connection.
2320 *
2321 * This function will fail if any problem is encountered, and will
2322 * return a negative error code. In case of a client, if the client
2323 * has asked to resume a session, but the server couldn't, then a
2324 * full handshake will be performed.
2325 *
2326 * The non-fatal errors such as %GNUTLS_E_AGAIN and
2327 * %GNUTLS_E_INTERRUPTED interrupt the handshake procedure, which
2328 * should be resumed later. Call this function again, until it
2329 * returns 0; cf. gnutls_record_get_direction() and
2330 * gnutls_error_is_fatal().
2331 *
2332 * If this function is called by a server after a rehandshake request
2333 * then %GNUTLS_E_GOT_APPLICATION_DATA or
2334 * %GNUTLS_E_WARNING_ALERT_RECEIVED may be returned. Note that these
2335 * are non fatal errors, only in the specific case of a rehandshake.
2336 * Their meaning is that the client rejected the rehandshake request or
2337 * in the case of %GNUTLS_E_GOT_APPLICATION_DATA it might also mean that
2338 * some data were pending.
2339 *
2340 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
2341 **/
2342int
2343gnutls_handshake (gnutls_session_t session)
2344{
2345 int ret;
2346 record_parameters_st *params;
2347
2348 /* sanity check. Verify that there are priorities setup.
2349 */
2350 if (session->internals.priorities.protocol.algorithms == 0)
2351 return gnutls_assert_val(GNUTLS_E_NO_PRIORITIES_WERE_SET)gnutls_assert_val_int(-326, "gnutls_handshake.c", 2351);
2352
2353 ret = _gnutls_epoch_get (session, session->security_parameters.epoch_next,
2354 &params);
2355 if (ret < 0)
2356 {
2357 /* We assume the epoch is not allocated if _gnutls_epoch_get fails. */
2358 ret =
2359 _gnutls_epoch_alloc (session, session->security_parameters.epoch_next,
2360 NULL((void*)0));
2361 if (ret < 0)
2362 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 2362);
2363 }
2364
2365 if (session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
2366 {
2367 do
2368 {
2369 ret = _gnutls_handshake_client (session);
2370 } while (ret == 1);
2371 }
2372 else
2373 {
2374 ret = _gnutls_handshake_server (session);
2375 }
2376 if (ret < 0)
2377 {
2378 /* In the case of a rehandshake abort
2379 * we should reset the handshake's internal state.
2380 */
2381 if (_gnutls_abort_handshake (session, ret) == 0)
2382 STATEsession->internals.handshake_state = STATE0;
2383
2384 return ret;
2385 }
2386
2387 ret = _gnutls_handshake_common (session);
2388
2389 if (ret < 0)
2390 {
2391 if (_gnutls_abort_handshake (session, ret) == 0)
2392 STATEsession->internals.handshake_state = STATE0;
2393
2394 return ret;
2395 }
2396
2397 STATEsession->internals.handshake_state = STATE0;
2398
2399 if (IS_DTLS(session)(session->internals.transport == GNUTLS_DGRAM)==0)
2400 {
2401 _gnutls_handshake_io_buffer_clear (session)_mbuffer_head_clear( &session->internals.handshake_send_buffer
); _gnutls_handshake_recv_buffer_clear( session);
;
2402 }
2403 else
2404 {
2405 _dtls_async_timer_init(session);
2406 }
2407
2408 _gnutls_handshake_internal_state_clear (session);
2409
2410 session->security_parameters.epoch_next++;
2411
2412 return 0;
2413}
2414
2415
2416#define IMED_RET( str, ret, allow_alert)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (allow_alert != 0 && ret==-16) return ret; do { if
(__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2416); } while(0
);; ; _gnutls_handshake_hash_buffers_clear(session); return ret
; } } while (0)
do { \
2417 if (ret < 0) { \
2418 /* EAGAIN and INTERRUPTED are always non-fatal */ \
2419 if (ret == GNUTLS_E_AGAIN-28 || ret == GNUTLS_E_INTERRUPTED-52) \
2420 return ret; \
2421 /* a warning alert might interrupt handshake */ \
2422 if (allow_alert != 0 && ret==GNUTLS_E_WARNING_ALERT_RECEIVED-16) return ret; \
2423 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2423); } while(0
);
; \
2424 ERR( str, ret); \
2425 _gnutls_handshake_hash_buffers_clear(session); \
2426 return ret; \
2427 } } while (0)
2428
2429
2430
2431/*
2432 * _gnutls_handshake_client
2433 * This function performs the client side of the handshake of the TLS/SSL protocol.
2434 */
2435int
2436_gnutls_handshake_client (gnutls_session_t session)
2437{
2438 int ret = 0;
2439
2440#ifdef HANDSHAKE_DEBUG
2441 char buf[64];
2442
2443 if (session->internals.resumed_security_parameters.session_id_size > 0)
2444 _gnutls_handshake_log ("HSK[%p]: Ask to resume: %s\n", session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Ask to resume: %s\n", session, _gnutls_bin2hex
(session-> internals.resumed_security_parameters.session_id
, session-> internals.resumed_security_parameters.session_id_size
, buf, sizeof (buf), ((void*)0))); } while(0)
2445 _gnutls_bin2hex (session->do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Ask to resume: %s\n", session, _gnutls_bin2hex
(session-> internals.resumed_security_parameters.session_id
, session-> internals.resumed_security_parameters.session_id_size
, buf, sizeof (buf), ((void*)0))); } while(0)
2446 internals.resumed_security_parameters.session_id,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Ask to resume: %s\n", session, _gnutls_bin2hex
(session-> internals.resumed_security_parameters.session_id
, session-> internals.resumed_security_parameters.session_id_size
, buf, sizeof (buf), ((void*)0))); } while(0)
2447 session->do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Ask to resume: %s\n", session, _gnutls_bin2hex
(session-> internals.resumed_security_parameters.session_id
, session-> internals.resumed_security_parameters.session_id_size
, buf, sizeof (buf), ((void*)0))); } while(0)
2448 internals.resumed_security_parameters.session_id_size,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Ask to resume: %s\n", session, _gnutls_bin2hex
(session-> internals.resumed_security_parameters.session_id
, session-> internals.resumed_security_parameters.session_id_size
, buf, sizeof (buf), ((void*)0))); } while(0)
2449 buf, sizeof (buf), NULL))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Ask to resume: %s\n", session, _gnutls_bin2hex
(session-> internals.resumed_security_parameters.session_id
, session-> internals.resumed_security_parameters.session_id_size
, buf, sizeof (buf), ((void*)0))); } while(0)
;
2450#endif
2451
2452 switch (STATEsession->internals.handshake_state)
2453 {
2454 case STATE0:
2455 case STATE1:
2456 ret = _gnutls_send_hello (session, AGAIN (STATE1)(session->internals.handshake_state==STATE1?1:0));
2457 STATEsession->internals.handshake_state = STATE1;
2458 IMED_RET ("send hello", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2458); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2459
2460 case STATE11:
2461 if (IS_DTLS (session)(session->internals.transport == GNUTLS_DGRAM))
2462 {
2463 ret =
2464 _gnutls_recv_handshake (session,
2465 GNUTLS_HANDSHAKE_HELLO_VERIFY_REQUEST,
2466 OPTIONAL_PACKET, NULL((void*)0));
2467 STATEsession->internals.handshake_state = STATE11;
2468 IMED_RET ("recv hello verify", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2468); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2469
2470 if (ret == 1)
2471 {
2472 STATEsession->internals.handshake_state = STATE0;
2473 return 1;
2474 }
2475 }
2476 case STATE2:
2477 /* receive the server hello */
2478 ret =
2479 _gnutls_recv_handshake (session,
2480 GNUTLS_HANDSHAKE_SERVER_HELLO,
2481 MANDATORY_PACKET, NULL((void*)0));
2482 STATEsession->internals.handshake_state = STATE2;
2483 IMED_RET ("recv hello", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2483); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2484
2485 case STATE70:
2486 if (session->security_parameters.do_recv_supplemental)
2487 {
2488 ret = _gnutls_recv_supplemental (session);
2489 STATEsession->internals.handshake_state = STATE70;
2490 IMED_RET ("recv supplemental", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2490); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2491 }
2492
2493 case STATE3:
2494 /* RECV CERTIFICATE */
2495 if (session->internals.resumed == RESUME_FALSE0) /* if we are not resuming */
2496 ret = _gnutls_recv_server_certificate (session);
2497 STATEsession->internals.handshake_state = STATE3;
2498 IMED_RET ("recv server certificate", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2498); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2499
2500 case STATE4:
2501 /* receive the server key exchange */
2502 if (session->internals.resumed == RESUME_FALSE0) /* if we are not resuming */
2503 ret = _gnutls_recv_server_kx_message (session);
2504 STATEsession->internals.handshake_state = STATE4;
2505 IMED_RET ("recv server kx message", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2505); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2506
2507 case STATE5:
2508 /* receive the server certificate request - if any
2509 */
2510
2511 if (session->internals.resumed == RESUME_FALSE0) /* if we are not resuming */
2512 ret = _gnutls_recv_server_certificate_request (session);
2513 STATEsession->internals.handshake_state = STATE5;
2514 IMED_RET ("recv server certificate request message", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2514); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2515
2516 case STATE6:
2517 /* receive the server hello done */
2518 if (session->internals.resumed == RESUME_FALSE0) /* if we are not resuming */
2519 ret =
2520 _gnutls_recv_handshake (session,
2521 GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
2522 MANDATORY_PACKET, NULL((void*)0));
2523 STATEsession->internals.handshake_state = STATE6;
2524 IMED_RET ("recv server hello done", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2524); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2525 case STATE71:
2526 if (session->security_parameters.do_send_supplemental)
2527 {
2528 ret = _gnutls_send_supplemental (session, AGAIN (STATE71)(session->internals.handshake_state==STATE71?1:0));
2529 STATEsession->internals.handshake_state = STATE71;
2530 IMED_RET ("send supplemental", ret, 0)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (0 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2530); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2531 }
2532
2533 case STATE7:
2534 /* send our certificate - if any and if requested
2535 */
2536 if (session->internals.resumed == RESUME_FALSE0) /* if we are not resuming */
2537 ret = _gnutls_send_client_certificate (session, AGAIN (STATE7)(session->internals.handshake_state==STATE7?1:0));
2538 STATEsession->internals.handshake_state = STATE7;
2539 IMED_RET ("send client certificate", ret, 0)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (0 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2539); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2540
2541 case STATE8:
2542 if (session->internals.resumed == RESUME_FALSE0) /* if we are not resuming */
2543 ret = _gnutls_send_client_kx_message (session, AGAIN (STATE8)(session->internals.handshake_state==STATE8?1:0));
2544 STATEsession->internals.handshake_state = STATE8;
2545 IMED_RET ("send client kx", ret, 0)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (0 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2545); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2546
2547 case STATE9:
2548 /* send client certificate verify */
2549 if (session->internals.resumed == RESUME_FALSE0) /* if we are not resuming */
2550 ret =
2551 _gnutls_send_client_certificate_verify (session, AGAIN (STATE9)(session->internals.handshake_state==STATE9?1:0));
2552 STATEsession->internals.handshake_state = STATE9;
2553 IMED_RET ("send client certificate verify", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2553); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2554
2555 STATEsession->internals.handshake_state = STATE0;
2556 default:
2557 break;
2558 }
2559
2560
2561 return 0;
2562}
2563
2564
2565
2566/* This function is to be called if the handshake was successfully
2567 * completed. This sends a Change Cipher Spec packet to the peer.
2568 */
2569static ssize_t
2570send_change_cipher_spec (gnutls_session_t session, int again)
2571{
2572 opaque* data;
2573 mbuffer_st * bufel;
2574 int ret;
2575
2576 if (again == 0)
2577 {
2578 bufel = _gnutls_handshake_alloc (session, 1, 1);
2579 if (bufel == NULL((void*)0))
2580 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR)gnutls_assert_val_int(-25, "gnutls_handshake.c", 2580);
2581
2582 _mbuffer_set_uhead_size(bufel, 1);
2583 _mbuffer_set_udata_size(bufel, 0);
2584
2585 data = _mbuffer_get_uhead_ptr (bufel);
2586
2587 data[0] = 1;
2588
2589 ret = _gnutls_handshake_io_cache_int (session, GNUTLS_HANDSHAKE_CHANGE_CIPHER_SPEC, bufel);
2590 if (ret < 0)
2591 {
2592 _mbuffer_xfree(&bufel);
2593 return gnutls_assert_val(ret)gnutls_assert_val_int(ret, "gnutls_handshake.c", 2593);
2594 }
2595
2596 _gnutls_handshake_log ("REC[%p]: Sent ChangeCipherSpec\n", session)do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "REC[%p]: Sent ChangeCipherSpec\n", session); } while(0)
;
2597 }
2598
2599 return 0;
2600}
2601
2602/* This function sends the final handshake packets and initializes connection
2603 */
2604static int
2605_gnutls_send_handshake_final (gnutls_session_t session, int init)
2606{
2607 int ret = 0;
2608
2609 /* Send the CHANGE CIPHER SPEC PACKET */
2610
2611 switch (STATEsession->internals.handshake_state)
2612 {
2613 case STATE0:
2614 case STATE20:
2615 ret = send_change_cipher_spec (session, AGAIN (STATE20)(session->internals.handshake_state==STATE20?1:0));
2616 STATEsession->internals.handshake_state = STATE0;
2617
2618 if (ret < 0)
2619 {
2620 ERR ("send ChangeCipherSpec", ret);
2621 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2621); } while(0
);
;
2622 return ret;
2623 }
2624 /* Initialize the connection session (start encryption) - in case of client
2625 */
2626 if (init == TRUE1)
2627 {
2628 ret = _gnutls_connection_state_init (session);
2629 if (ret < 0)
2630 {
2631 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2631); } while(0
);
;
2632 return ret;
2633 }
2634 }
2635
2636 ret = _gnutls_write_connection_state_init (session);
2637 if (ret < 0)
2638 {
2639 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2639); } while(0
);
;
2640 return ret;
2641 }
2642
2643 case STATE21:
2644 /* send the finished message */
2645 ret = _gnutls_send_finished (session, AGAIN (STATE21)(session->internals.handshake_state==STATE21?1:0));
2646 STATEsession->internals.handshake_state = STATE21;
2647 if (ret < 0)
2648 {
2649 ERR ("send Finished", ret);
2650 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2650); } while(0
);
;
2651 return ret;
2652 }
2653
2654 STATEsession->internals.handshake_state = STATE0;
2655 default:
2656 break;
2657 }
2658
2659 return 0;
2660}
2661
2662/* This function receives the final handshake packets
2663 * And executes the appropriate function to initialize the
2664 * read session.
2665 */
2666static int
2667_gnutls_recv_handshake_final (gnutls_session_t session, int init)
2668{
2669 int ret = 0;
2670 uint8_t ch;
2671
2672 switch (STATEsession->internals.handshake_state)
2673 {
2674 case STATE0:
2675 case STATE30:
2676 ret = _gnutls_recv_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, &ch, 1, NULL((void*)0));
2677 STATEsession->internals.handshake_state = STATE30;
2678 if (ret <= 0)
2679 {
2680 ERR ("recv ChangeCipherSpec", ret);
2681 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2681); } while(0
);
;
2682 return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
2683 }
2684
2685 /* Initialize the connection session (start encryption) - in case of server */
2686 if (init == TRUE1)
2687 {
2688 ret = _gnutls_connection_state_init (session);
2689 if (ret < 0)
2690 {
2691 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2691); } while(0
);
;
2692 return ret;
2693 }
2694 }
2695
2696 ret = _gnutls_read_connection_state_init (session);
2697 if (ret < 0)
2698 {
2699 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2699); } while(0
);
;
2700 return ret;
2701 }
2702
2703 case STATE31:
2704 ret = _gnutls_recv_finished (session);
2705 STATEsession->internals.handshake_state = STATE31;
2706 if (ret < 0)
2707 {
2708 ERR ("recv finished", ret);
2709 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2709); } while(0
);
;
2710 return ret;
2711 }
2712 STATEsession->internals.handshake_state = STATE0;
2713 default:
2714 break;
2715 }
2716
2717
2718 return 0;
2719}
2720
2721/*
2722 * _gnutls_handshake_server
2723 * This function does the server stuff of the handshake protocol.
2724 */
2725int
2726_gnutls_handshake_server (gnutls_session_t session)
2727{
2728 int ret = 0;
2729
2730 switch (STATEsession->internals.handshake_state)
2731 {
2732 case STATE0:
2733 case STATE1:
2734 ret =
2735 _gnutls_recv_handshake (session,
2736 GNUTLS_HANDSHAKE_CLIENT_HELLO,
2737 MANDATORY_PACKET, NULL((void*)0));
2738 STATEsession->internals.handshake_state = STATE1;
2739 IMED_RET ("recv hello", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2739); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2740
2741 case STATE2:
2742 ret = _gnutls_send_hello (session, AGAIN (STATE2)(session->internals.handshake_state==STATE2?1:0));
2743 STATEsession->internals.handshake_state = STATE2;
2744 IMED_RET ("send hello", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2744); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2745
2746 case STATE70:
2747 if (session->security_parameters.do_send_supplemental)
2748 {
2749 ret = _gnutls_send_supplemental (session, AGAIN (STATE70)(session->internals.handshake_state==STATE70?1:0));
2750 STATEsession->internals.handshake_state = STATE70;
2751 IMED_RET ("send supplemental data", ret, 0)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (0 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2751); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2752 }
2753
2754 /* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
2755 case STATE3:
2756 /* NOTE: these should not be send if we are resuming */
2757
2758 if (session->internals.resumed == RESUME_FALSE0)
2759 ret = _gnutls_send_server_certificate (session, AGAIN (STATE3)(session->internals.handshake_state==STATE3?1:0));
2760 STATEsession->internals.handshake_state = STATE3;
2761 IMED_RET ("send server certificate", ret, 0)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (0 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2761); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2762
2763 case STATE4:
2764 /* send server key exchange (A) */
2765 if (session->internals.resumed == RESUME_FALSE0)
2766 ret = _gnutls_send_server_kx_message (session, AGAIN (STATE4)(session->internals.handshake_state==STATE4?1:0));
2767 STATEsession->internals.handshake_state = STATE4;
2768 IMED_RET ("send server kx", ret, 0)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (0 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2768); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2769
2770 case STATE5:
2771 /* Send certificate request - if requested to */
2772 if (session->internals.resumed == RESUME_FALSE0)
2773 ret =
2774 _gnutls_send_server_certificate_request (session, AGAIN (STATE5)(session->internals.handshake_state==STATE5?1:0));
2775 STATEsession->internals.handshake_state = STATE5;
2776 IMED_RET ("send server cert request", ret, 0)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (0 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2776); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2777
2778 case STATE6:
2779 /* send the server hello done */
2780 if (session->internals.resumed == RESUME_FALSE0) /* if we are not resuming */
2781 ret =
2782 _gnutls_send_empty_handshake (session,
2783 GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
2784 AGAIN (STATE6)(session->internals.handshake_state==STATE6?1:0));
2785 STATEsession->internals.handshake_state = STATE6;
2786 IMED_RET ("send server hello done", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2786); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2787
2788 case STATE71:
2789 if (session->security_parameters.do_recv_supplemental)
2790 {
2791 ret = _gnutls_recv_supplemental (session);
2792 STATEsession->internals.handshake_state = STATE71;
2793 IMED_RET ("recv client supplemental", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2793); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2794 }
2795
2796 /* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_VERIFY */
2797 case STATE7:
2798 /* receive the client certificate message */
2799 if (session->internals.resumed == RESUME_FALSE0) /* if we are not resuming */
2800 ret = _gnutls_recv_client_certificate (session);
2801 STATEsession->internals.handshake_state = STATE7;
2802 IMED_RET ("recv client certificate", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2802); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2803
2804 case STATE8:
2805 /* receive the client key exchange message */
2806 if (session->internals.resumed == RESUME_FALSE0) /* if we are not resuming */
2807 ret = _gnutls_recv_client_kx_message (session);
2808 STATEsession->internals.handshake_state = STATE8;
2809 IMED_RET ("recv client kx", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2809); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2810
2811 case STATE9:
2812 /* receive the client certificate verify message */
2813 if (session->internals.resumed == RESUME_FALSE0) /* if we are not resuming */
2814 ret = _gnutls_recv_client_certificate_verify_message (session);
2815 STATEsession->internals.handshake_state = STATE9;
2816 IMED_RET ("recv client certificate verify", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2816); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2817
2818 STATEsession->internals.handshake_state = STATE0; /* finished thus clear session */
2819 default:
2820 break;
2821 }
2822
2823 return 0;
2824}
2825
2826int
2827_gnutls_handshake_common (gnutls_session_t session)
2828{
2829 int ret = 0;
2830
2831 /* send and recv the change cipher spec and finished messages */
2832 if ((session->internals.resumed != RESUME_FALSE0
2833 && session->security_parameters.entity == GNUTLS_CLIENT(1<<1))
2834 || (session->internals.resumed == RESUME_FALSE0
2835 && session->security_parameters.entity == GNUTLS_SERVER1))
2836 {
2837 /* if we are a client resuming - or we are a server not resuming */
2838 ret = _gnutls_recv_handshake_final (session, TRUE1);
2839 IMED_RET ("recv handshake final", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2839); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2840
2841 switch (STATEsession->internals.handshake_state)
2842 {
2843 case STATE0:
2844 case STATE40:
2845 ret = _gnutls_send_new_session_ticket (session, AGAIN (STATE40)(session->internals.handshake_state==STATE40?1:0));
2846 STATEsession->internals.handshake_state = STATE40;
2847 IMED_RET ("send handshake new session ticket", ret, 0)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (0 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2847); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2848 STATEsession->internals.handshake_state = STATE0;
2849 default:
2850 break;
2851 }
2852
2853 ret = _gnutls_send_handshake_final (session, FALSE0);
2854 IMED_RET ("send handshake final", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2854); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2855
2856 /* only store if we are not resuming a session and we didn't previously send a ticket
2857 */
2858 if (session->security_parameters.entity == GNUTLS_SERVER1 && session->internals.ticket_sent == 0)
2859 {
2860 /* in order to support session resuming */
2861 _gnutls_server_register_current_session (session);
2862 }
2863 }
2864 else
2865 { /* if we are a client not resuming - or we are a server resuming */
2866
2867 ret = _gnutls_send_handshake_final (session, TRUE1);
2868 IMED_RET ("send handshake final 2", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2868); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2869
2870 switch (STATEsession->internals.handshake_state)
2871 {
2872 case STATE0:
2873 case STATE41:
2874 ret = _gnutls_recv_new_session_ticket (session);
2875 STATEsession->internals.handshake_state = STATE41;
2876 IMED_RET ("recv handshake new session ticket", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2876); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2877 STATEsession->internals.handshake_state = STATE0;
2878 default:
2879 break;
2880 }
2881
2882 ret = _gnutls_recv_handshake_final (session, FALSE0);
2883 IMED_RET ("recv handshake final 2", ret, 1)do { if (ret < 0) { if (ret == -28 || ret == -52) return ret
; if (1 != 0 && ret==-16) return ret; do { if (__builtin_expect
((_gnutls_log_level >= 2), 0)) _gnutls_log( 2, "ASSERT: %s:%d\n"
, "gnutls_handshake.c",2883); } while(0);; ; _gnutls_handshake_hash_buffers_clear
(session); return ret; } } while (0)
;
2884
2885 }
2886
2887
2888 /* clear handshake buffer */
2889 _gnutls_handshake_hash_buffers_clear (session);
2890 return ret;
2891
2892}
2893
2894int
2895_gnutls_generate_session_id (opaque * session_id, uint8_t * len)
2896{
2897 int ret;
2898
2899 *len = TLS_MAX_SESSION_ID_SIZE32;
2900
2901 ret = _gnutls_rnd (GNUTLS_RND_NONCE, session_id, *len);
2902 if (ret < 0)
2903 {
2904 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2904); } while(0
);
;
2905 return ret;
2906 }
2907
2908 return 0;
2909}
2910
2911int
2912_gnutls_recv_hello_request (gnutls_session_t session, void *data,
2913 uint32_t data_size)
2914{
2915 uint8_t type;
2916
2917 if (session->security_parameters.entity == GNUTLS_SERVER1)
2918 {
2919 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2919); } while(0
);
;
2920 return GNUTLS_E_UNEXPECTED_PACKET-15;
2921 }
2922 if (data_size < 1)
2923 {
2924 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2924); } while(0
);
;
2925 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH-9;
2926 }
2927 type = ((uint8_t *) data)[0];
2928 if (type == GNUTLS_HANDSHAKE_HELLO_REQUEST)
2929 return GNUTLS_E_REHANDSHAKE-37;
2930 else
2931 {
2932 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",2932); } while(0
);
;
2933 return GNUTLS_E_UNEXPECTED_PACKET-15;
2934 }
2935}
2936
2937/* Returns 1 if the given KX has not the corresponding parameters
2938 * (DH or RSA) set up. Otherwise returns 0.
2939 */
2940inline static int
2941check_server_params (gnutls_session_t session,
2942 gnutls_kx_algorithm_t kx,
2943 gnutls_kx_algorithm_t * alg, int alg_size)
2944{
2945 int cred_type;
2946 gnutls_dh_params_t dh_params = NULL((void*)0);
2947 gnutls_rsa_params_t rsa_params = NULL((void*)0);
2948 int j;
2949
2950 cred_type = _gnutls_map_kx_get_cred (kx, 1);
2951
2952 /* Read the Diffie-Hellman parameters, if any.
2953 */
2954 if (cred_type == GNUTLS_CRD_CERTIFICATE)
2955 {
2956 int delete;
2957 gnutls_certificate_credentials_t x509_cred =
2958 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
2959 cred_type, NULL((void*)0));
2960
2961 if (x509_cred != NULL((void*)0))
2962 {
2963 dh_params =
2964 _gnutls_get_dh_params (x509_cred->dh_params,
2965 x509_cred->params_func, session);
2966 rsa_params =
2967 _gnutls_certificate_get_rsa_params (x509_cred->rsa_params,
2968 x509_cred->params_func,
2969 session);
2970 }
2971
2972 /* Check also if the certificate supports the
2973 * KX method.
2974 */
2975 delete = 1;
2976 for (j = 0; j < alg_size; j++)
2977 {
2978 if (alg[j] == kx)
2979 {
2980 delete = 0;
2981 break;
2982 }
2983 }
2984
2985 if (delete == 1)
2986 return 1;
2987
2988#ifdef ENABLE_ANON1
2989 }
2990 else if (cred_type == GNUTLS_CRD_ANON)
2991 {
2992 gnutls_anon_server_credentials_t anon_cred =
2993 (gnutls_anon_server_credentials_t) _gnutls_get_cred (session->key,
2994 cred_type, NULL((void*)0));
2995
2996 if (anon_cred != NULL((void*)0))
2997 {
2998 dh_params =
2999 _gnutls_get_dh_params (anon_cred->dh_params,
3000 anon_cred->params_func, session);
3001 }
3002#endif
3003#ifdef ENABLE_PSK1
3004 }
3005 else if (cred_type == GNUTLS_CRD_PSK)
3006 {
3007 gnutls_psk_server_credentials_t psk_cred =
3008 (gnutls_psk_server_credentials_t) _gnutls_get_cred (session->key,
3009 cred_type, NULL((void*)0));
3010
3011 if (psk_cred != NULL((void*)0))
3012 {
3013 dh_params =
3014 _gnutls_get_dh_params (psk_cred->dh_params, psk_cred->params_func,
3015 session);
3016 }
3017#endif
3018 }
3019 else
3020 return 0; /* no need for params */
3021
3022
3023 /* If the key exchange method needs RSA or DH params,
3024 * but they are not set then remove it.
3025 */
3026 if (_gnutls_kx_needs_rsa_params (kx) != 0)
3027 {
3028 /* needs rsa params. */
3029 if (_gnutls_rsa_params_to_mpi (rsa_params) == NULL((void*)0))
3030 {
3031 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",3031); } while(0
);
;
3032 return 1;
3033 }
3034 }
3035
3036 if (_gnutls_kx_needs_dh_params (kx) != 0)
3037 {
3038 /* needs DH params. */
3039 if (_gnutls_dh_params_to_mpi (dh_params) == NULL((void*)0))
3040 {
3041 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",3041); } while(0
);
;
3042 return 1;
3043 }
3044 }
3045
3046 return 0;
3047}
3048
3049/* This function will remove algorithms that are not supported by
3050 * the requested authentication method. We remove an algorithm if
3051 * we have a certificate with keyUsage bits set.
3052 *
3053 * This does a more high level check than gnutls_supported_ciphersuites(),
3054 * by checking certificates etc.
3055 */
3056static int
3057_gnutls_remove_unwanted_ciphersuites (gnutls_session_t session,
3058 uint8_t * cipher_suites,
3059 int cipher_suites_size,
3060 gnutls_pk_algorithm_t *pk_algos,
3061 size_t pk_algos_size)
3062{
3063
3064 int ret = 0;
3065 int i, new_suites_size;
3066 gnutls_certificate_credentials_t cert_cred;
3067 gnutls_kx_algorithm_t kx;
3068 int server = session->security_parameters.entity == GNUTLS_SERVER1 ? 1 : 0;
3069 gnutls_kx_algorithm_t alg[MAX_ALGOS32];
3070 int alg_size = MAX_ALGOS32;
3071
3072 /* if we should use a specific certificate,
3073 * we should remove all algorithms that are not supported
3074 * by that certificate and are on the same authentication
3075 * method (CERTIFICATE).
3076 */
3077
3078 cert_cred =
3079 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
3080 GNUTLS_CRD_CERTIFICATE,
3081 NULL((void*)0));
3082
3083 /* If there are certificate credentials, find an appropriate certificate
3084 * or disable them;
3085 */
3086 if (session->security_parameters.entity == GNUTLS_SERVER1
3087 && cert_cred != NULL((void*)0) && pk_algos_size > 0)
3088 {
3089 ret = _gnutls_server_select_cert (session, pk_algos, pk_algos_size);
3090 if (ret < 0)
3091 {
3092 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",3092); } while(0
);
;
3093 _gnutls_debug_log ("Could not find an appropriate certificate: %s\n",do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Could not find an appropriate certificate: %s\n", gnutls_strerror
(ret)); } while(0)
3094 gnutls_strerror (ret))do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "Could not find an appropriate certificate: %s\n", gnutls_strerror
(ret)); } while(0)
;
3095 }
3096 }
3097
3098 /* get all the key exchange algorithms that are
3099 * supported by the X509 certificate parameters.
3100 */
3101 if ((ret =
3102 _gnutls_selected_cert_supported_kx (session, alg, &alg_size)) < 0)
3103 {
3104 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "gnutls_handshake.c",3104); } while(0
);
;
3105 return ret;
3106 }
3107
3108 new_suites_size = 0;
3109
3110 /* now removes ciphersuites based on the KX algorithm
3111 */
3112 for (i = 0; i < cipher_suites_size; i+=2)
3113 {
3114 int delete = 0;
3115
3116 /* finds the key exchange algorithm in
3117 * the ciphersuite
3118 */
3119 kx = _gnutls_cipher_suite_get_kx_algo (&cipher_suites[i]);
3120
3121 /* if it is defined but had no credentials
3122 */
3123 if (_gnutls_get_kx_cred (session, kx, NULL((void*)0)) == NULL((void*)0))
3124 {
3125 delete = 1;
3126 }
3127 else
3128 {
3129 delete = 0;
3130
3131 if (server)
3132 delete = check_server_params (session, kx, alg, alg_size);
3133 }
3134
3135 /* If we have not agreed to a common curve with the peer don't bother
3136 * negotiating ECDH.
3137 */
3138 if (server != 0 && _gnutls_kx_is_ecc(kx))
3139 {
3140 if (_gnutls_session_ecc_curve_get(session) == GNUTLS_ECC_CURVE_INVALID)
3141 {
3142 delete = 1;
3143 }
3144 }
3145
3146 /* These two SRP kx's are marked to require a CRD_CERTIFICATE,
3147 (see cred_mappings in gnutls_algorithms.c), but it also
3148 requires a SRP credential. Don't use SRP kx unless we have a
3149 SRP credential too. */
3150 if (kx == GNUTLS_KX_SRP_RSA || kx == GNUTLS_KX_SRP_DSS)
3151 {
3152 if (!_gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL((void*)0)))
3153 {
3154 delete = 1;
3155 }
3156 }
3157
3158 if (delete == 0)
3159 {
3160
3161 _gnutls_handshake_log ("HSK[%p]: Keeping ciphersuite: %s\n",do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Keeping ciphersuite: %s\n", session, _gnutls_cipher_suite_get_name
(&cipher_suites[i])); } while(0)
3162 session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Keeping ciphersuite: %s\n", session, _gnutls_cipher_suite_get_name
(&cipher_suites[i])); } while(0)
3163 _gnutls_cipher_suite_get_name (&cipher_suites[i]))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Keeping ciphersuite: %s\n", session, _gnutls_cipher_suite_get_name
(&cipher_suites[i])); } while(0)
;
3164
3165 if (i != new_suites_size)
3166 memmove( &cipher_suites[new_suites_size], &cipher_suites[i], 2);
3167 new_suites_size+=2;
3168 }
3169 else
3170 {
3171 _gnutls_handshake_log ("HSK[%p]: Removing ciphersuite: %s\n",do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Removing ciphersuite: %s\n", session, _gnutls_cipher_suite_get_name
(&cipher_suites[i])); } while(0)
3172 session,do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Removing ciphersuite: %s\n", session, _gnutls_cipher_suite_get_name
(&cipher_suites[i])); } while(0)
3173 _gnutls_cipher_suite_get_name (&cipher_suites[i]))do { if (__builtin_expect((_gnutls_log_level >= 3), 0)) _gnutls_log
( 3, "HSK[%p]: Removing ciphersuite: %s\n", session, _gnutls_cipher_suite_get_name
(&cipher_suites[i])); } while(0)
;
3174
3175 }
3176 }
3177
3178 ret = new_suites_size;
3179
3180 return ret;
3181
3182}
3183
3184/**
3185 * gnutls_handshake_set_max_packet_length:
3186 * @session: is a #gnutls_session_t structure.
3187 * @max: is the maximum number.
3188 *
3189 * This function will set the maximum size of all handshake messages.
3190 * Handshakes over this size are rejected with
3191 * %GNUTLS_E_HANDSHAKE_TOO_LARGE error code. The default value is
3192 * 48kb which is typically large enough. Set this to 0 if you do not
3193 * want to set an upper limit.
3194 *
3195 * The reason for restricting the handshake message sizes are to
3196 * limit Denial of Service attacks.
3197 **/
3198void
3199gnutls_handshake_set_max_packet_length (gnutls_session_t session, size_t max)
3200{
3201 session->internals.max_handshake_data_buffer_size = max;
3202}
3203
3204void
3205_gnutls_set_adv_version (gnutls_session_t session, gnutls_protocol_t ver)
3206{
3207 set_adv_version (session, _gnutls_version_get_major (ver),session->internals.adv_version_major = _gnutls_version_get_major
(ver); session->internals.adv_version_minor = _gnutls_version_get_minor
(ver)
3208 _gnutls_version_get_minor (ver))session->internals.adv_version_major = _gnutls_version_get_major
(ver); session->internals.adv_version_minor = _gnutls_version_get_minor
(ver)
;
3209}
3210
3211gnutls_protocol_t
3212_gnutls_get_adv_version (gnutls_session_t session)
3213{
3214 return _gnutls_version_get (_gnutls_get_adv_version_major (session)session->internals.adv_version_major,
3215 _gnutls_get_adv_version_minor (session)session->internals.adv_version_minor);
3216}
3217
3218/**
3219 * gnutls_handshake_get_last_in:
3220 * @session: is a #gnutls_session_t structure.
3221 *
3222 * This function is only useful to check where the last performed
3223 * handshake failed. If the previous handshake succeed or was not
3224 * performed at all then no meaningful value will be returned.
3225 *
3226 * Check %gnutls_handshake_description_t in gnutls.h for the
3227 * available handshake descriptions.
3228 *
3229 * Returns: the last handshake message type received, a
3230 * %gnutls_handshake_description_t.
3231 **/
3232gnutls_handshake_description_t
3233gnutls_handshake_get_last_in (gnutls_session_t session)
3234{
3235 return session->internals.last_handshake_in;
3236}
3237
3238/**
3239 * gnutls_handshake_get_last_out:
3240 * @session: is a #gnutls_session_t structure.
3241 *
3242 * This function is only useful to check where the last performed
3243 * handshake failed. If the previous handshake succeed or was not
3244 * performed at all then no meaningful value will be returned.
3245 *
3246 * Check %gnutls_handshake_description_t in gnutls.h for the
3247 * available handshake descriptions.
3248 *
3249 * Returns: the last handshake message type sent, a
3250 * %gnutls_handshake_description_t.
3251 **/
3252gnutls_handshake_description_t
3253gnutls_handshake_get_last_out (gnutls_session_t session)
3254{
3255 return session->internals.last_handshake_out;
3256}