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

#include <openssl/asn1.h>
#include <openssl/bytestring.h>
#include <openssl/evp.h>
#include <openssl/obj.h>
#include <openssl/x509.h>

#include "base/logging.h"
#include "crypto/scoped_openssl_types.h"
#include "net/cert/sha256_legacy_support_win.h"

namespace net {

namespace sha256_interception {

namespace {

using ScopedX509_ALGOR = crypto::ScopedOpenSSL<X509_ALGOR, X509_ALGOR_free>;

// Parses |subject_signature| and writes the components into |*out_tbs_data|,
// |*out_algor|, and |*out_signature|. The BIT STRING in the signature must be
// a multiple of 8 bits. |*out_signature| will have the padding byte removed.
// It returns true on success and false on failure.
bool ParseSubjectSignature(const base::StringPiece& subject_signature,
                           CBS* out_tbs_data,
                           ScopedX509_ALGOR* out_algor,
                           CBS* out_signature) {
  CBS cbs, sequence, tbs_data, algorithm, signature;
  CBS_init(&cbs, reinterpret_cast<const uint8_t*>(subject_signature.data()),
           subject_signature.size());
  if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE) ||
      CBS_len(&cbs) != 0 ||
      !CBS_get_any_asn1_element(&sequence, &tbs_data, nullptr, nullptr) ||
      !CBS_get_asn1_element(&sequence, &algorithm,
                            CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1(&sequence, &signature, CBS_ASN1_BITSTRING) ||
      CBS_len(&sequence) != 0) {
    return false;
  }

  // Decode the algorithm.
  const uint8_t* ptr = CBS_data(&algorithm);
  ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &ptr, CBS_len(&algorithm)));
  if (!algor || ptr != CBS_data(&algorithm) + CBS_len(&algorithm))
    return false;

  // An ASN.1 BIT STRING is encoded with a leading byte denoting the number of
  // padding bits. All supported signature algorithms output octets, so the
  // leading byte must be zero.
  uint8_t padding;
  if (!CBS_get_u8(&signature, &padding) || padding != 0)
    return false;

  *out_tbs_data = tbs_data;
  *out_algor = algor.Pass();
  *out_signature = signature;
  return true;
}

}  // namespace

BOOL CryptVerifyCertificateSignatureExHook(
    CryptVerifyCertificateSignatureExFunc original_func,
    HCRYPTPROV_LEGACY provider,
    DWORD encoding_type,
    DWORD subject_type,
    void* subject_data,
    DWORD issuer_type,
    void* issuer_data,
    DWORD flags,
    void* extra) {
  CHECK(original_func);

  // Only intercept if the arguments are supported.
  if (provider != NULL || (encoding_type != X509_ASN_ENCODING) ||
      !IsSupportedSubjectType(subject_type) || subject_data == NULL ||
      !IsSupportedIssuerType(issuer_type) || issuer_data == NULL) {
    return original_func(provider, encoding_type, subject_type, subject_data,
                         issuer_type, issuer_data, flags, extra);
  }

  base::StringPiece subject_signature =
      GetSubjectSignature(subject_type, subject_data);
  bool should_intercept = false;

  // Parse out the data, AlgorithmIdentifier, and signature.
  CBS tbs_data, signature;
  ScopedX509_ALGOR algor;
  if (ParseSubjectSignature(subject_signature, &tbs_data, &algor,
                            &signature)) {
    // If the signature algorithm is RSA with one of the SHA-2 algorithms
    // supported by BoringSSL (excluding SHA-224, which is pointless), then
    // defer to the BoringSSL implementation. Otherwise, fall back and let the
    // OS handle it (e.g. in case there are any algorithm policies in effect).
    int nid = OBJ_obj2nid(algor->algorithm);
    if (nid == NID_sha256WithRSAEncryption ||
        nid == NID_sha384WithRSAEncryption ||
        nid == NID_sha512WithRSAEncryption) {
      should_intercept = true;
    }
  }

  if (!should_intercept) {
    return original_func(provider, encoding_type, subject_type, subject_data,
                         issuer_type, issuer_data, flags, extra);
  }

  // Rather than attempting to synthesize an EVP_PKEY by hand, just force the
  // OS to do an ASN.1 encoding and then decode it back into BoringSSL. This
  // is silly for performance, but safest for consistency.
  PCERT_PUBLIC_KEY_INFO issuer_public_key =
      GetIssuerPublicKey(issuer_type, issuer_data);
  if (!issuer_public_key) {
    SetLastError(static_cast<DWORD>(NTE_BAD_ALGID));
    return FALSE;
  }

  uint8_t* issuer_spki_data = NULL;
  DWORD issuer_spki_len = 0;
  if (!CryptEncodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
                           issuer_public_key, CRYPT_ENCODE_ALLOC_FLAG, NULL,
                           &issuer_spki_data, &issuer_spki_len)) {
    return FALSE;
  }

  const uint8_t* ptr = issuer_spki_data;
  crypto::ScopedEVP_PKEY pubkey(d2i_PUBKEY(NULL, &ptr, issuer_spki_len));
  if (!pubkey.get() || ptr != issuer_spki_data + issuer_spki_len) {
    ::LocalFree(issuer_spki_data);
    SetLastError(static_cast<DWORD>(NTE_BAD_ALGID));
    return FALSE;
  }
  ::LocalFree(issuer_spki_data);

  crypto::ScopedEVP_MD_CTX md_ctx(EVP_MD_CTX_create());
  if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
                                         pubkey.get()) ||
      !EVP_DigestVerifyUpdate(md_ctx.get(), CBS_data(&tbs_data),
                              CBS_len(&tbs_data)) ||
      !EVP_DigestVerifyFinal(md_ctx.get(), CBS_data(&signature),
                            CBS_len(&signature))) {
    SetLastError(static_cast<DWORD>(NTE_BAD_SIGNATURE));
    return FALSE;
  }
  return TRUE;
}

}  // namespace sha256_interception

}  // namespace net
