~ubuntu-branches/ubuntu/saucy/gnutls26/saucy-security

« back to all changes in this revision

Viewing changes to .pc/CVE-2014-0092.patch/lib/x509/verify.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-03-03 14:14:00 UTC
  • Revision ID: package-import@ubuntu.com-20140303141400-qufjcofwrokefsiy
Tags: 2.12.23-1ubuntu4.2
* SECURITY UPDATE: certificate validation bypass
  - debian/patches/CVE-2014-0092.patch: correct return codes in
    lib/x509/verify.c.
  - CVE-2014-0092

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2003, 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
/* All functions which relate to X.509 certificate verification stuff are
 
27
 * included here
 
28
 */
 
29
 
 
30
#include <gnutls_int.h>
 
31
#include <gnutls_errors.h>
 
32
#include <gnutls_cert.h>
 
33
#include <libtasn1.h>
 
34
#include <gnutls_global.h>
 
35
#include <gnutls_num.h>         /* MAX */
 
36
#include <gnutls_sig.h>
 
37
#include <gnutls_str.h>
 
38
#include <gnutls_datum.h>
 
39
#include "x509_int.h"
 
40
#include <common.h>
 
41
 
 
42
static int _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
 
43
                                        const gnutls_x509_crt_t * trusted_cas,
 
44
                                        int tcas_size, unsigned int flags,
 
45
                                        unsigned int *output,
 
46
                                        gnutls_x509_crt_t * issuer);
 
47
 
 
48
static int is_crl_issuer (gnutls_x509_crl_t crl,
 
49
                          gnutls_x509_crt_t issuer_cert);
 
50
 
 
51
static int _gnutls_verify_crl2 (gnutls_x509_crl_t crl,
 
52
                                const gnutls_x509_crt_t * trusted_cas,
 
53
                                int tcas_size, unsigned int flags,
 
54
                                unsigned int *output);
 
55
 
 
56
/* Checks if two certs are identical.  Return 0 on match. */
 
57
static int
 
58
check_if_same_cert (gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2)
 
59
{
 
60
  gnutls_datum_t cert1bin = { NULL, 0 }, cert2bin =
 
61
  {
 
62
  NULL, 0};
 
63
  int result;
 
64
  opaque serial1[128], serial2[128];
 
65
  size_t serial1_size, serial2_size;
 
66
 
 
67
  serial1_size = sizeof (serial1);
 
68
  result = gnutls_x509_crt_get_serial (cert1, serial1, &serial1_size);
 
69
  if (result < 0)
 
70
    {
 
71
      gnutls_assert ();
 
72
      goto cmp;
 
73
    }
 
74
 
 
75
  serial2_size = sizeof (serial2);
 
76
  result = gnutls_x509_crt_get_serial (cert2, serial2, &serial2_size);
 
77
  if (result < 0)
 
78
    {
 
79
      gnutls_assert ();
 
80
      goto cmp;
 
81
    }
 
82
 
 
83
  if (serial2_size != serial1_size
 
84
      || memcmp (serial1, serial2, serial1_size) != 0)
 
85
    {
 
86
      return 1;
 
87
    }
 
88
 
 
89
cmp:
 
90
  result = _gnutls_x509_der_encode (cert1->cert, "", &cert1bin, 0);
 
91
  if (result < 0)
 
92
    {
 
93
      gnutls_assert ();
 
94
      goto cleanup;
 
95
    }
 
96
 
 
97
  result = _gnutls_x509_der_encode (cert2->cert, "", &cert2bin, 0);
 
98
  if (result < 0)
 
99
    {
 
100
      gnutls_assert ();
 
101
      goto cleanup;
 
102
    }
 
103
 
 
104
  if ((cert1bin.size == cert2bin.size) &&
 
105
      (memcmp (cert1bin.data, cert2bin.data, cert1bin.size) == 0))
 
106
    result = 0;
 
107
  else
 
108
    result = 1;
 
109
 
 
110
cleanup:
 
111
  _gnutls_free_datum (&cert1bin);
 
112
  _gnutls_free_datum (&cert2bin);
 
113
  return result;
 
114
}
 
115
 
 
116
/* Checks if the issuer of a certificate is a
 
117
 * Certificate Authority, or if the certificate is the same
 
118
 * as the issuer (and therefore it doesn't need to be a CA).
 
119
 *
 
120
 * Returns true or false, if the issuer is a CA,
 
121
 * or not.
 
122
 */
 
123
static int
 
124
check_if_ca (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
 
125
             unsigned int flags)
 
126
{
 
127
  gnutls_datum_t cert_signed_data = { NULL, 0 };
 
128
  gnutls_datum_t issuer_signed_data = { NULL, 0 };
 
129
  gnutls_datum_t cert_signature = { NULL, 0 };
 
130
  gnutls_datum_t issuer_signature = { NULL, 0 };
 
131
  int result;
 
132
 
 
133
  /* Check if the issuer is the same with the
 
134
   * certificate. This is added in order for trusted
 
135
   * certificates to be able to verify themselves.
 
136
   */
 
137
 
 
138
  result =
 
139
    _gnutls_x509_get_signed_data (issuer->cert, "tbsCertificate",
 
140
                                  &issuer_signed_data);
 
141
  if (result < 0)
 
142
    {
 
143
      gnutls_assert ();
 
144
      goto cleanup;
 
145
    }
 
146
 
 
147
  result =
 
148
    _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
 
149
                                  &cert_signed_data);
 
150
  if (result < 0)
 
151
    {
 
152
      gnutls_assert ();
 
153
      goto cleanup;
 
154
    }
 
155
 
 
156
  result =
 
157
    _gnutls_x509_get_signature (issuer->cert, "signature", &issuer_signature);
 
158
  if (result < 0)
 
159
    {
 
160
      gnutls_assert ();
 
161
      goto cleanup;
 
162
    }
 
163
 
 
164
  result =
 
165
    _gnutls_x509_get_signature (cert->cert, "signature", &cert_signature);
 
166
  if (result < 0)
 
167
    {
 
168
      gnutls_assert ();
 
169
      goto cleanup;
 
170
    }
 
171
 
 
172
  /* If the subject certificate is the same as the issuer
 
173
   * return true.
 
174
   */
 
175
  if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
 
176
    if (cert_signed_data.size == issuer_signed_data.size)
 
177
      {
 
178
        if ((memcmp (cert_signed_data.data, issuer_signed_data.data,
 
179
                     cert_signed_data.size) == 0) &&
 
180
            (cert_signature.size == issuer_signature.size) &&
 
181
            (memcmp (cert_signature.data, issuer_signature.data,
 
182
                     cert_signature.size) == 0))
 
183
          {
 
184
            result = 1;
 
185
            goto cleanup;
 
186
          }
 
187
      }
 
188
 
 
189
  result = gnutls_x509_crt_get_ca_status (issuer, NULL);
 
190
  if (result == 1)
 
191
    {
 
192
      result = 1;
 
193
      goto cleanup;
 
194
    }
 
195
  /* Handle V1 CAs that do not have a basicConstraint, but accept
 
196
     these certs only if the appropriate flags are set. */
 
197
  else if ((result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) &&
 
198
           ((flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT) ||
 
199
            (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT) &&
 
200
             (gnutls_x509_crt_check_issuer (issuer, issuer) == 1))))
 
201
    {
 
202
      gnutls_assert ();
 
203
      result = 1;
 
204
      goto cleanup;
 
205
    }
 
206
  else
 
207
    gnutls_assert ();
 
208
 
 
209
  result = 0;
 
210
 
 
211
cleanup:
 
212
  _gnutls_free_datum (&cert_signed_data);
 
213
  _gnutls_free_datum (&issuer_signed_data);
 
214
  _gnutls_free_datum (&cert_signature);
 
215
  _gnutls_free_datum (&issuer_signature);
 
216
  return result;
 
217
}
 
218
 
 
219
 
 
220
/* This function checks if 'certs' issuer is 'issuer_cert'.
 
221
 * This does a straight (DER) compare of the issuer/subject fields in
 
222
 * the given certificates.
 
223
 *
 
224
 * Returns 1 if they match and zero if they don't match. Otherwise
 
225
 * a negative value is returned to indicate error.
 
226
 */
 
227
static int
 
228
is_issuer (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer_cert)
 
229
{
 
230
  gnutls_datum_t dn1 = { NULL, 0 }, 
 
231
                 dn2 = { NULL, 0};
 
232
  uint8_t id1[512];
 
233
  uint8_t id2[512];
 
234
  size_t id1_size;
 
235
  size_t id2_size;
 
236
  int ret;
 
237
 
 
238
  ret = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn1);
 
239
  if (ret < 0)
 
240
    {
 
241
      gnutls_assert ();
 
242
      goto cleanup;
 
243
    }
 
244
 
 
245
  ret = gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
 
246
  if (ret < 0)
 
247
    {
 
248
      gnutls_assert ();
 
249
      goto cleanup;
 
250
    }
 
251
 
 
252
  ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
 
253
  
 
254
  if (ret != 0)
 
255
    {
 
256
      /* check if the authority key identifier matches the subject key identifier
 
257
       * of the isser */
 
258
       id1_size = sizeof(id1);
 
259
       
 
260
       ret = gnutls_x509_crt_get_authority_key_id(cert, id1, &id1_size, NULL);
 
261
       if (ret < 0)
 
262
         {
 
263
           ret = 1;
 
264
           goto cleanup;
 
265
         }
 
266
 
 
267
       id2_size = sizeof(id2);
 
268
       ret = gnutls_x509_crt_get_subject_key_id(issuer_cert, id2, &id2_size, NULL);
 
269
       if (ret < 0)
 
270
         {
 
271
           ret = 1;
 
272
           gnutls_assert();
 
273
           goto cleanup;
 
274
         }
 
275
    
 
276
       if (id1_size == id2_size && memcmp(id1, id2, id1_size) == 0)
 
277
         ret = 1;
 
278
       else
 
279
         ret = 0;
 
280
    }
 
281
 
 
282
cleanup:
 
283
  _gnutls_free_datum (&dn1);
 
284
  _gnutls_free_datum (&dn2);
 
285
  return ret;
 
286
 
 
287
}
 
288
 
 
289
 
 
290
static inline gnutls_x509_crt_t
 
291
find_issuer (gnutls_x509_crt_t cert,
 
292
             const gnutls_x509_crt_t * trusted_cas, int tcas_size)
 
293
{
 
294
  int i;
 
295
 
 
296
  /* this is serial search. 
 
297
   */
 
298
 
 
299
  for (i = 0; i < tcas_size; i++)
 
300
    {
 
301
      if (is_issuer (cert, trusted_cas[i]) == 1)
 
302
        return trusted_cas[i];
 
303
    }
 
304
 
 
305
  gnutls_assert ();
 
306
  return NULL;
 
307
}
 
308
 
 
309
 
 
310
 
 
311
/* 
 
312
 * Verifies the given certificate again a certificate list of
 
313
 * trusted CAs.
 
314
 *
 
315
 * Returns only 0 or 1. If 1 it means that the certificate 
 
316
 * was successfuly verified.
 
317
 *
 
318
 * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
 
319
 *
 
320
 * Output will hold some extra information about the verification
 
321
 * procedure. Issuer will hold the actual issuer from the trusted list.
 
322
 */
 
323
static int
 
324
_gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
 
325
                             const gnutls_x509_crt_t * trusted_cas,
 
326
                             int tcas_size, unsigned int flags,
 
327
                             unsigned int *output,
 
328
                             gnutls_x509_crt_t * _issuer)
 
329
{
 
330
  gnutls_datum_t cert_signed_data = { NULL, 0 };
 
331
  gnutls_datum_t cert_signature = { NULL, 0 };
 
332
  gnutls_x509_crt_t issuer = NULL;
 
333
  int issuer_version, result;
 
334
 
 
335
  if (output)
 
336
    *output = 0;
 
337
 
 
338
  if (tcas_size >= 1)
 
339
    issuer = find_issuer (cert, trusted_cas, tcas_size);
 
340
  else
 
341
    {
 
342
      gnutls_assert ();
 
343
      if (output)
 
344
        *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
 
345
      return 0;
 
346
    }
 
347
 
 
348
  /* issuer is not in trusted certificate
 
349
   * authorities.
 
350
   */
 
351
  if (issuer == NULL)
 
352
    {
 
353
      if (output)
 
354
        *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
 
355
      gnutls_assert ();
 
356
      return 0;
 
357
    }
 
358
 
 
359
  if (_issuer != NULL)
 
360
    *_issuer = issuer;
 
361
 
 
362
  issuer_version = gnutls_x509_crt_get_version (issuer);
 
363
  if (issuer_version < 0)
 
364
    {
 
365
      gnutls_assert ();
 
366
      return issuer_version;
 
367
    }
 
368
 
 
369
  if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) &&
 
370
      ((flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT)
 
371
       || issuer_version != 1))
 
372
    {
 
373
      if (check_if_ca (cert, issuer, flags) == 0)
 
374
        {
 
375
          gnutls_assert ();
 
376
          if (output)
 
377
            *output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
 
378
          return 0;
 
379
        }
 
380
    }
 
381
 
 
382
  result =
 
383
    _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
 
384
                                  &cert_signed_data);
 
385
  if (result < 0)
 
386
    {
 
387
      gnutls_assert ();
 
388
      goto cleanup;
 
389
    }
 
390
 
 
391
  result =
 
392
    _gnutls_x509_get_signature (cert->cert, "signature", &cert_signature);
 
393
  if (result < 0)
 
394
    {
 
395
      gnutls_assert ();
 
396
      goto cleanup;
 
397
    }
 
398
 
 
399
  result =
 
400
    _gnutls_x509_verify_signature (&cert_signed_data, NULL, &cert_signature,
 
401
                                   issuer);
 
402
  if (result == GNUTLS_E_PK_SIG_VERIFY_FAILED)
 
403
    {
 
404
      gnutls_assert ();
 
405
      /* error. ignore it */
 
406
      if (output)
 
407
        *output |= GNUTLS_CERT_INVALID;
 
408
      result = 0;
 
409
    }
 
410
  else if (result < 0)
 
411
    {
 
412
      gnutls_assert();
 
413
      goto cleanup;
 
414
    }
 
415
 
 
416
  /* If the certificate is not self signed check if the algorithms
 
417
   * used are secure. If the certificate is self signed it doesn't
 
418
   * really matter.
 
419
   */
 
420
  if (is_issuer (cert, cert) == 0)
 
421
    {
 
422
      int sigalg;
 
423
 
 
424
      sigalg = gnutls_x509_crt_get_signature_algorithm (cert);
 
425
 
 
426
      if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
 
427
           !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
 
428
          ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
 
429
           !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
 
430
        {
 
431
          if (output)
 
432
            *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
 
433
          result = 0;
 
434
        }
 
435
    }
 
436
 
 
437
cleanup:
 
438
  _gnutls_free_datum (&cert_signed_data);
 
439
  _gnutls_free_datum (&cert_signature);
 
440
 
 
441
  return result;
 
442
}
 
443
 
 
444
/**
 
445
 * gnutls_x509_crt_check_issuer:
 
446
 * @cert: is the certificate to be checked
 
447
 * @issuer: is the certificate of a possible issuer
 
448
 *
 
449
 * This function will check if the given certificate was issued by the
 
450
 * given issuer. It checks the DN fields and the authority
 
451
 * key identifier and subject key identifier fields match.
 
452
 *
 
453
 * Returns: It will return true (1) if the given certificate is issued
 
454
 *   by the given issuer, and false (0) if not.  A negative value is
 
455
 *   returned in case of an error.
 
456
 **/
 
457
int
 
458
gnutls_x509_crt_check_issuer (gnutls_x509_crt_t cert,
 
459
                              gnutls_x509_crt_t issuer)
 
460
{
 
461
  return is_issuer (cert, issuer);
 
462
}
 
463
 
 
464
static unsigned int
 
465
check_time (gnutls_x509_crt_t crt, time_t now)
 
466
{
 
467
  int status = 0;
 
468
  time_t t;
 
469
 
 
470
  t = gnutls_x509_crt_get_activation_time (crt);
 
471
  if (t == (time_t) - 1 || now < t)
 
472
    {
 
473
      status |= GNUTLS_CERT_NOT_ACTIVATED;
 
474
      status |= GNUTLS_CERT_INVALID;
 
475
      return status;
 
476
    }
 
477
 
 
478
  t = gnutls_x509_crt_get_expiration_time (crt);
 
479
  if (t == (time_t) - 1 || now > t)
 
480
    {
 
481
      status |= GNUTLS_CERT_EXPIRED;
 
482
      status |= GNUTLS_CERT_INVALID;
 
483
      return status;
 
484
    }
 
485
 
 
486
  return 0;
 
487
}
 
488
 
 
489
/* Verify X.509 certificate chain.
 
490
 *
 
491
 * Note that the return value is an OR of GNUTLS_CERT_* elements.
 
492
 *
 
493
 * This function verifies a X.509 certificate list. The certificate
 
494
 * list should lead to a trusted certificate in order to be trusted.
 
495
 */
 
496
static unsigned int
 
497
_gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
 
498
                                 int clist_size,
 
499
                                 const gnutls_x509_crt_t * trusted_cas,
 
500
                                 int tcas_size,
 
501
                                 const gnutls_x509_crl_t * CRLs,
 
502
                                 int crls_size, unsigned int flags)
 
503
{
 
504
  int i = 0, ret;
 
505
  unsigned int status = 0, output;
 
506
  time_t now = gnutls_time (0);
 
507
  gnutls_x509_crt_t issuer = NULL;
 
508
 
 
509
  if (clist_size > 1)
 
510
    {
 
511
      /* Check if the last certificate in the path is self signed.
 
512
       * In that case ignore it (a certificate is trusted only if it
 
513
       * leads to a trusted party by us, not the server's).
 
514
       *
 
515
       * This prevents from verifying self signed certificates against
 
516
       * themselves. This (although not bad) caused verification
 
517
       * failures on some root self signed certificates that use the
 
518
       * MD2 algorithm.
 
519
       */
 
520
      if (gnutls_x509_crt_check_issuer (certificate_list[clist_size - 1],
 
521
                                        certificate_list[clist_size - 1]) > 0)
 
522
        {
 
523
          clist_size--;
 
524
        }
 
525
    }
 
526
 
 
527
  /* We want to shorten the chain by removing the cert that matches
 
528
   * one of the certs we trust and all the certs after that i.e. if
 
529
   * cert chain is A signed-by B signed-by C signed-by D (signed-by
 
530
   * self-signed E but already removed above), and we trust B, remove
 
531
   * B, C and D. */
 
532
  if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
 
533
    i = 0;                      /* also replace the first one */
 
534
  else
 
535
    i = 1;                      /* do not replace the first one */
 
536
 
 
537
  for (; i < clist_size; i++)
 
538
    {
 
539
      int j;
 
540
 
 
541
      for (j = 0; j < tcas_size; j++)
 
542
        {
 
543
          if (check_if_same_cert (certificate_list[i], trusted_cas[j]) == 0)
 
544
            {
 
545
              /* explicity time check for trusted CA that we remove from
 
546
               * list. GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS
 
547
               */
 
548
              if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS)
 
549
                  && !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS))
 
550
                {
 
551
                  status |= check_time (trusted_cas[j], now);
 
552
                  if (status != 0)
 
553
                    {
 
554
                      return status;
 
555
                    }
 
556
                }
 
557
              clist_size = i;
 
558
              break;
 
559
            }
 
560
        }
 
561
      /* clist_size may have been changed which gets out of loop */
 
562
    }
 
563
 
 
564
  if (clist_size == 0)
 
565
    /* The certificate is already present in the trusted certificate list.
 
566
     * Nothing to verify. */
 
567
    return status;
 
568
 
 
569
  /* Verify the last certificate in the certificate path
 
570
   * against the trusted CA certificate list.
 
571
   *
 
572
   * If no CAs are present returns CERT_INVALID. Thus works
 
573
   * in self signed etc certificates.
 
574
   */
 
575
  ret = _gnutls_verify_certificate2 (certificate_list[clist_size - 1],
 
576
                                     trusted_cas, tcas_size, flags, &output,
 
577
                                     &issuer);
 
578
  if (ret == 0)
 
579
    {
 
580
      /* if the last certificate in the certificate
 
581
       * list is invalid, then the certificate is not
 
582
       * trusted.
 
583
       */
 
584
      gnutls_assert ();
 
585
      status |= output;
 
586
      status |= GNUTLS_CERT_INVALID;
 
587
      return status;
 
588
    }
 
589
 
 
590
  /* Check for revoked certificates in the chain
 
591
   */
 
592
#ifdef ENABLE_PKI
 
593
  for (i = 0; i < clist_size; i++)
 
594
    {
 
595
      ret = gnutls_x509_crt_check_revocation (certificate_list[i],
 
596
                                              CRLs, crls_size);
 
597
      if (ret == 1)
 
598
        {                       /* revoked */
 
599
          status |= GNUTLS_CERT_REVOKED;
 
600
          status |= GNUTLS_CERT_INVALID;
 
601
          return status;
 
602
        }
 
603
    }
 
604
#endif
 
605
 
 
606
 
 
607
  /* Check activation/expiration times
 
608
   */
 
609
  if (!(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS))
 
610
    {
 
611
      /* check the time of the issuer first */
 
612
      if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS))
 
613
        {
 
614
          if (issuer == NULL)
 
615
            {
 
616
              gnutls_assert ();
 
617
              return GNUTLS_E_INTERNAL_ERROR;
 
618
            }
 
619
 
 
620
          status |= check_time (issuer, now);
 
621
          if (status != 0)
 
622
            {
 
623
              return status;
 
624
            }
 
625
        }
 
626
 
 
627
      for (i = 0; i < clist_size; i++)
 
628
        {
 
629
          status |= check_time (certificate_list[i], now);
 
630
          if (status != 0)
 
631
            {
 
632
              return status;
 
633
            }
 
634
        }
 
635
    }
 
636
 
 
637
  /* Verify the certificate path (chain)
 
638
   */
 
639
  for (i = clist_size - 1; i > 0; i--)
 
640
    {
 
641
      if (i - 1 < 0)
 
642
        break;
 
643
 
 
644
      /* note that here we disable this V1 CA flag. So that no version 1
 
645
       * certificates can exist in a supplied chain.
 
646
       */
 
647
      if (!(flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT)) {
 
648
        flags &= ~(GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
 
649
        flags |= GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT;
 
650
      }
 
651
      if ((ret =
 
652
           _gnutls_verify_certificate2 (certificate_list[i - 1],
 
653
                                        &certificate_list[i], 1, flags,
 
654
                                        NULL, NULL)) == 0)
 
655
        {
 
656
          status |= GNUTLS_CERT_INVALID;
 
657
          return status;
 
658
        }
 
659
    }
 
660
 
 
661
  return 0;
 
662
}
 
663
 
 
664
 
 
665
/* Reads the digest information.
 
666
 * we use DER here, although we should use BER. It works fine
 
667
 * anyway.
 
668
 */
 
669
static int
 
670
decode_ber_digest_info (const gnutls_datum_t * info,
 
671
                        gnutls_mac_algorithm_t * hash,
 
672
                        opaque * digest, int *digest_size)
 
673
{
 
674
  ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
 
675
  int result;
 
676
  char str[1024];
 
677
  int len;
 
678
 
 
679
  if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
 
680
                                     "GNUTLS.DigestInfo",
 
681
                                     &dinfo)) != ASN1_SUCCESS)
 
682
    {
 
683
      gnutls_assert ();
 
684
      return _gnutls_asn2err (result);
 
685
    }
 
686
 
 
687
  result = asn1_der_decoding (&dinfo, info->data, info->size, NULL);
 
688
  if (result != ASN1_SUCCESS)
 
689
    {
 
690
      gnutls_assert ();
 
691
      asn1_delete_structure (&dinfo);
 
692
      return _gnutls_asn2err (result);
 
693
    }
 
694
 
 
695
  len = sizeof (str) - 1;
 
696
  result = asn1_read_value (dinfo, "digestAlgorithm.algorithm", str, &len);
 
697
  if (result != ASN1_SUCCESS)
 
698
    {
 
699
      gnutls_assert ();
 
700
      asn1_delete_structure (&dinfo);
 
701
      return _gnutls_asn2err (result);
 
702
    }
 
703
 
 
704
  *hash = _gnutls_x509_oid2mac_algorithm (str);
 
705
 
 
706
  if (*hash == GNUTLS_MAC_UNKNOWN)
 
707
    {
 
708
 
 
709
      _gnutls_x509_log ("verify.c: HASH OID: %s\n", str);
 
710
 
 
711
      gnutls_assert ();
 
712
      asn1_delete_structure (&dinfo);
 
713
      return GNUTLS_E_UNKNOWN_ALGORITHM;
 
714
    }
 
715
 
 
716
  len = sizeof (str) - 1;
 
717
  result = asn1_read_value (dinfo, "digestAlgorithm.parameters", str, &len);
 
718
  /* To avoid permitting garbage in the parameters field, either the
 
719
     parameters field is not present, or it contains 0x05 0x00. */
 
720
  if (!(result == ASN1_ELEMENT_NOT_FOUND ||
 
721
        (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
 
722
         memcmp (str, ASN1_NULL, ASN1_NULL_SIZE) == 0)))
 
723
    {
 
724
      gnutls_assert ();
 
725
      asn1_delete_structure (&dinfo);
 
726
      return GNUTLS_E_ASN1_GENERIC_ERROR;
 
727
    }
 
728
 
 
729
  result = asn1_read_value (dinfo, "digest", digest, digest_size);
 
730
  if (result != ASN1_SUCCESS)
 
731
    {
 
732
      gnutls_assert ();
 
733
      asn1_delete_structure (&dinfo);
 
734
      return _gnutls_asn2err (result);
 
735
    }
 
736
 
 
737
  asn1_delete_structure (&dinfo);
 
738
 
 
739
  return 0;
 
740
}
 
741
 
 
742
/* if hash==MD5 then we do RSA-MD5
 
743
 * if hash==SHA then we do RSA-SHA
 
744
 * params[0] is modulus
 
745
 * params[1] is public key
 
746
 */
 
747
static int
 
748
_pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
 
749
                       const gnutls_datum_t * prehash,
 
750
                       const gnutls_datum_t * signature, bigint_t * params,
 
751
                       int params_len)
 
752
{
 
753
  gnutls_mac_algorithm_t hash = GNUTLS_MAC_UNKNOWN;
 
754
  int ret;
 
755
  opaque digest[MAX_HASH_SIZE], md[MAX_HASH_SIZE], *cmp;
 
756
  int digest_size;
 
757
  digest_hd_st hd;
 
758
  gnutls_datum_t decrypted;
 
759
 
 
760
  ret =
 
761
    _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, params_len, 1);
 
762
  if (ret < 0)
 
763
    {
 
764
      gnutls_assert ();
 
765
      return ret;
 
766
    }
 
767
 
 
768
  /* decrypted is a BER encoded data of type DigestInfo
 
769
   */
 
770
 
 
771
  digest_size = sizeof (digest);
 
772
  if ((ret =
 
773
       decode_ber_digest_info (&decrypted, &hash, digest, &digest_size)) != 0)
 
774
    {
 
775
      gnutls_assert ();
 
776
      _gnutls_free_datum (&decrypted);
 
777
      return ret;
 
778
    }
 
779
 
 
780
  _gnutls_free_datum (&decrypted);
 
781
 
 
782
  if (digest_size != _gnutls_hash_get_algo_len (hash))
 
783
    {
 
784
      gnutls_assert ();
 
785
      return GNUTLS_E_ASN1_GENERIC_ERROR;
 
786
    }
 
787
 
 
788
  if (prehash && prehash->data && prehash->size == digest_size)
 
789
    {
 
790
      cmp = prehash->data;
 
791
    }
 
792
  else
 
793
    {
 
794
      if (!text)
 
795
        {
 
796
          gnutls_assert ();
 
797
          return GNUTLS_E_INVALID_REQUEST;
 
798
        }
 
799
 
 
800
      ret = _gnutls_hash_init (&hd, hash);
 
801
      if (ret < 0)
 
802
        {
 
803
          gnutls_assert ();
 
804
          return ret;
 
805
        }
 
806
 
 
807
      _gnutls_hash (&hd, text->data, text->size);
 
808
      _gnutls_hash_deinit (&hd, md);
 
809
 
 
810
      cmp = md;
 
811
    }
 
812
 
 
813
  if (memcmp (cmp, digest, digest_size) != 0)
 
814
    {
 
815
      gnutls_assert ();
 
816
      return GNUTLS_E_PK_SIG_VERIFY_FAILED;
 
817
    }
 
818
 
 
819
  return 0;
 
820
}
 
821
 
 
822
/* Hashes input data and verifies a DSA signature.
 
823
 */
 
824
static int
 
825
dsa_verify_sig (const gnutls_datum_t * text,
 
826
                const gnutls_datum_t * hash,
 
827
                const gnutls_datum_t * signature, bigint_t * params,
 
828
                int params_len)
 
829
{
 
830
  int ret;
 
831
  opaque _digest[MAX_HASH_SIZE];
 
832
  gnutls_datum_t digest;
 
833
  digest_hd_st hd;
 
834
  gnutls_digest_algorithm_t algo;
 
835
  unsigned int hash_len;
 
836
 
 
837
  algo = _gnutls_dsa_q_to_hash (params[1], &hash_len);
 
838
  if (hash)
 
839
    {
 
840
      /* SHA1 or better allowed */
 
841
      if (!hash->data || hash->size < hash_len)
 
842
        {
 
843
          gnutls_assert();
 
844
          _gnutls_debug_log("Hash size (%d) does not correspond to hash %s", (int)hash->size, gnutls_mac_get_name(algo));
 
845
          
 
846
          if (hash->size != 20)
 
847
            return GNUTLS_E_PK_SIG_VERIFY_FAILED;
 
848
        }
 
849
      digest = *hash;
 
850
    }
 
851
  else
 
852
    {
 
853
 
 
854
      ret = _gnutls_hash_init (&hd, algo);
 
855
      if (ret < 0)
 
856
        {
 
857
          gnutls_assert ();
 
858
          return ret;
 
859
        }
 
860
 
 
861
      _gnutls_hash (&hd, text->data, text->size);
 
862
      _gnutls_hash_deinit (&hd, _digest);
 
863
 
 
864
      digest.data = _digest;
 
865
      digest.size = _gnutls_hash_get_algo_len(algo);
 
866
    }
 
867
 
 
868
  ret = _gnutls_dsa_verify (&digest, signature, params, params_len);
 
869
 
 
870
  return ret;
 
871
}
 
872
 
 
873
/* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if 
 
874
 * not verified, or 1 otherwise.
 
875
 */
 
876
int
 
877
pubkey_verify_sig (const gnutls_datum_t * tbs,
 
878
                   const gnutls_datum_t * hash,
 
879
                   const gnutls_datum_t * signature,
 
880
                   gnutls_pk_algorithm_t pk, bigint_t * issuer_params,
 
881
                   int issuer_params_size)
 
882
{
 
883
 
 
884
  switch (pk)
 
885
    {
 
886
    case GNUTLS_PK_RSA:
 
887
 
 
888
      if (_pkcs1_rsa_verify_sig
 
889
          (tbs, hash, signature, issuer_params, issuer_params_size) != 0)
 
890
        {
 
891
          gnutls_assert ();
 
892
          return GNUTLS_E_PK_SIG_VERIFY_FAILED;
 
893
        }
 
894
 
 
895
      return 1;
 
896
      break;
 
897
 
 
898
    case GNUTLS_PK_DSA:
 
899
      if (dsa_verify_sig
 
900
          (tbs, hash, signature, issuer_params, issuer_params_size) != 0)
 
901
        {
 
902
          gnutls_assert ();
 
903
          return GNUTLS_E_PK_SIG_VERIFY_FAILED;
 
904
        }
 
905
 
 
906
      return 1;
 
907
      break;
 
908
    default:
 
909
      gnutls_assert ();
 
910
      return GNUTLS_E_INTERNAL_ERROR;
 
911
 
 
912
    }
 
913
}
 
914
 
 
915
gnutls_digest_algorithm_t
 
916
_gnutls_dsa_q_to_hash (bigint_t q, unsigned int* hash_len)
 
917
{
 
918
  int bits = _gnutls_mpi_get_nbits (q);
 
919
 
 
920
  if (bits <= 160)
 
921
    {
 
922
      if (hash_len) *hash_len = 20;
 
923
      return GNUTLS_DIG_SHA1;
 
924
    }
 
925
  else if (bits <= 224)
 
926
    {
 
927
      if (hash_len) *hash_len = 28;
 
928
      return GNUTLS_DIG_SHA256;
 
929
    }
 
930
  else
 
931
    {
 
932
      if (hash_len) *hash_len = 32;
 
933
      return GNUTLS_DIG_SHA256;
 
934
    }
 
935
}
 
936
 
 
937
/* This will return the appropriate hash to verify the given signature.
 
938
 * If signature is NULL it will return an (or the) appropriate hash for
 
939
 * the given parameters.
 
940
 */
 
941
int
 
942
_gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
 
943
                               const gnutls_datum_t * signature,
 
944
                               gnutls_pk_algorithm pk,
 
945
                               bigint_t * issuer_params,
 
946
                               unsigned int issuer_params_size)
 
947
{
 
948
  opaque digest[MAX_HASH_SIZE];
 
949
  gnutls_datum_t decrypted;
 
950
  int digest_size;
 
951
  int ret;
 
952
 
 
953
  switch (pk)
 
954
    {
 
955
    case GNUTLS_PK_DSA:
 
956
 
 
957
      if (hash)
 
958
        *hash = _gnutls_dsa_q_to_hash (issuer_params[1], NULL);
 
959
 
 
960
      ret = 0;
 
961
      break;
 
962
    case GNUTLS_PK_RSA:
 
963
      if (signature == NULL)
 
964
        {                       /* return a sensible algorithm */
 
965
          if (hash)
 
966
            *hash = GNUTLS_DIG_SHA256;
 
967
          return 0;
 
968
        }
 
969
 
 
970
      ret =
 
971
        _gnutls_pkcs1_rsa_decrypt (&decrypted, signature,
 
972
                                   issuer_params, issuer_params_size, 1);
 
973
 
 
974
 
 
975
      if (ret < 0)
 
976
        {
 
977
          gnutls_assert ();
 
978
          goto cleanup;
 
979
        }
 
980
 
 
981
      digest_size = sizeof (digest);
 
982
      if ((ret =
 
983
           decode_ber_digest_info (&decrypted, hash, digest,
 
984
                                   &digest_size)) != 0)
 
985
        {
 
986
          gnutls_assert ();
 
987
          _gnutls_free_datum (&decrypted);
 
988
          goto cleanup;
 
989
        }
 
990
 
 
991
      _gnutls_free_datum (&decrypted);
 
992
      if (digest_size != _gnutls_hash_get_algo_len (*hash))
 
993
        {
 
994
          gnutls_assert ();
 
995
          ret = GNUTLS_E_ASN1_GENERIC_ERROR;
 
996
          goto cleanup;
 
997
        }
 
998
 
 
999
      ret = 0;
 
1000
      break;
 
1001
 
 
1002
    default:
 
1003
      gnutls_assert ();
 
1004
      ret = GNUTLS_E_INTERNAL_ERROR;
 
1005
    }
 
1006
 
 
1007
cleanup:
 
1008
 
 
1009
  return ret;
 
1010
 
 
1011
}
 
1012
 
 
1013
/* verifies if the certificate is properly signed.
 
1014
 * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success.
 
1015
 * 
 
1016
 * 'tbs' is the signed data
 
1017
 * 'signature' is the signature!
 
1018
 */
 
1019
int
 
1020
_gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
 
1021
                               const gnutls_datum_t * hash,
 
1022
                               const gnutls_datum_t * signature,
 
1023
                               gnutls_x509_crt_t issuer)
 
1024
{
 
1025
  bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE];
 
1026
  int ret, issuer_params_size, i;
 
1027
 
 
1028
  /* Read the MPI parameters from the issuer's certificate.
 
1029
   */
 
1030
  issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
 
1031
  ret =
 
1032
    _gnutls_x509_crt_get_mpis (issuer, issuer_params, &issuer_params_size);
 
1033
  if (ret < 0)
 
1034
    {
 
1035
      gnutls_assert ();
 
1036
      return ret;
 
1037
    }
 
1038
 
 
1039
  ret =
 
1040
    pubkey_verify_sig (tbs, hash, signature,
 
1041
                       gnutls_x509_crt_get_pk_algorithm (issuer, NULL),
 
1042
                       issuer_params, issuer_params_size);
 
1043
  if (ret < 0)
 
1044
    {
 
1045
      gnutls_assert ();
 
1046
    }
 
1047
 
 
1048
  /* release all allocated MPIs
 
1049
   */
 
1050
  for (i = 0; i < issuer_params_size; i++)
 
1051
    {
 
1052
      _gnutls_mpi_release (&issuer_params[i]);
 
1053
    }
 
1054
 
 
1055
  return ret;
 
1056
}
 
1057
 
 
1058
/* verifies if the certificate is properly signed.
 
1059
 * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success.
 
1060
 * 
 
1061
 * 'tbs' is the signed data
 
1062
 * 'signature' is the signature!
 
1063
 */
 
1064
int
 
1065
_gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs,
 
1066
                                       const gnutls_datum_t * signature,
 
1067
                                       gnutls_x509_privkey_t issuer)
 
1068
{
 
1069
  int ret;
 
1070
 
 
1071
  ret = pubkey_verify_sig (tbs, NULL, signature, issuer->pk_algorithm,
 
1072
                           issuer->params, issuer->params_size);
 
1073
  if (ret < 0)
 
1074
    {
 
1075
      gnutls_assert ();
 
1076
    }
 
1077
 
 
1078
  return ret;
 
1079
}
 
1080
 
 
1081
/**
 
1082
 * gnutls_x509_crt_list_verify:
 
1083
 * @cert_list: is the certificate list to be verified
 
1084
 * @cert_list_length: holds the number of certificate in cert_list
 
1085
 * @CA_list: is the CA list which will be used in verification
 
1086
 * @CA_list_length: holds the number of CA certificate in CA_list
 
1087
 * @CRL_list: holds a list of CRLs.
 
1088
 * @CRL_list_length: the length of CRL list.
 
1089
 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
 
1090
 * @verify: will hold the certificate verification output.
 
1091
 *
 
1092
 * This function will try to verify the given certificate list and
 
1093
 * return its status.  If no flags are specified (0), this function
 
1094
 * will use the basicConstraints (2.5.29.19) PKIX extension. This
 
1095
 * means that only a certificate authority is allowed to sign a
 
1096
 * certificate.
 
1097
 *
 
1098
 * You must also check the peer's name in order to check if the verified
 
1099
 * certificate belongs to the actual peer.
 
1100
 *
 
1101
 * The certificate verification output will be put in @verify and will
 
1102
 * be one or more of the gnutls_certificate_status_t enumerated
 
1103
 * elements bitwise or'd.  For a more detailed verification status use
 
1104
 * gnutls_x509_crt_verify() per list element.
 
1105
 *
 
1106
 * GNUTLS_CERT_INVALID: the certificate chain is not valid.
 
1107
 *
 
1108
 * GNUTLS_CERT_REVOKED: a certificate in the chain has been revoked.
 
1109
 *
 
1110
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
1111
 *   negative error value.
 
1112
 **/
 
1113
int
 
1114
gnutls_x509_crt_list_verify (const gnutls_x509_crt_t * cert_list,
 
1115
                             int cert_list_length,
 
1116
                             const gnutls_x509_crt_t * CA_list,
 
1117
                             int CA_list_length,
 
1118
                             const gnutls_x509_crl_t * CRL_list,
 
1119
                             int CRL_list_length, unsigned int flags,
 
1120
                             unsigned int *verify)
 
1121
{
 
1122
  if (cert_list == NULL || cert_list_length == 0)
 
1123
    return GNUTLS_E_NO_CERTIFICATE_FOUND;
 
1124
 
 
1125
  /* Verify certificate 
 
1126
   */
 
1127
  *verify =
 
1128
    _gnutls_x509_verify_certificate (cert_list, cert_list_length,
 
1129
                                     CA_list, CA_list_length, CRL_list,
 
1130
                                     CRL_list_length, flags);
 
1131
 
 
1132
  return 0;
 
1133
}
 
1134
 
 
1135
/**
 
1136
 * gnutls_x509_crt_verify:
 
1137
 * @cert: is the certificate to be verified
 
1138
 * @CA_list: is one certificate that is considered to be trusted one
 
1139
 * @CA_list_length: holds the number of CA certificate in CA_list
 
1140
 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
 
1141
 * @verify: will hold the certificate verification output.
 
1142
 *
 
1143
 * This function will try to verify the given certificate and return
 
1144
 * its status.
 
1145
 *
 
1146
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
1147
 *   negative error value.
 
1148
 **/
 
1149
int
 
1150
gnutls_x509_crt_verify (gnutls_x509_crt_t cert,
 
1151
                        const gnutls_x509_crt_t * CA_list,
 
1152
                        int CA_list_length, unsigned int flags,
 
1153
                        unsigned int *verify)
 
1154
{
 
1155
  /* Verify certificate 
 
1156
   */
 
1157
  *verify =
 
1158
    _gnutls_x509_verify_certificate (&cert, 1,
 
1159
                                     CA_list, CA_list_length, NULL, 0, flags);
 
1160
  return 0;
 
1161
}
 
1162
 
 
1163
 
 
1164
 
 
1165
#ifdef ENABLE_PKI
 
1166
 
 
1167
/**
 
1168
 * gnutls_x509_crl_check_issuer:
 
1169
 * @crl: is the CRL to be checked
 
1170
 * @issuer: is the certificate of a possible issuer
 
1171
 *
 
1172
 * This function will check if the given CRL was issued by the given
 
1173
 * issuer certificate.  It will return true (1) if the given CRL was
 
1174
 * issued by the given issuer, and false (0) if not.
 
1175
 *
 
1176
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
1177
 *   negative error value.
 
1178
 **/
 
1179
int
 
1180
gnutls_x509_crl_check_issuer (gnutls_x509_crl_t cert,
 
1181
                              gnutls_x509_crt_t issuer)
 
1182
{
 
1183
  return is_crl_issuer (cert, issuer);
 
1184
}
 
1185
 
 
1186
/**
 
1187
 * gnutls_x509_crl_verify:
 
1188
 * @crl: is the crl to be verified
 
1189
 * @CA_list: is a certificate list that is considered to be trusted one
 
1190
 * @CA_list_length: holds the number of CA certificates in CA_list
 
1191
 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
 
1192
 * @verify: will hold the crl verification output.
 
1193
 *
 
1194
 * This function will try to verify the given crl and return its status.
 
1195
 * See gnutls_x509_crt_list_verify() for a detailed description of
 
1196
 * return values.
 
1197
 *
 
1198
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 
1199
 *   negative error value.
 
1200
 **/
 
1201
int
 
1202
gnutls_x509_crl_verify (gnutls_x509_crl_t crl,
 
1203
                        const gnutls_x509_crt_t * CA_list,
 
1204
                        int CA_list_length, unsigned int flags,
 
1205
                        unsigned int *verify)
 
1206
{
 
1207
  int ret;
 
1208
  /* Verify crl 
 
1209
   */
 
1210
  ret = _gnutls_verify_crl2 (crl, CA_list, CA_list_length, flags, verify);
 
1211
  if (ret < 0)
 
1212
    {
 
1213
      gnutls_assert ();
 
1214
      return ret;
 
1215
    }
 
1216
 
 
1217
  return 0;
 
1218
}
 
1219
 
 
1220
 
 
1221
/* The same as above, but here we've got a CRL.
 
1222
 */
 
1223
static int
 
1224
is_crl_issuer (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer_cert)
 
1225
{
 
1226
  gnutls_datum_t dn1 = { NULL, 0 }, dn2 =
 
1227
  {
 
1228
  NULL, 0};
 
1229
  int ret;
 
1230
 
 
1231
  ret = gnutls_x509_crl_get_raw_issuer_dn (crl, &dn1);
 
1232
  if (ret < 0)
 
1233
    {
 
1234
      gnutls_assert ();
 
1235
      goto cleanup;
 
1236
    }
 
1237
 
 
1238
  ret = gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
 
1239
  if (ret < 0)
 
1240
    {
 
1241
      gnutls_assert ();
 
1242
      return ret;
 
1243
    }
 
1244
 
 
1245
  ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
 
1246
 
 
1247
cleanup:
 
1248
  _gnutls_free_datum (&dn1);
 
1249
  _gnutls_free_datum (&dn2);
 
1250
 
 
1251
  return ret;
 
1252
}
 
1253
 
 
1254
static inline gnutls_x509_crt_t
 
1255
find_crl_issuer (gnutls_x509_crl_t crl,
 
1256
                 const gnutls_x509_crt_t * trusted_cas, int tcas_size)
 
1257
{
 
1258
  int i;
 
1259
 
 
1260
  /* this is serial search. 
 
1261
   */
 
1262
 
 
1263
  for (i = 0; i < tcas_size; i++)
 
1264
    {
 
1265
      if (is_crl_issuer (crl, trusted_cas[i]) == 1)
 
1266
        return trusted_cas[i];
 
1267
    }
 
1268
 
 
1269
  gnutls_assert ();
 
1270
  return NULL;
 
1271
}
 
1272
 
 
1273
/* 
 
1274
 * Returns only 0 or 1. If 1 it means that the CRL
 
1275
 * was successfuly verified.
 
1276
 *
 
1277
 * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
 
1278
 *
 
1279
 * Output will hold information about the verification
 
1280
 * procedure. 
 
1281
 */
 
1282
static int
 
1283
_gnutls_verify_crl2 (gnutls_x509_crl_t crl,
 
1284
                     const gnutls_x509_crt_t * trusted_cas,
 
1285
                     int tcas_size, unsigned int flags, unsigned int *output)
 
1286
{
 
1287
/* CRL is ignored for now */
 
1288
  gnutls_datum_t crl_signed_data = { NULL, 0 };
 
1289
  gnutls_datum_t crl_signature = { NULL, 0 };
 
1290
  gnutls_x509_crt_t issuer;
 
1291
  int result;
 
1292
 
 
1293
  if (output)
 
1294
    *output = 0;
 
1295
 
 
1296
  if (tcas_size >= 1)
 
1297
    issuer = find_crl_issuer (crl, trusted_cas, tcas_size);
 
1298
  else
 
1299
    {
 
1300
      gnutls_assert ();
 
1301
      if (output)
 
1302
        *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
 
1303
      return 0;
 
1304
    }
 
1305
 
 
1306
  /* issuer is not in trusted certificate
 
1307
   * authorities.
 
1308
   */
 
1309
  if (issuer == NULL)
 
1310
    {
 
1311
      gnutls_assert ();
 
1312
      if (output)
 
1313
        *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
 
1314
      return 0;
 
1315
    }
 
1316
 
 
1317
  if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN))
 
1318
    {
 
1319
      if (gnutls_x509_crt_get_ca_status (issuer, NULL) != 1)
 
1320
        {
 
1321
          gnutls_assert ();
 
1322
          if (output)
 
1323
            *output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
 
1324
          return 0;
 
1325
        }
 
1326
    }
 
1327
 
 
1328
  result =
 
1329
    _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data);
 
1330
  if (result < 0)
 
1331
    {
 
1332
      gnutls_assert ();
 
1333
      goto cleanup;
 
1334
    }
 
1335
 
 
1336
  result = _gnutls_x509_get_signature (crl->crl, "signature", &crl_signature);
 
1337
  if (result < 0)
 
1338
    {
 
1339
      gnutls_assert ();
 
1340
      goto cleanup;
 
1341
    }
 
1342
 
 
1343
  result =
 
1344
    _gnutls_x509_verify_signature (&crl_signed_data, NULL, &crl_signature,
 
1345
                                   issuer);
 
1346
  if (result == GNUTLS_E_PK_SIG_VERIFY_FAILED)
 
1347
    {
 
1348
      gnutls_assert ();
 
1349
      /* error. ignore it */
 
1350
      if (output)
 
1351
        *output |= GNUTLS_CERT_INVALID;
 
1352
      result = 0;
 
1353
    }
 
1354
  else if (result < 0)
 
1355
    {
 
1356
      gnutls_assert ();
 
1357
      goto cleanup;
 
1358
    }
 
1359
 
 
1360
  {
 
1361
    int sigalg;
 
1362
 
 
1363
    sigalg = gnutls_x509_crl_get_signature_algorithm (crl);
 
1364
 
 
1365
    if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
 
1366
         !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
 
1367
        ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
 
1368
         !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
 
1369
      {
 
1370
        if (output)
 
1371
          *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
 
1372
        result = 0;
 
1373
      }
 
1374
  }
 
1375
 
 
1376
cleanup:
 
1377
  _gnutls_free_datum (&crl_signed_data);
 
1378
  _gnutls_free_datum (&crl_signature);
 
1379
 
 
1380
  return result;
 
1381
}
 
1382
 
 
1383
#endif