// 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_tree_head.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_);
}

bool CTLogVerifier::Init(const base::StringPiece& public_key) {
  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);

  // 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
