/* 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 <openssl/ssl.h>

#include <limits.h>

#include <openssl/ec.h>
#include <openssl/ec_key.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/type_check.h>

#include "internal.h"


int ssl_is_key_type_supported(int key_type) {
  return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC;
}

static int ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) {
  if (!ssl_is_key_type_supported(pkey->type)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
    return 0;
  }

  if (cert->chain != NULL &&
      sk_CRYPTO_BUFFER_value(cert->chain, 0) != NULL &&
      /* Sanity-check that the private key and the certificate match. */
      !ssl_cert_check_private_key(cert, pkey)) {
    return 0;
  }

  EVP_PKEY_free(cert->privatekey);
  EVP_PKEY_up_ref(pkey);
  cert->privatekey = pkey;

  return 1;
}

int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
  EVP_PKEY *pkey;
  int ret;

  if (rsa == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  pkey = EVP_PKEY_new();
  if (pkey == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
    return 0;
  }

  RSA_up_ref(rsa);
  EVP_PKEY_assign_RSA(pkey, rsa);

  ret = ssl_set_pkey(ssl->cert, pkey);
  EVP_PKEY_free(pkey);

  return ret;
}

int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
  if (pkey == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  return ssl_set_pkey(ssl->cert, pkey);
}

int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der,
                            size_t der_len) {
  if (der_len > LONG_MAX) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
    return 0;
  }

  const uint8_t *p = der;
  EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len);
  if (pkey == NULL || p != der + der_len) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
    EVP_PKEY_free(pkey);
    return 0;
  }

  int ret = SSL_use_PrivateKey(ssl, pkey);
  EVP_PKEY_free(pkey);
  return ret;
}

int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
  int ret;
  EVP_PKEY *pkey;

  if (rsa == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  pkey = EVP_PKEY_new();
  if (pkey == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
    return 0;
  }

  RSA_up_ref(rsa);
  EVP_PKEY_assign_RSA(pkey, rsa);

  ret = ssl_set_pkey(ctx->cert, pkey);
  EVP_PKEY_free(pkey);
  return ret;
}

int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der,
                                   size_t der_len) {
  RSA *rsa = RSA_private_key_from_bytes(der, der_len);
  if (rsa == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
    return 0;
  }

  int ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
  RSA_free(rsa);
  return ret;
}

int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) {
  if (pkey == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  return ssl_set_pkey(ctx->cert, pkey);
}

int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der,
                                size_t der_len) {
  if (der_len > LONG_MAX) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
    return 0;
  }

  const uint8_t *p = der;
  EVP_PKEY *pkey = d2i_PrivateKey(type, NULL, &p, (long)der_len);
  if (pkey == NULL || p != der + der_len) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
    EVP_PKEY_free(pkey);
    return 0;
  }

  int ret = SSL_CTX_use_PrivateKey(ctx, pkey);
  EVP_PKEY_free(pkey);
  return ret;
}

void SSL_set_private_key_method(SSL *ssl,
                                const SSL_PRIVATE_KEY_METHOD *key_method) {
  ssl->cert->key_method = key_method;
}

void SSL_CTX_set_private_key_method(SSL_CTX *ctx,
                                    const SSL_PRIVATE_KEY_METHOD *key_method) {
  ctx->cert->key_method = key_method;
}

static int set_signing_algorithm_prefs(CERT *cert, const uint16_t *prefs,
                                       size_t num_prefs) {
  OPENSSL_free(cert->sigalgs);

  cert->num_sigalgs = 0;
  cert->sigalgs = BUF_memdup(prefs, num_prefs * sizeof(prefs[0]));
  if (cert->sigalgs == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return 0;
  }
  cert->num_sigalgs = num_prefs;

  return 1;
}

int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
                                        size_t num_prefs) {
  return set_signing_algorithm_prefs(ctx->cert, prefs, num_prefs);
}


int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
                                    size_t num_prefs) {
  return set_signing_algorithm_prefs(ssl->cert, prefs, num_prefs);
}

int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids,
                                     size_t num_digests) {
  OPENSSL_free(ssl->cert->sigalgs);

  OPENSSL_COMPILE_ASSERT(sizeof(int) >= 2 * sizeof(uint16_t),
                         digest_list_conversion_cannot_overflow);

  ssl->cert->num_sigalgs = 0;
  ssl->cert->sigalgs = OPENSSL_malloc(sizeof(uint16_t) * 2 * num_digests);
  if (ssl->cert->sigalgs == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return 0;
  }

  /* Convert the digest list to a signature algorithms list.
   *
   * TODO(davidben): Replace this API with one that can express RSA-PSS, etc. */
  for (size_t i = 0; i < num_digests; i++) {
    switch (digest_nids[i]) {
      case NID_sha1:
        ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA1;
        ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = SSL_SIGN_ECDSA_SHA1;
        ssl->cert->num_sigalgs += 2;
        break;
      case NID_sha256:
        ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA256;
        ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
            SSL_SIGN_ECDSA_SECP256R1_SHA256;
        ssl->cert->num_sigalgs += 2;
        break;
      case NID_sha384:
        ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA384;
        ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
            SSL_SIGN_ECDSA_SECP384R1_SHA384;
        ssl->cert->num_sigalgs += 2;
        break;
      case NID_sha512:
        ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA512;
        ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
            SSL_SIGN_ECDSA_SECP521R1_SHA512;
        ssl->cert->num_sigalgs += 2;
        break;
    }
  }

  return 1;
}

int ssl_has_private_key(const SSL *ssl) {
  return ssl->cert->privatekey != NULL || ssl->cert->key_method != NULL;
}

int ssl_is_ecdsa_key_type(int type) {
  switch (type) {
    case NID_secp224r1:
    case NID_X9_62_prime256v1:
    case NID_secp384r1:
    case NID_secp521r1:
      return 1;
    default:
      return 0;
  }
}

int ssl_private_key_type(SSL *ssl) {
  if (ssl->cert->key_method != NULL) {
    return ssl->cert->key_method->type(ssl);
  }
  switch (EVP_PKEY_id(ssl->cert->privatekey)) {
    case EVP_PKEY_RSA:
      return NID_rsaEncryption;
    case EVP_PKEY_EC:
      return EC_GROUP_get_curve_name(
          EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey)));
    default:
      return NID_undef;
  }
}

size_t ssl_private_key_max_signature_len(SSL *ssl) {
  if (ssl->cert->key_method != NULL) {
    return ssl->cert->key_method->max_signature_len(ssl);
  }
  return EVP_PKEY_size(ssl->cert->privatekey);
}

/* TODO(davidben): Forbid RSA-PKCS1 in TLS 1.3. For now we allow it because NSS
 * has yet to start doing RSA-PSS, so enforcing it would complicate interop
 * testing. */
static int is_rsa_pkcs1(const EVP_MD **out_md, uint16_t sigalg) {
  switch (sigalg) {
    case SSL_SIGN_RSA_PKCS1_MD5_SHA1:
      *out_md = EVP_md5_sha1();
      return 1;
    case SSL_SIGN_RSA_PKCS1_SHA1:
      *out_md = EVP_sha1();
      return 1;
    case SSL_SIGN_RSA_PKCS1_SHA256:
      *out_md = EVP_sha256();
      return 1;
    case SSL_SIGN_RSA_PKCS1_SHA384:
      *out_md = EVP_sha384();
      return 1;
    case SSL_SIGN_RSA_PKCS1_SHA512:
      *out_md = EVP_sha512();
      return 1;
    default:
      return 0;
  }
}

static int ssl_sign_rsa_pkcs1(SSL *ssl, uint8_t *out, size_t *out_len,
                              size_t max_out, const EVP_MD *md,
                              const uint8_t *in, size_t in_len) {
  EVP_MD_CTX ctx;
  EVP_MD_CTX_init(&ctx);
  *out_len = max_out;
  int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) &&
            EVP_DigestSignUpdate(&ctx, in, in_len) &&
            EVP_DigestSignFinal(&ctx, out, out_len);
  EVP_MD_CTX_cleanup(&ctx);
  return ret;
}

static int ssl_verify_rsa_pkcs1(SSL *ssl, const uint8_t *signature,
                                size_t signature_len, const EVP_MD *md,
                                EVP_PKEY *pkey, const uint8_t *in,
                                size_t in_len) {
  if (pkey->type != EVP_PKEY_RSA) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
    return 0;
  }

  EVP_MD_CTX md_ctx;
  EVP_MD_CTX_init(&md_ctx);
  int ret = EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) &&
            EVP_DigestVerifyUpdate(&md_ctx, in, in_len) &&
            EVP_DigestVerifyFinal(&md_ctx, signature, signature_len);
  EVP_MD_CTX_cleanup(&md_ctx);
  return ret;
}

static int is_ecdsa(int *out_curve, const EVP_MD **out_md, uint16_t sigalg) {
  switch (sigalg) {
    case SSL_SIGN_ECDSA_SHA1:
      *out_curve = NID_undef;
      *out_md = EVP_sha1();
      return 1;
    case SSL_SIGN_ECDSA_SECP256R1_SHA256:
      *out_curve = NID_X9_62_prime256v1;
      *out_md = EVP_sha256();
      return 1;
    case SSL_SIGN_ECDSA_SECP384R1_SHA384:
      *out_curve = NID_secp384r1;
      *out_md = EVP_sha384();
      return 1;
    case SSL_SIGN_ECDSA_SECP521R1_SHA512:
      *out_curve = NID_secp521r1;
      *out_md = EVP_sha512();
      return 1;
    default:
      return 0;
  }
}

static int ssl_sign_ecdsa(SSL *ssl, uint8_t *out, size_t *out_len,
                          size_t max_out, int curve, const EVP_MD *md,
                          const uint8_t *in, size_t in_len) {
  EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->cert->privatekey);
  if (ec_key == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
    return 0;
  }

  /* In TLS 1.3, the curve is also specified by the signature algorithm. */
  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION &&
      (curve == NID_undef ||
       EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
    return 0;
  }

  EVP_MD_CTX ctx;
  EVP_MD_CTX_init(&ctx);
  *out_len = max_out;
  int ret = EVP_DigestSignInit(&ctx, NULL, md, NULL, ssl->cert->privatekey) &&
            EVP_DigestSignUpdate(&ctx, in, in_len) &&
            EVP_DigestSignFinal(&ctx, out, out_len);
  EVP_MD_CTX_cleanup(&ctx);
  return ret;
}

static int ssl_verify_ecdsa(SSL *ssl, const uint8_t *signature,
                            size_t signature_len, int curve, const EVP_MD *md,
                            EVP_PKEY *pkey, const uint8_t *in, size_t in_len) {
  EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
  if (ec_key == NULL) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
    return 0;
  }

  /* In TLS 1.3, the curve is also specified by the signature algorithm. */
  if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION &&
      (curve == NID_undef ||
       EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != curve)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
    return 0;
  }

  EVP_MD_CTX md_ctx;
  EVP_MD_CTX_init(&md_ctx);
  int ret = EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, pkey) &&
            EVP_DigestVerifyUpdate(&md_ctx, in, in_len) &&
            EVP_DigestVerifyFinal(&md_ctx, signature, signature_len);
  EVP_MD_CTX_cleanup(&md_ctx);
  return ret;
}

static int is_rsa_pss(const EVP_MD **out_md, uint16_t sigalg) {
  switch (sigalg) {
    case SSL_SIGN_RSA_PSS_SHA256:
      *out_md = EVP_sha256();
      return 1;
    case SSL_SIGN_RSA_PSS_SHA384:
      *out_md = EVP_sha384();
      return 1;
    case SSL_SIGN_RSA_PSS_SHA512:
      *out_md = EVP_sha512();
      return 1;
    default:
      return 0;
  }
}

static int ssl_sign_rsa_pss(SSL *ssl, uint8_t *out, size_t *out_len,
                              size_t max_out, const EVP_MD *md,
                              const uint8_t *in, size_t in_len) {
  EVP_MD_CTX ctx;
  EVP_MD_CTX_init(&ctx);
  *out_len = max_out;
  EVP_PKEY_CTX *pctx;
  int ret =
      EVP_DigestSignInit(&ctx, &pctx, md, NULL, ssl->cert->privatekey) &&
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) &&
      EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */) &&
      EVP_DigestSignUpdate(&ctx, in, in_len) &&
      EVP_DigestSignFinal(&ctx, out, out_len);
  EVP_MD_CTX_cleanup(&ctx);
  return ret;
}

static int ssl_verify_rsa_pss(SSL *ssl, const uint8_t *signature,
                                size_t signature_len, const EVP_MD *md,
                                EVP_PKEY *pkey, const uint8_t *in,
                                size_t in_len) {
  if (pkey->type != EVP_PKEY_RSA) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
    return 0;
  }

  EVP_MD_CTX md_ctx;
  EVP_MD_CTX_init(&md_ctx);
  EVP_PKEY_CTX *pctx;
  int ret =
      EVP_DigestVerifyInit(&md_ctx, &pctx, md, NULL, pkey) &&
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) &&
      EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */) &&
      EVP_DigestVerifyUpdate(&md_ctx, in, in_len) &&
      EVP_DigestVerifyFinal(&md_ctx, signature, signature_len);
  EVP_MD_CTX_cleanup(&md_ctx);
  return ret;
}

enum ssl_private_key_result_t ssl_private_key_sign(
    SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
    uint16_t signature_algorithm, const uint8_t *in, size_t in_len) {
  if (ssl->cert->key_method != NULL) {
    if (ssl->cert->key_method->sign != NULL) {
      return ssl->cert->key_method->sign(ssl, out, out_len, max_out,
                                         signature_algorithm, in, in_len);
    }

    /* TODO(davidben): Remove support for |sign_digest|-only
     * |SSL_PRIVATE_KEY_METHOD|s. */
    const EVP_MD *md;
    int curve;
    if (!is_rsa_pkcs1(&md, signature_algorithm) &&
        !is_ecdsa(&curve, &md, signature_algorithm)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY);
      return ssl_private_key_failure;
    }

    uint8_t hash[EVP_MAX_MD_SIZE];
    unsigned hash_len;
    if (!EVP_Digest(in, in_len, hash, &hash_len, md, NULL)) {
      return ssl_private_key_failure;
    }

    return ssl->cert->key_method->sign_digest(ssl, out, out_len, max_out, md,
                                              hash, hash_len);
  }

  const EVP_MD *md;
  if (is_rsa_pkcs1(&md, signature_algorithm) &&
      ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
    return ssl_sign_rsa_pkcs1(ssl, out, out_len, max_out, md, in, in_len)
               ? ssl_private_key_success
               : ssl_private_key_failure;
  }

  int curve;
  if (is_ecdsa(&curve, &md, signature_algorithm)) {
    return ssl_sign_ecdsa(ssl, out, out_len, max_out, curve, md, in, in_len)
               ? ssl_private_key_success
               : ssl_private_key_failure;
  }

  if (is_rsa_pss(&md, signature_algorithm)) {
    return ssl_sign_rsa_pss(ssl, out, out_len, max_out, md, in, in_len)
               ? ssl_private_key_success
               : ssl_private_key_failure;
  }

  OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
  return ssl_private_key_failure;
}

int ssl_public_key_verify(SSL *ssl, const uint8_t *signature,
                          size_t signature_len, uint16_t signature_algorithm,
                          EVP_PKEY *pkey, const uint8_t *in, size_t in_len) {
  const EVP_MD *md;
  if (is_rsa_pkcs1(&md, signature_algorithm) &&
      ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
    return ssl_verify_rsa_pkcs1(ssl, signature, signature_len, md, pkey, in,
                                in_len);
  }

  int curve;
  if (is_ecdsa(&curve, &md, signature_algorithm)) {
    return ssl_verify_ecdsa(ssl, signature, signature_len, curve, md, pkey, in,
                            in_len);
  }

  if (is_rsa_pss(&md, signature_algorithm)) {
    return ssl_verify_rsa_pss(ssl, signature, signature_len, md, pkey, in,
                              in_len);
  }

  OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
  return 0;
}

enum ssl_private_key_result_t ssl_private_key_decrypt(
    SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
    const uint8_t *in, size_t in_len) {
  if (ssl->cert->key_method != NULL) {
    return ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, in,
                                          in_len);
  }

  RSA *rsa = EVP_PKEY_get0_RSA(ssl->cert->privatekey);
  if (rsa == NULL) {
    /* Decrypt operations are only supported for RSA keys. */
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return ssl_private_key_failure;
  }

  /* Decrypt with no padding. PKCS#1 padding will be removed as part
   * of the timing-sensitive code by the caller. */
  if (!RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) {
    return ssl_private_key_failure;
  }
  return ssl_private_key_success;
}

enum ssl_private_key_result_t ssl_private_key_complete(SSL *ssl, uint8_t *out,
                                                       size_t *out_len,
                                                       size_t max_out) {
  /* Only custom keys may be asynchronous. */
  return ssl->cert->key_method->complete(ssl, out, out_len, max_out);
}

int ssl_private_key_supports_signature_algorithm(SSL *ssl,
                                                 uint16_t signature_algorithm) {
  const EVP_MD *md;
  if (is_rsa_pkcs1(&md, signature_algorithm) &&
      ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
    return ssl_private_key_type(ssl) == NID_rsaEncryption;
  }

  int curve;
  if (is_ecdsa(&curve, &md, signature_algorithm)) {
    int type = ssl_private_key_type(ssl);
    if (!ssl_is_ecdsa_key_type(type)) {
      return 0;
    }

    /* Prior to TLS 1.3, ECDSA curves did not match the signature algorithm. */
    if (ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
      return 1;
    }

    return curve != NID_undef && type == curve;
  }

  if (is_rsa_pss(&md, signature_algorithm)) {
    if (ssl_private_key_type(ssl) != NID_rsaEncryption) {
      return 0;
    }

    /* Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that
     * emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the
     * hash in TLS. Reasonable RSA key sizes are large enough for the largest
     * defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too large for
     * SHA-512. 1024-bit RSA is sometimes used for test credentials, so check
     * the size to fall back to another algorithm. */
    if (ssl_private_key_max_signature_len(ssl) < 2 * EVP_MD_size(md) + 2) {
      return 0;
    }

    /* RSA-PSS is only supported by message-based private keys. */
    if (ssl->cert->key_method != NULL && ssl->cert->key_method->sign == NULL) {
      return 0;
    }

    return 1;
  }

  return 0;
}
