1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/rsa_private_key.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <cryptohi.h> 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <keyhi.h> 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <pk11pub.h> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <list> 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/debug/leak_annotations.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/nss_util.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/nss_util_internal.h" 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// TODO(rafaelw): Consider refactoring common functions and definitions from 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// rsa_private_key_win.cc or using NSS's ASN.1 encoder. 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic bool ReadAttribute(SECKEYPrivateKey* key, 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CK_ATTRIBUTE_TYPE type, 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<uint8>* output) { 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SECItem item; 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SECStatus rv; 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rv = PK11_ReadRawAttribute(PK11_TypePrivKey, key, type, &item); 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (rv != SECSuccess) { 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->assign(item.data, item.data + item.len); 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SECITEM_FreeItem(&item, PR_FALSE); 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace crypto { 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRSAPrivateKey::~RSAPrivateKey() { 4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (key_) 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SECKEY_DestroyPrivateKey(key_); 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (public_key_) 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SECKEY_DestroyPublicKey(public_key_); 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return CreateWithParams(num_bits, 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PR_FALSE /* not permanent */, 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PR_FALSE /* not sensitive */); 563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return CreateWithParams(num_bits, 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PR_TRUE /* permanent */, 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PR_TRUE /* sensitive */); 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::vector<uint8>& input) { 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return CreateFromPrivateKeyInfoWithParams(input, 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PR_FALSE /* not permanent */, 703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PR_FALSE /* not sensitive */); 713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::vector<uint8>& input) { 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return CreateFromPrivateKeyInfoWithParams(input, 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PR_TRUE /* permanent */, 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PR_TRUE /* sensitive */); 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::vector<uint8>& input) { 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EnsureNSSInit(); 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // First, decode and save the public key. 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SECItem key_der; 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key_der.type = siBuffer; 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key_der.data = const_cast<unsigned char*>(&input[0]); 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key_der.len = input.size(); 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CERTSubjectPublicKeyInfo *spki = 953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der); 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!spki) { 973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result->public_key_ = SECKEY_ExtractPublicKey(spki); 1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SECKEY_DestroySubjectPublicKeyInfo(spki); 1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!result->public_key_) { 1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Now, look for the associated private key in the user's 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // hardware-backed NSS DB. If it's not there, consider that an 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // error. 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PK11SlotInfo *slot = GetPrivateNSSKeySlot(); 1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!slot) { 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Make sure the key is an RSA key. If not, that's an error 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (result->public_key_->keyType != rsaKey) { 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PK11_FreeSlot(slot); 1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SECItem *ck_id = PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus)); 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!ck_id) { 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PK11_FreeSlot(slot); 1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Finally...Look for the key! 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result->key_ = PK11_FindKeyByKeyID(slot, ck_id, NULL); 1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Cleanup... 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PK11_FreeSlot(slot); 1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SECITEM_FreeItem(ck_id, PR_TRUE); 1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If we didn't find it, that's ok. 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!result->key_) 1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return result.release(); 1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PrivateKeyInfoCodec private_key_info(true); 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Manually read the component attributes of the private key and build up 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the PrivateKeyInfo. 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ReadAttribute(key_, CKA_MODULUS, private_key_info.modulus()) || 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !ReadAttribute(key_, CKA_PUBLIC_EXPONENT, 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private_key_info.public_exponent()) || 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !ReadAttribute(key_, CKA_PRIVATE_EXPONENT, 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private_key_info.private_exponent()) || 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !ReadAttribute(key_, CKA_PRIME_1, private_key_info.prime1()) || 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !ReadAttribute(key_, CKA_PRIME_2, private_key_info.prime2()) || 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !ReadAttribute(key_, CKA_EXPONENT_1, private_key_info.exponent1()) || 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !ReadAttribute(key_, CKA_EXPONENT_2, private_key_info.exponent2()) || 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !ReadAttribute(key_, CKA_COEFFICIENT, private_key_info.coefficient())) { 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return private_key_info.Export(output); 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SECItem* der_pubkey = SECKEY_EncodeDERSubjectPublicKeyInfo(public_key_); 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!der_pubkey) { 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 0; i < der_pubkey->len; ++i) 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->push_back(der_pubkey->data[i]); 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SECITEM_FreeItem(der_pubkey, PR_TRUE); 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRSAPrivateKey::RSAPrivateKey() : key_(NULL), public_key_(NULL) { 18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EnsureNSSInit(); 18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static 18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRSAPrivateKey* RSAPrivateKey::CreateWithParams(uint16 num_bits, 18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool permanent, 18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool sensitive) { 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EnsureNSSInit(); 19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); 19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PK11SlotInfo *slot = GetPrivateNSSKeySlot(); 19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!slot) 19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return NULL; 19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen PK11RSAGenParams param; 19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen param.keySizeInBits = num_bits; 20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen param.pe = 65537L; 20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result->key_ = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, ¶m, 20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &result->public_key_, permanent, sensitive, NULL); 20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen PK11_FreeSlot(slot); 20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!result->key_) 20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return NULL; 20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result.release(); 20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static 21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams( 21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::vector<uint8>& input, bool permanent, bool sensitive) { 21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // This method currently leaks some memory. 21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // See http://crbug.com/34742. 21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ANNOTATE_SCOPED_MEMORY_LEAK; 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EnsureNSSInit(); 21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); 21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PK11SlotInfo *slot = GetPrivateNSSKeySlot(); 22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!slot) 22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return NULL; 22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SECItem der_private_key_info; 22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen der_private_key_info.data = const_cast<unsigned char*>(&input.front()); 22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen der_private_key_info.len = input.size(); 22772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Allow the private key to be used for key unwrapping, data decryption, 22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // and signature generation. 22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | 23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen KU_DIGITAL_SIGNATURE; 23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( 23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen slot, &der_private_key_info, NULL, NULL, permanent, sensitive, 23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen key_usage, &result->key_, NULL); 23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen PK11_FreeSlot(slot); 23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (rv != SECSuccess) { 23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NOTREACHED(); 23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return NULL; 23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result->public_key_ = SECKEY_ConvertToPublicKey(result->key_); 24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!result->public_key_) { 24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NOTREACHED(); 24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return NULL; 24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result.release(); 24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace crypto 250