// Copyright (c) 2011 The Chromium OS 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 "login_manager/nss_util.h"

#include <stdint.h>
#include <stdlib.h>

#include <string>
#include <utility>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/memory/scoped_ptr.h>
#include <base/strings/stringprintf.h>
#include <crypto/nss_util.h>
#include <crypto/nss_util_internal.h>
#include <crypto/rsa_private_key.h>
#include <crypto/scoped_nss_types.h>
#include <crypto/signature_creator.h>
#include <crypto/signature_verifier.h>
#include <keyhi.h>
#include <pk11pub.h>
#include <prerror.h>
#include <secmod.h>
#include <secmodt.h>

using crypto::RSAPrivateKey;
using crypto::ScopedPK11Slot;
using crypto::ScopedSECItem;
using crypto::ScopedSECKEYPublicKey;
using crypto::ScopedSECKEYPrivateKey;

namespace {
// This should match the same constant in Chrome tree:
// chrome/browser/chromeos/settings/owner_key_util.cc
const char kOwnerKeyFile[] = "/var/lib/whitelist/owner.key";
}  // namespace

namespace login_manager {
///////////////////////////////////////////////////////////////////////////
// NssUtil

NssUtil::NssUtil() {
}

NssUtil::~NssUtil() {
}

///////////////////////////////////////////////////////////////////////////
// NssUtilImpl

class NssUtilImpl : public NssUtil {
 public:
  NssUtilImpl();
  virtual ~NssUtilImpl();

  ScopedPK11Slot OpenUserDB(const base::FilePath& user_homedir) override;

  RSAPrivateKey* GetPrivateKeyForUser(
      const std::vector<uint8_t>& public_key_der,
      PK11SlotInfo* user_slot) override;

  RSAPrivateKey* GenerateKeyPairForUser(PK11SlotInfo* user_slot) override;

  base::FilePath GetOwnerKeyFilePath() override;

  base::FilePath GetNssdbSubpath() override;

  bool CheckPublicKeyBlob(const std::vector<uint8_t>& blob) override;

  bool Verify(const uint8_t* algorithm,
              int algorithm_len,
              const uint8_t* signature,
              int signature_len,
              const uint8_t* data,
              int data_len,
              const uint8_t* public_key,
              int public_key_len) override;

  bool Sign(const uint8_t* data,
            int data_len,
            std::vector<uint8_t>* OUT_signature,
            RSAPrivateKey* key) override;

 private:
  static const uint16_t kKeySizeInBits;
  static const char kNssdbSubpath[];

  DISALLOW_COPY_AND_ASSIGN(NssUtilImpl);
};

// Defined here, instead of up above, because we need NssUtilImpl.
// static
NssUtil* NssUtil::Create() {
  return new NssUtilImpl;
}

// static
void NssUtil::BlobFromBuffer(const std::string& buf,
                             std::vector<uint8_t>* out) {
  out->resize(buf.length());
  if (out->size() == 0)
    return;
  memcpy(&((*out)[0]), buf.c_str(), out->size());
}

// We're generating and using 2048-bit RSA keys.
// static
const uint16_t NssUtilImpl::kKeySizeInBits = 2048;
// static
const char NssUtilImpl::kNssdbSubpath[] = ".pki/nssdb";

NssUtilImpl::NssUtilImpl() {
  if (setenv("NSS_SDB_USE_CACHE", "no", 1) == -1)
    PLOG(WARNING) << "Can't set NSS_SDB_USE_CACHE=no in the environment!";
  crypto::EnsureNSSInit();
}

NssUtilImpl::~NssUtilImpl() {
}

ScopedPK11Slot NssUtilImpl::OpenUserDB(const base::FilePath& user_homedir) {
  // TODO(cmasone): If we ever try to keep the session_manager alive across
  // user sessions, we'll need to close these persistent DBs.
  base::FilePath db_path(user_homedir.AppendASCII(kNssdbSubpath));
  const std::string modspec =
      base::StringPrintf("configDir='sql:%s' tokenDescription='%s'",
                         db_path.value().c_str(),
                         user_homedir.value().c_str());
  ScopedPK11Slot db_slot(SECMOD_OpenUserDB(modspec.c_str()));
  if (!db_slot.get()) {
    LOG(ERROR) << "Error opening persistent database (" << modspec
               << "): " << PR_GetError();
    return ScopedPK11Slot();
  }
  if (PK11_NeedUserInit(db_slot.get()))
    PK11_InitPin(db_slot.get(), NULL, NULL);

  // If we opened successfully, we will have a non-default private key slot.
  if (PK11_IsInternalKeySlot(db_slot.get()))
    return ScopedPK11Slot();

  return ScopedPK11Slot(db_slot.get());
}

RSAPrivateKey* NssUtilImpl::GetPrivateKeyForUser(
    const std::vector<uint8_t>& public_key_der,
    PK11SlotInfo* user_slot) {
  if (public_key_der.size() == 0) {
    LOG(ERROR) << "Not checking key because size is 0";
    return NULL;
  }

  // First, decode and save the public key.
  SECItem key_der;
  key_der.type = siBuffer;
  key_der.data = const_cast<unsigned char*>(&public_key_der[0]);
  key_der.len = public_key_der.size();

  CERTSubjectPublicKeyInfo* spki =
      SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der);
  if (!spki) {
    NOTREACHED();
    return NULL;
  }

  ScopedSECKEYPublicKey public_key(SECKEY_ExtractPublicKey(spki));
  SECKEY_DestroySubjectPublicKeyInfo(spki);
  if (!public_key.get()) {
    NOTREACHED();
    return NULL;
  }

  // Make sure the key is an RSA key.  If not, that's an error
  if (SECKEY_GetPublicKeyType(public_key.get()) != rsaKey) {
    NOTREACHED();
    return NULL;
  }

  ScopedSECItem ck_id(PK11_MakeIDFromPubKey(&(public_key->u.rsa.modulus)));
  if (!ck_id.get()) {
    NOTREACHED();
    return NULL;
  }

  // Search in just the user slot for the key with the given ID.
  ScopedSECKEYPrivateKey key(PK11_FindKeyByKeyID(user_slot, ck_id.get(), NULL));
  if (key.get())
    return RSAPrivateKey::CreateFromKey(key.get());

  // We didn't find the key.
  return NULL;
}

RSAPrivateKey* NssUtilImpl::GenerateKeyPairForUser(PK11SlotInfo* user_slot) {
  PK11RSAGenParams param;
  param.keySizeInBits = kKeySizeInBits;
  param.pe = 65537L;
  SECKEYPublicKey* public_key_ptr = NULL;
  ScopedSECKEYPrivateKey key(PK11_GenerateKeyPair(user_slot,
                                                  CKM_RSA_PKCS_KEY_PAIR_GEN,
                                                  &param,
                                                  &public_key_ptr,
                                                  PR_TRUE /* permanent */,
                                                  PR_TRUE /* sensitive */,
                                                  NULL));
  ScopedSECKEYPublicKey public_key(public_key_ptr);
  if (!key.get())
    return NULL;

  return RSAPrivateKey::CreateFromKey(key.get());
}

base::FilePath NssUtilImpl::GetOwnerKeyFilePath() {
  return base::FilePath(kOwnerKeyFile);
}

base::FilePath NssUtilImpl::GetNssdbSubpath() {
  return base::FilePath(kNssdbSubpath);
}

bool NssUtilImpl::CheckPublicKeyBlob(const std::vector<uint8_t>& blob) {
  CERTSubjectPublicKeyInfo* spki = NULL;
  SECItem spki_der;
  spki_der.type = siBuffer;
  spki_der.data = const_cast<uint8_t*>(&blob[0]);
  spki_der.len = blob.size();
  spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_der);
  if (!spki)
    return false;

  ScopedSECKEYPublicKey public_key(SECKEY_ExtractPublicKey(spki));
  SECKEY_DestroySubjectPublicKeyInfo(spki);  // Done with spki.
  if (!public_key.get())
    return false;
  return true;
}

// This is pretty much just a blind passthrough, so I won't test it
// in the NssUtil unit tests.  I'll test it from a class that uses this API.
bool NssUtilImpl::Verify(const uint8_t* algorithm,
                         int algorithm_len,
                         const uint8_t* signature,
                         int signature_len,
                         const uint8_t* data,
                         int data_len,
                         const uint8_t* public_key,
                         int public_key_len) {
  crypto::SignatureVerifier verifier_;

  if (!verifier_.VerifyInit(algorithm,
                            algorithm_len,
                            signature,
                            signature_len,
                            public_key,
                            public_key_len)) {
    LOG(ERROR) << "Could not initialize verifier";
    return false;
  }

  verifier_.VerifyUpdate(data, data_len);
  return (verifier_.VerifyFinal());
}

// This is pretty much just a blind passthrough, so I won't test it
// in the NssUtil unit tests.  I'll test it from a class that uses this API.
bool NssUtilImpl::Sign(const uint8_t* data,
                       int data_len,
                       std::vector<uint8_t>* OUT_signature,
                       RSAPrivateKey* key) {
  scoped_ptr<crypto::SignatureCreator> signer(
      crypto::SignatureCreator::Create(key, crypto::SignatureCreator::SHA1));
  if (!signer->Update(data, data_len))
    return false;
  return signer->Final(OUT_signature);
}

}  // namespace login_manager
