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.
8296341Sdelphij *
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).
15296341Sdelphij *
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.
22296341Sdelphij *
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 :-).
37296341Sdelphij * 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)"
40296341Sdelphij *
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.
52296341Sdelphij *
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
73238405Sjkim/* CRL score values */
74238405Sjkim
75238405Sjkim/* No unhandled critical extensions */
76238405Sjkim
77296341Sdelphij#define CRL_SCORE_NOCRITICAL    0x100
78238405Sjkim
79238405Sjkim/* certificate is within CRL scope */
80238405Sjkim
81296341Sdelphij#define CRL_SCORE_SCOPE         0x080
82238405Sjkim
83238405Sjkim/* CRL times valid */
84238405Sjkim
85296341Sdelphij#define CRL_SCORE_TIME          0x040
86238405Sjkim
87238405Sjkim/* Issuer name matches certificate */
88238405Sjkim
89296341Sdelphij#define CRL_SCORE_ISSUER_NAME   0x020
90238405Sjkim
91238405Sjkim/* If this score or above CRL is probably valid */
92238405Sjkim
93238405Sjkim#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE)
94238405Sjkim
95238405Sjkim/* CRL issuer is certificate issuer */
96238405Sjkim
97296341Sdelphij#define CRL_SCORE_ISSUER_CERT   0x018
98238405Sjkim
99238405Sjkim/* CRL issuer is on certificate path */
100238405Sjkim
101296341Sdelphij#define CRL_SCORE_SAME_PATH     0x008
102238405Sjkim
103238405Sjkim/* CRL issuer matches CRL AKID */
104238405Sjkim
105296341Sdelphij#define CRL_SCORE_AKID          0x004
106238405Sjkim
107238405Sjkim/* Have a delta CRL with valid times */
108238405Sjkim
109296341Sdelphij#define CRL_SCORE_TIME_DELTA    0x002
110238405Sjkim
111296341Sdelphijstatic int null_callback(int ok, X509_STORE_CTX *e);
11268651Skrisstatic int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
11368651Skrisstatic X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
114160814Ssimonstatic int check_chain_extensions(X509_STORE_CTX *ctx);
115238405Sjkimstatic int check_name_constraints(X509_STORE_CTX *ctx);
11659191Skrisstatic int check_trust(X509_STORE_CTX *ctx);
117109998Smarkmstatic int check_revocation(X509_STORE_CTX *ctx);
118109998Smarkmstatic int check_cert(X509_STORE_CTX *ctx);
119160814Ssimonstatic int check_policy(X509_STORE_CTX *ctx);
120238405Sjkim
121238405Sjkimstatic int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
122296341Sdelphij                         unsigned int *preasons, X509_CRL *crl, X509 *x);
123238405Sjkimstatic int get_crl_delta(X509_STORE_CTX *ctx,
124296341Sdelphij                         X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
125296341Sdelphijstatic void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl,
126296341Sdelphij                         int *pcrl_score, X509_CRL *base,
127296341Sdelphij                         STACK_OF(X509_CRL) *crls);
128296341Sdelphijstatic void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
129296341Sdelphij                           int *pcrl_score);
130238405Sjkimstatic int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
131296341Sdelphij                           unsigned int *preasons);
132238405Sjkimstatic int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
133238405Sjkimstatic int check_crl_chain(X509_STORE_CTX *ctx,
134296341Sdelphij                           STACK_OF(X509) *cert_path,
135296341Sdelphij                           STACK_OF(X509) *crl_path);
136238405Sjkim
13755714Skrisstatic int internal_verify(X509_STORE_CTX *ctx);
138296341Sdelphijconst char X509_version[] = "X.509" OPENSSL_VERSION_PTEXT;
13955714Skris
14055714Skrisstatic int null_callback(int ok, X509_STORE_CTX *e)
141296341Sdelphij{
142296341Sdelphij    return ok;
143296341Sdelphij}
14455714Skris
14555714Skris#if 0
14655714Skrisstatic int x509_subject_cmp(X509 **a, X509 **b)
147296341Sdelphij{
148296341Sdelphij    return X509_subject_name_cmp(*a, *b);
149296341Sdelphij}
15055714Skris#endif
15155714Skris
15255714Skrisint X509_verify_cert(X509_STORE_CTX *ctx)
153296341Sdelphij{
154296341Sdelphij    X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
155296341Sdelphij    int bad_chain = 0;
156296341Sdelphij    X509_VERIFY_PARAM *param = ctx->param;
157296341Sdelphij    int depth, i, ok = 0;
158296341Sdelphij    int num, j, retry;
159296341Sdelphij    int (*cb) (int xok, X509_STORE_CTX *xctx);
160296341Sdelphij    STACK_OF(X509) *sktmp = NULL;
161296341Sdelphij    if (ctx->cert == NULL) {
162296341Sdelphij        X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
163296341Sdelphij        return -1;
164296341Sdelphij    }
165296341Sdelphij    if (ctx->chain != NULL) {
166296341Sdelphij        /*
167296341Sdelphij         * This X509_STORE_CTX has already been used to verify a cert. We
168296341Sdelphij         * cannot do another one.
169296341Sdelphij         */
170296341Sdelphij        X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
171296341Sdelphij        return -1;
172296341Sdelphij    }
17355714Skris
174296341Sdelphij    cb = ctx->verify_cb;
17555714Skris
176296341Sdelphij    /*
177296341Sdelphij     * first we make sure the chain we are going to build is present and that
178296341Sdelphij     * the first entry is in place
179296341Sdelphij     */
180296341Sdelphij    if (((ctx->chain = sk_X509_new_null()) == NULL) ||
181296341Sdelphij        (!sk_X509_push(ctx->chain, ctx->cert))) {
182296341Sdelphij        X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
183296341Sdelphij        goto end;
184296341Sdelphij    }
185296341Sdelphij    CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509);
186296341Sdelphij    ctx->last_untrusted = 1;
18755714Skris
188296341Sdelphij    /* We use a temporary STACK so we can chop and hack at it */
189296341Sdelphij    if (ctx->untrusted != NULL
190296341Sdelphij        && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
191296341Sdelphij        X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
192296341Sdelphij        goto end;
193296341Sdelphij    }
19455714Skris
195296341Sdelphij    num = sk_X509_num(ctx->chain);
196296341Sdelphij    x = sk_X509_value(ctx->chain, num - 1);
197296341Sdelphij    depth = param->depth;
19855714Skris
199296341Sdelphij    for (;;) {
200296341Sdelphij        /* If we have enough, we break */
201296341Sdelphij        if (depth < num)
202296341Sdelphij            break;              /* FIXME: If this happens, we should take
203296341Sdelphij                                 * note of it and, if appropriate, use the
204296341Sdelphij                                 * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
205296341Sdelphij                                 * later. */
20655714Skris
207296341Sdelphij        /* If we are self signed, we break */
208296341Sdelphij        if (ctx->check_issued(ctx, x, x))
209296341Sdelphij            break;
21055714Skris
211296341Sdelphij        /* If we were passed a cert chain, use it first */
212296341Sdelphij        if (ctx->untrusted != NULL) {
213296341Sdelphij            xtmp = find_issuer(ctx, sktmp, x);
214296341Sdelphij            if (xtmp != NULL) {
215296341Sdelphij                if (!sk_X509_push(ctx->chain, xtmp)) {
216296341Sdelphij                    X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
217296341Sdelphij                    goto end;
218296341Sdelphij                }
219296341Sdelphij                CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509);
220296341Sdelphij                (void)sk_X509_delete_ptr(sktmp, xtmp);
221296341Sdelphij                ctx->last_untrusted++;
222296341Sdelphij                x = xtmp;
223296341Sdelphij                num++;
224296341Sdelphij                /*
225296341Sdelphij                 * reparse the full chain for the next one
226296341Sdelphij                 */
227296341Sdelphij                continue;
228296341Sdelphij            }
229296341Sdelphij        }
230296341Sdelphij        break;
231296341Sdelphij    }
23255714Skris
233296341Sdelphij    /* Remember how many untrusted certs we have */
234296341Sdelphij    j = num;
235296341Sdelphij    /*
236296341Sdelphij     * at this point, chain should contain a list of untrusted certificates.
237296341Sdelphij     * We now need to add at least one trusted one, if possible, otherwise we
238296341Sdelphij     * complain.
239296341Sdelphij     */
24055714Skris
241296341Sdelphij    do {
242296341Sdelphij        /*
243296341Sdelphij         * Examine last certificate in chain and see if it is self signed.
244296341Sdelphij         */
245296341Sdelphij        i = sk_X509_num(ctx->chain);
246296341Sdelphij        x = sk_X509_value(ctx->chain, i - 1);
247296341Sdelphij        if (ctx->check_issued(ctx, x, x)) {
248296341Sdelphij            /* we have a self signed certificate */
249296341Sdelphij            if (sk_X509_num(ctx->chain) == 1) {
250296341Sdelphij                /*
251296341Sdelphij                 * We have a single self signed certificate: see if we can
252296341Sdelphij                 * find it in the store. We must have an exact match to avoid
253296341Sdelphij                 * possible impersonation.
254296341Sdelphij                 */
255296341Sdelphij                ok = ctx->get_issuer(&xtmp, ctx, x);
256296341Sdelphij                if ((ok <= 0) || X509_cmp(x, xtmp)) {
257296341Sdelphij                    ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
258296341Sdelphij                    ctx->current_cert = x;
259296341Sdelphij                    ctx->error_depth = i - 1;
260296341Sdelphij                    if (ok == 1)
261296341Sdelphij                        X509_free(xtmp);
262296341Sdelphij                    bad_chain = 1;
263296341Sdelphij                    ok = cb(0, ctx);
264296341Sdelphij                    if (!ok)
265296341Sdelphij                        goto end;
266296341Sdelphij                } else {
267296341Sdelphij                    /*
268296341Sdelphij                     * We have a match: replace certificate with store
269296341Sdelphij                     * version so we get any trust settings.
270296341Sdelphij                     */
271296341Sdelphij                    X509_free(x);
272296341Sdelphij                    x = xtmp;
273296341Sdelphij                    (void)sk_X509_set(ctx->chain, i - 1, x);
274296341Sdelphij                    ctx->last_untrusted = 0;
275296341Sdelphij                }
276296341Sdelphij            } else {
277296341Sdelphij                /*
278296341Sdelphij                 * extract and save self signed certificate for later use
279296341Sdelphij                 */
280296341Sdelphij                chain_ss = sk_X509_pop(ctx->chain);
281296341Sdelphij                ctx->last_untrusted--;
282296341Sdelphij                num--;
283296341Sdelphij                j--;
284296341Sdelphij                x = sk_X509_value(ctx->chain, num - 1);
285296341Sdelphij            }
286296341Sdelphij        }
287296341Sdelphij        /* We now lookup certs from the certificate store */
288296341Sdelphij        for (;;) {
289296341Sdelphij            /* If we have enough, we break */
290296341Sdelphij            if (depth < num)
291296341Sdelphij                break;
292296341Sdelphij            /* If we are self signed, we break */
293296341Sdelphij            if (ctx->check_issued(ctx, x, x))
294296341Sdelphij                break;
295296341Sdelphij            ok = ctx->get_issuer(&xtmp, ctx, x);
296296341Sdelphij            if (ok < 0)
297296341Sdelphij                return ok;
298296341Sdelphij            if (ok == 0)
299296341Sdelphij                break;
300296341Sdelphij            x = xtmp;
301296341Sdelphij            if (!sk_X509_push(ctx->chain, x)) {
302296341Sdelphij                X509_free(xtmp);
303296341Sdelphij                X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
304296341Sdelphij                return 0;
305296341Sdelphij            }
306296341Sdelphij            num++;
307296341Sdelphij        }
30855714Skris
309296341Sdelphij        /*
310296341Sdelphij         * If we haven't got a least one certificate from our store then check
311296341Sdelphij         * if there is an alternative chain that could be used.  We only do this
312296341Sdelphij         * if the user hasn't switched off alternate chain checking
313296341Sdelphij         */
314296341Sdelphij        retry = 0;
315296341Sdelphij        if (num == ctx->last_untrusted &&
316296341Sdelphij            !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
317296341Sdelphij            while (j-- > 1) {
318296341Sdelphij                xtmp2 = sk_X509_value(ctx->chain, j - 1);
319296341Sdelphij                ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
320296341Sdelphij                if (ok < 0)
321296341Sdelphij                    goto end;
322296341Sdelphij                /* Check if we found an alternate chain */
323296341Sdelphij                if (ok > 0) {
324296341Sdelphij                    /*
325296341Sdelphij                     * Free up the found cert we'll add it again later
326296341Sdelphij                     */
327296341Sdelphij                    X509_free(xtmp);
32868651Skris
329296341Sdelphij                    /*
330296341Sdelphij                     * Dump all the certs above this point - we've found an
331296341Sdelphij                     * alternate chain
332296341Sdelphij                     */
333296341Sdelphij                    while (num > j) {
334296341Sdelphij                        xtmp = sk_X509_pop(ctx->chain);
335296341Sdelphij                        X509_free(xtmp);
336296341Sdelphij                        num--;
337296341Sdelphij                    }
338296341Sdelphij                    ctx->last_untrusted = sk_X509_num(ctx->chain);
339296341Sdelphij                    retry = 1;
340296341Sdelphij                    break;
341296341Sdelphij                }
342296341Sdelphij            }
343296341Sdelphij        }
344296341Sdelphij    } while (retry);
34555714Skris
346296341Sdelphij    /* Is last certificate looked up self signed? */
347296341Sdelphij    if (!ctx->check_issued(ctx, x, x)) {
348296341Sdelphij        if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
349296341Sdelphij            if (ctx->last_untrusted >= num)
350296341Sdelphij                ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
351296341Sdelphij            else
352296341Sdelphij                ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
353296341Sdelphij            ctx->current_cert = x;
354296341Sdelphij        } else {
35555714Skris
356296341Sdelphij            sk_X509_push(ctx->chain, chain_ss);
357296341Sdelphij            num++;
358296341Sdelphij            ctx->last_untrusted = num;
359296341Sdelphij            ctx->current_cert = chain_ss;
360296341Sdelphij            ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
361296341Sdelphij            chain_ss = NULL;
362296341Sdelphij        }
36355714Skris
364296341Sdelphij        ctx->error_depth = num - 1;
365296341Sdelphij        bad_chain = 1;
366296341Sdelphij        ok = cb(0, ctx);
367296341Sdelphij        if (!ok)
368296341Sdelphij            goto end;
369296341Sdelphij    }
37068651Skris
371296341Sdelphij    /* We have the chain complete: now we need to check its purpose */
372296341Sdelphij    ok = check_chain_extensions(ctx);
37368651Skris
374296341Sdelphij    if (!ok)
375296341Sdelphij        goto end;
37655714Skris
377296341Sdelphij    /* Check name constraints */
37868651Skris
379296341Sdelphij    ok = check_name_constraints(ctx);
38055714Skris
381296341Sdelphij    if (!ok)
382296341Sdelphij        goto end;
38355714Skris
384296341Sdelphij    /* The chain extensions are OK: check trust */
38555714Skris
386296341Sdelphij    if (param->trust > 0)
387296341Sdelphij        ok = check_trust(ctx);
38859191Skris
389296341Sdelphij    if (!ok)
390296341Sdelphij        goto end;
39159191Skris
392296341Sdelphij    /* We may as well copy down any DSA parameters that are required */
393296341Sdelphij    X509_get_pubkey_parameters(NULL, ctx->chain);
394238405Sjkim
395296341Sdelphij    /*
396296341Sdelphij     * Check revocation status: we do this after copying parameters because
397296341Sdelphij     * they may be needed for CRL signature verification.
398296341Sdelphij     */
399238405Sjkim
400296341Sdelphij    ok = ctx->check_revocation(ctx);
401296341Sdelphij    if (!ok)
402296341Sdelphij        goto end;
40359191Skris
404296341Sdelphij    /* At this point, we have a chain and need to verify it */
405296341Sdelphij    if (ctx->verify != NULL)
406296341Sdelphij        ok = ctx->verify(ctx);
407296341Sdelphij    else
408296341Sdelphij        ok = internal_verify(ctx);
409296341Sdelphij    if (!ok)
410296341Sdelphij        goto end;
41159191Skris
412167612Ssimon#ifndef OPENSSL_NO_RFC3779
413296341Sdelphij    /* RFC 3779 path validation, now that CRL check has been done */
414296341Sdelphij    ok = v3_asid_validate_path(ctx);
415296341Sdelphij    if (!ok)
416296341Sdelphij        goto end;
417296341Sdelphij    ok = v3_addr_validate_path(ctx);
418296341Sdelphij    if (!ok)
419296341Sdelphij        goto end;
420167612Ssimon#endif
421167612Ssimon
422296341Sdelphij    /* If we get this far evaluate policies */
423296341Sdelphij    if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
424296341Sdelphij        ok = ctx->check_policy(ctx);
425296341Sdelphij    if (!ok)
426296341Sdelphij        goto end;
427296341Sdelphij    if (0) {
428296341Sdelphij end:
429296341Sdelphij        X509_get_pubkey_parameters(NULL, ctx->chain);
430296341Sdelphij    }
431296341Sdelphij    if (sktmp != NULL)
432296341Sdelphij        sk_X509_free(sktmp);
433296341Sdelphij    if (chain_ss != NULL)
434296341Sdelphij        X509_free(chain_ss);
435296341Sdelphij    return ok;
436296341Sdelphij}
43755714Skris
438296341Sdelphij/*
439296341Sdelphij * Given a STACK_OF(X509) find the issuer of cert (if any)
44068651Skris */
44168651Skris
44268651Skrisstatic X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
44368651Skris{
444296341Sdelphij    int i;
445296341Sdelphij    X509 *issuer;
446296341Sdelphij    for (i = 0; i < sk_X509_num(sk); i++) {
447296341Sdelphij        issuer = sk_X509_value(sk, i);
448296341Sdelphij        if (ctx->check_issued(ctx, x, issuer))
449296341Sdelphij            return issuer;
450296341Sdelphij    }
451296341Sdelphij    return NULL;
45268651Skris}
45368651Skris
45468651Skris/* Given a possible certificate and issuer check them */
45568651Skris
45668651Skrisstatic int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
45768651Skris{
458296341Sdelphij    int ret;
459296341Sdelphij    ret = X509_check_issued(issuer, x);
460296341Sdelphij    if (ret == X509_V_OK)
461296341Sdelphij        return 1;
462296341Sdelphij    /* If we haven't asked for issuer errors don't set ctx */
463296341Sdelphij    if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
464296341Sdelphij        return 0;
46568651Skris
466296341Sdelphij    ctx->error = ret;
467296341Sdelphij    ctx->current_cert = x;
468296341Sdelphij    ctx->current_issuer = issuer;
469296341Sdelphij    return ctx->verify_cb(0, ctx);
470296341Sdelphij    return 0;
47168651Skris}
47268651Skris
47368651Skris/* Alternative lookup method: look from a STACK stored in other_ctx */
47468651Skris
47568651Skrisstatic int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
47668651Skris{
477296341Sdelphij    *issuer = find_issuer(ctx, ctx->other_ctx, x);
478296341Sdelphij    if (*issuer) {
479296341Sdelphij        CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
480296341Sdelphij        return 1;
481296341Sdelphij    } else
482296341Sdelphij        return 0;
48368651Skris}
48468651Skris
485296341Sdelphij/*
486296341Sdelphij * Check a certificate chains extensions for consistency with the supplied
487296341Sdelphij * purpose
48859191Skris */
48959191Skris
490160814Ssimonstatic int check_chain_extensions(X509_STORE_CTX *ctx)
49159191Skris{
492109998Smarkm#ifdef OPENSSL_NO_CHAIN_VERIFY
493296341Sdelphij    return 1;
49459191Skris#else
495296341Sdelphij    int i, ok = 0, must_be_ca, plen = 0;
496296341Sdelphij    X509 *x;
497296341Sdelphij    int (*cb) (int xok, X509_STORE_CTX *xctx);
498296341Sdelphij    int proxy_path_length = 0;
499296341Sdelphij    int purpose;
500296341Sdelphij    int allow_proxy_certs;
501296341Sdelphij    cb = ctx->verify_cb;
502160814Ssimon
503296341Sdelphij    /*-
504296341Sdelphij     *  must_be_ca can have 1 of 3 values:
505296341Sdelphij     * -1: we accept both CA and non-CA certificates, to allow direct
506296341Sdelphij     *     use of self-signed certificates (which are marked as CA).
507296341Sdelphij     * 0:  we only accept non-CA certificates.  This is currently not
508296341Sdelphij     *     used, but the possibility is present for future extensions.
509296341Sdelphij     * 1:  we only accept CA certificates.  This is currently used for
510296341Sdelphij     *     all certificates in the chain except the leaf certificate.
511296341Sdelphij     */
512296341Sdelphij    must_be_ca = -1;
513160814Ssimon
514296341Sdelphij    /* CRL path validation */
515296341Sdelphij    if (ctx->parent) {
516296341Sdelphij        allow_proxy_certs = 0;
517296341Sdelphij        purpose = X509_PURPOSE_CRL_SIGN;
518296341Sdelphij    } else {
519296341Sdelphij        allow_proxy_certs =
520296341Sdelphij            ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
521296341Sdelphij        /*
522296341Sdelphij         * A hack to keep people who don't want to modify their software
523296341Sdelphij         * happy
524296341Sdelphij         */
525296341Sdelphij        if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
526296341Sdelphij            allow_proxy_certs = 1;
527296341Sdelphij        purpose = ctx->param->purpose;
528296341Sdelphij    }
529160814Ssimon
530296341Sdelphij    /* Check all untrusted certificates */
531296341Sdelphij    for (i = 0; i < ctx->last_untrusted; i++) {
532296341Sdelphij        int ret;
533296341Sdelphij        x = sk_X509_value(ctx->chain, i);
534296341Sdelphij        if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
535296341Sdelphij            && (x->ex_flags & EXFLAG_CRITICAL)) {
536296341Sdelphij            ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
537296341Sdelphij            ctx->error_depth = i;
538296341Sdelphij            ctx->current_cert = x;
539296341Sdelphij            ok = cb(0, ctx);
540296341Sdelphij            if (!ok)
541296341Sdelphij                goto end;
542296341Sdelphij        }
543296341Sdelphij        if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
544296341Sdelphij            ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
545296341Sdelphij            ctx->error_depth = i;
546296341Sdelphij            ctx->current_cert = x;
547296341Sdelphij            ok = cb(0, ctx);
548296341Sdelphij            if (!ok)
549296341Sdelphij                goto end;
550296341Sdelphij        }
551296341Sdelphij        ret = X509_check_ca(x);
552296341Sdelphij        switch (must_be_ca) {
553296341Sdelphij        case -1:
554296341Sdelphij            if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
555296341Sdelphij                && (ret != 1) && (ret != 0)) {
556296341Sdelphij                ret = 0;
557296341Sdelphij                ctx->error = X509_V_ERR_INVALID_CA;
558296341Sdelphij            } else
559296341Sdelphij                ret = 1;
560296341Sdelphij            break;
561296341Sdelphij        case 0:
562296341Sdelphij            if (ret != 0) {
563296341Sdelphij                ret = 0;
564296341Sdelphij                ctx->error = X509_V_ERR_INVALID_NON_CA;
565296341Sdelphij            } else
566296341Sdelphij                ret = 1;
567296341Sdelphij            break;
568296341Sdelphij        default:
569296341Sdelphij            if ((ret == 0)
570296341Sdelphij                || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
571296341Sdelphij                    && (ret != 1))) {
572296341Sdelphij                ret = 0;
573296341Sdelphij                ctx->error = X509_V_ERR_INVALID_CA;
574296341Sdelphij            } else
575296341Sdelphij                ret = 1;
576296341Sdelphij            break;
577296341Sdelphij        }
578296341Sdelphij        if (ret == 0) {
579296341Sdelphij            ctx->error_depth = i;
580296341Sdelphij            ctx->current_cert = x;
581296341Sdelphij            ok = cb(0, ctx);
582296341Sdelphij            if (!ok)
583296341Sdelphij                goto end;
584296341Sdelphij        }
585296341Sdelphij        if (ctx->param->purpose > 0) {
586296341Sdelphij            ret = X509_check_purpose(x, purpose, must_be_ca > 0);
587296341Sdelphij            if ((ret == 0)
588296341Sdelphij                || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
589296341Sdelphij                    && (ret != 1))) {
590296341Sdelphij                ctx->error = X509_V_ERR_INVALID_PURPOSE;
591296341Sdelphij                ctx->error_depth = i;
592296341Sdelphij                ctx->current_cert = x;
593296341Sdelphij                ok = cb(0, ctx);
594296341Sdelphij                if (!ok)
595296341Sdelphij                    goto end;
596296341Sdelphij            }
597296341Sdelphij        }
598296341Sdelphij        /* Check pathlen if not self issued */
599296341Sdelphij        if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
600296341Sdelphij            && (x->ex_pathlen != -1)
601296341Sdelphij            && (plen > (x->ex_pathlen + proxy_path_length + 1))) {
602296341Sdelphij            ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
603296341Sdelphij            ctx->error_depth = i;
604296341Sdelphij            ctx->current_cert = x;
605296341Sdelphij            ok = cb(0, ctx);
606296341Sdelphij            if (!ok)
607296341Sdelphij                goto end;
608296341Sdelphij        }
609296341Sdelphij        /* Increment path length if not self issued */
610296341Sdelphij        if (!(x->ex_flags & EXFLAG_SI))
611296341Sdelphij            plen++;
612296341Sdelphij        /*
613296341Sdelphij         * If this certificate is a proxy certificate, the next certificate
614296341Sdelphij         * must be another proxy certificate or a EE certificate.  If not,
615296341Sdelphij         * the next certificate must be a CA certificate.
616296341Sdelphij         */
617296341Sdelphij        if (x->ex_flags & EXFLAG_PROXY) {
618296341Sdelphij            if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
619296341Sdelphij                ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
620296341Sdelphij                ctx->error_depth = i;
621296341Sdelphij                ctx->current_cert = x;
622296341Sdelphij                ok = cb(0, ctx);
623296341Sdelphij                if (!ok)
624296341Sdelphij                    goto end;
625296341Sdelphij            }
626296341Sdelphij            proxy_path_length++;
627296341Sdelphij            must_be_ca = 0;
628296341Sdelphij        } else
629296341Sdelphij            must_be_ca = 1;
630296341Sdelphij    }
631296341Sdelphij    ok = 1;
63268651Skris end:
633296341Sdelphij    return ok;
63459191Skris#endif
63559191Skris}
63659191Skris
637238405Sjkimstatic int check_name_constraints(X509_STORE_CTX *ctx)
638296341Sdelphij{
639296341Sdelphij    X509 *x;
640296341Sdelphij    int i, j, rv;
641296341Sdelphij    /* Check name constraints for all certificates */
642296341Sdelphij    for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) {
643296341Sdelphij        x = sk_X509_value(ctx->chain, i);
644296341Sdelphij        /* Ignore self issued certs unless last in chain */
645296341Sdelphij        if (i && (x->ex_flags & EXFLAG_SI))
646296341Sdelphij            continue;
647296341Sdelphij        /*
648296341Sdelphij         * Check against constraints for all certificates higher in chain
649296341Sdelphij         * including trust anchor. Trust anchor not strictly speaking needed
650296341Sdelphij         * but if it includes constraints it is to be assumed it expects them
651296341Sdelphij         * to be obeyed.
652296341Sdelphij         */
653296341Sdelphij        for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
654296341Sdelphij            NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
655296341Sdelphij            if (nc) {
656296341Sdelphij                rv = NAME_CONSTRAINTS_check(x, nc);
657296341Sdelphij                if (rv != X509_V_OK) {
658296341Sdelphij                    ctx->error = rv;
659296341Sdelphij                    ctx->error_depth = i;
660296341Sdelphij                    ctx->current_cert = x;
661296341Sdelphij                    if (!ctx->verify_cb(0, ctx))
662296341Sdelphij                        return 0;
663296341Sdelphij                }
664296341Sdelphij            }
665296341Sdelphij        }
666296341Sdelphij    }
667296341Sdelphij    return 1;
668296341Sdelphij}
669238405Sjkim
67059191Skrisstatic int check_trust(X509_STORE_CTX *ctx)
67159191Skris{
672109998Smarkm#ifdef OPENSSL_NO_CHAIN_VERIFY
673296341Sdelphij    return 1;
67459191Skris#else
675296341Sdelphij    int i, ok;
676296341Sdelphij    X509 *x;
677296341Sdelphij    int (*cb) (int xok, X509_STORE_CTX *xctx);
678296341Sdelphij    cb = ctx->verify_cb;
67959191Skris/* For now just check the last certificate in the chain */
680296341Sdelphij    i = sk_X509_num(ctx->chain) - 1;
681296341Sdelphij    x = sk_X509_value(ctx->chain, i);
682296341Sdelphij    ok = X509_check_trust(x, ctx->param->trust, 0);
683296341Sdelphij    if (ok == X509_TRUST_TRUSTED)
684296341Sdelphij        return 1;
685296341Sdelphij    ctx->error_depth = i;
686296341Sdelphij    ctx->current_cert = x;
687296341Sdelphij    if (ok == X509_TRUST_REJECTED)
688296341Sdelphij        ctx->error = X509_V_ERR_CERT_REJECTED;
689296341Sdelphij    else
690296341Sdelphij        ctx->error = X509_V_ERR_CERT_UNTRUSTED;
691296341Sdelphij    ok = cb(0, ctx);
692296341Sdelphij    return ok;
69359191Skris#endif
69459191Skris}
69559191Skris
696109998Smarkmstatic int check_revocation(X509_STORE_CTX *ctx)
697296341Sdelphij{
698296341Sdelphij    int i, last, ok;
699296341Sdelphij    if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
700296341Sdelphij        return 1;
701296341Sdelphij    if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
702296341Sdelphij        last = sk_X509_num(ctx->chain) - 1;
703296341Sdelphij    else {
704296341Sdelphij        /* If checking CRL paths this isn't the EE certificate */
705296341Sdelphij        if (ctx->parent)
706296341Sdelphij            return 1;
707296341Sdelphij        last = 0;
708296341Sdelphij    }
709296341Sdelphij    for (i = 0; i <= last; i++) {
710296341Sdelphij        ctx->error_depth = i;
711296341Sdelphij        ok = check_cert(ctx);
712296341Sdelphij        if (!ok)
713296341Sdelphij            return ok;
714296341Sdelphij    }
715296341Sdelphij    return 1;
716296341Sdelphij}
717109998Smarkm
718109998Smarkmstatic int check_cert(X509_STORE_CTX *ctx)
719296341Sdelphij{
720296341Sdelphij    X509_CRL *crl = NULL, *dcrl = NULL;
721296341Sdelphij    X509 *x;
722296341Sdelphij    int ok, cnum;
723296341Sdelphij    unsigned int last_reasons;
724296341Sdelphij    cnum = ctx->error_depth;
725296341Sdelphij    x = sk_X509_value(ctx->chain, cnum);
726296341Sdelphij    ctx->current_cert = x;
727296341Sdelphij    ctx->current_issuer = NULL;
728296341Sdelphij    ctx->current_crl_score = 0;
729296341Sdelphij    ctx->current_reasons = 0;
730296341Sdelphij    while (ctx->current_reasons != CRLDP_ALL_REASONS) {
731296341Sdelphij        last_reasons = ctx->current_reasons;
732296341Sdelphij        /* Try to retrieve relevant CRL */
733296341Sdelphij        if (ctx->get_crl)
734296341Sdelphij            ok = ctx->get_crl(ctx, &crl, x);
735296341Sdelphij        else
736296341Sdelphij            ok = get_crl_delta(ctx, &crl, &dcrl, x);
737296341Sdelphij        /*
738296341Sdelphij         * If error looking up CRL, nothing we can do except notify callback
739296341Sdelphij         */
740296341Sdelphij        if (!ok) {
741296341Sdelphij            ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
742296341Sdelphij            ok = ctx->verify_cb(0, ctx);
743296341Sdelphij            goto err;
744296341Sdelphij        }
745296341Sdelphij        ctx->current_crl = crl;
746296341Sdelphij        ok = ctx->check_crl(ctx, crl);
747296341Sdelphij        if (!ok)
748296341Sdelphij            goto err;
749238405Sjkim
750296341Sdelphij        if (dcrl) {
751296341Sdelphij            ok = ctx->check_crl(ctx, dcrl);
752296341Sdelphij            if (!ok)
753296341Sdelphij                goto err;
754296341Sdelphij            ok = ctx->cert_crl(ctx, dcrl, x);
755296341Sdelphij            if (!ok)
756296341Sdelphij                goto err;
757296341Sdelphij        } else
758296341Sdelphij            ok = 1;
759238405Sjkim
760296341Sdelphij        /* Don't look in full CRL if delta reason is removefromCRL */
761296341Sdelphij        if (ok != 2) {
762296341Sdelphij            ok = ctx->cert_crl(ctx, crl, x);
763296341Sdelphij            if (!ok)
764296341Sdelphij                goto err;
765296341Sdelphij        }
766238405Sjkim
767296341Sdelphij        X509_CRL_free(crl);
768296341Sdelphij        X509_CRL_free(dcrl);
769296341Sdelphij        crl = NULL;
770296341Sdelphij        dcrl = NULL;
771296341Sdelphij        /*
772296341Sdelphij         * If reasons not updated we wont get anywhere by another iteration,
773296341Sdelphij         * so exit loop.
774296341Sdelphij         */
775296341Sdelphij        if (last_reasons == ctx->current_reasons) {
776296341Sdelphij            ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
777296341Sdelphij            ok = ctx->verify_cb(0, ctx);
778296341Sdelphij            goto err;
779296341Sdelphij        }
780296341Sdelphij    }
781296341Sdelphij err:
782296341Sdelphij    X509_CRL_free(crl);
783296341Sdelphij    X509_CRL_free(dcrl);
784238405Sjkim
785296341Sdelphij    ctx->current_crl = NULL;
786296341Sdelphij    return ok;
787109998Smarkm
788296341Sdelphij}
789109998Smarkm
790160814Ssimon/* Check CRL times against values in X509_STORE_CTX */
791160814Ssimon
792160814Ssimonstatic int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
793296341Sdelphij{
794296341Sdelphij    time_t *ptime;
795296341Sdelphij    int i;
796296341Sdelphij    if (notify)
797296341Sdelphij        ctx->current_crl = crl;
798296341Sdelphij    if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
799296341Sdelphij        ptime = &ctx->param->check_time;
800296341Sdelphij    else
801296341Sdelphij        ptime = NULL;
802160814Ssimon
803296341Sdelphij    i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
804296341Sdelphij    if (i == 0) {
805296341Sdelphij        if (!notify)
806296341Sdelphij            return 0;
807296341Sdelphij        ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
808296341Sdelphij        if (!ctx->verify_cb(0, ctx))
809296341Sdelphij            return 0;
810296341Sdelphij    }
811160814Ssimon
812296341Sdelphij    if (i > 0) {
813296341Sdelphij        if (!notify)
814296341Sdelphij            return 0;
815296341Sdelphij        ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
816296341Sdelphij        if (!ctx->verify_cb(0, ctx))
817296341Sdelphij            return 0;
818296341Sdelphij    }
819160814Ssimon
820296341Sdelphij    if (X509_CRL_get_nextUpdate(crl)) {
821296341Sdelphij        i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
822160814Ssimon
823296341Sdelphij        if (i == 0) {
824296341Sdelphij            if (!notify)
825296341Sdelphij                return 0;
826296341Sdelphij            ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
827296341Sdelphij            if (!ctx->verify_cb(0, ctx))
828296341Sdelphij                return 0;
829296341Sdelphij        }
830296341Sdelphij        /* Ignore expiry of base CRL is delta is valid */
831296341Sdelphij        if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
832296341Sdelphij            if (!notify)
833296341Sdelphij                return 0;
834296341Sdelphij            ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
835296341Sdelphij            if (!ctx->verify_cb(0, ctx))
836296341Sdelphij                return 0;
837296341Sdelphij        }
838296341Sdelphij    }
839160814Ssimon
840296341Sdelphij    if (notify)
841296341Sdelphij        ctx->current_crl = NULL;
842160814Ssimon
843296341Sdelphij    return 1;
844296341Sdelphij}
845160814Ssimon
846238405Sjkimstatic int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
847296341Sdelphij                      X509 **pissuer, int *pscore, unsigned int *preasons,
848296341Sdelphij                      STACK_OF(X509_CRL) *crls)
849296341Sdelphij{
850296341Sdelphij    int i, crl_score, best_score = *pscore;
851296341Sdelphij    unsigned int reasons, best_reasons = 0;
852296341Sdelphij    X509 *x = ctx->current_cert;
853296341Sdelphij    X509_CRL *crl, *best_crl = NULL;
854296341Sdelphij    X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
855238405Sjkim
856296341Sdelphij    for (i = 0; i < sk_X509_CRL_num(crls); i++) {
857296341Sdelphij        crl = sk_X509_CRL_value(crls, i);
858296341Sdelphij        reasons = *preasons;
859296341Sdelphij        crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
860238405Sjkim
861296341Sdelphij        if (crl_score > best_score) {
862296341Sdelphij            best_crl = crl;
863296341Sdelphij            best_crl_issuer = crl_issuer;
864296341Sdelphij            best_score = crl_score;
865296341Sdelphij            best_reasons = reasons;
866296341Sdelphij        }
867296341Sdelphij    }
868238405Sjkim
869296341Sdelphij    if (best_crl) {
870296341Sdelphij        if (*pcrl)
871296341Sdelphij            X509_CRL_free(*pcrl);
872296341Sdelphij        *pcrl = best_crl;
873296341Sdelphij        *pissuer = best_crl_issuer;
874296341Sdelphij        *pscore = best_score;
875296341Sdelphij        *preasons = best_reasons;
876296341Sdelphij        CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
877296341Sdelphij        if (*pdcrl) {
878296341Sdelphij            X509_CRL_free(*pdcrl);
879296341Sdelphij            *pdcrl = NULL;
880296341Sdelphij        }
881296341Sdelphij        get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
882296341Sdelphij    }
883238405Sjkim
884296341Sdelphij    if (best_score >= CRL_SCORE_VALID)
885296341Sdelphij        return 1;
886238405Sjkim
887296341Sdelphij    return 0;
888296341Sdelphij}
889160814Ssimon
890296341Sdelphij/*
891296341Sdelphij * Compare two CRL extensions for delta checking purposes. They should be
892238405Sjkim * both present or both absent. If both present all fields must be identical.
893109998Smarkm */
894238405Sjkim
895238405Sjkimstatic int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
896296341Sdelphij{
897296341Sdelphij    ASN1_OCTET_STRING *exta, *extb;
898296341Sdelphij    int i;
899296341Sdelphij    i = X509_CRL_get_ext_by_NID(a, nid, -1);
900296341Sdelphij    if (i >= 0) {
901296341Sdelphij        /* Can't have multiple occurrences */
902296341Sdelphij        if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
903296341Sdelphij            return 0;
904296341Sdelphij        exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
905296341Sdelphij    } else
906296341Sdelphij        exta = NULL;
907238405Sjkim
908296341Sdelphij    i = X509_CRL_get_ext_by_NID(b, nid, -1);
909238405Sjkim
910296341Sdelphij    if (i >= 0) {
911238405Sjkim
912296341Sdelphij        if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
913296341Sdelphij            return 0;
914296341Sdelphij        extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
915296341Sdelphij    } else
916296341Sdelphij        extb = NULL;
917238405Sjkim
918296341Sdelphij    if (!exta && !extb)
919296341Sdelphij        return 1;
920238405Sjkim
921296341Sdelphij    if (!exta || !extb)
922296341Sdelphij        return 0;
923238405Sjkim
924296341Sdelphij    if (ASN1_OCTET_STRING_cmp(exta, extb))
925296341Sdelphij        return 0;
926238405Sjkim
927296341Sdelphij    return 1;
928296341Sdelphij}
929238405Sjkim
930238405Sjkim/* See if a base and delta are compatible */
931238405Sjkim
932238405Sjkimstatic int check_delta_base(X509_CRL *delta, X509_CRL *base)
933296341Sdelphij{
934296341Sdelphij    /* Delta CRL must be a delta */
935296341Sdelphij    if (!delta->base_crl_number)
936296341Sdelphij        return 0;
937296341Sdelphij    /* Base must have a CRL number */
938296341Sdelphij    if (!base->crl_number)
939296341Sdelphij        return 0;
940296341Sdelphij    /* Issuer names must match */
941296341Sdelphij    if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta)))
942296341Sdelphij        return 0;
943296341Sdelphij    /* AKID and IDP must match */
944296341Sdelphij    if (!crl_extension_match(delta, base, NID_authority_key_identifier))
945296341Sdelphij        return 0;
946296341Sdelphij    if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
947296341Sdelphij        return 0;
948296341Sdelphij    /* Delta CRL base number must not exceed Full CRL number. */
949296341Sdelphij    if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
950296341Sdelphij        return 0;
951296341Sdelphij    /* Delta CRL number must exceed full CRL number */
952296341Sdelphij    if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
953296341Sdelphij        return 1;
954296341Sdelphij    return 0;
955296341Sdelphij}
956238405Sjkim
957296341Sdelphij/*
958296341Sdelphij * For a given base CRL find a delta... maybe extend to delta scoring or
959296341Sdelphij * retrieve a chain of deltas...
960238405Sjkim */
961238405Sjkim
962238405Sjkimstatic void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
963296341Sdelphij                         X509_CRL *base, STACK_OF(X509_CRL) *crls)
964296341Sdelphij{
965296341Sdelphij    X509_CRL *delta;
966296341Sdelphij    int i;
967296341Sdelphij    if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
968296341Sdelphij        return;
969296341Sdelphij    if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
970296341Sdelphij        return;
971296341Sdelphij    for (i = 0; i < sk_X509_CRL_num(crls); i++) {
972296341Sdelphij        delta = sk_X509_CRL_value(crls, i);
973296341Sdelphij        if (check_delta_base(delta, base)) {
974296341Sdelphij            if (check_crl_time(ctx, delta, 0))
975296341Sdelphij                *pscore |= CRL_SCORE_TIME_DELTA;
976296341Sdelphij            CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
977296341Sdelphij            *dcrl = delta;
978296341Sdelphij            return;
979296341Sdelphij        }
980296341Sdelphij    }
981296341Sdelphij    *dcrl = NULL;
982296341Sdelphij}
983160814Ssimon
984296341Sdelphij/*
985296341Sdelphij * For a given CRL return how suitable it is for the supplied certificate
986296341Sdelphij * 'x'. The return value is a mask of several criteria. If the issuer is not
987296341Sdelphij * the certificate issuer this is returned in *pissuer. The reasons mask is
988296341Sdelphij * also used to determine if the CRL is suitable: if no new reasons the CRL
989296341Sdelphij * is rejected, otherwise reasons is updated.
990238405Sjkim */
991160814Ssimon
992238405Sjkimstatic int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
993296341Sdelphij                         unsigned int *preasons, X509_CRL *crl, X509 *x)
994296341Sdelphij{
995238405Sjkim
996296341Sdelphij    int crl_score = 0;
997296341Sdelphij    unsigned int tmp_reasons = *preasons, crl_reasons;
998238405Sjkim
999296341Sdelphij    /* First see if we can reject CRL straight away */
1000238405Sjkim
1001296341Sdelphij    /* Invalid IDP cannot be processed */
1002296341Sdelphij    if (crl->idp_flags & IDP_INVALID)
1003296341Sdelphij        return 0;
1004296341Sdelphij    /* Reason codes or indirect CRLs need extended CRL support */
1005296341Sdelphij    if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
1006296341Sdelphij        if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
1007296341Sdelphij            return 0;
1008296341Sdelphij    } else if (crl->idp_flags & IDP_REASONS) {
1009296341Sdelphij        /* If no new reasons reject */
1010296341Sdelphij        if (!(crl->idp_reasons & ~tmp_reasons))
1011296341Sdelphij            return 0;
1012296341Sdelphij    }
1013296341Sdelphij    /* Don't process deltas at this stage */
1014296341Sdelphij    else if (crl->base_crl_number)
1015296341Sdelphij        return 0;
1016296341Sdelphij    /* If issuer name doesn't match certificate need indirect CRL */
1017296341Sdelphij    if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
1018296341Sdelphij        if (!(crl->idp_flags & IDP_INDIRECT))
1019296341Sdelphij            return 0;
1020296341Sdelphij    } else
1021296341Sdelphij        crl_score |= CRL_SCORE_ISSUER_NAME;
1022238405Sjkim
1023296341Sdelphij    if (!(crl->flags & EXFLAG_CRITICAL))
1024296341Sdelphij        crl_score |= CRL_SCORE_NOCRITICAL;
1025238405Sjkim
1026296341Sdelphij    /* Check expiry */
1027296341Sdelphij    if (check_crl_time(ctx, crl, 0))
1028296341Sdelphij        crl_score |= CRL_SCORE_TIME;
1029238405Sjkim
1030296341Sdelphij    /* Check authority key ID and locate certificate issuer */
1031296341Sdelphij    crl_akid_check(ctx, crl, pissuer, &crl_score);
1032238405Sjkim
1033296341Sdelphij    /* If we can't locate certificate issuer at this point forget it */
1034238405Sjkim
1035296341Sdelphij    if (!(crl_score & CRL_SCORE_AKID))
1036296341Sdelphij        return 0;
1037238405Sjkim
1038296341Sdelphij    /* Check cert for matching CRL distribution points */
1039238405Sjkim
1040296341Sdelphij    if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) {
1041296341Sdelphij        /* If no new reasons reject */
1042296341Sdelphij        if (!(crl_reasons & ~tmp_reasons))
1043296341Sdelphij            return 0;
1044296341Sdelphij        tmp_reasons |= crl_reasons;
1045296341Sdelphij        crl_score |= CRL_SCORE_SCOPE;
1046296341Sdelphij    }
1047238405Sjkim
1048296341Sdelphij    *preasons = tmp_reasons;
1049238405Sjkim
1050296341Sdelphij    return crl_score;
1051238405Sjkim
1052296341Sdelphij}
1053238405Sjkim
1054238405Sjkimstatic void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
1055296341Sdelphij                           X509 **pissuer, int *pcrl_score)
1056296341Sdelphij{
1057296341Sdelphij    X509 *crl_issuer = NULL;
1058296341Sdelphij    X509_NAME *cnm = X509_CRL_get_issuer(crl);
1059296341Sdelphij    int cidx = ctx->error_depth;
1060296341Sdelphij    int i;
1061238405Sjkim
1062296341Sdelphij    if (cidx != sk_X509_num(ctx->chain) - 1)
1063296341Sdelphij        cidx++;
1064238405Sjkim
1065296341Sdelphij    crl_issuer = sk_X509_value(ctx->chain, cidx);
1066238405Sjkim
1067296341Sdelphij    if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1068296341Sdelphij        if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
1069296341Sdelphij            *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT;
1070296341Sdelphij            *pissuer = crl_issuer;
1071296341Sdelphij            return;
1072296341Sdelphij        }
1073296341Sdelphij    }
1074238405Sjkim
1075296341Sdelphij    for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) {
1076296341Sdelphij        crl_issuer = sk_X509_value(ctx->chain, cidx);
1077296341Sdelphij        if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1078296341Sdelphij            continue;
1079296341Sdelphij        if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1080296341Sdelphij            *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
1081296341Sdelphij            *pissuer = crl_issuer;
1082296341Sdelphij            return;
1083296341Sdelphij        }
1084296341Sdelphij    }
1085238405Sjkim
1086296341Sdelphij    /* Anything else needs extended CRL support */
1087238405Sjkim
1088296341Sdelphij    if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
1089296341Sdelphij        return;
1090238405Sjkim
1091296341Sdelphij    /*
1092296341Sdelphij     * Otherwise the CRL issuer is not on the path. Look for it in the set of
1093296341Sdelphij     * untrusted certificates.
1094296341Sdelphij     */
1095296341Sdelphij    for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
1096296341Sdelphij        crl_issuer = sk_X509_value(ctx->untrusted, i);
1097296341Sdelphij        if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1098296341Sdelphij            continue;
1099296341Sdelphij        if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1100296341Sdelphij            *pissuer = crl_issuer;
1101296341Sdelphij            *pcrl_score |= CRL_SCORE_AKID;
1102296341Sdelphij            return;
1103296341Sdelphij        }
1104296341Sdelphij    }
1105296341Sdelphij}
1106238405Sjkim
1107296341Sdelphij/*
1108296341Sdelphij * Check the path of a CRL issuer certificate. This creates a new
1109238405Sjkim * X509_STORE_CTX and populates it with most of the parameters from the
1110296341Sdelphij * parent. This could be optimised somewhat since a lot of path checking will
1111296341Sdelphij * be duplicated by the parent, but this will rarely be used in practice.
1112238405Sjkim */
1113238405Sjkim
1114238405Sjkimstatic int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
1115296341Sdelphij{
1116296341Sdelphij    X509_STORE_CTX crl_ctx;
1117296341Sdelphij    int ret;
1118296341Sdelphij    /* Don't allow recursive CRL path validation */
1119296341Sdelphij    if (ctx->parent)
1120296341Sdelphij        return 0;
1121296341Sdelphij    if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
1122296341Sdelphij        return -1;
1123238405Sjkim
1124296341Sdelphij    crl_ctx.crls = ctx->crls;
1125296341Sdelphij    /* Copy verify params across */
1126296341Sdelphij    X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
1127238405Sjkim
1128296341Sdelphij    crl_ctx.parent = ctx;
1129296341Sdelphij    crl_ctx.verify_cb = ctx->verify_cb;
1130238405Sjkim
1131296341Sdelphij    /* Verify CRL issuer */
1132296341Sdelphij    ret = X509_verify_cert(&crl_ctx);
1133238405Sjkim
1134296341Sdelphij    if (ret <= 0)
1135296341Sdelphij        goto err;
1136238405Sjkim
1137296341Sdelphij    /* Check chain is acceptable */
1138238405Sjkim
1139296341Sdelphij    ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
1140296341Sdelphij err:
1141296341Sdelphij    X509_STORE_CTX_cleanup(&crl_ctx);
1142296341Sdelphij    return ret;
1143296341Sdelphij}
1144238405Sjkim
1145296341Sdelphij/*
1146296341Sdelphij * RFC3280 says nothing about the relationship between CRL path and
1147296341Sdelphij * certificate path, which could lead to situations where a certificate could
1148296341Sdelphij * be revoked or validated by a CA not authorised to do so. RFC5280 is more
1149296341Sdelphij * strict and states that the two paths must end in the same trust anchor,
1150296341Sdelphij * though some discussions remain... until this is resolved we use the
1151296341Sdelphij * RFC5280 version
1152238405Sjkim */
1153238405Sjkim
1154238405Sjkimstatic int check_crl_chain(X509_STORE_CTX *ctx,
1155296341Sdelphij                           STACK_OF(X509) *cert_path,
1156296341Sdelphij                           STACK_OF(X509) *crl_path)
1157296341Sdelphij{
1158296341Sdelphij    X509 *cert_ta, *crl_ta;
1159296341Sdelphij    cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
1160296341Sdelphij    crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
1161296341Sdelphij    if (!X509_cmp(cert_ta, crl_ta))
1162296341Sdelphij        return 1;
1163296341Sdelphij    return 0;
1164296341Sdelphij}
1165238405Sjkim
1166296341Sdelphij/*-
1167296341Sdelphij * Check for match between two dist point names: three separate cases.
1168238405Sjkim * 1. Both are relative names and compare X509_NAME types.
1169238405Sjkim * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
1170238405Sjkim * 3. Both are full names and compare two GENERAL_NAMES.
1171238405Sjkim * 4. One is NULL: automatic match.
1172238405Sjkim */
1173238405Sjkim
1174238405Sjkimstatic int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
1175296341Sdelphij{
1176296341Sdelphij    X509_NAME *nm = NULL;
1177296341Sdelphij    GENERAL_NAMES *gens = NULL;
1178296341Sdelphij    GENERAL_NAME *gena, *genb;
1179296341Sdelphij    int i, j;
1180296341Sdelphij    if (!a || !b)
1181296341Sdelphij        return 1;
1182296341Sdelphij    if (a->type == 1) {
1183296341Sdelphij        if (!a->dpname)
1184296341Sdelphij            return 0;
1185296341Sdelphij        /* Case 1: two X509_NAME */
1186296341Sdelphij        if (b->type == 1) {
1187296341Sdelphij            if (!b->dpname)
1188296341Sdelphij                return 0;
1189296341Sdelphij            if (!X509_NAME_cmp(a->dpname, b->dpname))
1190296341Sdelphij                return 1;
1191296341Sdelphij            else
1192296341Sdelphij                return 0;
1193296341Sdelphij        }
1194296341Sdelphij        /* Case 2: set name and GENERAL_NAMES appropriately */
1195296341Sdelphij        nm = a->dpname;
1196296341Sdelphij        gens = b->name.fullname;
1197296341Sdelphij    } else if (b->type == 1) {
1198296341Sdelphij        if (!b->dpname)
1199296341Sdelphij            return 0;
1200296341Sdelphij        /* Case 2: set name and GENERAL_NAMES appropriately */
1201296341Sdelphij        gens = a->name.fullname;
1202296341Sdelphij        nm = b->dpname;
1203296341Sdelphij    }
1204160814Ssimon
1205296341Sdelphij    /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
1206296341Sdelphij    if (nm) {
1207296341Sdelphij        for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
1208296341Sdelphij            gena = sk_GENERAL_NAME_value(gens, i);
1209296341Sdelphij            if (gena->type != GEN_DIRNAME)
1210296341Sdelphij                continue;
1211296341Sdelphij            if (!X509_NAME_cmp(nm, gena->d.directoryName))
1212296341Sdelphij                return 1;
1213296341Sdelphij        }
1214296341Sdelphij        return 0;
1215296341Sdelphij    }
1216238405Sjkim
1217296341Sdelphij    /* Else case 3: two GENERAL_NAMES */
1218238405Sjkim
1219296341Sdelphij    for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) {
1220296341Sdelphij        gena = sk_GENERAL_NAME_value(a->name.fullname, i);
1221296341Sdelphij        for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) {
1222296341Sdelphij            genb = sk_GENERAL_NAME_value(b->name.fullname, j);
1223296341Sdelphij            if (!GENERAL_NAME_cmp(gena, genb))
1224296341Sdelphij                return 1;
1225296341Sdelphij        }
1226296341Sdelphij    }
1227238405Sjkim
1228296341Sdelphij    return 0;
1229238405Sjkim
1230296341Sdelphij}
1231238405Sjkim
1232238405Sjkimstatic int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
1233296341Sdelphij{
1234296341Sdelphij    int i;
1235296341Sdelphij    X509_NAME *nm = X509_CRL_get_issuer(crl);
1236296341Sdelphij    /* If no CRLissuer return is successful iff don't need a match */
1237296341Sdelphij    if (!dp->CRLissuer)
1238296341Sdelphij        return ! !(crl_score & CRL_SCORE_ISSUER_NAME);
1239296341Sdelphij    for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
1240296341Sdelphij        GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
1241296341Sdelphij        if (gen->type != GEN_DIRNAME)
1242296341Sdelphij            continue;
1243296341Sdelphij        if (!X509_NAME_cmp(gen->d.directoryName, nm))
1244296341Sdelphij            return 1;
1245296341Sdelphij    }
1246296341Sdelphij    return 0;
1247296341Sdelphij}
1248238405Sjkim
1249238405Sjkim/* Check CRLDP and IDP */
1250238405Sjkim
1251238405Sjkimstatic int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
1252296341Sdelphij                           unsigned int *preasons)
1253296341Sdelphij{
1254296341Sdelphij    int i;
1255296341Sdelphij    if (crl->idp_flags & IDP_ONLYATTR)
1256296341Sdelphij        return 0;
1257296341Sdelphij    if (x->ex_flags & EXFLAG_CA) {
1258296341Sdelphij        if (crl->idp_flags & IDP_ONLYUSER)
1259296341Sdelphij            return 0;
1260296341Sdelphij    } else {
1261296341Sdelphij        if (crl->idp_flags & IDP_ONLYCA)
1262296341Sdelphij            return 0;
1263296341Sdelphij    }
1264296341Sdelphij    *preasons = crl->idp_reasons;
1265296341Sdelphij    for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
1266296341Sdelphij        DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
1267296341Sdelphij        if (crldp_check_crlissuer(dp, crl, crl_score)) {
1268296341Sdelphij            if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
1269296341Sdelphij                *preasons &= dp->dp_reasons;
1270296341Sdelphij                return 1;
1271296341Sdelphij            }
1272296341Sdelphij        }
1273296341Sdelphij    }
1274296341Sdelphij    if ((!crl->idp || !crl->idp->distpoint)
1275296341Sdelphij        && (crl_score & CRL_SCORE_ISSUER_NAME))
1276296341Sdelphij        return 1;
1277296341Sdelphij    return 0;
1278296341Sdelphij}
1279238405Sjkim
1280296341Sdelphij/*
1281296341Sdelphij * Retrieve CRL corresponding to current certificate. If deltas enabled try
1282296341Sdelphij * to find a delta CRL too
1283238405Sjkim */
1284296341Sdelphij
1285238405Sjkimstatic int get_crl_delta(X509_STORE_CTX *ctx,
1286296341Sdelphij                         X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
1287296341Sdelphij{
1288296341Sdelphij    int ok;
1289296341Sdelphij    X509 *issuer = NULL;
1290296341Sdelphij    int crl_score = 0;
1291296341Sdelphij    unsigned int reasons;
1292296341Sdelphij    X509_CRL *crl = NULL, *dcrl = NULL;
1293296341Sdelphij    STACK_OF(X509_CRL) *skcrl;
1294296341Sdelphij    X509_NAME *nm = X509_get_issuer_name(x);
1295296341Sdelphij    reasons = ctx->current_reasons;
1296296341Sdelphij    ok = get_crl_sk(ctx, &crl, &dcrl,
1297296341Sdelphij                    &issuer, &crl_score, &reasons, ctx->crls);
1298238405Sjkim
1299296341Sdelphij    if (ok)
1300296341Sdelphij        goto done;
1301238405Sjkim
1302296341Sdelphij    /* Lookup CRLs from store */
1303238405Sjkim
1304296341Sdelphij    skcrl = ctx->lookup_crls(ctx, nm);
1305238405Sjkim
1306296341Sdelphij    /* If no CRLs found and a near match from get_crl_sk use that */
1307296341Sdelphij    if (!skcrl && crl)
1308296341Sdelphij        goto done;
1309238405Sjkim
1310296341Sdelphij    get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
1311238405Sjkim
1312296341Sdelphij    sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
1313238405Sjkim
1314296341Sdelphij done:
1315238405Sjkim
1316296341Sdelphij    /* If we got any kind of CRL use it and return success */
1317296341Sdelphij    if (crl) {
1318296341Sdelphij        ctx->current_issuer = issuer;
1319296341Sdelphij        ctx->current_crl_score = crl_score;
1320296341Sdelphij        ctx->current_reasons = reasons;
1321296341Sdelphij        *pcrl = crl;
1322296341Sdelphij        *pdcrl = dcrl;
1323296341Sdelphij        return 1;
1324296341Sdelphij    }
1325238405Sjkim
1326296341Sdelphij    return 0;
1327296341Sdelphij}
1328109998Smarkm
1329109998Smarkm/* Check CRL validity */
1330109998Smarkmstatic int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
1331296341Sdelphij{
1332296341Sdelphij    X509 *issuer = NULL;
1333296341Sdelphij    EVP_PKEY *ikey = NULL;
1334296341Sdelphij    int ok = 0, chnum, cnum;
1335296341Sdelphij    cnum = ctx->error_depth;
1336296341Sdelphij    chnum = sk_X509_num(ctx->chain) - 1;
1337296341Sdelphij    /* if we have an alternative CRL issuer cert use that */
1338296341Sdelphij    if (ctx->current_issuer)
1339296341Sdelphij        issuer = ctx->current_issuer;
1340238405Sjkim
1341296341Sdelphij    /*
1342296341Sdelphij     * Else find CRL issuer: if not last certificate then issuer is next
1343296341Sdelphij     * certificate in chain.
1344296341Sdelphij     */
1345296341Sdelphij    else if (cnum < chnum)
1346296341Sdelphij        issuer = sk_X509_value(ctx->chain, cnum + 1);
1347296341Sdelphij    else {
1348296341Sdelphij        issuer = sk_X509_value(ctx->chain, chnum);
1349296341Sdelphij        /* If not self signed, can't check signature */
1350296341Sdelphij        if (!ctx->check_issued(ctx, issuer, issuer)) {
1351296341Sdelphij            ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
1352296341Sdelphij            ok = ctx->verify_cb(0, ctx);
1353296341Sdelphij            if (!ok)
1354296341Sdelphij                goto err;
1355296341Sdelphij        }
1356296341Sdelphij    }
1357109998Smarkm
1358296341Sdelphij    if (issuer) {
1359296341Sdelphij        /*
1360296341Sdelphij         * Skip most tests for deltas because they have already been done
1361296341Sdelphij         */
1362296341Sdelphij        if (!crl->base_crl_number) {
1363296341Sdelphij            /* Check for cRLSign bit if keyUsage present */
1364296341Sdelphij            if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
1365296341Sdelphij                !(issuer->ex_kusage & KU_CRL_SIGN)) {
1366296341Sdelphij                ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
1367296341Sdelphij                ok = ctx->verify_cb(0, ctx);
1368296341Sdelphij                if (!ok)
1369296341Sdelphij                    goto err;
1370296341Sdelphij            }
1371238405Sjkim
1372296341Sdelphij            if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
1373296341Sdelphij                ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
1374296341Sdelphij                ok = ctx->verify_cb(0, ctx);
1375296341Sdelphij                if (!ok)
1376296341Sdelphij                    goto err;
1377296341Sdelphij            }
1378238405Sjkim
1379296341Sdelphij            if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
1380296341Sdelphij                if (check_crl_path(ctx, ctx->current_issuer) <= 0) {
1381296341Sdelphij                    ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
1382296341Sdelphij                    ok = ctx->verify_cb(0, ctx);
1383296341Sdelphij                    if (!ok)
1384296341Sdelphij                        goto err;
1385296341Sdelphij                }
1386296341Sdelphij            }
1387238405Sjkim
1388296341Sdelphij            if (crl->idp_flags & IDP_INVALID) {
1389296341Sdelphij                ctx->error = X509_V_ERR_INVALID_EXTENSION;
1390296341Sdelphij                ok = ctx->verify_cb(0, ctx);
1391296341Sdelphij                if (!ok)
1392296341Sdelphij                    goto err;
1393296341Sdelphij            }
1394238405Sjkim
1395296341Sdelphij        }
1396238405Sjkim
1397296341Sdelphij        if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
1398296341Sdelphij            ok = check_crl_time(ctx, crl, 1);
1399296341Sdelphij            if (!ok)
1400296341Sdelphij                goto err;
1401296341Sdelphij        }
1402109998Smarkm
1403296341Sdelphij        /* Attempt to get issuer certificate public key */
1404296341Sdelphij        ikey = X509_get_pubkey(issuer);
1405238405Sjkim
1406296341Sdelphij        if (!ikey) {
1407296341Sdelphij            ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
1408296341Sdelphij            ok = ctx->verify_cb(0, ctx);
1409296341Sdelphij            if (!ok)
1410296341Sdelphij                goto err;
1411296341Sdelphij        } else {
1412296341Sdelphij            /* Verify CRL signature */
1413296341Sdelphij            if (X509_CRL_verify(crl, ikey) <= 0) {
1414296341Sdelphij                ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
1415296341Sdelphij                ok = ctx->verify_cb(0, ctx);
1416296341Sdelphij                if (!ok)
1417296341Sdelphij                    goto err;
1418296341Sdelphij            }
1419296341Sdelphij        }
1420296341Sdelphij    }
1421109998Smarkm
1422296341Sdelphij    ok = 1;
1423109998Smarkm
1424296341Sdelphij err:
1425296341Sdelphij    EVP_PKEY_free(ikey);
1426296341Sdelphij    return ok;
1427296341Sdelphij}
1428109998Smarkm
1429109998Smarkm/* Check certificate against CRL */
1430109998Smarkmstatic int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
1431296341Sdelphij{
1432296341Sdelphij    int ok;
1433296341Sdelphij    X509_REVOKED *rev;
1434296341Sdelphij    /*
1435296341Sdelphij     * The rules changed for this... previously if a CRL contained unhandled
1436296341Sdelphij     * critical extensions it could still be used to indicate a certificate
1437296341Sdelphij     * was revoked. This has since been changed since critical extension can
1438296341Sdelphij     * change the meaning of CRL entries.
1439296341Sdelphij     */
1440296341Sdelphij    if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
1441296341Sdelphij        && (crl->flags & EXFLAG_CRITICAL)) {
1442296341Sdelphij        ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
1443296341Sdelphij        ok = ctx->verify_cb(0, ctx);
1444296341Sdelphij        if (!ok)
1445296341Sdelphij            return 0;
1446296341Sdelphij    }
1447296341Sdelphij    /*
1448296341Sdelphij     * Look for serial number of certificate in CRL If found make sure reason
1449296341Sdelphij     * is not removeFromCRL.
1450296341Sdelphij     */
1451296341Sdelphij    if (X509_CRL_get0_by_cert(crl, &rev, x)) {
1452296341Sdelphij        if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
1453296341Sdelphij            return 2;
1454296341Sdelphij        ctx->error = X509_V_ERR_CERT_REVOKED;
1455296341Sdelphij        ok = ctx->verify_cb(0, ctx);
1456296341Sdelphij        if (!ok)
1457296341Sdelphij            return 0;
1458296341Sdelphij    }
1459127128Snectar
1460296341Sdelphij    return 1;
1461296341Sdelphij}
1462109998Smarkm
1463160814Ssimonstatic int check_policy(X509_STORE_CTX *ctx)
1464296341Sdelphij{
1465296341Sdelphij    int ret;
1466296341Sdelphij    if (ctx->parent)
1467296341Sdelphij        return 1;
1468296341Sdelphij    ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
1469296341Sdelphij                            ctx->param->policies, ctx->param->flags);
1470296341Sdelphij    if (ret == 0) {
1471296341Sdelphij        X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE);
1472296341Sdelphij        return 0;
1473296341Sdelphij    }
1474296341Sdelphij    /* Invalid or inconsistent extensions */
1475296341Sdelphij    if (ret == -1) {
1476296341Sdelphij        /*
1477296341Sdelphij         * Locate certificates with bad extensions and notify callback.
1478296341Sdelphij         */
1479296341Sdelphij        X509 *x;
1480296341Sdelphij        int i;
1481296341Sdelphij        for (i = 1; i < sk_X509_num(ctx->chain); i++) {
1482296341Sdelphij            x = sk_X509_value(ctx->chain, i);
1483296341Sdelphij            if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
1484296341Sdelphij                continue;
1485296341Sdelphij            ctx->current_cert = x;
1486296341Sdelphij            ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
1487296341Sdelphij            if (!ctx->verify_cb(0, ctx))
1488296341Sdelphij                return 0;
1489296341Sdelphij        }
1490296341Sdelphij        return 1;
1491296341Sdelphij    }
1492296341Sdelphij    if (ret == -2) {
1493296341Sdelphij        ctx->current_cert = NULL;
1494296341Sdelphij        ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
1495296341Sdelphij        return ctx->verify_cb(0, ctx);
1496296341Sdelphij    }
1497160814Ssimon
1498296341Sdelphij    if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
1499296341Sdelphij        ctx->current_cert = NULL;
1500296341Sdelphij        ctx->error = X509_V_OK;
1501296341Sdelphij        if (!ctx->verify_cb(2, ctx))
1502296341Sdelphij            return 0;
1503296341Sdelphij    }
1504160814Ssimon
1505296341Sdelphij    return 1;
1506296341Sdelphij}
1507160814Ssimon
1508160814Ssimonstatic int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
1509296341Sdelphij{
1510296341Sdelphij    time_t *ptime;
1511296341Sdelphij    int i;
1512160814Ssimon
1513296341Sdelphij    if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
1514296341Sdelphij        ptime = &ctx->param->check_time;
1515296341Sdelphij    else
1516296341Sdelphij        ptime = NULL;
1517160814Ssimon
1518296341Sdelphij    i = X509_cmp_time(X509_get_notBefore(x), ptime);
1519296341Sdelphij    if (i == 0) {
1520296341Sdelphij        ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
1521296341Sdelphij        ctx->current_cert = x;
1522296341Sdelphij        if (!ctx->verify_cb(0, ctx))
1523296341Sdelphij            return 0;
1524296341Sdelphij    }
1525160814Ssimon
1526296341Sdelphij    if (i > 0) {
1527296341Sdelphij        ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
1528296341Sdelphij        ctx->current_cert = x;
1529296341Sdelphij        if (!ctx->verify_cb(0, ctx))
1530296341Sdelphij            return 0;
1531296341Sdelphij    }
1532160814Ssimon
1533296341Sdelphij    i = X509_cmp_time(X509_get_notAfter(x), ptime);
1534296341Sdelphij    if (i == 0) {
1535296341Sdelphij        ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
1536296341Sdelphij        ctx->current_cert = x;
1537296341Sdelphij        if (!ctx->verify_cb(0, ctx))
1538296341Sdelphij            return 0;
1539296341Sdelphij    }
1540160814Ssimon
1541296341Sdelphij    if (i < 0) {
1542296341Sdelphij        ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
1543296341Sdelphij        ctx->current_cert = x;
1544296341Sdelphij        if (!ctx->verify_cb(0, ctx))
1545296341Sdelphij            return 0;
1546296341Sdelphij    }
1547160814Ssimon
1548296341Sdelphij    return 1;
1549296341Sdelphij}
1550160814Ssimon
155155714Skrisstatic int internal_verify(X509_STORE_CTX *ctx)
1552296341Sdelphij{
1553296341Sdelphij    int ok = 0, n;
1554296341Sdelphij    X509 *xs, *xi;
1555296341Sdelphij    EVP_PKEY *pkey = NULL;
1556296341Sdelphij    int (*cb) (int xok, X509_STORE_CTX *xctx);
155755714Skris
1558296341Sdelphij    cb = ctx->verify_cb;
155955714Skris
1560296341Sdelphij    n = sk_X509_num(ctx->chain);
1561296341Sdelphij    ctx->error_depth = n - 1;
1562296341Sdelphij    n--;
1563296341Sdelphij    xi = sk_X509_value(ctx->chain, n);
1564160814Ssimon
1565296341Sdelphij    if (ctx->check_issued(ctx, xi, xi))
1566296341Sdelphij        xs = xi;
1567296341Sdelphij    else {
1568296341Sdelphij        if (n <= 0) {
1569296341Sdelphij            ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
1570296341Sdelphij            ctx->current_cert = xi;
1571296341Sdelphij            ok = cb(0, ctx);
1572296341Sdelphij            goto end;
1573296341Sdelphij        } else {
1574296341Sdelphij            n--;
1575296341Sdelphij            ctx->error_depth = n;
1576296341Sdelphij            xs = sk_X509_value(ctx->chain, n);
1577296341Sdelphij        }
1578296341Sdelphij    }
157955714Skris
1580296341Sdelphij/*      ctx->error=0;  not needed */
1581296341Sdelphij    while (n >= 0) {
1582296341Sdelphij        ctx->error_depth = n;
1583205128Ssimon
1584296341Sdelphij        /*
1585296341Sdelphij         * Skip signature check for self signed certificates unless
1586296341Sdelphij         * explicitly asked for. It doesn't add any security and just wastes
1587296341Sdelphij         * time.
1588296341Sdelphij         */
1589296341Sdelphij        if (!xs->valid
1590296341Sdelphij            && (xs != xi
1591296341Sdelphij                || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) {
1592296341Sdelphij            if ((pkey = X509_get_pubkey(xi)) == NULL) {
1593296341Sdelphij                ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
1594296341Sdelphij                ctx->current_cert = xi;
1595296341Sdelphij                ok = (*cb) (0, ctx);
1596296341Sdelphij                if (!ok)
1597296341Sdelphij                    goto end;
1598296341Sdelphij            } else if (X509_verify(xs, pkey) <= 0) {
1599296341Sdelphij                ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
1600296341Sdelphij                ctx->current_cert = xs;
1601296341Sdelphij                ok = (*cb) (0, ctx);
1602296341Sdelphij                if (!ok) {
1603296341Sdelphij                    EVP_PKEY_free(pkey);
1604296341Sdelphij                    goto end;
1605296341Sdelphij                }
1606296341Sdelphij            }
1607296341Sdelphij            EVP_PKEY_free(pkey);
1608296341Sdelphij            pkey = NULL;
1609296341Sdelphij        }
161055714Skris
1611296341Sdelphij        xs->valid = 1;
161255714Skris
1613296341Sdelphij        ok = check_cert_time(ctx, xs);
1614296341Sdelphij        if (!ok)
1615296341Sdelphij            goto end;
161655714Skris
1617296341Sdelphij        /* The last error (if any) is still in the error value */
1618296341Sdelphij        ctx->current_issuer = xi;
1619296341Sdelphij        ctx->current_cert = xs;
1620296341Sdelphij        ok = (*cb) (1, ctx);
1621296341Sdelphij        if (!ok)
1622296341Sdelphij            goto end;
162355714Skris
1624296341Sdelphij        n--;
1625296341Sdelphij        if (n >= 0) {
1626296341Sdelphij            xi = xs;
1627296341Sdelphij            xs = sk_X509_value(ctx->chain, n);
1628296341Sdelphij        }
1629296341Sdelphij    }
1630296341Sdelphij    ok = 1;
1631296341Sdelphij end:
1632296341Sdelphij    return ok;
1633296341Sdelphij}
163455714Skris
1635238405Sjkimint X509_cmp_current_time(const ASN1_TIME *ctm)
163668651Skris{
1637296341Sdelphij    return X509_cmp_time(ctm, NULL);
163868651Skris}
163968651Skris
1640238405Sjkimint X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
1641284295Sdelphij{
1642296341Sdelphij    char *str;
1643296341Sdelphij    ASN1_TIME atm;
1644296341Sdelphij    long offset;
1645284295Sdelphij    char buff1[24], buff2[24], *p;
1646284295Sdelphij    int i, j, remaining;
164755714Skris
1648284295Sdelphij    p = buff1;
1649284295Sdelphij    remaining = ctm->length;
1650284295Sdelphij    str = (char *)ctm->data;
1651284295Sdelphij    /*
1652284295Sdelphij     * Note that the following (historical) code allows much more slack in the
1653284295Sdelphij     * time format than RFC5280. In RFC5280, the representation is fixed:
1654284295Sdelphij     * UTCTime: YYMMDDHHMMSSZ
1655284295Sdelphij     * GeneralizedTime: YYYYMMDDHHMMSSZ
1656284295Sdelphij     */
1657284295Sdelphij    if (ctm->type == V_ASN1_UTCTIME) {
1658284295Sdelphij        /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
1659284295Sdelphij        int min_length = sizeof("YYMMDDHHMMZ") - 1;
1660284295Sdelphij        int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
1661284295Sdelphij        if (remaining < min_length || remaining > max_length)
1662284295Sdelphij            return 0;
1663284295Sdelphij        memcpy(p, str, 10);
1664284295Sdelphij        p += 10;
1665284295Sdelphij        str += 10;
1666284295Sdelphij        remaining -= 10;
1667284295Sdelphij    } else {
1668284295Sdelphij        /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
1669284295Sdelphij        int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
1670284295Sdelphij        int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
1671284295Sdelphij        if (remaining < min_length || remaining > max_length)
1672284295Sdelphij            return 0;
1673284295Sdelphij        memcpy(p, str, 12);
1674284295Sdelphij        p += 12;
1675284295Sdelphij        str += 12;
1676284295Sdelphij        remaining -= 12;
1677296341Sdelphij    }
167855714Skris
1679284295Sdelphij    if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
1680284295Sdelphij        *(p++) = '0';
1681284295Sdelphij        *(p++) = '0';
1682284295Sdelphij    } else {
1683284295Sdelphij        /* SS (seconds) */
1684284295Sdelphij        if (remaining < 2)
1685284295Sdelphij            return 0;
1686284295Sdelphij        *(p++) = *(str++);
1687284295Sdelphij        *(p++) = *(str++);
1688284295Sdelphij        remaining -= 2;
1689284295Sdelphij        /*
1690284295Sdelphij         * Skip any (up to three) fractional seconds...
1691284295Sdelphij         * TODO(emilia): in RFC5280, fractional seconds are forbidden.
1692284295Sdelphij         * Can we just kill them altogether?
1693284295Sdelphij         */
1694284295Sdelphij        if (remaining && *str == '.') {
1695296341Sdelphij            str++;
1696284295Sdelphij            remaining--;
1697284295Sdelphij            for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
1698284295Sdelphij                if (*str < '0' || *str > '9')
1699284295Sdelphij                    break;
1700296341Sdelphij            }
1701296341Sdelphij        }
170255714Skris
1703284295Sdelphij    }
1704284295Sdelphij    *(p++) = 'Z';
1705284295Sdelphij    *(p++) = '\0';
1706284295Sdelphij
1707284295Sdelphij    /* We now need either a terminating 'Z' or an offset. */
1708284295Sdelphij    if (!remaining)
1709284295Sdelphij        return 0;
1710284295Sdelphij    if (*str == 'Z') {
1711284295Sdelphij        if (remaining != 1)
1712284295Sdelphij            return 0;
1713284295Sdelphij        offset = 0;
1714284295Sdelphij    } else {
1715284295Sdelphij        /* (+-)HHMM */
1716296341Sdelphij        if ((*str != '+') && (*str != '-'))
1717296341Sdelphij            return 0;
1718284295Sdelphij        /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
1719284295Sdelphij        if (remaining != 5)
1720284295Sdelphij            return 0;
1721284295Sdelphij        if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
1722284295Sdelphij            str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
1723284295Sdelphij            return 0;
1724284295Sdelphij        offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
1725284295Sdelphij        offset += (str[3] - '0') * 10 + (str[4] - '0');
1726296341Sdelphij        if (*str == '-')
1727284295Sdelphij            offset = -offset;
1728296341Sdelphij    }
1729284295Sdelphij    atm.type = ctm->type;
1730296341Sdelphij    atm.flags = 0;
1731284295Sdelphij    atm.length = sizeof(buff2);
1732284295Sdelphij    atm.data = (unsigned char *)buff2;
173355714Skris
1734284295Sdelphij    if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
1735296341Sdelphij        return 0;
173655714Skris
1737284295Sdelphij    if (ctm->type == V_ASN1_UTCTIME) {
1738284295Sdelphij        i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
1739284295Sdelphij        if (i < 50)
1740284295Sdelphij            i += 100;           /* cf. RFC 2459 */
1741284295Sdelphij        j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
1742284295Sdelphij        if (j < 50)
1743284295Sdelphij            j += 100;
174455714Skris
1745284295Sdelphij        if (i < j)
1746284295Sdelphij            return -1;
1747284295Sdelphij        if (i > j)
1748284295Sdelphij            return 1;
1749296341Sdelphij    }
1750284295Sdelphij    i = strcmp(buff1, buff2);
1751296341Sdelphij    if (i == 0)                 /* wait a second then return younger :-) */
1752296341Sdelphij        return -1;
1753296341Sdelphij    else
1754296341Sdelphij        return i;
1755284295Sdelphij}
175655714Skris
175768651SkrisASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
175868651Skris{
1759296341Sdelphij    return X509_time_adj(s, adj, NULL);
176068651Skris}
176168651Skris
1762238405SjkimASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
1763296341Sdelphij{
1764296341Sdelphij    return X509_time_adj_ex(s, 0, offset_sec, in_tm);
1765296341Sdelphij}
1766238405Sjkim
1767238405SjkimASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
1768296341Sdelphij                            int offset_day, long offset_sec, time_t *in_tm)
1769296341Sdelphij{
1770296341Sdelphij    time_t t;
177155714Skris
1772296341Sdelphij    if (in_tm)
1773296341Sdelphij        t = *in_tm;
1774296341Sdelphij    else
1775296341Sdelphij        time(&t);
177668651Skris
1777296341Sdelphij    if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) {
1778296341Sdelphij        if (s->type == V_ASN1_UTCTIME)
1779296341Sdelphij            return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
1780296341Sdelphij        if (s->type == V_ASN1_GENERALIZEDTIME)
1781296341Sdelphij            return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
1782296341Sdelphij    }
1783296341Sdelphij    return ASN1_TIME_adj(s, t, offset_day, offset_sec);
1784296341Sdelphij}
178555714Skris
178655714Skrisint X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
1787296341Sdelphij{
1788296341Sdelphij    EVP_PKEY *ktmp = NULL, *ktmp2;
1789296341Sdelphij    int i, j;
179055714Skris
1791296341Sdelphij    if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey))
1792296341Sdelphij        return 1;
179355714Skris
1794296341Sdelphij    for (i = 0; i < sk_X509_num(chain); i++) {
1795296341Sdelphij        ktmp = X509_get_pubkey(sk_X509_value(chain, i));
1796296341Sdelphij        if (ktmp == NULL) {
1797296341Sdelphij            X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
1798296341Sdelphij                    X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
1799296341Sdelphij            return 0;
1800296341Sdelphij        }
1801296341Sdelphij        if (!EVP_PKEY_missing_parameters(ktmp))
1802296341Sdelphij            break;
1803296341Sdelphij        else {
1804296341Sdelphij            EVP_PKEY_free(ktmp);
1805296341Sdelphij            ktmp = NULL;
1806296341Sdelphij        }
1807296341Sdelphij    }
1808296341Sdelphij    if (ktmp == NULL) {
1809296341Sdelphij        X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
1810296341Sdelphij                X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
1811296341Sdelphij        return 0;
1812296341Sdelphij    }
181355714Skris
1814296341Sdelphij    /* first, populate the other certs */
1815296341Sdelphij    for (j = i - 1; j >= 0; j--) {
1816296341Sdelphij        ktmp2 = X509_get_pubkey(sk_X509_value(chain, j));
1817296341Sdelphij        EVP_PKEY_copy_parameters(ktmp2, ktmp);
1818296341Sdelphij        EVP_PKEY_free(ktmp2);
1819296341Sdelphij    }
182055714Skris
1821296341Sdelphij    if (pkey != NULL)
1822296341Sdelphij        EVP_PKEY_copy_parameters(pkey, ktmp);
1823296341Sdelphij    EVP_PKEY_free(ktmp);
1824296341Sdelphij    return 1;
1825296341Sdelphij}
182655714Skris
1827296341Sdelphijint X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
1828296341Sdelphij                                    CRYPTO_EX_new *new_func,
1829296341Sdelphij                                    CRYPTO_EX_dup *dup_func,
1830296341Sdelphij                                    CRYPTO_EX_free *free_func)
1831296341Sdelphij{
1832296341Sdelphij    /*
1833296341Sdelphij     * This function is (usually) called only once, by
1834296341Sdelphij     * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c).
1835296341Sdelphij     */
1836296341Sdelphij    return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp,
1837296341Sdelphij                                   new_func, dup_func, free_func);
1838296341Sdelphij}
1839296341Sdelphij
184055714Skrisint X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
1841296341Sdelphij{
1842296341Sdelphij    return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
1843296341Sdelphij}
184455714Skris
184555714Skrisvoid *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
1846296341Sdelphij{
1847296341Sdelphij    return CRYPTO_get_ex_data(&ctx->ex_data, idx);
1848296341Sdelphij}
184955714Skris
185055714Skrisint X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
1851296341Sdelphij{
1852296341Sdelphij    return ctx->error;
1853296341Sdelphij}
185455714Skris
185555714Skrisvoid X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
1856296341Sdelphij{
1857296341Sdelphij    ctx->error = err;
1858296341Sdelphij}
185955714Skris
186055714Skrisint X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
1861296341Sdelphij{
1862296341Sdelphij    return ctx->error_depth;
1863296341Sdelphij}
186455714Skris
186555714SkrisX509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
1866296341Sdelphij{
1867296341Sdelphij    return ctx->current_cert;
1868296341Sdelphij}
186955714Skris
187055714SkrisSTACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
1871296341Sdelphij{
1872296341Sdelphij    return ctx->chain;
1873296341Sdelphij}
187455714Skris
187559191SkrisSTACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
1876296341Sdelphij{
1877296341Sdelphij    int i;
1878296341Sdelphij    X509 *x;
1879296341Sdelphij    STACK_OF(X509) *chain;
1880296341Sdelphij    if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain)))
1881296341Sdelphij        return NULL;
1882296341Sdelphij    for (i = 0; i < sk_X509_num(chain); i++) {
1883296341Sdelphij        x = sk_X509_value(chain, i);
1884296341Sdelphij        CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
1885296341Sdelphij    }
1886296341Sdelphij    return chain;
1887296341Sdelphij}
188859191Skris
1889238405SjkimX509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
1890296341Sdelphij{
1891296341Sdelphij    return ctx->current_issuer;
1892296341Sdelphij}
1893238405Sjkim
1894238405SjkimX509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
1895296341Sdelphij{
1896296341Sdelphij    return ctx->current_crl;
1897296341Sdelphij}
1898238405Sjkim
1899238405SjkimX509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
1900296341Sdelphij{
1901296341Sdelphij    return ctx->parent;
1902296341Sdelphij}
1903238405Sjkim
190455714Skrisvoid X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
1905296341Sdelphij{
1906296341Sdelphij    ctx->cert = x;
1907296341Sdelphij}
190855714Skris
190955714Skrisvoid X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
1910296341Sdelphij{
1911296341Sdelphij    ctx->untrusted = sk;
1912296341Sdelphij}
191355714Skris
1914160814Ssimonvoid X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
1915296341Sdelphij{
1916296341Sdelphij    ctx->crls = sk;
1917296341Sdelphij}
1918160814Ssimon
191959191Skrisint X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
1920296341Sdelphij{
1921296341Sdelphij    return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
1922296341Sdelphij}
192359191Skris
192459191Skrisint X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
1925296341Sdelphij{
1926296341Sdelphij    return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
1927296341Sdelphij}
192859191Skris
1929296341Sdelphij/*
1930296341Sdelphij * This function is used to set the X509_STORE_CTX purpose and trust values.
1931296341Sdelphij * This is intended to be used when another structure has its own trust and
1932296341Sdelphij * purpose values which (if set) will be inherited by the ctx. If they aren't
1933296341Sdelphij * set then we will usually have a default purpose in mind which should then
1934296341Sdelphij * be used to set the trust value. An example of this is SSL use: an SSL
1935296341Sdelphij * structure will have its own purpose and trust settings which the
1936296341Sdelphij * application can set: if they aren't set then we use the default of SSL
1937296341Sdelphij * client/server.
193859191Skris */
193959191Skris
194059191Skrisint X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
1941296341Sdelphij                                   int purpose, int trust)
194259191Skris{
1943296341Sdelphij    int idx;
1944296341Sdelphij    /* If purpose not set use default */
1945296341Sdelphij    if (!purpose)
1946296341Sdelphij        purpose = def_purpose;
1947296341Sdelphij    /* If we have a purpose then check it is valid */
1948296341Sdelphij    if (purpose) {
1949296341Sdelphij        X509_PURPOSE *ptmp;
1950296341Sdelphij        idx = X509_PURPOSE_get_by_id(purpose);
1951296341Sdelphij        if (idx == -1) {
1952296341Sdelphij            X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1953296341Sdelphij                    X509_R_UNKNOWN_PURPOSE_ID);
1954296341Sdelphij            return 0;
1955296341Sdelphij        }
1956296341Sdelphij        ptmp = X509_PURPOSE_get0(idx);
1957296341Sdelphij        if (ptmp->trust == X509_TRUST_DEFAULT) {
1958296341Sdelphij            idx = X509_PURPOSE_get_by_id(def_purpose);
1959296341Sdelphij            if (idx == -1) {
1960296341Sdelphij                X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1961296341Sdelphij                        X509_R_UNKNOWN_PURPOSE_ID);
1962296341Sdelphij                return 0;
1963296341Sdelphij            }
1964296341Sdelphij            ptmp = X509_PURPOSE_get0(idx);
1965296341Sdelphij        }
1966296341Sdelphij        /* If trust not set then get from purpose default */
1967296341Sdelphij        if (!trust)
1968296341Sdelphij            trust = ptmp->trust;
1969296341Sdelphij    }
1970296341Sdelphij    if (trust) {
1971296341Sdelphij        idx = X509_TRUST_get_by_id(trust);
1972296341Sdelphij        if (idx == -1) {
1973296341Sdelphij            X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1974296341Sdelphij                    X509_R_UNKNOWN_TRUST_ID);
1975296341Sdelphij            return 0;
1976296341Sdelphij        }
1977296341Sdelphij    }
197859191Skris
1979296341Sdelphij    if (purpose && !ctx->param->purpose)
1980296341Sdelphij        ctx->param->purpose = purpose;
1981296341Sdelphij    if (trust && !ctx->param->trust)
1982296341Sdelphij        ctx->param->trust = trust;
1983296341Sdelphij    return 1;
198459191Skris}
198559191Skris
198668651SkrisX509_STORE_CTX *X509_STORE_CTX_new(void)
198768651Skris{
1988296341Sdelphij    X509_STORE_CTX *ctx;
1989296341Sdelphij    ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
1990296341Sdelphij    if (!ctx) {
1991296341Sdelphij        X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE);
1992296341Sdelphij        return NULL;
1993296341Sdelphij    }
1994296341Sdelphij    memset(ctx, 0, sizeof(X509_STORE_CTX));
1995296341Sdelphij    return ctx;
199668651Skris}
199759191Skris
199868651Skrisvoid X509_STORE_CTX_free(X509_STORE_CTX *ctx)
199968651Skris{
2000296341Sdelphij    if (!ctx)
2001296341Sdelphij        return;
2002296341Sdelphij    X509_STORE_CTX_cleanup(ctx);
2003296341Sdelphij    OPENSSL_free(ctx);
200468651Skris}
200568651Skris
2006109998Smarkmint X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
2007296341Sdelphij                        STACK_OF(X509) *chain)
2008296341Sdelphij{
2009296341Sdelphij    int ret = 1;
2010296341Sdelphij    ctx->ctx = store;
2011296341Sdelphij    ctx->current_method = 0;
2012296341Sdelphij    ctx->cert = x509;
2013296341Sdelphij    ctx->untrusted = chain;
2014296341Sdelphij    ctx->crls = NULL;
2015296341Sdelphij    ctx->last_untrusted = 0;
2016296341Sdelphij    ctx->other_ctx = NULL;
2017296341Sdelphij    ctx->valid = 0;
2018296341Sdelphij    ctx->chain = NULL;
2019296341Sdelphij    ctx->error = 0;
2020296341Sdelphij    ctx->explicit_policy = 0;
2021296341Sdelphij    ctx->error_depth = 0;
2022296341Sdelphij    ctx->current_cert = NULL;
2023296341Sdelphij    ctx->current_issuer = NULL;
2024296341Sdelphij    ctx->current_crl = NULL;
2025296341Sdelphij    ctx->current_crl_score = 0;
2026296341Sdelphij    ctx->current_reasons = 0;
2027296341Sdelphij    ctx->tree = NULL;
2028296341Sdelphij    ctx->parent = NULL;
2029109998Smarkm
2030296341Sdelphij    ctx->param = X509_VERIFY_PARAM_new();
2031160814Ssimon
2032296341Sdelphij    if (!ctx->param) {
2033296341Sdelphij        X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
2034296341Sdelphij        return 0;
2035296341Sdelphij    }
2036160814Ssimon
2037296341Sdelphij    /*
2038296341Sdelphij     * Inherit callbacks and flags from X509_STORE if not set use defaults.
2039296341Sdelphij     */
2040109998Smarkm
2041296341Sdelphij    if (store)
2042296341Sdelphij        ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
2043296341Sdelphij    else
2044296341Sdelphij        ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
2045109998Smarkm
2046296341Sdelphij    if (store) {
2047296341Sdelphij        ctx->verify_cb = store->verify_cb;
2048296341Sdelphij        ctx->cleanup = store->cleanup;
2049296341Sdelphij    } else
2050296341Sdelphij        ctx->cleanup = 0;
2051160814Ssimon
2052296341Sdelphij    if (ret)
2053296341Sdelphij        ret = X509_VERIFY_PARAM_inherit(ctx->param,
2054296341Sdelphij                                        X509_VERIFY_PARAM_lookup("default"));
2055160814Ssimon
2056296341Sdelphij    if (ret == 0) {
2057296341Sdelphij        X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
2058296341Sdelphij        return 0;
2059296341Sdelphij    }
2060160814Ssimon
2061296341Sdelphij    if (store && store->check_issued)
2062296341Sdelphij        ctx->check_issued = store->check_issued;
2063296341Sdelphij    else
2064296341Sdelphij        ctx->check_issued = check_issued;
2065109998Smarkm
2066296341Sdelphij    if (store && store->get_issuer)
2067296341Sdelphij        ctx->get_issuer = store->get_issuer;
2068296341Sdelphij    else
2069296341Sdelphij        ctx->get_issuer = X509_STORE_CTX_get1_issuer;
2070109998Smarkm
2071296341Sdelphij    if (store && store->verify_cb)
2072296341Sdelphij        ctx->verify_cb = store->verify_cb;
2073296341Sdelphij    else
2074296341Sdelphij        ctx->verify_cb = null_callback;
2075109998Smarkm
2076296341Sdelphij    if (store && store->verify)
2077296341Sdelphij        ctx->verify = store->verify;
2078296341Sdelphij    else
2079296341Sdelphij        ctx->verify = internal_verify;
2080109998Smarkm
2081296341Sdelphij    if (store && store->check_revocation)
2082296341Sdelphij        ctx->check_revocation = store->check_revocation;
2083296341Sdelphij    else
2084296341Sdelphij        ctx->check_revocation = check_revocation;
2085109998Smarkm
2086296341Sdelphij    if (store && store->get_crl)
2087296341Sdelphij        ctx->get_crl = store->get_crl;
2088296341Sdelphij    else
2089296341Sdelphij        ctx->get_crl = NULL;
2090109998Smarkm
2091296341Sdelphij    if (store && store->check_crl)
2092296341Sdelphij        ctx->check_crl = store->check_crl;
2093296341Sdelphij    else
2094296341Sdelphij        ctx->check_crl = check_crl;
2095109998Smarkm
2096296341Sdelphij    if (store && store->cert_crl)
2097296341Sdelphij        ctx->cert_crl = store->cert_crl;
2098296341Sdelphij    else
2099296341Sdelphij        ctx->cert_crl = cert_crl;
2100109998Smarkm
2101296341Sdelphij    if (store && store->lookup_certs)
2102296341Sdelphij        ctx->lookup_certs = store->lookup_certs;
2103296341Sdelphij    else
2104296341Sdelphij        ctx->lookup_certs = X509_STORE_get1_certs;
2105109998Smarkm
2106296341Sdelphij    if (store && store->lookup_crls)
2107296341Sdelphij        ctx->lookup_crls = store->lookup_crls;
2108296341Sdelphij    else
2109296341Sdelphij        ctx->lookup_crls = X509_STORE_get1_crls;
2110238405Sjkim
2111296341Sdelphij    ctx->check_policy = check_policy;
2112238405Sjkim
2113296341Sdelphij    /*
2114296341Sdelphij     * This memset() can't make any sense anyway, so it's removed. As
2115296341Sdelphij     * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a
2116296341Sdelphij     * corresponding "new" here and remove this bogus initialisation.
2117296341Sdelphij     */
2118296341Sdelphij    /* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */
2119296341Sdelphij    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
2120296341Sdelphij                            &(ctx->ex_data))) {
2121296341Sdelphij        OPENSSL_free(ctx);
2122296341Sdelphij        X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
2123296341Sdelphij        return 0;
2124296341Sdelphij    }
2125296341Sdelphij    return 1;
2126296341Sdelphij}
2127109998Smarkm
2128296341Sdelphij/*
2129296341Sdelphij * Set alternative lookup method: just a STACK of trusted certificates. This
2130296341Sdelphij * avoids X509_STORE nastiness where it isn't needed.
213168651Skris */
213268651Skris
213368651Skrisvoid X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
213468651Skris{
2135296341Sdelphij    ctx->other_ctx = sk;
2136296341Sdelphij    ctx->get_issuer = get_issuer_sk;
213768651Skris}
213868651Skris
213968651Skrisvoid X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
2140296341Sdelphij{
2141296341Sdelphij    if (ctx->cleanup)
2142296341Sdelphij        ctx->cleanup(ctx);
2143296341Sdelphij    if (ctx->param != NULL) {
2144296341Sdelphij        if (ctx->parent == NULL)
2145296341Sdelphij            X509_VERIFY_PARAM_free(ctx->param);
2146296341Sdelphij        ctx->param = NULL;
2147296341Sdelphij    }
2148296341Sdelphij    if (ctx->tree != NULL) {
2149296341Sdelphij        X509_policy_tree_free(ctx->tree);
2150296341Sdelphij        ctx->tree = NULL;
2151296341Sdelphij    }
2152296341Sdelphij    if (ctx->chain != NULL) {
2153296341Sdelphij        sk_X509_pop_free(ctx->chain, X509_free);
2154296341Sdelphij        ctx->chain = NULL;
2155296341Sdelphij    }
2156296341Sdelphij    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data));
2157296341Sdelphij    memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
2158296341Sdelphij}
215968651Skris
2160160814Ssimonvoid X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
2161296341Sdelphij{
2162296341Sdelphij    X509_VERIFY_PARAM_set_depth(ctx->param, depth);
2163296341Sdelphij}
216468651Skris
2165160814Ssimonvoid X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
2166296341Sdelphij{
2167296341Sdelphij    X509_VERIFY_PARAM_set_flags(ctx->param, flags);
2168296341Sdelphij}
216968651Skris
2170296341Sdelphijvoid X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
2171296341Sdelphij                             time_t t)
2172296341Sdelphij{
2173296341Sdelphij    X509_VERIFY_PARAM_set_time(ctx->param, t);
2174296341Sdelphij}
2175160814Ssimon
217689837Skrisvoid X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
2177296341Sdelphij                                  int (*verify_cb) (int, X509_STORE_CTX *))
2178296341Sdelphij{
2179296341Sdelphij    ctx->verify_cb = verify_cb;
2180296341Sdelphij}
218189837Skris
2182160814SsimonX509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
2183296341Sdelphij{
2184296341Sdelphij    return ctx->tree;
2185296341Sdelphij}
2186160814Ssimon
2187160814Ssimonint X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
2188296341Sdelphij{
2189296341Sdelphij    return ctx->explicit_policy;
2190296341Sdelphij}
2191160814Ssimon
2192160814Ssimonint X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
2193296341Sdelphij{
2194296341Sdelphij    const X509_VERIFY_PARAM *param;
2195296341Sdelphij    param = X509_VERIFY_PARAM_lookup(name);
2196296341Sdelphij    if (!param)
2197296341Sdelphij        return 0;
2198296341Sdelphij    return X509_VERIFY_PARAM_inherit(ctx->param, param);
2199296341Sdelphij}
2200160814Ssimon
2201160814SsimonX509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
2202296341Sdelphij{
2203296341Sdelphij    return ctx->param;
2204296341Sdelphij}
2205160814Ssimon
2206160814Ssimonvoid X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
2207296341Sdelphij{
2208296341Sdelphij    if (ctx->param)
2209296341Sdelphij        X509_VERIFY_PARAM_free(ctx->param);
2210296341Sdelphij    ctx->param = param;
2211296341Sdelphij}
2212160814Ssimon
221355714SkrisIMPLEMENT_STACK_OF(X509)
2214296341Sdelphij
221555714SkrisIMPLEMENT_ASN1_SET_OF(X509)
221655714Skris
221755714SkrisIMPLEMENT_STACK_OF(X509_NAME)
221855714Skris
221955714SkrisIMPLEMENT_STACK_OF(X509_ATTRIBUTE)
2220296341Sdelphij
222155714SkrisIMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
2222