Use the new asn1_read_node_value()
[gnutls.git] / lib / x509 / verify.c
blobbcca3868106dfb71e228bb0381277244119eb780
1 /*
2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* All functions which relate to X.509 certificate verification stuff are
24 * included here
27 #include <gnutls_int.h>
28 #include <gnutls_errors.h>
29 #include <libtasn1.h>
30 #include <gnutls_global.h>
31 #include <gnutls_num.h> /* MAX */
32 #include <gnutls_sig.h>
33 #include <gnutls_str.h>
34 #include <gnutls_datum.h>
35 #include <x509_int.h>
36 #include <common.h>
37 #include <gnutls_pk.h>
39 static int is_crl_issuer (gnutls_x509_crl_t crl,
40 gnutls_x509_crt_t issuer_cert);
42 static int _gnutls_verify_crl2 (gnutls_x509_crl_t crl,
43 const gnutls_x509_crt_t * trusted_cas,
44 int tcas_size, unsigned int flags,
45 unsigned int *output);
47 /* Checks if two certs are identical. Return 0 on match. */
48 int
49 check_if_same_cert (gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2)
51 gnutls_datum_t cert1bin = { NULL, 0 }, cert2bin =
53 NULL, 0};
54 int result;
55 uint8_t serial1[128], serial2[128];
56 size_t serial1_size, serial2_size;
58 serial1_size = sizeof (serial1);
59 result = gnutls_x509_crt_get_serial (cert1, serial1, &serial1_size);
60 if (result < 0)
62 gnutls_assert ();
63 goto cmp;
66 serial2_size = sizeof (serial2);
67 result = gnutls_x509_crt_get_serial (cert2, serial2, &serial2_size);
68 if (result < 0)
70 gnutls_assert ();
71 goto cmp;
74 if (serial2_size != serial1_size
75 || memcmp (serial1, serial2, serial1_size) != 0)
77 return 1;
80 cmp:
81 result = _gnutls_x509_der_encode (cert1->cert, "", &cert1bin, 0);
82 if (result < 0)
84 gnutls_assert ();
85 goto cleanup;
88 result = _gnutls_x509_der_encode (cert2->cert, "", &cert2bin, 0);
89 if (result < 0)
91 gnutls_assert ();
92 goto cleanup;
95 if ((cert1bin.size == cert2bin.size) &&
96 (memcmp (cert1bin.data, cert2bin.data, cert1bin.size) == 0))
97 result = 0;
98 else
99 result = 1;
101 cleanup:
102 _gnutls_free_datum (&cert1bin);
103 _gnutls_free_datum (&cert2bin);
104 return result;
107 /* Checks if the issuer of a certificate is a
108 * Certificate Authority, or if the certificate is the same
109 * as the issuer (and therefore it doesn't need to be a CA).
111 * Returns true or false, if the issuer is a CA,
112 * or not.
114 static int
115 check_if_ca (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
116 unsigned int flags)
118 gnutls_datum_t cert_signed_data = { NULL, 0 };
119 gnutls_datum_t issuer_signed_data = { NULL, 0 };
120 gnutls_datum_t cert_signature = { NULL, 0 };
121 gnutls_datum_t issuer_signature = { NULL, 0 };
122 int result;
124 /* Check if the issuer is the same with the
125 * certificate. This is added in order for trusted
126 * certificates to be able to verify themselves.
129 result =
130 _gnutls_x509_get_signed_data (issuer->cert, "tbsCertificate",
131 &issuer_signed_data);
132 if (result < 0)
134 gnutls_assert ();
135 goto cleanup;
138 result =
139 _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
140 &cert_signed_data);
141 if (result < 0)
143 gnutls_assert ();
144 goto cleanup;
147 result =
148 _gnutls_x509_get_signature (issuer->cert, "signature", &issuer_signature);
149 if (result < 0)
151 gnutls_assert ();
152 goto cleanup;
155 result =
156 _gnutls_x509_get_signature (cert->cert, "signature", &cert_signature);
157 if (result < 0)
159 gnutls_assert ();
160 goto cleanup;
163 /* If the subject certificate is the same as the issuer
164 * return true.
166 if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
167 if (cert_signed_data.size == issuer_signed_data.size)
169 if ((memcmp (cert_signed_data.data, issuer_signed_data.data,
170 cert_signed_data.size) == 0) &&
171 (cert_signature.size == issuer_signature.size) &&
172 (memcmp (cert_signature.data, issuer_signature.data,
173 cert_signature.size) == 0))
175 result = 1;
176 goto cleanup;
180 result = gnutls_x509_crt_get_ca_status (issuer, NULL);
181 if (result == 1)
183 result = 1;
184 goto cleanup;
186 /* Handle V1 CAs that do not have a basicConstraint, but accept
187 these certs only if the appropriate flags are set. */
188 else if ((result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) &&
189 ((flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT) ||
190 (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT) &&
191 (gnutls_x509_crt_check_issuer (issuer, issuer) == 1))))
193 gnutls_assert ();
194 result = 1;
195 goto cleanup;
197 else
198 gnutls_assert ();
200 result = 0;
202 cleanup:
203 _gnutls_free_datum (&cert_signed_data);
204 _gnutls_free_datum (&issuer_signed_data);
205 _gnutls_free_datum (&cert_signature);
206 _gnutls_free_datum (&issuer_signature);
207 return result;
211 /* This function checks if 'certs' issuer is 'issuer_cert'.
212 * This does a straight (DER) compare of the issuer/subject fields in
213 * the given certificates.
215 * Returns 1 if they match and (0) if they don't match. Otherwise
216 * a negative error code is returned to indicate error.
218 static int
219 is_issuer (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer_cert)
221 gnutls_datum_t dn1 = { NULL, 0 },
222 dn2 = { NULL, 0};
223 uint8_t id1[512];
224 uint8_t id2[512];
225 size_t id1_size;
226 size_t id2_size;
227 int ret;
229 ret = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn1);
230 if (ret < 0)
232 gnutls_assert ();
233 goto cleanup;
236 ret = gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
237 if (ret < 0)
239 gnutls_assert ();
240 goto cleanup;
243 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
245 if (ret != 0)
247 /* check if the authority key identifier matches the subject key identifier
248 * of the issuer */
249 id1_size = sizeof(id1);
251 ret = gnutls_x509_crt_get_authority_key_id(cert, id1, &id1_size, NULL);
252 if (ret < 0)
254 ret = 1;
255 goto cleanup;
258 id2_size = sizeof(id2);
259 ret = gnutls_x509_crt_get_subject_key_id(issuer_cert, id2, &id2_size, NULL);
260 if (ret < 0)
262 ret = 1;
263 gnutls_assert();
264 goto cleanup;
267 if (id1_size == id2_size && memcmp(id1, id2, id1_size) == 0)
268 ret = 1;
269 else
270 ret = 0;
273 cleanup:
274 _gnutls_free_datum (&dn1);
275 _gnutls_free_datum (&dn2);
276 return ret;
280 /* Checks if the DN of two certificates is the same.
281 * Returns 1 if they match and (0) if they don't match. Otherwise
282 * a negative error code is returned to indicate error.
285 _gnutls_is_same_dn (gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2)
287 gnutls_datum_t dn1 = { NULL, 0 }, dn2 =
289 NULL, 0};
290 int ret;
292 ret = gnutls_x509_crt_get_raw_dn (cert1, &dn1);
293 if (ret < 0)
295 gnutls_assert ();
296 goto cleanup;
299 ret = gnutls_x509_crt_get_raw_dn (cert2, &dn2);
300 if (ret < 0)
302 gnutls_assert ();
303 goto cleanup;
306 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
308 cleanup:
309 _gnutls_free_datum (&dn1);
310 _gnutls_free_datum (&dn2);
311 return ret;
314 /* Finds an issuer of the certificate. If multiple issuers
315 * are present, returns one that is activated and not expired.
317 static inline gnutls_x509_crt_t
318 find_issuer (gnutls_x509_crt_t cert,
319 const gnutls_x509_crt_t * trusted_cas, int tcas_size)
321 int i;
322 gnutls_x509_crt_t issuer = NULL;
324 /* this is serial search.
327 for (i = 0; i < tcas_size; i++)
329 if (is_issuer (cert, trusted_cas[i]) == 1)
331 if (issuer == NULL)
333 issuer = trusted_cas[i];
335 else
337 time_t now = gnutls_time(0);
339 if (now < gnutls_x509_crt_get_expiration_time(trusted_cas[i]) &&
340 now >= gnutls_x509_crt_get_activation_time(trusted_cas[i]))
342 issuer = trusted_cas[i];
348 return issuer;
351 static unsigned int
352 check_time (gnutls_x509_crt_t crt, time_t now)
354 int status = 0;
355 time_t t;
357 t = gnutls_x509_crt_get_activation_time (crt);
358 if (t == (time_t) - 1 || now < t)
360 status |= GNUTLS_CERT_NOT_ACTIVATED;
361 status |= GNUTLS_CERT_INVALID;
362 return status;
365 t = gnutls_x509_crt_get_expiration_time (crt);
366 if (t == (time_t) - 1 || now > t)
368 status |= GNUTLS_CERT_EXPIRED;
369 status |= GNUTLS_CERT_INVALID;
370 return status;
373 return 0;
377 * Verifies the given certificate again a certificate list of
378 * trusted CAs.
380 * Returns only 0 or 1. If 1 it means that the certificate
381 * was successfuly verified.
383 * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
385 * Output will hold some extra information about the verification
386 * procedure. Issuer will hold the actual issuer from the trusted list.
388 static int
389 _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
390 const gnutls_x509_crt_t * trusted_cas,
391 int tcas_size, unsigned int flags,
392 unsigned int *output,
393 gnutls_x509_crt_t * _issuer,
394 time_t now,
395 gnutls_verify_output_function func)
397 gnutls_datum_t cert_signed_data = { NULL, 0 };
398 gnutls_datum_t cert_signature = { NULL, 0 };
399 gnutls_x509_crt_t issuer = NULL;
400 int issuer_version, result, hash_algo;
401 unsigned int out = 0;
403 if (output)
404 *output = 0;
406 if (tcas_size >= 1)
407 issuer = find_issuer (cert, trusted_cas, tcas_size);
408 else
410 gnutls_assert ();
411 out = GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
412 if (output)
413 *output |= out;
414 result = 0;
415 goto cleanup;
418 /* issuer is not in trusted certificate
419 * authorities.
421 if (issuer == NULL)
423 out = GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
424 if (output)
425 *output |= out;
426 gnutls_assert ();
427 result = 0;
428 goto cleanup;
431 if (_issuer != NULL)
432 *_issuer = issuer;
434 issuer_version = gnutls_x509_crt_get_version (issuer);
435 if (issuer_version < 0)
437 gnutls_assert ();
438 return issuer_version;
441 if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) &&
442 ((flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT)
443 || issuer_version != 1))
445 if (check_if_ca (cert, issuer, flags) == 0)
447 gnutls_assert ();
448 out = GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
449 if (output)
450 *output |= out;
451 result = 0;
452 goto cleanup;
456 result =
457 _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
458 &cert_signed_data);
459 if (result < 0)
461 gnutls_assert ();
462 goto cleanup;
465 result =
466 _gnutls_x509_get_signature (cert->cert, "signature", &cert_signature);
467 if (result < 0)
469 gnutls_assert ();
470 goto cleanup;
473 result = _gnutls_x509_get_signature_algorithm(cert->cert, "signatureAlgorithm.algorithm");
474 if (result < 0)
476 gnutls_assert ();
477 goto cleanup;
480 hash_algo = _gnutls_sign_get_hash_algorithm(result);
482 result =
483 _gnutls_x509_verify_data (hash_algo, &cert_signed_data, &cert_signature,
484 issuer);
485 if (result == GNUTLS_E_PK_SIG_VERIFY_FAILED)
487 gnutls_assert ();
488 out |= GNUTLS_CERT_INVALID;
489 /* error. ignore it */
490 if (output)
491 *output |= out;
492 result = 0;
494 else if (result < 0)
496 gnutls_assert();
497 goto cleanup;
500 /* If the certificate is not self signed check if the algorithms
501 * used are secure. If the certificate is self signed it doesn't
502 * really matter.
504 if (is_issuer (cert, cert) == 0)
506 int sigalg;
508 sigalg = gnutls_x509_crt_get_signature_algorithm (cert);
510 if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
511 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
512 ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
513 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
515 out = GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
516 if (output)
517 *output |= out;
518 result = 0;
522 /* Check activation/expiration times
524 if (!(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS))
526 /* check the time of the issuer first */
527 if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS))
529 out |= check_time (issuer, now);
530 if (out != 0)
532 result = 0;
533 if (output) *output |= out;
537 out |= check_time (cert, now);
538 if (out != 0)
540 result = 0;
541 if (output) *output |= out;
545 cleanup:
546 if (result >= 0 && func) func(cert, issuer, NULL, out);
547 _gnutls_free_datum (&cert_signed_data);
548 _gnutls_free_datum (&cert_signature);
550 return result;
554 * gnutls_x509_crt_check_issuer:
555 * @cert: is the certificate to be checked
556 * @issuer: is the certificate of a possible issuer
558 * This function will check if the given certificate was issued by the
559 * given issuer. It checks the DN fields and the authority
560 * key identifier and subject key identifier fields match.
562 * Returns: It will return true (1) if the given certificate is issued
563 * by the given issuer, and false (0) if not. A negative error code is
564 * returned in case of an error.
567 gnutls_x509_crt_check_issuer (gnutls_x509_crt_t cert,
568 gnutls_x509_crt_t issuer)
570 return is_issuer (cert, issuer);
573 /* Verify X.509 certificate chain.
575 * Note that the return value is an OR of GNUTLS_CERT_* elements.
577 * This function verifies a X.509 certificate list. The certificate
578 * list should lead to a trusted certificate in order to be trusted.
580 unsigned int
581 _gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
582 int clist_size,
583 const gnutls_x509_crt_t * trusted_cas,
584 int tcas_size,
585 unsigned int flags,
586 gnutls_verify_output_function func)
588 int i = 0, ret;
589 unsigned int status = 0, output;
590 time_t now = gnutls_time (0);
591 gnutls_x509_crt_t issuer = NULL;
593 if (clist_size > 1)
595 /* Check if the last certificate in the path is self signed.
596 * In that case ignore it (a certificate is trusted only if it
597 * leads to a trusted party by us, not the server's).
599 * This prevents from verifying self signed certificates against
600 * themselves. This (although not bad) caused verification
601 * failures on some root self signed certificates that use the
602 * MD2 algorithm.
604 if (gnutls_x509_crt_check_issuer (certificate_list[clist_size - 1],
605 certificate_list[clist_size - 1]) > 0)
607 clist_size--;
611 /* We want to shorten the chain by removing the cert that matches
612 * one of the certs we trust and all the certs after that i.e. if
613 * cert chain is A signed-by B signed-by C signed-by D (signed-by
614 * self-signed E but already removed above), and we trust B, remove
615 * B, C and D. */
616 if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
617 i = 0; /* also replace the first one */
618 else
619 i = 1; /* do not replace the first one */
621 for (; i < clist_size; i++)
623 int j;
625 for (j = 0; j < tcas_size; j++)
627 if (check_if_same_cert (certificate_list[i], trusted_cas[j]) == 0)
629 /* explicity time check for trusted CA that we remove from
630 * list. GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS
632 if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS)
633 && !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS))
635 status |= check_time (trusted_cas[j], now);
636 if (status != 0)
638 if (func) func(certificate_list[i], trusted_cas[j], NULL, status);
639 return status;
643 if (func) func(certificate_list[i], trusted_cas[j], NULL, status);
644 clist_size = i;
645 break;
648 /* clist_size may have been changed which gets out of loop */
651 if (clist_size == 0)
653 /* The certificate is already present in the trusted certificate list.
654 * Nothing to verify. */
655 return status;
658 /* Verify the last certificate in the certificate path
659 * against the trusted CA certificate list.
661 * If no CAs are present returns CERT_INVALID. Thus works
662 * in self signed etc certificates.
664 output = 0;
665 ret = _gnutls_verify_certificate2 (certificate_list[clist_size - 1],
666 trusted_cas, tcas_size, flags, &output,
667 &issuer, now, func);
668 if (ret == 0)
670 /* if the last certificate in the certificate
671 * list is invalid, then the certificate is not
672 * trusted.
674 gnutls_assert ();
675 status |= output;
676 status |= GNUTLS_CERT_INVALID;
677 return status;
680 /* Verify the certificate path (chain)
682 for (i = clist_size - 1; i > 0; i--)
684 output = 0;
685 if (i - 1 < 0)
686 break;
688 /* note that here we disable this V1 CA flag. So that no version 1
689 * certificates can exist in a supplied chain.
691 if (!(flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT))
692 flags &= ~(GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
693 if ((ret =
694 _gnutls_verify_certificate2 (certificate_list[i - 1],
695 &certificate_list[i], 1, flags,
696 &output, NULL, now, func)) == 0)
698 status |= output;
699 status |= GNUTLS_CERT_INVALID;
700 return status;
704 return 0;
707 /* This will return the appropriate hash to verify the given signature.
708 * If signature is NULL it will return an (or the) appropriate hash for
709 * the given parameters.
712 _gnutls_x509_verify_algorithm (gnutls_digest_algorithm_t * hash,
713 const gnutls_datum_t * signature,
714 gnutls_pk_algorithm_t pk,
715 gnutls_pk_params_st * issuer_params)
717 uint8_t digest[MAX_HASH_SIZE];
718 gnutls_datum_t decrypted;
719 unsigned int digest_size;
720 int ret;
722 switch (pk)
724 case GNUTLS_PK_DSA:
725 case GNUTLS_PK_EC:
727 if (hash)
728 *hash = _gnutls_dsa_q_to_hash (pk, issuer_params, NULL);
730 ret = 0;
731 break;
732 case GNUTLS_PK_RSA:
733 if (signature == NULL)
734 { /* return a sensible algorithm */
735 if (hash)
736 *hash = GNUTLS_DIG_SHA256;
737 return 0;
740 ret =
741 _gnutls_pkcs1_rsa_decrypt (&decrypted, signature,
742 issuer_params, 1);
745 if (ret < 0)
747 gnutls_assert ();
748 goto cleanup;
751 digest_size = sizeof (digest);
752 if ((ret =
753 decode_ber_digest_info (&decrypted, hash, digest,
754 &digest_size)) != 0)
756 gnutls_assert ();
757 _gnutls_free_datum (&decrypted);
758 goto cleanup;
761 _gnutls_free_datum (&decrypted);
762 if (digest_size != _gnutls_hash_get_algo_len (*hash))
764 gnutls_assert ();
765 ret = GNUTLS_E_ASN1_GENERIC_ERROR;
766 goto cleanup;
769 ret = 0;
770 break;
772 default:
773 gnutls_assert ();
774 ret = GNUTLS_E_INTERNAL_ERROR;
777 cleanup:
779 return ret;
783 /* verifies if the certificate is properly signed.
784 * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success.
786 * 'data' is the signed data
787 * 'signature' is the signature!
790 _gnutls_x509_verify_data (gnutls_digest_algorithm_t algo,
791 const gnutls_datum_t * data,
792 const gnutls_datum_t * signature,
793 gnutls_x509_crt_t issuer)
795 gnutls_pk_params_st issuer_params;
796 int ret;
798 /* Read the MPI parameters from the issuer's certificate.
800 ret =
801 _gnutls_x509_crt_get_mpis (issuer, &issuer_params);
802 if (ret < 0)
804 gnutls_assert ();
805 return ret;
808 ret =
809 pubkey_verify_data (gnutls_x509_crt_get_pk_algorithm (issuer, NULL), algo,
810 data, signature, &issuer_params);
811 if (ret < 0)
813 gnutls_assert ();
816 /* release all allocated MPIs
818 gnutls_pk_params_release(&issuer_params);
820 return ret;
824 * gnutls_x509_crt_list_verify:
825 * @cert_list: is the certificate list to be verified
826 * @cert_list_length: holds the number of certificate in cert_list
827 * @CA_list: is the CA list which will be used in verification
828 * @CA_list_length: holds the number of CA certificate in CA_list
829 * @CRL_list: holds a list of CRLs.
830 * @CRL_list_length: the length of CRL list.
831 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
832 * @verify: will hold the certificate verification output.
834 * This function will try to verify the given certificate list and
835 * return its status. If no flags are specified (0), this function
836 * will use the basicConstraints (2.5.29.19) PKIX extension. This
837 * means that only a certificate authority is allowed to sign a
838 * certificate.
840 * You must also check the peer's name in order to check if the verified
841 * certificate belongs to the actual peer.
843 * The certificate verification output will be put in @verify and will
844 * be one or more of the gnutls_certificate_status_t enumerated
845 * elements bitwise or'd. For a more detailed verification status use
846 * gnutls_x509_crt_verify() per list element.
848 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
849 * negative error value.
852 gnutls_x509_crt_list_verify (const gnutls_x509_crt_t * cert_list,
853 int cert_list_length,
854 const gnutls_x509_crt_t * CA_list,
855 int CA_list_length,
856 const gnutls_x509_crl_t * CRL_list,
857 int CRL_list_length, unsigned int flags,
858 unsigned int *verify)
860 int i, ret;
862 if (cert_list == NULL || cert_list_length == 0)
863 return GNUTLS_E_NO_CERTIFICATE_FOUND;
865 /* Verify certificate
867 *verify =
868 _gnutls_x509_verify_certificate (cert_list, cert_list_length,
869 CA_list, CA_list_length,
870 flags, NULL);
872 /* Check for revoked certificates in the chain.
874 for (i = 0; i < cert_list_length; i++)
876 ret = gnutls_x509_crt_check_revocation (cert_list[i],
877 CRL_list, CRL_list_length);
878 if (ret == 1)
879 { /* revoked */
880 *verify |= GNUTLS_CERT_REVOKED;
881 *verify |= GNUTLS_CERT_INVALID;
885 return 0;
889 * gnutls_x509_crt_verify:
890 * @cert: is the certificate to be verified
891 * @CA_list: is one certificate that is considered to be trusted one
892 * @CA_list_length: holds the number of CA certificate in CA_list
893 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
894 * @verify: will hold the certificate verification output.
896 * This function will try to verify the given certificate and return
897 * its status.
899 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
900 * negative error value.
903 gnutls_x509_crt_verify (gnutls_x509_crt_t cert,
904 const gnutls_x509_crt_t * CA_list,
905 int CA_list_length, unsigned int flags,
906 unsigned int *verify)
908 /* Verify certificate
910 *verify =
911 _gnutls_x509_verify_certificate (&cert, 1,
912 CA_list, CA_list_length,
913 flags, NULL);
914 return 0;
918 * gnutls_x509_crl_check_issuer:
919 * @crl: is the CRL to be checked
920 * @issuer: is the certificate of a possible issuer
922 * This function will check if the given CRL was issued by the given
923 * issuer certificate. It will return true (1) if the given CRL was
924 * issued by the given issuer, and false (0) if not.
926 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
927 * negative error value.
930 gnutls_x509_crl_check_issuer (gnutls_x509_crl_t crl,
931 gnutls_x509_crt_t issuer)
933 return is_crl_issuer (crl, issuer);
937 * gnutls_x509_crl_verify:
938 * @crl: is the crl to be verified
939 * @CA_list: is a certificate list that is considered to be trusted one
940 * @CA_list_length: holds the number of CA certificates in CA_list
941 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
942 * @verify: will hold the crl verification output.
944 * This function will try to verify the given crl and return its status.
945 * See gnutls_x509_crt_list_verify() for a detailed description of
946 * return values.
948 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
949 * negative error value.
952 gnutls_x509_crl_verify (gnutls_x509_crl_t crl,
953 const gnutls_x509_crt_t * CA_list,
954 int CA_list_length, unsigned int flags,
955 unsigned int *verify)
957 int ret;
958 /* Verify crl
960 ret = _gnutls_verify_crl2 (crl, CA_list, CA_list_length, flags, verify);
961 if (ret < 0)
963 gnutls_assert ();
964 return ret;
967 return 0;
971 /* The same as above, but here we've got a CRL.
973 static int
974 is_crl_issuer (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer_cert)
976 gnutls_datum_t dn1 = { NULL, 0 }, dn2 =
978 NULL, 0};
979 int ret;
981 ret = gnutls_x509_crl_get_raw_issuer_dn (crl, &dn1);
982 if (ret < 0)
984 gnutls_assert ();
985 goto cleanup;
988 ret = gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
989 if (ret < 0)
991 gnutls_assert ();
992 return ret;
995 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
997 cleanup:
998 _gnutls_free_datum (&dn1);
999 _gnutls_free_datum (&dn2);
1001 return ret;
1004 static inline gnutls_x509_crt_t
1005 find_crl_issuer (gnutls_x509_crl_t crl,
1006 const gnutls_x509_crt_t * trusted_cas, int tcas_size)
1008 int i;
1010 /* this is serial search.
1013 for (i = 0; i < tcas_size; i++)
1015 if (is_crl_issuer (crl, trusted_cas[i]) == 1)
1016 return trusted_cas[i];
1019 gnutls_assert ();
1020 return NULL;
1024 * Returns only 0 or 1. If 1 it means that the CRL
1025 * was successfuly verified.
1027 * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
1029 * Output will hold information about the verification
1030 * procedure.
1032 static int
1033 _gnutls_verify_crl2 (gnutls_x509_crl_t crl,
1034 const gnutls_x509_crt_t * trusted_cas,
1035 int tcas_size, unsigned int flags, unsigned int *output)
1037 /* CRL is ignored for now */
1038 gnutls_datum_t crl_signed_data = { NULL, 0 };
1039 gnutls_datum_t crl_signature = { NULL, 0 };
1040 gnutls_x509_crt_t issuer;
1041 int result, hash_algo;
1043 if (output)
1044 *output = 0;
1046 if (tcas_size >= 1)
1047 issuer = find_crl_issuer (crl, trusted_cas, tcas_size);
1048 else
1050 gnutls_assert ();
1051 if (output)
1052 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
1053 return 0;
1056 /* issuer is not in trusted certificate
1057 * authorities.
1059 if (issuer == NULL)
1061 gnutls_assert ();
1062 if (output)
1063 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
1064 return 0;
1067 if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN))
1069 if (gnutls_x509_crt_get_ca_status (issuer, NULL) != 1)
1071 gnutls_assert ();
1072 if (output)
1073 *output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
1074 return 0;
1078 result =
1079 _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data);
1080 if (result < 0)
1082 gnutls_assert ();
1083 goto cleanup;
1086 result = _gnutls_x509_get_signature (crl->crl, "signature", &crl_signature);
1087 if (result < 0)
1089 gnutls_assert ();
1090 goto cleanup;
1093 result = _gnutls_x509_get_signature_algorithm(crl->crl, "signatureAlgorithm.algorithm");
1094 if (result < 0)
1096 gnutls_assert ();
1097 goto cleanup;
1100 hash_algo = _gnutls_sign_get_hash_algorithm(result);
1102 result =
1103 _gnutls_x509_verify_data (hash_algo, &crl_signed_data, &crl_signature,
1104 issuer);
1105 if (result == GNUTLS_E_PK_SIG_VERIFY_FAILED)
1107 gnutls_assert ();
1108 /* error. ignore it */
1109 if (output)
1110 *output |= GNUTLS_CERT_INVALID;
1111 result = 0;
1113 else if (result < 0)
1115 gnutls_assert ();
1116 goto cleanup;
1120 int sigalg;
1122 sigalg = gnutls_x509_crl_get_signature_algorithm (crl);
1124 if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
1125 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
1126 ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
1127 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
1129 if (output)
1130 *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
1131 result = 0;
1135 cleanup:
1136 _gnutls_free_datum (&crl_signed_data);
1137 _gnutls_free_datum (&crl_signature);
1139 return result;