/* crypto/x509/x509_cmp.c */
/* 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 <string.h>

#include <openssl/asn1.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

#include "../internal.h"
#include "../x509v3/internal.h"
#include "internal.h"


int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) {
  int i;
  X509_CINF *ai, *bi;

  ai = a->cert_info;
  bi = b->cert_info;
  i = ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber);
  if (i) {
    return (i);
  }
  return (X509_NAME_cmp(ai->issuer, bi->issuer));
}

int X509_issuer_name_cmp(const X509 *a, const X509 *b) {
  return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer));
}

int X509_subject_name_cmp(const X509 *a, const X509 *b) {
  return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject));
}

int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) {
  return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer));
}

int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) {
  return OPENSSL_memcmp(a->crl_hash, b->crl_hash, SHA256_DIGEST_LENGTH);
}

X509_NAME *X509_get_issuer_name(const X509 *a) {
  return (a->cert_info->issuer);
}

unsigned long X509_issuer_name_hash(X509 *x) {
  return (X509_NAME_hash(x->cert_info->issuer));
}

unsigned long X509_issuer_name_hash_old(X509 *x) {
  return (X509_NAME_hash_old(x->cert_info->issuer));
}

X509_NAME *X509_get_subject_name(const X509 *a) {
  return (a->cert_info->subject);
}

ASN1_INTEGER *X509_get_serialNumber(X509 *a) {
  return (a->cert_info->serialNumber);
}

const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x509) {
  return x509->cert_info->serialNumber;
}

unsigned long X509_subject_name_hash(X509 *x) {
  return (X509_NAME_hash(x->cert_info->subject));
}

unsigned long X509_subject_name_hash_old(X509 *x) {
  return (X509_NAME_hash_old(x->cert_info->subject));
}

// Compare two certificates: they must be identical for this to work. NB:
// Although "cmp" operations are generally prototyped to take "const"
// arguments (eg. for use in STACKs), the way X509 handling is - these
// operations may involve ensuring the hashes are up-to-date and ensuring
// certain cert information is cached. So this is the point where the
// "depth-first" constification tree has to halt with an evil cast.
int X509_cmp(const X509 *a, const X509 *b) {
  // Fill in the |cert_hash| fields.
  //
  // TODO(davidben): This may fail, in which case the the hash will be all
  // zeros. This produces a consistent comparison (failures are sticky), but
  // not a good one. OpenSSL now returns -2, but this is not a consistent
  // comparison and may cause misbehaving sorts by transitivity. For now, we
  // retain the old OpenSSL behavior, which was to ignore the error. See
  // https://crbug.com/boringssl/355.
  x509v3_cache_extensions((X509 *)a);
  x509v3_cache_extensions((X509 *)b);

  return OPENSSL_memcmp(a->cert_hash, b->cert_hash, SHA256_DIGEST_LENGTH);
}

int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) {
  int ret;

  // Ensure canonical encoding is present and up to date

  if (!a->canon_enc || a->modified) {
    ret = i2d_X509_NAME((X509_NAME *)a, NULL);
    if (ret < 0) {
      return -2;
    }
  }

  if (!b->canon_enc || b->modified) {
    ret = i2d_X509_NAME((X509_NAME *)b, NULL);
    if (ret < 0) {
      return -2;
    }
  }

  ret = a->canon_enclen - b->canon_enclen;

  if (ret) {
    return ret;
  }

  return OPENSSL_memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
}

unsigned long X509_NAME_hash(X509_NAME *x) {
  unsigned long ret = 0;
  unsigned char md[SHA_DIGEST_LENGTH];

  // Make sure X509_NAME structure contains valid cached encoding
  i2d_X509_NAME(x, NULL);
  if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), NULL)) {
    return 0;
  }

  ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
         ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) &
        0xffffffffL;
  return (ret);
}

// I now DER encode the name and hash it.  Since I cache the DER encoding,
// this is reasonably efficient.

unsigned long X509_NAME_hash_old(X509_NAME *x) {
  EVP_MD_CTX md_ctx;
  unsigned long ret = 0;
  unsigned char md[16];

  // Make sure X509_NAME structure contains valid cached encoding
  i2d_X509_NAME(x, NULL);
  EVP_MD_CTX_init(&md_ctx);
  // EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
  if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL) &&
      EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length) &&
      EVP_DigestFinal_ex(&md_ctx, md, NULL)) {
    ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
           ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)) &
          0xffffffffL;
  }
  EVP_MD_CTX_cleanup(&md_ctx);

  return (ret);
}

// Search a stack of X509 for a match
X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
                                     ASN1_INTEGER *serial) {
  size_t i;
  X509_CINF cinf;
  X509 x, *x509 = NULL;

  if (!sk) {
    return NULL;
  }

  x.cert_info = &cinf;
  cinf.serialNumber = serial;
  cinf.issuer = name;

  for (i = 0; i < sk_X509_num(sk); i++) {
    x509 = sk_X509_value(sk, i);
    if (X509_issuer_and_serial_cmp(x509, &x) == 0) {
      return (x509);
    }
  }
  return (NULL);
}

X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) {
  X509 *x509;
  size_t i;

  for (i = 0; i < sk_X509_num(sk); i++) {
    x509 = sk_X509_value(sk, i);
    if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0) {
      return (x509);
    }
  }
  return (NULL);
}

EVP_PKEY *X509_get_pubkey(X509 *x) {
  if ((x == NULL) || (x->cert_info == NULL)) {
    return (NULL);
  }
  return (X509_PUBKEY_get(x->cert_info->key));
}

ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) {
  if (!x) {
    return NULL;
  }
  return x->cert_info->key->public_key;
}

int X509_check_private_key(X509 *x, const EVP_PKEY *k) {
  EVP_PKEY *xk;
  int ret;

  xk = X509_get_pubkey(x);

  if (xk) {
    ret = EVP_PKEY_cmp(xk, k);
  } else {
    ret = -2;
  }

  switch (ret) {
    case 1:
      break;
    case 0:
      OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
      break;
    case -1:
      OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
      break;
    case -2:
      OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
  }
  if (xk) {
    EVP_PKEY_free(xk);
  }
  if (ret > 0) {
    return 1;
  }
  return 0;
}

// Check a suite B algorithm is permitted: pass in a public key and the NID
// of its signature (or 0 if no signature). The pflags is a pointer to a
// flags field which must contain the suite B verification flags.

static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags) {
  const EC_GROUP *grp = NULL;
  int curve_nid;
  if (pkey && pkey->type == EVP_PKEY_EC) {
    grp = EC_KEY_get0_group(pkey->pkey.ec);
  }
  if (!grp) {
    return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
  }
  curve_nid = EC_GROUP_get_curve_name(grp);
  // Check curve is consistent with LOS
  if (curve_nid == NID_secp384r1) {  // P-384
    // Check signature algorithm is consistent with curve.
    if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384) {
      return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
    }
    if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS)) {
      return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
    }
    // If we encounter P-384 we cannot use P-256 later
    *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
  } else if (curve_nid == NID_X9_62_prime256v1) {  // P-256
    if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256) {
      return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
    }
    if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY)) {
      return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
    }
  } else {
    return X509_V_ERR_SUITE_B_INVALID_CURVE;
  }

  return X509_V_OK;
}

int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
                            unsigned long flags) {
  int rv, sign_nid;
  size_t i;
  EVP_PKEY *pk = NULL;
  unsigned long tflags;
  if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) {
    return X509_V_OK;
  }
  tflags = flags;
  // If no EE certificate passed in must be first in chain
  if (x == NULL) {
    x = sk_X509_value(chain, 0);
    i = 1;
  } else {
    i = 0;
  }

  if (X509_get_version(x) != X509_VERSION_3) {
    rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
    // Correct error depth
    i = 0;
    goto end;
  }

  pk = X509_get_pubkey(x);
  // Check EE key only
  rv = check_suite_b(pk, -1, &tflags);
  if (rv != X509_V_OK) {
    // Correct error depth
    i = 0;
    goto end;
  }
  for (; i < sk_X509_num(chain); i++) {
    sign_nid = X509_get_signature_nid(x);
    x = sk_X509_value(chain, i);
    if (X509_get_version(x) != X509_VERSION_3) {
      rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
      goto end;
    }
    EVP_PKEY_free(pk);
    pk = X509_get_pubkey(x);
    rv = check_suite_b(pk, sign_nid, &tflags);
    if (rv != X509_V_OK) {
      goto end;
    }
  }

  // Final check: root CA signature
  rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
end:
  if (pk) {
    EVP_PKEY_free(pk);
  }
  if (rv != X509_V_OK) {
    // Invalid signature or LOS errors are for previous cert
    if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM ||
         rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) &&
        i) {
      i--;
    }
    // If we have LOS error and flags changed then we are signing P-384
    // with P-256. Use more meaninggul error.
    if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags) {
      rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
    }
    if (perror_depth) {
      *perror_depth = i;
    }
  }
  return rv;
}

int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) {
  int sign_nid;
  if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) {
    return X509_V_OK;
  }
  sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm);
  return check_suite_b(pk, sign_nid, &flags);
}

// Not strictly speaking an "up_ref" as a STACK doesn't have a reference
// count but it has the same effect by duping the STACK and upping the ref of
// each X509 structure.
STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain) {
  STACK_OF(X509) *ret;
  size_t i;
  ret = sk_X509_dup(chain);
  for (i = 0; i < sk_X509_num(ret); i++) {
    X509_up_ref(sk_X509_value(ret, i));
  }
  return ret;
}
