Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Side by Side Diff: crypto/ec_private_key_openssl.cc

Issue 435593003: Align OpenSSL and NSS ChannelID formats. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | crypto/ec_private_key_unittest.cc » ('j') | crypto/ec_private_key_unittest.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include <openssl/ec.h> 7 #include <openssl/ec.h>
8 #include <openssl/evp.h> 8 #include <openssl/evp.h>
9 #include <openssl/pkcs12.h> 9 #include <openssl/pkcs12.h>
10 #include <openssl/x509.h> 10 #include <openssl/x509.h>
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 const std::string& password, 110 const std::string& password,
111 const std::vector<uint8>& encrypted_private_key_info, 111 const std::vector<uint8>& encrypted_private_key_info,
112 const std::vector<uint8>& subject_public_key_info) { 112 const std::vector<uint8>& subject_public_key_info) {
113 // NOTE: The |subject_public_key_info| can be ignored here, it is only 113 // NOTE: The |subject_public_key_info| can be ignored here, it is only
114 // useful for the NSS implementation (which uses the public key's SHA1 114 // useful for the NSS implementation (which uses the public key's SHA1
115 // as a lookup key when storing the private one in its store). 115 // as a lookup key when storing the private one in its store).
116 if (encrypted_private_key_info.empty()) 116 if (encrypted_private_key_info.empty())
117 return NULL; 117 return NULL;
118 118
119 OpenSSLErrStackTracer err_tracer(FROM_HERE); 119 OpenSSLErrStackTracer err_tracer(FROM_HERE);
120 // Write the encrypted private key into a memory BIO. 120
121 char* private_key_data = reinterpret_cast<char*>( 121 const uint8_t* data = &encrypted_private_key_info[0];
122 const_cast<uint8*>(&encrypted_private_key_info[0])); 122 const uint8_t* ptr = data;
123 int private_key_data_len = 123 ScopedX509_SIG p8_encrypted(
124 static_cast<int>(encrypted_private_key_info.size()); 124 d2i_X509_SIG(NULL, &ptr, encrypted_private_key_info.size()));
125 ScopedBIO bio(BIO_new_mem_buf(private_key_data, private_key_data_len)); 125 if (!p8_encrypted || ptr != data + encrypted_private_key_info.size())
126 if (!bio.get())
127 return NULL; 126 return NULL;
128 127
129 // Convert it, then decrypt it into a PKCS#8 object. 128 ScopedPKCS8_PRIV_KEY_INFO p8_decrypted;
130 ScopedX509_SIG p8_encrypted(d2i_PKCS8_bio(bio.get(), NULL)); 129 if (password.empty()) {
131 if (!p8_encrypted.get()) 130 // Hack for reading keys generated by an older version of the OpenSSL
132 return NULL; 131 // code. OpenSSL used to use "\0\0" rather than the empty string because it
132 // would treat the password as an ASCII string to be converted to UCS-2
133 // while NSS used a byte string.
134 p8_decrypted.reset(PKCS8_decrypt_pbe(
135 p8_encrypted.get(), reinterpret_cast<const uint8_t*>("\0\0"), 2));
136 }
137 if (!p8_decrypted) {
138 p8_decrypted.reset(PKCS8_decrypt_pbe(
139 p8_encrypted.get(),
140 reinterpret_cast<const uint8_t*>(password.data()),
141 password.size()));
142 }
133 143
134 ScopedPKCS8_PRIV_KEY_INFO p8_decrypted(PKCS8_decrypt( 144 if (!p8_decrypted)
135 p8_encrypted.get(), password.c_str(), static_cast<int>(password.size())));
136 if (!p8_decrypted.get() && password.empty()) {
137 // Hack for reading keys generated by ec_private_key_nss. Passing NULL
138 // causes OpenSSL to use an empty password instead of "\0\0".
139 p8_decrypted.reset(PKCS8_decrypt(p8_encrypted.get(), NULL, 0));
140 }
141 if (!p8_decrypted.get())
142 return NULL; 145 return NULL;
143 146
144 // Create a new EVP_PKEY for it. 147 // Create a new EVP_PKEY for it.
145 scoped_ptr<ECPrivateKey> result(new ECPrivateKey); 148 scoped_ptr<ECPrivateKey> result(new ECPrivateKey);
146 result->key_ = EVP_PKCS82PKEY(p8_decrypted.get()); 149 result->key_ = EVP_PKCS82PKEY(p8_decrypted.get());
147 if (!result->key_ || EVP_PKEY_type(result->key_->type) != EVP_PKEY_EC) 150 if (!result->key_ || EVP_PKEY_type(result->key_->type) != EVP_PKEY_EC)
148 return NULL; 151 return NULL;
149 152
150 return result.release(); 153 return result.release();
151 } 154 }
152 155
153 bool ECPrivateKey::ExportEncryptedPrivateKey( 156 bool ECPrivateKey::ExportEncryptedPrivateKey(
154 const std::string& password, 157 const std::string& password,
155 int iterations, 158 int iterations,
156 std::vector<uint8>* output) { 159 std::vector<uint8>* output) {
157 OpenSSLErrStackTracer err_tracer(FROM_HERE); 160 OpenSSLErrStackTracer err_tracer(FROM_HERE);
158 // Convert into a PKCS#8 object. 161 // Convert into a PKCS#8 object.
159 ScopedPKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(key_)); 162 ScopedPKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(key_));
160 if (!pkcs8.get()) 163 if (!pkcs8.get())
161 return false; 164 return false;
162 165
163 // Encrypt the object. 166 // Encrypt the object.
164 // NOTE: NSS uses SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC 167 // NOTE: NSS uses SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
165 // so use NID_pbe_WithSHA1And3_Key_TripleDES_CBC which should be the OpenSSL 168 // so use NID_pbe_WithSHA1And3_Key_TripleDES_CBC which should be the OpenSSL
166 // equivalent. 169 // equivalent.
167 ScopedX509_SIG encrypted(PKCS8_encrypt(NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 170 std::string password_copy = password;
168 NULL, 171 #if defined(OS_ANDROID)
169 password.c_str(), 172 // On Android, Channel IDs have historically been encrypted with "\0\0"
170 static_cast<int>(password.size()), 173 // because of a difference in OpenSSL and NSS behavior.
171 NULL, 174 if (password_copy.empty())
172 0, 175 password_copy.assign(2, '\0');
173 iterations, 176 #endif
Ryan Sleevi 2014/08/06 02:24:48 I'm not sure I understand this bit. That is, why d
davidben 2014/08/06 18:34:35 It was more about jumping back and forth across ht
174 pkcs8.get())); 177 ScopedX509_SIG encrypted(PKCS8_encrypt_pbe(
178 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
Ryan Sleevi 2014/08/06 02:24:48 Document why this constant is what it is.
davidben 2014/08/06 18:34:35 Isn't it documented up in "Encrypt the object"?
Ryan Sleevi 2014/08/06 21:02:19 Oh, I'm blind because of the ifdef. Ignore :)
179 reinterpret_cast<const uint8_t*>(password_copy.data()),
180 password_copy.size(),
181 NULL,
182 0,
183 iterations,
184 pkcs8.get()));
175 if (!encrypted.get()) 185 if (!encrypted.get())
176 return false; 186 return false;
177 187
178 // Write it into |*output| 188 // Write it into |*output|
179 return ExportKeyWithBio(encrypted.get(), 189 return ExportKeyWithBio(encrypted.get(),
180 reinterpret_cast<ExportBioFunction>(i2d_PKCS8_bio), 190 reinterpret_cast<ExportBioFunction>(i2d_PKCS8_bio),
181 output); 191 output);
182 } 192 }
183 193
184 bool ECPrivateKey::ExportPublicKey(std::vector<uint8>* output) { 194 bool ECPrivateKey::ExportPublicKey(std::vector<uint8>* output) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 OpenSSLErrStackTracer err_tracer(FROM_HERE); 229 OpenSSLErrStackTracer err_tracer(FROM_HERE);
220 ScopedEC_KEY ec_key(EVP_PKEY_get1_EC_KEY(key_)); 230 ScopedEC_KEY ec_key(EVP_PKEY_get1_EC_KEY(key_));
221 return ExportKey(ec_key.get(), 231 return ExportKey(ec_key.get(),
222 reinterpret_cast<ExportDataFunction>(i2d_ECParameters), 232 reinterpret_cast<ExportDataFunction>(i2d_ECParameters),
223 output); 233 output);
224 } 234 }
225 235
226 ECPrivateKey::ECPrivateKey() : key_(NULL) {} 236 ECPrivateKey::ECPrivateKey() : key_(NULL) {}
227 237
228 } // namespace crypto 238 } // namespace crypto
OLDNEW
« no previous file with comments | « no previous file | crypto/ec_private_key_unittest.cc » ('j') | crypto/ec_private_key_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698