~ubuntu-branches/ubuntu/raring/gnutls26/raring

« back to all changes in this revision

Viewing changes to lib/gnutls_sig.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2011-05-20 13:07:18 UTC
  • mfrom: (12.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20110520130718-db41dybbanzfvlji
Tags: 2.10.5-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Fix build failure with --no-add-needed.
  - Build for multiarch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2001, 2004, 2005, 2006, 2007, 2008 Free Software Foundation
 
2
 * Copyright (C) 2001, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
 
3
 * Software Foundation, Inc.
3
4
 *
4
5
 * Author: Nikos Mavrogiannopoulos
5
6
 *
6
 
 * This file is part of GNUTLS.
 
7
 * This file is part of GnuTLS.
7
8
 *
8
 
 * The GNUTLS library is free software; you can redistribute it and/or
 
9
 * The GnuTLS is free software; you can redistribute it and/or
9
10
 * modify it under the terms of the GNU Lesser General Public License
10
11
 * as published by the Free Software Foundation; either version 2.1 of
11
12
 * the License, or (at your option) any later version.
26
27
#include <gnutls_errors.h>
27
28
#include <x509_b64.h>
28
29
#include <auth_cert.h>
 
30
#include <gnutls_algorithms.h>
29
31
#include <gnutls_cert.h>
30
32
#include <gnutls_datum.h>
31
33
#include <gnutls_mpi.h>
35
37
#include <gnutls_buffers.h>
36
38
#include <gnutls_sig.h>
37
39
#include <gnutls_kx.h>
 
40
#include <libtasn1.h>
 
41
#include <ext_signature.h>
 
42
#include <gnutls_state.h>
 
43
#include <x509/common.h>
38
44
 
39
45
static int
40
46
_gnutls_tls_sign (gnutls_session_t session,
42
48
                  const gnutls_datum_t * hash_concat,
43
49
                  gnutls_datum_t * signature);
44
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
45
57
 
46
 
/* Generates a signature of all the previous sent packets in the 
47
 
 * handshake procedure. (20040227: now it works for SSL 3.0 as well)
 
58
/* Create a DER-encoded value as a opaque signature when RSA is used.
 
59
 * See RFC 5246 DigitallySigned for the actual format.
48
60
 */
49
 
int
50
 
_gnutls_tls_sign_hdata (gnutls_session_t session,
51
 
                        gnutls_cert * cert, gnutls_privkey * pkey,
 
61
static int
 
62
_gnutls_rsa_encode_sig (gnutls_mac_algorithm_t algo,
 
63
                        const gnutls_datum_t * hash,
52
64
                        gnutls_datum_t * signature)
53
65
{
54
 
  gnutls_datum_t dconcat;
55
 
  int ret;
56
 
  opaque concat[36];
57
 
  digest_hd_st td_md5;
58
 
  digest_hd_st td_sha;
59
 
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
60
 
 
61
 
  ret =
62
 
    _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha);
63
 
  if (ret < 0)
64
 
    {
65
 
      gnutls_assert ();
66
 
      return ret;
67
 
    }
68
 
 
69
 
  if (ver == GNUTLS_SSL3)
70
 
    {
71
 
      ret = _gnutls_generate_master (session, 1);
72
 
      if (ret < 0)
73
 
        {
74
 
          gnutls_assert ();
75
 
          return ret;
76
 
        }
77
 
 
78
 
      _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
79
 
                                         session->security_parameters.
80
 
                                         master_secret, GNUTLS_MASTER_SIZE);
81
 
    }
82
 
  else
83
 
    _gnutls_hash_deinit (&td_sha, &concat[16]);
84
 
 
85
 
  switch (cert->subject_pk_algorithm)
86
 
    {
87
 
    case GNUTLS_PK_RSA:
88
 
      ret =
89
 
        _gnutls_hash_copy (&td_md5,
90
 
                           &session->internals.handshake_mac_handle_md5);
91
 
      if (ret < 0)
92
 
        {
93
 
          gnutls_assert ();
94
 
          return ret;
95
 
        }
96
 
 
97
 
      if (ver == GNUTLS_SSL3)
98
 
        _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
99
 
                                           session->security_parameters.
100
 
                                           master_secret, GNUTLS_MASTER_SIZE);
101
 
      else
102
 
        _gnutls_hash_deinit (&td_md5, concat);
103
 
 
104
 
      dconcat.data = concat;
105
 
      dconcat.size = 36;
106
 
      break;
107
 
    case GNUTLS_PK_DSA:
108
 
      dconcat.data = &concat[16];
109
 
      dconcat.size = 20;
110
 
      break;
111
 
 
112
 
    default:
113
 
      gnutls_assert ();
114
 
      return GNUTLS_E_INTERNAL_ERROR;
115
 
    }
116
 
  ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
117
 
  if (ret < 0)
118
 
    {
119
 
      gnutls_assert ();
120
 
    }
121
 
 
122
 
  return ret;
 
66
  ASN1_TYPE di;
 
67
  const char *oid;
 
68
  int result, signature_size;
 
69
 
 
70
  oid = _gnutls_x509_mac_to_oid (algo);
 
71
  if (!oid)
 
72
    {
 
73
      gnutls_assert ();
 
74
      return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
 
75
    }
 
76
 
 
77
  if ((result = asn1_create_element
 
78
       (_gnutls_get_gnutls_asn (), "GNUTLS.DigestInfo", &di)) != ASN1_SUCCESS)
 
79
    {
 
80
      gnutls_assert ();
 
81
      return _gnutls_asn2err (result);
 
82
    }
 
83
 
 
84
  if ((result = asn1_write_value (di, "digestAlgorithm.algorithm",
 
85
                                  oid, strlen (oid))) != ASN1_SUCCESS)
 
86
    {
 
87
      gnutls_assert ();
 
88
      asn1_delete_structure (&di);
 
89
      return _gnutls_asn2err (result);
 
90
    }
 
91
 
 
92
  /* Use NULL parameters. */
 
93
  if ((result = asn1_write_value (di, "digestAlgorithm.parameters",
 
94
                                  ASN1_NULL, ASN1_NULL_SIZE)) != ASN1_SUCCESS)
 
95
    {
 
96
      gnutls_assert ();
 
97
      asn1_delete_structure (&di);
 
98
      return _gnutls_asn2err (result);
 
99
    }
 
100
 
 
101
  if ((result = asn1_write_value (di, "digest",
 
102
                                  hash->data, hash->size)) != ASN1_SUCCESS)
 
103
    {
 
104
      gnutls_assert ();
 
105
      asn1_delete_structure (&di);
 
106
      return _gnutls_asn2err (result);
 
107
    }
 
108
 
 
109
  signature_size = signature->size;
 
110
  result = asn1_der_coding (di, "", signature->data, &signature_size, NULL);
 
111
  asn1_delete_structure (&di);
 
112
 
 
113
  if (result != ASN1_SUCCESS)
 
114
    {
 
115
      gnutls_assert ();
 
116
      return _gnutls_asn2err (result);
 
117
    }
 
118
 
 
119
  signature->size = signature_size;
 
120
 
 
121
  return 0;
123
122
}
124
123
 
125
124
 
 
125
 
126
126
/* Generates a signature of all the random data and the parameters.
127
127
 * Used in DHE_* ciphersuites.
128
128
 */
129
129
int
130
 
_gnutls_tls_sign_params (gnutls_session_t session, gnutls_cert * cert,
131
 
                         gnutls_privkey * pkey, gnutls_datum_t * params,
132
 
                         gnutls_datum_t * signature)
 
130
_gnutls_handshake_sign_data (gnutls_session_t session, gnutls_cert * cert,
 
131
                             gnutls_privkey * pkey, gnutls_datum_t * params,
 
132
                             gnutls_datum_t * signature,
 
133
                             gnutls_sign_algorithm_t * sign_algo)
133
134
{
134
135
  gnutls_datum_t dconcat;
135
136
  int ret;
136
137
  digest_hd_st td_sha;
137
 
  opaque concat[36];
 
138
  opaque concat[MAX_SIG_SIZE];
138
139
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
139
 
 
140
 
  ret = _gnutls_hash_init (&td_sha, GNUTLS_MAC_SHA1);
 
140
  gnutls_digest_algorithm_t hash_algo;
 
141
 
 
142
  *sign_algo =
 
143
    _gnutls_session_get_sign_algo (session, cert->subject_pk_algorithm,
 
144
                                   &hash_algo);
 
145
  if (*sign_algo == GNUTLS_SIGN_UNKNOWN)
 
146
    {
 
147
      gnutls_assert ();
 
148
      return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
 
149
    }
 
150
 
 
151
  ret = _gnutls_hash_init (&td_sha, hash_algo);
141
152
  if (ret < 0)
142
153
    {
143
154
      gnutls_assert ();
153
164
  switch (cert->subject_pk_algorithm)
154
165
    {
155
166
    case GNUTLS_PK_RSA:
156
 
      if (ver < GNUTLS_TLS1_2)
 
167
      if (!_gnutls_version_has_selectable_prf (ver))
157
168
        {
158
169
          digest_hd_st td_md5;
159
170
 
173
184
          _gnutls_hash_deinit (&td_md5, concat);
174
185
          _gnutls_hash_deinit (&td_sha, &concat[16]);
175
186
 
 
187
          dconcat.data = concat;
176
188
          dconcat.size = 36;
177
189
        }
178
190
      else
179
 
        {
180
 
#if 1
181
 
          /* Use NULL parameters. */
182
 
          memcpy (concat,
183
 
                  "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
184
 
                  15);
185
 
          _gnutls_hash_deinit (&td_sha, &concat[15]);
186
 
          dconcat.size = 35;
187
 
#else
188
 
          /* No parameters field. */
189
 
          memcpy (concat,
190
 
                  "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
191
 
          _gnutls_hash_deinit (&td_sha, &concat[13]);
192
 
          dconcat.size = 33;
193
 
#endif
 
191
        {                       /* TLS 1.2 way */
 
192
          gnutls_datum_t hash;
 
193
 
 
194
          _gnutls_hash_deinit (&td_sha, concat);
 
195
 
 
196
          hash.data = concat;
 
197
          hash.size = _gnutls_hash_get_algo_len (hash_algo);
 
198
          dconcat.data = concat;
 
199
          dconcat.size = sizeof concat;
 
200
 
 
201
          ret = _gnutls_rsa_encode_sig (hash_algo, &hash, &dconcat);
 
202
          if (ret < 0)
 
203
            {
 
204
              gnutls_assert();
 
205
              return ret;
 
206
            }
194
207
        }
195
 
      dconcat.data = concat;
196
208
      break;
197
209
    case GNUTLS_PK_DSA:
198
210
      _gnutls_hash_deinit (&td_sha, concat);
 
211
 
 
212
      if (hash_algo != GNUTLS_DIG_SHA1)
 
213
        {
 
214
          gnutls_assert ();
 
215
          return GNUTLS_E_INTERNAL_ERROR;
 
216
        }
199
217
      dconcat.data = concat;
200
218
      dconcat.size = 20;
201
219
      break;
272
290
  if (cert != NULL)
273
291
    {
274
292
      if (cert->key_usage != 0)
275
 
        if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
 
293
        if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
276
294
          {
277
 
            gnutls_assert ();
 
295
            gnutls_assert ();
278
296
            return GNUTLS_E_KEY_USAGE_VIOLATION;
279
 
          }
 
297
          }
280
298
 
281
299
      /* External signing. */
282
300
      if (!pkey || pkey->params_size == 0)
283
 
        {
284
 
          if (!session->internals.sign_func)
 
301
        {
 
302
          if (!session->internals.sign_func)
285
303
            return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
286
304
 
287
 
          return (*session->internals.sign_func)
 
305
          return (*session->internals.sign_func)
288
306
            (session, session->internals.sign_func_userdata,
289
307
             cert->cert_type, &cert->raw, hash_concat, signature);
290
 
        }
 
308
        }
291
309
    }
292
310
 
293
311
  return _gnutls_sign (pkey->pk_algorithm, pkey->params,
297
315
static int
298
316
_gnutls_verify_sig (gnutls_cert * cert,
299
317
                    const gnutls_datum_t * hash_concat,
300
 
                    gnutls_datum_t * signature, size_t sha1pos)
 
318
                    gnutls_datum_t * signature, size_t sha1pos,
 
319
                    gnutls_pk_algorithm_t pk_algo)
301
320
{
302
321
  int ret;
303
322
  gnutls_datum_t vdata;
313
332
  /* If the certificate supports signing continue.
314
333
   */
315
334
  if (cert->key_usage != 0)
316
 
      if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
317
 
        {
318
 
          gnutls_assert ();
319
 
          return GNUTLS_E_KEY_USAGE_VIOLATION;
320
 
        }
 
335
    if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
 
336
      {
 
337
        gnutls_assert ();
 
338
        return GNUTLS_E_KEY_USAGE_VIOLATION;
 
339
      }
321
340
 
322
 
  switch (cert->subject_pk_algorithm)
 
341
  if (pk_algo == GNUTLS_PK_UNKNOWN)
 
342
    pk_algo = cert->subject_pk_algorithm;
 
343
  switch (pk_algo)
323
344
    {
324
345
    case GNUTLS_PK_RSA:
325
346
 
338
359
    case GNUTLS_PK_DSA:
339
360
 
340
361
      vdata.data = &hash_concat->data[sha1pos];
341
 
      vdata.size = 20;          /* sha1 */
 
362
      vdata.size = hash_concat->size - sha1pos;
342
363
 
343
364
      /* verify signature */
344
365
      if ((ret = _gnutls_dsa_verify (&vdata, signature, cert->params,
361
382
}
362
383
 
363
384
 
 
385
/* Generates a signature of all the random data and the parameters.
 
386
 * Used in DHE_* ciphersuites.
 
387
 */
 
388
int
 
389
_gnutls_handshake_verify_data (gnutls_session_t session, gnutls_cert * cert,
 
390
                               const gnutls_datum_t * params,
 
391
                               gnutls_datum_t * signature,
 
392
                               gnutls_sign_algorithm_t algo)
 
393
{
 
394
  gnutls_datum_t dconcat;
 
395
  int ret;
 
396
  digest_hd_st td_md5;
 
397
  digest_hd_st td_sha;
 
398
  opaque concat[MAX_SIG_SIZE];
 
399
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
400
  gnutls_digest_algorithm_t hash_algo = GNUTLS_DIG_SHA1;
 
401
 
 
402
  ret = _gnutls_session_sign_algo_enabled (session, algo);
 
403
  if (ret < 0)
 
404
    {
 
405
      gnutls_assert ();
 
406
      return ret;
 
407
    }
 
408
 
 
409
  if (!_gnutls_version_has_selectable_prf (ver))
 
410
    {
 
411
      ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
 
412
      if (ret < 0)
 
413
        {
 
414
          gnutls_assert ();
 
415
          return ret;
 
416
        }
 
417
 
 
418
      _gnutls_hash (&td_md5, session->security_parameters.client_random,
 
419
                    GNUTLS_RANDOM_SIZE);
 
420
      _gnutls_hash (&td_md5, session->security_parameters.server_random,
 
421
                    GNUTLS_RANDOM_SIZE);
 
422
      _gnutls_hash (&td_md5, params->data, params->size);
 
423
    }
 
424
 
 
425
  if (algo != GNUTLS_SIGN_UNKNOWN)
 
426
    hash_algo = _gnutls_sign_get_hash_algorithm (algo);
 
427
 
 
428
  ret = _gnutls_hash_init (&td_sha, hash_algo);
 
429
  if (ret < 0)
 
430
    {
 
431
      gnutls_assert ();
 
432
      if (!_gnutls_version_has_selectable_prf (ver))
 
433
        _gnutls_hash_deinit (&td_md5, NULL);
 
434
      return ret;
 
435
    }
 
436
 
 
437
  _gnutls_hash (&td_sha, session->security_parameters.client_random,
 
438
                GNUTLS_RANDOM_SIZE);
 
439
  _gnutls_hash (&td_sha, session->security_parameters.server_random,
 
440
                GNUTLS_RANDOM_SIZE);
 
441
  _gnutls_hash (&td_sha, params->data, params->size);
 
442
 
 
443
  if (!_gnutls_version_has_selectable_prf (ver))
 
444
    {
 
445
      _gnutls_hash_deinit (&td_md5, concat);
 
446
      _gnutls_hash_deinit (&td_sha, &concat[16]);
 
447
      dconcat.data = concat;
 
448
      dconcat.size = 36;
 
449
    }
 
450
  else
 
451
    {
 
452
      gnutls_datum_t hash;
 
453
 
 
454
      _gnutls_hash_deinit (&td_sha, concat);
 
455
 
 
456
      hash.data = concat;
 
457
      hash.size = _gnutls_hash_get_algo_len (hash_algo);
 
458
      dconcat.data = concat;
 
459
      dconcat.size = sizeof concat;
 
460
 
 
461
      ret = _gnutls_rsa_encode_sig (hash_algo, &hash, &dconcat);
 
462
      if (ret < 0)
 
463
        {
 
464
          gnutls_assert();
 
465
          return ret;
 
466
        }
 
467
    }
 
468
 
 
469
  ret = _gnutls_verify_sig (cert, &dconcat, signature,
 
470
                            dconcat.size -
 
471
                            _gnutls_hash_get_algo_len (hash_algo),
 
472
                            _gnutls_sign_get_pk_algorithm (algo));
 
473
  if (ret < 0)
 
474
    {
 
475
      gnutls_assert ();
 
476
      return ret;
 
477
    }
 
478
 
 
479
  return ret;
 
480
 
 
481
}
 
482
 
 
483
/* Client certificate verify calculations
 
484
 */
 
485
 
 
486
/* this is _gnutls_handshake_verify_cert_vrfy for TLS 1.2
 
487
 */
 
488
static int
 
489
_gnutls_handshake_verify_cert_vrfy12 (gnutls_session_t session,
 
490
                                      gnutls_cert * cert,
 
491
                                      gnutls_datum_t * signature,
 
492
                                      gnutls_sign_algorithm_t sign_algo)
 
493
{
 
494
  int ret;
 
495
  opaque concat[MAX_SIG_SIZE];
 
496
  digest_hd_st td;
 
497
  gnutls_datum_t dconcat;
 
498
  gnutls_datum_t hash;
 
499
  gnutls_sign_algorithm_t _sign_algo;
 
500
  gnutls_digest_algorithm_t hash_algo;
 
501
  digest_hd_st *handshake_td;
 
502
 
 
503
  handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
 
504
  hash_algo = handshake_td->algorithm;
 
505
  _sign_algo =
 
506
    _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
 
507
 
 
508
  if (_sign_algo != sign_algo)
 
509
    {
 
510
      handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
 
511
      hash_algo = handshake_td->algorithm;
 
512
      _sign_algo =
 
513
        _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
 
514
      if (sign_algo != _sign_algo)
 
515
        {
 
516
          gnutls_assert ();
 
517
          return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
 
518
        }
 
519
    }
 
520
 
 
521
  ret = _gnutls_hash_copy (&td, handshake_td);
 
522
  if (ret < 0)
 
523
    {
 
524
      gnutls_assert ();
 
525
      return GNUTLS_E_HASH_FAILED;
 
526
    }
 
527
 
 
528
  _gnutls_hash_deinit (&td, concat);
 
529
 
 
530
  hash.data = concat;
 
531
  hash.size = _gnutls_hash_get_algo_len (hash_algo);
 
532
 
 
533
  dconcat.data = concat;
 
534
  dconcat.size = sizeof concat;
 
535
 
 
536
  ret = _gnutls_rsa_encode_sig (hash_algo, &hash, &dconcat);
 
537
  if (ret < 0)
 
538
    {
 
539
      gnutls_assert();
 
540
      return ret;
 
541
    }
 
542
 
 
543
  ret =
 
544
    _gnutls_verify_sig (cert, &dconcat, signature, 0,
 
545
                        cert->subject_pk_algorithm);
 
546
  if (ret < 0)
 
547
    {
 
548
      gnutls_assert ();
 
549
      return ret;
 
550
    }
 
551
 
 
552
  return ret;
 
553
 
 
554
}
 
555
 
364
556
/* Verifies a TLS signature (like the one in the client certificate
365
557
 * verify message). 
366
558
 */
367
559
int
368
 
_gnutls_verify_sig_hdata (gnutls_session_t session, gnutls_cert * cert,
369
 
                          gnutls_datum_t * signature)
 
560
_gnutls_handshake_verify_cert_vrfy (gnutls_session_t session,
 
561
                                    gnutls_cert * cert,
 
562
                                    gnutls_datum_t * signature,
 
563
                                    gnutls_sign_algorithm_t sign_algo)
370
564
{
371
565
  int ret;
372
 
  opaque concat[36];
 
566
  opaque concat[MAX_SIG_SIZE];
373
567
  digest_hd_st td_md5;
374
568
  digest_hd_st td_sha;
375
569
  gnutls_datum_t dconcat;
376
570
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
377
571
 
 
572
  if (session->security_parameters.handshake_mac_handle_type ==
 
573
      HANDSHAKE_MAC_TYPE_12)
 
574
    {
 
575
      return _gnutls_handshake_verify_cert_vrfy12 (session, cert, signature,
 
576
                                                   sign_algo);
 
577
    }
 
578
  else if (session->security_parameters.handshake_mac_handle_type !=
 
579
           HANDSHAKE_MAC_TYPE_10)
 
580
    {
 
581
      gnutls_assert ();
 
582
      return GNUTLS_E_INTERNAL_ERROR;
 
583
    }
 
584
 
378
585
  ret =
379
 
    _gnutls_hash_copy (&td_md5, &session->internals.handshake_mac_handle_md5);
 
586
    _gnutls_hash_copy (&td_md5,
 
587
                       &session->internals.handshake_mac_handle.tls10.md5);
380
588
  if (ret < 0)
381
589
    {
382
590
      gnutls_assert ();
384
592
    }
385
593
 
386
594
  ret =
387
 
    _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha);
 
595
    _gnutls_hash_copy (&td_sha,
 
596
                       &session->internals.handshake_mac_handle.tls10.sha);
388
597
  if (ret < 0)
389
598
    {
390
599
      gnutls_assert ();
402
611
        }
403
612
 
404
613
      _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
405
 
                                         session->security_parameters.
406
 
                                         master_secret, GNUTLS_MASTER_SIZE);
 
614
                                         session->
 
615
                                         security_parameters.master_secret,
 
616
                                         GNUTLS_MASTER_SIZE);
407
617
      _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
408
 
                                         session->security_parameters.
409
 
                                         master_secret, GNUTLS_MASTER_SIZE);
 
618
                                         session->
 
619
                                         security_parameters.master_secret,
 
620
                                         GNUTLS_MASTER_SIZE);
410
621
    }
411
622
  else
412
623
    {
417
628
  dconcat.data = concat;
418
629
  dconcat.size = 20 + 16;       /* md5+ sha */
419
630
 
420
 
  ret = _gnutls_verify_sig (cert, &dconcat, signature, 16);
 
631
  ret =
 
632
    _gnutls_verify_sig (cert, &dconcat, signature, 16,
 
633
                        cert->subject_pk_algorithm);
421
634
  if (ret < 0)
422
635
    {
423
636
      gnutls_assert ();
428
641
 
429
642
}
430
643
 
431
 
/* Generates a signature of all the random data and the parameters.
432
 
 * Used in DHE_* ciphersuites.
 
644
/* the same as _gnutls_handshake_sign_cert_vrfy except that it is made for TLS 1.2
 
645
 */
 
646
static int
 
647
_gnutls_handshake_sign_cert_vrfy12 (gnutls_session_t session,
 
648
                                    gnutls_cert * cert, gnutls_privkey * pkey,
 
649
                                    gnutls_datum_t * signature)
 
650
{
 
651
  gnutls_datum_t dconcat, hash;
 
652
  int ret;
 
653
  opaque concat[MAX_SIG_SIZE];
 
654
  digest_hd_st td;
 
655
  gnutls_sign_algorithm_t sign_algo;
 
656
  gnutls_digest_algorithm_t hash_algo;
 
657
  digest_hd_st *handshake_td;
 
658
 
 
659
  handshake_td = &session->internals.handshake_mac_handle.tls12.sha1;
 
660
  hash_algo = handshake_td->algorithm;
 
661
  sign_algo = _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
 
662
 
 
663
  /* The idea here is to try signing with the one of the algorithms
 
664
   * that have been initiated at handshake (SHA1, SHA256). If they
 
665
   * are not requested by peer... tough luck
 
666
   */
 
667
  ret = _gnutls_session_sign_algo_requested (session, sign_algo);
 
668
  if (sign_algo == GNUTLS_SIGN_UNKNOWN || ret < 0)
 
669
    {
 
670
      handshake_td = &session->internals.handshake_mac_handle.tls12.sha256;
 
671
      hash_algo = handshake_td->algorithm;
 
672
      sign_algo =
 
673
        _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, hash_algo);
 
674
      if (sign_algo == GNUTLS_SIGN_UNKNOWN)
 
675
        {
 
676
          gnutls_assert ();
 
677
          return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
 
678
        }
 
679
 
 
680
      ret = _gnutls_session_sign_algo_requested (session, sign_algo);
 
681
      if (ret < 0)
 
682
        {
 
683
          gnutls_assert ();
 
684
          _gnutls_x509_log
 
685
            ("Server did not allow either '%s' or '%s' for signing\n",
 
686
             gnutls_mac_get_name (hash_algo),
 
687
             gnutls_mac_get_name (session->internals.handshake_mac_handle.
 
688
                                  tls12.sha1.algorithm));
 
689
          return ret;
 
690
        }
 
691
    }
 
692
 
 
693
  _gnutls_x509_log ("sign handshake cert vrfy: picked %s with %s\n",
 
694
                    gnutls_sign_algorithm_get_name (sign_algo),
 
695
                    gnutls_mac_get_name (hash_algo));
 
696
 
 
697
  ret = _gnutls_hash_copy (&td, handshake_td);
 
698
  if (ret < 0)
 
699
    {
 
700
      gnutls_assert ();
 
701
      return ret;
 
702
    }
 
703
 
 
704
  _gnutls_hash_deinit (&td, concat);
 
705
 
 
706
  hash.data = concat;
 
707
  hash.size = _gnutls_hash_get_algo_len (hash_algo);
 
708
 
 
709
  dconcat.data = concat;
 
710
  dconcat.size = sizeof concat;
 
711
 
 
712
  ret = _gnutls_rsa_encode_sig (hash_algo, &hash, &dconcat);
 
713
  if (ret < 0)
 
714
    {
 
715
      gnutls_assert();
 
716
      return ret;
 
717
    }
 
718
 
 
719
  ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
 
720
  if (ret < 0)
 
721
    {
 
722
      gnutls_assert ();
 
723
      return ret;
 
724
    }
 
725
 
 
726
  return sign_algo;
 
727
}
 
728
 
 
729
/* Generates a signature of all the previous sent packets in the 
 
730
 * handshake procedure. 
 
731
 * 20040227: now it works for SSL 3.0 as well
 
732
 * 20091031: works for TLS 1.2 too!
 
733
 *
 
734
 * For TLS1.x, x<2 returns negative for failure and zero or unspecified for success.
 
735
 * For TLS1.2 returns the signature algorithm used on success, or a negative value;
433
736
 */
434
737
int
435
 
_gnutls_verify_sig_params (gnutls_session_t session, gnutls_cert * cert,
436
 
                           const gnutls_datum_t * params,
437
 
                           gnutls_datum_t * signature)
 
738
_gnutls_handshake_sign_cert_vrfy (gnutls_session_t session,
 
739
                                  gnutls_cert * cert, gnutls_privkey * pkey,
 
740
                                  gnutls_datum_t * signature)
438
741
{
439
742
  gnutls_datum_t dconcat;
440
743
  int ret;
 
744
  opaque concat[MAX_SIG_SIZE];
441
745
  digest_hd_st td_md5;
442
746
  digest_hd_st td_sha;
443
 
  opaque concat[36];
444
747
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
445
748
 
446
 
  if (ver < GNUTLS_TLS1_2)
447
 
    {
448
 
      ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
449
 
      if (ret < 0)
450
 
        {
451
 
          gnutls_assert ();
452
 
          return ret;
453
 
        }
454
 
 
455
 
      _gnutls_hash (&td_md5, session->security_parameters.client_random,
456
 
                    GNUTLS_RANDOM_SIZE);
457
 
      _gnutls_hash (&td_md5, session->security_parameters.server_random,
458
 
                    GNUTLS_RANDOM_SIZE);
459
 
      _gnutls_hash (&td_md5, params->data, params->size);
460
 
    }
461
 
 
462
 
  ret = _gnutls_hash_init (&td_sha, GNUTLS_MAC_SHA1);
 
749
  if (session->security_parameters.handshake_mac_handle_type ==
 
750
      HANDSHAKE_MAC_TYPE_12)
 
751
    {
 
752
      return _gnutls_handshake_sign_cert_vrfy12 (session, cert, pkey,
 
753
                                                 signature);
 
754
    }
 
755
  else if (session->security_parameters.handshake_mac_handle_type !=
 
756
           HANDSHAKE_MAC_TYPE_10)
 
757
    {
 
758
      gnutls_assert ();
 
759
      return GNUTLS_E_INTERNAL_ERROR;
 
760
    }
 
761
 
 
762
  ret =
 
763
    _gnutls_hash_copy (&td_sha,
 
764
                       &session->internals.handshake_mac_handle.tls10.sha);
463
765
  if (ret < 0)
464
766
    {
465
767
      gnutls_assert ();
466
 
      if (ver < GNUTLS_TLS1_2)
467
 
        _gnutls_hash_deinit (&td_md5, NULL);
468
768
      return ret;
469
769
    }
470
770
 
471
 
  _gnutls_hash (&td_sha, session->security_parameters.client_random,
472
 
                GNUTLS_RANDOM_SIZE);
473
 
  _gnutls_hash (&td_sha, session->security_parameters.server_random,
474
 
                GNUTLS_RANDOM_SIZE);
475
 
  _gnutls_hash (&td_sha, params->data, params->size);
476
 
 
477
 
  if (ver < GNUTLS_TLS1_2)
478
 
    {
479
 
      _gnutls_hash_deinit (&td_md5, concat);
480
 
      _gnutls_hash_deinit (&td_sha, &concat[16]);
 
771
  if (ver == GNUTLS_SSL3)
 
772
    {
 
773
      ret = _gnutls_generate_master (session, 1);
 
774
      if (ret < 0)
 
775
        {
 
776
          gnutls_assert ();
 
777
          return ret;
 
778
        }
 
779
 
 
780
      _gnutls_mac_deinit_ssl3_handshake (&td_sha, &concat[16],
 
781
                                         session->
 
782
                                         security_parameters.master_secret,
 
783
                                         GNUTLS_MASTER_SIZE);
 
784
    }
 
785
  else
 
786
    _gnutls_hash_deinit (&td_sha, &concat[16]);
 
787
 
 
788
  switch (cert->subject_pk_algorithm)
 
789
    {
 
790
    case GNUTLS_PK_RSA:
 
791
      ret =
 
792
        _gnutls_hash_copy (&td_md5,
 
793
                           &session->internals.handshake_mac_handle.tls10.
 
794
                           md5);
 
795
      if (ret < 0)
 
796
        {
 
797
          gnutls_assert ();
 
798
          return ret;
 
799
        }
 
800
 
 
801
      if (ver == GNUTLS_SSL3)
 
802
        _gnutls_mac_deinit_ssl3_handshake (&td_md5, concat,
 
803
                                           session->
 
804
                                           security_parameters.master_secret,
 
805
                                           GNUTLS_MASTER_SIZE);
 
806
      else
 
807
        _gnutls_hash_deinit (&td_md5, concat);
 
808
 
 
809
      dconcat.data = concat;
481
810
      dconcat.size = 36;
482
 
    }
483
 
  else
484
 
    {
485
 
#if 1
486
 
      /* Use NULL parameters. */
487
 
      memcpy (concat,
488
 
              "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
489
 
              15);
490
 
      _gnutls_hash_deinit (&td_sha, &concat[15]);
491
 
      dconcat.size = 35;
492
 
#else
493
 
      /* No parameters field. */
494
 
      memcpy (concat,
495
 
              "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
496
 
      _gnutls_hash_deinit (&td_sha, &concat[13]);
497
 
      dconcat.size = 33;
498
 
#endif
499
 
    }
500
 
 
501
 
  dconcat.data = concat;
502
 
 
503
 
  ret = _gnutls_verify_sig (cert, &dconcat, signature, dconcat.size - 20);
 
811
      break;
 
812
    case GNUTLS_PK_DSA:
 
813
      dconcat.data = &concat[16];
 
814
      dconcat.size = 20;
 
815
      break;
 
816
 
 
817
    default:
 
818
      gnutls_assert ();
 
819
      return GNUTLS_E_INTERNAL_ERROR;
 
820
    }
 
821
  ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
504
822
  if (ret < 0)
505
823
    {
506
824
      gnutls_assert ();
507
 
      return ret;
508
825
    }
509
826
 
510
827
  return ret;
511
 
 
512
828
}