| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "crypto/ec_private_key.h" | 5 #include "crypto/ec_private_key.h" |
| 6 | 6 |
| 7 extern "C" { | 7 extern "C" { |
| 8 // Work around NSS missing SEC_BEGIN_PROTOS in secmodt.h. This must come before | 8 // Work around NSS missing SEC_BEGIN_PROTOS in secmodt.h. This must come before |
| 9 // other NSS headers. | 9 // other NSS headers. |
| 10 #include <secmodt.h> | 10 #include <secmodt.h> |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 PR_TRUE /* permanent */, | 97 PR_TRUE /* permanent */, |
| 98 PR_TRUE /* sensitive */); | 98 PR_TRUE /* sensitive */); |
| 99 #else | 99 #else |
| 100 // If USE_NSS is not defined, we initialize NSS with no databases, so we can't | 100 // If USE_NSS is not defined, we initialize NSS with no databases, so we can't |
| 101 // create permanent keys. | 101 // create permanent keys. |
| 102 NOTREACHED(); | 102 NOTREACHED(); |
| 103 return NULL; | 103 return NULL; |
| 104 #endif | 104 #endif |
| 105 } | 105 } |
| 106 | 106 |
| 107 // static |
| 108 bool ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( |
| 109 const std::string& password, |
| 110 const std::vector<uint8>& encrypted_private_key_info, |
| 111 CERTSubjectPublicKeyInfo* decoded_spki, |
| 112 bool permanent, |
| 113 bool sensitive, |
| 114 SECKEYPrivateKey** key, |
| 115 SECKEYPublicKey** public_key) { |
| 116 ScopedPK11Slot slot(GetPrivateNSSKeySlot()); |
| 117 if (!slot.get()) |
| 118 return false; |
| 119 |
| 120 *public_key = SECKEY_ExtractPublicKey(decoded_spki); |
| 121 |
| 122 if (!*public_key) { |
| 123 DLOG(ERROR) << "SECKEY_ExtractPublicKey: " << PORT_GetError(); |
| 124 return false; |
| 125 } |
| 126 |
| 127 SECItem encoded_epki = { |
| 128 siBuffer, |
| 129 const_cast<unsigned char*>(&encrypted_private_key_info[0]), |
| 130 encrypted_private_key_info.size() |
| 131 }; |
| 132 SECKEYEncryptedPrivateKeyInfo epki; |
| 133 memset(&epki, 0, sizeof(epki)); |
| 134 |
| 135 ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); |
| 136 |
| 137 SECStatus rv = SEC_QuickDERDecodeItem( |
| 138 arena.get(), |
| 139 &epki, |
| 140 SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate), |
| 141 &encoded_epki); |
| 142 if (rv != SECSuccess) { |
| 143 DLOG(ERROR) << "SEC_QuickDERDecodeItem: " << PORT_GetError(); |
| 144 SECKEY_DestroyPublicKey(*public_key); |
| 145 *public_key = NULL; |
| 146 return false; |
| 147 } |
| 148 |
| 149 SECItem password_item = { |
| 150 siBuffer, |
| 151 reinterpret_cast<unsigned char*>(const_cast<char*>(password.data())), |
| 152 password.size() |
| 153 }; |
| 154 |
| 155 rv = ImportEncryptedECPrivateKeyInfoAndReturnKey( |
| 156 slot.get(), |
| 157 &epki, |
| 158 &password_item, |
| 159 NULL, // nickname |
| 160 &(*public_key)->u.ec.publicValue, |
| 161 permanent, |
| 162 sensitive, |
| 163 key, |
| 164 NULL); // wincx |
| 165 if (rv != SECSuccess) { |
| 166 DLOG(ERROR) << "ImportEncryptedECPrivateKeyInfoAndReturnKey: " |
| 167 << PORT_GetError(); |
| 168 SECKEY_DestroyPublicKey(*public_key); |
| 169 *public_key = NULL; |
| 170 return false; |
| 171 } |
| 172 |
| 173 return true; |
| 174 } |
| 175 |
| 107 bool ECPrivateKey::ExportEncryptedPrivateKey( | 176 bool ECPrivateKey::ExportEncryptedPrivateKey( |
| 108 const std::string& password, | 177 const std::string& password, |
| 109 int iterations, | 178 int iterations, |
| 110 std::vector<uint8>* output) { | 179 std::vector<uint8>* output) { |
| 111 // We export as an EncryptedPrivateKeyInfo bundle instead of a plain PKCS #8 | 180 // We export as an EncryptedPrivateKeyInfo bundle instead of a plain PKCS #8 |
| 112 // PrivateKeyInfo because PK11_ImportDERPrivateKeyInfoAndReturnKey doesn't | 181 // PrivateKeyInfo because PK11_ImportDERPrivateKeyInfoAndReturnKey doesn't |
| 113 // support EC keys. | 182 // support EC keys. |
| 114 // https://bugzilla.mozilla.org/show_bug.cgi?id=327773 | 183 // https://bugzilla.mozilla.org/show_bug.cgi?id=327773 |
| 115 SECItem password_item = { | 184 SECItem password_item = { |
| 116 siBuffer, | 185 siBuffer, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfoWithParams( | 289 ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfoWithParams( |
| 221 const std::string& password, | 290 const std::string& password, |
| 222 const std::vector<uint8>& encrypted_private_key_info, | 291 const std::vector<uint8>& encrypted_private_key_info, |
| 223 const std::vector<uint8>& subject_public_key_info, | 292 const std::vector<uint8>& subject_public_key_info, |
| 224 bool permanent, | 293 bool permanent, |
| 225 bool sensitive) { | 294 bool sensitive) { |
| 226 EnsureNSSInit(); | 295 EnsureNSSInit(); |
| 227 | 296 |
| 228 scoped_ptr<ECPrivateKey> result(new ECPrivateKey); | 297 scoped_ptr<ECPrivateKey> result(new ECPrivateKey); |
| 229 | 298 |
| 230 ScopedPK11Slot slot(GetPrivateNSSKeySlot()); | |
| 231 if (!slot.get()) | |
| 232 return NULL; | |
| 233 | |
| 234 SECItem encoded_spki = { | 299 SECItem encoded_spki = { |
| 235 siBuffer, | 300 siBuffer, |
| 236 const_cast<unsigned char*>(&subject_public_key_info[0]), | 301 const_cast<unsigned char*>(&subject_public_key_info[0]), |
| 237 subject_public_key_info.size() | 302 subject_public_key_info.size() |
| 238 }; | 303 }; |
| 239 CERTSubjectPublicKeyInfo* decoded_spki = SECKEY_DecodeDERSubjectPublicKeyInfo( | 304 CERTSubjectPublicKeyInfo* decoded_spki = SECKEY_DecodeDERSubjectPublicKeyInfo( |
| 240 &encoded_spki); | 305 &encoded_spki); |
| 241 if (!decoded_spki) { | 306 if (!decoded_spki) { |
| 242 DLOG(ERROR) << "SECKEY_DecodeDERSubjectPublicKeyInfo: " << PORT_GetError(); | 307 DLOG(ERROR) << "SECKEY_DecodeDERSubjectPublicKeyInfo: " << PORT_GetError(); |
| 243 return NULL; | 308 return NULL; |
| 244 } | 309 } |
| 245 | 310 |
| 246 result->public_key_ = SECKEY_ExtractPublicKey(decoded_spki); | 311 bool success = ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( |
| 312 password, encrypted_private_key_info, decoded_spki, permanent, sensitive, |
| 313 &result->key_, &result->public_key_); |
| 247 | 314 |
| 248 SECKEY_DestroySubjectPublicKeyInfo(decoded_spki); | 315 SECKEY_DestroySubjectPublicKeyInfo(decoded_spki); |
| 249 | 316 |
| 250 if (!result->public_key_) { | 317 if (success) |
| 251 DLOG(ERROR) << "SECKEY_ExtractPublicKey: " << PORT_GetError(); | 318 return result.release(); |
| 252 return NULL; | |
| 253 } | |
| 254 | 319 |
| 255 SECItem encoded_epki = { | 320 return NULL; |
| 256 siBuffer, | |
| 257 const_cast<unsigned char*>(&encrypted_private_key_info[0]), | |
| 258 encrypted_private_key_info.size() | |
| 259 }; | |
| 260 SECKEYEncryptedPrivateKeyInfo epki; | |
| 261 memset(&epki, 0, sizeof(epki)); | |
| 262 | |
| 263 ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); | |
| 264 | |
| 265 SECStatus rv = SEC_QuickDERDecodeItem( | |
| 266 arena.get(), | |
| 267 &epki, | |
| 268 SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate), | |
| 269 &encoded_epki); | |
| 270 if (rv != SECSuccess) { | |
| 271 DLOG(ERROR) << "SEC_ASN1DecodeItem: " << PORT_GetError(); | |
| 272 return NULL; | |
| 273 } | |
| 274 | |
| 275 SECItem password_item = { | |
| 276 siBuffer, | |
| 277 reinterpret_cast<unsigned char*>(const_cast<char*>(password.data())), | |
| 278 password.size() | |
| 279 }; | |
| 280 | |
| 281 rv = ImportEncryptedECPrivateKeyInfoAndReturnKey( | |
| 282 slot.get(), | |
| 283 &epki, | |
| 284 &password_item, | |
| 285 NULL, // nickname | |
| 286 &result->public_key_->u.ec.publicValue, | |
| 287 permanent, | |
| 288 sensitive, | |
| 289 &result->key_, | |
| 290 NULL); // wincx | |
| 291 if (rv != SECSuccess) { | |
| 292 DLOG(ERROR) << "ImportEncryptedECPrivateKeyInfoAndReturnKey: " | |
| 293 << PORT_GetError(); | |
| 294 return NULL; | |
| 295 } | |
| 296 | |
| 297 return result.release(); | |
| 298 } | 321 } |
| 299 | 322 |
| 300 } // namespace crypto | 323 } // namespace crypto |
| OLD | NEW |