diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-14 17:37:14 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-14 17:37:14 +0000 |
commit | 4b559b4ddffc0b7f688019bcb80658f05e063af7 (patch) | |
tree | 0be21d8914de707f5125d2cb66733cbcf088606c /crypto/rsa_private_key_mac.cc | |
parent | 056dd45d610de34312344445d7b078a31f4a1e20 (diff) | |
download | chromium_src-4b559b4ddffc0b7f688019bcb80658f05e063af7.zip chromium_src-4b559b4ddffc0b7f688019bcb80658f05e063af7.tar.gz chromium_src-4b559b4ddffc0b7f688019bcb80658f05e063af7.tar.bz2 |
Move crypto files out of base, to a top level directory.
src/crypto is now an independent project that contains our
cryptographic primitives (except md5 and sha1).
This removes the base dependency from nss, openssl and sqlite.
BUG=76996
TEST=none
Review URL: http://codereview.chromium.org/6805019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81611 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'crypto/rsa_private_key_mac.cc')
-rw-r--r-- | crypto/rsa_private_key_mac.cc | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/crypto/rsa_private_key_mac.cc b/crypto/rsa_private_key_mac.cc new file mode 100644 index 0000000..85dadfa --- /dev/null +++ b/crypto/rsa_private_key_mac.cc @@ -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 |