| Index: crypto/rsa_private_key_mac.cc
|
| ===================================================================
|
| --- crypto/rsa_private_key_mac.cc (revision 0)
|
| +++ crypto/rsa_private_key_mac.cc (revision 0)
|
| @@ -0,0 +1,196 @@
|
| +// 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 "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(), NULL, &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(), NULL, 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);
|
| + }
|
| +}
|
| +
|
| +bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) {
|
| + 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) {
|
| + 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
|
|
|
| Property changes on: crypto\rsa_private_key_mac.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|