// 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.h"

#include <openssl/digest.h>
#include <openssl/evp.h>

#include <utility>

#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "crypto/scoped_openssl_types.h"
#include "net/base/net_errors.h"
#include "net/ssl/openssl_client_key_store.h"
#include "net/ssl/ssl_platform_key_task_runner.h"
#include "net/ssl/ssl_private_key.h"
#include "net/ssl/threaded_ssl_private_key.h"

namespace net {

namespace {

class SSLPlatformKeyAndroid : public ThreadedSSLPrivateKey::Delegate {
 public:
  SSLPlatformKeyAndroid(crypto::ScopedEVP_PKEY key, SSLPrivateKey::Type type)
      : key_(std::move(key)), type_(type) {}

  ~SSLPlatformKeyAndroid() override {}

  SSLPrivateKey::Type GetType() override { return type_; }

  std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override {
    static const SSLPrivateKey::Hash kHashes[] = {
        SSLPrivateKey::Hash::SHA512, SSLPrivateKey::Hash::SHA384,
        SSLPrivateKey::Hash::SHA256, SSLPrivateKey::Hash::SHA1};
    return std::vector<SSLPrivateKey::Hash>(kHashes,
                                            kHashes + arraysize(kHashes));
  }

  size_t GetMaxSignatureLengthInBytes() override {
    return EVP_PKEY_size(key_.get());
  }

  Error SignDigest(SSLPrivateKey::Hash hash,
                   const base::StringPiece& input,
                   std::vector<uint8_t>* signature) override {
    crypto::ScopedEVP_PKEY_CTX ctx =
        crypto::ScopedEVP_PKEY_CTX(EVP_PKEY_CTX_new(key_.get(), NULL));
    if (!ctx)
      return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
    if (!EVP_PKEY_sign_init(ctx.get()))
      return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;

    if (type_ == SSLPrivateKey::Type::RSA) {
      const EVP_MD* digest = nullptr;
      switch (hash) {
        case SSLPrivateKey::Hash::MD5_SHA1:
          digest = EVP_md5_sha1();
          break;
        case SSLPrivateKey::Hash::SHA1:
          digest = EVP_sha1();
          break;
        case SSLPrivateKey::Hash::SHA256:
          digest = EVP_sha256();
          break;
        case SSLPrivateKey::Hash::SHA384:
          digest = EVP_sha384();
          break;
        case SSLPrivateKey::Hash::SHA512:
          digest = EVP_sha512();
          break;
        default:
          return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
      }
      DCHECK(digest);
      if (!EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING))
        return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
      if (!EVP_PKEY_CTX_set_signature_md(ctx.get(), digest))
        return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
    }

    const uint8_t* input_ptr = reinterpret_cast<const uint8_t*>(input.data());
    size_t input_len = input.size();
    size_t sig_len = 0;
    if (!EVP_PKEY_sign(ctx.get(), NULL, &sig_len, input_ptr, input_len))
      return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
    signature->resize(sig_len);
    if (!EVP_PKEY_sign(ctx.get(), signature->data(), &sig_len, input_ptr,
                       input_len)) {
      return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
    }

    signature->resize(sig_len);

    return OK;
  }

 private:
  crypto::ScopedEVP_PKEY key_;
  SSLPrivateKey::Type type_;

  DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyAndroid);
};

scoped_refptr<SSLPrivateKey> WrapOpenSSLPrivateKey(crypto::ScopedEVP_PKEY key) {
  if (!key)
    return nullptr;

  SSLPrivateKey::Type type;
  switch (EVP_PKEY_id(key.get())) {
    case EVP_PKEY_RSA:
      type = SSLPrivateKey::Type::RSA;
      break;
    case EVP_PKEY_EC:
      type = SSLPrivateKey::Type::ECDSA;
      break;
    default:
      LOG(ERROR) << "Unknown key type: " << EVP_PKEY_id(key.get());
      return nullptr;
  }
  return make_scoped_refptr(new ThreadedSSLPrivateKey(
      base::WrapUnique(new SSLPlatformKeyAndroid(std::move(key), type)),
      GetSSLPlatformKeyTaskRunner()));
}

}  // namespace

scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(
    X509Certificate* certificate) {
  crypto::ScopedEVP_PKEY key =
      OpenSSLClientKeyStore::GetInstance()->FetchClientCertPrivateKey(
          certificate);
  return WrapOpenSSLPrivateKey(std::move(key));
}

}  // namespace net
