~ubuntu-branches/ubuntu/precise/gnutls26/precise-security

« back to all changes in this revision

Viewing changes to .pc/26_ignore_key_usage_violation.patch/lib/gnutls_sig.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-02-24 14:01:03 UTC
  • mfrom: (35.1.3 precise-proposed)
  • Revision ID: package-import@ubuntu.com-20140224140103-tvbk7sovhd36a1fj
Tags: 2.12.14-5ubuntu3.6
* SECURITY UPDATE: incorrect v1 intermediate cert handling
  - debian/patches/CVE-2014-1959.patch: don't consider a v1 intermediate
    cert to be a valid CA by default in lib/x509/verify.c.
  - CVE-2014-1959

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2001, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
 
3
 * Software Foundation, Inc.
 
4
 *
 
5
 * Author: Nikos Mavrogiannopoulos
 
6
 *
 
7
 * This file is part of GnuTLS.
 
8
 *
 
9
 * The GnuTLS is free software; you can redistribute it and/or
 
10
 * modify it under the terms of the GNU Lesser General Public License
 
11
 * as published by the Free Software Foundation; either version 2.1 of
 
12
 * the License, or (at your option) any later version.
 
13
 *
 
14
 * This library is distributed in the hope that it will be useful, but
 
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
17
 * Lesser General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU Lesser General Public
 
20
 * License along with this library; if not, write to the Free Software
 
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 
22
 * USA
 
23
 *
 
24
 */
 
25
 
 
26
#include <gnutls_int.h>
 
27
#include <gnutls_errors.h>
 
28
#include <x509_b64.h>
 
29
#include <auth_cert.h>
 
30
#include <gnutls_algorithms.h>
 
31
#include <gnutls_cert.h>
 
32
#include <gnutls_datum.h>
 
33
#include <gnutls_mpi.h>
 
34
#include <gnutls_global.h>
 
35
#include <gnutls_pk.h>
 
36
#include <debug.h>
 
37
#include <gnutls_buffers.h>
 
38
#include <gnutls_sig.h>
 
39
#include <gnutls_kx.h>
 
40
#include <libtasn1.h>
 
41
#include <ext_signature.h>
 
42
#include <gnutls_state.h>
 
43
#include <x509/common.h>
 
44
 
 
45
static int
 
46
sign_tls_hash (gnutls_session_t session, gnutls_digest_algorithm_t hash_algo,
 
47
                  gnutls_cert * cert, gnutls_privkey_t pkey,
 
48
                  const gnutls_datum_t * hash_concat,
 
49
                  gnutls_datum_t * signature);
 
50
 
 
51
/* While this is currently equal to the length of RSA/SHA512
 
52
 * signature, it should also be sufficient for DSS signature and any
 
53
 * other RSA signatures including one with the old MD5/SHA1-combined
 
54
 * format.
 
55
 */
 
56
#define MAX_SIG_SIZE 19 + MAX_HASH_SIZE
 
57
 
 
58
/* Generates a signature of all the random data and the parameters.
 
59
 * Used in DHE_* ciphersuites.
 
60
 */
 
61
int
 
62
_gnutls_handshake_sign_data (gnutls_session_t session, gnutls_cert * cert,
 
63
                             gnutls_privkey_t pkey, gnutls_datum_t * params,
 
64
                             gnutls_datum_t * signature,
 
65
                             gnutls_sign_algorithm_t * sign_algo)
 
66
{
 
67
  gnutls_datum_t dconcat;
 
68
  int ret;
 
69
  digest_hd_st td_sha;
 
70
  opaque concat[MAX_SIG_SIZE];
 
71
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
72
  gnutls_digest_algorithm_t hash_algo;
 
73
 
 
74
  *sign_algo =
 
75
    _gnutls_session_get_sign_algo (session, cert);
 
76
  if (*sign_algo == GNUTLS_SIGN_UNKNOWN)
 
77
    {
 
78
      gnutls_assert ();
 
79
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
 
80
    }
 
81
 
 
82
  hash_algo = _gnutls_sign_get_hash_algorithm (*sign_algo);
 
83
 
 
84
  _gnutls_handshake_log ("HSK[%p]: signing handshake data: using %s\n",
 
85
                    session, gnutls_sign_algorithm_get_name (*sign_algo));
 
86
 
 
87
  ret = _gnutls_hash_init (&td_sha, hash_algo);
 
88
  if (ret < 0)
 
89
    {
 
90
      gnutls_assert ();
 
91
      return ret;
 
92
    }
 
93
 
 
94
  _gnutls_hash (&td_sha, session->security_parameters.client_random,
 
95
                GNUTLS_RANDOM_SIZE);
 
96
  _gnutls_hash (&td_sha, session->security_parameters.server_random,
 
97
                GNUTLS_RANDOM_SIZE);
 
98
  _gnutls_hash (&td_sha, params->data, params->size);
 
99
 
 
100
  switch (cert->subject_pk_algorithm)
 
101
    {
 
102
    case GNUTLS_PK_RSA:
 
103
      if (!_gnutls_version_has_selectable_sighash (ver))
 
104
        {
 
105
          digest_hd_st td_md5;
 
106
 
 
107
          ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
 
108
          if (ret < 0)
 
109
            {
 
110
              gnutls_assert ();
 
111
              return ret;
 
112
            }
 
113
 
 
114
          _gnutls_hash (&td_md5, session->security_parameters.client_random,
 
115
                        GNUTLS_RANDOM_SIZE);
 
116
          _gnutls_hash (&td_md5, session->security_parameters.server_random,
 
117
                        GNUTLS_RANDOM_SIZE);
 
118
          _gnutls_hash (&td_md5, params->data, params->size);
 
119
 
 
120
          _gnutls_hash_deinit (&td_md5, concat);
 
121
          _gnutls_hash_deinit (&td_sha, &concat[16]);
 
122
 
 
123
          dconcat.data = concat;
 
124
          dconcat.size = 36;
 
125
        }
 
126
      else
 
127
        { /* TLS 1.2 way */
 
128
 
 
129
          _gnutls_hash_deinit (&td_sha, concat);
 
130
 
 
131
          dconcat.data = concat;
 
132
          dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
 
133
        }
 
134
      break;
 
135
    case GNUTLS_PK_DSA:
 
136
      _gnutls_hash_deinit (&td_sha, concat);
 
137
 
 
138
      if ((hash_algo != GNUTLS_DIG_SHA1) && (hash_algo != GNUTLS_DIG_SHA224)
 
139
          && (hash_algo != GNUTLS_DIG_SHA256))
 
140
        {
 
141
          gnutls_assert ();
 
142
          return GNUTLS_E_INTERNAL_ERROR;
 
143
        }
 
144
      dconcat.data = concat;
 
145
      dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
 
146
      break;
 
147
 
 
148
    default:
 
149
      gnutls_assert ();
 
150
      _gnutls_hash_deinit (&td_sha, NULL);
 
151
      return GNUTLS_E_INTERNAL_ERROR;
 
152
    }
 
153
 
 
154
  ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature);
 
155
  if (ret < 0)
 
156
    {
 
157
      gnutls_assert ();
 
158
    }
 
159
 
 
160
  return ret;
 
161
 
 
162
}
 
163
 
 
164
 
 
165
/* This will create a PKCS1 or DSA signature, using the given parameters, and the
 
166
 * given data. The output will be allocated and be put in signature.
 
167
 */
 
168
int
 
169
_gnutls_soft_sign (gnutls_pk_algorithm_t algo, bigint_t * params,
 
170
                   int params_size, const gnutls_datum_t * data,
 
171
                   gnutls_datum_t * signature)
 
172
{
 
173
  int ret;
 
174
 
 
175
  switch (algo)
 
176
    {
 
177
    case GNUTLS_PK_RSA:
 
178
      /* encrypt */
 
179
      if ((ret = _gnutls_pkcs1_rsa_encrypt (signature, data, params,
 
180
                                            params_size, 1)) < 0)
 
181
        {
 
182
          gnutls_assert ();
 
183
          return ret;
 
184
        }
 
185
 
 
186
      break;
 
187
    case GNUTLS_PK_DSA:
 
188
      /* sign */
 
189
      if ((ret = _gnutls_dsa_sign (signature, data, params, params_size)) < 0)
 
190
        {
 
191
          gnutls_assert ();
 
192
          return ret;
 
193
        }
 
194
      break;
 
195
    default:
 
196
      gnutls_assert ();
 
197
      return GNUTLS_E_INTERNAL_ERROR;
 
198
      break;
 
199
    }
 
200
 
 
201
  return 0;
 
202
}
 
203
 
 
204
/* This will create a PKCS1 or DSA signature, as defined in the TLS protocol.
 
205
 * Cert is the certificate of the corresponding private key. It is only checked if
 
206
 * it supports signing.
 
207
 */
 
208
static int
 
209
sign_tls_hash (gnutls_session_t session, gnutls_digest_algorithm_t hash_algo,
 
210
                  gnutls_cert * cert, gnutls_privkey_t pkey,
 
211
                  const gnutls_datum_t * hash_concat,
 
212
                  gnutls_datum_t * signature)
 
213
{
 
214
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
215
 
 
216
  /* If our certificate supports signing
 
217
   */
 
218
 
 
219
  if (cert != NULL)
 
220
    {
 
221
      if (cert->key_usage != 0)
 
222
        if (!(cert->key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
 
223
          {
 
224
            gnutls_assert ();
 
225
            return GNUTLS_E_KEY_USAGE_VIOLATION;
 
226
          }
 
227
 
 
228
      /* External signing. */
 
229
      if (!pkey)
 
230
        {
 
231
          int ret;
 
232
 
 
233
          if (!session->internals.sign_func)
 
234
            return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
 
235
 
 
236
          if (!_gnutls_version_has_selectable_sighash (ver))
 
237
            return (*session->internals.sign_func)
 
238
              (session, session->internals.sign_func_userdata,
 
239
               cert->cert_type, &cert->raw, hash_concat, signature);
 
240
          else
 
241
            {
 
242
              gnutls_datum_t digest;
 
243
 
 
244
              ret = _gnutls_set_datum(&digest, hash_concat->data, hash_concat->size);
 
245
              if (ret < 0)
 
246
                return gnutls_assert_val(ret);
 
247
              
 
248
              ret = pk_prepare_hash (gnutls_privkey_get_pk_algorithm(pkey, NULL), hash_algo, &digest);
 
249
              if (ret < 0)
 
250
                {
 
251
                  gnutls_assert ();
 
252
                  goto es_cleanup;
 
253
                }
 
254
 
 
255
              ret = (*session->internals.sign_func)
 
256
                (session, session->internals.sign_func_userdata,
 
257
                 cert->cert_type, &cert->raw, &digest, signature);
 
258
es_cleanup:
 
259
              gnutls_free(digest.data);
 
260
              
 
261
              return ret;
 
262
            }
 
263
        }
 
264
    }
 
265
 
 
266
   if (!_gnutls_version_has_selectable_sighash (ver))
 
267
    return _gnutls_privkey_sign_hash (pkey, hash_concat, signature);
 
268
  else
 
269
    return gnutls_privkey_sign_hash (pkey, hash_algo, 0, hash_concat, signature);
 
270
}
 
271
 
 
272
static int
 
273
verify_tls_hash (gnutls_protocol_t ver, gnutls_cert * cert,
 
274
                    const gnutls_datum_t * hash_concat,
 
275
                    gnutls_datum_t * signature, size_t sha1pos,
 
276
                    gnutls_pk_algorithm_t pk_algo)
 
277
{
 
278
  int ret;
 
279
  gnutls_datum_t vdata;
 
280
 
 
281
  if (cert == NULL || cert->version == 0)
 
282
    {                           /* this is the only way to check
 
283
                                 * if it is initialized
 
284
                                 */
 
285
      gnutls_assert ();
 
286
      return GNUTLS_E_CERTIFICATE_ERROR;
 
287
    }
 
288
 
 
289
  /* If the certificate supports signing continue.
 
290
   */
 
291
  if (cert->key_usage != 0)
 
292
    if (!(cert->key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE))
 
293
      {
 
294
        gnutls_assert ();
 
295
        return GNUTLS_E_KEY_USAGE_VIOLATION;
 
296
      }
 
297
 
 
298
  if (pk_algo == GNUTLS_PK_UNKNOWN)
 
299
    pk_algo = cert->subject_pk_algorithm;
 
300
  switch (pk_algo)
 
301
    {
 
302
    case GNUTLS_PK_RSA:
 
303
 
 
304
      vdata.data = hash_concat->data;
 
305
      vdata.size = hash_concat->size;
 
306
 
 
307
      /* verify signature */
 
308
      if (!_gnutls_version_has_selectable_sighash (ver))
 
309
        ret = _gnutls_rsa_verify (&vdata, signature, cert->params,
 
310
                                     cert->params_size, 1);
 
311
      else
 
312
        ret = pubkey_verify_sig( NULL, &vdata, signature, pk_algo, 
 
313
          cert->params, cert->params_size);
 
314
 
 
315
      if (ret < 0)
 
316
        {
 
317
          gnutls_assert ();
 
318
          return ret;
 
319
        }
 
320
 
 
321
      break;
 
322
    case GNUTLS_PK_DSA:
 
323
 
 
324
      vdata.data = &hash_concat->data[sha1pos];
 
325
      vdata.size = hash_concat->size - sha1pos;
 
326
 
 
327
      ret = pubkey_verify_sig( NULL, &vdata, signature, pk_algo, 
 
328
        cert->params, cert->params_size);
 
329
      /* verify signature */
 
330
      if (ret < 0)
 
331
        {
 
332
          gnutls_assert ();
 
333
          return ret;
 
334
        }
 
335
 
 
336
      break;
 
337
    default:
 
338
      gnutls_assert ();
 
339
      return GNUTLS_E_INTERNAL_ERROR;
 
340
    }
 
341
 
 
342
 
 
343
 
 
344
  return 0;
 
345
}
 
346
 
 
347
 
 
348
/* Generates a signature of all the random data and the parameters.
 
349
 * Used in DHE_* ciphersuites.
 
350
 */
 
351
int
 
352
_gnutls_handshake_verify_data (gnutls_session_t session, gnutls_cert * cert,
 
353
                               const gnutls_datum_t * params,
 
354
                               gnutls_datum_t * signature,
 
355
                               gnutls_sign_algorithm_t algo)
 
356
{
 
357
  gnutls_datum_t dconcat;
 
358
  int ret;
 
359
  digest_hd_st td_md5;
 
360
  digest_hd_st td_sha;
 
361
  opaque concat[MAX_SIG_SIZE];
 
362
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
363
  gnutls_digest_algorithm_t hash_algo;
 
364
 
 
365
  if (_gnutls_version_has_selectable_sighash (ver))
 
366
    {
 
367
      _gnutls_handshake_log ("HSK[%p]: verify handshake data: using %s\n",
 
368
                    session, gnutls_sign_algorithm_get_name (algo));
 
369
 
 
370
      ret = cert_compatible_with_sig(cert, ver, algo);
 
371
      if (ret < 0)
 
372
        return gnutls_assert_val(ret);
 
373
 
 
374
      ret = _gnutls_session_sign_algo_enabled (session, algo);
 
375
      if (ret < 0)
 
376
        return gnutls_assert_val(ret);
 
377
 
 
378
      hash_algo = _gnutls_sign_get_hash_algorithm (algo);
 
379
    }
 
380
  else
 
381
    {
 
382
      ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
 
383
      if (ret < 0)
 
384
        {
 
385
          gnutls_assert ();
 
386
          return ret;
 
387
        }
 
388
 
 
389
      _gnutls_hash (&td_md5, session->security_parameters.client_random,
 
390
                    GNUTLS_RANDOM_SIZE);
 
391
      _gnutls_hash (&td_md5, session->security_parameters.server_random,
 
392
                    GNUTLS_RANDOM_SIZE);
 
393
      _gnutls_hash (&td_md5, params->data, params->size);
 
394
 
 
395
      hash_algo = GNUTLS_DIG_SHA1;
 
396
    }
 
397
 
 
398
  ret = _gnutls_hash_init (&td_sha, hash_algo);
 
399
  if (ret < 0)
 
400
    {
 
401
      gnutls_assert ();
 
402
      if (!_gnutls_version_has_selectable_sighash (ver))
 
403
        _gnutls_hash_deinit (&td_md5, NULL);
 
404
      return ret;
 
405
    }
 
406
 
 
407
  _gnutls_hash (&td_sha, session->security_parameters.client_random,
 
408
                GNUTLS_RANDOM_SIZE);
 
409
  _gnutls_hash (&td_sha, session->security_parameters.server_random,
 
410
                GNUTLS_RANDOM_SIZE);
 
411
  _gnutls_hash (&td_sha, params->data, params->size);
 
412
 
 
413
  if (!_gnutls_version_has_selectable_sighash (ver))
 
414
    {
 
415
      _gnutls_hash_deinit (&td_md5, concat);
 
416
      _gnutls_hash_deinit (&td_sha, &concat[16]);
 
417
      dconcat.data = concat;
 
418
      dconcat.size = 36;
 
419
    }
 
420
  else
 
421
    {
 
422
      _gnutls_hash_deinit (&td_sha, concat);
 
423
 
 
424
      dconcat.data = concat;
 
425
      dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
 
426
    }
 
427
 
 
428
  ret = verify_tls_hash (ver, cert, &dconcat, signature,
 
429
                            dconcat.size -
 
430
                            _gnutls_hash_get_algo_len (hash_algo),
 
431
                            _gnutls_sign_get_pk_algorithm (algo));
 
432
  if (ret < 0)
 
433
    {
 
434
      gnutls_assert ();
 
435
      return ret;
 
436
    }
 
437
 
 
438
  return ret;
 
439
 
 
440
}
 
441
 
 
442
/* Client certificate verify calculations
 
443
 */
 
444
 
 
445
/* this is _gnutls_handshake_verify_cert_vrfy for TLS 1.2
 
446
 */
 
447
static int
 
448
_gnutls_handshake_verify_cert_vrfy12 (gnutls_session_t session,
 
449
                                      gnutls_cert * cert,
 
450
                                      gnutls_datum_t * signature,
 
451
                                      gnutls_sign_algorithm_t sign_algo)
 
452
{
 
453
  int ret;
 
454
  opaque concat[MAX_SIG_SIZE];
 
455
  digest_hd_st td;
 
456
  gnutls_datum_t dconcat;
 
457
  gnutls_sign_algorithm_t _sign_algo;
 
458
  gnutls_digest_algorithm_t hash_algo;
 
459
  digest_hd_st *handshake_td;
 
460
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
461
 
 
462
  handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
 
463
  hash_algo = handshake_td->algorithm;
 
464
  _sign_algo =
 
465
    _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
 
466
 
 
467
  if (_sign_algo != sign_algo)
 
468
    {
 
469
      handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
 
470
      hash_algo = handshake_td->algorithm;
 
471
      _sign_algo =
 
472
        _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
 
473
      if (sign_algo != _sign_algo)
 
474
        {
 
475
          gnutls_assert ();
 
476
          return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
 
477
        }
 
478
    }
 
479
 
 
480
  ret = _gnutls_hash_copy (&td, handshake_td);
 
481
  if (ret < 0)
 
482
    {
 
483
      gnutls_assert ();
 
484
      return GNUTLS_E_HASH_FAILED;
 
485
    }
 
486
 
 
487
  _gnutls_hash_deinit (&td, concat);
 
488
 
 
489
  dconcat.data = concat;
 
490
  dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
 
491
 
 
492
  ret =
 
493
    verify_tls_hash (ver, cert, &dconcat, signature, 0,
 
494
                        cert->subject_pk_algorithm);
 
495
  if (ret < 0)
 
496
    {
 
497
      gnutls_assert ();
 
498
      return ret;
 
499
    }
 
500
 
 
501
  return ret;
 
502
 
 
503
}
 
504
 
 
505
/* Verifies a TLS signature (like the one in the client certificate
 
506
 * verify message). 
 
507
 */
 
508
int
 
509
_gnutls_handshake_verify_cert_vrfy (gnutls_session_t session,
 
510
                                    gnutls_cert * cert,
 
511
                                    gnutls_datum_t * signature,
 
512
                                    gnutls_sign_algorithm_t sign_algo)
 
513
{
 
514
  int ret;
 
515
  opaque concat[MAX_SIG_SIZE];
 
516
  digest_hd_st td_md5;
 
517
  digest_hd_st td_sha;
 
518
  gnutls_datum_t dconcat;
 
519
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
520
 
 
521
  _gnutls_handshake_log ("HSK[%p]: verify cert vrfy: using %s\n",
 
522
                    session, gnutls_sign_algorithm_get_name (sign_algo));
 
523
 
 
524
  if (session->security_parameters.handshake_mac_handle_type ==
 
525
      HANDSHAKE_MAC_TYPE_12)
 
526
    {
 
527
      return _gnutls_handshake_verify_cert_vrfy12 (session, cert, signature,
 
528
                                                   sign_algo);
 
529
    }
 
530
  else if (session->security_parameters.handshake_mac_handle_type !=
 
531
           HANDSHAKE_MAC_TYPE_10)
 
532
    {
 
533
      gnutls_assert ();
 
534
      return GNUTLS_E_INTERNAL_ERROR;
 
535
    }
 
536
 
 
537
  ret =
 
538
    _gnutls_hash_copy (&td_md5,
 
539
                       &session->internals.handshake_mac_handle.tls10.md5);
 
540
  if (ret < 0)
 
541
    {
 
542
      gnutls_assert ();
 
543
      return ret;
 
544
    }
 
545
 
 
546
  ret =
 
547
    _gnutls_hash_copy (&td_sha,
 
548
                       &session->internals.handshake_mac_handle.tls10.sha);
 
549
  if (ret < 0)
 
550
    {
 
551
      gnutls_assert ();
 
552
      _gnutls_hash_deinit (&td_md5, NULL);
 
553
      return GNUTLS_E_HASH_FAILED;
 
554
    }
 
555
 
 
556
  if (ver == GNUTLS_SSL3)
 
557
    {
 
558
      ret = _gnutls_generate_master (session, 1);
 
559
      if (ret < 0)
 
560
        {
 
561
          gnutls_assert ();
 
562
          return ret;
 
563
        }
 
564
 
 
565
      _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
 
566
                                         session->
 
567
                                         security_parameters.master_secret,
 
568
                                         GNUTLS_MASTER_SIZE);
 
569
      _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
 
570
                                         session->
 
571
                                         security_parameters.master_secret,
 
572
                                         GNUTLS_MASTER_SIZE);
 
573
    }
 
574
  else
 
575
    {
 
576
      _gnutls_hash_deinit (&td_md5, concat);
 
577
      _gnutls_hash_deinit (&td_sha, &concat[16]);
 
578
    }
 
579
 
 
580
  dconcat.data = concat;
 
581
  dconcat.size = 20 + 16;       /* md5+ sha */
 
582
 
 
583
  ret =
 
584
    verify_tls_hash (ver, cert, &dconcat, signature, 16,
 
585
                        cert->subject_pk_algorithm);
 
586
  if (ret < 0)
 
587
    {
 
588
      gnutls_assert ();
 
589
      return ret;
 
590
    }
 
591
 
 
592
  return ret;
 
593
 
 
594
}
 
595
 
 
596
/* the same as _gnutls_handshake_sign_cert_vrfy except that it is made for TLS 1.2
 
597
 */
 
598
static int
 
599
_gnutls_handshake_sign_cert_vrfy12 (gnutls_session_t session,
 
600
                                    gnutls_cert * cert, gnutls_privkey_t pkey,
 
601
                                    gnutls_datum_t * signature)
 
602
{
 
603
  gnutls_datum_t dconcat;
 
604
  int ret;
 
605
  opaque concat[MAX_SIG_SIZE];
 
606
  digest_hd_st td;
 
607
  gnutls_sign_algorithm_t sign_algo;
 
608
  gnutls_digest_algorithm_t hash_algo;
 
609
  digest_hd_st *handshake_td;
 
610
 
 
611
  sign_algo =
 
612
    _gnutls_session_get_sign_algo (session, cert);
 
613
  if (sign_algo == GNUTLS_SIGN_UNKNOWN)
 
614
    {
 
615
      gnutls_assert ();
 
616
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
 
617
    }
 
618
 
 
619
  hash_algo = _gnutls_sign_get_hash_algorithm (sign_algo);
 
620
 
 
621
  _gnutls_debug_log ("sign handshake cert vrfy: picked %s with %s\n",
 
622
                    gnutls_sign_algorithm_get_name (sign_algo),
 
623
                    gnutls_mac_get_name (hash_algo));
 
624
 
 
625
  if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha1.algorithm)
 
626
    handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
 
627
  else if ((gnutls_mac_algorithm_t)hash_algo == session->internals.handshake_mac_handle.tls12.sha256.algorithm)
 
628
    handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
 
629
  else
 
630
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); /* too bad we only support SHA1 and SHA256 */
 
631
 
 
632
  ret = _gnutls_hash_copy (&td, handshake_td);
 
633
  if (ret < 0)
 
634
    {
 
635
      gnutls_assert ();
 
636
      return ret;
 
637
    }
 
638
 
 
639
  _gnutls_hash_deinit (&td, concat);
 
640
 
 
641
  dconcat.data = concat;
 
642
  dconcat.size = _gnutls_hash_get_algo_len (hash_algo);
 
643
 
 
644
  ret = sign_tls_hash (session, hash_algo, cert, pkey, &dconcat, signature);
 
645
  if (ret < 0)
 
646
    {
 
647
      gnutls_assert ();
 
648
      return ret;
 
649
    }
 
650
 
 
651
  return sign_algo;
 
652
}
 
653
 
 
654
 
 
655
/* Generates a signature of all the previous sent packets in the 
 
656
 * handshake procedure. 
 
657
 * 20040227: now it works for SSL 3.0 as well
 
658
 * 20091031: works for TLS 1.2 too!
 
659
 *
 
660
 * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success.
 
661
 * For TLS1.2 returns the signature algorithm used on success, or a negative value;
 
662
 */
 
663
int
 
664
_gnutls_handshake_sign_cert_vrfy (gnutls_session_t session,
 
665
                                  gnutls_cert * cert, gnutls_privkey_t pkey,
 
666
                                  gnutls_datum_t * signature)
 
667
{
 
668
  gnutls_datum_t dconcat;
 
669
  int ret, hash_algo;
 
670
  opaque concat[MAX_SIG_SIZE];
 
671
  digest_hd_st td_md5;
 
672
  digest_hd_st td_sha;
 
673
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
674
 
 
675
  if (session->security_parameters.handshake_mac_handle_type ==
 
676
      HANDSHAKE_MAC_TYPE_12)
 
677
    {
 
678
      return _gnutls_handshake_sign_cert_vrfy12 (session, cert, pkey,
 
679
                                                 signature);
 
680
    }
 
681
  else if (session->security_parameters.handshake_mac_handle_type !=
 
682
           HANDSHAKE_MAC_TYPE_10)
 
683
    {
 
684
      gnutls_assert ();
 
685
      return GNUTLS_E_INTERNAL_ERROR;
 
686
    }
 
687
 
 
688
  ret =
 
689
    _gnutls_hash_copy (&td_sha,
 
690
                       &session->internals.handshake_mac_handle.tls10.sha);
 
691
  if (ret < 0)
 
692
    {
 
693
      gnutls_assert ();
 
694
      return ret;
 
695
    }
 
696
 
 
697
  if (ver == GNUTLS_SSL3)
 
698
    {
 
699
      ret = _gnutls_generate_master (session, 1);
 
700
      if (ret < 0)
 
701
        {
 
702
          gnutls_assert ();
 
703
          return ret;
 
704
        }
 
705
 
 
706
      _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
 
707
                                         session->
 
708
                                         security_parameters.master_secret,
 
709
                                         GNUTLS_MASTER_SIZE);
 
710
    }
 
711
  else
 
712
    _gnutls_hash_deinit (&td_sha, &concat[16]);
 
713
 
 
714
  switch (cert->subject_pk_algorithm)
 
715
    {
 
716
    case GNUTLS_PK_RSA:
 
717
      ret =
 
718
        _gnutls_hash_copy (&td_md5,
 
719
                           &session->internals.handshake_mac_handle.tls10.
 
720
                           md5);
 
721
      if (ret < 0)
 
722
        {
 
723
          gnutls_assert ();
 
724
          return ret;
 
725
        }
 
726
 
 
727
      if (ver == GNUTLS_SSL3)
 
728
        _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
 
729
                                           session->
 
730
                                           security_parameters.master_secret,
 
731
                                           GNUTLS_MASTER_SIZE);
 
732
      else
 
733
        _gnutls_hash_deinit (&td_md5, concat);
 
734
 
 
735
      dconcat.data = concat;
 
736
      dconcat.size = 36;
 
737
      break;
 
738
    case GNUTLS_PK_DSA:
 
739
      /* ensure 1024 bit DSA keys are used */
 
740
      hash_algo = _gnutls_dsa_q_to_hash (cert->params[1], NULL);
 
741
      if (!_gnutls_version_has_selectable_sighash (ver) && hash_algo != GNUTLS_DIG_SHA1)
 
742
        return gnutls_assert_val(GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL);
 
743
 
 
744
      dconcat.data = &concat[16];
 
745
      dconcat.size = 20;
 
746
      break;
 
747
 
 
748
    default:
 
749
      return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
 
750
    }
 
751
  ret = sign_tls_hash (session, GNUTLS_DIG_NULL, cert, pkey, &dconcat, signature);
 
752
  if (ret < 0)
 
753
    {
 
754
      gnutls_assert ();
 
755
    }
 
756
 
 
757
  return ret;
 
758
}
 
759
 
 
760
int
 
761
pk_hash_data (gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash,
 
762
              bigint_t * params,
 
763
              const gnutls_datum_t * data, gnutls_datum_t * digest)
 
764
{
 
765
  int ret;
 
766
 
 
767
  digest->size = _gnutls_hash_get_algo_len (hash);
 
768
  digest->data = gnutls_malloc (digest->size);
 
769
  if (digest->data == NULL)
 
770
    {
 
771
      gnutls_assert ();
 
772
      return GNUTLS_E_MEMORY_ERROR;
 
773
    }
 
774
 
 
775
  ret = _gnutls_hash_fast (hash, data->data, data->size, digest->data);
 
776
  if (ret < 0)
 
777
    {
 
778
      gnutls_assert ();
 
779
      goto cleanup;
 
780
    }
 
781
 
 
782
  return 0;
 
783
 
 
784
cleanup:
 
785
  gnutls_free (digest->data);
 
786
  return ret;
 
787
}
 
788
 
 
789
/* Writes the digest information and the digest in a DER encoded
 
790
 * structure. The digest info is allocated and stored into the info structure.
 
791
 */
 
792
static int
 
793
encode_ber_digest_info (gnutls_digest_algorithm_t hash,
 
794
                        const gnutls_datum_t * digest,
 
795
                        gnutls_datum_t * output)
 
796
{
 
797
  ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
 
798
  int result;
 
799
  const char *algo;
 
800
  opaque *tmp_output;
 
801
  int tmp_output_size;
 
802
 
 
803
  algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash);
 
804
  if (algo == NULL)
 
805
    {
 
806
      gnutls_assert ();
 
807
      _gnutls_x509_log ("Hash algorithm: %d\n", hash);
 
808
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
 
809
    }
 
810
 
 
811
  if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
 
812
                                     "GNUTLS.DigestInfo",
 
813
                                     &dinfo)) != ASN1_SUCCESS)
 
814
    {
 
815
      gnutls_assert ();
 
816
      return _gnutls_asn2err (result);
 
817
    }
 
818
 
 
819
  result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1);
 
820
  if (result != ASN1_SUCCESS)
 
821
    {
 
822
      gnutls_assert ();
 
823
      asn1_delete_structure (&dinfo);
 
824
      return _gnutls_asn2err (result);
 
825
    }
 
826
 
 
827
  /* Write an ASN.1 NULL in the parameters field.  This matches RFC
 
828
     3279 and RFC 4055, although is arguable incorrect from a historic
 
829
     perspective (see those documents for more information).
 
830
     Regardless of what is correct, this appears to be what most
 
831
     implementations do.  */
 
832
  result = asn1_write_value (dinfo, "digestAlgorithm.parameters",
 
833
                             ASN1_NULL, ASN1_NULL_SIZE);
 
834
  if (result != ASN1_SUCCESS)
 
835
    {
 
836
      gnutls_assert ();
 
837
      asn1_delete_structure (&dinfo);
 
838
      return _gnutls_asn2err (result);
 
839
    }
 
840
 
 
841
  result = asn1_write_value (dinfo, "digest", digest->data, digest->size);
 
842
  if (result != ASN1_SUCCESS)
 
843
    {
 
844
      gnutls_assert ();
 
845
      asn1_delete_structure (&dinfo);
 
846
      return _gnutls_asn2err (result);
 
847
    }
 
848
 
 
849
  tmp_output_size = 0;
 
850
  asn1_der_coding (dinfo, "", NULL, &tmp_output_size, NULL);
 
851
 
 
852
  tmp_output = gnutls_malloc (tmp_output_size);
 
853
  if (output->data == NULL)
 
854
    {
 
855
      gnutls_assert ();
 
856
      asn1_delete_structure (&dinfo);
 
857
      return GNUTLS_E_MEMORY_ERROR;
 
858
    }
 
859
 
 
860
  result = asn1_der_coding (dinfo, "", tmp_output, &tmp_output_size, NULL);
 
861
  if (result != ASN1_SUCCESS)
 
862
    {
 
863
      gnutls_assert ();
 
864
      asn1_delete_structure (&dinfo);
 
865
      return _gnutls_asn2err (result);
 
866
    }
 
867
 
 
868
  asn1_delete_structure (&dinfo);
 
869
 
 
870
  output->size = tmp_output_size;
 
871
  output->data = tmp_output;
 
872
 
 
873
  return 0;
 
874
}
 
875
 
 
876
/* 
 
877
 * This function will do RSA PKCS #1 1.5 encoding
 
878
 * on the given digest. The given digest must be allocated
 
879
 * and will be freed if replacement is required.
 
880
 */
 
881
int
 
882
pk_prepare_hash (gnutls_pk_algorithm_t pk,
 
883
                 gnutls_digest_algorithm_t hash, gnutls_datum_t * digest)
 
884
{
 
885
  int ret;
 
886
  gnutls_datum old_digest = { digest->data, digest->size };
 
887
 
 
888
  switch (pk)
 
889
    {
 
890
    case GNUTLS_PK_RSA:
 
891
      /* Encode the digest as a DigestInfo
 
892
       */
 
893
      if ((ret = encode_ber_digest_info (hash, &old_digest, digest)) != 0)
 
894
        {
 
895
          gnutls_assert ();
 
896
          return ret;
 
897
        }
 
898
 
 
899
      _gnutls_free_datum (&old_digest);
 
900
      break;
 
901
    case GNUTLS_PK_DSA:
 
902
      break;
 
903
    default:
 
904
      gnutls_assert ();
 
905
      return GNUTLS_E_UNIMPLEMENTED_FEATURE;
 
906
    }
 
907
 
 
908
  return 0;
 
909
}