1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* crypto/x509/x509_vfy.c */
2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * All rights reserved.
4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This package is an SSL implementation written
6c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * by Eric Young (eay@cryptsoft.com).
7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The implementation was written so as to conform with Netscapes SSL.
8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This library is free for commercial and non-commercial use as long as
10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the following conditions are aheared to.  The following conditions
11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * apply to all code found in this distribution, be it the RC4, RSA,
12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * included with this distribution is covered by the same copyright terms
14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright remains Eric Young's, and as such any Copyright notices in
17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the code are not to be removed.
18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * If this package is used in a product, Eric Young should be given attribution
19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * as the author of the parts of the library used.
20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This can be in the form of a textual message at program startup or
21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * in documentation (online or textual) provided with the package.
22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without
24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions
25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met:
26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the copyright
27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer.
28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer in the
30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    documentation and/or other materials provided with the distribution.
31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this software
32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    must display the following acknowledgement:
33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes cryptographic software written by
34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *     Eric Young (eay@cryptsoft.com)"
35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    The word 'cryptographic' can be left out if the rouines from the library
36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    being used are not cryptographic related :-).
37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. If you include any Windows specific code (or a derivative thereof) from
38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    the apps directory (application code) you must include an acknowledgement:
39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SUCH DAMAGE.
52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The licence and distribution terms for any publically available version or
54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * derivative of this code cannot be changed.  i.e. this code cannot simply be
55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * copied and put under another distribution licence
56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * [including the GNU Public Licence.]
57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <stdio.h>
60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <time.h>
61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <errno.h>
62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "cryptlib.h"
64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/crypto.h>
65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/lhash.h>
66c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/buffer.h>
67c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/evp.h>
68c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/asn1.h>
69c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/x509.h>
70c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/x509v3.h>
71c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/objects.h>
72c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
73480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* CRL score values */
74480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
75480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* No unhandled critical extensions */
76480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
77480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#define CRL_SCORE_NOCRITICAL	0x100
78480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
79480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* certificate is within CRL scope */
80480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
81480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#define CRL_SCORE_SCOPE		0x080
82480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
83480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* CRL times valid */
84480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
85480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#define CRL_SCORE_TIME		0x040
86480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
87480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Issuer name matches certificate */
88480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
89480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#define CRL_SCORE_ISSUER_NAME	0x020
90480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
91480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* If this score or above CRL is probably valid */
92480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
93480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE)
94480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
95480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* CRL issuer is certificate issuer */
96480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
97480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#define CRL_SCORE_ISSUER_CERT	0x018
98480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
99480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* CRL issuer is on certificate path */
100480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
101480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#define CRL_SCORE_SAME_PATH	0x008
102480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
103480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* CRL issuer matches CRL AKID */
104480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
105480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#define CRL_SCORE_AKID		0x004
106480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
107480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Have a delta CRL with valid times */
108480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
109480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#define CRL_SCORE_TIME_DELTA	0x002
110480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
111c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int null_callback(int ok,X509_STORE_CTX *e);
112c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
113c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
114c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_chain_extensions(X509_STORE_CTX *ctx);
115480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int check_name_constraints(X509_STORE_CTX *ctx);
116c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_trust(X509_STORE_CTX *ctx);
117c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_revocation(X509_STORE_CTX *ctx);
118c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_cert(X509_STORE_CTX *ctx);
119c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_policy(X509_STORE_CTX *ctx);
120480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
121480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
122480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			unsigned int *preasons,
123480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509_CRL *crl, X509 *x);
124480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int get_crl_delta(X509_STORE_CTX *ctx,
125480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
126480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score,
127480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509_CRL *base, STACK_OF(X509_CRL) *crls);
128480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
129480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				X509 **pissuer, int *pcrl_score);
130480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
131480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				unsigned int *preasons);
132480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
133480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int check_crl_chain(X509_STORE_CTX *ctx,
134480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			STACK_OF(X509) *cert_path,
135480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			STACK_OF(X509) *crl_path);
136480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int internal_verify(X509_STORE_CTX *ctx);
138c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgconst char X509_version[]="X.509" OPENSSL_VERSION_PTEXT;
139c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
140c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
141c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int null_callback(int ok, X509_STORE_CTX *e)
142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ok;
144c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
146c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#if 0
147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int x509_subject_cmp(X509 **a, X509 **b)
148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return X509_subject_name_cmp(*a,*b);
150c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
151c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
152c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
153c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_verify_cert(X509_STORE_CTX *ctx)
154c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
155c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509 *x,*xtmp,*chain_ss=NULL;
156c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int bad_chain = 0;
157c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509_VERIFY_PARAM *param = ctx->param;
158c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int depth,i,ok=0;
159c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int num;
160c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int (*cb)(int xok,X509_STORE_CTX *xctx);
161c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	STACK_OF(X509) *sktmp=NULL;
162c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->cert == NULL)
163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return -1;
166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	cb=ctx->verify_cb;
169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
170c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* first we make sure the chain we are going to build is
171c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * present and that the first entry is in place */
172c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->chain == NULL)
173c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
174c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (	((ctx->chain=sk_X509_new_null()) == NULL) ||
175c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			(!sk_X509_push(ctx->chain,ctx->cert)))
176c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
177c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
178c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			goto end;
179c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
180c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509);
181c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->last_untrusted=1;
182c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
183c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
184c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* We use a temporary STACK so we can chop and hack at it */
185c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->untrusted != NULL
186c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	    && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
187c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
188c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
189c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		goto end;
190c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
191c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
192c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	num=sk_X509_num(ctx->chain);
193c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	x=sk_X509_value(ctx->chain,num-1);
194c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	depth=param->depth;
195c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for (;;)
198c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
199c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* If we have enough, we break */
200c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (depth < num) break; /* FIXME: If this happens, we should take
201c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		                         * note of it and, if appropriate, use the
202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		                         * X509_V_ERR_CERT_CHAIN_TOO_LONG error
203c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		                         * code later.
204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		                         */
205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* If we are self signed, we break */
207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (ctx->check_issued(ctx, x,x)) break;
208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* If we were passed a cert chain, use it first */
210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (ctx->untrusted != NULL)
211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			xtmp=find_issuer(ctx, sktmp,x);
213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (xtmp != NULL)
214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				if (!sk_X509_push(ctx->chain,xtmp))
216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					{
217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					goto end;
219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					}
220c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
221c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				(void)sk_X509_delete_ptr(sktmp,xtmp);
222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->last_untrusted++;
223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				x=xtmp;
224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				num++;
225c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				/* reparse the full chain for
226c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				 * the next one */
227c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				continue;
228c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
229c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
230c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		break;
231c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* at this point, chain should contain a list of untrusted
234c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * certificates.  We now need to add at least one trusted one,
235c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * if possible, otherwise we complain. */
236c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
237c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Examine last certificate in chain and see if it
238c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 	 * is self signed.
239c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org 	 */
240c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
241c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	i=sk_X509_num(ctx->chain);
242c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	x=sk_X509_value(ctx->chain,i-1);
243c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->check_issued(ctx, x, x))
244c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
245c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* we have a self signed certificate */
246c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (sk_X509_num(ctx->chain) == 1)
247c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
248c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* We have a single self signed certificate: see if
249c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 * we can find it in the store. We must have an exact
250c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 * match to avoid possible impersonation.
251c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			 */
252c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ok = ctx->get_issuer(&xtmp, ctx, x);
253c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if ((ok <= 0) || X509_cmp(x, xtmp))
254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
256c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->current_cert=x;
257c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error_depth=i-1;
258c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				if (ok == 1) X509_free(xtmp);
259c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				bad_chain = 1;
260c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ok=cb(0,ctx);
261c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				if (!ok) goto end;
262c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
263c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else
264c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
265c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				/* We have a match: replace certificate with store version
266c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				 * so we get any trust settings.
267c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				 */
268c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				X509_free(x);
269c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				x = xtmp;
270c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				(void)sk_X509_set(ctx->chain, i - 1, x);
271c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->last_untrusted=0;
272c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
273c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
274c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else
275c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
276c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* extract and save self signed certificate for later use */
277c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			chain_ss=sk_X509_pop(ctx->chain);
278c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->last_untrusted--;
279c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			num--;
280c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			x=sk_X509_value(ctx->chain,num-1);
281c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
282c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
283c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
284c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* We now lookup certs from the certificate store */
285c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for (;;)
286c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
287c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* If we have enough, we break */
288c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (depth < num) break;
289c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
290c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* If we are self signed, we break */
291c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (ctx->check_issued(ctx,x,x)) break;
292c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
293c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ok = ctx->get_issuer(&xtmp, ctx, x);
294c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
295c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (ok < 0) return ok;
296c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (ok == 0) break;
297c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
298c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		x = xtmp;
299c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!sk_X509_push(ctx->chain,x))
300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
301c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			X509_free(xtmp);
302c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
303c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
304c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
305c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		num++;
306c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
307c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
308c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* we now have our chain, lets check it... */
309c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
310c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Is last certificate looked up self signed? */
311c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!ctx->check_issued(ctx,x,x))
312c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
313c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
314c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
315c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (ctx->last_untrusted >= num)
316c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
317c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else
318c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
319c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->current_cert=x;
320c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
321c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else
322c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
323c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
324c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			sk_X509_push(ctx->chain,chain_ss);
325c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			num++;
326c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->last_untrusted=num;
327c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->current_cert=chain_ss;
328c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
329c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			chain_ss=NULL;
330c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
331c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
332c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error_depth=num-1;
333c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		bad_chain = 1;
334c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ok=cb(0,ctx);
335c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!ok) goto end;
336c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
337c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
338c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* We have the chain complete: now we need to check its purpose */
339c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ok = check_chain_extensions(ctx);
340c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
341c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!ok) goto end;
342c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
343480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Check name constraints */
344480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
345480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ok = check_name_constraints(ctx);
346480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
347480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!ok) goto end;
348480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
349c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* The chain extensions are OK: check trust */
350c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
351c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (param->trust > 0) ok = check_trust(ctx);
352c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
353c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!ok) goto end;
354c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
355c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* We may as well copy down any DSA parameters that are required */
356c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509_get_pubkey_parameters(NULL,ctx->chain);
357c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
358c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Check revocation status: we do this after copying parameters
359c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * because they may be needed for CRL signature verification.
360c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 */
361c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
362c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ok = ctx->check_revocation(ctx);
363c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if(!ok) goto end;
364c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
365c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* At this point, we have a chain and need to verify it */
366c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->verify != NULL)
367c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ok=ctx->verify(ctx);
368c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
369c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ok=internal_verify(ctx);
370c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if(!ok) goto end;
371c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
372c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifndef OPENSSL_NO_RFC3779
373c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* RFC 3779 path validation, now that CRL check has been done */
374c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ok = v3_asid_validate_path(ctx);
375c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!ok) goto end;
376c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ok = v3_addr_validate_path(ctx);
377c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!ok) goto end;
378c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
379c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
380c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* If we get this far evaluate policies */
381c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
382c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ok = ctx->check_policy(ctx);
383c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if(!ok) goto end;
384c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (0)
385c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
386c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgend:
387c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509_get_pubkey_parameters(NULL,ctx->chain);
388c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
389c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (sktmp != NULL) sk_X509_free(sktmp);
390c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (chain_ss != NULL) X509_free(chain_ss);
391c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ok;
392c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
393c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
394c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
395c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Given a STACK_OF(X509) find the issuer of cert (if any)
396c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
397c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
398c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
399c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
400c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i;
401c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509 *issuer;
402c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for (i = 0; i < sk_X509_num(sk); i++)
403c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
404c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		issuer = sk_X509_value(sk, i);
405c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (ctx->check_issued(ctx, x, issuer))
406c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return issuer;
407c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
408c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return NULL;
409c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
410c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
411c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Given a possible certificate and issuer check them */
412c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
413c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
414c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
415c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int ret;
416c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ret = X509_check_issued(issuer, x);
417c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ret == X509_V_OK)
418c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 1;
419c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* If we haven't asked for issuer errors don't set ctx */
420c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
421c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
422c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
423c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->error = ret;
424c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->current_cert = x;
425c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->current_issuer = issuer;
426c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ctx->verify_cb(0, ctx);
427c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 0;
428c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
429c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
430c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Alternative lookup method: look from a STACK stored in other_ctx */
431c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
432c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
433c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
434c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	*issuer = find_issuer(ctx, ctx->other_ctx, x);
435c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (*issuer)
436c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
437c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		CRYPTO_add(&(*issuer)->references,1,CRYPTO_LOCK_X509);
438c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 1;
439c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
440c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
441c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
442c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
443c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
444c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
445c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Check a certificate chains extensions for consistency
446c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * with the supplied purpose
447c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
448c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
449c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_chain_extensions(X509_STORE_CTX *ctx)
450c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
451c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef OPENSSL_NO_CHAIN_VERIFY
452c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
453c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else
454c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i, ok=0, must_be_ca, plen = 0;
455c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509 *x;
456c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int (*cb)(int xok,X509_STORE_CTX *xctx);
457c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int proxy_path_length = 0;
458480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int purpose;
459480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int allow_proxy_certs;
460c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	cb=ctx->verify_cb;
461c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
462c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* must_be_ca can have 1 of 3 values:
463c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	   -1: we accept both CA and non-CA certificates, to allow direct
464c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	       use of self-signed certificates (which are marked as CA).
465c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	   0:  we only accept non-CA certificates.  This is currently not
466c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	       used, but the possibility is present for future extensions.
467c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	   1:  we only accept CA certificates.  This is currently used for
468c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	       all certificates in the chain except the leaf certificate.
469c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	*/
470c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	must_be_ca = -1;
471c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
472480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* CRL path validation */
473480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ctx->parent)
474480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
475480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		allow_proxy_certs = 0;
476480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		purpose = X509_PURPOSE_CRL_SIGN;
477480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
478480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
479480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
480480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		allow_proxy_certs =
481480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			!!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
482480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* A hack to keep people who don't want to modify their
483480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		   software happy */
484480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
485480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			allow_proxy_certs = 1;
486480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		purpose = ctx->param->purpose;
487480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
488c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
489c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Check all untrusted certificates */
490c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for (i = 0; i < ctx->last_untrusted; i++)
491c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
492c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		int ret;
493c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		x = sk_X509_value(ctx->chain, i);
494c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
495c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			&& (x->ex_flags & EXFLAG_CRITICAL))
496c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
497c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
498c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error_depth = i;
499c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->current_cert = x;
500c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ok=cb(0,ctx);
501c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (!ok) goto end;
502c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
503c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY))
504c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
505c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
506c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error_depth = i;
507c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->current_cert = x;
508c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ok=cb(0,ctx);
509c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (!ok) goto end;
510c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
511c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ret = X509_check_ca(x);
512c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		switch(must_be_ca)
513c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
514c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		case -1:
515c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
516c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				&& (ret != 1) && (ret != 0))
517c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
518c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ret = 0;
519c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error = X509_V_ERR_INVALID_CA;
520c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
521c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else
522c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ret = 1;
523c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			break;
524c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		case 0:
525c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (ret != 0)
526c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
527c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ret = 0;
528c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error = X509_V_ERR_INVALID_NON_CA;
529c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
530c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else
531c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ret = 1;
532c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			break;
533c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		default:
534c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if ((ret == 0)
535c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
536c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					&& (ret != 1)))
537c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
538c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ret = 0;
539c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error = X509_V_ERR_INVALID_CA;
540c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
541c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else
542c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ret = 1;
543c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			break;
544c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
545c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (ret == 0)
546c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
547c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error_depth = i;
548c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->current_cert = x;
549c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ok=cb(0,ctx);
550c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (!ok) goto end;
551c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
552c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (ctx->param->purpose > 0)
553c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
554480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			ret = X509_check_purpose(x, purpose, must_be_ca > 0);
555c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if ((ret == 0)
556c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				|| ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
557c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					&& (ret != 1)))
558c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
559c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error = X509_V_ERR_INVALID_PURPOSE;
560c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error_depth = i;
561c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->current_cert = x;
562c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ok=cb(0,ctx);
563c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				if (!ok) goto end;
564c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
565c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
566c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* Check pathlen if not self issued */
567c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
568c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			   && (x->ex_pathlen != -1)
569c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			   && (plen > (x->ex_pathlen + proxy_path_length + 1)))
570c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
571c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
572c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error_depth = i;
573c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->current_cert = x;
574c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ok=cb(0,ctx);
575c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (!ok) goto end;
576c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
577c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* Increment path length if not self issued */
578c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!(x->ex_flags & EXFLAG_SI))
579c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			plen++;
580c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* If this certificate is a proxy certificate, the next
581c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		   certificate must be another proxy certificate or a EE
582c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		   certificate.  If not, the next certificate must be a
583c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		   CA certificate.  */
584c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (x->ex_flags & EXFLAG_PROXY)
585c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
586c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen)
587c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
588c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error =
589c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
590c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error_depth = i;
591c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->current_cert = x;
592c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ok=cb(0,ctx);
593c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				if (!ok) goto end;
594c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
595c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			proxy_path_length++;
596c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			must_be_ca = 0;
597c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
598c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else
599c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			must_be_ca = 1;
600c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
601c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ok = 1;
602c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org end:
603c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ok;
604c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
605c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
606c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
607480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int check_name_constraints(X509_STORE_CTX *ctx)
608480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
609480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509 *x;
610480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i, j, rv;
611480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Check name constraints for all certificates */
612480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--)
613480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
614480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		x = sk_X509_value(ctx->chain, i);
615480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* Ignore self issued certs unless last in chain */
616480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (i && (x->ex_flags & EXFLAG_SI))
617480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			continue;
618480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* Check against constraints for all certificates higher in
619480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 * chain including trust anchor. Trust anchor not strictly
620480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 * speaking needed but if it includes constraints it is to be
621480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 * assumed it expects them to be obeyed.
622480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 */
623480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		for (j = sk_X509_num(ctx->chain) - 1; j > i; j--)
624480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
625480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
626480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (nc)
627480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
628480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				rv = NAME_CONSTRAINTS_check(x, nc);
629480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				if (rv != X509_V_OK)
630480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					{
631480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					ctx->error = rv;
632480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					ctx->error_depth = i;
633480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					ctx->current_cert = x;
634480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					if (!ctx->verify_cb(0,ctx))
635480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org						return 0;
636480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					}
637480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
638480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
639480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
640480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
641480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
642480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
643c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_trust(X509_STORE_CTX *ctx)
644c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
645c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef OPENSSL_NO_CHAIN_VERIFY
646c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
647c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#else
648c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i, ok;
649c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509 *x;
650c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int (*cb)(int xok,X509_STORE_CTX *xctx);
651c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	cb=ctx->verify_cb;
652c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* For now just check the last certificate in the chain */
653c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	i = sk_X509_num(ctx->chain) - 1;
654c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	x = sk_X509_value(ctx->chain, i);
655c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ok = X509_check_trust(x, ctx->param->trust, 0);
656c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ok == X509_TRUST_TRUSTED)
657c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 1;
658c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->error_depth = i;
659c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->current_cert = x;
660c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ok == X509_TRUST_REJECTED)
661c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error = X509_V_ERR_CERT_REJECTED;
662c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
663c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error = X509_V_ERR_CERT_UNTRUSTED;
664c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ok = cb(0, ctx);
665c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ok;
666c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
667c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
668c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
669c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_revocation(X509_STORE_CTX *ctx)
670c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
671c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i, last, ok;
672c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
673c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 1;
674c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
675c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		last = sk_X509_num(ctx->chain) - 1;
676c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
677480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
678480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* If checking CRL paths this isn't the EE certificate */
679480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (ctx->parent)
680480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 1;
681c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		last = 0;
682480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
683c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for(i = 0; i <= last; i++)
684c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
685c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error_depth = i;
686c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ok = check_cert(ctx);
687c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!ok) return ok;
688c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
689c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
690c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
691c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
692c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_cert(X509_STORE_CTX *ctx)
693c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
694480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_CRL *crl = NULL, *dcrl = NULL;
695c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509 *x;
696c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int ok, cnum;
697c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	cnum = ctx->error_depth;
698c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	x = sk_X509_value(ctx->chain, cnum);
699c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->current_cert = x;
700480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ctx->current_issuer = NULL;
701480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ctx->current_crl_score = 0;
702480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ctx->current_reasons = 0;
703480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	while (ctx->current_reasons != CRLDP_ALL_REASONS)
704c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
705480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* Try to retrieve relevant CRL */
706480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (ctx->get_crl)
707480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			ok = ctx->get_crl(ctx, &crl, x);
708480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		else
709480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			ok = get_crl_delta(ctx, &crl, &dcrl, x);
710480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* If error looking up CRL, nothing we can do except
711480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 * notify callback
712480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 */
713480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if(!ok)
714480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
715480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
716480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			ok = ctx->verify_cb(0, ctx);
717480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
718480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
719480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->current_crl = crl;
720480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ok = ctx->check_crl(ctx, crl);
721480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!ok)
722480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
723480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
724480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (dcrl)
725480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
726480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			ok = ctx->check_crl(ctx, dcrl);
727480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!ok)
728480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
729480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			ok = ctx->cert_crl(ctx, dcrl, x);
730480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!ok)
731480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
732480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
733480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		else
734480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			ok = 1;
735480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
736480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* Don't look in full CRL if delta reason is removefromCRL */
737480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (ok != 2)
738480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
739480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			ok = ctx->cert_crl(ctx, crl, x);
740480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!ok)
741480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
742480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
743480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
744480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		X509_CRL_free(crl);
745480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		X509_CRL_free(dcrl);
746480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		crl = NULL;
747480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		dcrl = NULL;
748c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
749c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	err:
750c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509_CRL_free(crl);
751480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_CRL_free(dcrl);
752480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
753480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ctx->current_crl = NULL;
754c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ok;
755c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
756c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
757c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
758c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Check CRL times against values in X509_STORE_CTX */
759c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
760c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
761c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
762c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	time_t *ptime;
763c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i;
764480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (notify)
765480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->current_crl = crl;
766c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
767c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ptime = &ctx->param->check_time;
768c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
769c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ptime = NULL;
770c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
771c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
772c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (i == 0)
773c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
774480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!notify)
775480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
776c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
777480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!ctx->verify_cb(0, ctx))
778c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
779c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
780c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
781c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (i > 0)
782c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
783480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!notify)
784480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
785c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error=X509_V_ERR_CRL_NOT_YET_VALID;
786480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!ctx->verify_cb(0, ctx))
787c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
788c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
789c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
790c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if(X509_CRL_get_nextUpdate(crl))
791c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
792c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
793c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
794c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (i == 0)
795c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
796480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!notify)
797480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				return 0;
798c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
799480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!ctx->verify_cb(0, ctx))
800c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				return 0;
801c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
802480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* Ignore expiry of base CRL is delta is valid */
803480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA))
804c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
805480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!notify)
806480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				return 0;
807c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error=X509_V_ERR_CRL_HAS_EXPIRED;
808480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!ctx->verify_cb(0, ctx))
809c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				return 0;
810c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
811c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
812c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
813480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (notify)
814480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->current_crl = NULL;
815c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
816c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
817c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
818c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
819480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
820480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509 **pissuer, int *pscore, unsigned int *preasons,
821480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			STACK_OF(X509_CRL) *crls)
822c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
823480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i, crl_score, best_score = *pscore;
824480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	unsigned int reasons, best_reasons = 0;
825480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509 *x = ctx->current_cert;
826c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509_CRL *crl, *best_crl = NULL;
827480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
828480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
829c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for (i = 0; i < sk_X509_CRL_num(crls); i++)
830c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
831c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		crl = sk_X509_CRL_value(crls, i);
832480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		reasons = *preasons;
833480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
834480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
835480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (crl_score > best_score)
836c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
837480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			best_crl = crl;
838480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			best_crl_issuer = crl_issuer;
839480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			best_score = crl_score;
840480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			best_reasons = reasons;
841c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
842c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
843480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
844c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (best_crl)
845c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
846480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (*pcrl)
847480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509_CRL_free(*pcrl);
848c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		*pcrl = best_crl;
849480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		*pissuer = best_crl_issuer;
850480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		*pscore = best_score;
851480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		*preasons = best_reasons;
852480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
853480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (*pdcrl)
854480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
855480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509_CRL_free(*pdcrl);
856480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			*pdcrl = NULL;
857480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
858480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
859c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
860480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
861480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (best_score >= CRL_SCORE_VALID)
862480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 1;
863480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
864c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 0;
865c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
866c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
867480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Compare two CRL extensions for delta checking purposes. They should be
868480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * both present or both absent. If both present all fields must be identical.
869c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
870480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
871480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
872c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
873480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ASN1_OCTET_STRING *exta, *extb;
874480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i;
8757453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	i = X509_CRL_get_ext_by_NID(a, nid, -1);
876480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (i >= 0)
877c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
878480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* Can't have multiple occurrences */
879480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
880480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
881480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
882480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
883480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
884480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		exta = NULL;
885480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
8867453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	i = X509_CRL_get_ext_by_NID(b, nid, -1);
887480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
888480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (i >= 0)
889480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
890480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
891480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
892480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
893480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
894480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
895480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
896480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		extb = NULL;
897480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
898480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!exta && !extb)
899c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 1;
900480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
901480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!exta || !extb)
902480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
903480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
904480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
905480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ASN1_OCTET_STRING_cmp(exta, extb))
906480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
907480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
908480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 1;
909480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
910480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
911480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* See if a base and delta are compatible */
912480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
913480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int check_delta_base(X509_CRL *delta, X509_CRL *base)
914480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
915480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Delta CRL must be a delta */
916480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!delta->base_crl_number)
917480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
918480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Base must have a CRL number */
919480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!base->crl_number)
920480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
921480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Issuer names must match */
922480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (X509_NAME_cmp(X509_CRL_get_issuer(base),
923480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				X509_CRL_get_issuer(delta)))
924480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
925480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* AKID and IDP must match */
926480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!crl_extension_match(delta, base, NID_authority_key_identifier))
927480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
928480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
929480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
930480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Delta CRL base number must not exceed Full CRL number. */
931480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
932480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
933480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Delta CRL number must exceed full CRL number */
934480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
935480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 1;
936480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 0;
937480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
938480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
939480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* For a given base CRL find a delta... maybe extend to delta scoring
940480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * or retrieve a chain of deltas...
941480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */
942480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
943480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
944480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509_CRL *base, STACK_OF(X509_CRL) *crls)
945480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
946480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_CRL *delta;
947480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i;
948480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
949480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return;
950480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
951480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return;
952480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (i = 0; i < sk_X509_CRL_num(crls); i++)
953480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
954480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		delta = sk_X509_CRL_value(crls, i);
955480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (check_delta_base(delta, base))
956480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
957480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (check_crl_time(ctx, delta, 0))
958480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				*pscore |= CRL_SCORE_TIME_DELTA;
959480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
960480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			*dcrl = delta;
961480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return;
962480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
963480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
964480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	*dcrl = NULL;
965480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
966480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
967480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* For a given CRL return how suitable it is for the supplied certificate 'x'.
968480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * The return value is a mask of several criteria.
969480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * If the issuer is not the certificate issuer this is returned in *pissuer.
970480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * The reasons mask is also used to determine if the CRL is suitable: if
971480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * no new reasons the CRL is rejected, otherwise reasons is updated.
972480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */
973480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
974480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
975480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			unsigned int *preasons,
976480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509_CRL *crl, X509 *x)
977480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
978480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
979480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int crl_score = 0;
980480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	unsigned int tmp_reasons = *preasons, crl_reasons;
981480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
982480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* First see if we can reject CRL straight away */
983480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
984480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Invalid IDP cannot be processed */
985480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (crl->idp_flags & IDP_INVALID)
986480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
987480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Reason codes or indirect CRLs need extended CRL support */
988480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
989480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
990480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
991480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
992480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
993480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else if (crl->idp_flags & IDP_REASONS)
994480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
995480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* If no new reasons reject */
996480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!(crl->idp_reasons & ~tmp_reasons))
997480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
998480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
999480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Don't process deltas at this stage */
1000480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else if (crl->base_crl_number)
1001480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
1002480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* If issuer name doesn't match certificate need indirect CRL */
1003480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl)))
1004480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1005480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!(crl->idp_flags & IDP_INDIRECT))
1006480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
1007480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1008480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
1009480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		crl_score |= CRL_SCORE_ISSUER_NAME;
1010480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1011480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!(crl->flags & EXFLAG_CRITICAL))
1012480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		crl_score |= CRL_SCORE_NOCRITICAL;
1013480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1014480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Check expiry */
1015480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (check_crl_time(ctx, crl, 0))
1016480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		crl_score |= CRL_SCORE_TIME;
1017480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1018480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Check authority key ID and locate certificate issuer */
1019480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	crl_akid_check(ctx, crl, pissuer, &crl_score);
1020480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1021480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* If we can't locate certificate issuer at this point forget it */
1022480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1023480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!(crl_score & CRL_SCORE_AKID))
1024480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
1025480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1026480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Check cert for matching CRL distribution points */
1027480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1028480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (crl_crldp_check(x, crl, crl_score, &crl_reasons))
1029480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1030480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* If no new reasons reject */
1031480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!(crl_reasons & ~tmp_reasons))
1032480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
1033480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		tmp_reasons |= crl_reasons;
1034480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		crl_score |= CRL_SCORE_SCOPE;
1035c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1036c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1037480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	*preasons = tmp_reasons;
1038480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1039480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return crl_score;
1040480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1041480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1042c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1043480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
1044480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				X509 **pissuer, int *pcrl_score)
1045480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
1046480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509 *crl_issuer = NULL;
1047480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_NAME *cnm = X509_CRL_get_issuer(crl);
1048480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int cidx = ctx->error_depth;
1049480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i;
1050480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1051480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (cidx != sk_X509_num(ctx->chain) - 1)
1052480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		cidx++;
1053480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1054480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	crl_issuer = sk_X509_value(ctx->chain, cidx);
1055480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1056480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
1057c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1058480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (*pcrl_score & CRL_SCORE_ISSUER_NAME)
1059c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1060480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT;
1061480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			*pissuer = crl_issuer;
1062480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return;
1063480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
1064480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1065480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1066480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++)
1067480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1068480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		crl_issuer = sk_X509_value(ctx->chain, cidx);
1069480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1070480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			continue;
1071480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
1072480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
1073480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			*pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH;
1074480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			*pissuer = crl_issuer;
1075480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return;
1076480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
1077480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1078480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1079480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Anything else needs extended CRL support */
1080480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1081480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
1082480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return;
1083480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1084480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Otherwise the CRL issuer is not on the path. Look for it in the
1085480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	 * set of untrusted certificates.
1086480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	 */
1087480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (i = 0; i < sk_X509_num(ctx->untrusted); i++)
1088480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1089480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		crl_issuer = sk_X509_value(ctx->untrusted, i);
1090480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1091480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			continue;
1092480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK)
1093480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
1094480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			*pissuer = crl_issuer;
1095480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			*pcrl_score |= CRL_SCORE_AKID;
1096480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return;
1097480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
1098480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1099480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1100480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1101480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Check the path of a CRL issuer certificate. This creates a new
1102480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * X509_STORE_CTX and populates it with most of the parameters from the
1103480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * parent. This could be optimised somewhat since a lot of path checking
1104480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * will be duplicated by the parent, but this will rarely be used in
1105480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * practice.
1106480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */
1107480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1108480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
1109480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
1110480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_STORE_CTX crl_ctx;
1111480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int ret;
1112480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Don't allow recursive CRL path validation */
1113480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ctx->parent)
1114480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
1115480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
1116480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return -1;
1117480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1118480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	crl_ctx.crls = ctx->crls;
1119480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Copy verify params across */
1120480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
1121480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1122480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	crl_ctx.parent = ctx;
1123480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	crl_ctx.verify_cb = ctx->verify_cb;
1124480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1125480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Verify CRL issuer */
1126480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ret = X509_verify_cert(&crl_ctx);
1127480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1128480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ret <= 0)
1129480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
1130480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1131480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Check chain is acceptable */
1132480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1133480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
1134480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	err:
1135480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_STORE_CTX_cleanup(&crl_ctx);
1136480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return ret;
1137480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1138480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1139480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* RFC3280 says nothing about the relationship between CRL path
1140480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * and certificate path, which could lead to situations where a
1141480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * certificate could be revoked or validated by a CA not authorised
1142480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * to do so. RFC5280 is more strict and states that the two paths must
1143480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * end in the same trust anchor, though some discussions remain...
1144480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * until this is resolved we use the RFC5280 version
1145480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */
1146480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1147480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int check_crl_chain(X509_STORE_CTX *ctx,
1148480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			STACK_OF(X509) *cert_path,
1149480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			STACK_OF(X509) *crl_path)
1150480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
1151480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509 *cert_ta, *crl_ta;
1152480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
1153480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
1154480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!X509_cmp(cert_ta, crl_ta))
1155480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 1;
1156480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 0;
1157480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1158480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1159480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Check for match between two dist point names: three separate cases.
1160480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * 1. Both are relative names and compare X509_NAME types.
1161480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
1162480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * 3. Both are full names and compare two GENERAL_NAMES.
1163480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * 4. One is NULL: automatic match.
1164480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */
1165480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1166480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1167480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
1168480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
1169480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_NAME *nm = NULL;
1170480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	GENERAL_NAMES *gens = NULL;
1171480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	GENERAL_NAME *gena, *genb;
1172480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i, j;
1173480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!a || !b)
1174480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 1;
1175480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (a->type == 1)
1176480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1177480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!a->dpname)
1178480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
1179480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* Case 1: two X509_NAME */
1180480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (b->type == 1)
1181480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
1182480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!b->dpname)
1183480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				return 0;
1184480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!X509_NAME_cmp(a->dpname, b->dpname))
1185480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				return 1;
1186480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			else
1187480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				return 0;
1188480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
1189480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* Case 2: set name and GENERAL_NAMES appropriately */
1190480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		nm = a->dpname;
1191480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		gens = b->name.fullname;
1192480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1193480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else if (b->type == 1)
1194480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1195480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!b->dpname)
1196480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
1197480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* Case 2: set name and GENERAL_NAMES appropriately */
1198480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		gens = a->name.fullname;
1199480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		nm = b->dpname;
1200480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1201480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1202480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
1203480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (nm)
1204480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1205480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
1206480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
1207480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			gena = sk_GENERAL_NAME_value(gens, i);
1208480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (gena->type != GEN_DIRNAME)
1209480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				continue;
1210480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!X509_NAME_cmp(nm, gena->d.directoryName))
1211480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				return 1;
1212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
1214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1216480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Else case 3: two GENERAL_NAMES */
1217480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1218480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++)
1219480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1220480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		gena = sk_GENERAL_NAME_value(a->name.fullname, i);
1221480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++)
1222480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
1223480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			genb = sk_GENERAL_NAME_value(b->name.fullname, j);
1224480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!GENERAL_NAME_cmp(gena, genb))
1225480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				return 1;
1226480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
1227480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1228480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1229480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 0;
1230480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1231480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1232480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1233480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
1234480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
1235480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i;
1236480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_NAME *nm = X509_CRL_get_issuer(crl);
1237480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* If no CRLissuer return is successful iff don't need a match */
1238480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!dp->CRLissuer)
1239480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return !!(crl_score & CRL_SCORE_ISSUER_NAME);
1240480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++)
1241480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1242480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
1243480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (gen->type != GEN_DIRNAME)
1244480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			continue;
1245480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!X509_NAME_cmp(gen->d.directoryName, nm))
1246480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 1;
1247480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1248480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 0;
1249480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1250480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1251480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Check CRLDP and IDP */
1252480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1253480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
1254480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				unsigned int *preasons)
1255480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
1256480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i;
1257480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (crl->idp_flags & IDP_ONLYATTR)
1258480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
1259480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (x->ex_flags & EXFLAG_CA)
1260480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1261480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (crl->idp_flags & IDP_ONLYUSER)
1262480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
1263480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1264480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
1265480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1266480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (crl->idp_flags & IDP_ONLYCA)
1267480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
1268480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1269480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	*preasons = crl->idp_reasons;
1270480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
1271480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1272480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
1273480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (crldp_check_crlissuer(dp, crl, crl_score))
1274480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
1275480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!crl->idp ||
1276480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			     idp_check_dp(dp->distpoint, crl->idp->distpoint))
1277480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
1278480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				*preasons &= dp->dp_reasons;
1279480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				return 1;
1280480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
1281480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
1282480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1283480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if ((!crl->idp || !crl->idp->distpoint) && (crl_score & CRL_SCORE_ISSUER_NAME))
1284480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 1;
1285480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 0;
1286480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1287480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1288480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* Retrieve CRL corresponding to current certificate.
1289480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * If deltas enabled try to find a delta CRL too
1290480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */
1291480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1292480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int get_crl_delta(X509_STORE_CTX *ctx,
1293480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
1294480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
1295480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int ok;
1296480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509 *issuer = NULL;
1297480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int crl_score = 0;
1298480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	unsigned int reasons;
1299480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_CRL *crl = NULL, *dcrl = NULL;
1300480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	STACK_OF(X509_CRL) *skcrl;
1301480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_NAME *nm = X509_get_issuer_name(x);
1302480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	reasons = ctx->current_reasons;
1303480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ok = get_crl_sk(ctx, &crl, &dcrl,
1304480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				&issuer, &crl_score, &reasons, ctx->crls);
1305480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1306480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ok)
1307480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto done;
1308480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1309480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Lookup CRLs from store */
1310480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1311480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	skcrl = ctx->lookup_crls(ctx, nm);
1312480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1313480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* If no CRLs found and a near match from get_crl_sk use that */
1314480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!skcrl && crl)
1315480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto done;
1316480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1317480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
1318480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1319480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
1320480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1321480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	done:
1322480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1323480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* If we got any kind of CRL use it and return success */
1324c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (crl)
1325480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1326480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->current_issuer = issuer;
1327480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->current_crl_score = crl_score;
1328480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->current_reasons = reasons;
1329480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		*pcrl = crl;
1330480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		*pdcrl = dcrl;
1331480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 1;
1332480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1333480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1334480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return 0;
1335c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1336c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1337c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Check CRL validity */
1338c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
1339c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1340c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509 *issuer = NULL;
1341c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_PKEY *ikey = NULL;
1342c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int ok = 0, chnum, cnum;
1343c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	cnum = ctx->error_depth;
1344c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	chnum = sk_X509_num(ctx->chain) - 1;
1345480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* if we have an alternative CRL issuer cert use that */
1346480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ctx->current_issuer)
1347480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		issuer = ctx->current_issuer;
1348480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1349480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Else find CRL issuer: if not last certificate then issuer
1350c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * is next certificate in chain.
1351c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 */
1352480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else if (cnum < chnum)
1353c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		issuer = sk_X509_value(ctx->chain, cnum + 1);
1354c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
1355c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1356c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		issuer = sk_X509_value(ctx->chain, chnum);
1357c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* If not self signed, can't check signature */
1358c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if(!ctx->check_issued(ctx, issuer, issuer))
1359c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1360c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
1361c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ok = ctx->verify_cb(0, ctx);
1362c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if(!ok) goto err;
1363c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1364c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1365c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1366c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if(issuer)
1367c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1368480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		/* Skip most tests for deltas because they have already
1369480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 * been done
1370480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 */
1371480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!crl->base_crl_number)
1372c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1373480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			/* Check for cRLSign bit if keyUsage present */
1374480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
1375480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				!(issuer->ex_kusage & KU_CRL_SIGN))
1376480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
1377480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
1378480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				ok = ctx->verify_cb(0, ctx);
1379480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				if(!ok) goto err;
1380480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
1381480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1382480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!(ctx->current_crl_score & CRL_SCORE_SCOPE))
1383480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
1384480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
1385480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				ok = ctx->verify_cb(0, ctx);
1386480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				if(!ok) goto err;
1387480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
1388480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1389480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH))
1390480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
1391480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				if (check_crl_path(ctx, ctx->current_issuer) <= 0)
1392480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					{
1393480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
1394480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					ok = ctx->verify_cb(0, ctx);
1395480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					if(!ok) goto err;
1396480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					}
1397480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
1398480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1399480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (crl->idp_flags & IDP_INVALID)
1400480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
1401480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				ctx->error = X509_V_ERR_INVALID_EXTENSION;
1402480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				ok = ctx->verify_cb(0, ctx);
1403480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				if(!ok) goto err;
1404480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
1405480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1406480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1407480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
1408480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1409480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!(ctx->current_crl_score & CRL_SCORE_TIME))
1410480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
1411480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			ok = check_crl_time(ctx, crl, 1);
1412480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!ok)
1413480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
1414c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1415c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1416c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* Attempt to get issuer certificate public key */
1417c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ikey = X509_get_pubkey(issuer);
1418c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1419c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if(!ikey)
1420c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1421c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
1422c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ok = ctx->verify_cb(0, ctx);
1423c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (!ok) goto err;
1424c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1425c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else
1426c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1427c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* Verify CRL signature */
1428c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if(X509_CRL_verify(crl, ikey) <= 0)
1429c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
1430c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE;
1431c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ok = ctx->verify_cb(0, ctx);
1432c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				if (!ok) goto err;
1433c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
1434c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1435c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1436c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1437c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ok = 1;
1438c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1439c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	err:
1440c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_PKEY_free(ikey);
1441c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ok;
1442c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1443c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1444c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Check certificate against CRL */
1445c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
1446c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1447480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int ok;
1448480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	X509_REVOKED *rev;
1449480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* The rules changed for this... previously if a CRL contained
1450480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	 * unhandled critical extensions it could still be used to indicate
1451480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	 * a certificate was revoked. This has since been changed since
1452480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	 * critical extension can change the meaning of CRL entries.
1453480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	 */
1454480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (crl->flags & EXFLAG_CRITICAL)
1455c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1456480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
1457480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 1;
1458480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
1459480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ok = ctx->verify_cb(0, ctx);
1460480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if(!ok)
1461480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
1462c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1463480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Look for serial number of certificate in CRL
1464480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	 * If found make sure reason is not removeFromCRL.
1465c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 */
1466480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (X509_CRL_get0_by_cert(crl, &rev, x))
1467c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1468480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
1469480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 2;
1470c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error = X509_V_ERR_CERT_REVOKED;
1471c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ok = ctx->verify_cb(0, ctx);
1472480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!ok)
1473480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
1474c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1475c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1476c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
1477c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1478c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1479c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_policy(X509_STORE_CTX *ctx)
1480c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1481c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int ret;
1482480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ctx->parent)
1483480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 1;
1484c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
1485c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->param->policies, ctx->param->flags);
1486c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ret == 0)
1487c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1488c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509err(X509_F_CHECK_POLICY,ERR_R_MALLOC_FAILURE);
1489c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
1490c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1491c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Invalid or inconsistent extensions */
1492c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ret == -1)
1493c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1494c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* Locate certificates with bad extensions and notify
1495c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * callback.
1496c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 */
1497c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509 *x;
1498c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		int i;
1499c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		for (i = 1; i < sk_X509_num(ctx->chain); i++)
1500c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1501c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			x = sk_X509_value(ctx->chain, i);
1502c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
1503c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				continue;
1504c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->current_cert = x;
1505c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
1506480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if(!ctx->verify_cb(0, ctx))
1507480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				return 0;
1508c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1509c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 1;
1510c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1511c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ret == -2)
1512c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1513c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->current_cert = NULL;
1514c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
1515c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return ctx->verify_cb(0, ctx);
1516c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1517c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1518c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY)
1519c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1520c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->current_cert = NULL;
1521c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error = X509_V_OK;
1522c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!ctx->verify_cb(2, ctx))
1523c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
1524c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1525c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1526c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
1527c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1528c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1529c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
1530c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1531c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	time_t *ptime;
1532c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i;
1533c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1534c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
1535c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ptime = &ctx->param->check_time;
1536c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
1537c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ptime = NULL;
1538c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1539c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	i=X509_cmp_time(X509_get_notBefore(x), ptime);
1540c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (i == 0)
1541c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1542c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
1543c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->current_cert=x;
1544c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!ctx->verify_cb(0, ctx))
1545c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
1546c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1547c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1548c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (i > 0)
1549c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1550c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error=X509_V_ERR_CERT_NOT_YET_VALID;
1551c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->current_cert=x;
1552c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!ctx->verify_cb(0, ctx))
1553c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
1554c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1555c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1556c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	i=X509_cmp_time(X509_get_notAfter(x), ptime);
1557c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (i == 0)
1558c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1559c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
1560c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->current_cert=x;
1561c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!ctx->verify_cb(0, ctx))
1562c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
1563c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1564c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1565c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (i < 0)
1566c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1567c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error=X509_V_ERR_CERT_HAS_EXPIRED;
1568c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->current_cert=x;
1569c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!ctx->verify_cb(0, ctx))
1570c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
1571c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1572c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1573c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
1574c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1575c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1576c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgstatic int internal_verify(X509_STORE_CTX *ctx)
1577c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1578c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int ok=0,n;
1579c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509 *xs,*xi;
1580c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_PKEY *pkey=NULL;
1581c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int (*cb)(int xok,X509_STORE_CTX *xctx);
1582c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1583c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	cb=ctx->verify_cb;
1584c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1585c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	n=sk_X509_num(ctx->chain);
1586c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->error_depth=n-1;
1587c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	n--;
1588c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	xi=sk_X509_value(ctx->chain,n);
1589c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1590c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->check_issued(ctx, xi, xi))
1591c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		xs=xi;
1592c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
1593c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1594c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (n <= 0)
1595c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1596c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
1597c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->current_cert=xi;
1598c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ok=cb(0,ctx);
1599c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			goto end;
1600c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1601c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else
1602c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1603c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			n--;
1604c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ctx->error_depth=n;
1605c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			xs=sk_X509_value(ctx->chain,n);
1606c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1607c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1608c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1609c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/*	ctx->error=0;  not needed */
1610c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	while (n >= 0)
1611c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1612c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->error_depth=n;
1613c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1614c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* Skip signature check for self signed certificates unless
1615c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * explicitly asked for. It doesn't add any security and
1616c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * just wastes time.
1617c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 */
1618c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!xs->valid && (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)))
1619c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1620c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if ((pkey=X509_get_pubkey(xi)) == NULL)
1621c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
1622c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
1623c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->current_cert=xi;
1624c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ok=(*cb)(0,ctx);
1625c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				if (!ok) goto end;
1626c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
1627c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else if (X509_verify(xs,pkey) <= 0)
1628c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
1629c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;
1630c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ctx->current_cert=xs;
1631c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				ok=(*cb)(0,ctx);
1632c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				if (!ok)
1633c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					{
1634c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					EVP_PKEY_free(pkey);
1635c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					goto end;
1636c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					}
1637c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
1638c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			EVP_PKEY_free(pkey);
1639c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			pkey=NULL;
1640c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1641c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1642c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		xs->valid = 1;
1643c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1644c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ok = check_cert_time(ctx, xs);
1645c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!ok)
1646c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			goto end;
1647c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1648c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* The last error (if any) is still in the error value */
1649c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->current_issuer=xi;
1650c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->current_cert=xs;
1651c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ok=(*cb)(1,ctx);
1652c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!ok) goto end;
1653c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1654c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		n--;
1655c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (n >= 0)
1656c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1657c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			xi=xs;
1658c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			xs=sk_X509_value(ctx->chain,n);
1659c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1660c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1661c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ok=1;
1662c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgend:
1663c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ok;
1664c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1665c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1666480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint X509_cmp_current_time(const ASN1_TIME *ctm)
1667c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
1668c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return X509_cmp_time(ctm, NULL);
1669c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
1670c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1671480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
1672c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1673c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	char *str;
1674c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ASN1_TIME atm;
1675c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	long offset;
1676c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	char buff1[24],buff2[24],*p;
1677c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i,j;
1678c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1679c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	p=buff1;
1680c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	i=ctm->length;
1681c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	str=(char *)ctm->data;
1682c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctm->type == V_ASN1_UTCTIME)
1683c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1684c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if ((i < 11) || (i > 17)) return 0;
1685c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		memcpy(p,str,10);
1686c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		p+=10;
1687c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		str+=10;
1688c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1689c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
1690c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1691c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (i < 13) return 0;
1692c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		memcpy(p,str,12);
1693c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		p+=12;
1694c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		str+=12;
1695c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1696c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1697c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if ((*str == 'Z') || (*str == '-') || (*str == '+'))
1698c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{ *(p++)='0'; *(p++)='0'; }
1699c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
1700c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1701c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		*(p++)= *(str++);
1702c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		*(p++)= *(str++);
1703c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* Skip any fractional seconds... */
1704c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (*str == '.')
1705c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1706c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			str++;
1707c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			while ((*str >= '0') && (*str <= '9')) str++;
1708c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1709c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1710c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1711c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	*(p++)='Z';
1712c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	*(p++)='\0';
1713c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1714c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (*str == 'Z')
1715c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		offset=0;
1716c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
1717c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1718c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if ((*str != '+') && (*str != '-'))
1719c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
1720c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		offset=((str[1]-'0')*10+(str[2]-'0'))*60;
1721c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		offset+=(str[3]-'0')*10+(str[4]-'0');
1722c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (*str == '-')
1723c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			offset= -offset;
1724c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1725c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	atm.type=ctm->type;
1726480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	atm.flags = 0;
1727c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	atm.length=sizeof(buff2);
1728c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	atm.data=(unsigned char *)buff2;
1729c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1730480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (X509_time_adj(&atm, offset*60, cmp_time) == NULL)
1731c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
1732c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1733c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctm->type == V_ASN1_UTCTIME)
1734c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1735c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		i=(buff1[0]-'0')*10+(buff1[1]-'0');
1736c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (i < 50) i+=100; /* cf. RFC 2459 */
1737c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		j=(buff2[0]-'0')*10+(buff2[1]-'0');
1738c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (j < 50) j+=100;
1739c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1740c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (i < j) return -1;
1741c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (i > j) return 1;
1742c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1743c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	i=strcmp(buff1,buff2);
1744c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (i == 0) /* wait a second then return younger :-) */
1745c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return -1;
1746c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
1747c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return i;
1748c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1749c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1750c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
1751c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
1752c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return X509_time_adj(s, adj, NULL);
1753c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
1754c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1755480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
1756480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
1757480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return X509_time_adj_ex(s, 0, offset_sec, in_tm);
1758480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1759480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1760480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
1761480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				int offset_day, long offset_sec, time_t *in_tm)
1762c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1763c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	time_t t;
1764c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1765c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (in_tm) t = *in_tm;
1766c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else time(&t);
1767c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1768480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING))
1769480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1770480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (s->type == V_ASN1_UTCTIME)
1771480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec);
1772480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (s->type == V_ASN1_GENERALIZEDTIME)
1773480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return ASN1_GENERALIZEDTIME_adj(s, t, offset_day,
1774480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org								offset_sec);
1775480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1776480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return ASN1_TIME_adj(s, t, offset_day, offset_sec);
1777c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1778c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1779c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
1780c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1781c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_PKEY *ktmp=NULL,*ktmp2;
1782c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i,j;
1783c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1784c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) return 1;
1785c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1786c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for (i=0; i<sk_X509_num(chain); i++)
1787c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1788c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ktmp=X509_get_pubkey(sk_X509_value(chain,i));
1789c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (ktmp == NULL)
1790c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1791c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
1792c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
1793c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1794c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!EVP_PKEY_missing_parameters(ktmp))
1795c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			break;
1796c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else
1797c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1798c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			EVP_PKEY_free(ktmp);
1799c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ktmp=NULL;
1800c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1801c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1802c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ktmp == NULL)
1803c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1804c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
1805c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
1806c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1807c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1808c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* first, populate the other certs */
1809c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for (j=i-1; j >= 0; j--)
1810c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1811c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ktmp2=X509_get_pubkey(sk_X509_value(chain,j));
1812c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		EVP_PKEY_copy_parameters(ktmp2,ktmp);
1813c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		EVP_PKEY_free(ktmp2);
1814c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1815c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1816c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (pkey != NULL) EVP_PKEY_copy_parameters(pkey,ktmp);
1817c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_PKEY_free(ktmp);
1818c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
1819c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1820c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1821c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
1822c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
1823c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1824c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* This function is (usually) called only once, by
1825c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */
1826c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp,
1827c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			new_func, dup_func, free_func);
1828c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1829c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1830c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
1831c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1832c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return CRYPTO_set_ex_data(&ctx->ex_data,idx,data);
1833c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1834c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1835c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
1836c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1837c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return CRYPTO_get_ex_data(&ctx->ex_data,idx);
1838c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1839c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1840c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
1841c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1842c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ctx->error;
1843c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1844c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1845c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
1846c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1847c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->error=err;
1848c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1849c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1850c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
1851c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1852c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ctx->error_depth;
1853c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1854c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1855c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgX509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
1856c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1857c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ctx->current_cert;
1858c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1859c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1860c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgSTACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
1861c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1862c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ctx->chain;
1863c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1864c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1865c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgSTACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
1866c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1867c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i;
1868c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509 *x;
1869c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	STACK_OF(X509) *chain;
1870c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) return NULL;
1871c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for (i = 0; i < sk_X509_num(chain); i++)
1872c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1873c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		x = sk_X509_value(chain, i);
1874c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
1875c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1876c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return chain;
1877c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1878c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1879480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgX509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
1880480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
1881480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return ctx->current_issuer;
1882480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1883480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1884480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgX509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
1885480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
1886480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return ctx->current_crl;
1887480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1888480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1889480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgX509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
1890480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	{
1891480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return ctx->parent;
1892480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1893480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1894c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
1895c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1896c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->cert=x;
1897c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1898c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1899c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
1900c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1901c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->untrusted=sk;
1902c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1903c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1904c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
1905c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1906c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->crls=sk;
1907c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1908c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1909c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
1910c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1911c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
1912c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1913c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1914c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
1915c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1916c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
1917c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1918c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1919c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* This function is used to set the X509_STORE_CTX purpose and trust
1920c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * values. This is intended to be used when another structure has its
1921c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * own trust and purpose values which (if set) will be inherited by
1922c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the ctx. If they aren't set then we will usually have a default
1923c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * purpose in mind which should then be used to set the trust value.
1924c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * An example of this is SSL use: an SSL structure will have its own
1925c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * purpose and trust settings which the application can set: if they
1926c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * aren't set then we use the default of SSL client/server.
1927c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
1928c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1929c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
1930c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				int purpose, int trust)
1931c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
1932c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int idx;
1933c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* If purpose not set use default */
1934c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!purpose) purpose = def_purpose;
1935c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* If we have a purpose then check it is valid */
1936c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (purpose)
1937c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1938c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509_PURPOSE *ptmp;
1939c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		idx = X509_PURPOSE_get_by_id(purpose);
1940c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (idx == -1)
1941c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1942c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1943c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						X509_R_UNKNOWN_PURPOSE_ID);
1944c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
1945c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1946c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ptmp = X509_PURPOSE_get0(idx);
1947c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (ptmp->trust == X509_TRUST_DEFAULT)
1948c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1949c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			idx = X509_PURPOSE_get_by_id(def_purpose);
1950c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (idx == -1)
1951c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
1952c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1953c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						X509_R_UNKNOWN_PURPOSE_ID);
1954c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				return 0;
1955c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
1956c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			ptmp = X509_PURPOSE_get0(idx);
1957c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1958c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* If trust not set then get from purpose default */
1959c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!trust) trust = ptmp->trust;
1960c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1961c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (trust)
1962c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1963c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		idx = X509_TRUST_get_by_id(trust);
1964c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (idx == -1)
1965c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1966c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1967c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org						X509_R_UNKNOWN_TRUST_ID);
1968c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			return 0;
1969c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1970c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1971c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1972c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (purpose && !ctx->param->purpose) ctx->param->purpose = purpose;
1973c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (trust && !ctx->param->trust) ctx->param->trust = trust;
1974c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
1975c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
1976c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1977c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgX509_STORE_CTX *X509_STORE_CTX_new(void)
1978c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
1979c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509_STORE_CTX *ctx;
1980c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
1981c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!ctx)
1982c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1983c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509err(X509_F_X509_STORE_CTX_NEW,ERR_R_MALLOC_FAILURE);
1984c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return NULL;
1985c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1986c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	memset(ctx, 0, sizeof(X509_STORE_CTX));
1987c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ctx;
1988c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
1989c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1990c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_free(X509_STORE_CTX *ctx)
1991c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
1992c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509_STORE_CTX_cleanup(ctx);
1993c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	OPENSSL_free(ctx);
1994c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
1995c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1996c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
1997c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	     STACK_OF(X509) *chain)
1998c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1999c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int ret = 1;
2000c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->ctx=store;
2001c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->current_method=0;
2002c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->cert=x509;
2003c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->untrusted=chain;
2004c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->crls = NULL;
2005c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->last_untrusted=0;
2006c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->other_ctx=NULL;
2007c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->valid=0;
2008c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->chain=NULL;
2009c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->error=0;
2010c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->explicit_policy=0;
2011c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->error_depth=0;
2012c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->current_cert=NULL;
2013c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->current_issuer=NULL;
2014480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ctx->current_crl=NULL;
2015480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ctx->current_crl_score=0;
2016480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ctx->current_reasons=0;
2017c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->tree = NULL;
2018480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ctx->parent = NULL;
2019c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2020c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->param = X509_VERIFY_PARAM_new();
2021c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2022c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!ctx->param)
2023c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
2024c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
2025c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
2026c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
2027c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2028c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* Inherit callbacks and flags from X509_STORE if not set
2029c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * use defaults.
2030c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 */
2031c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2032c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2033c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (store)
2034c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
2035c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
2036480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE;
2037c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2038c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (store)
2039c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
2040c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->verify_cb = store->verify_cb;
2041c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->cleanup = store->cleanup;
2042c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
2043c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
2044c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->cleanup = 0;
2045c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2046c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ret)
2047c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ret = X509_VERIFY_PARAM_inherit(ctx->param,
2048c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					X509_VERIFY_PARAM_lookup("default"));
2049c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2050c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ret == 0)
2051c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
2052c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
2053c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
2054c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
2055c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2056c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (store && store->check_issued)
2057c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->check_issued = store->check_issued;
2058c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
2059c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->check_issued = check_issued;
2060c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2061c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (store && store->get_issuer)
2062c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->get_issuer = store->get_issuer;
2063c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
2064c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->get_issuer = X509_STORE_CTX_get1_issuer;
2065c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2066c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (store && store->verify_cb)
2067c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->verify_cb = store->verify_cb;
2068c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
2069c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->verify_cb = null_callback;
2070c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2071c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (store && store->verify)
2072c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->verify = store->verify;
2073c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
2074c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->verify = internal_verify;
2075c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2076c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (store && store->check_revocation)
2077c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->check_revocation = store->check_revocation;
2078c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
2079c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->check_revocation = check_revocation;
2080c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2081c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (store && store->get_crl)
2082c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->get_crl = store->get_crl;
2083c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
2084480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->get_crl = NULL;
2085c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2086c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (store && store->check_crl)
2087c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->check_crl = store->check_crl;
2088c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
2089c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->check_crl = check_crl;
2090c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2091c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (store && store->cert_crl)
2092c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->cert_crl = store->cert_crl;
2093c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
2094c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->cert_crl = cert_crl;
2095c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2096480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (store && store->lookup_certs)
2097480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->lookup_certs = store->lookup_certs;
2098480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
2099480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->lookup_certs = X509_STORE_get1_certs;
2100480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
2101480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (store && store->lookup_crls)
2102480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->lookup_crls = store->lookup_crls;
2103480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
2104480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		ctx->lookup_crls = X509_STORE_get1_crls;
2105480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
2106c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->check_policy = check_policy;
2107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2108c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2109c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* This memset() can't make any sense anyway, so it's removed. As
2110c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a
2111c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 * corresponding "new" here and remove this bogus initialisation. */
2112c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */
2113c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if(!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
2114c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				&(ctx->ex_data)))
2115c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
2116c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		OPENSSL_free(ctx);
2117c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE);
2118c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
2119c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
2120c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return 1;
2121c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
2122c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2123c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Set alternative lookup method: just a STACK of trusted certificates.
2124c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This avoids X509_STORE nastiness where it isn't needed.
2125c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
2126c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2127c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
2128c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{
2129c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->other_ctx = sk;
2130c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->get_issuer = get_issuer_sk;
2131c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org}
2132c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2133c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
2134c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
2135c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->cleanup) ctx->cleanup(ctx);
2136c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->param != NULL)
2137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
2138480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (ctx->parent == NULL)
2139480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			X509_VERIFY_PARAM_free(ctx->param);
2140c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->param=NULL;
2141c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
2142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->tree != NULL)
2143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
2144c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509_policy_tree_free(ctx->tree);
2145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->tree=NULL;
2146c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
2147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->chain != NULL)
2148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
2149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		sk_X509_pop_free(ctx->chain,X509_free);
2150c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ctx->chain=NULL;
2151c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
2152c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data));
2153c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA));
2154c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
2155c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2156c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
2157c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
2158c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
2159c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
2160c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2161c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
2162c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
2163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509_VERIFY_PARAM_set_flags(ctx->param, flags);
2164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
2165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t)
2167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
2168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	X509_VERIFY_PARAM_set_time(ctx->param, t);
2169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
2170c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2171c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
2172c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				  int (*verify_cb)(int, X509_STORE_CTX *))
2173c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
2174c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->verify_cb=verify_cb;
2175c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
2176c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2177c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgX509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
2178c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
2179c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ctx->tree;
2180c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
2181c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2182c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
2183c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
2184c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ctx->explicit_policy;
2185c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
2186c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2187c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
2188c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
2189c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	const X509_VERIFY_PARAM *param;
2190c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	param = X509_VERIFY_PARAM_lookup(name);
2191c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (!param)
2192c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return 0;
2193c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return X509_VERIFY_PARAM_inherit(ctx->param, param);
2194c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
2195c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgX509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
2197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
2198c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return ctx->param;
2199c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
2200c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2201c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgvoid X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
2202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
2203c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (ctx->param)
2204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		X509_VERIFY_PARAM_free(ctx->param);
2205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ctx->param = param;
2206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
2207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgIMPLEMENT_STACK_OF(X509)
2209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgIMPLEMENT_ASN1_SET_OF(X509)
2210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgIMPLEMENT_STACK_OF(X509_NAME)
2212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
2213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgIMPLEMENT_STACK_OF(X509_ATTRIBUTE)
2214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgIMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
2215