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, &param,
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