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' |
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 | |
40 | static int is_crl_issuer (gnutls_x509_crl_t crl, |
41 | gnutls_x509_crt_t issuer_cert); |
42 | |
43 | static 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. */ |
49 | int |
50 | check_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 | |
81 | cmp: |
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 | |
102 | cleanup: |
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 | */ |
115 | static int |
116 | check_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 | |
203 | cleanup: |
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 | */ |
219 | static int |
220 | is_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 | |
243 | cleanup: |
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 | */ |
254 | int |
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 | |
278 | cleanup: |
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 | */ |
287 | static inline gnutls_x509_crt_t |
288 | find_issuer (gnutls_x509_crt_t cert, |
289 | const gnutls_x509_crt_t * trusted_cas, int tcas_size) |
290 | { |
291 | int i; |
292 | gnutls_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 | |
321 | static unsigned int |
322 | check_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 | */ |
358 | static 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 | |
515 | cleanup: |
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 | **/ |
535 | int |
536 | gnutls_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 | */ |
549 | unsigned 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 | */ |
680 | int |
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 | |
746 | cleanup: |
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 | */ |
758 | int |
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 | |
792 | int |
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 | **/ |
853 | int |
854 | gnutls_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 | { |
862 | int 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 | **/ |
906 | int |
907 | gnutls_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 | **/ |
937 | int |
938 | gnutls_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 | **/ |
959 | int |
960 | gnutls_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 | */ |
981 | static int |
982 | is_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 | |
1005 | cleanup: |
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 | |
1012 | static inline gnutls_x509_crt_t |
1013 | find_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 | */ |
1040 | static 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 | |
1143 | cleanup: |
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 |