removed gnutls_pubkey_get_verify_algorithm() and unnecessary internal APIs
[gnutls:gnutls.git] / lib / x509 / verify.c
1 /*
2  * Copyright (C) 2003-2014 Free Software Foundation, Inc.
3  * Copyright (C) 2013 Nikos Mavrogiannopoulos
4  * Copyright (C) 2014 Red Hat
5  *
6  * Author: Nikos Mavrogiannopoulos
7  *
8  * This file is part of GnuTLS.
9  *
10  * The GnuTLS is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * as published by the Free Software Foundation; either version 2.1 of
13  * the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>
22  *
23  */
24
25 /* All functions which relate to X.509 certificate verification stuff are
26  * included here
27  */
28
29 #include <gnutls_int.h>
30 #include <gnutls_errors.h>
31 #include <libtasn1.h>
32 #include <gnutls_global.h>
33 #include <gnutls_num.h>         /* MAX */
34 #include <gnutls_sig.h>
35 #include <gnutls_str.h>
36 #include <gnutls_datum.h>
37 #include <x509_int.h>
38 #include <common.h>
39 #include <gnutls_pk.h>
40 #include <stdbool.h>
41
42 /* Checks if two certs have the same name and the same key.  Return 1 on match. 
43  * If @is_ca is zero then this function is identical to _gnutls_check_if_same_cert()
44  */
45 bool
46 _gnutls_check_if_same_key(gnutls_x509_crt_t cert1,
47                           gnutls_x509_crt_t cert2,
48                           unsigned is_ca)
49 {
50         int ret;
51         bool result;
52
53         if (is_ca == 0)
54                 return _gnutls_check_if_same_cert(cert1, cert2);
55
56         ret = _gnutls_is_same_dn(cert1, cert2);
57         if (ret == 0)
58                 return 0;
59
60         if (cert1->raw_spki.size > 0 && (cert1->raw_spki.size == cert2->raw_spki.size) &&
61             (memcmp(cert1->raw_spki.data, cert2->raw_spki.data, cert1->raw_spki.size) == 0))
62                 result = 1;
63         else
64                 result = 0;
65
66         return result;
67 }
68
69 bool
70 _gnutls_check_if_same_key2(gnutls_x509_crt_t cert1,
71                            gnutls_datum_t * cert2bin)
72 {
73         int ret;
74         gnutls_x509_crt_t cert2;
75
76         ret = gnutls_x509_crt_init(&cert2);
77         if (ret < 0)
78                 return gnutls_assert_val(0);
79
80         ret = gnutls_x509_crt_import(cert2, cert2bin, GNUTLS_X509_FMT_DER);
81         if (ret < 0) {
82                 gnutls_x509_crt_deinit(cert2);
83                 return gnutls_assert_val(0);
84         }
85
86         ret = _gnutls_check_if_same_key(cert1, cert2, 1);
87
88         gnutls_x509_crt_deinit(cert2);
89         return ret;
90 }
91
92 bool
93 _gnutls_check_if_same_cert(gnutls_x509_crt_t cert1,
94                            gnutls_x509_crt_t cert2)
95 {
96         int ret;
97         bool result;
98
99         ret = _gnutls_is_same_dn(cert1, cert2);
100         if (ret == 0)
101                 return 0;
102
103         if ((cert1->der.size == cert2->der.size) &&
104             (memcmp(cert1->der.data, cert2->der.data, cert1->der.size) == 0))
105                 result = 1;
106         else
107                 result = 0;
108
109         return result;
110 }
111
112 bool
113 _gnutls_check_if_same_cert2(gnutls_x509_crt_t cert1,
114                             gnutls_datum_t * cert2bin)
115 {
116         bool result;
117
118         if ((cert1->der.size == cert2bin->size) &&
119             (memcmp(cert1->der.data, cert2bin->data, cert1->der.size) == 0))
120                 result = 1;
121         else
122                 result = 0;
123
124         return result;
125 }
126
127 /* Checks if the issuer of a certificate is a
128  * Certificate Authority, or if the certificate is the same
129  * as the issuer (and therefore it doesn't need to be a CA).
130  *
131  * Returns true or false, if the issuer is a CA,
132  * or not.
133  */
134 static bool
135 check_if_ca(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
136             unsigned int *max_path, unsigned int flags)
137 {
138         gnutls_datum_t cert_signed_data = { NULL, 0 };
139         gnutls_datum_t issuer_signed_data = { NULL, 0 };
140         gnutls_datum_t cert_signature = { NULL, 0 };
141         gnutls_datum_t issuer_signature = { NULL, 0 };
142         int pathlen = -1, ret;
143         bool result;
144         unsigned int ca_status = 0;
145
146         /* Check if the issuer is the same with the
147          * certificate. This is added in order for trusted
148          * certificates to be able to verify themselves.
149          */
150
151         ret =
152             _gnutls_x509_get_signed_data(issuer->cert, &issuer->der, "tbsCertificate",
153                                          &issuer_signed_data);
154         if (ret < 0) {
155                 gnutls_assert();
156                 goto fail;
157         }
158
159         ret =
160             _gnutls_x509_get_signed_data(cert->cert, &cert->der, "tbsCertificate",
161                                          &cert_signed_data);
162         if (ret < 0) {
163                 gnutls_assert();
164                 goto fail;
165         }
166
167         ret =
168             _gnutls_x509_get_signature(issuer->cert, "signature",
169                                        &issuer_signature);
170         if (ret < 0) {
171                 gnutls_assert();
172                 goto fail;
173         }
174
175         ret =
176             _gnutls_x509_get_signature(cert->cert, "signature",
177                                        &cert_signature);
178         if (ret < 0) {
179                 gnutls_assert();
180                 goto fail;
181         }
182
183         /* If the subject certificate is the same as the issuer
184          * return true.
185          */
186         if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
187                 if (cert_signed_data.size == issuer_signed_data.size) {
188                         if ((memcmp
189                              (cert_signed_data.data,
190                               issuer_signed_data.data,
191                               cert_signed_data.size) == 0)
192                             && (cert_signature.size ==
193                                 issuer_signature.size)
194                             &&
195                             (memcmp
196                              (cert_signature.data, issuer_signature.data,
197                               cert_signature.size) == 0)) {
198                                 result = 1;
199                                 goto cleanup;
200                         }
201                 }
202
203         ret =
204             gnutls_x509_crt_get_basic_constraints(issuer, NULL, &ca_status,
205                                                   &pathlen);
206         if (ret < 0) {
207                 ca_status = 0;
208                 pathlen = -1;
209         }
210
211         if (ca_status != 0 && pathlen != -1) {
212                 if ((unsigned) pathlen < *max_path)
213                         *max_path = pathlen;
214         }
215
216         if (ca_status != 0) {
217                 result = 1;
218                 goto cleanup;
219         }
220         /* Handle V1 CAs that do not have a basicConstraint, but accept
221            these certs only if the appropriate flags are set. */
222         else if ((ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) &&
223                  ((flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT) ||
224                   (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT) &&
225                    (gnutls_x509_crt_check_issuer(issuer, issuer) != 0)))) {
226                 gnutls_assert();
227                 result = 1;
228                 goto cleanup;
229         } else {
230                 gnutls_assert();
231         }
232
233  fail:
234         result = 0;
235
236  cleanup:
237         _gnutls_free_datum(&cert_signed_data);
238         _gnutls_free_datum(&issuer_signed_data);
239         _gnutls_free_datum(&cert_signature);
240         _gnutls_free_datum(&issuer_signature);
241         return result;
242 }
243
244
245 /* This function checks if cert's issuer is issuer.
246  * This does a straight (DER) compare of the issuer/subject DN fields in
247  * the given certificates, as well as check the authority key ID.
248  *
249  * Returns 1 if they match and (0) if they don't match. 
250  */
251 static bool is_issuer(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer)
252 {
253         uint8_t id1[MAX_KEY_ID_SIZE];
254         uint8_t id2[MAX_KEY_ID_SIZE];
255         size_t id1_size;
256         size_t id2_size;
257         int ret;
258         bool result;
259
260         if (_gnutls_x509_compare_raw_dn
261             (&cert->raw_issuer_dn, &issuer->raw_dn) != 0)
262                 result = 1;
263         else
264                 result = 0;
265
266         if (result != 0) {
267                 /* check if the authority key identifier matches the subject key identifier
268                  * of the issuer */
269                 id1_size = sizeof(id1);
270
271                 ret =
272                     gnutls_x509_crt_get_authority_key_id(cert, id1,
273                                                          &id1_size, NULL);
274                 if (ret < 0) {
275                         /* If there is no authority key identifier in the
276                          * certificate, assume they match */
277                         result = 1;
278                         goto cleanup;
279                 }
280
281                 id2_size = sizeof(id2);
282                 ret =
283                     gnutls_x509_crt_get_subject_key_id(issuer, id2,
284                                                        &id2_size, NULL);
285                 if (ret < 0) {
286                         /* If there is no subject key identifier in the
287                          * issuer certificate, assume they match */
288                         result = 1;
289                         gnutls_assert();
290                         goto cleanup;
291                 }
292
293                 if (id1_size == id2_size
294                     && memcmp(id1, id2, id1_size) == 0)
295                         result = 1;
296                 else
297                         result = 0;
298         }
299
300       cleanup:
301         return result;
302 }
303
304 /* Check if the given certificate is the issuer of the CRL.
305  * Returns 1 on success and 0 otherwise.
306  */
307 static bool is_crl_issuer(gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer)
308 {
309         if (_gnutls_x509_compare_raw_dn
310             (&crl->raw_issuer_dn, &issuer->raw_dn) != 0)
311                 return 1;
312         else
313                 return 0;
314 }
315
316 /* Checks if the DN of two certificates is the same.
317  * Returns 1 if they match and (0) if they don't match. Otherwise
318  * a negative error code is returned to indicate error.
319  */
320 bool _gnutls_is_same_dn(gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2)
321 {
322         if (_gnutls_x509_compare_raw_dn(&cert1->raw_dn, &cert2->raw_dn) !=
323             0)
324                 return 1;
325         else
326                 return 0;
327 }
328
329 /* Finds an issuer of the certificate. If multiple issuers
330  * are present, returns one that is activated and not expired.
331  */
332 static inline gnutls_x509_crt_t
333 find_issuer(gnutls_x509_crt_t cert,
334             const gnutls_x509_crt_t * trusted_cas, int tcas_size)
335 {
336         int i;
337         gnutls_x509_crt_t issuer = NULL;
338
339         /* this is serial search. 
340          */
341         for (i = 0; i < tcas_size; i++) {
342                 if (is_issuer(cert, trusted_cas[i]) != 0) {
343                         if (issuer == NULL) {
344                                 issuer = trusted_cas[i];
345                         } else {
346                                 time_t now = gnutls_time(0);
347
348                                 if (now <
349                                     gnutls_x509_crt_get_expiration_time
350                                     (trusted_cas[i])
351                                     && now >=
352                                     gnutls_x509_crt_get_activation_time
353                                     (trusted_cas[i])) {
354                                         issuer = trusted_cas[i];
355                                 }
356                         }
357                 }
358         }
359
360         return issuer;
361 }
362
363 static unsigned int check_time_status(gnutls_x509_crt_t crt, time_t now)
364 {
365         int status = 0;
366         time_t t;
367
368         t = gnutls_x509_crt_get_activation_time(crt);
369         if (t == (time_t) - 1 || now < t) {
370                 status |= GNUTLS_CERT_NOT_ACTIVATED;
371                 status |= GNUTLS_CERT_INVALID;
372                 return status;
373         }
374
375         t = gnutls_x509_crt_get_expiration_time(crt);
376         if (t == (time_t) - 1 || now > t) {
377                 status |= GNUTLS_CERT_EXPIRED;
378                 status |= GNUTLS_CERT_INVALID;
379                 return status;
380         }
381
382         return 0;
383 }
384
385 static
386 int is_broken_allowed(gnutls_sign_algorithm_t sig, unsigned int flags)
387 {
388         if ((sig == GNUTLS_SIGN_RSA_MD2)
389             && (flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2))
390                 return 1;
391         if ((sig == GNUTLS_SIGN_RSA_MD5)
392             && (flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5))
393                 return 1;
394         return 0;
395 }
396
397 #define CASE_SEC_PARAM(profile, level) \
398         case profile: \
399                 sym_bits = gnutls_sec_param_to_symmetric_bits(level); \
400                 hash = gnutls_sign_get_hash_algorithm(sigalg); \
401                 entry = mac_to_entry(hash); \
402                 if (hash <= 0 || entry == NULL) { \
403                         _gnutls_debug_log(#level": certificate's signature hash is unknown\n"); \
404                         return gnutls_assert_val(0); \
405                 } \
406                 if (entry->secure == 0 || entry->output_size*8/2 < sym_bits) { \
407                         _gnutls_debug_log(#level": certificate's signature hash strength is unacceptable (is %u bits, needed %u)\n", entry->output_size*8/2, sym_bits); \
408                         return gnutls_assert_val(0); \
409                 } \
410                 sp = gnutls_pk_bits_to_sec_param(pkalg, bits); \
411                 if (sp < level) { \
412                         _gnutls_debug_log(#level": certificate's security level is unacceptable\n"); \
413                         return gnutls_assert_val(0); \
414                 } \
415                 sp = gnutls_pk_bits_to_sec_param(issuer_pkalg, issuer_bits); \
416                 if (sp < level) { \
417                         _gnutls_debug_log(#level": certificate's issuer security level is unacceptable\n"); \
418                         return gnutls_assert_val(0); \
419                 } \
420                 break;
421
422 /* Checks whether the provided certificates are acceptable
423  * according to verification profile specified.
424  *
425  * @crt: a certificate
426  * @issuer: the certificates issuer (allowed to be NULL)
427  * @sigalg: the signature algorithm used
428  * @flags: the specified verification flags
429  */
430 static bool is_level_acceptable(
431         gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
432         gnutls_sign_algorithm_t sigalg, unsigned flags)
433 {
434 gnutls_certificate_verification_profiles_t profile = GNUTLS_VFLAGS_TO_PROFILE(flags);
435 const mac_entry_st *entry;
436 int issuer_pkalg, pkalg, ret;
437 unsigned bits = 0, issuer_bits = 0, sym_bits = 0;
438 gnutls_pk_params_st params;
439 gnutls_sec_param_t sp;
440
441 int hash;
442
443         if (profile == 0)
444                 return 1;
445
446         pkalg = gnutls_x509_crt_get_pk_algorithm(crt, &bits);
447         if (pkalg < 0)
448                 return gnutls_assert_val(0);
449
450         issuer_pkalg = gnutls_x509_crt_get_pk_algorithm(crt, &issuer_bits);
451         if (issuer_pkalg < 0)
452                 return gnutls_assert_val(0);
453
454         switch (profile) {
455                 CASE_SEC_PARAM(GNUTLS_PROFILE_VERY_WEAK, GNUTLS_SEC_PARAM_VERY_WEAK);
456                 CASE_SEC_PARAM(GNUTLS_PROFILE_LOW, GNUTLS_SEC_PARAM_LOW);
457                 CASE_SEC_PARAM(GNUTLS_PROFILE_LEGACY, GNUTLS_SEC_PARAM_LEGACY);
458                 CASE_SEC_PARAM(GNUTLS_PROFILE_MEDIUM, GNUTLS_SEC_PARAM_MEDIUM);
459                 CASE_SEC_PARAM(GNUTLS_PROFILE_HIGH, GNUTLS_SEC_PARAM_HIGH);
460                 CASE_SEC_PARAM(GNUTLS_PROFILE_ULTRA, GNUTLS_SEC_PARAM_ULTRA);
461                 case GNUTLS_PROFILE_SUITEB128:
462                 case GNUTLS_PROFILE_SUITEB192: {
463                         unsigned curve, issuer_curve;
464
465                         /* check suiteB params validity: rfc5759 */
466
467                         if (gnutls_x509_crt_get_version(crt) != 3) {
468                                 _gnutls_debug_log("SUITEB: certificate uses an unacceptable version number\n");
469                                 return gnutls_assert_val(0);
470                         }
471
472                         if (sigalg != GNUTLS_SIGN_ECDSA_SHA256 && sigalg != GNUTLS_SIGN_ECDSA_SHA384) {
473                                 _gnutls_debug_log("SUITEB: certificate is not signed using ECDSA-SHA256 or ECDSA-SHA384\n");
474                                 return gnutls_assert_val(0);
475                         }
476
477                         if (pkalg != GNUTLS_PK_EC) {
478                                 _gnutls_debug_log("SUITEB: certificate does not contain ECC parameters\n");
479                                 return gnutls_assert_val(0);
480                         }
481
482                         if (issuer_pkalg != GNUTLS_PK_EC) {
483                                 _gnutls_debug_log("SUITEB: certificate's issuer does not have ECC parameters\n");
484                                 return gnutls_assert_val(0);
485                         }
486
487                         ret = _gnutls_x509_crt_get_mpis(crt, &params);
488                         if (ret < 0) {
489                                 _gnutls_debug_log("SUITEB: cannot read certificate params\n");
490                                 return gnutls_assert_val(0);
491                         }
492
493                         curve = params.flags;
494                         gnutls_pk_params_release(&params);
495
496                         if (curve != GNUTLS_ECC_CURVE_SECP256R1 &&
497                                 curve != GNUTLS_ECC_CURVE_SECP384R1) {
498                                 _gnutls_debug_log("SUITEB: certificate's ECC params do not contain SECP256R1 or SECP384R1\n");
499                                 return gnutls_assert_val(0);
500                         }
501
502                         if (profile == GNUTLS_PROFILE_SUITEB192) {
503                                 if (curve != GNUTLS_ECC_CURVE_SECP384R1) {
504                                         _gnutls_debug_log("SUITEB192: certificate does not use SECP384R1\n");
505                                         return gnutls_assert_val(0);
506                                 }
507                         }
508
509                         if (issuer != NULL) {
510                                 if (gnutls_x509_crt_get_version(issuer) != 3) {
511                                         _gnutls_debug_log("SUITEB: certificate's issuer uses an unacceptable version number\n");
512                                         return gnutls_assert_val(0);
513                                 }
514
515                                 ret = _gnutls_x509_crt_get_mpis(issuer, &params);
516                                 if (ret < 0) {
517                                         _gnutls_debug_log("SUITEB: cannot read certificate params\n");
518                                         return gnutls_assert_val(0);
519                                 }
520
521                                 issuer_curve = params.flags;
522                                 gnutls_pk_params_release(&params);
523
524                                 if (issuer_curve != GNUTLS_ECC_CURVE_SECP256R1 &&
525                                         issuer_curve != GNUTLS_ECC_CURVE_SECP384R1) {
526                                         _gnutls_debug_log("SUITEB: certificate's issuer ECC params do not contain SECP256R1 or SECP384R1\n");
527                                         return gnutls_assert_val(0);
528                                 }
529
530                                 if (issuer_curve < curve) {
531                                         _gnutls_debug_log("SUITEB: certificate's issuer ECC params are weaker than the certificate's\n");
532                                         return gnutls_assert_val(0);
533                                 }
534
535                                 if (sigalg == GNUTLS_SIGN_ECDSA_SHA256 && 
536                                         issuer_curve == GNUTLS_ECC_CURVE_SECP384R1) {
537                                         _gnutls_debug_log("SUITEB: certificate is signed with ECDSA-SHA256 when using SECP384R1\n");
538                                         return gnutls_assert_val(0);
539                                 }
540                         }
541
542                         break;
543                 }
544         }
545
546         return 1;
547 }
548
549 /* 
550  * Verifies the given certificate against a certificate list of
551  * trusted CAs.
552  *
553  * Returns only 0 or 1. If 1 it means that the certificate 
554  * was successfuly verified.
555  *
556  * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
557  *
558  * Output will hold some extra information about the verification
559  * procedure. Issuer will hold the actual issuer from the trusted list.
560  */
561 static bool
562 verify_crt(gnutls_x509_crt_t cert,
563                             const gnutls_x509_crt_t * trusted_cas,
564                             int tcas_size, unsigned int flags,
565                             unsigned int *output,
566                             gnutls_x509_crt_t * _issuer,
567                             time_t now,
568                             unsigned int *max_path,
569                             bool end_cert,
570                             gnutls_x509_name_constraints_t nc,
571                             gnutls_verify_output_function func)
572 {
573         gnutls_datum_t cert_signed_data = { NULL, 0 };
574         gnutls_datum_t cert_signature = { NULL, 0 };
575         gnutls_x509_crt_t issuer = NULL;
576         int issuer_version, hash_algo;
577         bool result = 1;
578         const mac_entry_st * me;
579         unsigned int out = 0, usage;
580         int sigalg, ret;
581
582         if (output)
583                 *output = 0;
584
585         if (*max_path == 0) {
586                 out |=
587                     GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE |
588                     GNUTLS_CERT_INVALID;
589                 gnutls_assert();
590                 result = 0;
591                 /* bail immediately, to avoid inconistency  */
592                 goto cleanup;
593         }
594         (*max_path)--;
595
596         if (tcas_size >= 1)
597                 issuer = find_issuer(cert, trusted_cas, tcas_size);
598
599         if (_issuer != NULL)
600                 *_issuer = issuer;
601
602         ret =
603             _gnutls_x509_get_signed_data(cert->cert, &cert->der, "tbsCertificate",
604                                          &cert_signed_data);
605         if (ret < 0) {
606                 result = 0;
607                 gnutls_assert();
608                 cert_signed_data.data = NULL;
609         }
610
611         ret =
612             _gnutls_x509_get_signature(cert->cert, "signature",
613                                        &cert_signature);
614         if (ret < 0) {
615                 result = 0;
616                 gnutls_assert();
617                 cert_signature.data = NULL;
618         }
619
620         ret =
621             _gnutls_x509_get_signature_algorithm(cert->cert,
622                                                  "signatureAlgorithm.algorithm");
623         if (ret < 0) {
624                 result = 0;
625                 gnutls_assert();
626         }
627         sigalg = ret;
628
629         /* issuer is not in trusted certificate
630          * authorities.
631          */
632         if (issuer == NULL) {
633                 out |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
634                 gnutls_assert();
635                 result = 0;
636         } else {
637                 if (nc != NULL) {
638                         /* append the issuer's constraints */
639                         ret = gnutls_x509_crt_get_name_constraints(issuer, nc, 
640                                 GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND, NULL);
641                         if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
642  nc_fail:
643                                 out |=
644                                     GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE |
645                                     GNUTLS_CERT_INVALID;
646                                 gnutls_assert();
647                                 result = 0;
648                                 goto nc_done;
649                         }
650
651                         /* only check name constraints in server certificates, not CAs */
652                         if (end_cert != 0) {
653                                 ret = gnutls_x509_name_constraints_check_crt(nc, GNUTLS_SAN_DNSNAME, cert);
654                                 if (ret == 0) {
655                                         gnutls_assert();
656                                         goto nc_fail;
657                                 }
658
659                                 ret = gnutls_x509_name_constraints_check_crt(nc, GNUTLS_SAN_RFC822NAME, cert);
660                                 if (ret == 0) {
661                                         gnutls_assert();
662                                         goto nc_fail;
663                                 }
664
665                                 ret = gnutls_x509_name_constraints_check_crt(nc, GNUTLS_SAN_DN, cert);
666                                 if (ret == 0) {
667                                         gnutls_assert();
668                                         goto nc_fail;
669                                 }
670
671                                 ret = gnutls_x509_name_constraints_check_crt(nc, GNUTLS_SAN_URI, cert);
672                                 if (ret == 0) {
673                                         gnutls_assert();
674                                         goto nc_fail;
675                                 }
676
677                                 ret = gnutls_x509_name_constraints_check_crt(nc, GNUTLS_SAN_IPADDRESS, cert);
678                                 if (ret == 0) {
679                                         gnutls_assert();
680                                         goto nc_fail;
681                                 }
682                         }
683                 }
684  nc_done:
685
686                 issuer_version = gnutls_x509_crt_get_version(issuer);
687
688                 if (issuer_version < 0) {
689                         gnutls_assert();
690                         result = 0;
691                 } else if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) &&
692                            ((flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT)
693                             || issuer_version != 1)) {
694                         if (check_if_ca(cert, issuer, max_path, flags) != 1) {
695                                 gnutls_assert();
696                                 out |=
697                                     GNUTLS_CERT_SIGNER_NOT_CA |
698                                     GNUTLS_CERT_INVALID;
699                                 result = 0;
700                         }
701
702                         ret =
703                             gnutls_x509_crt_get_key_usage(issuer, &usage, NULL);
704                         if (ret >= 0) {
705                                 if (!(usage & GNUTLS_KEY_KEY_CERT_SIGN)) {
706                                         gnutls_assert();
707                                         out |=
708                                             GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE
709                                             | GNUTLS_CERT_INVALID;
710                                         result = 0;
711                                 }
712                         }
713                 }
714
715                 if (sigalg >= 0) {
716                         hash_algo = gnutls_sign_get_hash_algorithm(sigalg);
717                         me = mac_to_entry(hash_algo);
718                 } else {
719                         me = NULL;
720                 }
721
722                 if (me == NULL) {
723                         gnutls_assert();
724                         result = 0;
725                 } else if (cert_signed_data.data != NULL &&
726                            cert_signature.data != NULL) {
727                         ret =
728                             _gnutls_x509_verify_data(me,
729                                                      &cert_signed_data,
730                                                      &cert_signature,
731                                                      issuer);
732                         if (ret == GNUTLS_E_PK_SIG_VERIFY_FAILED) {
733                                 gnutls_assert();
734                                 out |=
735                                     GNUTLS_CERT_INVALID |
736                                     GNUTLS_CERT_SIGNATURE_FAILURE;
737                                 /* error. ignore it */
738                                 result = 0;
739                         } else if (ret < 0) {
740                                 result = 0;
741                                 gnutls_assert();
742                         }
743                 }
744         }
745
746         if (sigalg >= 0) {
747                 if (is_level_acceptable(cert, issuer, sigalg, flags) == 0) {
748                         gnutls_assert();
749                         out |=
750                             GNUTLS_CERT_INSECURE_ALGORITHM |
751                             GNUTLS_CERT_INVALID;
752                         result = 0;
753                 }
754
755                 /* If the certificate is not self signed check if the algorithms
756                  * used are secure. If the certificate is self signed it doesn't
757                  * really matter.
758                  */
759                 if (gnutls_sign_is_secure(sigalg) == 0 &&
760                     is_broken_allowed(sigalg, flags) == 0 &&
761                     is_issuer(cert, cert) == 0) {
762                         gnutls_assert();
763                         out |=
764                             GNUTLS_CERT_INSECURE_ALGORITHM |
765                             GNUTLS_CERT_INVALID;
766                         result = 0;
767                 }
768         }
769
770         /* Check activation/expiration times
771          */
772         if (!(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
773                 /* check the time of the issuer first */
774                 if (issuer != NULL &&
775                     !(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS)) {
776                         out |= check_time_status(issuer, now);
777                         if (out != 0) {
778                                 gnutls_assert();
779                                 result = 0;
780                         }
781                 }
782
783                 out |= check_time_status(cert, now);
784                 if (out != 0) {
785                         gnutls_assert();
786                         result = 0;
787                 }
788         }
789
790       cleanup:
791         if (output)
792                 *output |= out;
793
794         if (func) {
795                 if (result == 0) {
796                         out |= GNUTLS_CERT_INVALID;
797                 }
798                 func(cert, issuer, NULL, out);
799         }
800         _gnutls_free_datum(&cert_signed_data);
801         _gnutls_free_datum(&cert_signature);
802
803         return result;
804 }
805
806 /**
807  * gnutls_x509_crt_check_issuer:
808  * @cert: is the certificate to be checked
809  * @issuer: is the certificate of a possible issuer
810  *
811  * This function will check if the given certificate was issued by the
812  * given issuer. It checks the DN fields and the authority
813  * key identifier and subject key identifier fields match.
814  *
815  * If the same certificate is provided at the @cert and @issuer fields,
816  * it will check whether the certificate is self-signed.
817  *
818  * Returns: It will return true (1) if the given certificate is issued
819  *   by the given issuer, and false (0) if not.  
820  **/
821 int
822 gnutls_x509_crt_check_issuer(gnutls_x509_crt_t cert,
823                              gnutls_x509_crt_t issuer)
824 {
825         return is_issuer(cert, issuer);
826 }
827
828 /* Verify X.509 certificate chain.
829  *
830  * Note that the return value is an OR of GNUTLS_CERT_* elements.
831  *
832  * This function verifies a X.509 certificate list. The certificate
833  * list should lead to a trusted certificate in order to be trusted.
834  */
835 unsigned int
836 _gnutls_verify_crt_status(const gnutls_x509_crt_t * certificate_list,
837                                 int clist_size,
838                                 const gnutls_x509_crt_t * trusted_cas,
839                                 int tcas_size,
840                                 unsigned int flags,
841                                 const char *purpose,
842                                 gnutls_verify_output_function func)
843 {
844         int i = 0, ret;
845         unsigned int status = 0, output;
846         time_t now = gnutls_time(0);
847         gnutls_x509_crt_t issuer = NULL;
848         unsigned int max_path;
849         gnutls_x509_name_constraints_t nc;
850
851         if (clist_size > 1) {
852                 /* Check if the last certificate in the path is self signed.
853                  * In that case ignore it (a certificate is trusted only if it
854                  * leads to a trusted party by us, not the server's).
855                  *
856                  * This prevents from verifying self signed certificates against
857                  * themselves. This (although not bad) caused verification
858                  * failures on some root self signed certificates that use the
859                  * MD2 algorithm.
860                  */
861                 if (gnutls_x509_crt_check_issuer
862                     (certificate_list[clist_size - 1],
863                      certificate_list[clist_size - 1]) != 0) {
864                         clist_size--;
865                 }
866         }
867
868         /* We want to shorten the chain by removing the cert that matches
869          * one of the certs we trust and all the certs after that i.e. if
870          * cert chain is A signed-by B signed-by C signed-by D (signed-by
871          * self-signed E but already removed above), and we trust B, remove
872          * B, C and D. */
873         if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
874                 i = 0;          /* also replace the first one */
875         else
876                 i = 1;          /* do not replace the first one */
877
878         for (; i < clist_size; i++) {
879                 int j;
880
881                 for (j = 0; j < tcas_size; j++) {
882                         /* we check for a certificate that may not be identical with the one
883                          * sent by the client, but will have the same name and key. That is
884                          * because it can happen that a CA certificate is upgraded from intermediate
885                          * CA to self-signed CA at some point. */
886                         if (_gnutls_check_if_same_key
887                             (certificate_list[i], trusted_cas[j], i) != 0) {
888                                 /* explicit time check for trusted CA that we remove from
889                                  * list. GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS
890                                  */
891
892                                 if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) &&
893                                         !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
894                                         status |=
895                                             check_time_status(trusted_cas[j],
896                                                        now);
897                                         if (status != 0) {
898                                                 if (func)
899                                                         func(certificate_list[i], trusted_cas[j], NULL, status);
900                                                 return status;
901                                         }
902                                 }
903
904                                 if (func)
905                                         func(certificate_list[i],
906                                              trusted_cas[j], NULL, status);
907                                 clist_size = i;
908                                 break;
909                         }
910                 }
911                 /* clist_size may have been changed which gets out of loop */
912         }
913
914         if (clist_size == 0) {
915                 /* The certificate is already present in the trusted certificate list.
916                  * Nothing to verify. */
917                 return status;
918         }
919
920         ret = gnutls_x509_name_constraints_init(&nc);
921         if (ret < 0) {
922                 gnutls_assert();
923                 status |= GNUTLS_CERT_INVALID;
924                 return status;
925         }
926
927         /* Verify the last certificate in the certificate path
928          * against the trusted CA certificate list.
929          *
930          * If no CAs are present returns CERT_INVALID. Thus works
931          * in self signed etc certificates.
932          */
933         output = 0;
934         max_path = MAX_VERIFY_DEPTH;
935
936         ret = verify_crt(certificate_list[clist_size - 1],
937                                           trusted_cas, tcas_size, flags,
938                                           &output, &issuer, now, &max_path,
939                                           clist_size==1?1:0, nc, func);
940         if (ret != 1) {
941                 /* if the last certificate in the certificate
942                  * list is invalid, then the certificate is not
943                  * trusted.
944                  */
945                 gnutls_assert();
946                 status |= output;
947                 status |= GNUTLS_CERT_INVALID;
948                 goto cleanup;
949         }
950
951         /* Verify the certificate path (chain)
952          */
953         for (i = clist_size - 1; i > 0; i--) {
954                 output = 0;
955                 if (i - 1 < 0)
956                         break;
957
958                 if (purpose != NULL) {
959                         ret = _gnutls_check_key_purpose(certificate_list[i], purpose, 1);
960                         if (ret != 1) {
961                                 gnutls_assert();
962                                 status |= GNUTLS_CERT_INVALID;
963                                 status |= GNUTLS_CERT_PURPOSE_MISMATCH;
964
965                                 if (func)
966                                         func(certificate_list[i-1],
967                                              certificate_list[i], NULL, status);
968                                 goto cleanup;
969                         }
970                 }
971
972                 /* note that here we disable this V1 CA flag. So that no version 1
973                  * certificates can exist in a supplied chain.
974                  */
975                 if (!(flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT)) {
976                         flags |= GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT;
977                 }
978
979                 if ((ret =
980                      verify_crt(certificate_list[i - 1],
981                                                  &certificate_list[i], 1,
982                                                  flags, &output, NULL, now,
983                                                  &max_path, i==1?1:0, nc, func)) != 1) {
984                         gnutls_assert();
985                         status |= output;
986                         status |= GNUTLS_CERT_INVALID;
987                         goto cleanup;
988                 }
989         }
990
991 cleanup:
992         gnutls_x509_name_constraints_deinit(nc);
993         return status;
994 }
995
996 /* Returns true if the provided purpose is in accordance with the certificate.
997  */
998 bool _gnutls_check_key_purpose(gnutls_x509_crt_t cert, const char *purpose, unsigned no_any)
999 {
1000         char oid[MAX_OID_SIZE];
1001         size_t oid_size;
1002         int ret;
1003         unsigned critical = 0;
1004         unsigned i;
1005
1006         for (i=0;;i++) {
1007                 oid_size = sizeof(oid);
1008                 ret = gnutls_x509_crt_get_key_purpose_oid(cert, i, oid, &oid_size, &critical);
1009                 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1010                         if (i==0) {
1011                                 /* no key purpose in certificate, assume ANY */
1012                                 return 1;
1013                         } else {
1014                                 gnutls_assert();
1015                                 break;
1016                         }
1017                 } else if (ret < 0) {
1018                         gnutls_assert();
1019                         break;
1020                 }
1021
1022                 if (strcmp(oid, purpose) == 0 || (no_any == 0 && strcmp(oid, GNUTLS_KP_ANY) == 0)) {
1023                         return 1;
1024                 }
1025         }
1026         return 0;
1027 }
1028
1029 #ifdef ENABLE_PKCS11
1030 /* Verify X.509 certificate chain using a PKCS #11 token.
1031  *
1032  * Note that the return value is an OR of GNUTLS_CERT_* elements.
1033  *
1034  * Unlike the non-PKCS#11 version, this function accepts a key purpose
1035  * (from GNUTLS_KP_...). That is because in the p11-kit trust modules
1036  * anchors are mixed and get assigned a purpose.
1037  *
1038  * This function verifies a X.509 certificate list. The certificate
1039  * list should lead to a trusted certificate in order to be trusted.
1040  */
1041 unsigned int
1042 _gnutls_pkcs11_verify_crt_status(const char* url,
1043                                 const gnutls_x509_crt_t * certificate_list,
1044                                 unsigned clist_size,
1045                                 const char *purpose,
1046                                 unsigned int flags,
1047                                 gnutls_verify_output_function func)
1048 {
1049         int ret;
1050         unsigned int status = 0, i;
1051         gnutls_x509_crt_t issuer = NULL;
1052         gnutls_datum_t raw_issuer = {NULL, 0};
1053         time_t now = gnutls_time(0);
1054
1055         if (clist_size > 1) {
1056                 /* Check if the last certificate in the path is self signed.
1057                  * In that case ignore it (a certificate is trusted only if it
1058                  * leads to a trusted party by us, not the server's).
1059                  *
1060                  * This prevents from verifying self signed certificates against
1061                  * themselves. This (although not bad) caused verification
1062                  * failures on some root self signed certificates that use the
1063                  * MD2 algorithm.
1064                  */
1065                 if (gnutls_x509_crt_check_issuer
1066                     (certificate_list[clist_size - 1],
1067                      certificate_list[clist_size - 1]) != 0) {
1068                         clist_size--;
1069                 }
1070         }
1071
1072         /* We want to shorten the chain by removing the cert that matches
1073          * one of the certs we trust and all the certs after that i.e. if
1074          * cert chain is A signed-by B signed-by C signed-by D (signed-by
1075          * self-signed E but already removed above), and we trust B, remove
1076          * B, C and D. */
1077         if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
1078                 i = 0;          /* also replace the first one */
1079         else
1080                 i = 1;          /* do not replace the first one */
1081
1082         for (; i < clist_size; i++) {
1083                 unsigned vflags;
1084
1085                 if (i == 0) /* in the end certificate do full comparison */
1086                         vflags = GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE|
1087                                 GNUTLS_PKCS11_OBJ_FLAG_COMPARE|GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_TRUSTED;
1088                 else
1089                         vflags = GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE|
1090                                 GNUTLS_PKCS11_OBJ_FLAG_COMPARE_KEY|GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_TRUSTED;
1091
1092                 if (gnutls_pkcs11_crt_is_known (url, certificate_list[i], vflags) != 0) {
1093
1094                         if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS) &&
1095                                 !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS)) {
1096                                 status |=
1097                                     check_time_status(certificate_list[i], now);
1098                                 if (status != 0) {
1099                                         if (func)
1100                                                 func(certificate_list[i], certificate_list[i], NULL, status);
1101                                         return status;
1102                                 }
1103                         }
1104                         if (func)
1105                                 func(certificate_list[i],
1106                                      certificate_list[i], NULL, status);
1107
1108                         clist_size = i;
1109                         break;
1110                 }
1111                 /* clist_size may have been changed which gets out of loop */
1112         }
1113
1114         if (clist_size == 0) {
1115                 /* The certificate is already present in the trusted certificate list.
1116                  * Nothing to verify. */
1117                 return status;
1118         }
1119
1120         /* check for blacklists */
1121         for (i = 0; i < clist_size; i++) {
1122                 if (gnutls_pkcs11_crt_is_known (url, certificate_list[i], 
1123                         GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE|
1124                         GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_DISTRUSTED) != 0) {
1125                         status |= GNUTLS_CERT_INVALID;
1126                         status |= GNUTLS_CERT_REVOKED;
1127                         if (func)
1128                                 func(certificate_list[i], certificate_list[i], NULL, status);
1129                         goto cleanup;
1130                 }
1131         }
1132
1133         /* check against issuer */
1134         ret = gnutls_pkcs11_get_raw_issuer(url, certificate_list[clist_size - 1],
1135                                            &raw_issuer, GNUTLS_X509_FMT_DER,
1136                                            GNUTLS_PKCS11_OBJ_FLAG_OVERWRITE_TRUSTMOD_EXT|GNUTLS_PKCS11_OBJ_FLAG_PRESENT_IN_TRUSTED_MODULE);
1137         if (ret < 0) {
1138                 gnutls_assert();
1139                 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE && clist_size > 2) {
1140
1141                         /* check if the last certificate in the chain is present
1142                          * in our trusted list, and if yes, verify against it. */
1143                         ret = gnutls_pkcs11_crt_is_known(url, certificate_list[clist_size - 1],
1144                                 GNUTLS_PKCS11_OBJ_FLAG_RETRIEVE_TRUSTED|GNUTLS_PKCS11_OBJ_FLAG_COMPARE);
1145                         if (ret != 0) {
1146                                 return _gnutls_verify_crt_status(certificate_list, clist_size,
1147                                         &certificate_list[clist_size - 1], 1, flags,
1148                                         purpose, func);
1149                         }
1150                 }
1151
1152                 status |= GNUTLS_CERT_INVALID;
1153                 status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
1154                 /* verify the certificate list against 0 trusted CAs in order
1155                  * to get, any additional flags from the certificate list (e.g.,
1156                  * insecure algorithms or expired */
1157                 status |= _gnutls_verify_crt_status(certificate_list, clist_size,
1158                                                     NULL, 0, flags, purpose, func);
1159                 goto cleanup;
1160         }
1161
1162         ret = gnutls_x509_crt_init(&issuer);
1163         if (ret < 0) {
1164                 gnutls_assert();
1165                 status |= GNUTLS_CERT_INVALID;
1166                 status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
1167                 goto cleanup;
1168         }
1169
1170         ret = gnutls_x509_crt_import(issuer, &raw_issuer, GNUTLS_X509_FMT_DER);
1171         if (ret < 0) {
1172                 gnutls_assert();
1173                 status |= GNUTLS_CERT_INVALID;
1174                 status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
1175                 goto cleanup;
1176         }
1177
1178         /* security modules that provide trust, bundle all certificates (of all purposes)
1179          * together. In software that doesn't specify any purpose assume the default to
1180          * be www-server. */
1181         ret = _gnutls_check_key_purpose(issuer, purpose==NULL?GNUTLS_KP_TLS_WWW_SERVER:purpose, 0);
1182         if (ret != 1) {
1183                 gnutls_assert();
1184                 status |= GNUTLS_CERT_INVALID;
1185                 status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
1186                 goto cleanup;
1187         }
1188
1189         status = _gnutls_verify_crt_status(certificate_list, clist_size,
1190                                 &issuer, 1, flags, purpose, func);
1191
1192 cleanup:
1193         gnutls_free(raw_issuer.data);
1194         if (issuer != NULL)
1195                 gnutls_x509_crt_deinit(issuer);
1196
1197         return status;
1198 }
1199 #endif
1200
1201 /* verifies if the certificate is properly signed.
1202  * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success.
1203  * 
1204  * 'data' is the signed data
1205  * 'signature' is the signature!
1206  */
1207 int
1208 _gnutls_x509_verify_data(const mac_entry_st * me,
1209                          const gnutls_datum_t * data,
1210                          const gnutls_datum_t * signature,
1211                          gnutls_x509_crt_t issuer)
1212 {
1213         gnutls_pk_params_st issuer_params;
1214         int ret;
1215
1216         /* Read the MPI parameters from the issuer's certificate.
1217          */
1218         ret = _gnutls_x509_crt_get_mpis(issuer, &issuer_params);
1219         if (ret < 0) {
1220                 gnutls_assert();
1221                 return ret;
1222         }
1223
1224         ret =
1225             pubkey_verify_data(gnutls_x509_crt_get_pk_algorithm
1226                                (issuer, NULL), me, data, signature,
1227                                &issuer_params);
1228         if (ret < 0) {
1229                 gnutls_assert();
1230         }
1231
1232         /* release all allocated MPIs
1233          */
1234         gnutls_pk_params_release(&issuer_params);
1235
1236         return ret;
1237 }
1238
1239 /**
1240  * gnutls_x509_crt_list_verify:
1241  * @cert_list: is the certificate list to be verified
1242  * @cert_list_length: holds the number of certificate in cert_list
1243  * @CA_list: is the CA list which will be used in verification
1244  * @CA_list_length: holds the number of CA certificate in CA_list
1245  * @CRL_list: holds a list of CRLs.
1246  * @CRL_list_length: the length of CRL list.
1247  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1248  * @verify: will hold the certificate verification output.
1249  *
1250  *
1251  * This function will try to verify the given certificate list and
1252  * return its status. The details of the verification are the same
1253  * as in gnutls_x509_trust_list_verify_crt2().
1254  *
1255  * You must check the peer's name in order to check if the verified
1256  * certificate belongs to the actual peer.
1257  *
1258  * The certificate verification output will be put in @verify and will
1259  * be one or more of the gnutls_certificate_status_t enumerated
1260  * elements bitwise or'd.  For a more detailed verification status use
1261  * gnutls_x509_crt_verify() per list element.
1262  *
1263  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1264  *   negative error value.
1265  **/
1266 int
1267 gnutls_x509_crt_list_verify(const gnutls_x509_crt_t * cert_list,
1268                             int cert_list_length,
1269                             const gnutls_x509_crt_t * CA_list,
1270                             int CA_list_length,
1271                             const gnutls_x509_crl_t * CRL_list,
1272                             int CRL_list_length, unsigned int flags,
1273                             unsigned int *verify)
1274 {
1275         int i, ret;
1276
1277         if (cert_list == NULL || cert_list_length == 0)
1278                 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1279
1280         /* Verify certificate 
1281          */
1282         *verify =
1283             _gnutls_verify_crt_status(cert_list, cert_list_length,
1284                                             CA_list, CA_list_length,
1285                                             flags, NULL, NULL);
1286
1287         /* Check for revoked certificates in the chain. 
1288          */
1289         for (i = 0; i < cert_list_length; i++) {
1290                 ret = gnutls_x509_crt_check_revocation(cert_list[i],
1291                                                        CRL_list,
1292                                                        CRL_list_length);
1293                 if (ret == 1) { /* revoked */
1294                         *verify |= GNUTLS_CERT_REVOKED;
1295                         *verify |= GNUTLS_CERT_INVALID;
1296                 }
1297         }
1298
1299         return 0;
1300 }
1301
1302 /**
1303  * gnutls_x509_crt_verify:
1304  * @cert: is the certificate to be verified
1305  * @CA_list: is one certificate that is considered to be trusted one
1306  * @CA_list_length: holds the number of CA certificate in CA_list
1307  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1308  * @verify: will hold the certificate verification output.
1309  *
1310  * This function will try to verify the given certificate and return
1311  * its status. Note that a verification error does not imply a negative
1312  * return status. In that case the @verify status is set.
1313  *
1314  * The details of the verification are the same
1315  * as in gnutls_x509_trust_list_verify_crt2().
1316  *
1317  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1318  *   negative error value.
1319  **/
1320 int
1321 gnutls_x509_crt_verify(gnutls_x509_crt_t cert,
1322                        const gnutls_x509_crt_t * CA_list,
1323                        int CA_list_length, unsigned int flags,
1324                        unsigned int *verify)
1325 {
1326         /* Verify certificate 
1327          */
1328         *verify =
1329             _gnutls_verify_crt_status(&cert, 1,
1330                                             CA_list, CA_list_length,
1331                                             flags, NULL, NULL);
1332         return 0;
1333 }
1334
1335 /**
1336  * gnutls_x509_crl_check_issuer:
1337  * @crl: is the CRL to be checked
1338  * @issuer: is the certificate of a possible issuer
1339  *
1340  * This function will check if the given CRL was issued by the given
1341  * issuer certificate.  
1342  *
1343  * Returns: true (1) if the given CRL was issued by the given issuer, 
1344  * and false (0) if not.
1345  **/
1346 int
1347 gnutls_x509_crl_check_issuer(gnutls_x509_crl_t crl,
1348                              gnutls_x509_crt_t issuer)
1349 {
1350         return is_crl_issuer(crl, issuer);
1351 }
1352
1353 static inline gnutls_x509_crt_t
1354 find_crl_issuer(gnutls_x509_crl_t crl,
1355                 const gnutls_x509_crt_t * trusted_cas, int tcas_size)
1356 {
1357         int i;
1358
1359         /* this is serial search. 
1360          */
1361
1362         for (i = 0; i < tcas_size; i++) {
1363                 if (is_crl_issuer(crl, trusted_cas[i]) != 0)
1364                         return trusted_cas[i];
1365         }
1366
1367         gnutls_assert();
1368         return NULL;
1369 }
1370
1371 /**
1372  * gnutls_x509_crl_verify:
1373  * @crl: is the crl to be verified
1374  * @trusted_cas: is a certificate list that is considered to be trusted one
1375  * @tcas_size: holds the number of CA certificates in CA_list
1376  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1377  * @verify: will hold the crl verification output.
1378  *
1379  * This function will try to verify the given crl and return its verification status.
1380  * See gnutls_x509_crt_list_verify() for a detailed description of
1381  * return values. Note that since GnuTLS 3.1.4 this function includes
1382  * the time checks.
1383  *
1384  * Note that value in @verify is set only when the return value of this 
1385  * function is success (i.e, failure to trust a CRL a certificate does not imply 
1386  * a negative return value).
1387  *
1388  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1389  *   negative error value.
1390  **/
1391 int
1392 gnutls_x509_crl_verify(gnutls_x509_crl_t crl,
1393                        const gnutls_x509_crt_t * trusted_cas,
1394                        int tcas_size, unsigned int flags,
1395                        unsigned int *verify)
1396 {
1397 /* CRL is ignored for now */
1398         gnutls_datum_t crl_signed_data = { NULL, 0 };
1399         gnutls_datum_t crl_signature = { NULL, 0 };
1400         gnutls_x509_crt_t issuer = NULL;
1401         int result, hash_algo;
1402         time_t now = gnutls_time(0);
1403         unsigned int usage;
1404
1405         if (verify)
1406                 *verify = 0;
1407
1408         if (tcas_size >= 1)
1409                 issuer = find_crl_issuer(crl, trusted_cas, tcas_size);
1410
1411         result =
1412             _gnutls_x509_get_signed_data(crl->crl, &crl->der, "tbsCertList",
1413                                          &crl_signed_data);
1414         if (result < 0) {
1415                 gnutls_assert();
1416                 if (verify)
1417                         *verify |= GNUTLS_CERT_INVALID;
1418                 goto cleanup;
1419         }
1420
1421         result =
1422             _gnutls_x509_get_signature(crl->crl, "signature",
1423                                        &crl_signature);
1424         if (result < 0) {
1425                 gnutls_assert();
1426                 if (verify)
1427                         *verify |= GNUTLS_CERT_INVALID;
1428                 goto cleanup;
1429         }
1430
1431         result =
1432             _gnutls_x509_get_signature_algorithm(crl->crl,
1433                                                  "signatureAlgorithm.algorithm");
1434         if (result < 0) {
1435                 gnutls_assert();
1436                 if (verify)
1437                         *verify |= GNUTLS_CERT_INVALID;
1438                 goto cleanup;
1439         }
1440
1441         hash_algo = gnutls_sign_get_hash_algorithm(result);
1442
1443         /* issuer is not in trusted certificate
1444          * authorities.
1445          */
1446         if (issuer == NULL) {
1447                 gnutls_assert();
1448                 if (verify)
1449                         *verify |=
1450                             GNUTLS_CERT_SIGNER_NOT_FOUND |
1451                             GNUTLS_CERT_INVALID;
1452         } else {
1453                 if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN)) {
1454                         if (gnutls_x509_crt_get_ca_status(issuer, NULL) != 1) {
1455                                 gnutls_assert();
1456                                 if (verify)
1457                                         *verify |=
1458                                             GNUTLS_CERT_SIGNER_NOT_CA |
1459                                             GNUTLS_CERT_INVALID;
1460                         }
1461
1462                         result =
1463                             gnutls_x509_crt_get_key_usage(issuer, &usage, NULL);
1464                         if (result >= 0) {
1465                                 if (!(usage & GNUTLS_KEY_CRL_SIGN)) {
1466                                         gnutls_assert();
1467                                         if (verify)
1468                                                 *verify |=
1469                                                     GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE
1470                                                     | GNUTLS_CERT_INVALID;
1471                                 }
1472                         }
1473                 }
1474
1475                 result =
1476                     _gnutls_x509_verify_data(mac_to_entry(hash_algo),
1477                                              &crl_signed_data, &crl_signature,
1478                                              issuer);
1479                 if (result == GNUTLS_E_PK_SIG_VERIFY_FAILED) {
1480                         gnutls_assert();
1481                         /* error. ignore it */
1482                         if (verify)
1483                                 *verify |= GNUTLS_CERT_SIGNATURE_FAILURE;
1484                         result = 0;
1485                 } else if (result < 0) {
1486                         gnutls_assert();
1487                         if (verify)
1488                                 *verify |= GNUTLS_CERT_INVALID;
1489                         goto cleanup;
1490                 }
1491         }
1492
1493         {
1494                 int sigalg;
1495
1496                 sigalg = gnutls_x509_crl_get_signature_algorithm(crl);
1497
1498                 if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
1499                      !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
1500                     ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
1501                      !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5))) {
1502                         if (verify)
1503                                 *verify |= GNUTLS_CERT_INSECURE_ALGORITHM;
1504                         result = 0;
1505                 }
1506         }
1507
1508         if (gnutls_x509_crl_get_this_update(crl) > now && verify)
1509                 *verify |= GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE;
1510
1511         if (gnutls_x509_crl_get_next_update(crl) < now && verify)
1512                 *verify |= GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED;
1513
1514
1515       cleanup:
1516         if (verify && *verify != 0)
1517                 *verify |= GNUTLS_CERT_INVALID;
1518
1519         _gnutls_free_datum(&crl_signed_data);
1520         _gnutls_free_datum(&crl_signature);
1521
1522         return result;
1523 }