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