// Copyright (c) 2011 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 "crypto/rsa_private_key.h"

#include <list>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_util.h"

namespace {
  // Helper for error handling during key import.
#define READ_ASSERT(truth) \
  if (!(truth)) { \
  NOTREACHED(); \
  return false; \
  }
}  // namespace

namespace crypto {

// static
RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) {
  scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
  if (!result->InitProvider())
    return NULL;

  DWORD flags = CRYPT_EXPORTABLE;

  // The size is encoded as the upper 16 bits of the flags. :: sigh ::.
  flags |= (num_bits << 16);
  if (!CryptGenKey(result->provider_, CALG_RSA_SIGN, flags,
                   result->key_.receive()))
    return NULL;

  return result.release();
}

// static
RSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) {
  NOTIMPLEMENTED();
  return NULL;
}

// static
RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
    const std::vector<uint8>& input) {
  scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);
  if (!result->InitProvider())
    return NULL;

  PrivateKeyInfoCodec pki(false);  // Little-Endian
  pki.Import(input);

  int blob_size = sizeof(PUBLICKEYSTRUC) +
                  sizeof(RSAPUBKEY) +
                  pki.modulus()->size() +
                  pki.prime1()->size() +
                  pki.prime2()->size() +
                  pki.exponent1()->size() +
                  pki.exponent2()->size() +
                  pki.coefficient()->size() +
                  pki.private_exponent()->size();
  scoped_array<BYTE> blob(new BYTE[blob_size]);

  uint8* dest = blob.get();
  PUBLICKEYSTRUC* public_key_struc = reinterpret_cast<PUBLICKEYSTRUC*>(dest);
  public_key_struc->bType = PRIVATEKEYBLOB;
  public_key_struc->bVersion = 0x02;
  public_key_struc->reserved = 0;
  public_key_struc->aiKeyAlg = CALG_RSA_SIGN;
  dest += sizeof(PUBLICKEYSTRUC);

  RSAPUBKEY* rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(dest);
  rsa_pub_key->magic = 0x32415352;
  rsa_pub_key->bitlen = pki.modulus()->size() * 8;
  int public_exponent_int = 0;
  for (size_t i = pki.public_exponent()->size(); i > 0; --i) {
    public_exponent_int <<= 8;
    public_exponent_int |= (*pki.public_exponent())[i - 1];
  }
  rsa_pub_key->pubexp = public_exponent_int;
  dest += sizeof(RSAPUBKEY);

  memcpy(dest, &pki.modulus()->front(), pki.modulus()->size());
  dest += pki.modulus()->size();
  memcpy(dest, &pki.prime1()->front(), pki.prime1()->size());
  dest += pki.prime1()->size();
  memcpy(dest, &pki.prime2()->front(), pki.prime2()->size());
  dest += pki.prime2()->size();
  memcpy(dest, &pki.exponent1()->front(), pki.exponent1()->size());
  dest += pki.exponent1()->size();
  memcpy(dest, &pki.exponent2()->front(), pki.exponent2()->size());
  dest += pki.exponent2()->size();
  memcpy(dest, &pki.coefficient()->front(), pki.coefficient()->size());
  dest += pki.coefficient()->size();
  memcpy(dest, &pki.private_exponent()->front(),
         pki.private_exponent()->size());
  dest += pki.private_exponent()->size();

  READ_ASSERT(dest == blob.get() + blob_size);
  if (!CryptImportKey(result->provider_,
                      reinterpret_cast<uint8*>(public_key_struc), blob_size, 0,
                      CRYPT_EXPORTABLE, result->key_.receive()))
    return NULL;

  return result.release();
}

// static
RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(
    const std::vector<uint8>& input) {
  NOTIMPLEMENTED();
  return NULL;
}

// static
RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo(
    const std::vector<uint8>& input) {
  NOTIMPLEMENTED();
  return NULL;
}

RSAPrivateKey::RSAPrivateKey() : provider_(NULL), key_(NULL) {}

RSAPrivateKey::~RSAPrivateKey() {}

bool RSAPrivateKey::InitProvider() {
  return FALSE != CryptAcquireContext(provider_.receive(), NULL, NULL,
                                      PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
}

bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) {
  // Export the key
  DWORD blob_length = 0;
  if (!CryptExportKey(key_, 0, PRIVATEKEYBLOB, 0, NULL, &blob_length)) {
    NOTREACHED();
    return false;
  }

  scoped_array<uint8> blob(new uint8[blob_length]);
  if (!CryptExportKey(key_, 0, PRIVATEKEYBLOB, 0, blob.get(), &blob_length)) {
    NOTREACHED();
    return false;
  }

  uint8* pos = blob.get();
  PUBLICKEYSTRUC *publickey_struct = reinterpret_cast<PUBLICKEYSTRUC*>(pos);
  pos += sizeof(PUBLICKEYSTRUC);

  RSAPUBKEY *rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(pos);
  pos += sizeof(RSAPUBKEY);

  int mod_size = rsa_pub_key->bitlen / 8;
  int primes_size = rsa_pub_key->bitlen / 16;

  PrivateKeyInfoCodec pki(false);  // Little-Endian

  pki.modulus()->assign(pos, pos + mod_size);
  pos += mod_size;

  pki.prime1()->assign(pos, pos + primes_size);
  pos += primes_size;
  pki.prime2()->assign(pos, pos + primes_size);
  pos += primes_size;

  pki.exponent1()->assign(pos, pos + primes_size);
  pos += primes_size;
  pki.exponent2()->assign(pos, pos + primes_size);
  pos += primes_size;

  pki.coefficient()->assign(pos, pos + primes_size);
  pos += primes_size;

  pki.private_exponent()->assign(pos, pos + mod_size);
  pos += mod_size;

  pki.public_exponent()->assign(reinterpret_cast<uint8*>(&rsa_pub_key->pubexp),
      reinterpret_cast<uint8*>(&rsa_pub_key->pubexp) + 4);

  CHECK_EQ(pos - blob_length, reinterpret_cast<BYTE*>(publickey_struct));

  return pki.Export(output);
}

bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) {
  DWORD key_info_len;
  if (!CryptExportPublicKeyInfo(
      provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
      NULL, &key_info_len)) {
    NOTREACHED();
    return false;
  }

  scoped_array<uint8> key_info(new uint8[key_info_len]);
  if (!CryptExportPublicKeyInfo(
      provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
      reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), &key_info_len)) {
    NOTREACHED();
    return false;
  }

  DWORD encoded_length;
  if (!CryptEncodeObject(
      X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
      reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), NULL,
      &encoded_length)) {
    NOTREACHED();
    return false;
  }

  scoped_array<BYTE> encoded(new BYTE[encoded_length]);
  if (!CryptEncodeObject(
      X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
      reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), encoded.get(),
      &encoded_length)) {
    NOTREACHED();
    return false;
  }

  for (size_t i = 0; i < encoded_length; ++i)
    output->push_back(encoded[i]);

  return true;
}

}  // namespace crypto
