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