/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#include <ctype.h>
#include <string.h>
#include <time.h>

#include <openssl/asn1.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/thread.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

#include "../internal.h"
#include "vpm_int.h"

static CRYPTO_EX_DATA_CLASS g_ex_data_class =
    CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;

/* CRL score values */

/* No unhandled critical extensions */

#define CRL_SCORE_NOCRITICAL 0x100

/* certificate is within CRL scope */

#define CRL_SCORE_SCOPE 0x080

/* CRL times valid */

#define CRL_SCORE_TIME 0x040

/* Issuer name matches certificate */

#define CRL_SCORE_ISSUER_NAME 0x020

/* If this score or above CRL is probably valid */

#define CRL_SCORE_VALID \
  (CRL_SCORE_NOCRITICAL | CRL_SCORE_TIME | CRL_SCORE_SCOPE)

/* CRL issuer is certificate issuer */

#define CRL_SCORE_ISSUER_CERT 0x018

/* CRL issuer is on certificate path */

#define CRL_SCORE_SAME_PATH 0x008

/* CRL issuer matches CRL AKID */

#define CRL_SCORE_AKID 0x004

/* Have a delta CRL with valid times */

#define CRL_SCORE_TIME_DELTA 0x002

static int null_callback(int ok, X509_STORE_CTX *e);
static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) * sk, X509 *x);
static int check_chain_extensions(X509_STORE_CTX *ctx);
static int check_name_constraints(X509_STORE_CTX *ctx);
static int check_id(X509_STORE_CTX *ctx);
static int check_trust(X509_STORE_CTX *ctx);
static int check_revocation(X509_STORE_CTX *ctx);
static int check_cert(X509_STORE_CTX *ctx);
static int check_policy(X509_STORE_CTX *ctx);

static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
                         unsigned int *preasons, X509_CRL *crl, X509 *x);
static int get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
                         X509 *x);
static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score,
                         X509_CRL *base, STACK_OF(X509_CRL) * crls);
static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
                           int *pcrl_score);
static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
                           unsigned int *preasons);
static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) * cert_path,
                           STACK_OF(X509) * crl_path);

static int internal_verify(X509_STORE_CTX *ctx);

static int null_callback(int ok, X509_STORE_CTX *e) { return ok; }

/* Return 1 is a certificate is self signed */
static int cert_self_signed(X509 *x) {
  X509_check_purpose(x, -1, 0);
  if (x->ex_flags & EXFLAG_SS)
    return 1;
  else
    return 0;
}

/* Given a certificate try and find an exact match in the store */

static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) {
  STACK_OF(X509) * certs;
  X509 *xtmp = NULL;
  size_t i;
  /* Lookup all certs with matching subject name */
  certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
  if (certs == NULL)
    return NULL;
  /* Look for exact match */
  for (i = 0; i < sk_X509_num(certs); i++) {
    xtmp = sk_X509_value(certs, i);
    if (!X509_cmp(xtmp, x))
      break;
  }
  if (i < sk_X509_num(certs))
    X509_up_ref(xtmp);
  else
    xtmp = NULL;
  sk_X509_pop_free(certs, X509_free);
  return xtmp;
}

int X509_verify_cert(X509_STORE_CTX *ctx) {
  X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
  int bad_chain = 0;
  X509_VERIFY_PARAM *param = ctx->param;
  int depth, i, ok = 0;
  int num, j, retry, trust;
  int (*cb)(int xok, X509_STORE_CTX *xctx);
  STACK_OF(X509) *sktmp = NULL;
  if (ctx->cert == NULL) {
    OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
    ctx->error = X509_V_ERR_INVALID_CALL;
    return -1;
  }
  if (ctx->chain != NULL) {
    /*
     * This X509_STORE_CTX has already been used to verify a cert. We
     * cannot do another one.
     */
    OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    ctx->error = X509_V_ERR_INVALID_CALL;
    return -1;
  }

  cb = ctx->verify_cb;

  /*
   * first we make sure the chain we are going to build is present and that
   * the first entry is in place
   */
  ctx->chain = sk_X509_new_null();
  if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) {
    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
    ctx->error = X509_V_ERR_OUT_OF_MEM;
    goto end;
  }
  X509_up_ref(ctx->cert);
  ctx->last_untrusted = 1;

  /* We use a temporary STACK so we can chop and hack at it.
   * sktmp = ctx->untrusted ++ ctx->ctx->additional_untrusted */
  if (ctx->untrusted != NULL && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
    ctx->error = X509_V_ERR_OUT_OF_MEM;
    goto end;
  }

  if (ctx->ctx->additional_untrusted != NULL) {
    if (sktmp == NULL) {
      sktmp = sk_X509_new_null();
      if (sktmp == NULL) {
        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
        ctx->error = X509_V_ERR_OUT_OF_MEM;
        goto end;
      }
    }

    for (size_t k = 0; k < sk_X509_num(ctx->ctx->additional_untrusted); k++) {
      if (!sk_X509_push(sktmp,
                        sk_X509_value(ctx->ctx->additional_untrusted, k))) {
        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
        ctx->error = X509_V_ERR_OUT_OF_MEM;
        goto end;
      }
    }
  }

  num = sk_X509_num(ctx->chain);
  x = sk_X509_value(ctx->chain, num - 1);
  depth = param->depth;

  for (;;) {
    /* If we have enough, we break */
    if (depth < num)
      break; /* FIXME: If this happens, we should take
              * note of it and, if appropriate, use the
              * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
              * later. */

    /* If we are self signed, we break */
    if (cert_self_signed(x))
      break;
    /*
     * If asked see if we can find issuer in trusted store first
     */
    if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
      ok = ctx->get_issuer(&xtmp, ctx, x);
      if (ok < 0) {
        ctx->error = X509_V_ERR_STORE_LOOKUP;
        goto end;
      }
      /*
       * If successful for now free up cert so it will be picked up
       * again later.
       */
      if (ok > 0) {
        X509_free(xtmp);
        break;
      }
    }

    /* If we were passed a cert chain, use it first */
    if (sktmp != NULL) {
      xtmp = find_issuer(ctx, sktmp, x);
      if (xtmp != NULL) {
        if (!sk_X509_push(ctx->chain, xtmp)) {
          OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
          ctx->error = X509_V_ERR_OUT_OF_MEM;
          ok = 0;
          goto end;
        }
        X509_up_ref(xtmp);
        (void)sk_X509_delete_ptr(sktmp, xtmp);
        ctx->last_untrusted++;
        x = xtmp;
        num++;
        /*
         * reparse the full chain for the next one
         */
        continue;
      }
    }
    break;
  }

  /* Remember how many untrusted certs we have */
  j = num;
  /*
   * at this point, chain should contain a list of untrusted certificates.
   * We now need to add at least one trusted one, if possible, otherwise we
   * complain.
   */

  do {
    /*
     * Examine last certificate in chain and see if it is self signed.
     */
    i = sk_X509_num(ctx->chain);
    x = sk_X509_value(ctx->chain, i - 1);
    if (cert_self_signed(x)) {
      /* we have a self signed certificate */
      if (sk_X509_num(ctx->chain) == 1) {
        /*
         * We have a single self signed certificate: see if we can
         * find it in the store. We must have an exact match to avoid
         * possible impersonation.
         */
        ok = ctx->get_issuer(&xtmp, ctx, x);
        if ((ok <= 0) || X509_cmp(x, xtmp)) {
          ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
          ctx->current_cert = x;
          ctx->error_depth = i - 1;
          if (ok == 1)
            X509_free(xtmp);
          bad_chain = 1;
          ok = cb(0, ctx);
          if (!ok)
            goto end;
        } else {
          /*
           * We have a match: replace certificate with store
           * version so we get any trust settings.
           */
          X509_free(x);
          x = xtmp;
          (void)sk_X509_set(ctx->chain, i - 1, x);
          ctx->last_untrusted = 0;
        }
      } else {
        /*
         * extract and save self signed certificate for later use
         */
        chain_ss = sk_X509_pop(ctx->chain);
        ctx->last_untrusted--;
        num--;
        j--;
        x = sk_X509_value(ctx->chain, num - 1);
      }
    }
    /* We now lookup certs from the certificate store */
    for (;;) {
      /* If we have enough, we break */
      if (depth < num)
        break;
      /* If we are self signed, we break */
      if (cert_self_signed(x))
        break;
      ok = ctx->get_issuer(&xtmp, ctx, x);

      if (ok < 0) {
        ctx->error = X509_V_ERR_STORE_LOOKUP;
        goto end;
      }
      if (ok == 0)
        break;
      x = xtmp;
      if (!sk_X509_push(ctx->chain, x)) {
        X509_free(xtmp);
        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
        ctx->error = X509_V_ERR_OUT_OF_MEM;
        ok = 0;
        goto end;
      }
      num++;
    }

    /* we now have our chain, lets check it... */
    trust = check_trust(ctx);

    /* If explicitly rejected error */
    if (trust == X509_TRUST_REJECTED) {
      ok = 0;
      goto end;
    }
    /*
     * If it's not explicitly trusted then check if there is an alternative
     * chain that could be used. We only do this if we haven't already
     * checked via TRUSTED_FIRST and the user hasn't switched off alternate
     * chain checking
     */
    retry = 0;
    if (trust != X509_TRUST_TRUSTED &&
        !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) &&
        !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
      while (j-- > 1) {
        xtmp2 = sk_X509_value(ctx->chain, j - 1);
        ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
        if (ok < 0)
          goto end;
        /* Check if we found an alternate chain */
        if (ok > 0) {
          /*
           * Free up the found cert we'll add it again later
           */
          X509_free(xtmp);

          /*
           * Dump all the certs above this point - we've found an
           * alternate chain
           */
          while (num > j) {
            xtmp = sk_X509_pop(ctx->chain);
            X509_free(xtmp);
            num--;
          }
          ctx->last_untrusted = sk_X509_num(ctx->chain);
          retry = 1;
          break;
        }
      }
    }
  } while (retry);

  /*
   * If not explicitly trusted then indicate error unless it's a single
   * self signed certificate in which case we've indicated an error already
   * and set bad_chain == 1
   */
  if (trust != X509_TRUST_TRUSTED && !bad_chain) {
    if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
      if (ctx->last_untrusted >= num)
        ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
      else
        ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
      ctx->current_cert = x;
    } else {
      sk_X509_push(ctx->chain, chain_ss);
      num++;
      ctx->last_untrusted = num;
      ctx->current_cert = chain_ss;
      ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
      chain_ss = NULL;
    }

    ctx->error_depth = num - 1;
    bad_chain = 1;
    ok = cb(0, ctx);
    if (!ok)
      goto end;
  }

  /* We have the chain complete: now we need to check its purpose */
  ok = check_chain_extensions(ctx);

  if (!ok)
    goto end;

  ok = check_id(ctx);

  if (!ok)
    goto end;

  /*
   * Check revocation status: we do this after copying parameters because
   * they may be needed for CRL signature verification.
   */

  ok = ctx->check_revocation(ctx);
  if (!ok)
    goto end;

  int err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
                                    ctx->param->flags);
  if (err != X509_V_OK) {
    ctx->error = err;
    ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
    ok = cb(0, ctx);
    if (!ok)
      goto end;
  }

  /* At this point, we have a chain and need to verify it */
  if (ctx->verify != NULL)
    ok = ctx->verify(ctx);
  else
    ok = internal_verify(ctx);
  if (!ok)
    goto end;

  /* Check name constraints */

  ok = check_name_constraints(ctx);
  if (!ok)
    goto end;

  /* If we get this far evaluate policies */
  if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
    ok = ctx->check_policy(ctx);

end:
  if (sktmp != NULL)
    sk_X509_free(sktmp);
  if (chain_ss != NULL)
    X509_free(chain_ss);

  /* Safety net, error returns must set ctx->error */
  if (ok <= 0 && ctx->error == X509_V_OK)
    ctx->error = X509_V_ERR_UNSPECIFIED;
  return ok;
}

/*
 * Given a STACK_OF(X509) find the issuer of cert (if any)
 */

static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) * sk, X509 *x) {
  size_t i;
  X509 *issuer;
  for (i = 0; i < sk_X509_num(sk); i++) {
    issuer = sk_X509_value(sk, i);
    if (ctx->check_issued(ctx, x, issuer))
      return issuer;
  }
  return NULL;
}

/* Given a possible certificate and issuer check them */

static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) {
  int ret;
  ret = X509_check_issued(issuer, x);
  if (ret == X509_V_OK)
    return 1;
  /* If we haven't asked for issuer errors don't set ctx */
  if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
    return 0;

  ctx->error = ret;
  ctx->current_cert = x;
  ctx->current_issuer = issuer;
  return ctx->verify_cb(0, ctx);
}

/* Alternative lookup method: look from a STACK stored in other_ctx */

static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) {
  *issuer = find_issuer(ctx, ctx->other_ctx, x);
  if (*issuer) {
    X509_up_ref(*issuer);
    return 1;
  } else
    return 0;
}

/*
 * Check a certificate chains extensions for consistency with the supplied
 * purpose
 */

static int check_chain_extensions(X509_STORE_CTX *ctx) {
  int i, ok = 0, plen = 0;
  X509 *x;
  int (*cb)(int xok, X509_STORE_CTX *xctx);
  int proxy_path_length = 0;
  int purpose;
  int allow_proxy_certs;
  cb = ctx->verify_cb;

  enum {
    // ca_or_leaf allows either type of certificate so that direct use of
    // self-signed certificates works.
    ca_or_leaf,
    must_be_ca,
    must_not_be_ca,
  } ca_requirement;

  /* CRL path validation */
  if (ctx->parent) {
    allow_proxy_certs = 0;
    purpose = X509_PURPOSE_CRL_SIGN;
  } else {
    allow_proxy_certs = !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
    purpose = ctx->param->purpose;
  }

  ca_requirement = ca_or_leaf;

  /* Check all untrusted certificates */
  for (i = 0; i < ctx->last_untrusted; i++) {
    int ret;
    x = sk_X509_value(ctx->chain, i);
    if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) &&
        (x->ex_flags & EXFLAG_CRITICAL)) {
      ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
      ctx->error_depth = i;
      ctx->current_cert = x;
      ok = cb(0, ctx);
      if (!ok)
        goto end;
    }
    if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
      ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
      ctx->error_depth = i;
      ctx->current_cert = x;
      ok = cb(0, ctx);
      if (!ok)
        goto end;
    }

    switch (ca_requirement) {
      case ca_or_leaf:
        ret = 1;
        break;
      case must_not_be_ca:
        if (X509_check_ca(x)) {
          ret = 0;
          ctx->error = X509_V_ERR_INVALID_NON_CA;
        } else
          ret = 1;
        break;
      case must_be_ca:
        if (!X509_check_ca(x)) {
          ret = 0;
          ctx->error = X509_V_ERR_INVALID_CA;
        } else
          ret = 1;
        break;
      default:
        // impossible.
        ret = 0;
    }

    if (ret == 0) {
      ctx->error_depth = i;
      ctx->current_cert = x;
      ok = cb(0, ctx);
      if (!ok)
        goto end;
    }
    if (ctx->param->purpose > 0) {
      ret = X509_check_purpose(x, purpose, ca_requirement == must_be_ca);
      if (ret != 1) {
        ret = 0;
        ctx->error = X509_V_ERR_INVALID_PURPOSE;
        ctx->error_depth = i;
        ctx->current_cert = x;
        ok = cb(0, ctx);
        if (!ok)
          goto end;
      }
    }
    /* Check pathlen if not self issued */
    if ((i > 1) && !(x->ex_flags & EXFLAG_SI) && (x->ex_pathlen != -1) &&
        (plen > (x->ex_pathlen + proxy_path_length + 1))) {
      ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
      ctx->error_depth = i;
      ctx->current_cert = x;
      ok = cb(0, ctx);
      if (!ok)
        goto end;
    }
    /* Increment path length if not self issued */
    if (!(x->ex_flags & EXFLAG_SI))
      plen++;
    /*
     * If this certificate is a proxy certificate, the next certificate
     * must be another proxy certificate or a EE certificate.  If not,
     * the next certificate must be a CA certificate.
     */
    if (x->ex_flags & EXFLAG_PROXY) {
      if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
        ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
        ctx->error_depth = i;
        ctx->current_cert = x;
        ok = cb(0, ctx);
        if (!ok)
          goto end;
      }
      proxy_path_length++;
      ca_requirement = must_not_be_ca;
    } else {
      ca_requirement = must_be_ca;
    }
  }
  ok = 1;
end:
  return ok;
}

static int check_name_constraints(X509_STORE_CTX *ctx) {
  X509 *x;
  int i, j, rv;
  /* Check name constraints for all certificates */
  for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) {
    x = sk_X509_value(ctx->chain, i);
    /* Ignore self issued certs unless last in chain */
    if (i && (x->ex_flags & EXFLAG_SI))
      continue;
    /*
     * Check against constraints for all certificates higher in chain
     * including trust anchor. Trust anchor not strictly speaking needed
     * but if it includes constraints it is to be assumed it expects them
     * to be obeyed.
     */
    for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
      NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
      if (nc) {
        rv = NAME_CONSTRAINTS_check(x, nc);
        switch (rv) {
          case X509_V_OK:
            continue;
          case X509_V_ERR_OUT_OF_MEM:
            ctx->error = rv;
            return 0;
          default:
            ctx->error = rv;
            ctx->error_depth = i;
            ctx->current_cert = x;
            if (!ctx->verify_cb(0, ctx))
              return 0;
            break;
        }
      }
    }
  }
  return 1;
}

static int check_id_error(X509_STORE_CTX *ctx, int errcode) {
  ctx->error = errcode;
  ctx->current_cert = ctx->cert;
  ctx->error_depth = 0;
  return ctx->verify_cb(0, ctx);
}

static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id) {
  size_t i;
  size_t n = sk_OPENSSL_STRING_num(id->hosts);
  char *name;

  if (id->peername != NULL) {
    OPENSSL_free(id->peername);
    id->peername = NULL;
  }
  for (i = 0; i < n; ++i) {
    name = sk_OPENSSL_STRING_value(id->hosts, i);
    if (X509_check_host(x, name, OPENSSL_port_strlen(name), id->hostflags, &id->peername) >
        0)
      return 1;
  }
  return n == 0;
}

static int check_id(X509_STORE_CTX *ctx) {
  X509_VERIFY_PARAM *vpm = ctx->param;
  X509_VERIFY_PARAM_ID *id = vpm->id;
  X509 *x = ctx->cert;
  if (id->poison) {
    if (!check_id_error(ctx, X509_V_ERR_INVALID_CALL))
      return 0;
  }
  if (id->hosts && check_hosts(x, id) <= 0) {
    if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
      return 0;
  }
  if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0) {
    if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
      return 0;
  }
  if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0) {
    if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
      return 0;
  }
  return 1;
}

static int check_trust(X509_STORE_CTX *ctx) {
  size_t i;
  int ok;
  X509 *x = NULL;
  int (*cb)(int xok, X509_STORE_CTX *xctx);
  cb = ctx->verify_cb;
  /* Check all trusted certificates in chain */
  for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
    x = sk_X509_value(ctx->chain, i);
    ok = X509_check_trust(x, ctx->param->trust, 0);
    /* If explicitly trusted return trusted */
    if (ok == X509_TRUST_TRUSTED)
      return X509_TRUST_TRUSTED;
    /*
     * If explicitly rejected notify callback and reject if not
     * overridden.
     */
    if (ok == X509_TRUST_REJECTED) {
      ctx->error_depth = i;
      ctx->current_cert = x;
      ctx->error = X509_V_ERR_CERT_REJECTED;
      ok = cb(0, ctx);
      if (!ok)
        return X509_TRUST_REJECTED;
    }
  }
  /*
   * If we accept partial chains and have at least one trusted certificate
   * return success.
   */
  if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
    X509 *mx;
    if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain))
      return X509_TRUST_TRUSTED;
    x = sk_X509_value(ctx->chain, 0);
    mx = lookup_cert_match(ctx, x);
    if (mx) {
      (void)sk_X509_set(ctx->chain, 0, mx);
      X509_free(x);
      ctx->last_untrusted = 0;
      return X509_TRUST_TRUSTED;
    }
  }

  /*
   * If no trusted certs in chain at all return untrusted and allow
   * standard (no issuer cert) etc errors to be indicated.
   */
  return X509_TRUST_UNTRUSTED;
}

static int check_revocation(X509_STORE_CTX *ctx) {
  int i, last, ok;
  if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
    return 1;
  if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
    last = sk_X509_num(ctx->chain) - 1;
  else {
    /* If checking CRL paths this isn't the EE certificate */
    if (ctx->parent)
      return 1;
    last = 0;
  }
  for (i = 0; i <= last; i++) {
    ctx->error_depth = i;
    ok = check_cert(ctx);
    if (!ok)
      return ok;
  }
  return 1;
}

static int check_cert(X509_STORE_CTX *ctx) {
  X509_CRL *crl = NULL, *dcrl = NULL;
  X509 *x;
  int ok = 0, cnum;
  unsigned int last_reasons;
  cnum = ctx->error_depth;
  x = sk_X509_value(ctx->chain, cnum);
  ctx->current_cert = x;
  ctx->current_issuer = NULL;
  ctx->current_crl_score = 0;
  ctx->current_reasons = 0;
  while (ctx->current_reasons != CRLDP_ALL_REASONS) {
    last_reasons = ctx->current_reasons;
    /* Try to retrieve relevant CRL */
    if (ctx->get_crl)
      ok = ctx->get_crl(ctx, &crl, x);
    else
      ok = get_crl_delta(ctx, &crl, &dcrl, x);
    /*
     * If error looking up CRL, nothing we can do except notify callback
     */
    if (!ok) {
      ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
      ok = ctx->verify_cb(0, ctx);
      goto err;
    }
    ctx->current_crl = crl;
    ok = ctx->check_crl(ctx, crl);
    if (!ok)
      goto err;

    if (dcrl) {
      ok = ctx->check_crl(ctx, dcrl);
      if (!ok)
        goto err;
      ok = ctx->cert_crl(ctx, dcrl, x);
      if (!ok)
        goto err;
    } else
      ok = 1;

    /* Don't look in full CRL if delta reason is removefromCRL */
    if (ok != 2) {
      ok = ctx->cert_crl(ctx, crl, x);
      if (!ok)
        goto err;
    }

    X509_CRL_free(crl);
    X509_CRL_free(dcrl);
    crl = NULL;
    dcrl = NULL;
    /*
     * If reasons not updated we wont get anywhere by another iteration,
     * so exit loop.
     */
    if (last_reasons == ctx->current_reasons) {
      ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
      ok = ctx->verify_cb(0, ctx);
      goto err;
    }
  }
err:
  X509_CRL_free(crl);
  X509_CRL_free(dcrl);

  ctx->current_crl = NULL;
  return ok;
}

/* Check CRL times against values in X509_STORE_CTX */

static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) {
  OPENSSL_port_time_t *ptime;
  int i;
  if (notify)
    ctx->current_crl = crl;
  if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
    ptime = &ctx->param->check_time;
  else
    ptime = NULL;

  i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
  if (i == 0) {
    if (!notify)
      return 0;
    ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
    if (!ctx->verify_cb(0, ctx))
      return 0;
  }

  if (i > 0) {
    if (!notify)
      return 0;
    ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
    if (!ctx->verify_cb(0, ctx))
      return 0;
  }

  if (X509_CRL_get_nextUpdate(crl)) {
    i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);

    if (i == 0) {
      if (!notify)
        return 0;
      ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
      if (!ctx->verify_cb(0, ctx))
        return 0;
    }
    /* Ignore expiry of base CRL is delta is valid */
    if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
      if (!notify)
        return 0;
      ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
      if (!ctx->verify_cb(0, ctx))
        return 0;
    }
  }

  if (notify)
    ctx->current_crl = NULL;

  return 1;
}

static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
                      X509 **pissuer, int *pscore, unsigned int *preasons,
                      STACK_OF(X509_CRL) * crls) {
  int crl_score, best_score = *pscore;
  size_t i;
  unsigned int reasons, best_reasons = 0;
  X509 *x = ctx->current_cert;
  X509_CRL *crl, *best_crl = NULL;
  X509 *crl_issuer = NULL, *best_crl_issuer = NULL;

  for (i = 0; i < sk_X509_CRL_num(crls); i++) {
    crl = sk_X509_CRL_value(crls, i);
    reasons = *preasons;
    crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
    if (crl_score < best_score || crl_score == 0)
      continue;
    /* If current CRL is equivalent use it if it is newer */
    if (crl_score == best_score && best_crl != NULL) {
      int day, sec;
      if (ASN1_TIME_diff(&day, &sec, X509_CRL_get_lastUpdate(best_crl),
                         X509_CRL_get_lastUpdate(crl)) == 0)
        continue;
      /*
       * ASN1_TIME_diff never returns inconsistent signs for |day|
       * and |sec|.
       */
      if (day <= 0 && sec <= 0)
        continue;
    }
    best_crl = crl;
    best_crl_issuer = crl_issuer;
    best_score = crl_score;
    best_reasons = reasons;
  }

  if (best_crl) {
    if (*pcrl)
      X509_CRL_free(*pcrl);
    *pcrl = best_crl;
    *pissuer = best_crl_issuer;
    *pscore = best_score;
    *preasons = best_reasons;
    X509_CRL_up_ref(best_crl);
    if (*pdcrl) {
      X509_CRL_free(*pdcrl);
      *pdcrl = NULL;
    }
    get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
  }

  if (best_score >= CRL_SCORE_VALID)
    return 1;

  return 0;
}

/*
 * Compare two CRL extensions for delta checking purposes. They should be
 * both present or both absent. If both present all fields must be identical.
 */

static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) {
  ASN1_OCTET_STRING *exta, *extb;
  int i;
  i = X509_CRL_get_ext_by_NID(a, nid, -1);
  if (i >= 0) {
    /* Can't have multiple occurrences */
    if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
      return 0;
    exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
  } else
    exta = NULL;

  i = X509_CRL_get_ext_by_NID(b, nid, -1);

  if (i >= 0) {
    if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
      return 0;
    extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
  } else
    extb = NULL;

  if (!exta && !extb)
    return 1;

  if (!exta || !extb)
    return 0;

  if (ASN1_OCTET_STRING_cmp(exta, extb))
    return 0;

  return 1;
}

/* See if a base and delta are compatible */

static int check_delta_base(X509_CRL *delta, X509_CRL *base) {
  /* Delta CRL must be a delta */
  if (!delta->base_crl_number)
    return 0;
  /* Base must have a CRL number */
  if (!base->crl_number)
    return 0;
  /* Issuer names must match */
  if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta)))
    return 0;
  /* AKID and IDP must match */
  if (!crl_extension_match(delta, base, NID_authority_key_identifier))
    return 0;
  if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
    return 0;
  /* Delta CRL base number must not exceed Full CRL number. */
  if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
    return 0;
  /* Delta CRL number must exceed full CRL number */
  if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
    return 1;
  return 0;
}

/*
 * For a given base CRL find a delta... maybe extend to delta scoring or
 * retrieve a chain of deltas...
 */

static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
                         X509_CRL *base, STACK_OF(X509_CRL) * crls) {
  X509_CRL *delta;
  size_t i;
  if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
    return;
  if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
    return;
  for (i = 0; i < sk_X509_CRL_num(crls); i++) {
    delta = sk_X509_CRL_value(crls, i);
    if (check_delta_base(delta, base)) {
      if (check_crl_time(ctx, delta, 0))
        *pscore |= CRL_SCORE_TIME_DELTA;
      X509_CRL_up_ref(delta);
      *dcrl = delta;
      return;
    }
  }
  *dcrl = NULL;
}

/*
 * For a given CRL return how suitable it is for the supplied certificate
 * 'x'. The return value is a mask of several criteria. If the issuer is not
 * the certificate issuer this is returned in *pissuer. The reasons mask is
 * also used to determine if the CRL is suitable: if no new reasons the CRL
 * is rejected, otherwise reasons is updated.
 */

static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
                         unsigned int *preasons, X509_CRL *crl, X509 *x) {
  int crl_score = 0;
  unsigned int tmp_reasons = *preasons, crl_reasons;

  /* First see if we can reject CRL straight away */

  /* Invalid IDP cannot be processed */
  if (crl->idp_flags & IDP_INVALID)
    return 0;
  /* Reason codes or indirect CRLs need extended CRL support */
  if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
    if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
      return 0;
  } else if (crl->idp_flags & IDP_REASONS) {
    /* If no new reasons reject */
    if (!(crl->idp_reasons & ~tmp_reasons))
      return 0;
  }
  /* Don't process deltas at this stage */
  else if (crl->base_crl_number)
    return 0;
  /* If issuer name doesn't match certificate need indirect CRL */
  if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
    if (!(crl->idp_flags & IDP_INDIRECT))
      return 0;
  } else
    crl_score |= CRL_SCORE_ISSUER_NAME;

  if (!(crl->flags & EXFLAG_CRITICAL))
    crl_score |= CRL_SCORE_NOCRITICAL;

  /* Check expiry */
  if (check_crl_time(ctx, crl, 0))
    crl_score |= CRL_SCORE_TIME;

  /* Check authority key ID and locate certificate issuer */
  crl_akid_check(ctx, crl, pissuer, &crl_score);

  /* If we can't locate certificate issuer at this point forget it */

  if (!(crl_score & CRL_SCORE_AKID))
    return 0;

  /* Check cert for matching CRL distribution points */

  if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) {
    /* If no new reasons reject */
    if (!(crl_reasons & ~tmp_reasons))
      return 0;
    tmp_reasons |= crl_reasons;
    crl_score |= CRL_SCORE_SCOPE;
  }

  *preasons = tmp_reasons;

  return crl_score;
}

static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
                           int *pcrl_score) {
  X509 *crl_issuer = NULL;
  X509_NAME *cnm = X509_CRL_get_issuer(crl);
  int cidx = ctx->error_depth;
  size_t i;

  if ((size_t)cidx != sk_X509_num(ctx->chain) - 1)
    cidx++;

  crl_issuer = sk_X509_value(ctx->chain, cidx);

  if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
    if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
      *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT;
      *pissuer = crl_issuer;
      return;
    }
  }

  for (cidx++; cidx < (int)sk_X509_num(ctx->chain); cidx++) {
    crl_issuer = sk_X509_value(ctx->chain, cidx);
    if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
      continue;
    if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
      *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
      *pissuer = crl_issuer;
      return;
    }
  }

  /* Anything else needs extended CRL support */

  if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
    return;

  /*
   * Otherwise the CRL issuer is not on the path. Look for it in the set of
   * untrusted certificates.
   */
  for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
    crl_issuer = sk_X509_value(ctx->untrusted, i);
    if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
      continue;
    if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
      *pissuer = crl_issuer;
      *pcrl_score |= CRL_SCORE_AKID;
      return;
    }
  }

  for (i = 0; i < sk_X509_num(ctx->ctx->additional_untrusted); i++) {
    crl_issuer = sk_X509_value(ctx->ctx->additional_untrusted, i);
    if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
      continue;
    if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
      *pissuer = crl_issuer;
      *pcrl_score |= CRL_SCORE_AKID;
      return;
    }
  }
}

/*
 * Check the path of a CRL issuer certificate. This creates a new
 * X509_STORE_CTX and populates it with most of the parameters from the
 * parent. This could be optimised somewhat since a lot of path checking will
 * be duplicated by the parent, but this will rarely be used in practice.
 */

static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) {
  X509_STORE_CTX crl_ctx;
  int ret;
  /* Don't allow recursive CRL path validation */
  if (ctx->parent)
    return 0;
  if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
    return -1;

  crl_ctx.crls = ctx->crls;
  /* Copy verify params across */
  X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);

  crl_ctx.parent = ctx;
  crl_ctx.verify_cb = ctx->verify_cb;

  /* Verify CRL issuer */
  ret = X509_verify_cert(&crl_ctx);

  if (ret <= 0)
    goto err;

  /* Check chain is acceptable */

  ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
err:
  X509_STORE_CTX_cleanup(&crl_ctx);
  return ret;
}

/*
 * RFC3280 says nothing about the relationship between CRL path and
 * certificate path, which could lead to situations where a certificate could
 * be revoked or validated by a CA not authorised to do so. RFC5280 is more
 * strict and states that the two paths must end in the same trust anchor,
 * though some discussions remain... until this is resolved we use the
 * RFC5280 version
 */

static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) * cert_path,
                           STACK_OF(X509) * crl_path) {
  X509 *cert_ta, *crl_ta;
  cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
  crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
  if (!X509_cmp(cert_ta, crl_ta))
    return 1;
  return 0;
}

/*
 * Check for match between two dist point names: three separate cases. 1.
 * Both are relative names and compare X509_NAME types. 2. One full, one
 * relative. Compare X509_NAME to GENERAL_NAMES. 3. Both are full names and
 * compare two GENERAL_NAMES. 4. One is NULL: automatic match.
 */

static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) {
  X509_NAME *nm = NULL;
  GENERAL_NAMES *gens = NULL;
  GENERAL_NAME *gena, *genb;
  size_t i, j;
  if (!a || !b)
    return 1;
  if (a->type == 1) {
    if (!a->dpname)
      return 0;
    /* Case 1: two X509_NAME */
    if (b->type == 1) {
      if (!b->dpname)
        return 0;
      if (!X509_NAME_cmp(a->dpname, b->dpname))
        return 1;
      else
        return 0;
    }
    /* Case 2: set name and GENERAL_NAMES appropriately */
    nm = a->dpname;
    gens = b->name.fullname;
  } else if (b->type == 1) {
    if (!b->dpname)
      return 0;
    /* Case 2: set name and GENERAL_NAMES appropriately */
    gens = a->name.fullname;
    nm = b->dpname;
  }

  /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
  if (nm) {
    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
      gena = sk_GENERAL_NAME_value(gens, i);
      if (gena->type != GEN_DIRNAME)
        continue;
      if (!X509_NAME_cmp(nm, gena->d.directoryName))
        return 1;
    }
    return 0;
  }

  /* Else case 3: two GENERAL_NAMES */

  for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) {
    gena = sk_GENERAL_NAME_value(a->name.fullname, i);
    for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) {
      genb = sk_GENERAL_NAME_value(b->name.fullname, j);
      if (!GENERAL_NAME_cmp(gena, genb))
        return 1;
    }
  }

  return 0;
}

static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) {
  size_t i;
  X509_NAME *nm = X509_CRL_get_issuer(crl);
  /* If no CRLissuer return is successful iff don't need a match */
  if (!dp->CRLissuer)
    return !!(crl_score & CRL_SCORE_ISSUER_NAME);
  for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
    GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
    if (gen->type != GEN_DIRNAME)
      continue;
    if (!X509_NAME_cmp(gen->d.directoryName, nm))
      return 1;
  }
  return 0;
}

/* Check CRLDP and IDP */

static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
                           unsigned int *preasons) {
  size_t i;
  if (crl->idp_flags & IDP_ONLYATTR)
    return 0;
  if (x->ex_flags & EXFLAG_CA) {
    if (crl->idp_flags & IDP_ONLYUSER)
      return 0;
  } else {
    if (crl->idp_flags & IDP_ONLYCA)
      return 0;
  }
  *preasons = crl->idp_reasons;
  for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
    DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
    if (crldp_check_crlissuer(dp, crl, crl_score)) {
      if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
        *preasons &= dp->dp_reasons;
        return 1;
      }
    }
  }
  if ((!crl->idp || !crl->idp->distpoint) &&
      (crl_score & CRL_SCORE_ISSUER_NAME))
    return 1;
  return 0;
}

/*
 * Retrieve CRL corresponding to current certificate. If deltas enabled try
 * to find a delta CRL too
 */

static int get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
                         X509 *x) {
  int ok;
  X509 *issuer = NULL;
  int crl_score = 0;
  unsigned int reasons;
  X509_CRL *crl = NULL, *dcrl = NULL;
  STACK_OF(X509_CRL) * skcrl;
  X509_NAME *nm = X509_get_issuer_name(x);
  reasons = ctx->current_reasons;
  ok = get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, ctx->crls);

  if (ok)
    goto done;

  /* Lookup CRLs from store */

  skcrl = ctx->lookup_crls(ctx, nm);

  /* If no CRLs found and a near match from get_crl_sk use that */
  if (!skcrl && crl)
    goto done;

  get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);

  sk_X509_CRL_pop_free(skcrl, X509_CRL_free);

done:

  /* If we got any kind of CRL use it and return success */
  if (crl) {
    ctx->current_issuer = issuer;
    ctx->current_crl_score = crl_score;
    ctx->current_reasons = reasons;
    *pcrl = crl;
    *pdcrl = dcrl;
    return 1;
  }

  return 0;
}

/* Check CRL validity */
static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) {
  X509 *issuer = NULL;
  EVP_PKEY *ikey = NULL;
  int ok = 0, chnum, cnum;
  cnum = ctx->error_depth;
  chnum = sk_X509_num(ctx->chain) - 1;
  /* if we have an alternative CRL issuer cert use that */
  if (ctx->current_issuer)
    issuer = ctx->current_issuer;

  /*
   * Else find CRL issuer: if not last certificate then issuer is next
   * certificate in chain.
   */
  else if (cnum < chnum)
    issuer = sk_X509_value(ctx->chain, cnum + 1);
  else {
    issuer = sk_X509_value(ctx->chain, chnum);
    /* If not self signed, can't check signature */
    if (!ctx->check_issued(ctx, issuer, issuer)) {
      ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
      ok = ctx->verify_cb(0, ctx);
      if (!ok)
        goto err;
    }
  }

  if (issuer) {
    /*
     * Skip most tests for deltas because they have already been done
     */
    if (!crl->base_crl_number) {
      /* Check for cRLSign bit if keyUsage present */
      if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
          !(issuer->ex_kusage & KU_CRL_SIGN)) {
        ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
        ok = ctx->verify_cb(0, ctx);
        if (!ok)
          goto err;
      }

      if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
        ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
        ok = ctx->verify_cb(0, ctx);
        if (!ok)
          goto err;
      }

      if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
        if (check_crl_path(ctx, ctx->current_issuer) <= 0) {
          ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
          ok = ctx->verify_cb(0, ctx);
          if (!ok)
            goto err;
        }
      }

      if (crl->idp_flags & IDP_INVALID) {
        ctx->error = X509_V_ERR_INVALID_EXTENSION;
        ok = ctx->verify_cb(0, ctx);
        if (!ok)
          goto err;
      }
    }

    if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
      ok = check_crl_time(ctx, crl, 1);
      if (!ok)
        goto err;
    }

    /* Attempt to get issuer certificate public key */
    ikey = X509_get_pubkey(issuer);

    if (!ikey) {
      ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
      ok = ctx->verify_cb(0, ctx);
      if (!ok)
        goto err;
    } else {
      int rv;
      rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
      if (rv != X509_V_OK) {
        ctx->error = rv;
        ok = ctx->verify_cb(0, ctx);
        if (!ok)
          goto err;
      }
      /* Verify CRL signature */
      if (X509_CRL_verify(crl, ikey) <= 0) {
        ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
        ok = ctx->verify_cb(0, ctx);
        if (!ok)
          goto err;
      }
    }
  }

  ok = 1;

err:
  EVP_PKEY_free(ikey);
  return ok;
}

/* Check certificate against CRL */
static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) {
  int ok;
  X509_REVOKED *rev;
  /*
   * The rules changed for this... previously if a CRL contained unhandled
   * critical extensions it could still be used to indicate a certificate
   * was revoked. This has since been changed since critical extension can
   * change the meaning of CRL entries.
   */
  if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) &&
      (crl->flags & EXFLAG_CRITICAL)) {
    ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
    ok = ctx->verify_cb(0, ctx);
    if (!ok)
      return 0;
  }
  /*
   * Look for serial number of certificate in CRL If found make sure reason
   * is not removeFromCRL.
   */
  if (X509_CRL_get0_by_cert(crl, &rev, x)) {
    if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
      return 2;
    ctx->error = X509_V_ERR_CERT_REVOKED;
    ok = ctx->verify_cb(0, ctx);
    if (!ok)
      return 0;
  }

  return 1;
}

static int check_policy(X509_STORE_CTX *ctx) {
  int ret;
  if (ctx->parent)
    return 1;
  ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
                          ctx->param->policies, ctx->param->flags);
  if (ret == 0) {
    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
    ctx->error = X509_V_ERR_OUT_OF_MEM;
    return 0;
  }
  /* Invalid or inconsistent extensions */
  if (ret == -1) {
    /*
     * Locate certificates with bad extensions and notify callback.
     */
    X509 *x;
    size_t i;
    for (i = 1; i < sk_X509_num(ctx->chain); i++) {
      x = sk_X509_value(ctx->chain, i);
      if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
        continue;
      ctx->current_cert = x;
      ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
      if (!ctx->verify_cb(0, ctx))
        return 0;
    }
    return 1;
  }
  if (ret == -2) {
    ctx->current_cert = NULL;
    ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
    return ctx->verify_cb(0, ctx);
  }

  if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
    ctx->current_cert = NULL;
    /*
     * Verification errors need to be "sticky", a callback may have allowed
     * an SSL handshake to continue despite an error, and we must then
     * remain in an error state.  Therefore, we MUST NOT clear earlier
     * verification errors by setting the error to X509_V_OK.
     */
    if (!ctx->verify_cb(2, ctx))
      return 0;
  }

  return 1;
}

static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) {
  OPENSSL_port_time_t *ptime;
  int i;

  if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
    ptime = &ctx->param->check_time;
  else
    ptime = NULL;

  i = X509_cmp_time(X509_get_notBefore(x), ptime);
  if (i == 0) {
    ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
    ctx->current_cert = x;
    if (!ctx->verify_cb(0, ctx))
      return 0;
  }

  if (i > 0) {
    ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
    ctx->current_cert = x;
    if (!ctx->verify_cb(0, ctx))
      return 0;
  }

  i = X509_cmp_time(X509_get_notAfter(x), ptime);
  if (i == 0) {
    ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
    ctx->current_cert = x;
    if (!ctx->verify_cb(0, ctx))
      return 0;
  }

  if (i < 0) {
    ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
    ctx->current_cert = x;
    if (!ctx->verify_cb(0, ctx))
      return 0;
  }

  return 1;
}

static int internal_verify(X509_STORE_CTX *ctx) {
  int ok = 0, n;
  X509 *xs, *xi;
  EVP_PKEY *pkey = NULL;
  int (*cb)(int xok, X509_STORE_CTX *xctx);

  cb = ctx->verify_cb;

  n = sk_X509_num(ctx->chain);
  ctx->error_depth = n - 1;
  n--;
  xi = sk_X509_value(ctx->chain, n);

  if (ctx->check_issued(ctx, xi, xi))
    xs = xi;
  else {
    if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
      xs = xi;
      goto check_cert;
    }
    if (n <= 0) {
      ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
      ctx->current_cert = xi;
      ok = cb(0, ctx);
      goto end;
    } else {
      n--;
      ctx->error_depth = n;
      xs = sk_X509_value(ctx->chain, n);
    }
  }

  /*      ctx->error=0;  not needed */
  while (n >= 0) {
    ctx->error_depth = n;

    /*
     * Skip signature check for self signed certificates unless
     * explicitly asked for. It doesn't add any security and just wastes
     * time.
     */
    if (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) {
      if ((pkey = X509_get_pubkey(xi)) == NULL) {
        ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
        ctx->current_cert = xi;
        ok = (*cb)(0, ctx);
        if (!ok)
          goto end;
      } else if (X509_verify(xs, pkey) <= 0) {
        ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
        ctx->current_cert = xs;
        ok = (*cb)(0, ctx);
        if (!ok) {
          EVP_PKEY_free(pkey);
          goto end;
        }
      }
      EVP_PKEY_free(pkey);
      pkey = NULL;
    }

  check_cert:
    ok = check_cert_time(ctx, xs);
    if (!ok)
      goto end;

    /* The last error (if any) is still in the error value */
    ctx->current_issuer = xi;
    ctx->current_cert = xs;
    ok = (*cb)(1, ctx);
    if (!ok)
      goto end;

    n--;
    if (n >= 0) {
      xi = xs;
      xs = sk_X509_value(ctx->chain, n);
    }
  }
  ok = 1;
end:
  return ok;
}

int X509_cmp_current_time(const ASN1_TIME *ctm) {
  return X509_cmp_time(ctm, NULL);
}

int X509_cmp_time(const ASN1_TIME *ctm, OPENSSL_port_time_t *cmp_time) {
  char *str;
  ASN1_TIME atm;
  long offset;
  char buff1[24], buff2[24], *p;
  int i, j, remaining;

  p = buff1;
  remaining = ctm->length;
  str = (char *)ctm->data;
  /*
   * Note that the following (historical) code allows much more slack in the
   * time format than RFC5280. In RFC5280, the representation is fixed:
   * UTCTime: YYMMDDHHMMSSZ
   * GeneralizedTime: YYYYMMDDHHMMSSZ
   */
  if (ctm->type == V_ASN1_UTCTIME) {
    /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
    int min_length = sizeof("YYMMDDHHMMZ") - 1;
    int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
    if (remaining < min_length || remaining > max_length)
      return 0;
    OPENSSL_port_memcpy(p, str, 10);
    p += 10;
    str += 10;
    remaining -= 10;
  } else {
    /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
    int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
    int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
    if (remaining < min_length || remaining > max_length)
      return 0;
    OPENSSL_port_memcpy(p, str, 12);
    p += 12;
    str += 12;
    remaining -= 12;
  }

  if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
    *(p++) = '0';
    *(p++) = '0';
  } else {
    /* SS (seconds) */
    if (remaining < 2)
      return 0;
    *(p++) = *(str++);
    *(p++) = *(str++);
    remaining -= 2;
    /*
     * Skip any (up to three) fractional seconds...
     * TODO(emilia): in RFC5280, fractional seconds are forbidden.
     * Can we just kill them altogether?
     */
    if (remaining && *str == '.') {
      str++;
      remaining--;
      for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
        if (*str < '0' || *str > '9')
          break;
      }
    }
  }
  *(p++) = 'Z';
  *(p++) = '\0';

  /* We now need either a terminating 'Z' or an offset. */
  if (!remaining)
    return 0;
  if (*str == 'Z') {
    if (remaining != 1)
      return 0;
    offset = 0;
  } else {
    /* (+-)HHMM */
    if ((*str != '+') && (*str != '-'))
      return 0;
    /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
    if (remaining != 5)
      return 0;
    if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
        str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
      return 0;
    offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
    offset += (str[3] - '0') * 10 + (str[4] - '0');
    if (*str == '-')
      offset = -offset;
  }
  atm.type = ctm->type;
  atm.flags = 0;
  atm.length = sizeof(buff2);
  atm.data = (unsigned char *)buff2;

  if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
    return 0;

  if (ctm->type == V_ASN1_UTCTIME) {
    i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
    if (i < 50)
      i += 100; /* cf. RFC 2459 */
    j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
    if (j < 50)
      j += 100;

    if (i < j)
      return -1;
    if (i > j)
      return 1;
  }
  i = OPENSSL_port_strcmp(buff1, buff2);
  if (i == 0) /* wait a second then return younger :-) */
    return -1;
  else
    return i;
}

ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) {
  return X509_time_adj(s, adj, NULL);
}

ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, OPENSSL_port_time_t *in_tm) {
  return X509_time_adj_ex(s, 0, offset_sec, in_tm);
}

ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec,
                            OPENSSL_port_time_t *in_tm) {
  OPENSSL_port_time_t t = 0;

  if (in_tm)
    t = *in_tm;
  else
    OPENSSL_port_time(&t);

  if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) {
    if (s->type == V_ASN1_UTCTIME)
      return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
    if (s->type == V_ASN1_GENERALIZEDTIME)
      return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
  }
  return ASN1_TIME_adj(s, t, offset_day, offset_sec);
}

/* Make a delta CRL as the diff between two full CRLs */

X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, EVP_PKEY *skey,
                        const EVP_MD *md, unsigned int flags) {
  X509_CRL *crl = NULL;
  int i;
  size_t j;
  STACK_OF(X509_REVOKED) *revs = NULL;
  /* CRLs can't be delta already */
  if (base->base_crl_number || newer->base_crl_number) {
    OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA);
    return NULL;
  }
  /* Base and new CRL must have a CRL number */
  if (!base->crl_number || !newer->crl_number) {
    OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER);
    return NULL;
  }
  /* Issuer names must match */
  if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) {
    OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH);
    return NULL;
  }
  /* AKID and IDP must match */
  if (!crl_extension_match(base, newer, NID_authority_key_identifier)) {
    OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH);
    return NULL;
  }
  if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) {
    OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH);
    return NULL;
  }
  /* Newer CRL number must exceed full CRL number */
  if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) {
    OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER);
    return NULL;
  }
  /* CRLs must verify */
  if (skey &&
      (X509_CRL_verify(base, skey) <= 0 || X509_CRL_verify(newer, skey) <= 0)) {
    OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE);
    return NULL;
  }
  /* Create new CRL */
  crl = X509_CRL_new();
  if (!crl || !X509_CRL_set_version(crl, 1))
    goto memerr;
  /* Set issuer name */
  if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
    goto memerr;

  if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer)))
    goto memerr;
  if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer)))
    goto memerr;

  /* Set base CRL number: must be critical */

  if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0))
    goto memerr;

  /*
   * Copy extensions across from newest CRL to delta: this will set CRL
   * number to correct value too.
   */

  for (i = 0; i < X509_CRL_get_ext_count(newer); i++) {
    X509_EXTENSION *ext;
    ext = X509_CRL_get_ext(newer, i);
    if (!X509_CRL_add_ext(crl, ext, -1))
      goto memerr;
  }

  /* Go through revoked entries, copying as needed */

  revs = X509_CRL_get_REVOKED(newer);

  for (j = 0; j < sk_X509_REVOKED_num(revs); j++) {
    X509_REVOKED *rvn, *rvtmp;
    rvn = sk_X509_REVOKED_value(revs, j);
    /*
     * Add only if not also in base. TODO: need something cleverer here
     * for some more complex CRLs covering multiple CAs.
     */
    if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) {
      rvtmp = X509_REVOKED_dup(rvn);
      if (!rvtmp)
        goto memerr;
      if (!X509_CRL_add0_revoked(crl, rvtmp)) {
        X509_REVOKED_free(rvtmp);
        goto memerr;
      }
    }
  }
  /* TODO: optionally prune deleted entries */

  if (skey && md && !X509_CRL_sign(crl, skey, md))
    goto memerr;

  return crl;

memerr:
  OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
  if (crl)
    X509_CRL_free(crl);
  return NULL;
}

int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
                                    CRYPTO_EX_unused *unused,
                                    CRYPTO_EX_dup *dup_unused,
                                    CRYPTO_EX_free *free_func) {
  /*
   * This function is (usually) called only once, by
   * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c).
   */
  int index;
  if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
                               free_func)) {
    return -1;
  }
  return index;
}

int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) {
  return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
}

void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) {
  return CRYPTO_get_ex_data(&ctx->ex_data, idx);
}

int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) { return ctx->error; }

void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) {
  ctx->error = err;
}

int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) {
  return ctx->error_depth;
}

X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) {
  return ctx->current_cert;
}

STACK_OF(X509) * X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) {
  return ctx->chain;
}

STACK_OF(X509) * X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) {
  if (!ctx->chain)
    return NULL;
  return X509_chain_up_ref(ctx->chain);
}

X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) {
  return ctx->current_issuer;
}

X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) {
  return ctx->current_crl;
}

X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) {
  return ctx->parent;
}

void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) { ctx->cert = x; }

void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) * sk) {
  ctx->untrusted = sk;
}

STACK_OF(X509) * X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) {
  return ctx->untrusted;
}

void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) * sk) {
  ctx->crls = sk;
}

int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) {
  return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
}

int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) {
  return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
}

/*
 * This function is used to set the X509_STORE_CTX purpose and trust values.
 * This is intended to be used when another structure has its own trust and
 * purpose values which (if set) will be inherited by the ctx. If they aren't
 * set then we will usually have a default purpose in mind which should then
 * be used to set the trust value. An example of this is SSL use: an SSL
 * structure will have its own purpose and trust settings which the
 * application can set: if they aren't set then we use the default of SSL
 * client/server.
 */

int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
                                   int purpose, int trust) {
  int idx;
  /* If purpose not set use default */
  if (!purpose)
    purpose = def_purpose;
  /* If we have a purpose then check it is valid */
  if (purpose) {
    X509_PURPOSE *ptmp;
    idx = X509_PURPOSE_get_by_id(purpose);
    if (idx == -1) {
      OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
      return 0;
    }
    ptmp = X509_PURPOSE_get0(idx);
    if (ptmp->trust == X509_TRUST_DEFAULT) {
      idx = X509_PURPOSE_get_by_id(def_purpose);
      if (idx == -1) {
        OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
        return 0;
      }
      ptmp = X509_PURPOSE_get0(idx);
    }
    /* If trust not set then get from purpose default */
    if (!trust)
      trust = ptmp->trust;
  }
  if (trust) {
    idx = X509_TRUST_get_by_id(trust);
    if (idx == -1) {
      OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
      return 0;
    }
  }

  if (purpose && !ctx->param->purpose)
    ctx->param->purpose = purpose;
  if (trust && !ctx->param->trust)
    ctx->param->trust = trust;
  return 1;
}

X509_STORE_CTX *X509_STORE_CTX_new(void) {
  X509_STORE_CTX *ctx;
  ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
  if (!ctx) {
    OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  X509_STORE_CTX_zero(ctx);
  return ctx;
}

void X509_STORE_CTX_zero(X509_STORE_CTX *ctx) {
  OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
}

void X509_STORE_CTX_free(X509_STORE_CTX *ctx) {
  if (ctx == NULL) {
    return;
  }
  X509_STORE_CTX_cleanup(ctx);
  OPENSSL_free(ctx);
}

int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
                        STACK_OF(X509) * chain) {
  int ret = 1;

  X509_STORE_CTX_zero(ctx);
  ctx->ctx = store;
  ctx->cert = x509;
  ctx->untrusted = chain;

  CRYPTO_new_ex_data(&ctx->ex_data);

  ctx->param = X509_VERIFY_PARAM_new();
  if (!ctx->param)
    goto err;

  /*
   * Inherit callbacks and flags from X509_STORE if not set use defaults.
   */

  if (store)
    ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
  else
    ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;

  if (store) {
    ctx->verify_cb = store->verify_cb;
    ctx->cleanup = store->cleanup;
  } else
    ctx->cleanup = 0;

  if (ret)
    ret = X509_VERIFY_PARAM_inherit(ctx->param,
                                    X509_VERIFY_PARAM_lookup("default"));

  if (ret == 0)
    goto err;

  if (store && store->check_issued)
    ctx->check_issued = store->check_issued;
  else
    ctx->check_issued = check_issued;

  if (store && store->get_issuer)
    ctx->get_issuer = store->get_issuer;
  else
    ctx->get_issuer = X509_STORE_CTX_get1_issuer;

  if (store && store->verify_cb)
    ctx->verify_cb = store->verify_cb;
  else
    ctx->verify_cb = null_callback;

  if (store && store->verify)
    ctx->verify = store->verify;
  else
    ctx->verify = internal_verify;

  if (store && store->check_revocation)
    ctx->check_revocation = store->check_revocation;
  else
    ctx->check_revocation = check_revocation;

  if (store && store->get_crl)
    ctx->get_crl = store->get_crl;
  else
    ctx->get_crl = NULL;

  if (store && store->check_crl)
    ctx->check_crl = store->check_crl;
  else
    ctx->check_crl = check_crl;

  if (store && store->cert_crl)
    ctx->cert_crl = store->cert_crl;
  else
    ctx->cert_crl = cert_crl;

  if (store && store->lookup_certs)
    ctx->lookup_certs = store->lookup_certs;
  else
    ctx->lookup_certs = X509_STORE_get1_certs;

  if (store && store->lookup_crls)
    ctx->lookup_crls = store->lookup_crls;
  else
    ctx->lookup_crls = X509_STORE_get1_crls;

  ctx->check_policy = check_policy;

  return 1;

err:
  CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
  if (ctx->param != NULL) {
    X509_VERIFY_PARAM_free(ctx->param);
  }

  OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
  OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
  return 0;
}

/*
 * Set alternative lookup method: just a STACK of trusted certificates. This
 * avoids X509_STORE nastiness where it isn't needed.
 */

void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) * sk) {
  ctx->other_ctx = sk;
  ctx->get_issuer = get_issuer_sk;
}

void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) {
  /* We need to be idempotent because, unfortunately, |X509_STORE_CTX_free|
   * also calls this function. */
  if (ctx->cleanup != NULL) {
    ctx->cleanup(ctx);
    ctx->cleanup = NULL;
  }
  if (ctx->param != NULL) {
    if (ctx->parent == NULL)
      X509_VERIFY_PARAM_free(ctx->param);
    ctx->param = NULL;
  }
  if (ctx->tree != NULL) {
    X509_policy_tree_free(ctx->tree);
    ctx->tree = NULL;
  }
  if (ctx->chain != NULL) {
    sk_X509_pop_free(ctx->chain, X509_free);
    ctx->chain = NULL;
  }
  CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data));
  OPENSSL_memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
}

void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) {
  X509_VERIFY_PARAM_set_depth(ctx->param, depth);
}

void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) {
  X509_VERIFY_PARAM_set_flags(ctx->param, flags);
}

void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
                             OPENSSL_port_time_t t) {
  X509_VERIFY_PARAM_set_time(ctx->param, t);
}

X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) { return ctx->cert; }

void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
                                  int (*verify_cb)(int, X509_STORE_CTX *)) {
  ctx->verify_cb = verify_cb;
}

X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) {
  return ctx->tree;
}

int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) {
  return ctx->explicit_policy;
}

int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) {
  const X509_VERIFY_PARAM *param;
  param = X509_VERIFY_PARAM_lookup(name);
  if (!param)
    return 0;
  return X509_VERIFY_PARAM_inherit(ctx->param, param);
}

X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) {
  return ctx->param;
}

void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) {
  if (ctx->param)
    X509_VERIFY_PARAM_free(ctx->param);
  ctx->param = param;
}

IMPLEMENT_ASN1_SET_OF(X509)

IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
