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

namespace crypto {

// static
RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) {
  scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);

  CSSM_CC_HANDLE cc_handle;
  CSSM_RETURN crtn;
  crtn = CSSM_CSP_CreateKeyGenContext(GetSharedCSPHandle(), CSSM_ALGID_RSA,
                                      num_bits, NULL, NULL, NULL, NULL, NULL,
                                      &cc_handle);
  if (crtn) {
    NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn;
    return NULL;
  }

  CSSM_DATA label = { 9,
      const_cast<uint8*>(reinterpret_cast<const uint8*>("temp_key")) };
  crtn = CSSM_GenerateKeyPair(cc_handle,
      CSSM_KEYUSE_VERIFY,
      CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label,
      result->public_key(), CSSM_KEYUSE_SIGN,
      CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label, NULL,
      result->key());
  CSSM_DeleteContext(cc_handle);
  if (crtn) {
    NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn;
    return NULL;
  }

  return result.release();
}

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

// static
RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo(
    const std::vector<uint8>& input) {
  if (input.empty())
    return NULL;

  scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey);

  CSSM_KEY key;
  memset(&key, 0, sizeof(key));
  key.KeyData.Data = const_cast<uint8*>(&input.front());
  key.KeyData.Length = input.size();
  key.KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8;
  key.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION;
  key.KeyHeader.BlobType = CSSM_KEYBLOB_RAW;
  key.KeyHeader.AlgorithmId = CSSM_ALGID_RSA;
  key.KeyHeader.KeyClass = CSSM_KEYCLASS_PRIVATE_KEY;
  key.KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
  key.KeyHeader.KeyUsage = CSSM_KEYUSE_ANY;

  CSSM_KEY_SIZE key_size;
  CSSM_RETURN crtn;
  crtn = CSSM_QueryKeySizeInBits(
      GetSharedCSPHandle(), CSSM_INVALID_HANDLE, &key, &key_size);
  if (crtn) {
    NOTREACHED() << "CSSM_QueryKeySizeInBits failed: " << crtn;
    return NULL;
  }
  key.KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits;

  // Perform a NULL unwrap operation on the key so that result's key_
  // instance variable points to a key that can be released via CSSM_FreeKey().
  CSSM_ACCESS_CREDENTIALS creds;
  memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
  CSSM_CC_HANDLE cc_handle;
  crtn = CSSM_CSP_CreateSymmetricContext(GetSharedCSPHandle(), CSSM_ALGID_NONE,
      CSSM_ALGMODE_NONE, &creds, NULL, NULL, CSSM_PADDING_NONE, 0, &cc_handle);
  if (crtn) {
    NOTREACHED() << "CSSM_CSP_CreateSymmetricContext failed: " << crtn;
    return NULL;
  }
  CSSM_DATA label_data, desc_data = { 0, NULL };
  label_data.Data =
      const_cast<uint8*>(reinterpret_cast<const uint8*>("unwrapped"));
  label_data.Length = 9;
  crtn = CSSM_UnwrapKey(cc_handle, NULL, &key, CSSM_KEYUSE_ANY,
      CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label_data,
      NULL, result->key(), &desc_data);
  if (crtn) {
    NOTREACHED() << "CSSM_UnwrapKey failed: " << crtn;
    return NULL;
  }

  // Extract a public key from the private key.
  // Apple doesn't accept CSSM_KEYBLOB_RAW_FORMAT_X509 as a valid key
  // format when attempting to generate certs, so use PKCS1 instead.
  PrivateKeyInfoCodec codec(true);
  std::vector<uint8> private_key_data;
  private_key_data.assign(key.KeyData.Data,
                          key.KeyData.Data + key.KeyData.Length);
  if (!codec.Import(private_key_data)) {
    return NULL;
  }
  std::vector<uint8> public_key_data;
  if (!codec.ExportPublicKey(&public_key_data)) {
    return NULL;
  }

  CSSM_KEY* public_key = result->public_key();
  size_t size = public_key_data.size();
  public_key->KeyData.Data = reinterpret_cast<uint8*>(CSSMMalloc(size));
  if (!public_key->KeyData.Data) {
    NOTREACHED() << "CSSMMalloc failed";
    return NULL;
  }
  memcpy(public_key->KeyData.Data, &public_key_data.front(), size);
  public_key->KeyData.Length = size;
  public_key->KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
  public_key->KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION;
  public_key->KeyHeader.BlobType = CSSM_KEYBLOB_RAW;
  public_key->KeyHeader.AlgorithmId = CSSM_ALGID_RSA;
  public_key->KeyHeader.KeyClass = CSSM_KEYCLASS_PUBLIC_KEY;
  public_key->KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE;
  public_key->KeyHeader.KeyUsage = CSSM_KEYUSE_ANY;

  crtn = CSSM_QueryKeySizeInBits(
      GetSharedCSPHandle(), CSSM_INVALID_HANDLE, public_key, &key_size);
  if (crtn) {
    DLOG(ERROR) << "CSSM_QueryKeySizeInBits failed " << crtn;
    return NULL;
  }
  public_key->KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits;

  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() {
  memset(&key_, 0, sizeof(key_));
  memset(&public_key_, 0, sizeof(public_key_));

  EnsureCSSMInit();
}

RSAPrivateKey::~RSAPrivateKey() {
  if (key_.KeyData.Data) {
    CSSM_FreeKey(GetSharedCSPHandle(), NULL, &key_, CSSM_FALSE);
  }
  if (public_key_.KeyData.Data) {
    CSSM_FreeKey(GetSharedCSPHandle(), NULL, &public_key_, CSSM_FALSE);
  }
}

RSAPrivateKey* RSAPrivateKey::Copy() const {
  std::vector<uint8> key_bytes;
  if (!ExportPrivateKey(&key_bytes))
    return NULL;
  return CreateFromPrivateKeyInfo(key_bytes);
}

bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) const {
  if (!key_.KeyData.Data || !key_.KeyData.Length) {
    return false;
  }
  output->clear();
  output->insert(output->end(), key_.KeyData.Data,
                 key_.KeyData.Data + key_.KeyData.Length);
  return true;
}

bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) const {
  PrivateKeyInfoCodec private_key_info(true);
  std::vector<uint8> private_key_data;
  private_key_data.assign(key_.KeyData.Data,
                          key_.KeyData.Data + key_.KeyData.Length);
  return (private_key_info.Import(private_key_data) &&
          private_key_info.ExportPublicKeyInfo(output));
}

}  // namespace crypto
