~ubuntu-branches/ubuntu/trusty/gnutls26/trusty

« back to all changes in this revision

Viewing changes to lib/ext_safe_renegotiation.c

  • Committer: Package Import Robot
  • Author(s): Andreas Metzler
  • Date: 2011-10-01 15:28:13 UTC
  • mfrom: (12.1.20 sid)
  • Revision ID: package-import@ubuntu.com-20111001152813-yygm1c4cxonfxhzy
* New upstream version.
  + Allow CA importing of 0 certificates to succeed. Closes: #640639
* Add libp11-kit-dev to libgnutls-dev dependencies. (see #643811)
* [20_guiledocstring.diff] guile: Fix docstring extraction with CPP 4.5+.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include <ext_safe_renegotiation.h>
27
27
#include <gnutls_errors.h>
28
28
 
29
 
int
30
 
_gnutls_safe_renegotiation_recv_params (gnutls_session_t session,
31
 
                                        const opaque * data,
32
 
                                        size_t _data_size)
33
 
{
34
 
  tls_ext_st *ext = &session->security_parameters.extensions;
 
29
 
 
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);
 
35
 
 
36
extension_entry_st ext_mod_sr = {
 
37
  .name = "SAFE RENEGOTIATION",
 
38
  .type = GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
 
39
  .parse_type = GNUTLS_EXT_MANDATORY,
 
40
 
 
41
  .recv_func = _gnutls_sr_recv_params,
 
42
  .send_func = _gnutls_sr_send_params,
 
43
  .pack_func = NULL,
 
44
  .unpack_func = NULL,
 
45
  .deinit_func = _gnutls_sr_deinit_data,
 
46
};
 
47
 
 
48
int
 
49
_gnutls_ext_sr_finished (gnutls_session_t session, void *vdata,
 
50
                         size_t vdata_size, int dir)
 
51
{
 
52
  int ret;
 
53
  sr_ext_st *priv;
 
54
  extension_priv_data_t epriv;
 
55
 
 
56
  if (session->internals.priorities.sr == SR_DISABLED)
 
57
    {
 
58
      return 0;
 
59
    }
 
60
 
 
61
  ret = _gnutls_ext_get_session_data (session,
 
62
                                      GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
 
63
                                      &epriv);
 
64
  if (ret < 0)
 
65
    {
 
66
      gnutls_assert ();
 
67
      return ret;
 
68
    }
 
69
  priv = epriv.ptr;
 
70
 
 
71
  /* Save data for safe renegotiation. 
 
72
   */
 
73
  if (vdata_size > MAX_VERIFY_DATA_SIZE)
 
74
    {
 
75
      gnutls_assert ();
 
76
      return GNUTLS_E_INTERNAL_ERROR;
 
77
    }
 
78
 
 
79
  if ((session->security_parameters.entity == GNUTLS_CLIENT && dir == 0) ||
 
80
      (session->security_parameters.entity == GNUTLS_SERVER && dir == 1))
 
81
    {
 
82
      priv->client_verify_data_len = vdata_size;
 
83
      memcpy (priv->client_verify_data, vdata, vdata_size);
 
84
    }
 
85
  else
 
86
    {
 
87
      priv->server_verify_data_len = vdata_size;
 
88
      memcpy (priv->server_verify_data, vdata, vdata_size);
 
89
    }
 
90
 
 
91
  return 0;
 
92
}
 
93
 
 
94
int
 
95
_gnutls_ext_sr_verify (gnutls_session_t session)
 
96
{
 
97
  int ret;
 
98
  sr_ext_st *priv = NULL;
 
99
  extension_priv_data_t epriv;
 
100
 
 
101
  if (session->internals.priorities.sr == SR_DISABLED)
 
102
    {
 
103
      gnutls_assert ();
 
104
      return 0;
 
105
    }
 
106
 
 
107
  ret = _gnutls_ext_get_session_data (session,
 
108
                                      GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
 
109
                                      &epriv);
 
110
  if (ret >= 0)
 
111
    priv = epriv.ptr;
 
112
 
 
113
  /* Safe renegotiation */
 
114
 
 
115
  if (priv && priv->safe_renegotiation_received)
 
116
    {
 
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)))
 
120
        {
 
121
          gnutls_assert ();
 
122
          _gnutls_handshake_log ("HSK[%p]: Safe renegotiation failed [1]\n",
 
123
                                 session);
 
124
          return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
 
125
        }
 
126
 
 
127
      if (session->security_parameters.entity == GNUTLS_CLIENT)
 
128
        {
 
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)
 
134
            {
 
135
              gnutls_assert ();
 
136
              _gnutls_handshake_log
 
137
                ("HSK[%p]: Safe renegotiation failed [2]\n", session);
 
138
              return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
 
139
            }
 
140
        }
 
141
      else                      /* Make sure there are 0 extra bytes */
 
142
        {
 
143
          if (priv->ri_extension_data_len != priv->client_verify_data_len)
 
144
            {
 
145
              gnutls_assert ();
 
146
              _gnutls_handshake_log
 
147
                ("HSK[%p]: Safe renegotiation failed [3]\n", session);
 
148
              return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
 
149
            }
 
150
        }
 
151
 
 
152
      _gnutls_handshake_log ("HSK[%p]: Safe renegotiation succeeded\n",
 
153
                             session);
 
154
    }
 
155
  else                          /* safe renegotiation not received... */
 
156
    {
 
157
      if (priv && priv->connection_using_safe_renegotiation)
 
158
        {
 
159
          gnutls_assert ();
 
160
          _gnutls_handshake_log
 
161
            ("HSK[%p]: Peer previously asked for safe renegotiation\n",
 
162
             session);
 
163
          return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
 
164
        }
 
165
 
 
166
      /* Clients can't tell if it's an initial negotiation */
 
167
      if (session->internals.initial_negotiation_completed)
 
168
        {
 
169
          if (session->internals.priorities.sr < SR_PARTIAL)
 
170
            {
 
171
              _gnutls_handshake_log
 
172
                ("HSK[%p]: Allowing unsafe (re)negotiation\n", session);
 
173
            }
 
174
          else
 
175
            {
 
176
              gnutls_assert ();
 
177
              _gnutls_handshake_log
 
178
                ("HSK[%p]: Denying unsafe (re)negotiation\n", session);
 
179
              return GNUTLS_E_UNSAFE_RENEGOTIATION_DENIED;
 
180
            }
 
181
        }
 
182
      else
 
183
        {
 
184
          if (session->internals.priorities.sr < SR_SAFE)
 
185
            {
 
186
              _gnutls_handshake_log
 
187
                ("HSK[%p]: Allowing unsafe initial negotiation\n", session);
 
188
            }
 
189
          else
 
190
            {
 
191
              gnutls_assert ();
 
192
              _gnutls_handshake_log
 
193
                ("HSK[%p]: Denying unsafe initial negotiation\n", session);
 
194
              return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
 
195
            }
 
196
        }
 
197
    }
 
198
 
 
199
  return 0;
 
200
}
 
201
 
 
202
/* if a server received the special ciphersuite.
 
203
 */
 
204
int
 
205
_gnutls_ext_sr_recv_cs (gnutls_session_t session)
 
206
{
 
207
  int ret, set = 0;
 
208
  sr_ext_st *priv;
 
209
  extension_priv_data_t epriv;
 
210
 
 
211
  ret = _gnutls_ext_get_session_data (session,
 
212
                                      GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
 
213
                                      &epriv);
 
214
  if (ret < 0)
 
215
    {
 
216
      set = 1;
 
217
    }
 
218
  else if (ret < 0)
 
219
    {
 
220
      gnutls_assert ();
 
221
      return ret;
 
222
    }
 
223
 
 
224
  if (set != 0)
 
225
    {
 
226
      priv = gnutls_calloc (1, sizeof (*priv));
 
227
      if (priv == NULL)
 
228
        {
 
229
          gnutls_assert ();
 
230
          return GNUTLS_E_MEMORY_ERROR;
 
231
        }
 
232
      epriv.ptr = priv;
 
233
    }
 
234
  else
 
235
    priv = epriv.ptr;
 
236
 
 
237
  priv->safe_renegotiation_received = 1;
 
238
  priv->connection_using_safe_renegotiation = 1;
 
239
 
 
240
  if (set != 0)
 
241
    _gnutls_ext_set_session_data (session,
 
242
                                  GNUTLS_EXTENSION_SAFE_RENEGOTIATION, epriv);
 
243
 
 
244
  return 0;
 
245
}
 
246
 
 
247
int
 
248
_gnutls_ext_sr_send_cs (gnutls_session_t session)
 
249
{
 
250
  int ret, set = 0;
 
251
  sr_ext_st *priv;
 
252
  extension_priv_data_t epriv;
 
253
 
 
254
  ret = _gnutls_ext_get_session_data (session,
 
255
                                      GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
 
256
                                      &epriv);
 
257
  if (ret < 0)
 
258
    {
 
259
      set = 1;
 
260
    }
 
261
  else if (ret < 0)
 
262
    {
 
263
      gnutls_assert ();
 
264
      return ret;
 
265
    }
 
266
 
 
267
  if (set != 0)
 
268
    {
 
269
      priv = gnutls_calloc (1, sizeof (*priv));
 
270
      if (priv == NULL)
 
271
        {
 
272
          gnutls_assert ();
 
273
          return GNUTLS_E_MEMORY_ERROR;
 
274
        }
 
275
      epriv.ptr = priv;
 
276
    }
 
277
  else
 
278
    priv = epriv.ptr;
 
279
 
 
280
  if (set != 0)
 
281
    _gnutls_ext_set_session_data (session,
 
282
                                  GNUTLS_EXTENSION_SAFE_RENEGOTIATION, epriv);
 
283
 
 
284
  return 0;
 
285
}
 
286
 
 
287
static int
 
288
_gnutls_sr_recv_params (gnutls_session_t session,
 
289
                        const opaque * data, size_t _data_size)
 
290
{
35
291
  int len = data[0];
36
292
  ssize_t data_size = _data_size;
 
293
  sr_ext_st *priv;
 
294
  extension_priv_data_t epriv;
 
295
  int set = 0, ret;
37
296
 
38
297
  DECR_LEN (data_size, len + 1 /* count the first byte and payload */ );
39
298
 
40
 
  if (session->internals.priorities.safe_renegotiation == SR_DISABLED)
 
299
  if (session->internals.priorities.sr == SR_DISABLED)
41
300
    {
42
301
      gnutls_assert ();
43
302
      return 0;
44
303
    }
45
304
 
 
305
  ret = _gnutls_ext_get_session_data (session,
 
306
                                      GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
 
307
                                      &epriv);
 
308
  if (ret < 0 && session->security_parameters.entity == GNUTLS_SERVER)
 
309
    {
 
310
      set = 1;
 
311
    }
 
312
  else if (ret < 0)
 
313
    {
 
314
      gnutls_assert ();
 
315
      return ret;
 
316
    }
 
317
 
 
318
  if (set != 0)
 
319
    {
 
320
      priv = gnutls_calloc (1, sizeof (*priv));
 
321
      if (priv == NULL)
 
322
        {
 
323
          gnutls_assert ();
 
324
          return GNUTLS_E_MEMORY_ERROR;
 
325
        }
 
326
      epriv.ptr = priv;
 
327
    }
 
328
  else
 
329
    priv = epriv.ptr;
 
330
 
46
331
  /* It is not legal to receive this extension on a renegotiation and
47
332
   * not receive it on the initial negotiation.
48
333
   */
49
334
  if (session->internals.initial_negotiation_completed != 0 &&
50
 
      session->internals.connection_using_safe_renegotiation == 0)
 
335
      priv->connection_using_safe_renegotiation == 0)
51
336
    {
52
337
      gnutls_assert ();
53
338
      return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
54
339
    }
55
340
 
56
 
  if (len > sizeof (ext->ri_extension_data))
 
341
  if (len > sizeof (priv->ri_extension_data))
57
342
    {
58
343
      gnutls_assert ();
59
344
      return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
60
345
    }
61
346
 
62
347
  if (len > 0)
63
 
    memcpy (ext->ri_extension_data, &data[1], len);
64
 
  ext->ri_extension_data_len = len;
 
348
    memcpy (priv->ri_extension_data, &data[1], len);
 
349
  priv->ri_extension_data_len = len;
65
350
 
66
351
  /* "safe renegotiation received" means on *this* handshake; "connection using
67
352
   * safe renegotiation" means that the initial hello received on the connection
68
353
   * indicated safe renegotiation.
69
354
   */
70
 
  session->internals.safe_renegotiation_received = 1;
71
 
  session->internals.connection_using_safe_renegotiation = 1;
 
355
  priv->safe_renegotiation_received = 1;
 
356
  priv->connection_using_safe_renegotiation = 1;
72
357
 
 
358
  if (set != 0)
 
359
    _gnutls_ext_set_session_data (session,
 
360
                                  GNUTLS_EXTENSION_SAFE_RENEGOTIATION, epriv);
73
361
  return 0;
74
362
}
75
363
 
76
 
int
77
 
_gnutls_safe_renegotiation_send_params (gnutls_session_t session,
78
 
                                        opaque * data, size_t _data_size)
 
364
static int
 
365
_gnutls_sr_send_params (gnutls_session_t session,
 
366
                        opaque * data, size_t _data_size)
79
367
{
80
368
  /* The format of this extension is a one-byte length of verify data followed
81
369
   * by the verify data itself. Note that the length byte does not include
83
371
   * the minimum extension is one byte: 0x00.
84
372
   */
85
373
  ssize_t data_size = _data_size;
86
 
  tls_ext_st *ext = &session->security_parameters.extensions;
 
374
  sr_ext_st *priv;
 
375
  int ret, set = 0;
 
376
  extension_priv_data_t epriv;
87
377
 
88
 
  if (session->internals.priorities.safe_renegotiation == SR_DISABLED)
 
378
  if (session->internals.priorities.sr == SR_DISABLED)
89
379
    {
90
380
      gnutls_assert ();
91
381
      return 0;
92
382
    }
93
383
 
 
384
  ret = _gnutls_ext_get_session_data (session,
 
385
                                      GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
 
386
                                      &epriv);
 
387
  if (ret < 0)
 
388
    {
 
389
      set = 1;
 
390
    }
 
391
 
 
392
  if (set != 0)
 
393
    {
 
394
      priv = gnutls_calloc (1, sizeof (*priv));
 
395
      if (priv == NULL)
 
396
        {
 
397
          gnutls_assert ();
 
398
          return GNUTLS_E_MEMORY_ERROR;
 
399
        }
 
400
      epriv.ptr = priv;
 
401
 
 
402
      _gnutls_ext_set_session_data (session,
 
403
                                    GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
 
404
                                    epriv);
 
405
    }
 
406
  else
 
407
    priv = epriv.ptr;
 
408
 
94
409
  data[0] = 0;
95
410
 
96
411
  /* Always offer the extension if we're a client */
97
 
  if (session->internals.connection_using_safe_renegotiation ||
 
412
  if (priv->connection_using_safe_renegotiation ||
98
413
      session->security_parameters.entity == GNUTLS_CLIENT)
99
414
    {
100
415
      DECR_LEN (data_size, 1);
101
 
      data[0] = ext->client_verify_data_len;
102
 
 
103
 
      DECR_LEN (data_size, ext->client_verify_data_len);
104
 
 
105
 
      if (ext->client_verify_data_len > 0)
106
 
        memcpy (&data[1], ext->client_verify_data,
107
 
                ext->client_verify_data_len);
 
416
      data[0] = priv->client_verify_data_len;
 
417
 
 
418
      DECR_LEN (data_size, priv->client_verify_data_len);
 
419
 
 
420
      if (priv->client_verify_data_len > 0)
 
421
        memcpy (&data[1], priv->client_verify_data,
 
422
                priv->client_verify_data_len);
108
423
 
109
424
      if (session->security_parameters.entity == GNUTLS_SERVER)
110
 
        {
111
 
          data[0] += ext->server_verify_data_len;
112
 
 
113
 
          DECR_LEN (data_size, ext->server_verify_data_len);
114
 
 
115
 
          if (ext->server_verify_data_len > 0)
116
 
            memcpy (&data[1 + ext->client_verify_data_len],
117
 
                    ext->server_verify_data, ext->server_verify_data_len);
118
 
        }
 
425
        {
 
426
          data[0] += priv->server_verify_data_len;
 
427
 
 
428
          DECR_LEN (data_size, priv->server_verify_data_len);
 
429
 
 
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);
 
433
        }
119
434
    }
120
435
  else
121
436
    return 0;
122
437
 
123
 
  return 1 + data[0];           /* don't forget the length byte */
 
438
  return 1 + data[0];           /* don't forget the length byte */
 
439
}
 
440
 
 
441
static void
 
442
_gnutls_sr_deinit_data (extension_priv_data_t priv)
 
443
{
 
444
  gnutls_free (priv.ptr);
124
445
}
125
446
 
126
447
/**
138
459
int
139
460
gnutls_safe_renegotiation_status (gnutls_session_t session)
140
461
{
141
 
  return session->internals.connection_using_safe_renegotiation;
 
462
  int ret;
 
463
  sr_ext_st *priv;
 
464
  extension_priv_data_t epriv;
 
465
 
 
466
  ret = _gnutls_ext_get_session_data (session,
 
467
                                      GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
 
468
                                      &epriv);
 
469
  if (ret < 0)
 
470
    {
 
471
      gnutls_assert ();
 
472
      return 0;
 
473
    }
 
474
  priv = epriv.ptr;
 
475
 
 
476
  return priv->connection_using_safe_renegotiation;
142
477
}