// Copyright 2015 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 "net/ssl/ssl_platform_key_nss.h"

#include <cert.h>
#include <keyhi.h>
#include <pk11pub.h>
#include <prerror.h>

#include <memory>
#include <utility>

#include "base/logging.h"
#include "base/macros.h"
#include "base/threading/scoped_blocking_call.h"
#include "crypto/nss_crypto_module_delegate.h"
#include "crypto/scoped_nss_types.h"
#include "net/cert/x509_certificate.h"
#include "net/ssl/ssl_platform_key_util.h"
#include "net/ssl/ssl_private_key.h"
#include "net/ssl/threaded_ssl_private_key.h"
#include "starboard/types.h"
#include "third_party/boringssl/src/include/openssl/bn.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/ec.h"
#include "third_party/boringssl/src/include/openssl/ec_key.h"
#include "third_party/boringssl/src/include/openssl/ecdsa.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
#include "third_party/boringssl/src/include/openssl/mem.h"
#include "third_party/boringssl/src/include/openssl/nid.h"
#include "third_party/boringssl/src/include/openssl/rsa.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"

namespace net {

namespace {

void LogPRError(const char* message) {
  PRErrorCode err = PR_GetError();
  const char* err_name = PR_ErrorToName(err);
  if (err_name == nullptr)
    err_name = "";
  LOG(ERROR) << message << ": " << err << " (" << err_name << ")";
}

class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate {
 public:
  SSLPlatformKeyNSS(int type,
                    scoped_refptr<crypto::CryptoModuleBlockingPasswordDelegate>
                        password_delegate,
                    crypto::ScopedSECKEYPrivateKey key)
      : type_(type),
        password_delegate_(std::move(password_delegate)),
        key_(std::move(key)) {}
  ~SSLPlatformKeyNSS() override = default;

  std::vector<uint16_t> GetAlgorithmPreferences() override {
    return SSLPrivateKey::DefaultAlgorithmPreferences(type_,
                                                      true /* supports PSS */);
  }

  Error Sign(uint16_t algorithm,
             base::span<const uint8_t> input,
             std::vector<uint8_t>* signature) override {
    const EVP_MD* md = SSL_get_signature_algorithm_digest(algorithm);
    uint8_t digest[EVP_MAX_MD_SIZE];
    unsigned digest_len;
    if (!md || !EVP_Digest(input.data(), input.size(), digest, &digest_len, md,
                           nullptr)) {
      return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
    }
    SECItem digest_item;
    digest_item.data = digest;
    digest_item.len = digest_len;

    CK_MECHANISM_TYPE mechanism = PK11_MapSignKeyType(key_->keyType);
    SECItem param = {siBuffer, nullptr, 0};
    CK_RSA_PKCS_PSS_PARAMS pss_params;
    bssl::UniquePtr<uint8_t> free_digest_info;
    if (SSL_is_signature_algorithm_rsa_pss(algorithm)) {
      switch (EVP_MD_type(md)) {
        case NID_sha256:
          pss_params.hashAlg = CKM_SHA256;
          pss_params.mgf = CKG_MGF1_SHA256;
          break;
        case NID_sha384:
          pss_params.hashAlg = CKM_SHA384;
          pss_params.mgf = CKG_MGF1_SHA384;
          break;
        case NID_sha512:
          pss_params.hashAlg = CKM_SHA512;
          pss_params.mgf = CKG_MGF1_SHA512;
          break;
        default:
          LOG(ERROR) << "Unexpected hash algorithm";
          return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
      }
      // Use the hash length for the salt length.
      pss_params.sLen = EVP_MD_size(md);
      mechanism = CKM_RSA_PKCS_PSS;
      param.data = reinterpret_cast<unsigned char*>(&pss_params);
      param.len = sizeof(pss_params);
    } else if (SSL_get_signature_algorithm_key_type(algorithm) ==
               EVP_PKEY_RSA) {
      // PK11_SignWithMechanism expects the caller to prepend the DigestInfo for
      // PKCS #1.
      int hash_nid = EVP_MD_type(SSL_get_signature_algorithm_digest(algorithm));
      int is_alloced;
      size_t prefix_len;
      if (!RSA_add_pkcs1_prefix(&digest_item.data, &prefix_len, &is_alloced,
                                hash_nid, digest_item.data, digest_item.len)) {
        return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
      }
      digest_item.len = prefix_len;
      if (is_alloced)
        free_digest_info.reset(digest_item.data);
    }

    int len = PK11_SignatureLen(key_.get());
    if (len <= 0) {
      LogPRError("PK11_SignatureLen failed");
      return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
    }
    signature->resize(len);
    SECItem signature_item;
    signature_item.data = signature->data();
    signature_item.len = signature->size();

    SECStatus rv = PK11_SignWithMechanism(key_.get(), mechanism, &param,
                                          &signature_item, &digest_item);
    if (rv != SECSuccess) {
      LogPRError("PK11_SignWithMechanism failed");
      return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
    }
    signature->resize(signature_item.len);

    // NSS emits raw ECDSA signatures, but BoringSSL expects a DER-encoded
    // ECDSA-Sig-Value.
    if (SSL_get_signature_algorithm_key_type(algorithm) == EVP_PKEY_EC) {
      if (signature->size() % 2 != 0) {
        LOG(ERROR) << "Bad signature length";
        return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
      }
      size_t order_len = signature->size() / 2;

      // Convert the RAW ECDSA signature to a DER-encoded ECDSA-Sig-Value.
      bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
      if (!sig || !BN_bin2bn(signature->data(), order_len, sig->r) ||
          !BN_bin2bn(signature->data() + order_len, order_len, sig->s)) {
        return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
      }

      int len = i2d_ECDSA_SIG(sig.get(), nullptr);
      if (len <= 0)
        return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
      signature->resize(len);
      uint8_t* ptr = signature->data();
      len = i2d_ECDSA_SIG(sig.get(), &ptr);
      if (len <= 0)
        return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
      signature->resize(len);
    }

    return OK;
  }

 private:
  int type_;
  // NSS retains a pointer to the password delegate, so retain a reference here
  // to ensure the lifetimes are correct.
  scoped_refptr<crypto::CryptoModuleBlockingPasswordDelegate>
      password_delegate_;
  crypto::ScopedSECKEYPrivateKey key_;

  DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyNSS);
};

}  // namespace

scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
    const X509Certificate* certificate,
    CERTCertificate* cert_certificate,
    scoped_refptr<crypto::CryptoModuleBlockingPasswordDelegate>
        password_delegate) {
  // This function may acquire the NSS lock or reenter this code via extension
  // hooks (such as smart card UI). To ensure threads are not starved or
  // deadlocked, the base::ScopedBlockingCall below increments the thread pool
  // capacity if this method takes too much time to run.
  base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);

  void* wincx = password_delegate ? password_delegate->wincx() : nullptr;
  crypto::ScopedSECKEYPrivateKey key(
      PK11_FindKeyByAnyCert(cert_certificate, wincx));
  if (!key)
    return nullptr;

  int type;
  size_t max_length;
  if (!GetClientCertInfo(certificate, &type, &max_length))
    return nullptr;

  // Note that key contains a reference to password_delegate->wincx() and may
  // use it in PK11_Sign. Thus password_delegate must outlive key. We pass it
  // into SSLPlatformKeyNSS to tie the lifetimes together. See
  // https://crbug.com/779090.
  return base::MakeRefCounted<ThreadedSSLPrivateKey>(
      std::make_unique<SSLPlatformKeyNSS>(type, std::move(password_delegate),
                                          std::move(key)),
      GetSSLPlatformKeyTaskRunner());
}

}  // namespace net
