2 * Copyright (C) 2009, 2010 Free Software Foundation, Inc.
4 * Author: Steve Dispensa (<dispensa@phonefactor.com>)
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 #include <gnutls_int.h>
26 #include <ext_safe_renegotiation.h>
27 #include <gnutls_errors.h>
30 static int _gnutls_sr_recv_params (gnutls_session_t state,
31 const opaque * data, size_t data_size);
32 static int _gnutls_sr_send_params (gnutls_session_t state,
33 opaque * data, size_t);
34 static void _gnutls_sr_deinit_data (extension_priv_data_t priv);
36 extension_entry_st ext_mod_sr = {
37 .name = "SAFE RENEGOTIATION",
38 .type = GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
39 .parse_type = GNUTLS_EXT_MANDATORY,
41 .recv_func = _gnutls_sr_recv_params,
42 .send_func = _gnutls_sr_send_params,
45 .deinit_func = _gnutls_sr_deinit_data,
49 _gnutls_ext_sr_finished (gnutls_session_t session, void *vdata,
50 size_t vdata_size, int dir)
54 extension_priv_data_t epriv;
56 if (session->internals.priorities.sr == SR_DISABLED)
61 ret = _gnutls_ext_get_session_data (session,
62 GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
71 /* Save data for safe renegotiation.
73 if (vdata_size > MAX_VERIFY_DATA_SIZE)
76 return GNUTLS_E_INTERNAL_ERROR;
79 if ((session->security_parameters.entity == GNUTLS_CLIENT && dir == 0) ||
80 (session->security_parameters.entity == GNUTLS_SERVER && dir == 1))
82 priv->client_verify_data_len = vdata_size;
83 memcpy (priv->client_verify_data, vdata, vdata_size);
87 priv->server_verify_data_len = vdata_size;
88 memcpy (priv->server_verify_data, vdata, vdata_size);
95 _gnutls_ext_sr_verify (gnutls_session_t session)
98 sr_ext_st *priv = NULL;
99 extension_priv_data_t epriv;
101 if (session->internals.priorities.sr == SR_DISABLED)
107 ret = _gnutls_ext_get_session_data (session,
108 GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
113 /* Safe renegotiation */
115 if (priv && priv->safe_renegotiation_received)
117 if ((priv->ri_extension_data_len < priv->client_verify_data_len) ||
118 (memcmp (priv->ri_extension_data,
119 priv->client_verify_data, priv->client_verify_data_len)))
122 _gnutls_handshake_log ("HSK[%p]: Safe renegotiation failed [1]\n",
124 return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
127 if (session->security_parameters.entity == GNUTLS_CLIENT)
129 if ((priv->ri_extension_data_len !=
130 priv->client_verify_data_len + priv->server_verify_data_len) ||
131 memcmp (priv->ri_extension_data + priv->client_verify_data_len,
132 priv->server_verify_data,
133 priv->server_verify_data_len) != 0)
136 _gnutls_handshake_log
137 ("HSK[%p]: Safe renegotiation failed [2]\n", session);
138 return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
141 else /* Make sure there are 0 extra bytes */
143 if (priv->ri_extension_data_len != priv->client_verify_data_len)
146 _gnutls_handshake_log
147 ("HSK[%p]: Safe renegotiation failed [3]\n", session);
148 return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
152 _gnutls_handshake_log ("HSK[%p]: Safe renegotiation succeeded\n",
155 else /* safe renegotiation not received... */
157 if (priv && priv->connection_using_safe_renegotiation)
160 _gnutls_handshake_log
161 ("HSK[%p]: Peer previously asked for safe renegotiation\n",
163 return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
166 /* Clients can't tell if it's an initial negotiation */
167 if (session->internals.initial_negotiation_completed)
169 if (session->internals.priorities.sr < SR_PARTIAL)
171 _gnutls_handshake_log
172 ("HSK[%p]: Allowing unsafe (re)negotiation\n", session);
177 _gnutls_handshake_log
178 ("HSK[%p]: Denying unsafe (re)negotiation\n", session);
179 return GNUTLS_E_UNSAFE_RENEGOTIATION_DENIED;
184 if (session->internals.priorities.sr < SR_SAFE)
186 _gnutls_handshake_log
187 ("HSK[%p]: Allowing unsafe initial negotiation\n", session);
192 _gnutls_handshake_log
193 ("HSK[%p]: Denying unsafe initial negotiation\n", session);
194 return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
202 /* if a server received the special ciphersuite.
205 _gnutls_ext_sr_recv_cs (gnutls_session_t session)
209 extension_priv_data_t epriv;
211 ret = _gnutls_ext_get_session_data (session,
212 GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
226 priv = gnutls_calloc (1, sizeof (*priv));
230 return GNUTLS_E_MEMORY_ERROR;
237 priv->safe_renegotiation_received = 1;
238 priv->connection_using_safe_renegotiation = 1;
241 _gnutls_ext_set_session_data (session,
242 GNUTLS_EXTENSION_SAFE_RENEGOTIATION, epriv);
248 _gnutls_ext_sr_send_cs (gnutls_session_t session)
252 extension_priv_data_t epriv;
254 ret = _gnutls_ext_get_session_data (session,
255 GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
269 priv = gnutls_calloc (1, sizeof (*priv));
273 return GNUTLS_E_MEMORY_ERROR;
281 _gnutls_ext_set_session_data (session,
282 GNUTLS_EXTENSION_SAFE_RENEGOTIATION, epriv);
288 _gnutls_sr_recv_params (gnutls_session_t session,
289 const opaque * data, size_t _data_size)
292 ssize_t data_size = _data_size;
294 extension_priv_data_t epriv;
297 DECR_LEN (data_size, len + 1 /* count the first byte and payload */ );
299 if (session->internals.priorities.sr == SR_DISABLED)
305 ret = _gnutls_ext_get_session_data (session,
306 GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
308 if (ret < 0 && session->security_parameters.entity == GNUTLS_SERVER)
320 priv = gnutls_calloc (1, sizeof (*priv));
324 return GNUTLS_E_MEMORY_ERROR;
331 /* It is not legal to receive this extension on a renegotiation and
332 * not receive it on the initial negotiation.
334 if (session->internals.initial_negotiation_completed != 0 &&
335 priv->connection_using_safe_renegotiation == 0)
338 return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
341 if (len > sizeof (priv->ri_extension_data))
344 return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
348 memcpy (priv->ri_extension_data, &data[1], len);
349 priv->ri_extension_data_len = len;
351 /* "safe renegotiation received" means on *this* handshake; "connection using
352 * safe renegotiation" means that the initial hello received on the connection
353 * indicated safe renegotiation.
355 priv->safe_renegotiation_received = 1;
356 priv->connection_using_safe_renegotiation = 1;
359 _gnutls_ext_set_session_data (session,
360 GNUTLS_EXTENSION_SAFE_RENEGOTIATION, epriv);
365 _gnutls_sr_send_params (gnutls_session_t session,
366 opaque * data, size_t _data_size)
368 /* The format of this extension is a one-byte length of verify data followed
369 * by the verify data itself. Note that the length byte does not include
370 * itself; IOW, empty verify data is represented as a length of 0. That means
371 * the minimum extension is one byte: 0x00.
373 ssize_t data_size = _data_size;
376 extension_priv_data_t epriv;
378 if (session->internals.priorities.sr == SR_DISABLED)
384 ret = _gnutls_ext_get_session_data (session,
385 GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
394 priv = gnutls_calloc (1, sizeof (*priv));
398 return GNUTLS_E_MEMORY_ERROR;
402 _gnutls_ext_set_session_data (session,
403 GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
411 /* Always offer the extension if we're a client */
412 if (priv->connection_using_safe_renegotiation ||
413 session->security_parameters.entity == GNUTLS_CLIENT)
415 DECR_LEN (data_size, 1);
416 data[0] = priv->client_verify_data_len;
418 DECR_LEN (data_size, priv->client_verify_data_len);
420 if (priv->client_verify_data_len > 0)
421 memcpy (&data[1], priv->client_verify_data,
422 priv->client_verify_data_len);
424 if (session->security_parameters.entity == GNUTLS_SERVER)
426 data[0] += priv->server_verify_data_len;
428 DECR_LEN (data_size, priv->server_verify_data_len);
430 if (priv->server_verify_data_len > 0)
431 memcpy (&data[1 + priv->client_verify_data_len],
432 priv->server_verify_data, priv->server_verify_data_len);
438 return 1 + data[0]; /* don't forget the length byte */
442 _gnutls_sr_deinit_data (extension_priv_data_t priv)
444 gnutls_free (priv.ptr);
448 * gnutls_safe_renegotiation_status:
449 * @session: is a #gnutls_session_t structure.
451 * Can be used to check whether safe renegotiation is being used
452 * in the current session.
454 * Returns: 0 when safe renegotiation is not used and non zero when
455 * safe renegotiation is used.
460 gnutls_safe_renegotiation_status (gnutls_session_t session)
464 extension_priv_data_t epriv;
466 ret = _gnutls_ext_get_session_data (session,
467 GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
476 return priv->connection_using_safe_renegotiation;