155714Skris/* crypto/x509/x509_vfy.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296465Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296465Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296465Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296465Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296465Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include <time.h>
6155714Skris#include <errno.h>
6255714Skris
6359191Skris#include "cryptlib.h"
6455714Skris#include <openssl/crypto.h>
6555714Skris#include <openssl/lhash.h>
6655714Skris#include <openssl/buffer.h>
6755714Skris#include <openssl/evp.h>
6855714Skris#include <openssl/asn1.h>
6955714Skris#include <openssl/x509.h>
7059191Skris#include <openssl/x509v3.h>
7155714Skris#include <openssl/objects.h>
7255714Skris
73296465Sdelphijstatic int null_callback(int ok, X509_STORE_CTX *e);
7468651Skrisstatic int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
7568651Skrisstatic X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
76160814Ssimonstatic int check_chain_extensions(X509_STORE_CTX *ctx);
7759191Skrisstatic int check_trust(X509_STORE_CTX *ctx);
78109998Smarkmstatic int check_revocation(X509_STORE_CTX *ctx);
79109998Smarkmstatic int check_cert(X509_STORE_CTX *ctx);
80160814Ssimonstatic int check_policy(X509_STORE_CTX *ctx);
8155714Skrisstatic int internal_verify(X509_STORE_CTX *ctx);
82296465Sdelphijconst char X509_version[] = "X.509" OPENSSL_VERSION_PTEXT;
8355714Skris
8455714Skrisstatic int null_callback(int ok, X509_STORE_CTX *e)
85296465Sdelphij{
86296465Sdelphij    return ok;
87296465Sdelphij}
8855714Skris
8955714Skris#if 0
9055714Skrisstatic int x509_subject_cmp(X509 **a, X509 **b)
91296465Sdelphij{
92296465Sdelphij    return X509_subject_name_cmp(*a, *b);
93296465Sdelphij}
9455714Skris#endif
9555714Skris
9655714Skrisint X509_verify_cert(X509_STORE_CTX *ctx)
97296465Sdelphij{
98296465Sdelphij    X509 *x, *xtmp, *chain_ss = NULL;
99296465Sdelphij    int bad_chain = 0;
100296465Sdelphij    X509_VERIFY_PARAM *param = ctx->param;
101296465Sdelphij    int depth, i, ok = 0;
102296465Sdelphij    int num;
103296465Sdelphij    int (*cb) (int xok, X509_STORE_CTX *xctx);
104296465Sdelphij    STACK_OF(X509) *sktmp = NULL;
105296465Sdelphij    if (ctx->cert == NULL) {
106296465Sdelphij        X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
107296465Sdelphij        return -1;
108296465Sdelphij    }
10955714Skris
110296465Sdelphij    cb = ctx->verify_cb;
11155714Skris
112296465Sdelphij    /*
113296465Sdelphij     * first we make sure the chain we are going to build is present and that
114296465Sdelphij     * the first entry is in place
115296465Sdelphij     */
116296465Sdelphij    if (ctx->chain == NULL) {
117296465Sdelphij        if (((ctx->chain = sk_X509_new_null()) == NULL) ||
118296465Sdelphij            (!sk_X509_push(ctx->chain, ctx->cert))) {
119296465Sdelphij            X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
120296465Sdelphij            goto end;
121296465Sdelphij        }
122296465Sdelphij        CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509);
123296465Sdelphij        ctx->last_untrusted = 1;
124296465Sdelphij    }
12555714Skris
126296465Sdelphij    /* We use a temporary STACK so we can chop and hack at it */
127296465Sdelphij    if (ctx->untrusted != NULL
128296465Sdelphij        && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
129296465Sdelphij        X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
130296465Sdelphij        goto end;
131296465Sdelphij    }
13255714Skris
133296465Sdelphij    num = sk_X509_num(ctx->chain);
134296465Sdelphij    x = sk_X509_value(ctx->chain, num - 1);
135296465Sdelphij    depth = param->depth;
13655714Skris
137296465Sdelphij    for (;;) {
138296465Sdelphij        /* If we have enough, we break */
139296465Sdelphij        if (depth < num)
140296465Sdelphij            break;              /* FIXME: If this happens, we should take
141296465Sdelphij                                 * note of it and, if appropriate, use the
142296465Sdelphij                                 * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
143296465Sdelphij                                 * later. */
14455714Skris
145296465Sdelphij        /* If we are self signed, we break */
146296465Sdelphij        if (ctx->check_issued(ctx, x, x))
147296465Sdelphij            break;
14855714Skris
149296465Sdelphij        /* If we were passed a cert chain, use it first */
150296465Sdelphij        if (ctx->untrusted != NULL) {
151296465Sdelphij            xtmp = find_issuer(ctx, sktmp, x);
152296465Sdelphij            if (xtmp != NULL) {
153296465Sdelphij                if (!sk_X509_push(ctx->chain, xtmp)) {
154296465Sdelphij                    X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
155296465Sdelphij                    goto end;
156296465Sdelphij                }
157296465Sdelphij                CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509);
158296465Sdelphij                (void)sk_X509_delete_ptr(sktmp, xtmp);
159296465Sdelphij                ctx->last_untrusted++;
160296465Sdelphij                x = xtmp;
161296465Sdelphij                num++;
162296465Sdelphij                /*
163296465Sdelphij                 * reparse the full chain for the next one
164296465Sdelphij                 */
165296465Sdelphij                continue;
166296465Sdelphij            }
167296465Sdelphij        }
168296465Sdelphij        break;
169296465Sdelphij    }
17055714Skris
171296465Sdelphij    /*
172296465Sdelphij     * at this point, chain should contain a list of untrusted certificates.
173296465Sdelphij     * We now need to add at least one trusted one, if possible, otherwise we
174296465Sdelphij     * complain.
175296465Sdelphij     */
17655714Skris
177296465Sdelphij    /*
178296465Sdelphij     * Examine last certificate in chain and see if it is self signed.
179296465Sdelphij     */
18055714Skris
181296465Sdelphij    i = sk_X509_num(ctx->chain);
182296465Sdelphij    x = sk_X509_value(ctx->chain, i - 1);
183296465Sdelphij    if (ctx->check_issued(ctx, x, x)) {
184296465Sdelphij        /* we have a self signed certificate */
185296465Sdelphij        if (sk_X509_num(ctx->chain) == 1) {
186296465Sdelphij            /*
187296465Sdelphij             * We have a single self signed certificate: see if we can find
188296465Sdelphij             * it in the store. We must have an exact match to avoid possible
189296465Sdelphij             * impersonation.
190296465Sdelphij             */
191296465Sdelphij            ok = ctx->get_issuer(&xtmp, ctx, x);
192296465Sdelphij            if ((ok <= 0) || X509_cmp(x, xtmp)) {
193296465Sdelphij                ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
194296465Sdelphij                ctx->current_cert = x;
195296465Sdelphij                ctx->error_depth = i - 1;
196296465Sdelphij                if (ok == 1)
197296465Sdelphij                    X509_free(xtmp);
198296465Sdelphij                bad_chain = 1;
199296465Sdelphij                ok = cb(0, ctx);
200296465Sdelphij                if (!ok)
201296465Sdelphij                    goto end;
202296465Sdelphij            } else {
203296465Sdelphij                /*
204296465Sdelphij                 * We have a match: replace certificate with store version so
205296465Sdelphij                 * we get any trust settings.
206296465Sdelphij                 */
207296465Sdelphij                X509_free(x);
208296465Sdelphij                x = xtmp;
209296465Sdelphij                (void)sk_X509_set(ctx->chain, i - 1, x);
210296465Sdelphij                ctx->last_untrusted = 0;
211296465Sdelphij            }
212296465Sdelphij        } else {
213296465Sdelphij            /*
214296465Sdelphij             * extract and save self signed certificate for later use
215296465Sdelphij             */
216296465Sdelphij            chain_ss = sk_X509_pop(ctx->chain);
217296465Sdelphij            ctx->last_untrusted--;
218296465Sdelphij            num--;
219296465Sdelphij            x = sk_X509_value(ctx->chain, num - 1);
220296465Sdelphij        }
221296465Sdelphij    }
22268651Skris
223296465Sdelphij    /* We now lookup certs from the certificate store */
224296465Sdelphij    for (;;) {
225296465Sdelphij        /* If we have enough, we break */
226296465Sdelphij        if (depth < num)
227296465Sdelphij            break;
22855714Skris
229296465Sdelphij        /* If we are self signed, we break */
230296465Sdelphij        if (ctx->check_issued(ctx, x, x))
231296465Sdelphij            break;
23255714Skris
233296465Sdelphij        ok = ctx->get_issuer(&xtmp, ctx, x);
23455714Skris
235296465Sdelphij        if (ok < 0)
236296465Sdelphij            return ok;
237296465Sdelphij        if (ok == 0)
238296465Sdelphij            break;
23968651Skris
240296465Sdelphij        x = xtmp;
241296465Sdelphij        if (!sk_X509_push(ctx->chain, x)) {
242296465Sdelphij            X509_free(xtmp);
243296465Sdelphij            X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
244296465Sdelphij            return 0;
245296465Sdelphij        }
246296465Sdelphij        num++;
247296465Sdelphij    }
24868651Skris
249296465Sdelphij    /* we now have our chain, lets check it... */
25055714Skris
251296465Sdelphij    /* Is last certificate looked up self signed? */
252296465Sdelphij    if (!ctx->check_issued(ctx, x, x)) {
253296465Sdelphij        if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
254296465Sdelphij            if (ctx->last_untrusted >= num)
255296465Sdelphij                ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
256296465Sdelphij            else
257296465Sdelphij                ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
258296465Sdelphij            ctx->current_cert = x;
259296465Sdelphij        } else {
26068651Skris
261296465Sdelphij            sk_X509_push(ctx->chain, chain_ss);
262296465Sdelphij            num++;
263296465Sdelphij            ctx->last_untrusted = num;
264296465Sdelphij            ctx->current_cert = chain_ss;
265296465Sdelphij            ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
266296465Sdelphij            chain_ss = NULL;
267296465Sdelphij        }
26855714Skris
269296465Sdelphij        ctx->error_depth = num - 1;
270296465Sdelphij        bad_chain = 1;
271296465Sdelphij        ok = cb(0, ctx);
272296465Sdelphij        if (!ok)
273296465Sdelphij            goto end;
274296465Sdelphij    }
27555714Skris
276296465Sdelphij    /* We have the chain complete: now we need to check its purpose */
277296465Sdelphij    ok = check_chain_extensions(ctx);
27855714Skris
279296465Sdelphij    if (!ok)
280296465Sdelphij        goto end;
28159191Skris
282296465Sdelphij    /* The chain extensions are OK: check trust */
28359191Skris
284296465Sdelphij    if (param->trust > 0)
285296465Sdelphij        ok = check_trust(ctx);
28659191Skris
287296465Sdelphij    if (!ok)
288296465Sdelphij        goto end;
28959191Skris
290296465Sdelphij    /* We may as well copy down any DSA parameters that are required */
291296465Sdelphij    X509_get_pubkey_parameters(NULL, ctx->chain);
29259191Skris
293296465Sdelphij    /*
294296465Sdelphij     * Check revocation status: we do this after copying parameters because
295296465Sdelphij     * they may be needed for CRL signature verification.
296296465Sdelphij     */
29755714Skris
298296465Sdelphij    ok = ctx->check_revocation(ctx);
299296465Sdelphij    if (!ok)
300296465Sdelphij        goto end;
301109998Smarkm
302296465Sdelphij    /* At this point, we have a chain and need to verify it */
303296465Sdelphij    if (ctx->verify != NULL)
304296465Sdelphij        ok = ctx->verify(ctx);
305296465Sdelphij    else
306296465Sdelphij        ok = internal_verify(ctx);
307296465Sdelphij    if (!ok)
308296465Sdelphij        goto end;
309109998Smarkm
310167612Ssimon#ifndef OPENSSL_NO_RFC3779
311296465Sdelphij    /* RFC 3779 path validation, now that CRL check has been done */
312296465Sdelphij    ok = v3_asid_validate_path(ctx);
313296465Sdelphij    if (!ok)
314296465Sdelphij        goto end;
315296465Sdelphij    ok = v3_addr_validate_path(ctx);
316296465Sdelphij    if (!ok)
317296465Sdelphij        goto end;
318167612Ssimon#endif
319167612Ssimon
320296465Sdelphij    /* If we get this far evaluate policies */
321296465Sdelphij    if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
322296465Sdelphij        ok = ctx->check_policy(ctx);
323296465Sdelphij    if (!ok)
324296465Sdelphij        goto end;
325296465Sdelphij    if (0) {
326296465Sdelphij end:
327296465Sdelphij        X509_get_pubkey_parameters(NULL, ctx->chain);
328296465Sdelphij    }
329296465Sdelphij    if (sktmp != NULL)
330296465Sdelphij        sk_X509_free(sktmp);
331296465Sdelphij    if (chain_ss != NULL)
332296465Sdelphij        X509_free(chain_ss);
333296465Sdelphij    return ok;
334296465Sdelphij}
33555714Skris
336296465Sdelphij/*
337296465Sdelphij * Given a STACK_OF(X509) find the issuer of cert (if any)
33868651Skris */
33968651Skris
34068651Skrisstatic X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
34168651Skris{
342296465Sdelphij    int i;
343296465Sdelphij    X509 *issuer;
344296465Sdelphij    for (i = 0; i < sk_X509_num(sk); i++) {
345296465Sdelphij        issuer = sk_X509_value(sk, i);
346296465Sdelphij        if (ctx->check_issued(ctx, x, issuer))
347296465Sdelphij            return issuer;
348296465Sdelphij    }
349296465Sdelphij    return NULL;
35068651Skris}
35168651Skris
35268651Skris/* Given a possible certificate and issuer check them */
35368651Skris
35468651Skrisstatic int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
35568651Skris{
356296465Sdelphij    int ret;
357296465Sdelphij    ret = X509_check_issued(issuer, x);
358296465Sdelphij    if (ret == X509_V_OK)
359296465Sdelphij        return 1;
360296465Sdelphij    /* If we haven't asked for issuer errors don't set ctx */
361296465Sdelphij    if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
362296465Sdelphij        return 0;
36368651Skris
364296465Sdelphij    ctx->error = ret;
365296465Sdelphij    ctx->current_cert = x;
366296465Sdelphij    ctx->current_issuer = issuer;
367296465Sdelphij    return ctx->verify_cb(0, ctx);
368296465Sdelphij    return 0;
36968651Skris}
37068651Skris
37168651Skris/* Alternative lookup method: look from a STACK stored in other_ctx */
37268651Skris
37368651Skrisstatic int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
37468651Skris{
375296465Sdelphij    *issuer = find_issuer(ctx, ctx->other_ctx, x);
376296465Sdelphij    if (*issuer) {
377296465Sdelphij        CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
378296465Sdelphij        return 1;
379296465Sdelphij    } else
380296465Sdelphij        return 0;
38168651Skris}
38268651Skris
383296465Sdelphij/*
384296465Sdelphij * Check a certificate chains extensions for consistency with the supplied
385296465Sdelphij * purpose
38659191Skris */
38759191Skris
388160814Ssimonstatic int check_chain_extensions(X509_STORE_CTX *ctx)
38959191Skris{
390109998Smarkm#ifdef OPENSSL_NO_CHAIN_VERIFY
391296465Sdelphij    return 1;
39259191Skris#else
393296465Sdelphij    int i, ok = 0, must_be_ca, plen = 0;
394296465Sdelphij    X509 *x;
395296465Sdelphij    int (*cb) (int xok, X509_STORE_CTX *xctx);
396296465Sdelphij    int proxy_path_length = 0;
397296465Sdelphij    int allow_proxy_certs =
398296465Sdelphij        ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
399296465Sdelphij    cb = ctx->verify_cb;
400160814Ssimon
401296465Sdelphij    /*-
402296465Sdelphij     *  must_be_ca can have 1 of 3 values:
403296465Sdelphij     * -1: we accept both CA and non-CA certificates, to allow direct
404296465Sdelphij     *     use of self-signed certificates (which are marked as CA).
405296465Sdelphij     * 0:  we only accept non-CA certificates.  This is currently not
406296465Sdelphij     *     used, but the possibility is present for future extensions.
407296465Sdelphij     * 1:  we only accept CA certificates.  This is currently used for
408296465Sdelphij     *     all certificates in the chain except the leaf certificate.
409296465Sdelphij     */
410296465Sdelphij    must_be_ca = -1;
411160814Ssimon
412296465Sdelphij    /*
413296465Sdelphij     * A hack to keep people who don't want to modify their software happy
414296465Sdelphij     */
415296465Sdelphij    if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
416296465Sdelphij        allow_proxy_certs = 1;
417160814Ssimon
418296465Sdelphij    /* Check all untrusted certificates */
419296465Sdelphij    for (i = 0; i < ctx->last_untrusted; i++) {
420296465Sdelphij        int ret;
421296465Sdelphij        x = sk_X509_value(ctx->chain, i);
422296465Sdelphij        if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
423296465Sdelphij            && (x->ex_flags & EXFLAG_CRITICAL)) {
424296465Sdelphij            ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
425296465Sdelphij            ctx->error_depth = i;
426296465Sdelphij            ctx->current_cert = x;
427296465Sdelphij            ok = cb(0, ctx);
428296465Sdelphij            if (!ok)
429296465Sdelphij                goto end;
430296465Sdelphij        }
431296465Sdelphij        if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
432296465Sdelphij            ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
433296465Sdelphij            ctx->error_depth = i;
434296465Sdelphij            ctx->current_cert = x;
435296465Sdelphij            ok = cb(0, ctx);
436296465Sdelphij            if (!ok)
437296465Sdelphij                goto end;
438296465Sdelphij        }
439296465Sdelphij        ret = X509_check_ca(x);
440296465Sdelphij        switch (must_be_ca) {
441296465Sdelphij        case -1:
442296465Sdelphij            if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
443296465Sdelphij                && (ret != 1) && (ret != 0)) {
444296465Sdelphij                ret = 0;
445296465Sdelphij                ctx->error = X509_V_ERR_INVALID_CA;
446296465Sdelphij            } else
447296465Sdelphij                ret = 1;
448296465Sdelphij            break;
449296465Sdelphij        case 0:
450296465Sdelphij            if (ret != 0) {
451296465Sdelphij                ret = 0;
452296465Sdelphij                ctx->error = X509_V_ERR_INVALID_NON_CA;
453296465Sdelphij            } else
454296465Sdelphij                ret = 1;
455296465Sdelphij            break;
456296465Sdelphij        default:
457296465Sdelphij            if ((ret == 0)
458296465Sdelphij                || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
459296465Sdelphij                    && (ret != 1))) {
460296465Sdelphij                ret = 0;
461296465Sdelphij                ctx->error = X509_V_ERR_INVALID_CA;
462296465Sdelphij            } else
463296465Sdelphij                ret = 1;
464296465Sdelphij            break;
465296465Sdelphij        }
466296465Sdelphij        if (ret == 0) {
467296465Sdelphij            ctx->error_depth = i;
468296465Sdelphij            ctx->current_cert = x;
469296465Sdelphij            ok = cb(0, ctx);
470296465Sdelphij            if (!ok)
471296465Sdelphij                goto end;
472296465Sdelphij        }
473296465Sdelphij        if (ctx->param->purpose > 0) {
474296465Sdelphij            ret = X509_check_purpose(x, ctx->param->purpose, must_be_ca > 0);
475296465Sdelphij            if ((ret == 0)
476296465Sdelphij                || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
477296465Sdelphij                    && (ret != 1))) {
478296465Sdelphij                ctx->error = X509_V_ERR_INVALID_PURPOSE;
479296465Sdelphij                ctx->error_depth = i;
480296465Sdelphij                ctx->current_cert = x;
481296465Sdelphij                ok = cb(0, ctx);
482296465Sdelphij                if (!ok)
483296465Sdelphij                    goto end;
484296465Sdelphij            }
485296465Sdelphij        }
486296465Sdelphij        /* Check pathlen if not self issued */
487296465Sdelphij        if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
488296465Sdelphij            && (x->ex_pathlen != -1)
489296465Sdelphij            && (plen > (x->ex_pathlen + proxy_path_length + 1))) {
490296465Sdelphij            ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
491296465Sdelphij            ctx->error_depth = i;
492296465Sdelphij            ctx->current_cert = x;
493296465Sdelphij            ok = cb(0, ctx);
494296465Sdelphij            if (!ok)
495296465Sdelphij                goto end;
496296465Sdelphij        }
497296465Sdelphij        /* Increment path length if not self issued */
498296465Sdelphij        if (!(x->ex_flags & EXFLAG_SI))
499296465Sdelphij            plen++;
500296465Sdelphij        /*
501296465Sdelphij         * If this certificate is a proxy certificate, the next certificate
502296465Sdelphij         * must be another proxy certificate or a EE certificate.  If not,
503296465Sdelphij         * the next certificate must be a CA certificate.
504296465Sdelphij         */
505296465Sdelphij        if (x->ex_flags & EXFLAG_PROXY) {
506296465Sdelphij            if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
507296465Sdelphij                ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
508296465Sdelphij                ctx->error_depth = i;
509296465Sdelphij                ctx->current_cert = x;
510296465Sdelphij                ok = cb(0, ctx);
511296465Sdelphij                if (!ok)
512296465Sdelphij                    goto end;
513296465Sdelphij            }
514296465Sdelphij            proxy_path_length++;
515296465Sdelphij            must_be_ca = 0;
516296465Sdelphij        } else
517296465Sdelphij            must_be_ca = 1;
518296465Sdelphij    }
519296465Sdelphij    ok = 1;
52068651Skris end:
521296465Sdelphij    return ok;
52259191Skris#endif
52359191Skris}
52459191Skris
52559191Skrisstatic int check_trust(X509_STORE_CTX *ctx)
52659191Skris{
527109998Smarkm#ifdef OPENSSL_NO_CHAIN_VERIFY
528296465Sdelphij    return 1;
52959191Skris#else
530296465Sdelphij    int i, ok;
531296465Sdelphij    X509 *x;
532296465Sdelphij    int (*cb) (int xok, X509_STORE_CTX *xctx);
533296465Sdelphij    cb = ctx->verify_cb;
53459191Skris/* For now just check the last certificate in the chain */
535296465Sdelphij    i = sk_X509_num(ctx->chain) - 1;
536296465Sdelphij    x = sk_X509_value(ctx->chain, i);
537296465Sdelphij    ok = X509_check_trust(x, ctx->param->trust, 0);
538296465Sdelphij    if (ok == X509_TRUST_TRUSTED)
539296465Sdelphij        return 1;
540296465Sdelphij    ctx->error_depth = i;
541296465Sdelphij    ctx->current_cert = x;
542296465Sdelphij    if (ok == X509_TRUST_REJECTED)
543296465Sdelphij        ctx->error = X509_V_ERR_CERT_REJECTED;
544296465Sdelphij    else
545296465Sdelphij        ctx->error = X509_V_ERR_CERT_UNTRUSTED;
546296465Sdelphij    ok = cb(0, ctx);
547296465Sdelphij    return ok;
54859191Skris#endif
54959191Skris}
55059191Skris
551109998Smarkmstatic int check_revocation(X509_STORE_CTX *ctx)
552296465Sdelphij{
553296465Sdelphij    int i, last, ok;
554296465Sdelphij    if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
555296465Sdelphij        return 1;
556296465Sdelphij    if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
557296465Sdelphij        last = sk_X509_num(ctx->chain) - 1;
558296465Sdelphij    else
559296465Sdelphij        last = 0;
560296465Sdelphij    for (i = 0; i <= last; i++) {
561296465Sdelphij        ctx->error_depth = i;
562296465Sdelphij        ok = check_cert(ctx);
563296465Sdelphij        if (!ok)
564296465Sdelphij            return ok;
565296465Sdelphij    }
566296465Sdelphij    return 1;
567296465Sdelphij}
568109998Smarkm
569109998Smarkmstatic int check_cert(X509_STORE_CTX *ctx)
570296465Sdelphij{
571296465Sdelphij    X509_CRL *crl = NULL;
572296465Sdelphij    X509 *x;
573296465Sdelphij    int ok, cnum;
574296465Sdelphij    cnum = ctx->error_depth;
575296465Sdelphij    x = sk_X509_value(ctx->chain, cnum);
576296465Sdelphij    ctx->current_cert = x;
577296465Sdelphij    /* Try to retrieve relevant CRL */
578296465Sdelphij    ok = ctx->get_crl(ctx, &crl, x);
579296465Sdelphij    /*
580296465Sdelphij     * If error looking up CRL, nothing we can do except notify callback
581296465Sdelphij     */
582296465Sdelphij    if (!ok) {
583296465Sdelphij        ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
584296465Sdelphij        ok = ctx->verify_cb(0, ctx);
585296465Sdelphij        goto err;
586296465Sdelphij    }
587296465Sdelphij    ctx->current_crl = crl;
588296465Sdelphij    ok = ctx->check_crl(ctx, crl);
589296465Sdelphij    if (!ok)
590296465Sdelphij        goto err;
591296465Sdelphij    ok = ctx->cert_crl(ctx, crl, x);
592296465Sdelphij err:
593296465Sdelphij    ctx->current_crl = NULL;
594296465Sdelphij    X509_CRL_free(crl);
595296465Sdelphij    return ok;
596109998Smarkm
597296465Sdelphij}
598109998Smarkm
599160814Ssimon/* Check CRL times against values in X509_STORE_CTX */
600160814Ssimon
601160814Ssimonstatic int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
602296465Sdelphij{
603296465Sdelphij    time_t *ptime;
604296465Sdelphij    int i;
605296465Sdelphij    ctx->current_crl = crl;
606296465Sdelphij    if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
607296465Sdelphij        ptime = &ctx->param->check_time;
608296465Sdelphij    else
609296465Sdelphij        ptime = NULL;
610160814Ssimon
611296465Sdelphij    i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
612296465Sdelphij    if (i == 0) {
613296465Sdelphij        ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
614296465Sdelphij        if (!notify || !ctx->verify_cb(0, ctx))
615296465Sdelphij            return 0;
616296465Sdelphij    }
617160814Ssimon
618296465Sdelphij    if (i > 0) {
619296465Sdelphij        ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
620296465Sdelphij        if (!notify || !ctx->verify_cb(0, ctx))
621296465Sdelphij            return 0;
622296465Sdelphij    }
623160814Ssimon
624296465Sdelphij    if (X509_CRL_get_nextUpdate(crl)) {
625296465Sdelphij        i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
626160814Ssimon
627296465Sdelphij        if (i == 0) {
628296465Sdelphij            ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
629296465Sdelphij            if (!notify || !ctx->verify_cb(0, ctx))
630296465Sdelphij                return 0;
631296465Sdelphij        }
632160814Ssimon
633296465Sdelphij        if (i < 0) {
634296465Sdelphij            ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
635296465Sdelphij            if (!notify || !ctx->verify_cb(0, ctx))
636296465Sdelphij                return 0;
637296465Sdelphij        }
638296465Sdelphij    }
639160814Ssimon
640296465Sdelphij    ctx->current_crl = NULL;
641160814Ssimon
642296465Sdelphij    return 1;
643296465Sdelphij}
644160814Ssimon
645296465Sdelphij/*
646296465Sdelphij * Lookup CRLs from the supplied list. Look for matching isser name and
647296465Sdelphij * validity. If we can't find a valid CRL return the last one with matching
648296465Sdelphij * name. This gives more meaningful error codes. Otherwise we'd get a CRL not
649296465Sdelphij * found error if a CRL existed with matching name but was invalid.
650160814Ssimon */
651160814Ssimon
652160814Ssimonstatic int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl,
653296465Sdelphij                      X509_NAME *nm, STACK_OF(X509_CRL) *crls)
654296465Sdelphij{
655296465Sdelphij    int i;
656296465Sdelphij    X509_CRL *crl, *best_crl = NULL;
657296465Sdelphij    for (i = 0; i < sk_X509_CRL_num(crls); i++) {
658296465Sdelphij        crl = sk_X509_CRL_value(crls, i);
659296465Sdelphij        if (X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
660296465Sdelphij            continue;
661296465Sdelphij        if (check_crl_time(ctx, crl, 0)) {
662296465Sdelphij            *pcrl = crl;
663296465Sdelphij            CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509);
664296465Sdelphij            return 1;
665296465Sdelphij        }
666296465Sdelphij        best_crl = crl;
667296465Sdelphij    }
668296465Sdelphij    if (best_crl) {
669296465Sdelphij        *pcrl = best_crl;
670296465Sdelphij        CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509);
671296465Sdelphij    }
672160814Ssimon
673296465Sdelphij    return 0;
674296465Sdelphij}
675296465Sdelphij
676296465Sdelphij/*
677296465Sdelphij * Retrieve CRL corresponding to certificate: currently just a subject
678296465Sdelphij * lookup: maybe use AKID later...
679109998Smarkm */
680160814Ssimonstatic int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x)
681296465Sdelphij{
682296465Sdelphij    int ok;
683296465Sdelphij    X509_CRL *crl = NULL;
684296465Sdelphij    X509_OBJECT xobj;
685296465Sdelphij    X509_NAME *nm;
686296465Sdelphij    nm = X509_get_issuer_name(x);
687296465Sdelphij    ok = get_crl_sk(ctx, &crl, nm, ctx->crls);
688296465Sdelphij    if (ok) {
689296465Sdelphij        *pcrl = crl;
690296465Sdelphij        return 1;
691296465Sdelphij    }
692160814Ssimon
693296465Sdelphij    ok = X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj);
694160814Ssimon
695296465Sdelphij    if (!ok) {
696296465Sdelphij        /* If we got a near match from get_crl_sk use that */
697296465Sdelphij        if (crl) {
698296465Sdelphij            *pcrl = crl;
699296465Sdelphij            return 1;
700296465Sdelphij        }
701296465Sdelphij        return 0;
702296465Sdelphij    }
703160814Ssimon
704296465Sdelphij    *pcrl = xobj.data.crl;
705296465Sdelphij    if (crl)
706296465Sdelphij        X509_CRL_free(crl);
707296465Sdelphij    return 1;
708296465Sdelphij}
709109998Smarkm
710109998Smarkm/* Check CRL validity */
711109998Smarkmstatic int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
712296465Sdelphij{
713296465Sdelphij    X509 *issuer = NULL;
714296465Sdelphij    EVP_PKEY *ikey = NULL;
715296465Sdelphij    int ok = 0, chnum, cnum;
716296465Sdelphij    cnum = ctx->error_depth;
717296465Sdelphij    chnum = sk_X509_num(ctx->chain) - 1;
718296465Sdelphij    /*
719296465Sdelphij     * Find CRL issuer: if not last certificate then issuer is next
720296465Sdelphij     * certificate in chain.
721296465Sdelphij     */
722296465Sdelphij    if (cnum < chnum)
723296465Sdelphij        issuer = sk_X509_value(ctx->chain, cnum + 1);
724296465Sdelphij    else {
725296465Sdelphij        issuer = sk_X509_value(ctx->chain, chnum);
726296465Sdelphij        /* If not self signed, can't check signature */
727296465Sdelphij        if (!ctx->check_issued(ctx, issuer, issuer)) {
728296465Sdelphij            ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
729296465Sdelphij            ok = ctx->verify_cb(0, ctx);
730296465Sdelphij            if (!ok)
731296465Sdelphij                goto err;
732296465Sdelphij        }
733296465Sdelphij    }
734109998Smarkm
735296465Sdelphij    if (issuer) {
736296465Sdelphij        /* Check for cRLSign bit if keyUsage present */
737296465Sdelphij        if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
738296465Sdelphij            !(issuer->ex_kusage & KU_CRL_SIGN)) {
739296465Sdelphij            ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
740296465Sdelphij            ok = ctx->verify_cb(0, ctx);
741296465Sdelphij            if (!ok)
742296465Sdelphij                goto err;
743296465Sdelphij        }
744109998Smarkm
745296465Sdelphij        /* Attempt to get issuer certificate public key */
746296465Sdelphij        ikey = X509_get_pubkey(issuer);
747109998Smarkm
748296465Sdelphij        if (!ikey) {
749296465Sdelphij            ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
750296465Sdelphij            ok = ctx->verify_cb(0, ctx);
751296465Sdelphij            if (!ok)
752296465Sdelphij                goto err;
753296465Sdelphij        } else {
754296465Sdelphij            /* Verify CRL signature */
755296465Sdelphij            if (X509_CRL_verify(crl, ikey) <= 0) {
756296465Sdelphij                ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
757296465Sdelphij                ok = ctx->verify_cb(0, ctx);
758296465Sdelphij                if (!ok)
759296465Sdelphij                    goto err;
760296465Sdelphij            }
761296465Sdelphij        }
762296465Sdelphij    }
763109998Smarkm
764296465Sdelphij    ok = check_crl_time(ctx, crl, 1);
765296465Sdelphij    if (!ok)
766296465Sdelphij        goto err;
767109998Smarkm
768296465Sdelphij    ok = 1;
769109998Smarkm
770296465Sdelphij err:
771296465Sdelphij    EVP_PKEY_free(ikey);
772296465Sdelphij    return ok;
773296465Sdelphij}
774109998Smarkm
775109998Smarkm/* Check certificate against CRL */
776109998Smarkmstatic int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
777296465Sdelphij{
778296465Sdelphij    int idx, ok;
779296465Sdelphij    X509_REVOKED rtmp;
780296465Sdelphij    STACK_OF(X509_EXTENSION) *exts;
781296465Sdelphij    X509_EXTENSION *ext;
782296465Sdelphij    /* Look for serial number of certificate in CRL */
783296465Sdelphij    rtmp.serialNumber = X509_get_serialNumber(x);
784296465Sdelphij    /*
785296465Sdelphij     * Sort revoked into serial number order if not already sorted. Do this
786296465Sdelphij     * under a lock to avoid race condition.
787296465Sdelphij     */
788296465Sdelphij    if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) {
789296465Sdelphij        CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
790296465Sdelphij        sk_X509_REVOKED_sort(crl->crl->revoked);
791296465Sdelphij        CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
792296465Sdelphij    }
793296465Sdelphij    idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
794296465Sdelphij    /*
795296465Sdelphij     * If found assume revoked: want something cleverer than this to handle
796296465Sdelphij     * entry extensions in V2 CRLs.
797296465Sdelphij     */
798296465Sdelphij    if (idx >= 0) {
799296465Sdelphij        ctx->error = X509_V_ERR_CERT_REVOKED;
800296465Sdelphij        ok = ctx->verify_cb(0, ctx);
801296465Sdelphij        if (!ok)
802296465Sdelphij            return 0;
803296465Sdelphij    }
804127128Snectar
805296465Sdelphij    if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
806296465Sdelphij        return 1;
807127128Snectar
808296465Sdelphij    /*
809296465Sdelphij     * See if we have any critical CRL extensions: since we currently don't
810296465Sdelphij     * handle any CRL extensions the CRL must be rejected. This code
811296465Sdelphij     * accesses the X509_CRL structure directly: applications shouldn't do
812296465Sdelphij     * this.
813296465Sdelphij     */
814127128Snectar
815296465Sdelphij    exts = crl->crl->extensions;
816127128Snectar
817296465Sdelphij    for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
818296465Sdelphij        ext = sk_X509_EXTENSION_value(exts, idx);
819296465Sdelphij        if (ext->critical > 0) {
820296465Sdelphij            ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
821296465Sdelphij            ok = ctx->verify_cb(0, ctx);
822296465Sdelphij            if (!ok)
823296465Sdelphij                return 0;
824296465Sdelphij            break;
825296465Sdelphij        }
826296465Sdelphij    }
827296465Sdelphij    return 1;
828296465Sdelphij}
829109998Smarkm
830160814Ssimonstatic int check_policy(X509_STORE_CTX *ctx)
831296465Sdelphij{
832296465Sdelphij    int ret;
833296465Sdelphij    ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
834296465Sdelphij                            ctx->param->policies, ctx->param->flags);
835296465Sdelphij    if (ret == 0) {
836296465Sdelphij        X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE);
837296465Sdelphij        return 0;
838296465Sdelphij    }
839296465Sdelphij    /* Invalid or inconsistent extensions */
840296465Sdelphij    if (ret == -1) {
841296465Sdelphij        /*
842296465Sdelphij         * Locate certificates with bad extensions and notify callback.
843296465Sdelphij         */
844296465Sdelphij        X509 *x;
845296465Sdelphij        int i;
846296465Sdelphij        for (i = 1; i < sk_X509_num(ctx->chain); i++) {
847296465Sdelphij            x = sk_X509_value(ctx->chain, i);
848296465Sdelphij            if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
849296465Sdelphij                continue;
850296465Sdelphij            ctx->current_cert = x;
851296465Sdelphij            ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
852296465Sdelphij            ret = ctx->verify_cb(0, ctx);
853296465Sdelphij        }
854296465Sdelphij        return 1;
855296465Sdelphij    }
856296465Sdelphij    if (ret == -2) {
857296465Sdelphij        ctx->current_cert = NULL;
858296465Sdelphij        ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
859296465Sdelphij        return ctx->verify_cb(0, ctx);
860296465Sdelphij    }
861160814Ssimon
862296465Sdelphij    if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
863296465Sdelphij        ctx->current_cert = NULL;
864296465Sdelphij        ctx->error = X509_V_OK;
865296465Sdelphij        if (!ctx->verify_cb(2, ctx))
866296465Sdelphij            return 0;
867296465Sdelphij    }
868160814Ssimon
869296465Sdelphij    return 1;
870296465Sdelphij}
871160814Ssimon
872160814Ssimonstatic int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
873296465Sdelphij{
874296465Sdelphij    time_t *ptime;
875296465Sdelphij    int i;
876160814Ssimon
877296465Sdelphij    if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
878296465Sdelphij        ptime = &ctx->param->check_time;
879296465Sdelphij    else
880296465Sdelphij        ptime = NULL;
881160814Ssimon
882296465Sdelphij    i = X509_cmp_time(X509_get_notBefore(x), ptime);
883296465Sdelphij    if (i == 0) {
884296465Sdelphij        ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
885296465Sdelphij        ctx->current_cert = x;
886296465Sdelphij        if (!ctx->verify_cb(0, ctx))
887296465Sdelphij            return 0;
888296465Sdelphij    }
889160814Ssimon
890296465Sdelphij    if (i > 0) {
891296465Sdelphij        ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
892296465Sdelphij        ctx->current_cert = x;
893296465Sdelphij        if (!ctx->verify_cb(0, ctx))
894296465Sdelphij            return 0;
895296465Sdelphij    }
896160814Ssimon
897296465Sdelphij    i = X509_cmp_time(X509_get_notAfter(x), ptime);
898296465Sdelphij    if (i == 0) {
899296465Sdelphij        ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
900296465Sdelphij        ctx->current_cert = x;
901296465Sdelphij        if (!ctx->verify_cb(0, ctx))
902296465Sdelphij            return 0;
903296465Sdelphij    }
904160814Ssimon
905296465Sdelphij    if (i < 0) {
906296465Sdelphij        ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
907296465Sdelphij        ctx->current_cert = x;
908296465Sdelphij        if (!ctx->verify_cb(0, ctx))
909296465Sdelphij            return 0;
910296465Sdelphij    }
911160814Ssimon
912296465Sdelphij    return 1;
913296465Sdelphij}
914160814Ssimon
91555714Skrisstatic int internal_verify(X509_STORE_CTX *ctx)
916296465Sdelphij{
917296465Sdelphij    int ok = 0, n;
918296465Sdelphij    X509 *xs, *xi;
919296465Sdelphij    EVP_PKEY *pkey = NULL;
920296465Sdelphij    int (*cb) (int xok, X509_STORE_CTX *xctx);
92155714Skris
922296465Sdelphij    cb = ctx->verify_cb;
92355714Skris
924296465Sdelphij    n = sk_X509_num(ctx->chain);
925296465Sdelphij    ctx->error_depth = n - 1;
926296465Sdelphij    n--;
927296465Sdelphij    xi = sk_X509_value(ctx->chain, n);
928160814Ssimon
929296465Sdelphij    if (ctx->check_issued(ctx, xi, xi))
930296465Sdelphij        xs = xi;
931296465Sdelphij    else {
932296465Sdelphij        if (n <= 0) {
933296465Sdelphij            ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
934296465Sdelphij            ctx->current_cert = xi;
935296465Sdelphij            ok = cb(0, ctx);
936296465Sdelphij            goto end;
937296465Sdelphij        } else {
938296465Sdelphij            n--;
939296465Sdelphij            ctx->error_depth = n;
940296465Sdelphij            xs = sk_X509_value(ctx->chain, n);
941296465Sdelphij        }
942296465Sdelphij    }
94355714Skris
944296465Sdelphij/*      ctx->error=0;  not needed */
945296465Sdelphij    while (n >= 0) {
946296465Sdelphij        ctx->error_depth = n;
947205128Ssimon
948296465Sdelphij        /*
949296465Sdelphij         * Skip signature check for self signed certificates unless
950296465Sdelphij         * explicitly asked for. It doesn't add any security and just wastes
951296465Sdelphij         * time.
952296465Sdelphij         */
953296465Sdelphij        if (!xs->valid
954296465Sdelphij            && (xs != xi
955296465Sdelphij                || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) {
956296465Sdelphij            if ((pkey = X509_get_pubkey(xi)) == NULL) {
957296465Sdelphij                ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
958296465Sdelphij                ctx->current_cert = xi;
959296465Sdelphij                ok = (*cb) (0, ctx);
960296465Sdelphij                if (!ok)
961296465Sdelphij                    goto end;
962296465Sdelphij            } else if (X509_verify(xs, pkey) <= 0) {
963296465Sdelphij                ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
964296465Sdelphij                ctx->current_cert = xs;
965296465Sdelphij                ok = (*cb) (0, ctx);
966296465Sdelphij                if (!ok) {
967296465Sdelphij                    EVP_PKEY_free(pkey);
968296465Sdelphij                    goto end;
969296465Sdelphij                }
970296465Sdelphij            }
971296465Sdelphij            EVP_PKEY_free(pkey);
972296465Sdelphij            pkey = NULL;
973296465Sdelphij        }
97455714Skris
975296465Sdelphij        xs->valid = 1;
97655714Skris
977296465Sdelphij        ok = check_cert_time(ctx, xs);
978296465Sdelphij        if (!ok)
979296465Sdelphij            goto end;
98055714Skris
981296465Sdelphij        /* The last error (if any) is still in the error value */
982296465Sdelphij        ctx->current_issuer = xi;
983296465Sdelphij        ctx->current_cert = xs;
984296465Sdelphij        ok = (*cb) (1, ctx);
985296465Sdelphij        if (!ok)
986296465Sdelphij            goto end;
98755714Skris
988296465Sdelphij        n--;
989296465Sdelphij        if (n >= 0) {
990296465Sdelphij            xi = xs;
991296465Sdelphij            xs = sk_X509_value(ctx->chain, n);
992296465Sdelphij        }
993296465Sdelphij    }
994296465Sdelphij    ok = 1;
995296465Sdelphij end:
996296465Sdelphij    return ok;
997296465Sdelphij}
99855714Skris
99968651Skrisint X509_cmp_current_time(ASN1_TIME *ctm)
100068651Skris{
1001296465Sdelphij    return X509_cmp_time(ctm, NULL);
100268651Skris}
100368651Skris
100468651Skrisint X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time)
1005284295Sdelphij{
1006296465Sdelphij    char *str;
1007296465Sdelphij    ASN1_TIME atm;
1008296465Sdelphij    long offset;
1009284295Sdelphij    char buff1[24], buff2[24], *p;
1010284295Sdelphij    int i, j, remaining;
101155714Skris
1012284295Sdelphij    p = buff1;
1013284295Sdelphij    remaining = ctm->length;
1014284295Sdelphij    str = (char *)ctm->data;
1015284295Sdelphij    /*
1016284295Sdelphij     * Note that the following (historical) code allows much more slack in the
1017284295Sdelphij     * time format than RFC5280. In RFC5280, the representation is fixed:
1018284295Sdelphij     * UTCTime: YYMMDDHHMMSSZ
1019284295Sdelphij     * GeneralizedTime: YYYYMMDDHHMMSSZ
1020284295Sdelphij     */
1021284295Sdelphij    if (ctm->type == V_ASN1_UTCTIME) {
1022284295Sdelphij        /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
1023284295Sdelphij        int min_length = sizeof("YYMMDDHHMMZ") - 1;
1024284295Sdelphij        int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
1025284295Sdelphij        if (remaining < min_length || remaining > max_length)
1026284295Sdelphij            return 0;
1027284295Sdelphij        memcpy(p, str, 10);
1028284295Sdelphij        p += 10;
1029284295Sdelphij        str += 10;
1030284295Sdelphij        remaining -= 10;
1031284295Sdelphij    } else {
1032284295Sdelphij        /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
1033284295Sdelphij        int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
1034284295Sdelphij        int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
1035284295Sdelphij        if (remaining < min_length || remaining > max_length)
1036284295Sdelphij            return 0;
1037284295Sdelphij        memcpy(p, str, 12);
1038284295Sdelphij        p += 12;
1039284295Sdelphij        str += 12;
1040284295Sdelphij        remaining -= 12;
1041296465Sdelphij    }
104255714Skris
1043284295Sdelphij    if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
1044284295Sdelphij        *(p++) = '0';
1045284295Sdelphij        *(p++) = '0';
1046284295Sdelphij    } else {
1047284295Sdelphij        /* SS (seconds) */
1048284295Sdelphij        if (remaining < 2)
1049284295Sdelphij            return 0;
1050284295Sdelphij        *(p++) = *(str++);
1051284295Sdelphij        *(p++) = *(str++);
1052284295Sdelphij        remaining -= 2;
1053284295Sdelphij        /*
1054284295Sdelphij         * Skip any (up to three) fractional seconds...
1055284295Sdelphij         * TODO(emilia): in RFC5280, fractional seconds are forbidden.
1056284295Sdelphij         * Can we just kill them altogether?
1057284295Sdelphij         */
1058284295Sdelphij        if (remaining && *str == '.') {
1059296465Sdelphij            str++;
1060284295Sdelphij            remaining--;
1061284295Sdelphij            for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
1062284295Sdelphij                if (*str < '0' || *str > '9')
1063284295Sdelphij                    break;
1064296465Sdelphij            }
1065296465Sdelphij        }
106655714Skris
1067284295Sdelphij    }
1068284295Sdelphij    *(p++) = 'Z';
1069284295Sdelphij    *(p++) = '\0';
1070284295Sdelphij
1071284295Sdelphij    /* We now need either a terminating 'Z' or an offset. */
1072284295Sdelphij    if (!remaining)
1073284295Sdelphij        return 0;
1074284295Sdelphij    if (*str == 'Z') {
1075284295Sdelphij        if (remaining != 1)
1076284295Sdelphij            return 0;
1077284295Sdelphij        offset = 0;
1078284295Sdelphij    } else {
1079284295Sdelphij        /* (+-)HHMM */
1080296465Sdelphij        if ((*str != '+') && (*str != '-'))
1081296465Sdelphij            return 0;
1082284295Sdelphij        /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
1083284295Sdelphij        if (remaining != 5)
1084284295Sdelphij            return 0;
1085284295Sdelphij        if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
1086284295Sdelphij            str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
1087284295Sdelphij            return 0;
1088284295Sdelphij        offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
1089284295Sdelphij        offset += (str[3] - '0') * 10 + (str[4] - '0');
1090296465Sdelphij        if (*str == '-')
1091284295Sdelphij            offset = -offset;
1092296465Sdelphij    }
1093284295Sdelphij    atm.type = ctm->type;
1094284295Sdelphij    atm.length = sizeof(buff2);
1095284295Sdelphij    atm.data = (unsigned char *)buff2;
109655714Skris
1097284295Sdelphij    if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
1098296465Sdelphij        return 0;
109955714Skris
1100284295Sdelphij    if (ctm->type == V_ASN1_UTCTIME) {
1101284295Sdelphij        i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
1102284295Sdelphij        if (i < 50)
1103284295Sdelphij            i += 100;           /* cf. RFC 2459 */
1104284295Sdelphij        j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
1105284295Sdelphij        if (j < 50)
1106284295Sdelphij            j += 100;
110755714Skris
1108284295Sdelphij        if (i < j)
1109284295Sdelphij            return -1;
1110284295Sdelphij        if (i > j)
1111284295Sdelphij            return 1;
1112296465Sdelphij    }
1113284295Sdelphij    i = strcmp(buff1, buff2);
1114296465Sdelphij    if (i == 0)                 /* wait a second then return younger :-) */
1115296465Sdelphij        return -1;
1116296465Sdelphij    else
1117296465Sdelphij        return i;
1118284295Sdelphij}
111955714Skris
112068651SkrisASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
112168651Skris{
1122296465Sdelphij    return X509_time_adj(s, adj, NULL);
112368651Skris}
112468651Skris
112568651SkrisASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *in_tm)
1126296465Sdelphij{
1127296465Sdelphij    time_t t;
1128296465Sdelphij    int type = -1;
112955714Skris
1130296465Sdelphij    if (in_tm)
1131296465Sdelphij        t = *in_tm;
1132296465Sdelphij    else
1133296465Sdelphij        time(&t);
113468651Skris
1135296465Sdelphij    t += adj;
1136296465Sdelphij    if (s)
1137296465Sdelphij        type = s->type;
1138296465Sdelphij    if (type == V_ASN1_UTCTIME)
1139296465Sdelphij        return ASN1_UTCTIME_set(s, t);
1140296465Sdelphij    if (type == V_ASN1_GENERALIZEDTIME)
1141296465Sdelphij        return ASN1_GENERALIZEDTIME_set(s, t);
1142296465Sdelphij    return ASN1_TIME_set(s, t);
1143296465Sdelphij}
114455714Skris
114555714Skrisint X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
1146296465Sdelphij{
1147296465Sdelphij    EVP_PKEY *ktmp = NULL, *ktmp2;
1148296465Sdelphij    int i, j;
114955714Skris
1150296465Sdelphij    if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey))
1151296465Sdelphij        return 1;
115255714Skris
1153296465Sdelphij    for (i = 0; i < sk_X509_num(chain); i++) {
1154296465Sdelphij        ktmp = X509_get_pubkey(sk_X509_value(chain, i));
1155296465Sdelphij        if (ktmp == NULL) {
1156296465Sdelphij            X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
1157296465Sdelphij                    X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
1158296465Sdelphij            return 0;
1159296465Sdelphij        }
1160296465Sdelphij        if (!EVP_PKEY_missing_parameters(ktmp))
1161296465Sdelphij            break;
1162296465Sdelphij        else {
1163296465Sdelphij            EVP_PKEY_free(ktmp);
1164296465Sdelphij            ktmp = NULL;
1165296465Sdelphij        }
1166296465Sdelphij    }
1167296465Sdelphij    if (ktmp == NULL) {
1168296465Sdelphij        X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
1169296465Sdelphij                X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
1170296465Sdelphij        return 0;
1171296465Sdelphij    }
117255714Skris
1173296465Sdelphij    /* first, populate the other certs */
1174296465Sdelphij    for (j = i - 1; j >= 0; j--) {
1175296465Sdelphij        ktmp2 = X509_get_pubkey(sk_X509_value(chain, j));
1176296465Sdelphij        EVP_PKEY_copy_parameters(ktmp2, ktmp);
1177296465Sdelphij        EVP_PKEY_free(ktmp2);
1178296465Sdelphij    }
117955714Skris
1180296465Sdelphij    if (pkey != NULL)
1181296465Sdelphij        EVP_PKEY_copy_parameters(pkey, ktmp);
1182296465Sdelphij    EVP_PKEY_free(ktmp);
1183296465Sdelphij    return 1;
1184296465Sdelphij}
118555714Skris
1186296465Sdelphijint X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
1187296465Sdelphij                                    CRYPTO_EX_new *new_func,
1188296465Sdelphij                                    CRYPTO_EX_dup *dup_func,
1189296465Sdelphij                                    CRYPTO_EX_free *free_func)
1190296465Sdelphij{
1191296465Sdelphij    /*
1192296465Sdelphij     * This function is (usually) called only once, by
1193296465Sdelphij     * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c).
1194296465Sdelphij     */
1195296465Sdelphij    return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp,
1196296465Sdelphij                                   new_func, dup_func, free_func);
1197296465Sdelphij}
1198296465Sdelphij
119955714Skrisint X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
1200296465Sdelphij{
1201296465Sdelphij    return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
1202296465Sdelphij}
120355714Skris
120455714Skrisvoid *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
1205296465Sdelphij{
1206296465Sdelphij    return CRYPTO_get_ex_data(&ctx->ex_data, idx);
1207296465Sdelphij}
120855714Skris
120955714Skrisint X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
1210296465Sdelphij{
1211296465Sdelphij    return ctx->error;
1212296465Sdelphij}
121355714Skris
121455714Skrisvoid X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
1215296465Sdelphij{
1216296465Sdelphij    ctx->error = err;
1217296465Sdelphij}
121855714Skris
121955714Skrisint X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
1220296465Sdelphij{
1221296465Sdelphij    return ctx->error_depth;
1222296465Sdelphij}
122355714Skris
122455714SkrisX509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
1225296465Sdelphij{
1226296465Sdelphij    return ctx->current_cert;
1227296465Sdelphij}
122855714Skris
122955714SkrisSTACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
1230296465Sdelphij{
1231296465Sdelphij    return ctx->chain;
1232296465Sdelphij}
123355714Skris
123459191SkrisSTACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
1235296465Sdelphij{
1236296465Sdelphij    int i;
1237296465Sdelphij    X509 *x;
1238296465Sdelphij    STACK_OF(X509) *chain;
1239296465Sdelphij    if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain)))
1240296465Sdelphij        return NULL;
1241296465Sdelphij    for (i = 0; i < sk_X509_num(chain); i++) {
1242296465Sdelphij        x = sk_X509_value(chain, i);
1243296465Sdelphij        CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
1244296465Sdelphij    }
1245296465Sdelphij    return chain;
1246296465Sdelphij}
124759191Skris
124855714Skrisvoid X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
1249296465Sdelphij{
1250296465Sdelphij    ctx->cert = x;
1251296465Sdelphij}
125255714Skris
125355714Skrisvoid X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
1254296465Sdelphij{
1255296465Sdelphij    ctx->untrusted = sk;
1256296465Sdelphij}
125755714Skris
1258160814Ssimonvoid X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
1259296465Sdelphij{
1260296465Sdelphij    ctx->crls = sk;
1261296465Sdelphij}
1262160814Ssimon
126359191Skrisint X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
1264296465Sdelphij{
1265296465Sdelphij    return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
1266296465Sdelphij}
126759191Skris
126859191Skrisint X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
1269296465Sdelphij{
1270296465Sdelphij    return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
1271296465Sdelphij}
127259191Skris
1273296465Sdelphij/*
1274296465Sdelphij * This function is used to set the X509_STORE_CTX purpose and trust values.
1275296465Sdelphij * This is intended to be used when another structure has its own trust and
1276296465Sdelphij * purpose values which (if set) will be inherited by the ctx. If they aren't
1277296465Sdelphij * set then we will usually have a default purpose in mind which should then
1278296465Sdelphij * be used to set the trust value. An example of this is SSL use: an SSL
1279296465Sdelphij * structure will have its own purpose and trust settings which the
1280296465Sdelphij * application can set: if they aren't set then we use the default of SSL
1281296465Sdelphij * client/server.
128259191Skris */
128359191Skris
128459191Skrisint X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
1285296465Sdelphij                                   int purpose, int trust)
128659191Skris{
1287296465Sdelphij    int idx;
1288296465Sdelphij    /* If purpose not set use default */
1289296465Sdelphij    if (!purpose)
1290296465Sdelphij        purpose = def_purpose;
1291296465Sdelphij    /* If we have a purpose then check it is valid */
1292296465Sdelphij    if (purpose) {
1293296465Sdelphij        X509_PURPOSE *ptmp;
1294296465Sdelphij        idx = X509_PURPOSE_get_by_id(purpose);
1295296465Sdelphij        if (idx == -1) {
1296296465Sdelphij            X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1297296465Sdelphij                    X509_R_UNKNOWN_PURPOSE_ID);
1298296465Sdelphij            return 0;
1299296465Sdelphij        }
1300296465Sdelphij        ptmp = X509_PURPOSE_get0(idx);
1301296465Sdelphij        if (ptmp->trust == X509_TRUST_DEFAULT) {
1302296465Sdelphij            idx = X509_PURPOSE_get_by_id(def_purpose);
1303296465Sdelphij            if (idx == -1) {
1304296465Sdelphij                X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1305296465Sdelphij                        X509_R_UNKNOWN_PURPOSE_ID);
1306296465Sdelphij                return 0;
1307296465Sdelphij            }
1308296465Sdelphij            ptmp = X509_PURPOSE_get0(idx);
1309296465Sdelphij        }
1310296465Sdelphij        /* If trust not set then get from purpose default */
1311296465Sdelphij        if (!trust)
1312296465Sdelphij            trust = ptmp->trust;
1313296465Sdelphij    }
1314296465Sdelphij    if (trust) {
1315296465Sdelphij        idx = X509_TRUST_get_by_id(trust);
1316296465Sdelphij        if (idx == -1) {
1317296465Sdelphij            X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1318296465Sdelphij                    X509_R_UNKNOWN_TRUST_ID);
1319296465Sdelphij            return 0;
1320296465Sdelphij        }
1321296465Sdelphij    }
132259191Skris
1323296465Sdelphij    if (purpose && !ctx->param->purpose)
1324296465Sdelphij        ctx->param->purpose = purpose;
1325296465Sdelphij    if (trust && !ctx->param->trust)
1326296465Sdelphij        ctx->param->trust = trust;
1327296465Sdelphij    return 1;
132859191Skris}
132959191Skris
133068651SkrisX509_STORE_CTX *X509_STORE_CTX_new(void)
133168651Skris{
1332296465Sdelphij    X509_STORE_CTX *ctx;
1333296465Sdelphij    ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
1334296465Sdelphij    if (!ctx) {
1335296465Sdelphij        X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE);
1336296465Sdelphij        return NULL;
1337296465Sdelphij    }
1338296465Sdelphij    memset(ctx, 0, sizeof(X509_STORE_CTX));
1339296465Sdelphij    return ctx;
134068651Skris}
134159191Skris
134268651Skrisvoid X509_STORE_CTX_free(X509_STORE_CTX *ctx)
134368651Skris{
1344296465Sdelphij    if (!ctx)
1345296465Sdelphij        return;
1346296465Sdelphij    X509_STORE_CTX_cleanup(ctx);
1347296465Sdelphij    OPENSSL_free(ctx);
134868651Skris}
134968651Skris
1350109998Smarkmint X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
1351296465Sdelphij                        STACK_OF(X509) *chain)
1352296465Sdelphij{
1353296465Sdelphij    int ret = 1;
1354296465Sdelphij    ctx->ctx = store;
1355296465Sdelphij    ctx->current_method = 0;
1356296465Sdelphij    ctx->cert = x509;
1357296465Sdelphij    ctx->untrusted = chain;
1358296465Sdelphij    ctx->crls = NULL;
1359296465Sdelphij    ctx->last_untrusted = 0;
1360296465Sdelphij    ctx->other_ctx = NULL;
1361296465Sdelphij    ctx->valid = 0;
1362296465Sdelphij    ctx->chain = NULL;
1363296465Sdelphij    ctx->error = 0;
1364296465Sdelphij    ctx->explicit_policy = 0;
1365296465Sdelphij    ctx->error_depth = 0;
1366296465Sdelphij    ctx->current_cert = NULL;
1367296465Sdelphij    ctx->current_issuer = NULL;
1368296465Sdelphij    ctx->tree = NULL;
1369109998Smarkm
1370296465Sdelphij    ctx->param = X509_VERIFY_PARAM_new();
1371160814Ssimon
1372296465Sdelphij    if (!ctx->param) {
1373296465Sdelphij        X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
1374296465Sdelphij        return 0;
1375296465Sdelphij    }
1376160814Ssimon
1377296465Sdelphij    /*
1378296465Sdelphij     * Inherit callbacks and flags from X509_STORE if not set use defaults.
1379296465Sdelphij     */
1380109998Smarkm
1381296465Sdelphij    if (store)
1382296465Sdelphij        ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
1383296465Sdelphij    else
1384296465Sdelphij        ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
1385109998Smarkm
1386296465Sdelphij    if (store) {
1387296465Sdelphij        ctx->verify_cb = store->verify_cb;
1388296465Sdelphij        ctx->cleanup = store->cleanup;
1389296465Sdelphij    } else
1390296465Sdelphij        ctx->cleanup = 0;
1391160814Ssimon
1392296465Sdelphij    if (ret)
1393296465Sdelphij        ret = X509_VERIFY_PARAM_inherit(ctx->param,
1394296465Sdelphij                                        X509_VERIFY_PARAM_lookup("default"));
1395160814Ssimon
1396296465Sdelphij    if (ret == 0) {
1397296465Sdelphij        X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
1398296465Sdelphij        return 0;
1399296465Sdelphij    }
1400160814Ssimon
1401296465Sdelphij    if (store && store->check_issued)
1402296465Sdelphij        ctx->check_issued = store->check_issued;
1403296465Sdelphij    else
1404296465Sdelphij        ctx->check_issued = check_issued;
1405109998Smarkm
1406296465Sdelphij    if (store && store->get_issuer)
1407296465Sdelphij        ctx->get_issuer = store->get_issuer;
1408296465Sdelphij    else
1409296465Sdelphij        ctx->get_issuer = X509_STORE_CTX_get1_issuer;
1410109998Smarkm
1411296465Sdelphij    if (store && store->verify_cb)
1412296465Sdelphij        ctx->verify_cb = store->verify_cb;
1413296465Sdelphij    else
1414296465Sdelphij        ctx->verify_cb = null_callback;
1415109998Smarkm
1416296465Sdelphij    if (store && store->verify)
1417296465Sdelphij        ctx->verify = store->verify;
1418296465Sdelphij    else
1419296465Sdelphij        ctx->verify = internal_verify;
1420109998Smarkm
1421296465Sdelphij    if (store && store->check_revocation)
1422296465Sdelphij        ctx->check_revocation = store->check_revocation;
1423296465Sdelphij    else
1424296465Sdelphij        ctx->check_revocation = check_revocation;
1425109998Smarkm
1426296465Sdelphij    if (store && store->get_crl)
1427296465Sdelphij        ctx->get_crl = store->get_crl;
1428296465Sdelphij    else
1429296465Sdelphij        ctx->get_crl = get_crl;
1430109998Smarkm
1431296465Sdelphij    if (store && store->check_crl)
1432296465Sdelphij        ctx->check_crl = store->check_crl;
1433296465Sdelphij    else
1434296465Sdelphij        ctx->check_crl = check_crl;
1435109998Smarkm
1436296465Sdelphij    if (store && store->cert_crl)
1437296465Sdelphij        ctx->cert_crl = store->cert_crl;
1438296465Sdelphij    else
1439296465Sdelphij        ctx->cert_crl = cert_crl;
1440109998Smarkm
1441296465Sdelphij    ctx->check_policy = check_policy;
1442109998Smarkm
1443296465Sdelphij    /*
1444296465Sdelphij     * This memset() can't make any sense anyway, so it's removed. As
1445296465Sdelphij     * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a
1446296465Sdelphij     * corresponding "new" here and remove this bogus initialisation.
1447296465Sdelphij     */
1448296465Sdelphij    /* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */
1449296465Sdelphij    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
1450296465Sdelphij                            &(ctx->ex_data))) {
1451296465Sdelphij        OPENSSL_free(ctx);
1452296465Sdelphij        X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
1453296465Sdelphij        return 0;
1454296465Sdelphij    }
1455296465Sdelphij    return 1;
1456296465Sdelphij}
1457109998Smarkm
1458296465Sdelphij/*
1459296465Sdelphij * Set alternative lookup method: just a STACK of trusted certificates. This
1460296465Sdelphij * avoids X509_STORE nastiness where it isn't needed.
146168651Skris */
146268651Skris
146368651Skrisvoid X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
146468651Skris{
1465296465Sdelphij    ctx->other_ctx = sk;
1466296465Sdelphij    ctx->get_issuer = get_issuer_sk;
146768651Skris}
146868651Skris
146968651Skrisvoid X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
1470296465Sdelphij{
1471296465Sdelphij    if (ctx->cleanup)
1472296465Sdelphij        ctx->cleanup(ctx);
1473296465Sdelphij    if (ctx->param != NULL) {
1474296465Sdelphij        X509_VERIFY_PARAM_free(ctx->param);
1475296465Sdelphij        ctx->param = NULL;
1476296465Sdelphij    }
1477296465Sdelphij    if (ctx->tree != NULL) {
1478296465Sdelphij        X509_policy_tree_free(ctx->tree);
1479296465Sdelphij        ctx->tree = NULL;
1480296465Sdelphij    }
1481296465Sdelphij    if (ctx->chain != NULL) {
1482296465Sdelphij        sk_X509_pop_free(ctx->chain, X509_free);
1483296465Sdelphij        ctx->chain = NULL;
1484296465Sdelphij    }
1485296465Sdelphij    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data));
1486296465Sdelphij    memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
1487296465Sdelphij}
148868651Skris
1489160814Ssimonvoid X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
1490296465Sdelphij{
1491296465Sdelphij    X509_VERIFY_PARAM_set_depth(ctx->param, depth);
1492296465Sdelphij}
149368651Skris
1494160814Ssimonvoid X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
1495296465Sdelphij{
1496296465Sdelphij    X509_VERIFY_PARAM_set_flags(ctx->param, flags);
1497296465Sdelphij}
149868651Skris
1499296465Sdelphijvoid X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
1500296465Sdelphij                             time_t t)
1501296465Sdelphij{
1502296465Sdelphij    X509_VERIFY_PARAM_set_time(ctx->param, t);
1503296465Sdelphij}
1504160814Ssimon
150589837Skrisvoid X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
1506296465Sdelphij                                  int (*verify_cb) (int, X509_STORE_CTX *))
1507296465Sdelphij{
1508296465Sdelphij    ctx->verify_cb = verify_cb;
1509296465Sdelphij}
151089837Skris
1511160814SsimonX509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
1512296465Sdelphij{
1513296465Sdelphij    return ctx->tree;
1514296465Sdelphij}
1515160814Ssimon
1516160814Ssimonint X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
1517296465Sdelphij{
1518296465Sdelphij    return ctx->explicit_policy;
1519296465Sdelphij}
1520160814Ssimon
1521160814Ssimonint X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
1522296465Sdelphij{
1523296465Sdelphij    const X509_VERIFY_PARAM *param;
1524296465Sdelphij    param = X509_VERIFY_PARAM_lookup(name);
1525296465Sdelphij    if (!param)
1526296465Sdelphij        return 0;
1527296465Sdelphij    return X509_VERIFY_PARAM_inherit(ctx->param, param);
1528296465Sdelphij}
1529160814Ssimon
1530160814SsimonX509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
1531296465Sdelphij{
1532296465Sdelphij    return ctx->param;
1533296465Sdelphij}
1534160814Ssimon
1535160814Ssimonvoid X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
1536296465Sdelphij{
1537296465Sdelphij    if (ctx->param)
1538296465Sdelphij        X509_VERIFY_PARAM_free(ctx->param);
1539296465Sdelphij    ctx->param = param;
1540296465Sdelphij}
1541160814Ssimon
154255714SkrisIMPLEMENT_STACK_OF(X509)
1543296465Sdelphij
154455714SkrisIMPLEMENT_ASN1_SET_OF(X509)
154555714Skris
154655714SkrisIMPLEMENT_STACK_OF(X509_NAME)
154755714Skris
154855714SkrisIMPLEMENT_STACK_OF(X509_ATTRIBUTE)
1549296465Sdelphij
155055714SkrisIMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
1551