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.
8280304Sjkim *
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).
15280304Sjkim *
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.
22280304Sjkim *
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 :-).
37280304Sjkim * 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)"
40280304Sjkim *
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.
52280304Sjkim *
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
77280304Sjkim#define CRL_SCORE_NOCRITICAL    0x100
78238405Sjkim
79238405Sjkim/* certificate is within CRL scope */
80238405Sjkim
81280304Sjkim#define CRL_SCORE_SCOPE         0x080
82238405Sjkim
83238405Sjkim/* CRL times valid */
84238405Sjkim
85280304Sjkim#define CRL_SCORE_TIME          0x040
86238405Sjkim
87238405Sjkim/* Issuer name matches certificate */
88238405Sjkim
89280304Sjkim#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
97280304Sjkim#define CRL_SCORE_ISSUER_CERT   0x018
98238405Sjkim
99238405Sjkim/* CRL issuer is on certificate path */
100238405Sjkim
101280304Sjkim#define CRL_SCORE_SAME_PATH     0x008
102238405Sjkim
103238405Sjkim/* CRL issuer matches CRL AKID */
104238405Sjkim
105280304Sjkim#define CRL_SCORE_AKID          0x004
106238405Sjkim
107238405Sjkim/* Have a delta CRL with valid times */
108238405Sjkim
109280304Sjkim#define CRL_SCORE_TIME_DELTA    0x002
110238405Sjkim
111280304Sjkimstatic 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,
122280304Sjkim                         unsigned int *preasons, X509_CRL *crl, X509 *x);
123238405Sjkimstatic int get_crl_delta(X509_STORE_CTX *ctx,
124280304Sjkim                         X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
125280304Sjkimstatic void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl,
126280304Sjkim                         int *pcrl_score, X509_CRL *base,
127280304Sjkim                         STACK_OF(X509_CRL) *crls);
128280304Sjkimstatic void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
129280304Sjkim                           int *pcrl_score);
130238405Sjkimstatic int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
131280304Sjkim                           unsigned int *preasons);
132238405Sjkimstatic int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
133238405Sjkimstatic int check_crl_chain(X509_STORE_CTX *ctx,
134280304Sjkim                           STACK_OF(X509) *cert_path,
135280304Sjkim                           STACK_OF(X509) *crl_path);
136238405Sjkim
13755714Skrisstatic int internal_verify(X509_STORE_CTX *ctx);
138280304Sjkimconst char X509_version[] = "X.509" OPENSSL_VERSION_PTEXT;
13955714Skris
14055714Skrisstatic int null_callback(int ok, X509_STORE_CTX *e)
141280304Sjkim{
142280304Sjkim    return ok;
143280304Sjkim}
14455714Skris
14555714Skris#if 0
14655714Skrisstatic int x509_subject_cmp(X509 **a, X509 **b)
147280304Sjkim{
148280304Sjkim    return X509_subject_name_cmp(*a, *b);
149280304Sjkim}
15055714Skris#endif
15155714Skris
15255714Skrisint X509_verify_cert(X509_STORE_CTX *ctx)
153280304Sjkim{
154284285Sjkim    X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
155280304Sjkim    int bad_chain = 0;
156280304Sjkim    X509_VERIFY_PARAM *param = ctx->param;
157280304Sjkim    int depth, i, ok = 0;
158284285Sjkim    int num, j, retry;
159280304Sjkim    int (*cb) (int xok, X509_STORE_CTX *xctx);
160280304Sjkim    STACK_OF(X509) *sktmp = NULL;
161280304Sjkim    if (ctx->cert == NULL) {
162280304Sjkim        X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
163280304Sjkim        return -1;
164280304Sjkim    }
165285330Sjkim    if (ctx->chain != NULL) {
166285330Sjkim        /*
167285330Sjkim         * This X509_STORE_CTX has already been used to verify a cert. We
168285330Sjkim         * cannot do another one.
169285330Sjkim         */
170285330Sjkim        X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
171285330Sjkim        return -1;
172285330Sjkim    }
17355714Skris
174280304Sjkim    cb = ctx->verify_cb;
17555714Skris
176280304Sjkim    /*
177280304Sjkim     * first we make sure the chain we are going to build is present and that
178280304Sjkim     * the first entry is in place
179280304Sjkim     */
180285330Sjkim    if (((ctx->chain = sk_X509_new_null()) == NULL) ||
181285330Sjkim        (!sk_X509_push(ctx->chain, ctx->cert))) {
182285330Sjkim        X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
183285330Sjkim        goto end;
184280304Sjkim    }
185285330Sjkim    CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509);
186285330Sjkim    ctx->last_untrusted = 1;
18755714Skris
188280304Sjkim    /* We use a temporary STACK so we can chop and hack at it */
189280304Sjkim    if (ctx->untrusted != NULL
190280304Sjkim        && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
191280304Sjkim        X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
192280304Sjkim        goto end;
193280304Sjkim    }
19455714Skris
195280304Sjkim    num = sk_X509_num(ctx->chain);
196280304Sjkim    x = sk_X509_value(ctx->chain, num - 1);
197280304Sjkim    depth = param->depth;
19855714Skris
199280304Sjkim    for (;;) {
200280304Sjkim        /* If we have enough, we break */
201280304Sjkim        if (depth < num)
202280304Sjkim            break;              /* FIXME: If this happens, we should take
203280304Sjkim                                 * note of it and, if appropriate, use the
204280304Sjkim                                 * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
205280304Sjkim                                 * later. */
20655714Skris
207280304Sjkim        /* If we are self signed, we break */
208280304Sjkim        if (ctx->check_issued(ctx, x, x))
209280304Sjkim            break;
21055714Skris
211280304Sjkim        /* If we were passed a cert chain, use it first */
212280304Sjkim        if (ctx->untrusted != NULL) {
213280304Sjkim            xtmp = find_issuer(ctx, sktmp, x);
214280304Sjkim            if (xtmp != NULL) {
215280304Sjkim                if (!sk_X509_push(ctx->chain, xtmp)) {
216280304Sjkim                    X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
217280304Sjkim                    goto end;
218280304Sjkim                }
219280304Sjkim                CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509);
220280304Sjkim                (void)sk_X509_delete_ptr(sktmp, xtmp);
221280304Sjkim                ctx->last_untrusted++;
222280304Sjkim                x = xtmp;
223280304Sjkim                num++;
224280304Sjkim                /*
225280304Sjkim                 * reparse the full chain for the next one
226280304Sjkim                 */
227280304Sjkim                continue;
228280304Sjkim            }
229280304Sjkim        }
230280304Sjkim        break;
231280304Sjkim    }
23255714Skris
233284285Sjkim    /* Remember how many untrusted certs we have */
234284285Sjkim    j = num;
235280304Sjkim    /*
236280304Sjkim     * at this point, chain should contain a list of untrusted certificates.
237280304Sjkim     * We now need to add at least one trusted one, if possible, otherwise we
238280304Sjkim     * complain.
239280304Sjkim     */
24055714Skris
241284285Sjkim    do {
242284285Sjkim        /*
243284285Sjkim         * Examine last certificate in chain and see if it is self signed.
244284285Sjkim         */
245284285Sjkim        i = sk_X509_num(ctx->chain);
246284285Sjkim        x = sk_X509_value(ctx->chain, i - 1);
247284285Sjkim        if (ctx->check_issued(ctx, x, x)) {
248284285Sjkim            /* we have a self signed certificate */
249284285Sjkim            if (sk_X509_num(ctx->chain) == 1) {
250284285Sjkim                /*
251284285Sjkim                 * We have a single self signed certificate: see if we can
252284285Sjkim                 * find it in the store. We must have an exact match to avoid
253284285Sjkim                 * possible impersonation.
254284285Sjkim                 */
255284285Sjkim                ok = ctx->get_issuer(&xtmp, ctx, x);
256284285Sjkim                if ((ok <= 0) || X509_cmp(x, xtmp)) {
257284285Sjkim                    ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
258284285Sjkim                    ctx->current_cert = x;
259284285Sjkim                    ctx->error_depth = i - 1;
260284285Sjkim                    if (ok == 1)
261284285Sjkim                        X509_free(xtmp);
262284285Sjkim                    bad_chain = 1;
263284285Sjkim                    ok = cb(0, ctx);
264284285Sjkim                    if (!ok)
265284285Sjkim                        goto end;
266284285Sjkim                } else {
267284285Sjkim                    /*
268284285Sjkim                     * We have a match: replace certificate with store
269284285Sjkim                     * version so we get any trust settings.
270284285Sjkim                     */
271284285Sjkim                    X509_free(x);
272284285Sjkim                    x = xtmp;
273284285Sjkim                    (void)sk_X509_set(ctx->chain, i - 1, x);
274284285Sjkim                    ctx->last_untrusted = 0;
275284285Sjkim                }
276280304Sjkim            } else {
277280304Sjkim                /*
278284285Sjkim                 * extract and save self signed certificate for later use
279280304Sjkim                 */
280284285Sjkim                chain_ss = sk_X509_pop(ctx->chain);
281284285Sjkim                ctx->last_untrusted--;
282284285Sjkim                num--;
283284285Sjkim                j--;
284284285Sjkim                x = sk_X509_value(ctx->chain, num - 1);
285280304Sjkim            }
286280304Sjkim        }
287284285Sjkim        /* We now lookup certs from the certificate store */
288284285Sjkim        for (;;) {
289284285Sjkim            /* If we have enough, we break */
290284285Sjkim            if (depth < num)
291284285Sjkim                break;
292284285Sjkim            /* If we are self signed, we break */
293284285Sjkim            if (ctx->check_issued(ctx, x, x))
294284285Sjkim                break;
295284285Sjkim            ok = ctx->get_issuer(&xtmp, ctx, x);
296284285Sjkim            if (ok < 0)
297284285Sjkim                return ok;
298284285Sjkim            if (ok == 0)
299284285Sjkim                break;
300284285Sjkim            x = xtmp;
301284285Sjkim            if (!sk_X509_push(ctx->chain, x)) {
302284285Sjkim                X509_free(xtmp);
303284285Sjkim                X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
304284285Sjkim                return 0;
305284285Sjkim            }
306284285Sjkim            num++;
307284285Sjkim        }
30868651Skris
309284285Sjkim        /*
310284285Sjkim         * If we haven't got a least one certificate from our store then check
311284285Sjkim         * if there is an alternative chain that could be used.  We only do this
312284285Sjkim         * if the user hasn't switched off alternate chain checking
313284285Sjkim         */
314284285Sjkim        retry = 0;
315285330Sjkim        if (num == ctx->last_untrusted &&
316284285Sjkim            !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
317284285Sjkim            while (j-- > 1) {
318284285Sjkim                xtmp2 = sk_X509_value(ctx->chain, j - 1);
319284285Sjkim                ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
320284285Sjkim                if (ok < 0)
321284285Sjkim                    goto end;
322284285Sjkim                /* Check if we found an alternate chain */
323284285Sjkim                if (ok > 0) {
324284285Sjkim                    /*
325284285Sjkim                     * Free up the found cert we'll add it again later
326284285Sjkim                     */
327284285Sjkim                    X509_free(xtmp);
32855714Skris
329284285Sjkim                    /*
330284285Sjkim                     * Dump all the certs above this point - we've found an
331284285Sjkim                     * alternate chain
332284285Sjkim                     */
333284285Sjkim                    while (num > j) {
334284285Sjkim                        xtmp = sk_X509_pop(ctx->chain);
335284285Sjkim                        X509_free(xtmp);
336284285Sjkim                        num--;
337284285Sjkim                    }
338285330Sjkim                    ctx->last_untrusted = sk_X509_num(ctx->chain);
339284285Sjkim                    retry = 1;
340284285Sjkim                    break;
341284285Sjkim                }
342284285Sjkim            }
343280304Sjkim        }
344284285Sjkim    } while (retry);
34568651Skris
346280304Sjkim    /* Is last certificate looked up self signed? */
347280304Sjkim    if (!ctx->check_issued(ctx, x, x)) {
348280304Sjkim        if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
349280304Sjkim            if (ctx->last_untrusted >= num)
350280304Sjkim                ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
351280304Sjkim            else
352280304Sjkim                ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
353280304Sjkim            ctx->current_cert = x;
354280304Sjkim        } else {
35568651Skris
356280304Sjkim            sk_X509_push(ctx->chain, chain_ss);
357280304Sjkim            num++;
358280304Sjkim            ctx->last_untrusted = num;
359280304Sjkim            ctx->current_cert = chain_ss;
360280304Sjkim            ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
361280304Sjkim            chain_ss = NULL;
362280304Sjkim        }
36355714Skris
364280304Sjkim        ctx->error_depth = num - 1;
365280304Sjkim        bad_chain = 1;
366280304Sjkim        ok = cb(0, ctx);
367280304Sjkim        if (!ok)
368280304Sjkim            goto end;
369280304Sjkim    }
37055714Skris
371280304Sjkim    /* We have the chain complete: now we need to check its purpose */
372280304Sjkim    ok = check_chain_extensions(ctx);
37355714Skris
374280304Sjkim    if (!ok)
375280304Sjkim        goto end;
37659191Skris
377280304Sjkim    /* Check name constraints */
37859191Skris
379280304Sjkim    ok = check_name_constraints(ctx);
380238405Sjkim
381280304Sjkim    if (!ok)
382280304Sjkim        goto end;
383238405Sjkim
384280304Sjkim    /* The chain extensions are OK: check trust */
38559191Skris
386280304Sjkim    if (param->trust > 0)
387280304Sjkim        ok = check_trust(ctx);
38859191Skris
389280304Sjkim    if (!ok)
390280304Sjkim        goto end;
39159191Skris
392280304Sjkim    /* We may as well copy down any DSA parameters that are required */
393280304Sjkim    X509_get_pubkey_parameters(NULL, ctx->chain);
39455714Skris
395280304Sjkim    /*
396280304Sjkim     * Check revocation status: we do this after copying parameters because
397280304Sjkim     * they may be needed for CRL signature verification.
398280304Sjkim     */
399109998Smarkm
400280304Sjkim    ok = ctx->check_revocation(ctx);
401280304Sjkim    if (!ok)
402280304Sjkim        goto end;
403109998Smarkm
404280304Sjkim    /* At this point, we have a chain and need to verify it */
405280304Sjkim    if (ctx->verify != NULL)
406280304Sjkim        ok = ctx->verify(ctx);
407280304Sjkim    else
408280304Sjkim        ok = internal_verify(ctx);
409280304Sjkim    if (!ok)
410280304Sjkim        goto end;
411160814Ssimon
412167612Ssimon#ifndef OPENSSL_NO_RFC3779
413280304Sjkim    /* RFC 3779 path validation, now that CRL check has been done */
414280304Sjkim    ok = v3_asid_validate_path(ctx);
415280304Sjkim    if (!ok)
416280304Sjkim        goto end;
417280304Sjkim    ok = v3_addr_validate_path(ctx);
418280304Sjkim    if (!ok)
419280304Sjkim        goto end;
420167612Ssimon#endif
421167612Ssimon
422280304Sjkim    /* If we get this far evaluate policies */
423280304Sjkim    if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
424280304Sjkim        ok = ctx->check_policy(ctx);
425280304Sjkim    if (!ok)
426280304Sjkim        goto end;
427280304Sjkim    if (0) {
428280304Sjkim end:
429280304Sjkim        X509_get_pubkey_parameters(NULL, ctx->chain);
430280304Sjkim    }
431280304Sjkim    if (sktmp != NULL)
432280304Sjkim        sk_X509_free(sktmp);
433280304Sjkim    if (chain_ss != NULL)
434280304Sjkim        X509_free(chain_ss);
435280304Sjkim    return ok;
436280304Sjkim}
43755714Skris
438280304Sjkim/*
439280304Sjkim * 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{
444280304Sjkim    int i;
445280304Sjkim    X509 *issuer;
446280304Sjkim    for (i = 0; i < sk_X509_num(sk); i++) {
447280304Sjkim        issuer = sk_X509_value(sk, i);
448280304Sjkim        if (ctx->check_issued(ctx, x, issuer))
449280304Sjkim            return issuer;
450280304Sjkim    }
451280304Sjkim    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{
458280304Sjkim    int ret;
459280304Sjkim    ret = X509_check_issued(issuer, x);
460280304Sjkim    if (ret == X509_V_OK)
461280304Sjkim        return 1;
462280304Sjkim    /* If we haven't asked for issuer errors don't set ctx */
463280304Sjkim    if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
464280304Sjkim        return 0;
46568651Skris
466280304Sjkim    ctx->error = ret;
467280304Sjkim    ctx->current_cert = x;
468280304Sjkim    ctx->current_issuer = issuer;
469280304Sjkim    return ctx->verify_cb(0, ctx);
470280304Sjkim    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{
477280304Sjkim    *issuer = find_issuer(ctx, ctx->other_ctx, x);
478280304Sjkim    if (*issuer) {
479280304Sjkim        CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
480280304Sjkim        return 1;
481280304Sjkim    } else
482280304Sjkim        return 0;
48368651Skris}
48468651Skris
485280304Sjkim/*
486280304Sjkim * Check a certificate chains extensions for consistency with the supplied
487280304Sjkim * purpose
48859191Skris */
48959191Skris
490160814Ssimonstatic int check_chain_extensions(X509_STORE_CTX *ctx)
49159191Skris{
492109998Smarkm#ifdef OPENSSL_NO_CHAIN_VERIFY
493280304Sjkim    return 1;
49459191Skris#else
495280304Sjkim    int i, ok = 0, must_be_ca, plen = 0;
496280304Sjkim    X509 *x;
497280304Sjkim    int (*cb) (int xok, X509_STORE_CTX *xctx);
498280304Sjkim    int proxy_path_length = 0;
499280304Sjkim    int purpose;
500280304Sjkim    int allow_proxy_certs;
501280304Sjkim    cb = ctx->verify_cb;
502160814Ssimon
503280304Sjkim    /*-
504280304Sjkim     *  must_be_ca can have 1 of 3 values:
505280304Sjkim     * -1: we accept both CA and non-CA certificates, to allow direct
506280304Sjkim     *     use of self-signed certificates (which are marked as CA).
507280304Sjkim     * 0:  we only accept non-CA certificates.  This is currently not
508280304Sjkim     *     used, but the possibility is present for future extensions.
509280304Sjkim     * 1:  we only accept CA certificates.  This is currently used for
510280304Sjkim     *     all certificates in the chain except the leaf certificate.
511280304Sjkim     */
512280304Sjkim    must_be_ca = -1;
513160814Ssimon
514280304Sjkim    /* CRL path validation */
515280304Sjkim    if (ctx->parent) {
516280304Sjkim        allow_proxy_certs = 0;
517280304Sjkim        purpose = X509_PURPOSE_CRL_SIGN;
518280304Sjkim    } else {
519280304Sjkim        allow_proxy_certs =
520280304Sjkim            ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
521280304Sjkim        /*
522280304Sjkim         * A hack to keep people who don't want to modify their software
523280304Sjkim         * happy
524280304Sjkim         */
525280304Sjkim        if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
526280304Sjkim            allow_proxy_certs = 1;
527280304Sjkim        purpose = ctx->param->purpose;
528280304Sjkim    }
529160814Ssimon
530280304Sjkim    /* Check all untrusted certificates */
531280304Sjkim    for (i = 0; i < ctx->last_untrusted; i++) {
532280304Sjkim        int ret;
533280304Sjkim        x = sk_X509_value(ctx->chain, i);
534280304Sjkim        if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
535280304Sjkim            && (x->ex_flags & EXFLAG_CRITICAL)) {
536280304Sjkim            ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
537280304Sjkim            ctx->error_depth = i;
538280304Sjkim            ctx->current_cert = x;
539280304Sjkim            ok = cb(0, ctx);
540280304Sjkim            if (!ok)
541280304Sjkim                goto end;
542280304Sjkim        }
543280304Sjkim        if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
544280304Sjkim            ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
545280304Sjkim            ctx->error_depth = i;
546280304Sjkim            ctx->current_cert = x;
547280304Sjkim            ok = cb(0, ctx);
548280304Sjkim            if (!ok)
549280304Sjkim                goto end;
550280304Sjkim        }
551280304Sjkim        ret = X509_check_ca(x);
552280304Sjkim        switch (must_be_ca) {
553280304Sjkim        case -1:
554280304Sjkim            if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
555280304Sjkim                && (ret != 1) && (ret != 0)) {
556280304Sjkim                ret = 0;
557280304Sjkim                ctx->error = X509_V_ERR_INVALID_CA;
558280304Sjkim            } else
559280304Sjkim                ret = 1;
560280304Sjkim            break;
561280304Sjkim        case 0:
562280304Sjkim            if (ret != 0) {
563280304Sjkim                ret = 0;
564280304Sjkim                ctx->error = X509_V_ERR_INVALID_NON_CA;
565280304Sjkim            } else
566280304Sjkim                ret = 1;
567280304Sjkim            break;
568280304Sjkim        default:
569280304Sjkim            if ((ret == 0)
570280304Sjkim                || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
571280304Sjkim                    && (ret != 1))) {
572280304Sjkim                ret = 0;
573280304Sjkim                ctx->error = X509_V_ERR_INVALID_CA;
574280304Sjkim            } else
575280304Sjkim                ret = 1;
576280304Sjkim            break;
577280304Sjkim        }
578280304Sjkim        if (ret == 0) {
579280304Sjkim            ctx->error_depth = i;
580280304Sjkim            ctx->current_cert = x;
581280304Sjkim            ok = cb(0, ctx);
582280304Sjkim            if (!ok)
583280304Sjkim                goto end;
584280304Sjkim        }
585280304Sjkim        if (ctx->param->purpose > 0) {
586280304Sjkim            ret = X509_check_purpose(x, purpose, must_be_ca > 0);
587280304Sjkim            if ((ret == 0)
588280304Sjkim                || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
589280304Sjkim                    && (ret != 1))) {
590280304Sjkim                ctx->error = X509_V_ERR_INVALID_PURPOSE;
591280304Sjkim                ctx->error_depth = i;
592280304Sjkim                ctx->current_cert = x;
593280304Sjkim                ok = cb(0, ctx);
594280304Sjkim                if (!ok)
595280304Sjkim                    goto end;
596280304Sjkim            }
597280304Sjkim        }
598280304Sjkim        /* Check pathlen if not self issued */
599280304Sjkim        if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
600280304Sjkim            && (x->ex_pathlen != -1)
601280304Sjkim            && (plen > (x->ex_pathlen + proxy_path_length + 1))) {
602280304Sjkim            ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
603280304Sjkim            ctx->error_depth = i;
604280304Sjkim            ctx->current_cert = x;
605280304Sjkim            ok = cb(0, ctx);
606280304Sjkim            if (!ok)
607280304Sjkim                goto end;
608280304Sjkim        }
609280304Sjkim        /* Increment path length if not self issued */
610280304Sjkim        if (!(x->ex_flags & EXFLAG_SI))
611280304Sjkim            plen++;
612280304Sjkim        /*
613280304Sjkim         * If this certificate is a proxy certificate, the next certificate
614280304Sjkim         * must be another proxy certificate or a EE certificate.  If not,
615280304Sjkim         * the next certificate must be a CA certificate.
616280304Sjkim         */
617280304Sjkim        if (x->ex_flags & EXFLAG_PROXY) {
618280304Sjkim            if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
619280304Sjkim                ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
620280304Sjkim                ctx->error_depth = i;
621280304Sjkim                ctx->current_cert = x;
622280304Sjkim                ok = cb(0, ctx);
623280304Sjkim                if (!ok)
624280304Sjkim                    goto end;
625280304Sjkim            }
626280304Sjkim            proxy_path_length++;
627280304Sjkim            must_be_ca = 0;
628280304Sjkim        } else
629280304Sjkim            must_be_ca = 1;
630280304Sjkim    }
631280304Sjkim    ok = 1;
63268651Skris end:
633280304Sjkim    return ok;
63459191Skris#endif
63559191Skris}
63659191Skris
637238405Sjkimstatic int check_name_constraints(X509_STORE_CTX *ctx)
638280304Sjkim{
639280304Sjkim    X509 *x;
640280304Sjkim    int i, j, rv;
641280304Sjkim    /* Check name constraints for all certificates */
642280304Sjkim    for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) {
643280304Sjkim        x = sk_X509_value(ctx->chain, i);
644280304Sjkim        /* Ignore self issued certs unless last in chain */
645280304Sjkim        if (i && (x->ex_flags & EXFLAG_SI))
646280304Sjkim            continue;
647280304Sjkim        /*
648280304Sjkim         * Check against constraints for all certificates higher in chain
649280304Sjkim         * including trust anchor. Trust anchor not strictly speaking needed
650280304Sjkim         * but if it includes constraints it is to be assumed it expects them
651280304Sjkim         * to be obeyed.
652280304Sjkim         */
653280304Sjkim        for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
654280304Sjkim            NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
655280304Sjkim            if (nc) {
656280304Sjkim                rv = NAME_CONSTRAINTS_check(x, nc);
657280304Sjkim                if (rv != X509_V_OK) {
658280304Sjkim                    ctx->error = rv;
659280304Sjkim                    ctx->error_depth = i;
660280304Sjkim                    ctx->current_cert = x;
661280304Sjkim                    if (!ctx->verify_cb(0, ctx))
662280304Sjkim                        return 0;
663280304Sjkim                }
664280304Sjkim            }
665280304Sjkim        }
666280304Sjkim    }
667280304Sjkim    return 1;
668280304Sjkim}
669238405Sjkim
67059191Skrisstatic int check_trust(X509_STORE_CTX *ctx)
67159191Skris{
672109998Smarkm#ifdef OPENSSL_NO_CHAIN_VERIFY
673280304Sjkim    return 1;
67459191Skris#else
675280304Sjkim    int i, ok;
676280304Sjkim    X509 *x;
677280304Sjkim    int (*cb) (int xok, X509_STORE_CTX *xctx);
678280304Sjkim    cb = ctx->verify_cb;
67959191Skris/* For now just check the last certificate in the chain */
680280304Sjkim    i = sk_X509_num(ctx->chain) - 1;
681280304Sjkim    x = sk_X509_value(ctx->chain, i);
682280304Sjkim    ok = X509_check_trust(x, ctx->param->trust, 0);
683280304Sjkim    if (ok == X509_TRUST_TRUSTED)
684280304Sjkim        return 1;
685280304Sjkim    ctx->error_depth = i;
686280304Sjkim    ctx->current_cert = x;
687280304Sjkim    if (ok == X509_TRUST_REJECTED)
688280304Sjkim        ctx->error = X509_V_ERR_CERT_REJECTED;
689280304Sjkim    else
690280304Sjkim        ctx->error = X509_V_ERR_CERT_UNTRUSTED;
691280304Sjkim    ok = cb(0, ctx);
692280304Sjkim    return ok;
69359191Skris#endif
69459191Skris}
69559191Skris
696109998Smarkmstatic int check_revocation(X509_STORE_CTX *ctx)
697280304Sjkim{
698280304Sjkim    int i, last, ok;
699280304Sjkim    if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
700280304Sjkim        return 1;
701280304Sjkim    if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
702280304Sjkim        last = sk_X509_num(ctx->chain) - 1;
703280304Sjkim    else {
704280304Sjkim        /* If checking CRL paths this isn't the EE certificate */
705280304Sjkim        if (ctx->parent)
706280304Sjkim            return 1;
707280304Sjkim        last = 0;
708280304Sjkim    }
709280304Sjkim    for (i = 0; i <= last; i++) {
710280304Sjkim        ctx->error_depth = i;
711280304Sjkim        ok = check_cert(ctx);
712280304Sjkim        if (!ok)
713280304Sjkim            return ok;
714280304Sjkim    }
715280304Sjkim    return 1;
716280304Sjkim}
717109998Smarkm
718109998Smarkmstatic int check_cert(X509_STORE_CTX *ctx)
719280304Sjkim{
720280304Sjkim    X509_CRL *crl = NULL, *dcrl = NULL;
721280304Sjkim    X509 *x;
722280304Sjkim    int ok, cnum;
723280304Sjkim    unsigned int last_reasons;
724280304Sjkim    cnum = ctx->error_depth;
725280304Sjkim    x = sk_X509_value(ctx->chain, cnum);
726280304Sjkim    ctx->current_cert = x;
727280304Sjkim    ctx->current_issuer = NULL;
728280304Sjkim    ctx->current_crl_score = 0;
729280304Sjkim    ctx->current_reasons = 0;
730280304Sjkim    while (ctx->current_reasons != CRLDP_ALL_REASONS) {
731280304Sjkim        last_reasons = ctx->current_reasons;
732280304Sjkim        /* Try to retrieve relevant CRL */
733280304Sjkim        if (ctx->get_crl)
734280304Sjkim            ok = ctx->get_crl(ctx, &crl, x);
735280304Sjkim        else
736280304Sjkim            ok = get_crl_delta(ctx, &crl, &dcrl, x);
737280304Sjkim        /*
738280304Sjkim         * If error looking up CRL, nothing we can do except notify callback
739280304Sjkim         */
740280304Sjkim        if (!ok) {
741280304Sjkim            ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
742280304Sjkim            ok = ctx->verify_cb(0, ctx);
743280304Sjkim            goto err;
744280304Sjkim        }
745280304Sjkim        ctx->current_crl = crl;
746280304Sjkim        ok = ctx->check_crl(ctx, crl);
747280304Sjkim        if (!ok)
748280304Sjkim            goto err;
749238405Sjkim
750280304Sjkim        if (dcrl) {
751280304Sjkim            ok = ctx->check_crl(ctx, dcrl);
752280304Sjkim            if (!ok)
753280304Sjkim                goto err;
754280304Sjkim            ok = ctx->cert_crl(ctx, dcrl, x);
755280304Sjkim            if (!ok)
756280304Sjkim                goto err;
757280304Sjkim        } else
758280304Sjkim            ok = 1;
759238405Sjkim
760280304Sjkim        /* Don't look in full CRL if delta reason is removefromCRL */
761280304Sjkim        if (ok != 2) {
762280304Sjkim            ok = ctx->cert_crl(ctx, crl, x);
763280304Sjkim            if (!ok)
764280304Sjkim                goto err;
765280304Sjkim        }
766238405Sjkim
767280304Sjkim        X509_CRL_free(crl);
768280304Sjkim        X509_CRL_free(dcrl);
769280304Sjkim        crl = NULL;
770280304Sjkim        dcrl = NULL;
771280304Sjkim        /*
772280304Sjkim         * If reasons not updated we wont get anywhere by another iteration,
773280304Sjkim         * so exit loop.
774280304Sjkim         */
775280304Sjkim        if (last_reasons == ctx->current_reasons) {
776280304Sjkim            ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
777280304Sjkim            ok = ctx->verify_cb(0, ctx);
778280304Sjkim            goto err;
779280304Sjkim        }
780280304Sjkim    }
781280304Sjkim err:
782280304Sjkim    X509_CRL_free(crl);
783280304Sjkim    X509_CRL_free(dcrl);
784238405Sjkim
785280304Sjkim    ctx->current_crl = NULL;
786280304Sjkim    return ok;
787109998Smarkm
788280304Sjkim}
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)
793280304Sjkim{
794280304Sjkim    time_t *ptime;
795280304Sjkim    int i;
796280304Sjkim    if (notify)
797280304Sjkim        ctx->current_crl = crl;
798280304Sjkim    if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
799280304Sjkim        ptime = &ctx->param->check_time;
800280304Sjkim    else
801280304Sjkim        ptime = NULL;
802160814Ssimon
803280304Sjkim    i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
804280304Sjkim    if (i == 0) {
805280304Sjkim        if (!notify)
806280304Sjkim            return 0;
807280304Sjkim        ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
808280304Sjkim        if (!ctx->verify_cb(0, ctx))
809280304Sjkim            return 0;
810280304Sjkim    }
811160814Ssimon
812280304Sjkim    if (i > 0) {
813280304Sjkim        if (!notify)
814280304Sjkim            return 0;
815280304Sjkim        ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
816280304Sjkim        if (!ctx->verify_cb(0, ctx))
817280304Sjkim            return 0;
818280304Sjkim    }
819160814Ssimon
820280304Sjkim    if (X509_CRL_get_nextUpdate(crl)) {
821280304Sjkim        i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
822160814Ssimon
823280304Sjkim        if (i == 0) {
824280304Sjkim            if (!notify)
825280304Sjkim                return 0;
826280304Sjkim            ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
827280304Sjkim            if (!ctx->verify_cb(0, ctx))
828280304Sjkim                return 0;
829280304Sjkim        }
830280304Sjkim        /* Ignore expiry of base CRL is delta is valid */
831280304Sjkim        if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
832280304Sjkim            if (!notify)
833280304Sjkim                return 0;
834280304Sjkim            ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
835280304Sjkim            if (!ctx->verify_cb(0, ctx))
836280304Sjkim                return 0;
837280304Sjkim        }
838280304Sjkim    }
839160814Ssimon
840280304Sjkim    if (notify)
841280304Sjkim        ctx->current_crl = NULL;
842160814Ssimon
843280304Sjkim    return 1;
844280304Sjkim}
845160814Ssimon
846238405Sjkimstatic int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
847280304Sjkim                      X509 **pissuer, int *pscore, unsigned int *preasons,
848280304Sjkim                      STACK_OF(X509_CRL) *crls)
849280304Sjkim{
850280304Sjkim    int i, crl_score, best_score = *pscore;
851280304Sjkim    unsigned int reasons, best_reasons = 0;
852280304Sjkim    X509 *x = ctx->current_cert;
853280304Sjkim    X509_CRL *crl, *best_crl = NULL;
854280304Sjkim    X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
855238405Sjkim
856280304Sjkim    for (i = 0; i < sk_X509_CRL_num(crls); i++) {
857280304Sjkim        crl = sk_X509_CRL_value(crls, i);
858280304Sjkim        reasons = *preasons;
859280304Sjkim        crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
860238405Sjkim
861280304Sjkim        if (crl_score > best_score) {
862280304Sjkim            best_crl = crl;
863280304Sjkim            best_crl_issuer = crl_issuer;
864280304Sjkim            best_score = crl_score;
865280304Sjkim            best_reasons = reasons;
866280304Sjkim        }
867280304Sjkim    }
868238405Sjkim
869280304Sjkim    if (best_crl) {
870280304Sjkim        if (*pcrl)
871280304Sjkim            X509_CRL_free(*pcrl);
872280304Sjkim        *pcrl = best_crl;
873280304Sjkim        *pissuer = best_crl_issuer;
874280304Sjkim        *pscore = best_score;
875280304Sjkim        *preasons = best_reasons;
876280304Sjkim        CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
877280304Sjkim        if (*pdcrl) {
878280304Sjkim            X509_CRL_free(*pdcrl);
879280304Sjkim            *pdcrl = NULL;
880280304Sjkim        }
881280304Sjkim        get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
882280304Sjkim    }
883238405Sjkim
884280304Sjkim    if (best_score >= CRL_SCORE_VALID)
885280304Sjkim        return 1;
886238405Sjkim
887280304Sjkim    return 0;
888280304Sjkim}
889160814Ssimon
890280304Sjkim/*
891280304Sjkim * 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)
896280304Sjkim{
897280304Sjkim    ASN1_OCTET_STRING *exta, *extb;
898280304Sjkim    int i;
899280304Sjkim    i = X509_CRL_get_ext_by_NID(a, nid, -1);
900280304Sjkim    if (i >= 0) {
901280304Sjkim        /* Can't have multiple occurrences */
902280304Sjkim        if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
903280304Sjkim            return 0;
904280304Sjkim        exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
905280304Sjkim    } else
906280304Sjkim        exta = NULL;
907238405Sjkim
908280304Sjkim    i = X509_CRL_get_ext_by_NID(b, nid, -1);
909238405Sjkim
910280304Sjkim    if (i >= 0) {
911238405Sjkim
912280304Sjkim        if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
913280304Sjkim            return 0;
914280304Sjkim        extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
915280304Sjkim    } else
916280304Sjkim        extb = NULL;
917238405Sjkim
918280304Sjkim    if (!exta && !extb)
919280304Sjkim        return 1;
920238405Sjkim
921280304Sjkim    if (!exta || !extb)
922280304Sjkim        return 0;
923238405Sjkim
924280304Sjkim    if (ASN1_OCTET_STRING_cmp(exta, extb))
925280304Sjkim        return 0;
926238405Sjkim
927280304Sjkim    return 1;
928280304Sjkim}
929238405Sjkim
930238405Sjkim/* See if a base and delta are compatible */
931238405Sjkim
932238405Sjkimstatic int check_delta_base(X509_CRL *delta, X509_CRL *base)
933280304Sjkim{
934280304Sjkim    /* Delta CRL must be a delta */
935280304Sjkim    if (!delta->base_crl_number)
936280304Sjkim        return 0;
937280304Sjkim    /* Base must have a CRL number */
938280304Sjkim    if (!base->crl_number)
939280304Sjkim        return 0;
940280304Sjkim    /* Issuer names must match */
941280304Sjkim    if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta)))
942280304Sjkim        return 0;
943280304Sjkim    /* AKID and IDP must match */
944280304Sjkim    if (!crl_extension_match(delta, base, NID_authority_key_identifier))
945280304Sjkim        return 0;
946280304Sjkim    if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
947280304Sjkim        return 0;
948280304Sjkim    /* Delta CRL base number must not exceed Full CRL number. */
949280304Sjkim    if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
950280304Sjkim        return 0;
951280304Sjkim    /* Delta CRL number must exceed full CRL number */
952280304Sjkim    if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
953280304Sjkim        return 1;
954280304Sjkim    return 0;
955280304Sjkim}
956238405Sjkim
957280304Sjkim/*
958280304Sjkim * For a given base CRL find a delta... maybe extend to delta scoring or
959280304Sjkim * retrieve a chain of deltas...
960238405Sjkim */
961238405Sjkim
962238405Sjkimstatic void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
963280304Sjkim                         X509_CRL *base, STACK_OF(X509_CRL) *crls)
964280304Sjkim{
965280304Sjkim    X509_CRL *delta;
966280304Sjkim    int i;
967280304Sjkim    if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
968280304Sjkim        return;
969280304Sjkim    if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
970280304Sjkim        return;
971280304Sjkim    for (i = 0; i < sk_X509_CRL_num(crls); i++) {
972280304Sjkim        delta = sk_X509_CRL_value(crls, i);
973280304Sjkim        if (check_delta_base(delta, base)) {
974280304Sjkim            if (check_crl_time(ctx, delta, 0))
975280304Sjkim                *pscore |= CRL_SCORE_TIME_DELTA;
976280304Sjkim            CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
977280304Sjkim            *dcrl = delta;
978280304Sjkim            return;
979280304Sjkim        }
980280304Sjkim    }
981280304Sjkim    *dcrl = NULL;
982280304Sjkim}
983160814Ssimon
984280304Sjkim/*
985280304Sjkim * For a given CRL return how suitable it is for the supplied certificate
986280304Sjkim * 'x'. The return value is a mask of several criteria. If the issuer is not
987280304Sjkim * the certificate issuer this is returned in *pissuer. The reasons mask is
988280304Sjkim * also used to determine if the CRL is suitable: if no new reasons the CRL
989280304Sjkim * is rejected, otherwise reasons is updated.
990238405Sjkim */
991160814Ssimon
992238405Sjkimstatic int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
993280304Sjkim                         unsigned int *preasons, X509_CRL *crl, X509 *x)
994280304Sjkim{
995238405Sjkim
996280304Sjkim    int crl_score = 0;
997280304Sjkim    unsigned int tmp_reasons = *preasons, crl_reasons;
998238405Sjkim
999280304Sjkim    /* First see if we can reject CRL straight away */
1000238405Sjkim
1001280304Sjkim    /* Invalid IDP cannot be processed */
1002280304Sjkim    if (crl->idp_flags & IDP_INVALID)
1003280304Sjkim        return 0;
1004280304Sjkim    /* Reason codes or indirect CRLs need extended CRL support */
1005280304Sjkim    if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
1006280304Sjkim        if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
1007280304Sjkim            return 0;
1008280304Sjkim    } else if (crl->idp_flags & IDP_REASONS) {
1009280304Sjkim        /* If no new reasons reject */
1010280304Sjkim        if (!(crl->idp_reasons & ~tmp_reasons))
1011280304Sjkim            return 0;
1012280304Sjkim    }
1013280304Sjkim    /* Don't process deltas at this stage */
1014280304Sjkim    else if (crl->base_crl_number)
1015280304Sjkim        return 0;
1016280304Sjkim    /* If issuer name doesn't match certificate need indirect CRL */
1017280304Sjkim    if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
1018280304Sjkim        if (!(crl->idp_flags & IDP_INDIRECT))
1019280304Sjkim            return 0;
1020280304Sjkim    } else
1021280304Sjkim        crl_score |= CRL_SCORE_ISSUER_NAME;
1022238405Sjkim
1023280304Sjkim    if (!(crl->flags & EXFLAG_CRITICAL))
1024280304Sjkim        crl_score |= CRL_SCORE_NOCRITICAL;
1025238405Sjkim
1026280304Sjkim    /* Check expiry */
1027280304Sjkim    if (check_crl_time(ctx, crl, 0))
1028280304Sjkim        crl_score |= CRL_SCORE_TIME;
1029238405Sjkim
1030280304Sjkim    /* Check authority key ID and locate certificate issuer */
1031280304Sjkim    crl_akid_check(ctx, crl, pissuer, &crl_score);
1032238405Sjkim
1033280304Sjkim    /* If we can't locate certificate issuer at this point forget it */
1034238405Sjkim
1035280304Sjkim    if (!(crl_score & CRL_SCORE_AKID))
1036280304Sjkim        return 0;
1037238405Sjkim
1038280304Sjkim    /* Check cert for matching CRL distribution points */
1039238405Sjkim
1040280304Sjkim    if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) {
1041280304Sjkim        /* If no new reasons reject */
1042280304Sjkim        if (!(crl_reasons & ~tmp_reasons))
1043280304Sjkim            return 0;
1044280304Sjkim        tmp_reasons |= crl_reasons;
1045280304Sjkim        crl_score |= CRL_SCORE_SCOPE;
1046280304Sjkim    }
1047238405Sjkim
1048280304Sjkim    *preasons = tmp_reasons;
1049238405Sjkim
1050280304Sjkim    return crl_score;
1051238405Sjkim
1052280304Sjkim}
1053238405Sjkim
1054238405Sjkimstatic void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
1055280304Sjkim                           X509 **pissuer, int *pcrl_score)
1056280304Sjkim{
1057280304Sjkim    X509 *crl_issuer = NULL;
1058280304Sjkim    X509_NAME *cnm = X509_CRL_get_issuer(crl);
1059280304Sjkim    int cidx = ctx->error_depth;
1060280304Sjkim    int i;
1061238405Sjkim
1062280304Sjkim    if (cidx != sk_X509_num(ctx->chain) - 1)
1063280304Sjkim        cidx++;
1064238405Sjkim
1065280304Sjkim    crl_issuer = sk_X509_value(ctx->chain, cidx);
1066238405Sjkim
1067280304Sjkim    if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1068280304Sjkim        if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
1069280304Sjkim            *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT;
1070280304Sjkim            *pissuer = crl_issuer;
1071280304Sjkim            return;
1072280304Sjkim        }
1073280304Sjkim    }
1074238405Sjkim
1075280304Sjkim    for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) {
1076280304Sjkim        crl_issuer = sk_X509_value(ctx->chain, cidx);
1077280304Sjkim        if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1078280304Sjkim            continue;
1079280304Sjkim        if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1080280304Sjkim            *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
1081280304Sjkim            *pissuer = crl_issuer;
1082280304Sjkim            return;
1083280304Sjkim        }
1084280304Sjkim    }
1085238405Sjkim
1086280304Sjkim    /* Anything else needs extended CRL support */
1087238405Sjkim
1088280304Sjkim    if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
1089280304Sjkim        return;
1090238405Sjkim
1091280304Sjkim    /*
1092280304Sjkim     * Otherwise the CRL issuer is not on the path. Look for it in the set of
1093280304Sjkim     * untrusted certificates.
1094280304Sjkim     */
1095280304Sjkim    for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
1096280304Sjkim        crl_issuer = sk_X509_value(ctx->untrusted, i);
1097280304Sjkim        if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
1098280304Sjkim            continue;
1099280304Sjkim        if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
1100280304Sjkim            *pissuer = crl_issuer;
1101280304Sjkim            *pcrl_score |= CRL_SCORE_AKID;
1102280304Sjkim            return;
1103280304Sjkim        }
1104280304Sjkim    }
1105280304Sjkim}
1106238405Sjkim
1107280304Sjkim/*
1108280304Sjkim * 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
1110280304Sjkim * parent. This could be optimised somewhat since a lot of path checking will
1111280304Sjkim * 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)
1115280304Sjkim{
1116280304Sjkim    X509_STORE_CTX crl_ctx;
1117280304Sjkim    int ret;
1118280304Sjkim    /* Don't allow recursive CRL path validation */
1119280304Sjkim    if (ctx->parent)
1120280304Sjkim        return 0;
1121280304Sjkim    if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
1122280304Sjkim        return -1;
1123238405Sjkim
1124280304Sjkim    crl_ctx.crls = ctx->crls;
1125280304Sjkim    /* Copy verify params across */
1126280304Sjkim    X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
1127238405Sjkim
1128280304Sjkim    crl_ctx.parent = ctx;
1129280304Sjkim    crl_ctx.verify_cb = ctx->verify_cb;
1130238405Sjkim
1131280304Sjkim    /* Verify CRL issuer */
1132280304Sjkim    ret = X509_verify_cert(&crl_ctx);
1133238405Sjkim
1134280304Sjkim    if (ret <= 0)
1135280304Sjkim        goto err;
1136238405Sjkim
1137280304Sjkim    /* Check chain is acceptable */
1138238405Sjkim
1139280304Sjkim    ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
1140280304Sjkim err:
1141280304Sjkim    X509_STORE_CTX_cleanup(&crl_ctx);
1142280304Sjkim    return ret;
1143280304Sjkim}
1144238405Sjkim
1145280304Sjkim/*
1146280304Sjkim * RFC3280 says nothing about the relationship between CRL path and
1147280304Sjkim * certificate path, which could lead to situations where a certificate could
1148280304Sjkim * be revoked or validated by a CA not authorised to do so. RFC5280 is more
1149280304Sjkim * strict and states that the two paths must end in the same trust anchor,
1150280304Sjkim * though some discussions remain... until this is resolved we use the
1151280304Sjkim * RFC5280 version
1152238405Sjkim */
1153238405Sjkim
1154238405Sjkimstatic int check_crl_chain(X509_STORE_CTX *ctx,
1155280304Sjkim                           STACK_OF(X509) *cert_path,
1156280304Sjkim                           STACK_OF(X509) *crl_path)
1157280304Sjkim{
1158280304Sjkim    X509 *cert_ta, *crl_ta;
1159280304Sjkim    cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
1160280304Sjkim    crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
1161280304Sjkim    if (!X509_cmp(cert_ta, crl_ta))
1162280304Sjkim        return 1;
1163280304Sjkim    return 0;
1164280304Sjkim}
1165238405Sjkim
1166280304Sjkim/*-
1167280304Sjkim * 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)
1175280304Sjkim{
1176280304Sjkim    X509_NAME *nm = NULL;
1177280304Sjkim    GENERAL_NAMES *gens = NULL;
1178280304Sjkim    GENERAL_NAME *gena, *genb;
1179280304Sjkim    int i, j;
1180280304Sjkim    if (!a || !b)
1181280304Sjkim        return 1;
1182280304Sjkim    if (a->type == 1) {
1183280304Sjkim        if (!a->dpname)
1184280304Sjkim            return 0;
1185280304Sjkim        /* Case 1: two X509_NAME */
1186280304Sjkim        if (b->type == 1) {
1187280304Sjkim            if (!b->dpname)
1188280304Sjkim                return 0;
1189280304Sjkim            if (!X509_NAME_cmp(a->dpname, b->dpname))
1190280304Sjkim                return 1;
1191280304Sjkim            else
1192280304Sjkim                return 0;
1193280304Sjkim        }
1194280304Sjkim        /* Case 2: set name and GENERAL_NAMES appropriately */
1195280304Sjkim        nm = a->dpname;
1196280304Sjkim        gens = b->name.fullname;
1197280304Sjkim    } else if (b->type == 1) {
1198280304Sjkim        if (!b->dpname)
1199280304Sjkim            return 0;
1200280304Sjkim        /* Case 2: set name and GENERAL_NAMES appropriately */
1201280304Sjkim        gens = a->name.fullname;
1202280304Sjkim        nm = b->dpname;
1203280304Sjkim    }
1204160814Ssimon
1205280304Sjkim    /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
1206280304Sjkim    if (nm) {
1207280304Sjkim        for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
1208280304Sjkim            gena = sk_GENERAL_NAME_value(gens, i);
1209280304Sjkim            if (gena->type != GEN_DIRNAME)
1210280304Sjkim                continue;
1211280304Sjkim            if (!X509_NAME_cmp(nm, gena->d.directoryName))
1212280304Sjkim                return 1;
1213280304Sjkim        }
1214280304Sjkim        return 0;
1215280304Sjkim    }
1216238405Sjkim
1217280304Sjkim    /* Else case 3: two GENERAL_NAMES */
1218238405Sjkim
1219280304Sjkim    for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) {
1220280304Sjkim        gena = sk_GENERAL_NAME_value(a->name.fullname, i);
1221280304Sjkim        for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) {
1222280304Sjkim            genb = sk_GENERAL_NAME_value(b->name.fullname, j);
1223280304Sjkim            if (!GENERAL_NAME_cmp(gena, genb))
1224280304Sjkim                return 1;
1225280304Sjkim        }
1226280304Sjkim    }
1227238405Sjkim
1228280304Sjkim    return 0;
1229238405Sjkim
1230280304Sjkim}
1231238405Sjkim
1232238405Sjkimstatic int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
1233280304Sjkim{
1234280304Sjkim    int i;
1235280304Sjkim    X509_NAME *nm = X509_CRL_get_issuer(crl);
1236280304Sjkim    /* If no CRLissuer return is successful iff don't need a match */
1237280304Sjkim    if (!dp->CRLissuer)
1238280304Sjkim        return ! !(crl_score & CRL_SCORE_ISSUER_NAME);
1239280304Sjkim    for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
1240280304Sjkim        GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
1241280304Sjkim        if (gen->type != GEN_DIRNAME)
1242280304Sjkim            continue;
1243280304Sjkim        if (!X509_NAME_cmp(gen->d.directoryName, nm))
1244280304Sjkim            return 1;
1245280304Sjkim    }
1246280304Sjkim    return 0;
1247280304Sjkim}
1248238405Sjkim
1249238405Sjkim/* Check CRLDP and IDP */
1250238405Sjkim
1251238405Sjkimstatic int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
1252280304Sjkim                           unsigned int *preasons)
1253280304Sjkim{
1254280304Sjkim    int i;
1255280304Sjkim    if (crl->idp_flags & IDP_ONLYATTR)
1256280304Sjkim        return 0;
1257280304Sjkim    if (x->ex_flags & EXFLAG_CA) {
1258280304Sjkim        if (crl->idp_flags & IDP_ONLYUSER)
1259280304Sjkim            return 0;
1260280304Sjkim    } else {
1261280304Sjkim        if (crl->idp_flags & IDP_ONLYCA)
1262280304Sjkim            return 0;
1263280304Sjkim    }
1264280304Sjkim    *preasons = crl->idp_reasons;
1265280304Sjkim    for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
1266280304Sjkim        DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
1267280304Sjkim        if (crldp_check_crlissuer(dp, crl, crl_score)) {
1268280304Sjkim            if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
1269280304Sjkim                *preasons &= dp->dp_reasons;
1270280304Sjkim                return 1;
1271280304Sjkim            }
1272280304Sjkim        }
1273280304Sjkim    }
1274280304Sjkim    if ((!crl->idp || !crl->idp->distpoint)
1275280304Sjkim        && (crl_score & CRL_SCORE_ISSUER_NAME))
1276280304Sjkim        return 1;
1277280304Sjkim    return 0;
1278280304Sjkim}
1279238405Sjkim
1280280304Sjkim/*
1281280304Sjkim * Retrieve CRL corresponding to current certificate. If deltas enabled try
1282280304Sjkim * to find a delta CRL too
1283238405Sjkim */
1284280304Sjkim
1285238405Sjkimstatic int get_crl_delta(X509_STORE_CTX *ctx,
1286280304Sjkim                         X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
1287280304Sjkim{
1288280304Sjkim    int ok;
1289280304Sjkim    X509 *issuer = NULL;
1290280304Sjkim    int crl_score = 0;
1291280304Sjkim    unsigned int reasons;
1292280304Sjkim    X509_CRL *crl = NULL, *dcrl = NULL;
1293280304Sjkim    STACK_OF(X509_CRL) *skcrl;
1294280304Sjkim    X509_NAME *nm = X509_get_issuer_name(x);
1295280304Sjkim    reasons = ctx->current_reasons;
1296280304Sjkim    ok = get_crl_sk(ctx, &crl, &dcrl,
1297280304Sjkim                    &issuer, &crl_score, &reasons, ctx->crls);
1298238405Sjkim
1299280304Sjkim    if (ok)
1300280304Sjkim        goto done;
1301238405Sjkim
1302280304Sjkim    /* Lookup CRLs from store */
1303238405Sjkim
1304280304Sjkim    skcrl = ctx->lookup_crls(ctx, nm);
1305238405Sjkim
1306280304Sjkim    /* If no CRLs found and a near match from get_crl_sk use that */
1307280304Sjkim    if (!skcrl && crl)
1308280304Sjkim        goto done;
1309238405Sjkim
1310280304Sjkim    get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
1311238405Sjkim
1312280304Sjkim    sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
1313238405Sjkim
1314280304Sjkim done:
1315238405Sjkim
1316280304Sjkim    /* If we got any kind of CRL use it and return success */
1317280304Sjkim    if (crl) {
1318280304Sjkim        ctx->current_issuer = issuer;
1319280304Sjkim        ctx->current_crl_score = crl_score;
1320280304Sjkim        ctx->current_reasons = reasons;
1321280304Sjkim        *pcrl = crl;
1322280304Sjkim        *pdcrl = dcrl;
1323280304Sjkim        return 1;
1324280304Sjkim    }
1325238405Sjkim
1326280304Sjkim    return 0;
1327280304Sjkim}
1328109998Smarkm
1329109998Smarkm/* Check CRL validity */
1330109998Smarkmstatic int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
1331280304Sjkim{
1332280304Sjkim    X509 *issuer = NULL;
1333280304Sjkim    EVP_PKEY *ikey = NULL;
1334280304Sjkim    int ok = 0, chnum, cnum;
1335280304Sjkim    cnum = ctx->error_depth;
1336280304Sjkim    chnum = sk_X509_num(ctx->chain) - 1;
1337280304Sjkim    /* if we have an alternative CRL issuer cert use that */
1338280304Sjkim    if (ctx->current_issuer)
1339280304Sjkim        issuer = ctx->current_issuer;
1340238405Sjkim
1341280304Sjkim    /*
1342280304Sjkim     * Else find CRL issuer: if not last certificate then issuer is next
1343280304Sjkim     * certificate in chain.
1344280304Sjkim     */
1345280304Sjkim    else if (cnum < chnum)
1346280304Sjkim        issuer = sk_X509_value(ctx->chain, cnum + 1);
1347280304Sjkim    else {
1348280304Sjkim        issuer = sk_X509_value(ctx->chain, chnum);
1349280304Sjkim        /* If not self signed, can't check signature */
1350280304Sjkim        if (!ctx->check_issued(ctx, issuer, issuer)) {
1351280304Sjkim            ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
1352280304Sjkim            ok = ctx->verify_cb(0, ctx);
1353280304Sjkim            if (!ok)
1354280304Sjkim                goto err;
1355280304Sjkim        }
1356280304Sjkim    }
1357109998Smarkm
1358280304Sjkim    if (issuer) {
1359280304Sjkim        /*
1360280304Sjkim         * Skip most tests for deltas because they have already been done
1361280304Sjkim         */
1362280304Sjkim        if (!crl->base_crl_number) {
1363280304Sjkim            /* Check for cRLSign bit if keyUsage present */
1364280304Sjkim            if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
1365280304Sjkim                !(issuer->ex_kusage & KU_CRL_SIGN)) {
1366280304Sjkim                ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
1367280304Sjkim                ok = ctx->verify_cb(0, ctx);
1368280304Sjkim                if (!ok)
1369280304Sjkim                    goto err;
1370280304Sjkim            }
1371238405Sjkim
1372280304Sjkim            if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
1373280304Sjkim                ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
1374280304Sjkim                ok = ctx->verify_cb(0, ctx);
1375280304Sjkim                if (!ok)
1376280304Sjkim                    goto err;
1377280304Sjkim            }
1378238405Sjkim
1379280304Sjkim            if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
1380280304Sjkim                if (check_crl_path(ctx, ctx->current_issuer) <= 0) {
1381280304Sjkim                    ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
1382280304Sjkim                    ok = ctx->verify_cb(0, ctx);
1383280304Sjkim                    if (!ok)
1384280304Sjkim                        goto err;
1385280304Sjkim                }
1386280304Sjkim            }
1387238405Sjkim
1388280304Sjkim            if (crl->idp_flags & IDP_INVALID) {
1389280304Sjkim                ctx->error = X509_V_ERR_INVALID_EXTENSION;
1390280304Sjkim                ok = ctx->verify_cb(0, ctx);
1391280304Sjkim                if (!ok)
1392280304Sjkim                    goto err;
1393280304Sjkim            }
1394238405Sjkim
1395280304Sjkim        }
1396238405Sjkim
1397280304Sjkim        if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
1398280304Sjkim            ok = check_crl_time(ctx, crl, 1);
1399280304Sjkim            if (!ok)
1400280304Sjkim                goto err;
1401280304Sjkim        }
1402109998Smarkm
1403280304Sjkim        /* Attempt to get issuer certificate public key */
1404280304Sjkim        ikey = X509_get_pubkey(issuer);
1405238405Sjkim
1406280304Sjkim        if (!ikey) {
1407280304Sjkim            ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
1408280304Sjkim            ok = ctx->verify_cb(0, ctx);
1409280304Sjkim            if (!ok)
1410280304Sjkim                goto err;
1411280304Sjkim        } else {
1412280304Sjkim            /* Verify CRL signature */
1413280304Sjkim            if (X509_CRL_verify(crl, ikey) <= 0) {
1414280304Sjkim                ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
1415280304Sjkim                ok = ctx->verify_cb(0, ctx);
1416280304Sjkim                if (!ok)
1417280304Sjkim                    goto err;
1418280304Sjkim            }
1419280304Sjkim        }
1420280304Sjkim    }
1421109998Smarkm
1422280304Sjkim    ok = 1;
1423109998Smarkm
1424280304Sjkim err:
1425280304Sjkim    EVP_PKEY_free(ikey);
1426280304Sjkim    return ok;
1427280304Sjkim}
1428109998Smarkm
1429109998Smarkm/* Check certificate against CRL */
1430109998Smarkmstatic int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
1431280304Sjkim{
1432280304Sjkim    int ok;
1433280304Sjkim    X509_REVOKED *rev;
1434280304Sjkim    /*
1435280304Sjkim     * The rules changed for this... previously if a CRL contained unhandled
1436280304Sjkim     * critical extensions it could still be used to indicate a certificate
1437280304Sjkim     * was revoked. This has since been changed since critical extension can
1438280304Sjkim     * change the meaning of CRL entries.
1439280304Sjkim     */
1440280304Sjkim    if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
1441280304Sjkim        && (crl->flags & EXFLAG_CRITICAL)) {
1442280304Sjkim        ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
1443280304Sjkim        ok = ctx->verify_cb(0, ctx);
1444280304Sjkim        if (!ok)
1445280304Sjkim            return 0;
1446280304Sjkim    }
1447280304Sjkim    /*
1448280304Sjkim     * Look for serial number of certificate in CRL If found make sure reason
1449280304Sjkim     * is not removeFromCRL.
1450280304Sjkim     */
1451280304Sjkim    if (X509_CRL_get0_by_cert(crl, &rev, x)) {
1452280304Sjkim        if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
1453280304Sjkim            return 2;
1454280304Sjkim        ctx->error = X509_V_ERR_CERT_REVOKED;
1455280304Sjkim        ok = ctx->verify_cb(0, ctx);
1456280304Sjkim        if (!ok)
1457280304Sjkim            return 0;
1458280304Sjkim    }
1459127128Snectar
1460280304Sjkim    return 1;
1461280304Sjkim}
1462109998Smarkm
1463160814Ssimonstatic int check_policy(X509_STORE_CTX *ctx)
1464280304Sjkim{
1465280304Sjkim    int ret;
1466280304Sjkim    if (ctx->parent)
1467280304Sjkim        return 1;
1468280304Sjkim    ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
1469280304Sjkim                            ctx->param->policies, ctx->param->flags);
1470280304Sjkim    if (ret == 0) {
1471280304Sjkim        X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE);
1472280304Sjkim        return 0;
1473280304Sjkim    }
1474280304Sjkim    /* Invalid or inconsistent extensions */
1475280304Sjkim    if (ret == -1) {
1476280304Sjkim        /*
1477280304Sjkim         * Locate certificates with bad extensions and notify callback.
1478280304Sjkim         */
1479280304Sjkim        X509 *x;
1480280304Sjkim        int i;
1481280304Sjkim        for (i = 1; i < sk_X509_num(ctx->chain); i++) {
1482280304Sjkim            x = sk_X509_value(ctx->chain, i);
1483280304Sjkim            if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
1484280304Sjkim                continue;
1485280304Sjkim            ctx->current_cert = x;
1486280304Sjkim            ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
1487280304Sjkim            if (!ctx->verify_cb(0, ctx))
1488280304Sjkim                return 0;
1489280304Sjkim        }
1490280304Sjkim        return 1;
1491280304Sjkim    }
1492280304Sjkim    if (ret == -2) {
1493280304Sjkim        ctx->current_cert = NULL;
1494280304Sjkim        ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
1495280304Sjkim        return ctx->verify_cb(0, ctx);
1496280304Sjkim    }
1497160814Ssimon
1498280304Sjkim    if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
1499280304Sjkim        ctx->current_cert = NULL;
1500280304Sjkim        ctx->error = X509_V_OK;
1501280304Sjkim        if (!ctx->verify_cb(2, ctx))
1502280304Sjkim            return 0;
1503280304Sjkim    }
1504160814Ssimon
1505280304Sjkim    return 1;
1506280304Sjkim}
1507160814Ssimon
1508160814Ssimonstatic int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
1509280304Sjkim{
1510280304Sjkim    time_t *ptime;
1511280304Sjkim    int i;
1512160814Ssimon
1513280304Sjkim    if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
1514280304Sjkim        ptime = &ctx->param->check_time;
1515280304Sjkim    else
1516280304Sjkim        ptime = NULL;
1517160814Ssimon
1518280304Sjkim    i = X509_cmp_time(X509_get_notBefore(x), ptime);
1519280304Sjkim    if (i == 0) {
1520280304Sjkim        ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
1521280304Sjkim        ctx->current_cert = x;
1522280304Sjkim        if (!ctx->verify_cb(0, ctx))
1523280304Sjkim            return 0;
1524280304Sjkim    }
1525160814Ssimon
1526280304Sjkim    if (i > 0) {
1527280304Sjkim        ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
1528280304Sjkim        ctx->current_cert = x;
1529280304Sjkim        if (!ctx->verify_cb(0, ctx))
1530280304Sjkim            return 0;
1531280304Sjkim    }
1532160814Ssimon
1533280304Sjkim    i = X509_cmp_time(X509_get_notAfter(x), ptime);
1534280304Sjkim    if (i == 0) {
1535280304Sjkim        ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
1536280304Sjkim        ctx->current_cert = x;
1537280304Sjkim        if (!ctx->verify_cb(0, ctx))
1538280304Sjkim            return 0;
1539280304Sjkim    }
1540160814Ssimon
1541280304Sjkim    if (i < 0) {
1542280304Sjkim        ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
1543280304Sjkim        ctx->current_cert = x;
1544280304Sjkim        if (!ctx->verify_cb(0, ctx))
1545280304Sjkim            return 0;
1546280304Sjkim    }
1547160814Ssimon
1548280304Sjkim    return 1;
1549280304Sjkim}
1550160814Ssimon
155155714Skrisstatic int internal_verify(X509_STORE_CTX *ctx)
1552280304Sjkim{
1553280304Sjkim    int ok = 0, n;
1554280304Sjkim    X509 *xs, *xi;
1555280304Sjkim    EVP_PKEY *pkey = NULL;
1556280304Sjkim    int (*cb) (int xok, X509_STORE_CTX *xctx);
155755714Skris
1558280304Sjkim    cb = ctx->verify_cb;
155955714Skris
1560280304Sjkim    n = sk_X509_num(ctx->chain);
1561280304Sjkim    ctx->error_depth = n - 1;
1562280304Sjkim    n--;
1563280304Sjkim    xi = sk_X509_value(ctx->chain, n);
1564160814Ssimon
1565280304Sjkim    if (ctx->check_issued(ctx, xi, xi))
1566280304Sjkim        xs = xi;
1567280304Sjkim    else {
1568280304Sjkim        if (n <= 0) {
1569280304Sjkim            ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
1570280304Sjkim            ctx->current_cert = xi;
1571280304Sjkim            ok = cb(0, ctx);
1572280304Sjkim            goto end;
1573280304Sjkim        } else {
1574280304Sjkim            n--;
1575280304Sjkim            ctx->error_depth = n;
1576280304Sjkim            xs = sk_X509_value(ctx->chain, n);
1577280304Sjkim        }
1578280304Sjkim    }
157955714Skris
1580280304Sjkim/*      ctx->error=0;  not needed */
1581280304Sjkim    while (n >= 0) {
1582280304Sjkim        ctx->error_depth = n;
1583205128Ssimon
1584280304Sjkim        /*
1585280304Sjkim         * Skip signature check for self signed certificates unless
1586280304Sjkim         * explicitly asked for. It doesn't add any security and just wastes
1587280304Sjkim         * time.
1588280304Sjkim         */
1589280304Sjkim        if (!xs->valid
1590280304Sjkim            && (xs != xi
1591280304Sjkim                || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) {
1592280304Sjkim            if ((pkey = X509_get_pubkey(xi)) == NULL) {
1593280304Sjkim                ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
1594280304Sjkim                ctx->current_cert = xi;
1595280304Sjkim                ok = (*cb) (0, ctx);
1596280304Sjkim                if (!ok)
1597280304Sjkim                    goto end;
1598280304Sjkim            } else if (X509_verify(xs, pkey) <= 0) {
1599280304Sjkim                ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
1600280304Sjkim                ctx->current_cert = xs;
1601280304Sjkim                ok = (*cb) (0, ctx);
1602280304Sjkim                if (!ok) {
1603280304Sjkim                    EVP_PKEY_free(pkey);
1604280304Sjkim                    goto end;
1605280304Sjkim                }
1606280304Sjkim            }
1607280304Sjkim            EVP_PKEY_free(pkey);
1608280304Sjkim            pkey = NULL;
1609280304Sjkim        }
161055714Skris
1611280304Sjkim        xs->valid = 1;
161255714Skris
1613280304Sjkim        ok = check_cert_time(ctx, xs);
1614280304Sjkim        if (!ok)
1615280304Sjkim            goto end;
161655714Skris
1617280304Sjkim        /* The last error (if any) is still in the error value */
1618280304Sjkim        ctx->current_issuer = xi;
1619280304Sjkim        ctx->current_cert = xs;
1620280304Sjkim        ok = (*cb) (1, ctx);
1621280304Sjkim        if (!ok)
1622280304Sjkim            goto end;
162355714Skris
1624280304Sjkim        n--;
1625280304Sjkim        if (n >= 0) {
1626280304Sjkim            xi = xs;
1627280304Sjkim            xs = sk_X509_value(ctx->chain, n);
1628280304Sjkim        }
1629280304Sjkim    }
1630280304Sjkim    ok = 1;
1631280304Sjkim end:
1632280304Sjkim    return ok;
1633280304Sjkim}
163455714Skris
1635238405Sjkimint X509_cmp_current_time(const ASN1_TIME *ctm)
163668651Skris{
1637280304Sjkim    return X509_cmp_time(ctm, NULL);
163868651Skris}
163968651Skris
1640238405Sjkimint X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
1641280304Sjkim{
1642280304Sjkim    char *str;
1643280304Sjkim    ASN1_TIME atm;
1644280304Sjkim    long offset;
1645280304Sjkim    char buff1[24], buff2[24], *p;
1646284285Sjkim    int i, j, remaining;
164755714Skris
1648280304Sjkim    p = buff1;
1649284285Sjkim    remaining = ctm->length;
1650280304Sjkim    str = (char *)ctm->data;
1651284285Sjkim    /*
1652284285Sjkim     * Note that the following (historical) code allows much more slack in the
1653284285Sjkim     * time format than RFC5280. In RFC5280, the representation is fixed:
1654284285Sjkim     * UTCTime: YYMMDDHHMMSSZ
1655284285Sjkim     * GeneralizedTime: YYYYMMDDHHMMSSZ
1656284285Sjkim     */
1657280304Sjkim    if (ctm->type == V_ASN1_UTCTIME) {
1658284285Sjkim        /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
1659284285Sjkim        int min_length = sizeof("YYMMDDHHMMZ") - 1;
1660284285Sjkim        int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
1661284285Sjkim        if (remaining < min_length || remaining > max_length)
1662280304Sjkim            return 0;
1663280304Sjkim        memcpy(p, str, 10);
1664280304Sjkim        p += 10;
1665280304Sjkim        str += 10;
1666284285Sjkim        remaining -= 10;
1667280304Sjkim    } else {
1668284285Sjkim        /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
1669284285Sjkim        int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
1670284285Sjkim        int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
1671284285Sjkim        if (remaining < min_length || remaining > max_length)
1672280304Sjkim            return 0;
1673280304Sjkim        memcpy(p, str, 12);
1674280304Sjkim        p += 12;
1675280304Sjkim        str += 12;
1676284285Sjkim        remaining -= 12;
1677280304Sjkim    }
167855714Skris
1679280304Sjkim    if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
1680280304Sjkim        *(p++) = '0';
1681280304Sjkim        *(p++) = '0';
1682280304Sjkim    } else {
1683284285Sjkim        /* SS (seconds) */
1684284285Sjkim        if (remaining < 2)
1685284285Sjkim            return 0;
1686280304Sjkim        *(p++) = *(str++);
1687280304Sjkim        *(p++) = *(str++);
1688284285Sjkim        remaining -= 2;
1689284285Sjkim        /*
1690284285Sjkim         * Skip any (up to three) fractional seconds...
1691284285Sjkim         * TODO(emilia): in RFC5280, fractional seconds are forbidden.
1692284285Sjkim         * Can we just kill them altogether?
1693284285Sjkim         */
1694284285Sjkim        if (remaining && *str == '.') {
1695280304Sjkim            str++;
1696284285Sjkim            remaining--;
1697284285Sjkim            for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
1698284285Sjkim                if (*str < '0' || *str > '9')
1699284285Sjkim                    break;
1700284285Sjkim            }
1701280304Sjkim        }
170255714Skris
1703280304Sjkim    }
1704280304Sjkim    *(p++) = 'Z';
1705280304Sjkim    *(p++) = '\0';
170655714Skris
1707284285Sjkim    /* We now need either a terminating 'Z' or an offset. */
1708284285Sjkim    if (!remaining)
1709284285Sjkim        return 0;
1710284285Sjkim    if (*str == 'Z') {
1711284285Sjkim        if (remaining != 1)
1712284285Sjkim            return 0;
1713280304Sjkim        offset = 0;
1714284285Sjkim    } else {
1715284285Sjkim        /* (+-)HHMM */
1716280304Sjkim        if ((*str != '+') && (*str != '-'))
1717280304Sjkim            return 0;
1718284285Sjkim        /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
1719284285Sjkim        if (remaining != 5)
1720284285Sjkim            return 0;
1721284285Sjkim        if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
1722284285Sjkim            str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
1723284285Sjkim            return 0;
1724280304Sjkim        offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
1725280304Sjkim        offset += (str[3] - '0') * 10 + (str[4] - '0');
1726280304Sjkim        if (*str == '-')
1727280304Sjkim            offset = -offset;
1728280304Sjkim    }
1729280304Sjkim    atm.type = ctm->type;
1730280304Sjkim    atm.flags = 0;
1731280304Sjkim    atm.length = sizeof(buff2);
1732280304Sjkim    atm.data = (unsigned char *)buff2;
173355714Skris
1734280304Sjkim    if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
1735280304Sjkim        return 0;
173655714Skris
1737280304Sjkim    if (ctm->type == V_ASN1_UTCTIME) {
1738280304Sjkim        i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
1739280304Sjkim        if (i < 50)
1740280304Sjkim            i += 100;           /* cf. RFC 2459 */
1741280304Sjkim        j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
1742280304Sjkim        if (j < 50)
1743280304Sjkim            j += 100;
174455714Skris
1745280304Sjkim        if (i < j)
1746280304Sjkim            return -1;
1747280304Sjkim        if (i > j)
1748280304Sjkim            return 1;
1749280304Sjkim    }
1750280304Sjkim    i = strcmp(buff1, buff2);
1751280304Sjkim    if (i == 0)                 /* wait a second then return younger :-) */
1752280304Sjkim        return -1;
1753280304Sjkim    else
1754280304Sjkim        return i;
1755280304Sjkim}
1756280304Sjkim
175768651SkrisASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
175868651Skris{
1759280304Sjkim    return X509_time_adj(s, adj, NULL);
176068651Skris}
176168651Skris
1762238405SjkimASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
1763280304Sjkim{
1764280304Sjkim    return X509_time_adj_ex(s, 0, offset_sec, in_tm);
1765280304Sjkim}
1766238405Sjkim
1767238405SjkimASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
1768280304Sjkim                            int offset_day, long offset_sec, time_t *in_tm)
1769280304Sjkim{
1770280304Sjkim    time_t t;
177155714Skris
1772280304Sjkim    if (in_tm)
1773280304Sjkim        t = *in_tm;
1774280304Sjkim    else
1775280304Sjkim        time(&t);
177668651Skris
1777280304Sjkim    if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) {
1778280304Sjkim        if (s->type == V_ASN1_UTCTIME)
1779280304Sjkim            return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
1780280304Sjkim        if (s->type == V_ASN1_GENERALIZEDTIME)
1781280304Sjkim            return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
1782280304Sjkim    }
1783280304Sjkim    return ASN1_TIME_adj(s, t, offset_day, offset_sec);
1784280304Sjkim}
178555714Skris
178655714Skrisint X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
1787280304Sjkim{
1788280304Sjkim    EVP_PKEY *ktmp = NULL, *ktmp2;
1789280304Sjkim    int i, j;
179055714Skris
1791280304Sjkim    if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey))
1792280304Sjkim        return 1;
179355714Skris
1794280304Sjkim    for (i = 0; i < sk_X509_num(chain); i++) {
1795280304Sjkim        ktmp = X509_get_pubkey(sk_X509_value(chain, i));
1796280304Sjkim        if (ktmp == NULL) {
1797280304Sjkim            X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
1798280304Sjkim                    X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
1799280304Sjkim            return 0;
1800280304Sjkim        }
1801280304Sjkim        if (!EVP_PKEY_missing_parameters(ktmp))
1802280304Sjkim            break;
1803280304Sjkim        else {
1804280304Sjkim            EVP_PKEY_free(ktmp);
1805280304Sjkim            ktmp = NULL;
1806280304Sjkim        }
1807280304Sjkim    }
1808280304Sjkim    if (ktmp == NULL) {
1809280304Sjkim        X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
1810280304Sjkim                X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
1811280304Sjkim        return 0;
1812280304Sjkim    }
181355714Skris
1814280304Sjkim    /* first, populate the other certs */
1815280304Sjkim    for (j = i - 1; j >= 0; j--) {
1816280304Sjkim        ktmp2 = X509_get_pubkey(sk_X509_value(chain, j));
1817280304Sjkim        EVP_PKEY_copy_parameters(ktmp2, ktmp);
1818280304Sjkim        EVP_PKEY_free(ktmp2);
1819280304Sjkim    }
182055714Skris
1821280304Sjkim    if (pkey != NULL)
1822280304Sjkim        EVP_PKEY_copy_parameters(pkey, ktmp);
1823280304Sjkim    EVP_PKEY_free(ktmp);
1824280304Sjkim    return 1;
1825280304Sjkim}
182655714Skris
1827280304Sjkimint X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
1828280304Sjkim                                    CRYPTO_EX_new *new_func,
1829280304Sjkim                                    CRYPTO_EX_dup *dup_func,
1830280304Sjkim                                    CRYPTO_EX_free *free_func)
1831280304Sjkim{
1832280304Sjkim    /*
1833280304Sjkim     * This function is (usually) called only once, by
1834280304Sjkim     * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c).
1835280304Sjkim     */
1836280304Sjkim    return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp,
1837280304Sjkim                                   new_func, dup_func, free_func);
1838280304Sjkim}
1839280304Sjkim
184055714Skrisint X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
1841280304Sjkim{
1842280304Sjkim    return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
1843280304Sjkim}
184455714Skris
184555714Skrisvoid *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
1846280304Sjkim{
1847280304Sjkim    return CRYPTO_get_ex_data(&ctx->ex_data, idx);
1848280304Sjkim}
184955714Skris
185055714Skrisint X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
1851280304Sjkim{
1852280304Sjkim    return ctx->error;
1853280304Sjkim}
185455714Skris
185555714Skrisvoid X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
1856280304Sjkim{
1857280304Sjkim    ctx->error = err;
1858280304Sjkim}
185955714Skris
186055714Skrisint X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
1861280304Sjkim{
1862280304Sjkim    return ctx->error_depth;
1863280304Sjkim}
186455714Skris
186555714SkrisX509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
1866280304Sjkim{
1867280304Sjkim    return ctx->current_cert;
1868280304Sjkim}
186955714Skris
187055714SkrisSTACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
1871280304Sjkim{
1872280304Sjkim    return ctx->chain;
1873280304Sjkim}
187455714Skris
187559191SkrisSTACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
1876280304Sjkim{
1877280304Sjkim    int i;
1878280304Sjkim    X509 *x;
1879280304Sjkim    STACK_OF(X509) *chain;
1880280304Sjkim    if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain)))
1881280304Sjkim        return NULL;
1882280304Sjkim    for (i = 0; i < sk_X509_num(chain); i++) {
1883280304Sjkim        x = sk_X509_value(chain, i);
1884280304Sjkim        CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
1885280304Sjkim    }
1886280304Sjkim    return chain;
1887280304Sjkim}
188859191Skris
1889238405SjkimX509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
1890280304Sjkim{
1891280304Sjkim    return ctx->current_issuer;
1892280304Sjkim}
1893238405Sjkim
1894238405SjkimX509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
1895280304Sjkim{
1896280304Sjkim    return ctx->current_crl;
1897280304Sjkim}
1898238405Sjkim
1899238405SjkimX509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
1900280304Sjkim{
1901280304Sjkim    return ctx->parent;
1902280304Sjkim}
1903238405Sjkim
190455714Skrisvoid X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
1905280304Sjkim{
1906280304Sjkim    ctx->cert = x;
1907280304Sjkim}
190855714Skris
190955714Skrisvoid X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
1910280304Sjkim{
1911280304Sjkim    ctx->untrusted = sk;
1912280304Sjkim}
191355714Skris
1914160814Ssimonvoid X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
1915280304Sjkim{
1916280304Sjkim    ctx->crls = sk;
1917280304Sjkim}
1918160814Ssimon
191959191Skrisint X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
1920280304Sjkim{
1921280304Sjkim    return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
1922280304Sjkim}
192359191Skris
192459191Skrisint X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
1925280304Sjkim{
1926280304Sjkim    return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
1927280304Sjkim}
192859191Skris
1929280304Sjkim/*
1930280304Sjkim * This function is used to set the X509_STORE_CTX purpose and trust values.
1931280304Sjkim * This is intended to be used when another structure has its own trust and
1932280304Sjkim * purpose values which (if set) will be inherited by the ctx. If they aren't
1933280304Sjkim * set then we will usually have a default purpose in mind which should then
1934280304Sjkim * be used to set the trust value. An example of this is SSL use: an SSL
1935280304Sjkim * structure will have its own purpose and trust settings which the
1936280304Sjkim * application can set: if they aren't set then we use the default of SSL
1937280304Sjkim * client/server.
193859191Skris */
193959191Skris
194059191Skrisint X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
1941280304Sjkim                                   int purpose, int trust)
194259191Skris{
1943280304Sjkim    int idx;
1944280304Sjkim    /* If purpose not set use default */
1945280304Sjkim    if (!purpose)
1946280304Sjkim        purpose = def_purpose;
1947280304Sjkim    /* If we have a purpose then check it is valid */
1948280304Sjkim    if (purpose) {
1949280304Sjkim        X509_PURPOSE *ptmp;
1950280304Sjkim        idx = X509_PURPOSE_get_by_id(purpose);
1951280304Sjkim        if (idx == -1) {
1952280304Sjkim            X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1953280304Sjkim                    X509_R_UNKNOWN_PURPOSE_ID);
1954280304Sjkim            return 0;
1955280304Sjkim        }
1956280304Sjkim        ptmp = X509_PURPOSE_get0(idx);
1957280304Sjkim        if (ptmp->trust == X509_TRUST_DEFAULT) {
1958280304Sjkim            idx = X509_PURPOSE_get_by_id(def_purpose);
1959280304Sjkim            if (idx == -1) {
1960280304Sjkim                X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1961280304Sjkim                        X509_R_UNKNOWN_PURPOSE_ID);
1962280304Sjkim                return 0;
1963280304Sjkim            }
1964280304Sjkim            ptmp = X509_PURPOSE_get0(idx);
1965280304Sjkim        }
1966280304Sjkim        /* If trust not set then get from purpose default */
1967280304Sjkim        if (!trust)
1968280304Sjkim            trust = ptmp->trust;
1969280304Sjkim    }
1970280304Sjkim    if (trust) {
1971280304Sjkim        idx = X509_TRUST_get_by_id(trust);
1972280304Sjkim        if (idx == -1) {
1973280304Sjkim            X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
1974280304Sjkim                    X509_R_UNKNOWN_TRUST_ID);
1975280304Sjkim            return 0;
1976280304Sjkim        }
1977280304Sjkim    }
197859191Skris
1979280304Sjkim    if (purpose && !ctx->param->purpose)
1980280304Sjkim        ctx->param->purpose = purpose;
1981280304Sjkim    if (trust && !ctx->param->trust)
1982280304Sjkim        ctx->param->trust = trust;
1983280304Sjkim    return 1;
198459191Skris}
198559191Skris
198668651SkrisX509_STORE_CTX *X509_STORE_CTX_new(void)
198768651Skris{
1988280304Sjkim    X509_STORE_CTX *ctx;
1989280304Sjkim    ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
1990280304Sjkim    if (!ctx) {
1991280304Sjkim        X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE);
1992280304Sjkim        return NULL;
1993280304Sjkim    }
1994280304Sjkim    memset(ctx, 0, sizeof(X509_STORE_CTX));
1995280304Sjkim    return ctx;
199668651Skris}
199759191Skris
199868651Skrisvoid X509_STORE_CTX_free(X509_STORE_CTX *ctx)
199968651Skris{
2000284285Sjkim    if (!ctx)
2001284285Sjkim        return;
2002280304Sjkim    X509_STORE_CTX_cleanup(ctx);
2003280304Sjkim    OPENSSL_free(ctx);
200468651Skris}
200568651Skris
2006109998Smarkmint X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
2007280304Sjkim                        STACK_OF(X509) *chain)
2008280304Sjkim{
2009280304Sjkim    int ret = 1;
2010280304Sjkim    ctx->ctx = store;
2011280304Sjkim    ctx->current_method = 0;
2012280304Sjkim    ctx->cert = x509;
2013280304Sjkim    ctx->untrusted = chain;
2014280304Sjkim    ctx->crls = NULL;
2015280304Sjkim    ctx->last_untrusted = 0;
2016280304Sjkim    ctx->other_ctx = NULL;
2017280304Sjkim    ctx->valid = 0;
2018280304Sjkim    ctx->chain = NULL;
2019280304Sjkim    ctx->error = 0;
2020280304Sjkim    ctx->explicit_policy = 0;
2021280304Sjkim    ctx->error_depth = 0;
2022280304Sjkim    ctx->current_cert = NULL;
2023280304Sjkim    ctx->current_issuer = NULL;
2024280304Sjkim    ctx->current_crl = NULL;
2025280304Sjkim    ctx->current_crl_score = 0;
2026280304Sjkim    ctx->current_reasons = 0;
2027280304Sjkim    ctx->tree = NULL;
2028280304Sjkim    ctx->parent = NULL;
2029295016Sjkim    /* Zero ex_data to make sure we're cleanup-safe */
2030295016Sjkim    memset(&ctx->ex_data, 0, sizeof(ctx->ex_data));
2031109998Smarkm
2032280304Sjkim    ctx->param = X509_VERIFY_PARAM_new();
2033280304Sjkim    if (!ctx->param) {
2034280304Sjkim        X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
2035280304Sjkim        return 0;
2036280304Sjkim    }
2037160814Ssimon
2038280304Sjkim    /*
2039280304Sjkim     * Inherit callbacks and flags from X509_STORE if not set use defaults.
2040280304Sjkim     */
2041280304Sjkim    if (store)
2042280304Sjkim        ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
2043280304Sjkim    else
2044280304Sjkim        ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
2045109998Smarkm
2046280304Sjkim    if (store) {
2047280304Sjkim        ctx->verify_cb = store->verify_cb;
2048295016Sjkim        /* Seems to always be 0 in OpenSSL, else must be idempotent */
2049280304Sjkim        ctx->cleanup = store->cleanup;
2050280304Sjkim    } else
2051280304Sjkim        ctx->cleanup = 0;
2052160814Ssimon
2053280304Sjkim    if (ret)
2054280304Sjkim        ret = X509_VERIFY_PARAM_inherit(ctx->param,
2055280304Sjkim                                        X509_VERIFY_PARAM_lookup("default"));
2056160814Ssimon
2057280304Sjkim    if (ret == 0) {
2058280304Sjkim        X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
2059295016Sjkim        goto err;
2060280304Sjkim    }
2061160814Ssimon
2062280304Sjkim    if (store && store->check_issued)
2063280304Sjkim        ctx->check_issued = store->check_issued;
2064280304Sjkim    else
2065280304Sjkim        ctx->check_issued = check_issued;
2066109998Smarkm
2067280304Sjkim    if (store && store->get_issuer)
2068280304Sjkim        ctx->get_issuer = store->get_issuer;
2069280304Sjkim    else
2070280304Sjkim        ctx->get_issuer = X509_STORE_CTX_get1_issuer;
2071109998Smarkm
2072280304Sjkim    if (store && store->verify_cb)
2073280304Sjkim        ctx->verify_cb = store->verify_cb;
2074280304Sjkim    else
2075280304Sjkim        ctx->verify_cb = null_callback;
2076109998Smarkm
2077280304Sjkim    if (store && store->verify)
2078280304Sjkim        ctx->verify = store->verify;
2079280304Sjkim    else
2080280304Sjkim        ctx->verify = internal_verify;
2081109998Smarkm
2082280304Sjkim    if (store && store->check_revocation)
2083280304Sjkim        ctx->check_revocation = store->check_revocation;
2084280304Sjkim    else
2085280304Sjkim        ctx->check_revocation = check_revocation;
2086109998Smarkm
2087280304Sjkim    if (store && store->get_crl)
2088280304Sjkim        ctx->get_crl = store->get_crl;
2089280304Sjkim    else
2090280304Sjkim        ctx->get_crl = NULL;
2091109998Smarkm
2092280304Sjkim    if (store && store->check_crl)
2093280304Sjkim        ctx->check_crl = store->check_crl;
2094280304Sjkim    else
2095280304Sjkim        ctx->check_crl = check_crl;
2096109998Smarkm
2097280304Sjkim    if (store && store->cert_crl)
2098280304Sjkim        ctx->cert_crl = store->cert_crl;
2099280304Sjkim    else
2100280304Sjkim        ctx->cert_crl = cert_crl;
2101109998Smarkm
2102280304Sjkim    if (store && store->lookup_certs)
2103280304Sjkim        ctx->lookup_certs = store->lookup_certs;
2104280304Sjkim    else
2105280304Sjkim        ctx->lookup_certs = X509_STORE_get1_certs;
2106109998Smarkm
2107280304Sjkim    if (store && store->lookup_crls)
2108280304Sjkim        ctx->lookup_crls = store->lookup_crls;
2109280304Sjkim    else
2110280304Sjkim        ctx->lookup_crls = X509_STORE_get1_crls;
2111238405Sjkim
2112280304Sjkim    ctx->check_policy = check_policy;
2113238405Sjkim
2114295016Sjkim    if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
2115295016Sjkim                           &ctx->ex_data))
2116295016Sjkim        return 1;
2117295016Sjkim    X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
2118295016Sjkim
2119295016Sjkim err:
2120280304Sjkim    /*
2121295016Sjkim     * On error clean up allocated storage, if the store context was not
2122295016Sjkim     * allocated with X509_STORE_CTX_new() this is our last chance to do so.
2123280304Sjkim     */
2124295016Sjkim    X509_STORE_CTX_cleanup(ctx);
2125295016Sjkim    return 0;
2126280304Sjkim}
2127109998Smarkm
2128280304Sjkim/*
2129280304Sjkim * Set alternative lookup method: just a STACK of trusted certificates. This
2130280304Sjkim * 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{
2135280304Sjkim    ctx->other_ctx = sk;
2136280304Sjkim    ctx->get_issuer = get_issuer_sk;
213768651Skris}
213868651Skris
213968651Skrisvoid X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
2140280304Sjkim{
2141295016Sjkim    /*
2142295016Sjkim     * We need to be idempotent because, unfortunately, free() also calls
2143295016Sjkim     * cleanup(), so the natural call sequence new(), init(), cleanup(), free()
2144295016Sjkim     * calls cleanup() for the same object twice!  Thus we must zero the
2145295016Sjkim     * pointers below after they're freed!
2146295016Sjkim     */
2147295016Sjkim    /* Seems to always be 0 in OpenSSL, do this at most once. */
2148295016Sjkim    if (ctx->cleanup != NULL) {
2149280304Sjkim        ctx->cleanup(ctx);
2150295016Sjkim        ctx->cleanup = NULL;
2151295016Sjkim    }
2152280304Sjkim    if (ctx->param != NULL) {
2153280304Sjkim        if (ctx->parent == NULL)
2154280304Sjkim            X509_VERIFY_PARAM_free(ctx->param);
2155280304Sjkim        ctx->param = NULL;
2156280304Sjkim    }
2157280304Sjkim    if (ctx->tree != NULL) {
2158280304Sjkim        X509_policy_tree_free(ctx->tree);
2159280304Sjkim        ctx->tree = NULL;
2160280304Sjkim    }
2161280304Sjkim    if (ctx->chain != NULL) {
2162280304Sjkim        sk_X509_pop_free(ctx->chain, X509_free);
2163280304Sjkim        ctx->chain = NULL;
2164280304Sjkim    }
2165280304Sjkim    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data));
2166280304Sjkim    memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
2167280304Sjkim}
216868651Skris
2169160814Ssimonvoid X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
2170280304Sjkim{
2171280304Sjkim    X509_VERIFY_PARAM_set_depth(ctx->param, depth);
2172280304Sjkim}
217368651Skris
2174160814Ssimonvoid X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
2175280304Sjkim{
2176280304Sjkim    X509_VERIFY_PARAM_set_flags(ctx->param, flags);
2177280304Sjkim}
217868651Skris
2179280304Sjkimvoid X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
2180280304Sjkim                             time_t t)
2181280304Sjkim{
2182280304Sjkim    X509_VERIFY_PARAM_set_time(ctx->param, t);
2183280304Sjkim}
2184160814Ssimon
218589837Skrisvoid X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
2186280304Sjkim                                  int (*verify_cb) (int, X509_STORE_CTX *))
2187280304Sjkim{
2188280304Sjkim    ctx->verify_cb = verify_cb;
2189280304Sjkim}
219089837Skris
2191160814SsimonX509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
2192280304Sjkim{
2193280304Sjkim    return ctx->tree;
2194280304Sjkim}
2195160814Ssimon
2196160814Ssimonint X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
2197280304Sjkim{
2198280304Sjkim    return ctx->explicit_policy;
2199280304Sjkim}
2200160814Ssimon
2201160814Ssimonint X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
2202280304Sjkim{
2203280304Sjkim    const X509_VERIFY_PARAM *param;
2204280304Sjkim    param = X509_VERIFY_PARAM_lookup(name);
2205280304Sjkim    if (!param)
2206280304Sjkim        return 0;
2207280304Sjkim    return X509_VERIFY_PARAM_inherit(ctx->param, param);
2208280304Sjkim}
2209160814Ssimon
2210160814SsimonX509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
2211280304Sjkim{
2212280304Sjkim    return ctx->param;
2213280304Sjkim}
2214160814Ssimon
2215160814Ssimonvoid X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
2216280304Sjkim{
2217280304Sjkim    if (ctx->param)
2218280304Sjkim        X509_VERIFY_PARAM_free(ctx->param);
2219280304Sjkim    ctx->param = param;
2220280304Sjkim}
2221160814Ssimon
222255714SkrisIMPLEMENT_STACK_OF(X509)
2223280304Sjkim
222455714SkrisIMPLEMENT_ASN1_SET_OF(X509)
222555714Skris
222655714SkrisIMPLEMENT_STACK_OF(X509_NAME)
222755714Skris
222855714SkrisIMPLEMENT_STACK_OF(X509_ATTRIBUTE)
2229280304Sjkim
223055714SkrisIMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
2231