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