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