Bug Summary

File:lib/x509/verify.c
Location:line 662, column 12
Description:Although the value stored to 'ret' is used in the enclosing expression, the value is never actually read from 'ret'

Annotated Source Code

1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
3 * Free Software Foundation, Inc.
4 *
5 * Author: Nikos Mavrogiannopoulos
6 *
7 * This file is part of GnuTLS.
8 *
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
21 *
22 */
23
24/* All functions which relate to X.509 certificate verification stuff are
25 * included here
26 */
27
28#include <gnutls_int.h>
29#include <gnutls_errors.h>
30#include <libtasn1.h>
31#include <gnutls_global.h>
32#include <gnutls_num.h> /* MAX */
33#include <gnutls_sig.h>
34#include <gnutls_str.h>
35#include <gnutls_datumgnutls_datum_t.h>
36#include <x509_int.h>
37#include <common.h>
38#include <gnutls_pk.h>
39
40static int is_crl_issuer (gnutls_x509_crl_t crl,
41 gnutls_x509_crt_t issuer_cert);
42
43static int _gnutls_verify_crl2 (gnutls_x509_crl_t crl,
44 const gnutls_x509_crt_t * trusted_cas,
45 int tcas_size, unsigned int flags,
46 unsigned int *output);
47
48/* Checks if two certs are identical. Return 0 on match. */
49int
50check_if_same_cert (gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2)
51{
52 gnutls_datum_t cert1bin = { NULL((void*)0), 0 }, cert2bin =
53 {
54 NULL((void*)0), 0};
55 int result;
56 opaque serial1[128], serial2[128];
57 size_t serial1_size, serial2_size;
58
59 serial1_size = sizeof (serial1);
60 result = gnutls_x509_crt_get_serial (cert1, serial1, &serial1_size);
61 if (result < 0)
62 {
63 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",63); } while(0);
;
64 goto cmp;
65 }
66
67 serial2_size = sizeof (serial2);
68 result = gnutls_x509_crt_get_serial (cert2, serial2, &serial2_size);
69 if (result < 0)
70 {
71 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",71); } while(0);
;
72 goto cmp;
73 }
74
75 if (serial2_size != serial1_size
76 || memcmp (serial1, serial2, serial1_size) != 0)
77 {
78 return 1;
79 }
80
81cmp:
82 result = _gnutls_x509_der_encode (cert1->cert, "", &cert1bin, 0);
83 if (result < 0)
84 {
85 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",85); } while(0);
;
86 goto cleanup;
87 }
88
89 result = _gnutls_x509_der_encode (cert2->cert, "", &cert2bin, 0);
90 if (result < 0)
91 {
92 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",92); } while(0);
;
93 goto cleanup;
94 }
95
96 if ((cert1bin.size == cert2bin.size) &&
97 (memcmp (cert1bin.data, cert2bin.data, cert1bin.size) == 0))
98 result = 0;
99 else
100 result = 1;
101
102cleanup:
103 _gnutls_free_datum (&cert1bin)_gnutls_free_datum_m(&cert1bin, gnutls_free);
104 _gnutls_free_datum (&cert2bin)_gnutls_free_datum_m(&cert2bin, gnutls_free);
105 return result;
106}
107
108/* Checks if the issuer of a certificate is a
109 * Certificate Authority, or if the certificate is the same
110 * as the issuer (and therefore it doesn't need to be a CA).
111 *
112 * Returns true or false, if the issuer is a CA,
113 * or not.
114 */
115static int
116check_if_ca (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,
117 unsigned int flags)
118{
119 gnutls_datum_t cert_signed_data = { NULL((void*)0), 0 };
120 gnutls_datum_t issuer_signed_data = { NULL((void*)0), 0 };
121 gnutls_datum_t cert_signature = { NULL((void*)0), 0 };
122 gnutls_datum_t issuer_signature = { NULL((void*)0), 0 };
123 int result;
124
125 /* Check if the issuer is the same with the
126 * certificate. This is added in order for trusted
127 * certificates to be able to verify themselves.
128 */
129
130 result =
131 _gnutls_x509_get_signed_data (issuer->cert, "tbsCertificate",
132 &issuer_signed_data);
133 if (result < 0)
134 {
135 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",135); } while(0);
;
136 goto cleanup;
137 }
138
139 result =
140 _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
141 &cert_signed_data);
142 if (result < 0)
143 {
144 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",144); } while(0);
;
145 goto cleanup;
146 }
147
148 result =
149 _gnutls_x509_get_signature (issuer->cert, "signature", &issuer_signature);
150 if (result < 0)
151 {
152 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",152); } while(0);
;
153 goto cleanup;
154 }
155
156 result =
157 _gnutls_x509_get_signature (cert->cert, "signature", &cert_signature);
158 if (result < 0)
159 {
160 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",160); } while(0);
;
161 goto cleanup;
162 }
163
164 /* If the subject certificate is the same as the issuer
165 * return true.
166 */
167 if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
168 if (cert_signed_data.size == issuer_signed_data.size)
169 {
170 if ((memcmp (cert_signed_data.data, issuer_signed_data.data,
171 cert_signed_data.size) == 0) &&
172 (cert_signature.size == issuer_signature.size) &&
173 (memcmp (cert_signature.data, issuer_signature.data,
174 cert_signature.size) == 0))
175 {
176 result = 1;
177 goto cleanup;
178 }
179 }
180
181 result = gnutls_x509_crt_get_ca_status (issuer, NULL((void*)0));
182 if (result == 1)
183 {
184 result = 1;
185 goto cleanup;
186 }
187 /* Handle V1 CAs that do not have a basicConstraint, but accept
188 these certs only if the appropriate flags are set. */
189 else if ((result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE-56) &&
190 ((flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT) ||
191 (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT) &&
192 (gnutls_x509_crt_check_issuer (issuer, issuer) == 1))))
193 {
194 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",194); } while(0);
;
195 result = 1;
196 goto cleanup;
197 }
198 else
199 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",199); } while(0);
;
200
201 result = 0;
202
203cleanup:
204 _gnutls_free_datum (&cert_signed_data)_gnutls_free_datum_m(&cert_signed_data, gnutls_free);
205 _gnutls_free_datum (&issuer_signed_data)_gnutls_free_datum_m(&issuer_signed_data, gnutls_free);
206 _gnutls_free_datum (&cert_signature)_gnutls_free_datum_m(&cert_signature, gnutls_free);
207 _gnutls_free_datum (&issuer_signature)_gnutls_free_datum_m(&issuer_signature, gnutls_free);
208 return result;
209}
210
211
212/* This function checks if 'certs' issuer is 'issuer_cert'.
213 * This does a straight (DER) compare of the issuer/subject fields in
214 * the given certificates.
215 *
216 * Returns 1 if they match and (0) if they don't match. Otherwise
217 * a negative error code is returned to indicate error.
218 */
219static int
220is_issuer (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer_cert)
221{
222 gnutls_datum_t dn1 = { NULL((void*)0), 0 }, dn2 =
223 {
224 NULL((void*)0), 0};
225 int ret;
226
227 ret = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn1);
228 if (ret < 0)
229 {
230 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",230); } while(0);
;
231 goto cleanup;
232 }
233
234 ret = gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
235 if (ret < 0)
236 {
237 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",237); } while(0);
;
238 goto cleanup;
239 }
240
241 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
242
243cleanup:
244 _gnutls_free_datum (&dn1)_gnutls_free_datum_m(&dn1, gnutls_free);
245 _gnutls_free_datum (&dn2)_gnutls_free_datum_m(&dn2, gnutls_free);
246 return ret;
247
248}
249
250/* Checks if the DN of two certificates is the same.
251 * Returns 1 if they match and (0) if they don't match. Otherwise
252 * a negative error code is returned to indicate error.
253 */
254int
255_gnutls_is_same_dn (gnutls_x509_crt_t cert1, gnutls_x509_crt_t cert2)
256{
257 gnutls_datum_t dn1 = { NULL((void*)0), 0 }, dn2 =
258 {
259 NULL((void*)0), 0};
260 int ret;
261
262 ret = gnutls_x509_crt_get_raw_dn (cert1, &dn1);
263 if (ret < 0)
264 {
265 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",265); } while(0);
;
266 goto cleanup;
267 }
268
269 ret = gnutls_x509_crt_get_raw_dn (cert2, &dn2);
270 if (ret < 0)
271 {
272 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",272); } while(0);
;
273 goto cleanup;
274 }
275
276 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
277
278cleanup:
279 _gnutls_free_datum (&dn1)_gnutls_free_datum_m(&dn1, gnutls_free);
280 _gnutls_free_datum (&dn2)_gnutls_free_datum_m(&dn2, gnutls_free);
281 return ret;
282}
283
284/* Finds an issuer of the certificate. If multiple issuers
285 * are present, returns one that is activated and not expired.
286 */
287static inline gnutls_x509_crt_t
288find_issuer (gnutls_x509_crt_t cert,
289 const gnutls_x509_crt_t * trusted_cas, int tcas_size)
290{
291int i;
292gnutls_x509_crt_t issuer = NULL((void*)0);
293
294 /* this is serial search.
295 */
296
297 for (i = 0; i < tcas_size; i++)
298 {
299 if (is_issuer (cert, trusted_cas[i]) == 1)
300 {
301 if (issuer == NULL((void*)0))
302 {
303 issuer = trusted_cas[i];
304 }
305 else
306 {
307 time_t now = gnutls_time(0);
308
309 if (now < gnutls_x509_crt_get_expiration_time(trusted_cas[i]) &&
310 now >= gnutls_x509_crt_get_activation_time(trusted_cas[i]))
311 {
312 issuer = trusted_cas[i];
313 }
314 }
315 }
316 }
317
318 return issuer;
319}
320
321static unsigned int
322check_time (gnutls_x509_crt_t crt, time_t now)
323{
324 int status = 0;
325 time_t t;
326
327 t = gnutls_x509_crt_get_activation_time (crt);
328 if (t == (time_t) - 1 || now < t)
329 {
330 status |= GNUTLS_CERT_NOT_ACTIVATED;
331 status |= GNUTLS_CERT_INVALID;
332 return status;
333 }
334
335 t = gnutls_x509_crt_get_expiration_time (crt);
336 if (t == (time_t) - 1 || now > t)
337 {
338 status |= GNUTLS_CERT_EXPIRED;
339 status |= GNUTLS_CERT_INVALID;
340 return status;
341 }
342
343 return 0;
344}
345
346/*
347 * Verifies the given certificate again a certificate list of
348 * trusted CAs.
349 *
350 * Returns only 0 or 1. If 1 it means that the certificate
351 * was successfuly verified.
352 *
353 * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
354 *
355 * Output will hold some extra information about the verification
356 * procedure. Issuer will hold the actual issuer from the trusted list.
357 */
358static int
359_gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
360 const gnutls_x509_crt_t * trusted_cas,
361 int tcas_size, unsigned int flags,
362 unsigned int *output,
363 gnutls_x509_crt_t * _issuer,
364 time_t now,
365 gnutls_verify_output_function func)
366{
367 gnutls_datum_t cert_signed_data = { NULL((void*)0), 0 };
368 gnutls_datum_t cert_signature = { NULL((void*)0), 0 };
369 gnutls_x509_crt_t issuer = NULL((void*)0);
370 int issuer_version, result, hash_algo;
371 unsigned int out = 0;
372
373 if (output)
374 *output = 0;
375
376 if (tcas_size >= 1)
377 issuer = find_issuer (cert, trusted_cas, tcas_size);
378 else
379 {
380 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",380); } while(0);
;
381 out = GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
382 if (output)
383 *output |= out;
384 result = 0;
385 goto cleanup;
386 }
387
388 /* issuer is not in trusted certificate
389 * authorities.
390 */
391 if (issuer == NULL((void*)0))
392 {
393 out = GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
394 if (output)
395 *output |= out;
396 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",396); } while(0);
;
397 result = 0;
398 goto cleanup;
399 }
400
401 if (_issuer != NULL((void*)0))
402 *_issuer = issuer;
403
404 issuer_version = gnutls_x509_crt_get_version (issuer);
405 if (issuer_version < 0)
406 {
407 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",407); } while(0);
;
408 return issuer_version;
409 }
410
411 if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) &&
412 ((flags & GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT)
413 || issuer_version != 1))
414 {
415 if (check_if_ca (cert, issuer, flags) == 0)
416 {
417 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",417); } while(0);
;
418 out = GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
419 if (output)
420 *output |= out;
421 result = 0;
422 goto cleanup;
423 }
424 }
425
426 result =
427 _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
428 &cert_signed_data);
429 if (result < 0)
430 {
431 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",431); } while(0);
;
432 goto cleanup;
433 }
434
435 result =
436 _gnutls_x509_get_signature (cert->cert, "signature", &cert_signature);
437 if (result < 0)
438 {
439 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",439); } while(0);
;
440 goto cleanup;
441 }
442
443 result = _gnutls_x509_get_signature_algorithm(cert->cert, "signatureAlgorithm.algorithm");
444 if (result < 0)
445 {
446 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",446); } while(0);
;
447 goto cleanup;
448 }
449
450 hash_algo = _gnutls_sign_get_hash_algorithm(result);
451
452 result =
453 _gnutls_x509_verify_data (hash_algo, &cert_signed_data, &cert_signature,
454 issuer);
455 if (result == GNUTLS_E_PK_SIG_VERIFY_FAILED-89)
456 {
457 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",457); } while(0);
;
458 out |= GNUTLS_CERT_INVALID;
459 /* error. ignore it */
460 if (output)
461 *output |= out;
462 result = 0;
463 }
464 else if (result < 0)
465 {
466 gnutls_assert()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",466); } while(0);
;
467 goto cleanup;
468 }
469
470 /* If the certificate is not self signed check if the algorithms
471 * used are secure. If the certificate is self signed it doesn't
472 * really matter.
473 */
474 if (is_issuer (cert, cert) == 0)
475 {
476 int sigalg;
477
478 sigalg = gnutls_x509_crt_get_signature_algorithm (cert);
479
480 if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
481 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
482 ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
483 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
484 {
485 out = GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
486 if (output)
487 *output |= out;
488 result = 0;
489 }
490 }
491
492 /* Check activation/expiration times
493 */
494 if (!(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS))
495 {
496 /* check the time of the issuer first */
497 if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS))
498 {
499 out |= check_time (issuer, now);
500 if (out != 0)
501 {
502 result = 0;
503 if (output) *output |= out;
504 }
505 }
506
507 out |= check_time (cert, now);
508 if (out != 0)
509 {
510 result = 0;
511 if (output) *output |= out;
512 }
513 }
514
515cleanup:
516 if (result >= 0 && func) func(cert, issuer, NULL((void*)0), out);
517 _gnutls_free_datum (&cert_signed_data)_gnutls_free_datum_m(&cert_signed_data, gnutls_free);
518 _gnutls_free_datum (&cert_signature)_gnutls_free_datum_m(&cert_signature, gnutls_free);
519
520 return result;
521}
522
523/**
524 * gnutls_x509_crt_check_issuer:
525 * @cert: is the certificate to be checked
526 * @issuer: is the certificate of a possible issuer
527 *
528 * This function will check if the given certificate was issued by the
529 * given issuer.
530 *
531 * Returns: It will return true (1) if the given certificate is issued
532 * by the given issuer, and false (0) if not. A negative error code is
533 * returned in case of an error.
534 **/
535int
536gnutls_x509_crt_check_issuer (gnutls_x509_crt_t cert,
537 gnutls_x509_crt_t issuer)
538{
539 return is_issuer (cert, issuer);
540}
541
542/* Verify X.509 certificate chain.
543 *
544 * Note that the return value is an OR of GNUTLS_CERT_* elements.
545 *
546 * This function verifies a X.509 certificate list. The certificate
547 * list should lead to a trusted certificate in order to be trusted.
548 */
549unsigned int
550_gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
551 int clist_size,
552 const gnutls_x509_crt_t * trusted_cas,
553 int tcas_size,
554 unsigned int flags,
555 gnutls_verify_output_function func)
556{
557 int i = 0, ret;
558 unsigned int status = 0, output;
559 time_t now = gnutls_time (0);
560 gnutls_x509_crt_t issuer = NULL((void*)0);
561
562 if (clist_size > 1)
563 {
564 /* Check if the last certificate in the path is self signed.
565 * In that case ignore it (a certificate is trusted only if it
566 * leads to a trusted party by us, not the server's).
567 *
568 * This prevents from verifying self signed certificates against
569 * themselves. This (although not bad) caused verification
570 * failures on some root self signed certificates that use the
571 * MD2 algorithm.
572 */
573 if (gnutls_x509_crt_check_issuer (certificate_list[clist_size - 1],
574 certificate_list[clist_size - 1]) > 0)
575 {
576 clist_size--;
577 }
578 }
579
580 /* We want to shorten the chain by removing the cert that matches
581 * one of the certs we trust and all the certs after that i.e. if
582 * cert chain is A signed-by B signed-by C signed-by D (signed-by
583 * self-signed E but already removed above), and we trust B, remove
584 * B, C and D. */
585 if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
586 i = 0; /* also replace the first one */
587 else
588 i = 1; /* do not replace the first one */
589
590 for (; i < clist_size; i++)
591 {
592 int j;
593
594 for (j = 0; j < tcas_size; j++)
595 {
596 if (check_if_same_cert (certificate_list[i], trusted_cas[j]) == 0)
597 {
598 /* explicity time check for trusted CA that we remove from
599 * list. GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS
600 */
601 if (!(flags & GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS)
602 && !(flags & GNUTLS_VERIFY_DISABLE_TIME_CHECKS))
603 {
604 status |= check_time (trusted_cas[j], now);
605 if (status != 0)
606 {
607 if (func) func(certificate_list[i], trusted_cas[j], NULL((void*)0), status);
608 return status;
609 }
610 }
611
612 if (func) func(certificate_list[i], trusted_cas[j], NULL((void*)0), status);
613 clist_size = i;
614 break;
615 }
616 }
617 /* clist_size may have been changed which gets out of loop */
618 }
619
620 if (clist_size == 0)
621 {
622 /* The certificate is already present in the trusted certificate list.
623 * Nothing to verify. */
624 return status;
625 }
626
627 /* Verify the last certificate in the certificate path
628 * against the trusted CA certificate list.
629 *
630 * If no CAs are present returns CERT_INVALID. Thus works
631 * in self signed etc certificates.
632 */
633 output = 0;
634 ret = _gnutls_verify_certificate2 (certificate_list[clist_size - 1],
635 trusted_cas, tcas_size, flags, &output,
636 &issuer, now, func);
637 if (ret == 0)
638 {
639 /* if the last certificate in the certificate
640 * list is invalid, then the certificate is not
641 * trusted.
642 */
643 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",643); } while(0);
;
644 status |= output;
645 status |= GNUTLS_CERT_INVALID;
646 return status;
647 }
648
649 /* Verify the certificate path (chain)
650 */
651 for (i = clist_size - 1; i > 0; i--)
652 {
653 output = 0;
654 if (i - 1 < 0)
655 break;
656
657 /* note that here we disable this V1 CA flag. So that no version 1
658 * certificates can exist in a supplied chain.
659 */
660 if (!(flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT))
661 flags &= ~(GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
662 if ((ret =
Although the value stored to 'ret' is used in the enclosing expression, the value is never actually read from 'ret'
663 _gnutls_verify_certificate2 (certificate_list[i - 1],
664 &certificate_list[i], 1, flags,
665 &output, NULL((void*)0), now, func)) == 0)
666 {
667 status |= output;
668 status |= GNUTLS_CERT_INVALID;
669 return status;
670 }
671 }
672
673 return 0;
674}
675
676/* This will return the appropriate hash to verify the given signature.
677 * If signature is NULL it will return an (or the) appropriate hash for
678 * the given parameters.
679 */
680int
681_gnutls_x509_verify_algorithm (gnutls_mac_algorithm_t * hash,
682 const gnutls_datum_t * signature,
683 gnutls_pk_algorithm_t pk,
684 gnutls_pk_params_st * issuer_params)
685{
686 opaque digest[MAX_HASH_SIZE64];
687 gnutls_datum_t decrypted;
688 int digest_size;
689 int ret;
690
691 switch (pk)
692 {
693 case GNUTLS_PK_DSA:
694 case GNUTLS_PK_EC:
695
696 if (hash)
697 *hash = _gnutls_dsa_q_to_hash (pk, issuer_params, NULL((void*)0));
698
699 ret = 0;
700 break;
701 case GNUTLS_PK_RSA:
702 if (signature == NULL((void*)0))
703 { /* return a sensible algorithm */
704 if (hash)
705 *hash = GNUTLS_DIG_SHA256;
706 return 0;
707 }
708
709 ret =
710 _gnutls_pkcs1_rsa_decrypt (&decrypted, signature,
711 issuer_params, 1);
712
713
714 if (ret < 0)
715 {
716 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",716); } while(0);
;
717 goto cleanup;
718 }
719
720 digest_size = sizeof (digest);
721 if ((ret =
722 decode_ber_digest_info (&decrypted, hash, digest,
723 &digest_size)) != 0)
724 {
725 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",725); } while(0);
;
726 _gnutls_free_datum (&decrypted)_gnutls_free_datum_m(&decrypted, gnutls_free);
727 goto cleanup;
728 }
729
730 _gnutls_free_datum (&decrypted)_gnutls_free_datum_m(&decrypted, gnutls_free);
731 if (digest_size != _gnutls_hash_get_algo_len (*hash))
732 {
733 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",733); } while(0);
;
734 ret = GNUTLS_E_ASN1_GENERIC_ERROR-71;
735 goto cleanup;
736 }
737
738 ret = 0;
739 break;
740
741 default:
742 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",742); } while(0);
;
743 ret = GNUTLS_E_INTERNAL_ERROR-59;
744 }
745
746cleanup:
747
748 return ret;
749
750}
751
752/* verifies if the certificate is properly signed.
753 * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success.
754 *
755 * 'data' is the signed data
756 * 'signature' is the signature!
757 */
758int
759_gnutls_x509_verify_data (gnutls_digest_algorithm_t algo,
760 const gnutls_datum_t * data,
761 const gnutls_datum_t * signature,
762 gnutls_x509_crt_t issuer)
763{
764 gnutls_pk_params_st issuer_params;
765 int ret;
766
767 /* Read the MPI parameters from the issuer's certificate.
768 */
769 ret =
770 _gnutls_x509_crt_get_mpis (issuer, &issuer_params);
771 if (ret < 0)
772 {
773 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",773); } while(0);
;
774 return ret;
775 }
776
777 ret =
778 pubkey_verify_data (gnutls_x509_crt_get_pk_algorithm (issuer, NULL((void*)0)), algo,
779 data, signature, &issuer_params);
780 if (ret < 0)
781 {
782 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",782); } while(0);
;
783 }
784
785 /* release all allocated MPIs
786 */
787 gnutls_pk_params_release(&issuer_params);
788
789 return ret;
790}
791
792int
793_gnutls_x509_verify_hashed_data (const gnutls_datum_t * hash,
794 const gnutls_datum_t * signature,
795 gnutls_x509_crt_t issuer)
796{
797 gnutls_pk_params_st issuer_params;
798 int ret;
799
800 /* Read the MPI parameters from the issuer's certificate.
801 */
802 ret =
803 _gnutls_x509_crt_get_mpis (issuer, &issuer_params);
804 if (ret < 0)
805 {
806 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",806); } while(0);
;
807 return ret;
808 }
809
810 ret =
811 pubkey_verify_hashed_data (gnutls_x509_crt_get_pk_algorithm (issuer, NULL((void*)0)),
812 hash, signature, &issuer_params);
813 if (ret < 0)
814 {
815 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",815); } while(0);
;
816 }
817
818 /* release all allocated MPIs
819 */
820 gnutls_pk_params_release(&issuer_params);
821
822 return ret;
823}
824
825/**
826 * gnutls_x509_crt_list_verify:
827 * @cert_list: is the certificate list to be verified
828 * @cert_list_length: holds the number of certificate in cert_list
829 * @CA_list: is the CA list which will be used in verification
830 * @CA_list_length: holds the number of CA certificate in CA_list
831 * @CRL_list: holds a list of CRLs.
832 * @CRL_list_length: the length of CRL list.
833 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
834 * @verify: will hold the certificate verification output.
835 *
836 * This function will try to verify the given certificate list and
837 * return its status. If no flags are specified (0), this function
838 * will use the basicConstraints (2.5.29.19) PKIX extension. This
839 * means that only a certificate authority is allowed to sign a
840 * certificate.
841 *
842 * You must also check the peer's name in order to check if the verified
843 * certificate belongs to the actual peer.
844 *
845 * The certificate verification output will be put in @verify and will
846 * be one or more of the gnutls_certificate_status_t enumerated
847 * elements bitwise or'd. For a more detailed verification status use
848 * gnutls_x509_crt_verify() per list element.
849 *
850 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
851 * negative error value.
852 **/
853int
854gnutls_x509_crt_list_verify (const gnutls_x509_crt_t * cert_list,
855 int cert_list_length,
856 const gnutls_x509_crt_t * CA_list,
857 int CA_list_length,
858 const gnutls_x509_crl_t * CRL_list,
859 int CRL_list_length, unsigned int flags,
860 unsigned int *verify)
861{
862int i, ret;
863
864 if (cert_list == NULL((void*)0) || cert_list_length == 0)
865 return GNUTLS_E_NO_CERTIFICATE_FOUND-49;
866
867 /* Verify certificate
868 */
869 *verify =
870 _gnutls_x509_verify_certificate (cert_list, cert_list_length,
871 CA_list, CA_list_length,
872 flags, NULL((void*)0));
873
874 /* Check for revoked certificates in the chain.
875 */
876#ifdef ENABLE_PKI1
877 for (i = 0; i < cert_list_length; i++)
878 {
879 ret = gnutls_x509_crt_check_revocation (cert_list[i],
880 CRL_list, CRL_list_length);
881 if (ret == 1)
882 { /* revoked */
883 *verify |= GNUTLS_CERT_REVOKED;
884 *verify |= GNUTLS_CERT_INVALID;
885 }
886 }
887#endif
888
889 return 0;
890}
891
892/**
893 * gnutls_x509_crt_verify:
894 * @cert: is the certificate to be verified
895 * @CA_list: is one certificate that is considered to be trusted one
896 * @CA_list_length: holds the number of CA certificate in CA_list
897 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
898 * @verify: will hold the certificate verification output.
899 *
900 * This function will try to verify the given certificate and return
901 * its status.
902 *
903 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
904 * negative error value.
905 **/
906int
907gnutls_x509_crt_verify (gnutls_x509_crt_t cert,
908 const gnutls_x509_crt_t * CA_list,
909 int CA_list_length, unsigned int flags,
910 unsigned int *verify)
911{
912 /* Verify certificate
913 */
914 *verify =
915 _gnutls_x509_verify_certificate (&cert, 1,
916 CA_list, CA_list_length,
917 flags, NULL((void*)0));
918 return 0;
919}
920
921
922
923#ifdef ENABLE_PKI1
924
925/**
926 * gnutls_x509_crl_check_issuer:
927 * @crl: is the CRL to be checked
928 * @issuer: is the certificate of a possible issuer
929 *
930 * This function will check if the given CRL was issued by the given
931 * issuer certificate. It will return true (1) if the given CRL was
932 * issued by the given issuer, and false (0) if not.
933 *
934 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
935 * negative error value.
936 **/
937int
938gnutls_x509_crl_check_issuer (gnutls_x509_crl_t crl,
939 gnutls_x509_crt_t issuer)
940{
941 return is_crl_issuer (crl, issuer);
942}
943
944/**
945 * gnutls_x509_crl_verify:
946 * @crl: is the crl to be verified
947 * @CA_list: is a certificate list that is considered to be trusted one
948 * @CA_list_length: holds the number of CA certificates in CA_list
949 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
950 * @verify: will hold the crl verification output.
951 *
952 * This function will try to verify the given crl and return its status.
953 * See gnutls_x509_crt_list_verify() for a detailed description of
954 * return values.
955 *
956 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
957 * negative error value.
958 **/
959int
960gnutls_x509_crl_verify (gnutls_x509_crl_t crl,
961 const gnutls_x509_crt_t * CA_list,
962 int CA_list_length, unsigned int flags,
963 unsigned int *verify)
964{
965 int ret;
966 /* Verify crl
967 */
968 ret = _gnutls_verify_crl2 (crl, CA_list, CA_list_length, flags, verify);
969 if (ret < 0)
970 {
971 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",971); } while(0);
;
972 return ret;
973 }
974
975 return 0;
976}
977
978
979/* The same as above, but here we've got a CRL.
980 */
981static int
982is_crl_issuer (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer_cert)
983{
984 gnutls_datum_t dn1 = { NULL((void*)0), 0 }, dn2 =
985 {
986 NULL((void*)0), 0};
987 int ret;
988
989 ret = gnutls_x509_crl_get_raw_issuer_dn (crl, &dn1);
990 if (ret < 0)
991 {
992 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",992); } while(0);
;
993 goto cleanup;
994 }
995
996 ret = gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
997 if (ret < 0)
998 {
999 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",999); } while(0);
;
1000 return ret;
1001 }
1002
1003 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
1004
1005cleanup:
1006 _gnutls_free_datum (&dn1)_gnutls_free_datum_m(&dn1, gnutls_free);
1007 _gnutls_free_datum (&dn2)_gnutls_free_datum_m(&dn2, gnutls_free);
1008
1009 return ret;
1010}
1011
1012static inline gnutls_x509_crt_t
1013find_crl_issuer (gnutls_x509_crl_t crl,
1014 const gnutls_x509_crt_t * trusted_cas, int tcas_size)
1015{
1016 int i;
1017
1018 /* this is serial search.
1019 */
1020
1021 for (i = 0; i < tcas_size; i++)
1022 {
1023 if (is_crl_issuer (crl, trusted_cas[i]) == 1)
1024 return trusted_cas[i];
1025 }
1026
1027 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",1027); } while(0);
;
1028 return NULL((void*)0);
1029}
1030
1031/*
1032 * Returns only 0 or 1. If 1 it means that the CRL
1033 * was successfuly verified.
1034 *
1035 * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
1036 *
1037 * Output will hold information about the verification
1038 * procedure.
1039 */
1040static int
1041_gnutls_verify_crl2 (gnutls_x509_crl_t crl,
1042 const gnutls_x509_crt_t * trusted_cas,
1043 int tcas_size, unsigned int flags, unsigned int *output)
1044{
1045/* CRL is ignored for now */
1046 gnutls_datum_t crl_signed_data = { NULL((void*)0), 0 };
1047 gnutls_datum_t crl_signature = { NULL((void*)0), 0 };
1048 gnutls_x509_crt_t issuer;
1049 int result, hash_algo;
1050
1051 if (output)
1052 *output = 0;
1053
1054 if (tcas_size >= 1)
1055 issuer = find_crl_issuer (crl, trusted_cas, tcas_size);
1056 else
1057 {
1058 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",1058); } while(0);
;
1059 if (output)
1060 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
1061 return 0;
1062 }
1063
1064 /* issuer is not in trusted certificate
1065 * authorities.
1066 */
1067 if (issuer == NULL((void*)0))
1068 {
1069 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",1069); } while(0);
;
1070 if (output)
1071 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
1072 return 0;
1073 }
1074
1075 if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN))
1076 {
1077 if (gnutls_x509_crt_get_ca_status (issuer, NULL((void*)0)) != 1)
1078 {
1079 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",1079); } while(0);
;
1080 if (output)
1081 *output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
1082 return 0;
1083 }
1084 }
1085
1086 result =
1087 _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data);
1088 if (result < 0)
1089 {
1090 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",1090); } while(0);
;
1091 goto cleanup;
1092 }
1093
1094 result = _gnutls_x509_get_signature (crl->crl, "signature", &crl_signature);
1095 if (result < 0)
1096 {
1097 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",1097); } while(0);
;
1098 goto cleanup;
1099 }
1100
1101 result = _gnutls_x509_get_signature_algorithm(crl->crl, "signatureAlgorithm.algorithm");
1102 if (result < 0)
1103 {
1104 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",1104); } while(0);
;
1105 goto cleanup;
1106 }
1107
1108 hash_algo = _gnutls_sign_get_hash_algorithm(result);
1109
1110 result =
1111 _gnutls_x509_verify_data (hash_algo, &crl_signed_data, &crl_signature,
1112 issuer);
1113 if (result == GNUTLS_E_PK_SIG_VERIFY_FAILED-89)
1114 {
1115 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",1115); } while(0);
;
1116 /* error. ignore it */
1117 if (output)
1118 *output |= GNUTLS_CERT_INVALID;
1119 result = 0;
1120 }
1121 else if (result < 0)
1122 {
1123 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "verify.c",1123); } while(0);
;
1124 goto cleanup;
1125 }
1126
1127 {
1128 int sigalg;
1129
1130 sigalg = gnutls_x509_crl_get_signature_algorithm (crl);
1131
1132 if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
1133 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
1134 ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
1135 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
1136 {
1137 if (output)
1138 *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
1139 result = 0;
1140 }
1141 }
1142
1143cleanup:
1144 _gnutls_free_datum (&crl_signed_data)_gnutls_free_datum_m(&crl_signed_data, gnutls_free);
1145 _gnutls_free_datum (&crl_signature)_gnutls_free_datum_m(&crl_signature, gnutls_free);
1146
1147 return result;
1148}
1149
1150#endif