// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "verify_signed_data.h"

#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include "cert_errors.h"
#include "input.h"
#include "parse_values.h"
#include "parser.h"
#include "signature_algorithm.h"
#include "signature_verify_cache.h"

namespace bssl {

namespace {

bool SHA256UpdateWithLengthPrefixedData(SHA256_CTX *s_ctx, const uint8_t *data,
                                        uint64_t length) {
  return (SHA256_Update(s_ctx, reinterpret_cast<uint8_t *>(&length),
                        sizeof(length)) &&
          SHA256_Update(s_ctx, data, length));
}

// Increase to make incompatible changes in the computation of the
// cache key.
constexpr uint32_t VerifyCacheKeyVersion = 1;

std::string SignatureVerifyCacheKey(std::string_view algorithm_name,
                                    const der::Input &signed_data,
                                    const der::Input &signature_value_bytes,
                                    EVP_PKEY *public_key) {
  SHA256_CTX s_ctx;
  bssl::ScopedCBB public_key_cbb;
  uint8_t digest[SHA256_DIGEST_LENGTH];
  uint32_t version = VerifyCacheKeyVersion;
  if (CBB_init(public_key_cbb.get(), 128) &&
      EVP_marshal_public_key(public_key_cbb.get(), public_key) &&
      SHA256_Init(&s_ctx) &&
      SHA256_Update(&s_ctx, reinterpret_cast<uint8_t *>(&version),
                    sizeof(version)) &&
      SHA256UpdateWithLengthPrefixedData(
          &s_ctx, reinterpret_cast<const uint8_t *>(algorithm_name.data()),
          algorithm_name.length()) &&
      SHA256UpdateWithLengthPrefixedData(&s_ctx, CBB_data(public_key_cbb.get()),
                                         CBB_len(public_key_cbb.get())) &&
      SHA256UpdateWithLengthPrefixedData(&s_ctx, signature_value_bytes.data(),
                                         signature_value_bytes.size()) &&
      SHA256UpdateWithLengthPrefixedData(&s_ctx, signed_data.data(),
                                         signed_data.size()) &&
      SHA256_Final(digest, &s_ctx)) {
    return std::string(reinterpret_cast<char *>(digest), sizeof(digest));
  }
  return std::string();
}

// Place an instance of this class on the call stack to automatically clear
// the OpenSSL error stack on function exit.
// TODO(crbug.com/boringssl/38): Remove this when the library is more robust to
// leaving things in the error queue.
class OpenSSLErrStackTracer {
 public:
  ~OpenSSLErrStackTracer() { ERR_clear_error(); };
};

}  // namespace

// Parses an RSA public key or EC public key from SPKI to an EVP_PKEY. Returns
// true on success.
//
// This function only recognizes the "pk-rsa" (rsaEncryption) flavor of RSA
// public key from RFC 5912.
//
//     pk-rsa PUBLIC-KEY ::= {
//      IDENTIFIER rsaEncryption
//      KEY RSAPublicKey
//      PARAMS TYPE NULL ARE absent
//      -- Private key format not in this module --
//      CERT-KEY-USAGE {digitalSignature, nonRepudiation,
//      keyEncipherment, dataEncipherment, keyCertSign, cRLSign}
//     }
//
// COMPATIBILITY NOTE: RFC 5912 and RFC 3279 are in disagreement on the value
// of parameters for rsaEncryption. Whereas RFC 5912 says they must be absent,
// RFC 3279 says they must be NULL:
//
//     The rsaEncryption OID is intended to be used in the algorithm field
//     of a value of type AlgorithmIdentifier.  The parameters field MUST
//     have ASN.1 type NULL for this algorithm identifier.
//
// Following RFC 3279 in this case.
//
// In the case of parsing EC keys, RFC 5912 describes all the ECDSA
// signature algorithms as requiring a public key of type "pk-ec":
//
//     pk-ec PUBLIC-KEY ::= {
//      IDENTIFIER id-ecPublicKey
//      KEY ECPoint
//      PARAMS TYPE ECParameters ARE required
//      -- Private key format not in this module --
//      CERT-KEY-USAGE { digitalSignature, nonRepudiation, keyAgreement,
//                           keyCertSign, cRLSign }
//     }
//
// Moreover RFC 5912 stipulates what curves are allowed. The ECParameters
// MUST NOT use an implicitCurve or specificCurve for PKIX:
//
//     ECParameters ::= CHOICE {
//      namedCurve      CURVE.&id({NamedCurve})
//      -- implicitCurve   NULL
//        -- implicitCurve MUST NOT be used in PKIX
//      -- specifiedCurve  SpecifiedCurve
//        -- specifiedCurve MUST NOT be used in PKIX
//        -- Details for specifiedCurve can be found in [X9.62]
//        -- Any future additions to this CHOICE should be coordinated
//        -- with ANSI X.9.
//     }
//     -- If you need to be able to decode ANSI X.9 parameter structures,
//     -- uncomment the implicitCurve and specifiedCurve above, and also
//     -- uncomment the following:
//     --(WITH COMPONENTS {namedCurve PRESENT})
//
// The namedCurves are extensible. The ones described by RFC 5912 are:
//
//     NamedCurve CURVE ::= {
//     { ID secp192r1 } | { ID sect163k1 } | { ID sect163r2 } |
//     { ID secp224r1 } | { ID sect233k1 } | { ID sect233r1 } |
//     { ID secp256r1 } | { ID sect283k1 } | { ID sect283r1 } |
//     { ID secp384r1 } | { ID sect409k1 } | { ID sect409r1 } |
//     { ID secp521r1 } | { ID sect571k1 } | { ID sect571r1 },
//     ... -- Extensible
//     }
bool ParsePublicKey(const der::Input &public_key_spki,
                    bssl::UniquePtr<EVP_PKEY> *public_key) {
  // Parse the SPKI to an EVP_PKEY.
  OpenSSLErrStackTracer err_tracer;

  CBS cbs;
  CBS_init(&cbs, public_key_spki.data(), public_key_spki.size());
  public_key->reset(EVP_parse_public_key(&cbs));
  if (!*public_key || CBS_len(&cbs) != 0) {
    public_key->reset();
    return false;
  }
  return true;
}

bool VerifySignedData(SignatureAlgorithm algorithm,
                      const der::Input &signed_data,
                      const der::BitString &signature_value,
                      EVP_PKEY *public_key, SignatureVerifyCache *cache) {
  int expected_pkey_id = 1;
  const EVP_MD *digest = nullptr;
  bool is_rsa_pss = false;
  std::string_view cache_algorithm_name;
  switch (algorithm) {
    case SignatureAlgorithm::kRsaPkcs1Sha1:
      expected_pkey_id = EVP_PKEY_RSA;
      digest = EVP_sha1();
      cache_algorithm_name = "RsaPkcs1Sha1";
      break;
    case SignatureAlgorithm::kRsaPkcs1Sha256:
      expected_pkey_id = EVP_PKEY_RSA;
      digest = EVP_sha256();
      cache_algorithm_name = "RsaPkcs1Sha256";
      break;
    case SignatureAlgorithm::kRsaPkcs1Sha384:
      expected_pkey_id = EVP_PKEY_RSA;
      digest = EVP_sha384();
      cache_algorithm_name = "RsaPkcs1Sha384";
      break;
    case SignatureAlgorithm::kRsaPkcs1Sha512:
      expected_pkey_id = EVP_PKEY_RSA;
      digest = EVP_sha512();
      cache_algorithm_name = "RsaPkcs1Sha512";
      break;

    case SignatureAlgorithm::kEcdsaSha1:
      expected_pkey_id = EVP_PKEY_EC;
      digest = EVP_sha1();
      cache_algorithm_name = "EcdsaSha1";
      break;
    case SignatureAlgorithm::kEcdsaSha256:
      expected_pkey_id = EVP_PKEY_EC;
      digest = EVP_sha256();
      cache_algorithm_name = "EcdsaSha256";
      break;
    case SignatureAlgorithm::kEcdsaSha384:
      expected_pkey_id = EVP_PKEY_EC;
      digest = EVP_sha384();
      cache_algorithm_name = "EcdsaSha384";
      break;
    case SignatureAlgorithm::kEcdsaSha512:
      expected_pkey_id = EVP_PKEY_EC;
      digest = EVP_sha512();
      cache_algorithm_name = "EcdsaSha512";
      break;

    case SignatureAlgorithm::kRsaPssSha256:
      expected_pkey_id = EVP_PKEY_RSA;
      digest = EVP_sha256();
      cache_algorithm_name = "RsaPssSha256";
      is_rsa_pss = true;
      break;
    case SignatureAlgorithm::kRsaPssSha384:
      expected_pkey_id = EVP_PKEY_RSA;
      digest = EVP_sha384();
      cache_algorithm_name = "RsaPssSha384";
      is_rsa_pss = true;
      break;
    case SignatureAlgorithm::kRsaPssSha512:
      expected_pkey_id = EVP_PKEY_RSA;
      digest = EVP_sha512();
      cache_algorithm_name = "RsaPssSha512";
      is_rsa_pss = true;
      break;
  }

  if (expected_pkey_id != EVP_PKEY_id(public_key)) {
    return false;
  }

  // For the supported algorithms the signature value must be a whole
  // number of bytes.
  if (signature_value.unused_bits() != 0) {
    return false;
  }
  const der::Input &signature_value_bytes = signature_value.bytes();

  std::string cache_key;
  if (cache) {
    cache_key = SignatureVerifyCacheKey(cache_algorithm_name, signed_data,
                                        signature_value_bytes, public_key);
    if (!cache_key.empty()) {
      switch (cache->Check(cache_key)) {
        case SignatureVerifyCache::Value::kValid:
          return true;
        case SignatureVerifyCache::Value::kInvalid:
          return false;
        case SignatureVerifyCache::Value::kUnknown:
          break;
      }
    }
  }

  OpenSSLErrStackTracer err_tracer;

  bssl::ScopedEVP_MD_CTX ctx;
  EVP_PKEY_CTX *pctx = nullptr;  // Owned by |ctx|.

  if (!EVP_DigestVerifyInit(ctx.get(), &pctx, digest, nullptr, public_key)) {
    return false;
  }

  if (is_rsa_pss) {
    // All supported RSASSA-PSS algorithms match signing and MGF-1 digest. They
    // also use the digest length as the salt length, which is specified with -1
    // in OpenSSL's API.
    if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
        !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) {
      return false;
    }
  }

  bool ret = 1 == EVP_DigestVerify(ctx.get(), signature_value_bytes.data(),
                                   signature_value_bytes.size(),
                                   signed_data.data(), signed_data.size());
  if (!cache_key.empty()) {
    cache->Store(cache_key, ret ? SignatureVerifyCache::Value::kValid
                                : SignatureVerifyCache::Value::kInvalid);
  }

  return ret;
}

bool VerifySignedData(SignatureAlgorithm algorithm,
                      const der::Input &signed_data,
                      const der::BitString &signature_value,
                      const der::Input &public_key_spki,
                      SignatureVerifyCache *cache) {
  bssl::UniquePtr<EVP_PKEY> public_key;
  if (!ParsePublicKey(public_key_spki, &public_key)) {
    return false;
  }
  return VerifySignedData(algorithm, signed_data, signature_value,
                          public_key.get(), cache);
}

}  // namespace bssl
