1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "crypto/rsa_private_key.h" 6 7 #include <cryptohi.h> 8 #include <keyhi.h> 9 #include <pk11pub.h> 10 #include <secmod.h> 11 12 #include <list> 13 14 #include "base/debug/leak_annotations.h" 15 #include "base/logging.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/strings/string_util.h" 18 #include "crypto/nss_util.h" 19 #include "crypto/nss_util_internal.h" 20 #include "crypto/scoped_nss_types.h" 21 22 // TODO(rafaelw): Consider using NSS's ASN.1 encoder. 23 namespace { 24 25 static bool ReadAttribute(SECKEYPrivateKey* key, 26 CK_ATTRIBUTE_TYPE type, 27 std::vector<uint8>* output) { 28 SECItem item; 29 SECStatus rv; 30 rv = PK11_ReadRawAttribute(PK11_TypePrivKey, key, type, &item); 31 if (rv != SECSuccess) { 32 NOTREACHED(); 33 return false; 34 } 35 36 output->assign(item.data, item.data + item.len); 37 SECITEM_FreeItem(&item, PR_FALSE); 38 return true; 39 } 40 41 #if defined(USE_NSS) 42 struct PublicKeyInfoDeleter { 43 inline void operator()(CERTSubjectPublicKeyInfo* spki) { 44 SECKEY_DestroySubjectPublicKeyInfo(spki); 45 } 46 }; 47 48 typedef scoped_ptr<CERTSubjectPublicKeyInfo, PublicKeyInfoDeleter> 49 ScopedPublicKeyInfo; 50 51 // The function decodes RSA public key from the |input|. 52 crypto::ScopedSECKEYPublicKey GetRSAPublicKey(const std::vector<uint8>& input) { 53 // First, decode and save the public key. 54 SECItem key_der; 55 key_der.type = siBuffer; 56 key_der.data = const_cast<unsigned char*>(&input[0]); 57 key_der.len = input.size(); 58 59 ScopedPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der)); 60 if (!spki) 61 return crypto::ScopedSECKEYPublicKey(); 62 63 crypto::ScopedSECKEYPublicKey result(SECKEY_ExtractPublicKey(spki.get())); 64 65 // Make sure the key is an RSA key.. If not, that's an error. 66 if (!result || result->keyType != rsaKey) 67 return crypto::ScopedSECKEYPublicKey(); 68 return result.Pass(); 69 } 70 #endif // defined(USE_NSS) 71 72 } // namespace 73 74 namespace crypto { 75 76 RSAPrivateKey::~RSAPrivateKey() { 77 if (key_) 78 SECKEY_DestroyPrivateKey(key_); 79 if (public_key_) 80 SECKEY_DestroyPublicKey(public_key_); 81 } 82 83 // static 84 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { 85 EnsureNSSInit(); 86 87 ScopedPK11Slot slot(PK11_GetInternalSlot()); 88 return CreateWithParams(slot.get(), 89 num_bits, 90 false /* not permanent */, 91 false /* not sensitive */); 92 } 93 94 // static 95 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( 96 const std::vector<uint8>& input) { 97 EnsureNSSInit(); 98 99 ScopedPK11Slot slot(PK11_GetInternalSlot()); 100 return CreateFromPrivateKeyInfoWithParams( 101 slot.get(), 102 input, 103 false /* not permanent */, 104 false /* not sensitive */); 105 } 106 107 #if defined(USE_NSS) 108 // static 109 RSAPrivateKey* RSAPrivateKey::CreateSensitive(PK11SlotInfo* slot, 110 uint16 num_bits) { 111 return CreateWithParams(slot, 112 num_bits, 113 true /* permanent */, 114 true /* sensitive */); 115 } 116 117 // static 118 RSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( 119 PK11SlotInfo* slot, 120 const std::vector<uint8>& input) { 121 return CreateFromPrivateKeyInfoWithParams(slot, 122 input, 123 true /* permanent */, 124 true /* sensitive */); 125 } 126 127 // static 128 RSAPrivateKey* RSAPrivateKey::CreateFromKey(SECKEYPrivateKey* key) { 129 DCHECK(key); 130 if (SECKEY_GetPrivateKeyType(key) != rsaKey) 131 return NULL; 132 RSAPrivateKey* copy = new RSAPrivateKey(); 133 copy->key_ = SECKEY_CopyPrivateKey(key); 134 copy->public_key_ = SECKEY_ConvertToPublicKey(key); 135 if (!copy->key_ || !copy->public_key_) { 136 NOTREACHED(); 137 delete copy; 138 return NULL; 139 } 140 return copy; 141 } 142 143 // static 144 RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( 145 const std::vector<uint8>& input) { 146 scoped_ptr<RSAPrivateKey> result(InitPublicPart(input)); 147 if (!result) 148 return NULL; 149 150 ScopedSECItem ck_id( 151 PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus))); 152 if (!ck_id.get()) { 153 NOTREACHED(); 154 return NULL; 155 } 156 157 // Search all slots in all modules for the key with the given ID. 158 AutoSECMODListReadLock auto_lock; 159 SECMODModuleList* head = SECMOD_GetDefaultModuleList(); 160 for (SECMODModuleList* item = head; item != NULL; item = item->next) { 161 int slot_count = item->module->loaded ? item->module->slotCount : 0; 162 for (int i = 0; i < slot_count; i++) { 163 // Finally...Look for the key! 164 result->key_ = PK11_FindKeyByKeyID(item->module->slots[i], 165 ck_id.get(), NULL); 166 if (result->key_) 167 return result.release(); 168 } 169 } 170 171 // We didn't find the key. 172 return NULL; 173 } 174 175 // static 176 RSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfoInSlot( 177 const std::vector<uint8>& input, 178 PK11SlotInfo* slot) { 179 if (!slot) 180 return NULL; 181 182 scoped_ptr<RSAPrivateKey> result(InitPublicPart(input)); 183 if (!result) 184 return NULL; 185 186 ScopedSECItem ck_id( 187 PK11_MakeIDFromPubKey(&(result->public_key_->u.rsa.modulus))); 188 if (!ck_id.get()) { 189 NOTREACHED(); 190 return NULL; 191 } 192 193 result->key_ = PK11_FindKeyByKeyID(slot, ck_id.get(), NULL); 194 if (!result->key_) 195 return NULL; 196 return result.release(); 197 } 198 #endif 199 200 RSAPrivateKey* RSAPrivateKey::Copy() const { 201 RSAPrivateKey* copy = new RSAPrivateKey(); 202 copy->key_ = SECKEY_CopyPrivateKey(key_); 203 copy->public_key_ = SECKEY_CopyPublicKey(public_key_); 204 return copy; 205 } 206 207 bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) const { 208 PrivateKeyInfoCodec private_key_info(true); 209 210 // Manually read the component attributes of the private key and build up 211 // the PrivateKeyInfo. 212 if (!ReadAttribute(key_, CKA_MODULUS, private_key_info.modulus()) || 213 !ReadAttribute(key_, CKA_PUBLIC_EXPONENT, 214 private_key_info.public_exponent()) || 215 !ReadAttribute(key_, CKA_PRIVATE_EXPONENT, 216 private_key_info.private_exponent()) || 217 !ReadAttribute(key_, CKA_PRIME_1, private_key_info.prime1()) || 218 !ReadAttribute(key_, CKA_PRIME_2, private_key_info.prime2()) || 219 !ReadAttribute(key_, CKA_EXPONENT_1, private_key_info.exponent1()) || 220 !ReadAttribute(key_, CKA_EXPONENT_2, private_key_info.exponent2()) || 221 !ReadAttribute(key_, CKA_COEFFICIENT, private_key_info.coefficient())) { 222 NOTREACHED(); 223 return false; 224 } 225 226 return private_key_info.Export(output); 227 } 228 229 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) const { 230 ScopedSECItem der_pubkey(SECKEY_EncodeDERSubjectPublicKeyInfo(public_key_)); 231 if (!der_pubkey.get()) { 232 NOTREACHED(); 233 return false; 234 } 235 236 output->assign(der_pubkey->data, der_pubkey->data + der_pubkey->len); 237 return true; 238 } 239 240 RSAPrivateKey::RSAPrivateKey() : key_(NULL), public_key_(NULL) { 241 EnsureNSSInit(); 242 } 243 244 // static 245 RSAPrivateKey* RSAPrivateKey::CreateWithParams(PK11SlotInfo* slot, 246 uint16 num_bits, 247 bool permanent, 248 bool sensitive) { 249 if (!slot) 250 return NULL; 251 252 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); 253 254 PK11RSAGenParams param; 255 param.keySizeInBits = num_bits; 256 param.pe = 65537L; 257 result->key_ = PK11_GenerateKeyPair(slot, 258 CKM_RSA_PKCS_KEY_PAIR_GEN, 259 ¶m, 260 &result->public_key_, 261 permanent, 262 sensitive, 263 NULL); 264 if (!result->key_) 265 return NULL; 266 267 return result.release(); 268 } 269 270 // static 271 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfoWithParams( 272 PK11SlotInfo* slot, 273 const std::vector<uint8>& input, 274 bool permanent, 275 bool sensitive) { 276 if (!slot) 277 return NULL; 278 279 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); 280 281 SECItem der_private_key_info; 282 der_private_key_info.data = const_cast<unsigned char*>(&input.front()); 283 der_private_key_info.len = input.size(); 284 // Allow the private key to be used for key unwrapping, data decryption, 285 // and signature generation. 286 const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | 287 KU_DIGITAL_SIGNATURE; 288 SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( 289 slot, &der_private_key_info, NULL, NULL, permanent, sensitive, 290 key_usage, &result->key_, NULL); 291 if (rv != SECSuccess) { 292 NOTREACHED(); 293 return NULL; 294 } 295 296 result->public_key_ = SECKEY_ConvertToPublicKey(result->key_); 297 if (!result->public_key_) { 298 NOTREACHED(); 299 return NULL; 300 } 301 302 return result.release(); 303 } 304 305 #if defined(USE_NSS) 306 // static 307 RSAPrivateKey* RSAPrivateKey::InitPublicPart(const std::vector<uint8>& input) { 308 EnsureNSSInit(); 309 310 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey()); 311 result->public_key_ = GetRSAPublicKey(input).release(); 312 if (!result->public_key_) { 313 NOTREACHED(); 314 return NULL; 315 } 316 317 return result.release(); 318 } 319 #endif // defined(USE_NSS) 320 321 } // namespace crypto 322