]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/x509/x509_vfy.c
PKCS7_verify() performance optimization. When the content is large and a
[thirdparty/openssl.git] / crypto / x509 / x509_vfy.c
CommitLineData
d02b48c6 1/* crypto/x509/x509_vfy.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <time.h>
61#include <errno.h>
d02b48c6
RE
62
63#include "cryptlib.h"
17f389bb 64#include <openssl/crypto.h>
ec577822
BM
65#include <openssl/lhash.h>
66#include <openssl/buffer.h>
67#include <openssl/evp.h>
68#include <openssl/asn1.h>
69#include <openssl/x509.h>
11262391 70#include <openssl/x509v3.h>
ec577822 71#include <openssl/objects.h>
d02b48c6 72
d02b48c6 73static int null_callback(int ok,X509_STORE_CTX *e);
2f043896
DSH
74static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
75static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
30b415b0 76static int check_chain_extensions(X509_STORE_CTX *ctx);
51630a37 77static int check_trust(X509_STORE_CTX *ctx);
b545dc67
DSH
78static int check_revocation(X509_STORE_CTX *ctx);
79static int check_cert(X509_STORE_CTX *ctx);
5d7c222d 80static int check_policy(X509_STORE_CTX *ctx);
d02b48c6 81static int internal_verify(X509_STORE_CTX *ctx);
e778802f 82const char *X509_version="X.509" OPENSSL_VERSION_PTEXT;
b4cadc6e 83
d02b48c6 84
6b691a5c 85static int null_callback(int ok, X509_STORE_CTX *e)
d02b48c6 86 {
f684090c 87 return ok;
d02b48c6
RE
88 }
89
90#if 0
6b691a5c 91static int x509_subject_cmp(X509 **a, X509 **b)
d02b48c6 92 {
f684090c 93 return X509_subject_name_cmp(*a,*b);
d02b48c6
RE
94 }
95#endif
96
6b691a5c 97int X509_verify_cert(X509_STORE_CTX *ctx)
d02b48c6
RE
98 {
99 X509 *x,*xtmp,*chain_ss=NULL;
100 X509_NAME *xn;
5d7c222d
DSH
101 int bad_chain = 0;
102 X509_VERIFY_PARAM *param = ctx->param;
d02b48c6
RE
103 int depth,i,ok=0;
104 int num;
105 int (*cb)();
f73e07cf 106 STACK_OF(X509) *sktmp=NULL;
d02b48c6
RE
107 if (ctx->cert == NULL)
108 {
109 X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
f684090c 110 return -1;
d02b48c6
RE
111 }
112
2f043896 113 cb=ctx->verify_cb;
d02b48c6
RE
114
115 /* first we make sure the chain we are going to build is
116 * present and that the first entry is in place */
117 if (ctx->chain == NULL)
118 {
7e258a56
BL
119 if ( ((ctx->chain=sk_X509_new_null()) == NULL) ||
120 (!sk_X509_push(ctx->chain,ctx->cert)))
d02b48c6
RE
121 {
122 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
123 goto end;
124 }
125 CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509);
126 ctx->last_untrusted=1;
127 }
128
f76d8c47 129 /* We use a temporary STACK so we can chop and hack at it */
f73e07cf
BL
130 if (ctx->untrusted != NULL
131 && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
d02b48c6
RE
132 {
133 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
134 goto end;
135 }
136
7e258a56
BL
137 num=sk_X509_num(ctx->chain);
138 x=sk_X509_value(ctx->chain,num-1);
5d7c222d 139 depth=param->depth;
d02b48c6
RE
140
141
142 for (;;)
143 {
144 /* If we have enough, we break */
d797727b 145 if (depth < num) break; /* FIXME: If this happens, we should take
a9642be6
BM
146 * note of it and, if appropriate, use the
147 * X509_V_ERR_CERT_CHAIN_TOO_LONG error
148 * code later.
149 */
d02b48c6
RE
150
151 /* If we are self signed, we break */
152 xn=X509_get_issuer_name(x);
2f043896 153 if (ctx->check_issued(ctx, x,x)) break;
d02b48c6
RE
154
155 /* If we were passed a cert chain, use it first */
156 if (ctx->untrusted != NULL)
157 {
2f043896 158 xtmp=find_issuer(ctx, sktmp,x);
d02b48c6
RE
159 if (xtmp != NULL)
160 {
7e258a56 161 if (!sk_X509_push(ctx->chain,xtmp))
d02b48c6
RE
162 {
163 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
164 goto end;
165 }
166 CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
f73e07cf 167 sk_X509_delete_ptr(sktmp,xtmp);
d02b48c6
RE
168 ctx->last_untrusted++;
169 x=xtmp;
170 num++;
171 /* reparse the full chain for
172 * the next one */
173 continue;
174 }
175 }
176 break;
177 }
178
179 /* at this point, chain should contain a list of untrusted
180 * certificates. We now need to add at least one trusted one,
181 * if possible, otherwise we complain. */
182
2f043896
DSH
183 /* Examine last certificate in chain and see if it
184 * is self signed.
185 */
186
7e258a56
BL
187 i=sk_X509_num(ctx->chain);
188 x=sk_X509_value(ctx->chain,i-1);
f76d8c47 189 xn = X509_get_subject_name(x);
2f043896 190 if (ctx->check_issued(ctx, x, x))
d02b48c6
RE
191 {
192 /* we have a self signed certificate */
7e258a56 193 if (sk_X509_num(ctx->chain) == 1)
d02b48c6 194 {
f76d8c47
DSH
195 /* We have a single self signed certificate: see if
196 * we can find it in the store. We must have an exact
197 * match to avoid possible impersonation.
198 */
2f043896
DSH
199 ok = ctx->get_issuer(&xtmp, ctx, x);
200 if ((ok <= 0) || X509_cmp(x, xtmp))
f76d8c47
DSH
201 {
202 ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
203 ctx->current_cert=x;
204 ctx->error_depth=i-1;
b7c190d9 205 if (ok == 1) X509_free(xtmp);
5d7c222d 206 bad_chain = 1;
f76d8c47
DSH
207 ok=cb(0,ctx);
208 if (!ok) goto end;
209 }
210 else
211 {
212 /* We have a match: replace certificate with store version
213 * so we get any trust settings.
214 */
215 X509_free(x);
2f043896 216 x = xtmp;
f76d8c47
DSH
217 sk_X509_set(ctx->chain, i - 1, x);
218 ctx->last_untrusted=0;
219 }
d02b48c6
RE
220 }
221 else
222 {
2f043896 223 /* extract and save self signed certificate for later use */
7e258a56 224 chain_ss=sk_X509_pop(ctx->chain);
d02b48c6
RE
225 ctx->last_untrusted--;
226 num--;
7e258a56 227 x=sk_X509_value(ctx->chain,num-1);
d02b48c6
RE
228 }
229 }
230
231 /* We now lookup certs from the certificate store */
232 for (;;)
233 {
234 /* If we have enough, we break */
7f89714e 235 if (depth < num) break;
d02b48c6
RE
236
237 /* If we are self signed, we break */
238 xn=X509_get_issuer_name(x);
2f043896 239 if (ctx->check_issued(ctx,x,x)) break;
d02b48c6 240
2f043896
DSH
241 ok = ctx->get_issuer(&xtmp, ctx, x);
242
243 if (ok < 0) return ok;
b7c190d9 244 if (ok == 0) break;
2f043896
DSH
245
246 x = xtmp;
247 if (!sk_X509_push(ctx->chain,x))
d02b48c6 248 {
2f043896 249 X509_free(xtmp);
d02b48c6 250 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
f684090c 251 return 0;
d02b48c6
RE
252 }
253 num++;
254 }
255
256 /* we now have our chain, lets check it... */
257 xn=X509_get_issuer_name(x);
2f043896
DSH
258
259 /* Is last certificate looked up self signed? */
260 if (!ctx->check_issued(ctx,x,x))
d02b48c6 261 {
2f043896 262 if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
d02b48c6
RE
263 {
264 if (ctx->last_untrusted >= num)
265 ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
266 else
267 ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
268 ctx->current_cert=x;
269 }
270 else
271 {
272
7e258a56 273 sk_X509_push(ctx->chain,chain_ss);
d02b48c6
RE
274 num++;
275 ctx->last_untrusted=num;
276 ctx->current_cert=chain_ss;
277 ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
278 chain_ss=NULL;
279 }
280
281 ctx->error_depth=num-1;
5d7c222d 282 bad_chain = 1;
d02b48c6
RE
283 ok=cb(0,ctx);
284 if (!ok) goto end;
285 }
286
11262391 287 /* We have the chain complete: now we need to check its purpose */
30b415b0 288 ok = check_chain_extensions(ctx);
11262391 289
b7c190d9 290 if (!ok) goto end;
11262391 291
51630a37
DSH
292 /* The chain extensions are OK: check trust */
293
5d7c222d 294 if (param->trust > 0) ok = check_trust(ctx);
51630a37 295
b7c190d9 296 if (!ok) goto end;
51630a37 297
d02b48c6
RE
298 /* We may as well copy down any DSA parameters that are required */
299 X509_get_pubkey_parameters(NULL,ctx->chain);
300
b545dc67
DSH
301 /* Check revocation status: we do this after copying parameters
302 * because they may be needed for CRL signature verification.
303 */
304
305 ok = ctx->check_revocation(ctx);
306 if(!ok) goto end;
307
5d7c222d 308 /* At this point, we have a chain and need to verify it */
2f043896
DSH
309 if (ctx->verify != NULL)
310 ok=ctx->verify(ctx);
d02b48c6
RE
311 else
312 ok=internal_verify(ctx);
5d7c222d
DSH
313 if(!ok) goto end;
314
315 /* If we get this far evaluate policies */
316 if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
317 ok = ctx->check_policy(ctx);
318 if(!ok) goto end;
dfeab068
RE
319 if (0)
320 {
d02b48c6 321end:
dfeab068
RE
322 X509_get_pubkey_parameters(NULL,ctx->chain);
323 }
f73e07cf 324 if (sktmp != NULL) sk_X509_free(sktmp);
d02b48c6 325 if (chain_ss != NULL) X509_free(chain_ss);
f684090c 326 return ok;
d02b48c6
RE
327 }
328
2f043896
DSH
329
330/* Given a STACK_OF(X509) find the issuer of cert (if any)
331 */
332
333static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
334{
335 int i;
336 X509 *issuer;
b7c190d9 337 for (i = 0; i < sk_X509_num(sk); i++)
82aec1cc 338 {
2f043896 339 issuer = sk_X509_value(sk, i);
b7c190d9 340 if (ctx->check_issued(ctx, x, issuer))
82aec1cc
BM
341 return issuer;
342 }
2f043896
DSH
343 return NULL;
344}
345
346/* Given a possible certificate and issuer check them */
347
348static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
349{
350 int ret;
351 ret = X509_check_issued(issuer, x);
82aec1cc
BM
352 if (ret == X509_V_OK)
353 return 1;
dbba890c 354 /* If we haven't asked for issuer errors don't set ctx */
5d7c222d 355 if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
dbba890c
DSH
356 return 0;
357
358 ctx->error = ret;
359 ctx->current_cert = x;
360 ctx->current_issuer = issuer;
bdee69f7 361 return ctx->verify_cb(0, ctx);
2f043896
DSH
362 return 0;
363}
364
365/* Alternative lookup method: look from a STACK stored in other_ctx */
366
367static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
368{
369 *issuer = find_issuer(ctx, ctx->other_ctx, x);
82aec1cc
BM
370 if (*issuer)
371 {
2f043896
DSH
372 CRYPTO_add(&(*issuer)->references,1,CRYPTO_LOCK_X509);
373 return 1;
82aec1cc
BM
374 }
375 else
376 return 0;
2f043896
DSH
377}
378
379
11262391
DSH
380/* Check a certificate chains extensions for consistency
381 * with the supplied purpose
382 */
383
30b415b0 384static int check_chain_extensions(X509_STORE_CTX *ctx)
11262391 385{
cf1b7d96 386#ifdef OPENSSL_NO_CHAIN_VERIFY
11262391
DSH
387 return 1;
388#else
30b415b0 389 int i, ok=0, must_be_ca;
11262391
DSH
390 X509 *x;
391 int (*cb)();
6951c23a 392 int proxy_path_length = 0;
2f043896 393 cb=ctx->verify_cb;
30b415b0
RL
394
395 /* must_be_ca can have 1 of 3 values:
396 -1: we accept both CA and non-CA certificates, to allow direct
397 use of self-signed certificates (which are marked as CA).
398 0: we only accept non-CA certificates. This is currently not
399 used, but the possibility is present for future extensions.
400 1: we only accept CA certificates. This is currently used for
401 all certificates in the chain except the leaf certificate.
402 */
403 must_be_ca = -1;
11262391 404 /* Check all untrusted certificates */
b7c190d9 405 for (i = 0; i < ctx->last_untrusted; i++)
82aec1cc 406 {
bc501570 407 int ret;
11262391 408 x = sk_X509_value(ctx->chain, i);
5d7c222d 409 if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
f1558bb4
DSH
410 && (x->ex_flags & EXFLAG_CRITICAL))
411 {
412 ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
413 ctx->error_depth = i;
414 ctx->current_cert = x;
415 ok=cb(0,ctx);
416 if (!ok) goto end;
417 }
30b415b0
RL
418 ret = X509_check_ca(x);
419 switch(must_be_ca)
82aec1cc 420 {
30b415b0
RL
421 case -1:
422 if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
423 && (ret != 1) && (ret != 0))
424 {
425 ret = 0;
82aec1cc 426 ctx->error = X509_V_ERR_INVALID_CA;
30b415b0 427 }
82aec1cc 428 else
30b415b0
RL
429 ret = 1;
430 break;
431 case 0:
432 if (ret != 0)
433 {
434 ret = 0;
435 ctx->error = X509_V_ERR_INVALID_NON_CA;
436 }
437 else
438 ret = 1;
439 break;
440 default:
441 if ((ret == 0)
442 || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
443 && (ret != 1)))
444 {
445 ret = 0;
446 ctx->error = X509_V_ERR_INVALID_CA;
447 }
448 else
449 ret = 1;
450 break;
451 }
452 if (ret == 0)
453 {
11262391
DSH
454 ctx->error_depth = i;
455 ctx->current_cert = x;
456 ok=cb(0,ctx);
82aec1cc
BM
457 if (!ok) goto end;
458 }
30b415b0
RL
459 if (ctx->param->purpose > 0)
460 {
461 ret = X509_check_purpose(x, ctx->param->purpose,
462 must_be_ca > 0);
463 if ((ret == 0)
464 || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
465 && (ret != 1)))
466 {
467 ctx->error = X509_V_ERR_INVALID_PURPOSE;
468 ctx->error_depth = i;
469 ctx->current_cert = x;
470 ok=cb(0,ctx);
471 if (!ok) goto end;
472 }
473 }
11262391 474 /* Check pathlen */
b7c190d9 475 if ((i > 1) && (x->ex_pathlen != -1)
6951c23a 476 && (i > (x->ex_pathlen + proxy_path_length + 1)))
82aec1cc 477 {
11262391
DSH
478 ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
479 ctx->error_depth = i;
480 ctx->current_cert = x;
481 ok=cb(0,ctx);
82aec1cc
BM
482 if (!ok) goto end;
483 }
6951c23a
RL
484 /* If this certificate is a proxy certificate, the next
485 certificate must be another proxy certificate or a EE
486 certificate. If not, the next certificate must be a
487 CA certificate. */
488 if (x->ex_flags & EXFLAG_PROXY)
489 {
490 if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen)
491 {
492 ctx->error =
493 X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
494 ctx->error_depth = i;
495 ctx->current_cert = x;
496 ok=cb(0,ctx);
497 if (!ok) goto end;
498 }
499 proxy_path_length++;
500 must_be_ca = 0;
501 }
502 else
503 must_be_ca = 1;
11262391 504 }
11262391 505 ok = 1;
82aec1cc 506 end:
f684090c 507 return ok;
11262391
DSH
508#endif
509}
510
51630a37
DSH
511static int check_trust(X509_STORE_CTX *ctx)
512{
cf1b7d96 513#ifdef OPENSSL_NO_CHAIN_VERIFY
51630a37
DSH
514 return 1;
515#else
516 int i, ok;
517 X509 *x;
518 int (*cb)();
2f043896 519 cb=ctx->verify_cb;
51630a37
DSH
520/* For now just check the last certificate in the chain */
521 i = sk_X509_num(ctx->chain) - 1;
522 x = sk_X509_value(ctx->chain, i);
5d7c222d 523 ok = X509_check_trust(x, ctx->param->trust, 0);
82aec1cc
BM
524 if (ok == X509_TRUST_TRUSTED)
525 return 1;
b545dc67 526 ctx->error_depth = i;
51630a37 527 ctx->current_cert = x;
82aec1cc
BM
528 if (ok == X509_TRUST_REJECTED)
529 ctx->error = X509_V_ERR_CERT_REJECTED;
530 else
531 ctx->error = X509_V_ERR_CERT_UNTRUSTED;
51630a37 532 ok = cb(0, ctx);
f684090c 533 return ok;
51630a37
DSH
534#endif
535}
536
b545dc67
DSH
537static int check_revocation(X509_STORE_CTX *ctx)
538 {
539 int i, last, ok;
5d7c222d 540 if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
b545dc67 541 return 1;
5d7c222d 542 if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
b545dc67 543 last = sk_X509_num(ctx->chain) - 1;
50078051
DSH
544 else
545 last = 0;
b545dc67
DSH
546 for(i = 0; i <= last; i++)
547 {
548 ctx->error_depth = i;
549 ok = check_cert(ctx);
550 if (!ok) return ok;
551 }
552 return 1;
553 }
554
555static int check_cert(X509_STORE_CTX *ctx)
556 {
557 X509_CRL *crl = NULL;
558 X509 *x;
559 int ok, cnum;
560 cnum = ctx->error_depth;
561 x = sk_X509_value(ctx->chain, cnum);
562 ctx->current_cert = x;
563 /* Try to retrieve relevant CRL */
564 ok = ctx->get_crl(ctx, &crl, x);
565 /* If error looking up CRL, nothing we can do except
566 * notify callback
567 */
568 if(!ok)
569 {
570 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
bdee69f7 571 ok = ctx->verify_cb(0, ctx);
b545dc67
DSH
572 goto err;
573 }
574 ctx->current_crl = crl;
575 ok = ctx->check_crl(ctx, crl);
576 if (!ok) goto err;
577 ok = ctx->cert_crl(ctx, crl, x);
578 err:
579 ctx->current_crl = NULL;
580 X509_CRL_free(crl);
581 return ok;
582
583 }
584
e1a27eb3
DSH
585/* Check CRL times against values in X509_STORE_CTX */
586
587static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
588 {
589 time_t *ptime;
590 int i;
591 ctx->current_crl = crl;
5d7c222d
DSH
592 if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
593 ptime = &ctx->param->check_time;
e1a27eb3
DSH
594 else
595 ptime = NULL;
596
597 i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
598 if (i == 0)
599 {
600 ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
601 if (!notify || !ctx->verify_cb(0, ctx))
602 return 0;
603 }
604
605 if (i > 0)
606 {
607 ctx->error=X509_V_ERR_CRL_NOT_YET_VALID;
608 if (!notify || !ctx->verify_cb(0, ctx))
609 return 0;
610 }
611
612 if(X509_CRL_get_nextUpdate(crl))
613 {
614 i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
615
616 if (i == 0)
617 {
618 ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
619 if (!notify || !ctx->verify_cb(0, ctx))
620 return 0;
621 }
622
623 if (i < 0)
624 {
625 ctx->error=X509_V_ERR_CRL_HAS_EXPIRED;
626 if (!notify || !ctx->verify_cb(0, ctx))
627 return 0;
628 }
629 }
630
631 ctx->current_crl = NULL;
632
633 return 1;
634 }
635
636/* Lookup CRLs from the supplied list. Look for matching isser name
637 * and validity. If we can't find a valid CRL return the last one
638 * with matching name. This gives more meaningful error codes. Otherwise
639 * we'd get a CRL not found error if a CRL existed with matching name but
640 * was invalid.
641 */
642
643static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl,
644 X509_NAME *nm, STACK_OF(X509_CRL) *crls)
645 {
646 int i;
647 X509_CRL *crl, *best_crl = NULL;
648 for (i = 0; i < sk_X509_CRL_num(crls); i++)
649 {
650 crl = sk_X509_CRL_value(crls, i);
651 if (X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
652 continue;
653 if (check_crl_time(ctx, crl, 0))
654 {
655 *pcrl = crl;
656 CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509);
657 return 1;
658 }
659 best_crl = crl;
660 }
661 if (best_crl)
662 {
663 *pcrl = best_crl;
664 CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509);
665 }
666
667 return 0;
668 }
669
b545dc67
DSH
670/* Retrieve CRL corresponding to certificate: currently just a
671 * subject lookup: maybe use AKID later...
b545dc67 672 */
e1a27eb3 673static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x)
b545dc67
DSH
674 {
675 int ok;
e1a27eb3 676 X509_CRL *crl = NULL;
b545dc67 677 X509_OBJECT xobj;
e1a27eb3
DSH
678 X509_NAME *nm;
679 nm = X509_get_issuer_name(x);
680 ok = get_crl_sk(ctx, &crl, nm, ctx->crls);
681 if (ok)
682 {
683 *pcrl = crl;
684 return 1;
685 }
686
687 ok = X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj);
688
689 if (!ok)
690 {
691 /* If we got a near match from get_crl_sk use that */
692 if (crl)
693 {
694 *pcrl = crl;
695 return 1;
696 }
697 return 0;
698 }
699
700 *pcrl = xobj.data.crl;
701 if (crl)
702 X509_CRL_free(crl);
b545dc67
DSH
703 return 1;
704 }
705
706/* Check CRL validity */
707static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
708 {
709 X509 *issuer = NULL;
710 EVP_PKEY *ikey = NULL;
e1a27eb3 711 int ok = 0, chnum, cnum;
b545dc67
DSH
712 cnum = ctx->error_depth;
713 chnum = sk_X509_num(ctx->chain) - 1;
714 /* Find CRL issuer: if not last certificate then issuer
715 * is next certificate in chain.
716 */
717 if(cnum < chnum)
718 issuer = sk_X509_value(ctx->chain, cnum + 1);
719 else
720 {
721 issuer = sk_X509_value(ctx->chain, chnum);
722 /* If not self signed, can't check signature */
723 if(!ctx->check_issued(ctx, issuer, issuer))
724 {
725 ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
bdee69f7 726 ok = ctx->verify_cb(0, ctx);
b545dc67
DSH
727 if(!ok) goto err;
728 }
729 }
730
731 if(issuer)
732 {
bc501570
DSH
733 /* Check for cRLSign bit if keyUsage present */
734 if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
735 !(issuer->ex_kusage & KU_CRL_SIGN))
736 {
737 ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
738 ok = ctx->verify_cb(0, ctx);
739 if(!ok) goto err;
740 }
b545dc67
DSH
741
742 /* Attempt to get issuer certificate public key */
743 ikey = X509_get_pubkey(issuer);
744
745 if(!ikey)
746 {
747 ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
bdee69f7 748 ok = ctx->verify_cb(0, ctx);
b545dc67
DSH
749 if (!ok) goto err;
750 }
751 else
752 {
753 /* Verify CRL signature */
754 if(X509_CRL_verify(crl, ikey) <= 0)
755 {
756 ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE;
bdee69f7 757 ok = ctx->verify_cb(0, ctx);
b545dc67
DSH
758 if (!ok) goto err;
759 }
760 }
761 }
762
e1a27eb3
DSH
763 if (!check_crl_time(ctx, crl, 1))
764 goto err;
b545dc67
DSH
765
766 ok = 1;
767
768 err:
769 EVP_PKEY_free(ikey);
770 return ok;
771 }
772
773/* Check certificate against CRL */
774static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
775 {
776 int idx, ok;
777 X509_REVOKED rtmp;
bc501570
DSH
778 STACK_OF(X509_EXTENSION) *exts;
779 X509_EXTENSION *ext;
b545dc67
DSH
780 /* Look for serial number of certificate in CRL */
781 rtmp.serialNumber = X509_get_serialNumber(x);
2f605e8d
DSH
782 /* Sort revoked into serial number order if not already sorted.
783 * Do this under a lock to avoid race condition.
784 */
785 if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
786 {
787 CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
788 sk_X509_REVOKED_sort(crl->crl->revoked);
789 CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
790 }
b545dc67 791 idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
bc501570 792 /* If found assume revoked: want something cleverer than
b545dc67
DSH
793 * this to handle entry extensions in V2 CRLs.
794 */
bc501570
DSH
795 if(idx >= 0)
796 {
797 ctx->error = X509_V_ERR_CERT_REVOKED;
798 ok = ctx->verify_cb(0, ctx);
799 if (!ok) return 0;
800 }
801
5d7c222d 802 if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
bc501570
DSH
803 return 1;
804
805 /* See if we have any critical CRL extensions: since we
806 * currently don't handle any CRL extensions the CRL must be
807 * rejected.
808 * This code accesses the X509_CRL structure directly: applications
809 * shouldn't do this.
810 */
811
812 exts = crl->crl->extensions;
813
814 for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
815 {
816 ext = sk_X509_EXTENSION_value(exts, idx);
817 if (ext->critical > 0)
818 {
819 ctx->error =
820 X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
821 ok = ctx->verify_cb(0, ctx);
822 if(!ok) return 0;
823 break;
824 }
825 }
826 return 1;
b545dc67
DSH
827 }
828
5d7c222d
DSH
829static int check_policy(X509_STORE_CTX *ctx)
830 {
831 int ret;
175ac681 832 ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
5d7c222d
DSH
833 ctx->param->policies, ctx->param->flags);
834 if (ret == 0)
835 {
836 X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
837 return 0;
838 }
839 /* Invalid or inconsistent extensions */
840 if (ret == -1)
841 {
842 /* Locate certificates with bad extensions and notify
843 * callback.
844 */
845 X509 *x;
846 int i;
847 for (i = 1; i < sk_X509_num(ctx->chain); i++)
848 {
849 x = sk_X509_value(ctx->chain, i);
850 if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
851 continue;
852 ctx->current_cert = x;
853 ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
854 ret = ctx->verify_cb(0, ctx);
855 }
856 return 1;
857 }
858 if (ret == -2)
859 {
860 ctx->current_cert = NULL;
861 ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
862 return ctx->verify_cb(0, ctx);
863 }
864
865 if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY)
866 {
867 ctx->current_cert = NULL;
868 ctx->error = X509_V_OK;
869 if (!ctx->verify_cb(2, ctx))
870 return 0;
871 }
872
873 return 1;
874 }
875
e1a27eb3
DSH
876static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
877 {
878 time_t *ptime;
879 int i;
880
5d7c222d
DSH
881 if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
882 ptime = &ctx->param->check_time;
e1a27eb3
DSH
883 else
884 ptime = NULL;
885
886 i=X509_cmp_time(X509_get_notBefore(x), ptime);
887 if (i == 0)
888 {
889 ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
890 ctx->current_cert=x;
891 if (!ctx->verify_cb(0, ctx))
892 return 0;
893 }
894
895 if (i > 0)
896 {
897 ctx->error=X509_V_ERR_CERT_NOT_YET_VALID;
898 ctx->current_cert=x;
899 if (!ctx->verify_cb(0, ctx))
900 return 0;
901 }
902
903 i=X509_cmp_time(X509_get_notAfter(x), ptime);
904 if (i == 0)
905 {
906 ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
907 ctx->current_cert=x;
908 if (!ctx->verify_cb(0, ctx))
909 return 0;
910 }
911
912 if (i < 0)
913 {
914 ctx->error=X509_V_ERR_CERT_HAS_EXPIRED;
915 ctx->current_cert=x;
916 if (!ctx->verify_cb(0, ctx))
917 return 0;
918 }
919
920 return 1;
921 }
922
6b691a5c 923static int internal_verify(X509_STORE_CTX *ctx)
d02b48c6 924 {
e1a27eb3 925 int ok=0,n;
d02b48c6
RE
926 X509 *xs,*xi;
927 EVP_PKEY *pkey=NULL;
928 int (*cb)();
929
2f043896 930 cb=ctx->verify_cb;
d02b48c6 931
7e258a56 932 n=sk_X509_num(ctx->chain);
d02b48c6
RE
933 ctx->error_depth=n-1;
934 n--;
7e258a56 935 xi=sk_X509_value(ctx->chain,n);
e1a27eb3 936
bbb72003 937 if (ctx->check_issued(ctx, xi, xi))
d02b48c6
RE
938 xs=xi;
939 else
940 {
941 if (n <= 0)
942 {
943 ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
944 ctx->current_cert=xi;
945 ok=cb(0,ctx);
946 goto end;
947 }
948 else
949 {
950 n--;
951 ctx->error_depth=n;
7e258a56 952 xs=sk_X509_value(ctx->chain,n);
d02b48c6
RE
953 }
954 }
955
956/* ctx->error=0; not needed */
957 while (n >= 0)
958 {
959 ctx->error_depth=n;
960 if (!xs->valid)
961 {
962 if ((pkey=X509_get_pubkey(xi)) == NULL)
963 {
964 ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
965 ctx->current_cert=xi;
966 ok=(*cb)(0,ctx);
967 if (!ok) goto end;
968 }
29902449 969 else if (X509_verify(xs,pkey) <= 0)
78f3a2aa
BM
970 /* XXX For the final trusted self-signed cert,
971 * this is a waste of time. That check should
972 * optional so that e.g. 'openssl x509' can be
973 * used to detect invalid self-signatures, but
974 * we don't verify again and again in SSL
975 * handshakes and the like once the cert has
976 * been declared trusted. */
d02b48c6
RE
977 {
978 ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;
979 ctx->current_cert=xs;
980 ok=(*cb)(0,ctx);
582e5929
DSH
981 if (!ok)
982 {
983 EVP_PKEY_free(pkey);
984 goto end;
985 }
d02b48c6 986 }
cfcf6453 987 EVP_PKEY_free(pkey);
d02b48c6 988 pkey=NULL;
d02b48c6
RE
989 }
990
e1a27eb3 991 xs->valid = 1;
d02b48c6 992
e1a27eb3
DSH
993 if (!check_cert_time(ctx, xs))
994 goto end;
d02b48c6 995
d02b48c6
RE
996 /* The last error (if any) is still in the error value */
997 ctx->current_cert=xs;
998 ok=(*cb)(1,ctx);
999 if (!ok) goto end;
1000
1001 n--;
1002 if (n >= 0)
1003 {
1004 xi=xs;
7e258a56 1005 xs=sk_X509_value(ctx->chain,n);
d02b48c6
RE
1006 }
1007 }
1008 ok=1;
1009end:
f684090c 1010 return ok;
d02b48c6
RE
1011 }
1012
284ef5f3 1013int X509_cmp_current_time(ASN1_TIME *ctm)
bbb72003
DSH
1014{
1015 return X509_cmp_time(ctm, NULL);
1016}
1017
1018int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time)
d02b48c6
RE
1019 {
1020 char *str;
284ef5f3 1021 ASN1_TIME atm;
527497a7 1022 long offset;
d02b48c6
RE
1023 char buff1[24],buff2[24],*p;
1024 int i,j;
1025
1026 p=buff1;
1027 i=ctm->length;
1028 str=(char *)ctm->data;
82aec1cc
BM
1029 if (ctm->type == V_ASN1_UTCTIME)
1030 {
f684090c 1031 if ((i < 11) || (i > 17)) return 0;
284ef5f3
DSH
1032 memcpy(p,str,10);
1033 p+=10;
1034 str+=10;
82aec1cc
BM
1035 }
1036 else
1037 {
1038 if (i < 13) return 0;
284ef5f3
DSH
1039 memcpy(p,str,12);
1040 p+=12;
1041 str+=12;
82aec1cc 1042 }
d02b48c6
RE
1043
1044 if ((*str == 'Z') || (*str == '-') || (*str == '+'))
1045 { *(p++)='0'; *(p++)='0'; }
284ef5f3
DSH
1046 else
1047 {
1048 *(p++)= *(str++);
1049 *(p++)= *(str++);
1050 /* Skip any fractional seconds... */
82aec1cc 1051 if (*str == '.')
284ef5f3
DSH
1052 {
1053 str++;
b7c190d9 1054 while ((*str >= '0') && (*str <= '9')) str++;
284ef5f3 1055 }
82aec1cc
BM
1056
1057 }
d02b48c6
RE
1058 *(p++)='Z';
1059 *(p++)='\0';
1060
1061 if (*str == 'Z')
1062 offset=0;
1063 else
1064 {
1065 if ((*str != '+') && (str[5] != '-'))
f684090c 1066 return 0;
d02b48c6
RE
1067 offset=((str[1]-'0')*10+(str[2]-'0'))*60;
1068 offset+=(str[3]-'0')*10+(str[4]-'0');
1069 if (*str == '-')
dfeab068 1070 offset= -offset;
d02b48c6 1071 }
284ef5f3 1072 atm.type=ctm->type;
d02b48c6
RE
1073 atm.length=sizeof(buff2);
1074 atm.data=(unsigned char *)buff2;
1075
a0e7c8ee
DSH
1076 if (X509_time_adj(&atm,-offset*60, cmp_time) == NULL)
1077 return 0;
d02b48c6 1078
b7c190d9 1079 if (ctm->type == V_ASN1_UTCTIME)
284ef5f3
DSH
1080 {
1081 i=(buff1[0]-'0')*10+(buff1[1]-'0');
1082 if (i < 50) i+=100; /* cf. RFC 2459 */
1083 j=(buff2[0]-'0')*10+(buff2[1]-'0');
1084 if (j < 50) j+=100;
d02b48c6 1085
f684090c
BM
1086 if (i < j) return -1;
1087 if (i > j) return 1;
284ef5f3 1088 }
d02b48c6
RE
1089 i=strcmp(buff1,buff2);
1090 if (i == 0) /* wait a second then return younger :-) */
f684090c 1091 return -1;
d02b48c6 1092 else
f684090c 1093 return i;
d02b48c6
RE
1094 }
1095
284ef5f3 1096ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
bbb72003
DSH
1097{
1098 return X509_time_adj(s, adj, NULL);
1099}
1100
1101ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *in_tm)
d02b48c6
RE
1102 {
1103 time_t t;
ba8e2824 1104 int type = -1;
d02b48c6 1105
b7c190d9 1106 if (in_tm) t = *in_tm;
bbb72003
DSH
1107 else time(&t);
1108
d02b48c6 1109 t+=adj;
ba8e2824
DSH
1110 if (s) type = s->type;
1111 if (type == V_ASN1_UTCTIME) return ASN1_UTCTIME_set(s,t);
1112 if (type == V_ASN1_GENERALIZEDTIME) return ASN1_GENERALIZEDTIME_set(s, t);
1113 return ASN1_TIME_set(s, t);
d02b48c6
RE
1114 }
1115
7e258a56 1116int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
d02b48c6
RE
1117 {
1118 EVP_PKEY *ktmp=NULL,*ktmp2;
1119 int i,j;
1120
f684090c 1121 if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) return 1;
d02b48c6 1122
7e258a56 1123 for (i=0; i<sk_X509_num(chain); i++)
d02b48c6 1124 {
7e258a56 1125 ktmp=X509_get_pubkey(sk_X509_value(chain,i));
d02b48c6
RE
1126 if (ktmp == NULL)
1127 {
1128 X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
f684090c 1129 return 0;
d02b48c6
RE
1130 }
1131 if (!EVP_PKEY_missing_parameters(ktmp))
1132 break;
1133 else
1134 {
cfcf6453 1135 EVP_PKEY_free(ktmp);
d02b48c6
RE
1136 ktmp=NULL;
1137 }
1138 }
1139 if (ktmp == NULL)
1140 {
1141 X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
f684090c 1142 return 0;
d02b48c6
RE
1143 }
1144
1145 /* first, populate the other certs */
1146 for (j=i-1; j >= 0; j--)
1147 {
7e258a56 1148 ktmp2=X509_get_pubkey(sk_X509_value(chain,j));
d02b48c6 1149 EVP_PKEY_copy_parameters(ktmp2,ktmp);
cfcf6453 1150 EVP_PKEY_free(ktmp2);
d02b48c6
RE
1151 }
1152
cfcf6453
DSH
1153 if (pkey != NULL) EVP_PKEY_copy_parameters(pkey,ktmp);
1154 EVP_PKEY_free(ktmp);
f684090c 1155 return 1;
d02b48c6
RE
1156 }
1157
dd9d233e
DSH
1158int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
1159 CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
3ac82faa
BM
1160 {
1161 /* This function is (usually) called only once, by
79aa04ef
GT
1162 * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */
1163 return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp,
1164 new_func, dup_func, free_func);
3ac82faa 1165 }
58964a49 1166
6b691a5c 1167int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
58964a49 1168 {
f684090c 1169 return CRYPTO_set_ex_data(&ctx->ex_data,idx,data);
58964a49
RE
1170 }
1171
6b691a5c 1172void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
58964a49 1173 {
f684090c 1174 return CRYPTO_get_ex_data(&ctx->ex_data,idx);
58964a49
RE
1175 }
1176
6b691a5c 1177int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
58964a49 1178 {
f684090c 1179 return ctx->error;
58964a49
RE
1180 }
1181
6b691a5c 1182void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
58964a49
RE
1183 {
1184 ctx->error=err;
1185 }
1186
6b691a5c 1187int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
58964a49 1188 {
f684090c 1189 return ctx->error_depth;
58964a49
RE
1190 }
1191
6b691a5c 1192X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
58964a49 1193 {
f684090c 1194 return ctx->current_cert;
58964a49
RE
1195 }
1196
7e258a56 1197STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
58964a49 1198 {
f684090c 1199 return ctx->chain;
58964a49
RE
1200 }
1201
c7cb16a8 1202STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
25f923dd
DSH
1203 {
1204 int i;
1205 X509 *x;
1206 STACK_OF(X509) *chain;
b7c190d9
BM
1207 if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) return NULL;
1208 for (i = 0; i < sk_X509_num(chain); i++)
82aec1cc 1209 {
25f923dd
DSH
1210 x = sk_X509_value(chain, i);
1211 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
82aec1cc 1212 }
f684090c 1213 return chain;
25f923dd
DSH
1214 }
1215
6b691a5c 1216void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
58964a49
RE
1217 {
1218 ctx->cert=x;
1219 }
1220
6b691a5c 1221void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
58964a49
RE
1222 {
1223 ctx->untrusted=sk;
1224 }
1225
e1a27eb3
DSH
1226void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
1227 {
1228 ctx->crls=sk;
1229 }
1230
13938ace 1231int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
11262391 1232 {
13938ace 1233 return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
11262391
DSH
1234 }
1235
bb7cd4e3 1236int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
11262391 1237 {
bb7cd4e3 1238 return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
11262391
DSH
1239 }
1240
13938ace
DSH
1241/* This function is used to set the X509_STORE_CTX purpose and trust
1242 * values. This is intended to be used when another structure has its
1243 * own trust and purpose values which (if set) will be inherited by
1244 * the ctx. If they aren't set then we will usually have a default
1245 * purpose in mind which should then be used to set the trust value.
1246 * An example of this is SSL use: an SSL structure will have its own
1247 * purpose and trust settings which the application can set: if they
1248 * aren't set then we use the default of SSL client/server.
1249 */
1250
1251int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
1252 int purpose, int trust)
51630a37 1253{
51630a37 1254 int idx;
13938ace 1255 /* If purpose not set use default */
82aec1cc 1256 if (!purpose) purpose = def_purpose;
13938ace 1257 /* If we have a purpose then check it is valid */
82aec1cc
BM
1258 if (purpose)
1259 {
068fdce8 1260 X509_PURPOSE *ptmp;
13938ace 1261 idx = X509_PURPOSE_get_by_id(purpose);
b7c190d9 1262 if (idx == -1)
82aec1cc 1263 {
13938ace
DSH
1264 X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1265 X509_R_UNKNOWN_PURPOSE_ID);
1266 return 0;
82aec1cc 1267 }
068fdce8 1268 ptmp = X509_PURPOSE_get0(idx);
b7c190d9 1269 if (ptmp->trust == X509_TRUST_DEFAULT)
82aec1cc 1270 {
068fdce8 1271 idx = X509_PURPOSE_get_by_id(def_purpose);
b7c190d9 1272 if (idx == -1)
82aec1cc 1273 {
068fdce8
DSH
1274 X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1275 X509_R_UNKNOWN_PURPOSE_ID);
1276 return 0;
82aec1cc 1277 }
6d0d5431 1278 ptmp = X509_PURPOSE_get0(idx);
82aec1cc 1279 }
068fdce8 1280 /* If trust not set then get from purpose default */
b7c190d9 1281 if (!trust) trust = ptmp->trust;
82aec1cc 1282 }
b7c190d9 1283 if (trust)
82aec1cc 1284 {
13938ace 1285 idx = X509_TRUST_get_by_id(trust);
b7c190d9 1286 if (idx == -1)
82aec1cc 1287 {
13938ace
DSH
1288 X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1289 X509_R_UNKNOWN_TRUST_ID);
1290 return 0;
82aec1cc 1291 }
13938ace 1292 }
13938ace 1293
5d7c222d
DSH
1294 if (purpose && !ctx->param->purpose) ctx->param->purpose = purpose;
1295 if (trust && !ctx->param->trust) ctx->param->trust = trust;
51630a37
DSH
1296 return 1;
1297}
1298
2f043896
DSH
1299X509_STORE_CTX *X509_STORE_CTX_new(void)
1300{
1301 X509_STORE_CTX *ctx;
1302 ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
79aa04ef
GT
1303 if (!ctx)
1304 {
1305 X509err(X509_F_X509_STORE_CTX_NEW,ERR_R_MALLOC_FAILURE);
1306 return NULL;
1307 }
1308 memset(ctx, 0, sizeof(X509_STORE_CTX));
2f043896
DSH
1309 return ctx;
1310}
1311
1312void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
1313{
1314 X509_STORE_CTX_cleanup(ctx);
1315 OPENSSL_free(ctx);
1316}
1317
79aa04ef 1318int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
2f043896
DSH
1319 STACK_OF(X509) *chain)
1320 {
5d7c222d 1321 int ret = 1;
2f043896
DSH
1322 ctx->ctx=store;
1323 ctx->current_method=0;
1324 ctx->cert=x509;
1325 ctx->untrusted=chain;
5d7c222d 1326 ctx->crls = NULL;
2f043896 1327 ctx->last_untrusted=0;
82aec1cc 1328 ctx->other_ctx=NULL;
2f043896
DSH
1329 ctx->valid=0;
1330 ctx->chain=NULL;
2f043896 1331 ctx->error=0;
175ac681 1332 ctx->explicit_policy=0;
82aec1cc 1333 ctx->error_depth=0;
2f043896
DSH
1334 ctx->current_cert=NULL;
1335 ctx->current_issuer=NULL;
5d7c222d
DSH
1336 ctx->tree = NULL;
1337
1338 ctx->param = X509_VERIFY_PARAM_new();
1339
1340 if (!ctx->param)
1341 {
1342 X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
1343 return 0;
1344 }
bdee69f7
DSH
1345
1346 /* Inherit callbacks and flags from X509_STORE if not set
1347 * use defaults.
1348 */
1349
bdee69f7 1350
5d7c222d
DSH
1351 if (store)
1352 ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
1353 else
1354 ctx->param->flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE;
1355
a3829cb7
DSH
1356 if (store)
1357 {
5d7c222d 1358 ctx->verify_cb = store->verify_cb;
a3829cb7
DSH
1359 ctx->cleanup = store->cleanup;
1360 }
1361 else
a3829cb7 1362 ctx->cleanup = 0;
5d7c222d
DSH
1363
1364 if (ret)
1365 ret = X509_VERIFY_PARAM_inherit(ctx->param,
1366 X509_VERIFY_PARAM_lookup("default"));
1367
1368 if (ret == 0)
1369 {
1370 X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
1371 return 0;
a3829cb7
DSH
1372 }
1373
1374 if (store && store->check_issued)
bdee69f7
DSH
1375 ctx->check_issued = store->check_issued;
1376 else
1377 ctx->check_issued = check_issued;
1378
a3829cb7 1379 if (store && store->get_issuer)
bdee69f7
DSH
1380 ctx->get_issuer = store->get_issuer;
1381 else
1382 ctx->get_issuer = X509_STORE_CTX_get1_issuer;
1383
a3829cb7 1384 if (store && store->verify_cb)
bdee69f7
DSH
1385 ctx->verify_cb = store->verify_cb;
1386 else
1387 ctx->verify_cb = null_callback;
1388
a3829cb7 1389 if (store && store->verify)
bdee69f7
DSH
1390 ctx->verify = store->verify;
1391 else
1392 ctx->verify = internal_verify;
1393
a3829cb7 1394 if (store && store->check_revocation)
bdee69f7
DSH
1395 ctx->check_revocation = store->check_revocation;
1396 else
1397 ctx->check_revocation = check_revocation;
1398
a3829cb7 1399 if (store && store->get_crl)
bdee69f7
DSH
1400 ctx->get_crl = store->get_crl;
1401 else
1402 ctx->get_crl = get_crl;
1403
a3829cb7 1404 if (store && store->check_crl)
bdee69f7
DSH
1405 ctx->check_crl = store->check_crl;
1406 else
1407 ctx->check_crl = check_crl;
1408
a3829cb7 1409 if (store && store->cert_crl)
bdee69f7
DSH
1410 ctx->cert_crl = store->cert_crl;
1411 else
1412 ctx->cert_crl = cert_crl;
1413
5d7c222d
DSH
1414 ctx->check_policy = check_policy;
1415
bdee69f7 1416
79aa04ef
GT
1417 /* This memset() can't make any sense anyway, so it's removed. As
1418 * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a
1419 * corresponding "new" here and remove this bogus initialisation. */
1420 /* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */
1421 if(!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
1422 &(ctx->ex_data)))
1423 {
1424 OPENSSL_free(ctx);
1425 X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
1426 return 0;
1427 }
1428 return 1;
2f043896
DSH
1429 }
1430
1431/* Set alternative lookup method: just a STACK of trusted certificates.
1432 * This avoids X509_STORE nastiness where it isn't needed.
1433 */
1434
1435void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
1436{
1437 ctx->other_ctx = sk;
1438 ctx->get_issuer = get_issuer_sk;
1439}
1440
1441void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
1442 {
b7c190d9 1443 if (ctx->cleanup) ctx->cleanup(ctx);
5d7c222d
DSH
1444 X509_VERIFY_PARAM_free(ctx->param);
1445 if (ctx->tree)
1446 X509_policy_tree_free(ctx->tree);
2f043896
DSH
1447 if (ctx->chain != NULL)
1448 {
1449 sk_X509_pop_free(ctx->chain,X509_free);
1450 ctx->chain=NULL;
1451 }
79aa04ef 1452 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data));
c17810b0 1453 memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA));
2f043896 1454 }
13938ace 1455
5d7c222d 1456void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
bbb72003 1457 {
5d7c222d 1458 X509_VERIFY_PARAM_set_depth(ctx->param, depth);
bbb72003
DSH
1459 }
1460
5d7c222d 1461void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
bbb72003 1462 {
5d7c222d
DSH
1463 X509_VERIFY_PARAM_set_flags(ctx->param, flags);
1464 }
1465
1466void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t)
1467 {
1468 X509_VERIFY_PARAM_set_time(ctx->param, t);
bbb72003
DSH
1469 }
1470
db089ad6
LJ
1471void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
1472 int (*verify_cb)(int, X509_STORE_CTX *))
1473 {
1474 ctx->verify_cb=verify_cb;
1475 }
1476
5d7c222d
DSH
1477X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
1478 {
1479 return ctx->tree;
1480 }
1481
1482int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
1483 {
175ac681 1484 return ctx->explicit_policy;
5d7c222d
DSH
1485 }
1486
1487int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
1488 {
1489 const X509_VERIFY_PARAM *param;
1490 param = X509_VERIFY_PARAM_lookup(name);
1491 if (!param)
1492 return 0;
1493 return X509_VERIFY_PARAM_inherit(ctx->param, param);
1494 }
1495
1496X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
1497 {
1498 return ctx->param;
1499 }
1500
1501void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
1502 {
1503 if (ctx->param)
1504 X509_VERIFY_PARAM_free(ctx->param);
1505 ctx->param = param;
1506 }
1507
f73e07cf
BL
1508IMPLEMENT_STACK_OF(X509)
1509IMPLEMENT_ASN1_SET_OF(X509)
d500de16 1510
f73e07cf 1511IMPLEMENT_STACK_OF(X509_NAME)
d500de16 1512
f5fedc04 1513IMPLEMENT_STACK_OF(X509_ATTRIBUTE)
d500de16 1514IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)