Tizen 2.0 Release
[external/libgnutls26.git] / lib / x509 / verify.c
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       if ((ret =
650            _gnutls_verify_certificate2 (certificate_list[i - 1],
651                                         &certificate_list[i], 1, flags,
652                                         NULL, NULL)) == 0)
653         {
654           status |= GNUTLS_CERT_INVALID;
655           return status;
656         }
657     }
658
659   return 0;
660 }
661
662
663 /* Reads the digest information.
664  * we use DER here, although we should use BER. It works fine
665  * anyway.
666  */
667 static int
668 decode_ber_digest_info (const gnutls_datum_t * info,
669                         gnutls_mac_algorithm_t * hash,
670                         opaque * digest, int *digest_size)
671 {
672   ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
673   int result;
674   char str[1024];
675   int len;
676
677   if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
678                                      "GNUTLS.DigestInfo",
679                                      &dinfo)) != ASN1_SUCCESS)
680     {
681       gnutls_assert ();
682       return _gnutls_asn2err (result);
683     }
684
685   result = asn1_der_decoding (&dinfo, info->data, info->size, NULL);
686   if (result != ASN1_SUCCESS)
687     {
688       gnutls_assert ();
689       asn1_delete_structure (&dinfo);
690       return _gnutls_asn2err (result);
691     }
692
693   len = sizeof (str) - 1;
694   result = asn1_read_value (dinfo, "digestAlgorithm.algorithm", str, &len);
695   if (result != ASN1_SUCCESS)
696     {
697       gnutls_assert ();
698       asn1_delete_structure (&dinfo);
699       return _gnutls_asn2err (result);
700     }
701
702   *hash = _gnutls_x509_oid2mac_algorithm (str);
703
704   if (*hash == GNUTLS_MAC_UNKNOWN)
705     {
706
707       _gnutls_x509_log ("verify.c: HASH OID: %s\n", str);
708
709       gnutls_assert ();
710       asn1_delete_structure (&dinfo);
711       return GNUTLS_E_UNKNOWN_ALGORITHM;
712     }
713
714   len = sizeof (str) - 1;
715   result = asn1_read_value (dinfo, "digestAlgorithm.parameters", str, &len);
716   /* To avoid permitting garbage in the parameters field, either the
717      parameters field is not present, or it contains 0x05 0x00. */
718   if (!(result == ASN1_ELEMENT_NOT_FOUND ||
719         (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
720          memcmp (str, ASN1_NULL, ASN1_NULL_SIZE) == 0)))
721     {
722       gnutls_assert ();
723       asn1_delete_structure (&dinfo);
724       return GNUTLS_E_ASN1_GENERIC_ERROR;
725     }
726
727   result = asn1_read_value (dinfo, "digest", digest, digest_size);
728   if (result != ASN1_SUCCESS)
729     {
730       gnutls_assert ();
731       asn1_delete_structure (&dinfo);
732       return _gnutls_asn2err (result);
733     }
734
735   asn1_delete_structure (&dinfo);
736
737   return 0;
738 }
739
740 /* if hash==MD5 then we do RSA-MD5
741  * if hash==SHA then we do RSA-SHA
742  * params[0] is modulus
743  * params[1] is public key
744  */
745 static int
746 _pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
747                        const gnutls_datum_t * prehash,
748                        const gnutls_datum_t * signature, bigint_t * params,
749                        int params_len)
750 {
751   gnutls_mac_algorithm_t hash = GNUTLS_MAC_UNKNOWN;
752   int ret;
753   opaque digest[MAX_HASH_SIZE], md[MAX_HASH_SIZE], *cmp;
754   int digest_size;
755   digest_hd_st hd;
756   gnutls_datum_t decrypted;
757
758   ret =
759     _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, params_len, 1);
760   if (ret < 0)
761     {
762       gnutls_assert ();
763       return ret;
764     }
765
766   /* decrypted is a BER encoded data of type DigestInfo
767    */
768
769   digest_size = sizeof (digest);
770   if ((ret =
771        decode_ber_digest_info (&decrypted, &hash, digest, &digest_size)) != 0)
772     {
773       gnutls_assert ();
774       _gnutls_free_datum (&decrypted);
775       return ret;
776     }
777
778   _gnutls_free_datum (&decrypted);
779
780   if (digest_size != _gnutls_hash_get_algo_len (hash))
781     {
782       gnutls_assert ();
783       return GNUTLS_E_ASN1_GENERIC_ERROR;
784     }
785
786   if (prehash && prehash->data && prehash->size == digest_size)
787     {
788       cmp = prehash->data;
789     }
790   else
791     {
792       if (!text)
793         {
794           gnutls_assert ();
795           return GNUTLS_E_INVALID_REQUEST;
796         }
797
798       ret = _gnutls_hash_init (&hd, hash);
799       if (ret < 0)
800         {
801           gnutls_assert ();
802           return ret;
803         }
804
805       _gnutls_hash (&hd, text->data, text->size);
806       _gnutls_hash_deinit (&hd, md);
807
808       cmp = md;
809     }
810
811   if (memcmp (cmp, digest, digest_size) != 0)
812     {
813       gnutls_assert ();
814       return GNUTLS_E_PK_SIG_VERIFY_FAILED;
815     }
816
817   return 0;
818 }
819
820 /* Hashes input data and verifies a DSA signature.
821  */
822 static int
823 dsa_verify_sig (const gnutls_datum_t * text,
824                 const gnutls_datum_t * hash,
825                 const gnutls_datum_t * signature, bigint_t * params,
826                 int params_len)
827 {
828   int ret;
829   opaque _digest[MAX_HASH_SIZE];
830   gnutls_datum_t digest;
831   digest_hd_st hd;
832   gnutls_digest_algorithm_t algo;
833   unsigned int hash_len;
834
835   algo = _gnutls_dsa_q_to_hash (params[1], &hash_len);
836   if (hash)
837     {
838       /* SHA1 or better allowed */
839       if (!hash->data || hash->size < hash_len)
840         {
841           gnutls_assert();
842           _gnutls_debug_log("Hash size (%d) does not correspond to hash %s", (int)hash->size, gnutls_mac_get_name(algo));
843           
844           if (hash->size != 20)
845             return GNUTLS_E_PK_SIG_VERIFY_FAILED;
846         }
847       digest = *hash;
848     }
849   else
850     {
851
852       ret = _gnutls_hash_init (&hd, algo);
853       if (ret < 0)
854         {
855           gnutls_assert ();
856           return ret;
857         }
858
859       _gnutls_hash (&hd, text->data, text->size);
860       _gnutls_hash_deinit (&hd, _digest);
861
862       digest.data = _digest;
863       digest.size = _gnutls_hash_get_algo_len(algo);
864     }
865
866   ret = _gnutls_dsa_verify (&digest, signature, params, params_len);
867
868   return ret;
869 }
870
871 /* Verifies the signature data, and returns GNUTLS_E_PK_SIG_VERIFY_FAILED if 
872  * not verified, or 1 otherwise.
873  */
874 int
875 pubkey_verify_sig (const gnutls_datum_t * tbs,
876                    const gnutls_datum_t * hash,
877                    const gnutls_datum_t * signature,
878                    gnutls_pk_algorithm_t pk, bigint_t * issuer_params,
879                    int issuer_params_size)
880 {
881
882   switch (pk)
883     {
884     case GNUTLS_PK_RSA:
885
886       if (_pkcs1_rsa_verify_sig
887           (tbs, hash, signature, issuer_params, issuer_params_size) != 0)
888         {
889           gnutls_assert ();
890           return GNUTLS_E_PK_SIG_VERIFY_FAILED;
891         }
892
893       return 1;
894       break;
895
896     case GNUTLS_PK_DSA:
897       if (dsa_verify_sig
898           (tbs, hash, signature, issuer_params, issuer_params_size) != 0)
899         {
900           gnutls_assert ();
901           return GNUTLS_E_PK_SIG_VERIFY_FAILED;
902         }
903
904       return 1;
905       break;
906     default:
907       gnutls_assert ();
908       return GNUTLS_E_INTERNAL_ERROR;
909
910     }
911 }
912
913 gnutls_digest_algorithm_t
914 _gnutls_dsa_q_to_hash (bigint_t q, unsigned int* hash_len)
915 {
916   int bits = _gnutls_mpi_get_nbits (q);
917
918   if (bits <= 160)
919     {
920       if (hash_len) *hash_len = 20;
921       return GNUTLS_DIG_SHA1;
922     }
923   else if (bits <= 224)
924     {
925       if (hash_len) *hash_len = 28;
926       return GNUTLS_DIG_SHA256;
927     }
928   else
929     {
930       if (hash_len) *hash_len = 32;
931       return GNUTLS_DIG_SHA256;
932     }
933 }
934
935 /* This will return the appropriate hash to verify the given signature.
936  * If signature is NULL it will return an (or the) appropriate hash for
937  * the given parameters.
938  */
939 int
940 _gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
941                                const gnutls_datum_t * signature,
942                                gnutls_pk_algorithm pk,
943                                bigint_t * issuer_params,
944                                unsigned int issuer_params_size)
945 {
946   opaque digest[MAX_HASH_SIZE];
947   gnutls_datum_t decrypted;
948   int digest_size;
949   int ret;
950
951   switch (pk)
952     {
953     case GNUTLS_PK_DSA:
954
955       if (hash)
956         *hash = _gnutls_dsa_q_to_hash (issuer_params[1], NULL);
957
958       ret = 0;
959       break;
960     case GNUTLS_PK_RSA:
961       if (signature == NULL)
962         {                       /* return a sensible algorithm */
963           if (hash)
964             *hash = GNUTLS_DIG_SHA256;
965           return 0;
966         }
967
968       ret =
969         _gnutls_pkcs1_rsa_decrypt (&decrypted, signature,
970                                    issuer_params, issuer_params_size, 1);
971
972
973       if (ret < 0)
974         {
975           gnutls_assert ();
976           goto cleanup;
977         }
978
979       digest_size = sizeof (digest);
980       if ((ret =
981            decode_ber_digest_info (&decrypted, hash, digest,
982                                    &digest_size)) != 0)
983         {
984           gnutls_assert ();
985           _gnutls_free_datum (&decrypted);
986           goto cleanup;
987         }
988
989       _gnutls_free_datum (&decrypted);
990       if (digest_size != _gnutls_hash_get_algo_len (*hash))
991         {
992           gnutls_assert ();
993           ret = GNUTLS_E_ASN1_GENERIC_ERROR;
994           goto cleanup;
995         }
996
997       ret = 0;
998       break;
999
1000     default:
1001       gnutls_assert ();
1002       ret = GNUTLS_E_INTERNAL_ERROR;
1003     }
1004
1005 cleanup:
1006
1007   return ret;
1008
1009 }
1010
1011 /* verifies if the certificate is properly signed.
1012  * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success.
1013  * 
1014  * 'tbs' is the signed data
1015  * 'signature' is the signature!
1016  */
1017 int
1018 _gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
1019                                const gnutls_datum_t * hash,
1020                                const gnutls_datum_t * signature,
1021                                gnutls_x509_crt_t issuer)
1022 {
1023   bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE];
1024   int ret, issuer_params_size, i;
1025
1026   /* Read the MPI parameters from the issuer's certificate.
1027    */
1028   issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
1029   ret =
1030     _gnutls_x509_crt_get_mpis (issuer, issuer_params, &issuer_params_size);
1031   if (ret < 0)
1032     {
1033       gnutls_assert ();
1034       return ret;
1035     }
1036
1037   ret =
1038     pubkey_verify_sig (tbs, hash, signature,
1039                        gnutls_x509_crt_get_pk_algorithm (issuer, NULL),
1040                        issuer_params, issuer_params_size);
1041   if (ret < 0)
1042     {
1043       gnutls_assert ();
1044     }
1045
1046   /* release all allocated MPIs
1047    */
1048   for (i = 0; i < issuer_params_size; i++)
1049     {
1050       _gnutls_mpi_release (&issuer_params[i]);
1051     }
1052
1053   return ret;
1054 }
1055
1056 /* verifies if the certificate is properly signed.
1057  * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success.
1058  * 
1059  * 'tbs' is the signed data
1060  * 'signature' is the signature!
1061  */
1062 int
1063 _gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs,
1064                                        const gnutls_datum_t * signature,
1065                                        gnutls_x509_privkey_t issuer)
1066 {
1067   int ret;
1068
1069   ret = pubkey_verify_sig (tbs, NULL, signature, issuer->pk_algorithm,
1070                            issuer->params, issuer->params_size);
1071   if (ret < 0)
1072     {
1073       gnutls_assert ();
1074     }
1075
1076   return ret;
1077 }
1078
1079 /**
1080  * gnutls_x509_crt_list_verify:
1081  * @cert_list: is the certificate list to be verified
1082  * @cert_list_length: holds the number of certificate in cert_list
1083  * @CA_list: is the CA list which will be used in verification
1084  * @CA_list_length: holds the number of CA certificate in CA_list
1085  * @CRL_list: holds a list of CRLs.
1086  * @CRL_list_length: the length of CRL list.
1087  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1088  * @verify: will hold the certificate verification output.
1089  *
1090  * This function will try to verify the given certificate list and
1091  * return its status.  If no flags are specified (0), this function
1092  * will use the basicConstraints (2.5.29.19) PKIX extension. This
1093  * means that only a certificate authority is allowed to sign a
1094  * certificate.
1095  *
1096  * You must also check the peer's name in order to check if the verified
1097  * certificate belongs to the actual peer.
1098  *
1099  * The certificate verification output will be put in @verify and will
1100  * be one or more of the gnutls_certificate_status_t enumerated
1101  * elements bitwise or'd.  For a more detailed verification status use
1102  * gnutls_x509_crt_verify() per list element.
1103  *
1104  * GNUTLS_CERT_INVALID: the certificate chain is not valid.
1105  *
1106  * GNUTLS_CERT_REVOKED: a certificate in the chain has been revoked.
1107  *
1108  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1109  *   negative error value.
1110  **/
1111 int
1112 gnutls_x509_crt_list_verify (const gnutls_x509_crt_t * cert_list,
1113                              int cert_list_length,
1114                              const gnutls_x509_crt_t * CA_list,
1115                              int CA_list_length,
1116                              const gnutls_x509_crl_t * CRL_list,
1117                              int CRL_list_length, unsigned int flags,
1118                              unsigned int *verify)
1119 {
1120   if (cert_list == NULL || cert_list_length == 0)
1121     return GNUTLS_E_NO_CERTIFICATE_FOUND;
1122
1123   /* Verify certificate 
1124    */
1125   *verify =
1126     _gnutls_x509_verify_certificate (cert_list, cert_list_length,
1127                                      CA_list, CA_list_length, CRL_list,
1128                                      CRL_list_length, flags);
1129
1130   return 0;
1131 }
1132
1133 /**
1134  * gnutls_x509_crt_verify:
1135  * @cert: is the certificate to be verified
1136  * @CA_list: is one certificate that is considered to be trusted one
1137  * @CA_list_length: holds the number of CA certificate in CA_list
1138  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1139  * @verify: will hold the certificate verification output.
1140  *
1141  * This function will try to verify the given certificate and return
1142  * its status.
1143  *
1144  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1145  *   negative error value.
1146  **/
1147 int
1148 gnutls_x509_crt_verify (gnutls_x509_crt_t cert,
1149                         const gnutls_x509_crt_t * CA_list,
1150                         int CA_list_length, unsigned int flags,
1151                         unsigned int *verify)
1152 {
1153   /* Verify certificate 
1154    */
1155   *verify =
1156     _gnutls_x509_verify_certificate (&cert, 1,
1157                                      CA_list, CA_list_length, NULL, 0, flags);
1158   return 0;
1159 }
1160
1161
1162
1163 #ifdef ENABLE_PKI
1164
1165 /**
1166  * gnutls_x509_crl_check_issuer:
1167  * @crl: is the CRL to be checked
1168  * @issuer: is the certificate of a possible issuer
1169  *
1170  * This function will check if the given CRL was issued by the given
1171  * issuer certificate.  It will return true (1) if the given CRL was
1172  * issued by the given issuer, and false (0) if not.
1173  *
1174  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1175  *   negative error value.
1176  **/
1177 int
1178 gnutls_x509_crl_check_issuer (gnutls_x509_crl_t cert,
1179                               gnutls_x509_crt_t issuer)
1180 {
1181   return is_crl_issuer (cert, issuer);
1182 }
1183
1184 /**
1185  * gnutls_x509_crl_verify:
1186  * @crl: is the crl to be verified
1187  * @CA_list: is a certificate list that is considered to be trusted one
1188  * @CA_list_length: holds the number of CA certificates in CA_list
1189  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1190  * @verify: will hold the crl verification output.
1191  *
1192  * This function will try to verify the given crl and return its status.
1193  * See gnutls_x509_crt_list_verify() for a detailed description of
1194  * return values.
1195  *
1196  * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
1197  *   negative error value.
1198  **/
1199 int
1200 gnutls_x509_crl_verify (gnutls_x509_crl_t crl,
1201                         const gnutls_x509_crt_t * CA_list,
1202                         int CA_list_length, unsigned int flags,
1203                         unsigned int *verify)
1204 {
1205   int ret;
1206   /* Verify crl 
1207    */
1208   ret = _gnutls_verify_crl2 (crl, CA_list, CA_list_length, flags, verify);
1209   if (ret < 0)
1210     {
1211       gnutls_assert ();
1212       return ret;
1213     }
1214
1215   return 0;
1216 }
1217
1218
1219 /* The same as above, but here we've got a CRL.
1220  */
1221 static int
1222 is_crl_issuer (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer_cert)
1223 {
1224   gnutls_datum_t dn1 = { NULL, 0 }, dn2 =
1225   {
1226   NULL, 0};
1227   int ret;
1228
1229   ret = gnutls_x509_crl_get_raw_issuer_dn (crl, &dn1);
1230   if (ret < 0)
1231     {
1232       gnutls_assert ();
1233       goto cleanup;
1234     }
1235
1236   ret = gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
1237   if (ret < 0)
1238     {
1239       gnutls_assert ();
1240       return ret;
1241     }
1242
1243   ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
1244
1245 cleanup:
1246   _gnutls_free_datum (&dn1);
1247   _gnutls_free_datum (&dn2);
1248
1249   return ret;
1250 }
1251
1252 static inline gnutls_x509_crt_t
1253 find_crl_issuer (gnutls_x509_crl_t crl,
1254                  const gnutls_x509_crt_t * trusted_cas, int tcas_size)
1255 {
1256   int i;
1257
1258   /* this is serial search. 
1259    */
1260
1261   for (i = 0; i < tcas_size; i++)
1262     {
1263       if (is_crl_issuer (crl, trusted_cas[i]) == 1)
1264         return trusted_cas[i];
1265     }
1266
1267   gnutls_assert ();
1268   return NULL;
1269 }
1270
1271 /* 
1272  * Returns only 0 or 1. If 1 it means that the CRL
1273  * was successfuly verified.
1274  *
1275  * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
1276  *
1277  * Output will hold information about the verification
1278  * procedure. 
1279  */
1280 static int
1281 _gnutls_verify_crl2 (gnutls_x509_crl_t crl,
1282                      const gnutls_x509_crt_t * trusted_cas,
1283                      int tcas_size, unsigned int flags, unsigned int *output)
1284 {
1285 /* CRL is ignored for now */
1286   gnutls_datum_t crl_signed_data = { NULL, 0 };
1287   gnutls_datum_t crl_signature = { NULL, 0 };
1288   gnutls_x509_crt_t issuer;
1289   int result;
1290
1291   if (output)
1292     *output = 0;
1293
1294   if (tcas_size >= 1)
1295     issuer = find_crl_issuer (crl, trusted_cas, tcas_size);
1296   else
1297     {
1298       gnutls_assert ();
1299       if (output)
1300         *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
1301       return 0;
1302     }
1303
1304   /* issuer is not in trusted certificate
1305    * authorities.
1306    */
1307   if (issuer == NULL)
1308     {
1309       gnutls_assert ();
1310       if (output)
1311         *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
1312       return 0;
1313     }
1314
1315   if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN))
1316     {
1317       if (gnutls_x509_crt_get_ca_status (issuer, NULL) != 1)
1318         {
1319           gnutls_assert ();
1320           if (output)
1321             *output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
1322           return 0;
1323         }
1324     }
1325
1326   result =
1327     _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data);
1328   if (result < 0)
1329     {
1330       gnutls_assert ();
1331       goto cleanup;
1332     }
1333
1334   result = _gnutls_x509_get_signature (crl->crl, "signature", &crl_signature);
1335   if (result < 0)
1336     {
1337       gnutls_assert ();
1338       goto cleanup;
1339     }
1340
1341   result =
1342     _gnutls_x509_verify_signature (&crl_signed_data, NULL, &crl_signature,
1343                                    issuer);
1344   if (result == GNUTLS_E_PK_SIG_VERIFY_FAILED)
1345     {
1346       gnutls_assert ();
1347       /* error. ignore it */
1348       if (output)
1349         *output |= GNUTLS_CERT_INVALID;
1350       result = 0;
1351     }
1352   else if (result < 0)
1353     {
1354       gnutls_assert ();
1355       goto cleanup;
1356     }
1357
1358   {
1359     int sigalg;
1360
1361     sigalg = gnutls_x509_crl_get_signature_algorithm (crl);
1362
1363     if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
1364          !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
1365         ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
1366          !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
1367       {
1368         if (output)
1369           *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
1370         result = 0;
1371       }
1372   }
1373
1374 cleanup:
1375   _gnutls_free_datum (&crl_signed_data);
1376   _gnutls_free_datum (&crl_signature);
1377
1378   return result;
1379 }
1380
1381 #endif