/* 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, 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)
