// Copyright 2013 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/cert/ct_log_verifier.h"

#include <cryptohi.h>
#include <keyhi.h>
#include <nss.h>
#include <pk11pub.h>
#include <secitem.h>
#include <secoid.h>

#include "base/logging.h"
#include "crypto/nss_util.h"
#include "crypto/sha2.h"
#include "net/cert/signed_certificate_timestamp.h"

namespace net {

namespace {

SECOidTag GetNSSSigAlg(ct::DigitallySigned::SignatureAlgorithm alg) {
  switch (alg) {
    case ct::DigitallySigned::SIG_ALGO_RSA:
      return SEC_OID_PKCS1_RSA_ENCRYPTION;
    case ct::DigitallySigned::SIG_ALGO_DSA:
      return SEC_OID_ANSIX9_DSA_SIGNATURE;
    case ct::DigitallySigned::SIG_ALGO_ECDSA:
      return SEC_OID_ANSIX962_EC_PUBLIC_KEY;
    case ct::DigitallySigned::SIG_ALGO_ANONYMOUS:
    default:
      NOTREACHED();
      return SEC_OID_UNKNOWN;
  }
}

SECOidTag GetNSSHashAlg(ct::DigitallySigned::HashAlgorithm alg) {
  switch (alg) {
    case ct::DigitallySigned::HASH_ALGO_MD5:
      return SEC_OID_MD5;
    case ct::DigitallySigned::HASH_ALGO_SHA1:
      return SEC_OID_SHA1;
    case ct::DigitallySigned::HASH_ALGO_SHA224:
      return SEC_OID_SHA224;
    case ct::DigitallySigned::HASH_ALGO_SHA256:
      return SEC_OID_SHA256;
    case ct::DigitallySigned::HASH_ALGO_SHA384:
      return SEC_OID_SHA384;
    case ct::DigitallySigned::HASH_ALGO_SHA512:
      return SEC_OID_SHA512;
    case ct::DigitallySigned::HASH_ALGO_NONE:
    default:
      NOTREACHED();
      return SEC_OID_UNKNOWN;
  }
}

}  // namespace

CTLogVerifier::~CTLogVerifier() {
  if (public_key_)
    SECKEY_DestroyPublicKey(public_key_);
}

CTLogVerifier::CTLogVerifier()
    : hash_algorithm_(ct::DigitallySigned::HASH_ALGO_NONE),
      signature_algorithm_(ct::DigitallySigned::SIG_ALGO_ANONYMOUS),
      public_key_(NULL) {}

bool CTLogVerifier::Init(const base::StringPiece& public_key,
                         const base::StringPiece& description) {
  SECItem key_data;

  crypto::EnsureNSSInit();

  key_data.data = reinterpret_cast<unsigned char*>(
      const_cast<char*>(public_key.data()));
  key_data.len = public_key.size();

  CERTSubjectPublicKeyInfo* public_key_info =
      SECKEY_DecodeDERSubjectPublicKeyInfo(&key_data);
  if (!public_key_info) {
    DVLOG(1) << "Failed decoding public key.";
    return false;
  }

  public_key_ = SECKEY_ExtractPublicKey(public_key_info);
  SECKEY_DestroySubjectPublicKeyInfo(public_key_info);

  if (!public_key_) {
    DVLOG(1) << "Failed extracting public key.";
    return false;
  }

  key_id_ = crypto::SHA256HashString(public_key);
  description_ = description.as_string();

  // Right now, only RSASSA-PKCS1v15 with SHA-256 and ECDSA with SHA-256 are
  // supported.
  switch (SECKEY_GetPublicKeyType(public_key_)) {
    case rsaKey:
      hash_algorithm_ = ct::DigitallySigned::HASH_ALGO_SHA256;
      signature_algorithm_ = ct::DigitallySigned::SIG_ALGO_RSA;
      break;
    case ecKey:
      hash_algorithm_ = ct::DigitallySigned::HASH_ALGO_SHA256;
      signature_algorithm_ = ct::DigitallySigned::SIG_ALGO_ECDSA;
      break;
    default:
      DVLOG(1) << "Unsupported key type: "
               << SECKEY_GetPublicKeyType(public_key_);
      return false;
  }

  // Extra sanity check: Require RSA keys of at least 2048 bits.
  if (signature_algorithm_ == ct::DigitallySigned::SIG_ALGO_RSA &&
      SECKEY_PublicKeyStrengthInBits(public_key_) < 2048) {
    DVLOG(1) << "Too small a public key.";
    return false;
  }

  return true;
}

bool CTLogVerifier::VerifySignature(const base::StringPiece& data_to_sign,
                                    const base::StringPiece& signature) {
  SECItem sig_data;
  sig_data.data = reinterpret_cast<unsigned char*>(const_cast<char*>(
      signature.data()));
  sig_data.len = signature.size();

  SECStatus rv = VFY_VerifyDataDirect(
      reinterpret_cast<const unsigned char*>(data_to_sign.data()),
      data_to_sign.size(), public_key_, &sig_data,
      GetNSSSigAlg(signature_algorithm_), GetNSSHashAlg(hash_algorithm_),
      NULL, NULL);
  DVLOG(1) << "Signature verification result: " << (rv == SECSuccess);
  return rv == SECSuccess;
}

}  // namespace net
