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

Side by Side Diff: net/android/keystore_openssl.cc

Issue 365503007: Insulate the legacy Android client auth code from OpenSSL ABI changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: yfriedman comments Created 6 years, 5 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "net/android/keystore_openssl.h" 5 #include "net/android/keystore_openssl.h"
6 6
7 #include <jni.h> 7 #include <jni.h>
8 #include <openssl/bn.h> 8 #include <openssl/bn.h>
9 // This include is required to get the ECDSA_METHOD structure definition 9 // This include is required to get the ECDSA_METHOD structure definition
10 // which isn't currently part of the OpenSSL official ABI. This should 10 // which isn't currently part of the OpenSSL official ABI. This should
11 // not be a concern for Chromium which always links against its own 11 // not be a concern for Chromium which always links against its own
12 // version of the library on Android. 12 // version of the library on Android.
13 #include <openssl/crypto/ecdsa/ecs_locl.h> 13 #include <openssl/crypto/ecdsa/ecs_locl.h>
14 // And this one is needed for the EC_GROUP definition. 14 // And this one is needed for the EC_GROUP definition.
15 #include <openssl/crypto/ec/ec_lcl.h> 15 #include <openssl/crypto/ec/ec_lcl.h>
16 #include <openssl/dsa.h> 16 #include <openssl/dsa.h>
17 #include <openssl/ec.h> 17 #include <openssl/ec.h>
18 #include <openssl/engine.h> 18 #include <openssl/engine.h>
19 #include <openssl/evp.h> 19 #include <openssl/evp.h>
20 #include <openssl/rsa.h> 20 #include <openssl/rsa.h>
21 21
22 #include "base/android/build_info.h" 22 #include "base/android/build_info.h"
23 #include "base/android/jni_android.h" 23 #include "base/android/jni_android.h"
24 #include "base/android/scoped_java_ref.h" 24 #include "base/android/scoped_java_ref.h"
25 #include "base/basictypes.h" 25 #include "base/basictypes.h"
26 #include "base/lazy_instance.h" 26 #include "base/lazy_instance.h"
27 #include "base/logging.h" 27 #include "base/logging.h"
28 #include "crypto/openssl_util.h" 28 #include "crypto/openssl_util.h"
29 #include "net/android/keystore.h" 29 #include "net/android/keystore.h"
30 #include "net/android/legacy_openssl.h"
30 #include "net/ssl/ssl_client_cert_type.h" 31 #include "net/ssl/ssl_client_cert_type.h"
31 32
32 // IMPORTANT NOTE: The following code will currently only work when used 33 // IMPORTANT NOTE: The following code will currently only work when used
33 // to implement client certificate support with OpenSSL. That's because 34 // to implement client certificate support with OpenSSL. That's because
34 // only the signing operations used in this use case are implemented here. 35 // only the signing operations used in this use case are implemented here.
35 // 36 //
36 // Generally speaking, OpenSSL provides many different ways to sign 37 // Generally speaking, OpenSSL provides many different ways to sign
37 // digests. This code doesn't support all these cases, only the ones that 38 // digests. This code doesn't support all these cases, only the ones that
38 // are required to sign the digest during the OpenSSL handshake for TLS. 39 // are required to sign the digest during the OpenSSL handshake for TLS.
39 // 40 //
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // DSA_size() and ECDSA_size() work properly with the wrapper EVP_PKEY. 89 // DSA_size() and ECDSA_size() work properly with the wrapper EVP_PKEY.
89 // 90 //
90 // Note that there is no need to define an OpenSSL ENGINE here. These 91 // Note that there is no need to define an OpenSSL ENGINE here. These
91 // are objects that can be used to expose custom methods (i.e. either 92 // are objects that can be used to expose custom methods (i.e. either
92 // RSA_METHOD, DSA_METHOD, ECDSA_METHOD, and a large number of other ones 93 // RSA_METHOD, DSA_METHOD, ECDSA_METHOD, and a large number of other ones
93 // for types not related to this source file), and make them used by 94 // for types not related to this source file), and make them used by
94 // default for a lot of operations. Very fortunately, this is not needed 95 // default for a lot of operations. Very fortunately, this is not needed
95 // here, which saves a lot of complexity. 96 // here, which saves a lot of complexity.
96 97
97 using base::android::ScopedJavaGlobalRef; 98 using base::android::ScopedJavaGlobalRef;
99 using base::android::ScopedJavaLocalRef;
98 100
99 namespace net { 101 namespace net {
100 namespace android { 102 namespace android {
101 103
102 namespace { 104 namespace {
103 105
104 typedef crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> ScopedEVP_PKEY; 106 typedef crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> ScopedEVP_PKEY;
105 typedef crypto::ScopedOpenSSL<RSA, RSA_free> ScopedRSA; 107 typedef crypto::ScopedOpenSSL<RSA, RSA_free> ScopedRSA;
106 typedef crypto::ScopedOpenSSL<DSA, DSA_free> ScopedDSA; 108 typedef crypto::ScopedOpenSSL<DSA, DSA_free> ScopedDSA;
107 typedef crypto::ScopedOpenSSL<EC_KEY, EC_KEY_free> ScopedEC_KEY; 109 typedef crypto::ScopedOpenSSL<EC_KEY, EC_KEY_free> ScopedEC_KEY;
108 typedef crypto::ScopedOpenSSL<EC_GROUP, EC_GROUP_free> ScopedEC_GROUP; 110 typedef crypto::ScopedOpenSSL<EC_GROUP, EC_GROUP_free> ScopedEC_GROUP;
109 111
110 // Custom RSA_METHOD that uses the platform APIs. 112 // Custom RSA_METHOD that uses the platform APIs.
111 // Note that for now, only signing through RSA_sign() is really supported. 113 // Note that for now, only signing through RSA_sign() is really supported.
112 // all other method pointers are either stubs returning errors, or no-ops. 114 // all other method pointers are either stubs returning errors, or no-ops.
113 // See <openssl/rsa.h> for exact declaration of RSA_METHOD. 115 // See <openssl/rsa.h> for exact declaration of RSA_METHOD.
114 116
117 struct RsaAppData {
118 jobject private_key;
119 AndroidRSA* legacy_rsa;
120 };
121
115 int RsaMethodPubEnc(int flen, 122 int RsaMethodPubEnc(int flen,
116 const unsigned char* from, 123 const unsigned char* from,
117 unsigned char* to, 124 unsigned char* to,
118 RSA* rsa, 125 RSA* rsa,
119 int padding) { 126 int padding) {
120 NOTIMPLEMENTED(); 127 NOTIMPLEMENTED();
121 RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); 128 RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
122 return -1; 129 return -1;
123 } 130 }
124 131
(...skipping 22 matching lines...) Expand all
147 // "RSA/ECB/NoPadding" or "RSA/ECB/PKCS1Padding" transformation as 154 // "RSA/ECB/NoPadding" or "RSA/ECB/PKCS1Padding" transformation as
148 // appropriate. I believe support for both of these was added in 155 // appropriate. I believe support for both of these was added in
149 // the same Android version as the "NONEwithRSA" 156 // the same Android version as the "NONEwithRSA"
150 // java.security.Signature algorithm, so the same version checks 157 // java.security.Signature algorithm, so the same version checks
151 // for GetRsaLegacyKey should work. 158 // for GetRsaLegacyKey should work.
152 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); 159 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
153 return -1; 160 return -1;
154 } 161 }
155 162
156 // Retrieve private key JNI reference. 163 // Retrieve private key JNI reference.
157 jobject private_key = reinterpret_cast<jobject>(RSA_get_app_data(rsa)); 164 RsaAppData* app_data = static_cast<RsaAppData*>(RSA_get_app_data(rsa));
158 if (!private_key) { 165 if (!app_data || !app_data->private_key) {
159 LOG(WARNING) << "Null JNI reference passed to RsaMethodPrivEnc!"; 166 LOG(WARNING) << "Null JNI reference passed to RsaMethodPrivEnc!";
160 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); 167 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
161 return -1; 168 return -1;
162 } 169 }
163 170
171 // Pre-4.2 legacy codepath.
172 if (app_data->legacy_rsa) {
173 int ret = app_data->legacy_rsa->meth->rsa_priv_enc(
174 flen, from, to, app_data->legacy_rsa, ANDROID_RSA_PKCS1_PADDING);
175 if (ret < 0) {
176 LOG(WARNING) << "Could not sign message in RsaMethodPrivEnc!";
177 // System OpenSSL will use a separate error queue, so it is still
178 // necessary to push a new error.
179 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
agl 2014/07/10 16:33:44 Do we need to clear the system's error queue?
davidben 2014/07/10 21:47:07 Added a TODO, but doing so seems to be difficult.
180 return -1;
181 }
182 return ret;
183 }
184
164 base::StringPiece from_piece(reinterpret_cast<const char*>(from), flen); 185 base::StringPiece from_piece(reinterpret_cast<const char*>(from), flen);
165 std::vector<uint8> result; 186 std::vector<uint8> result;
166 // For RSA keys, this function behaves as RSA_private_encrypt with 187 // For RSA keys, this function behaves as RSA_private_encrypt with
167 // PKCS#1 padding. 188 // PKCS#1 padding.
168 if (!RawSignDigestWithPrivateKey(private_key, from_piece, &result)) { 189 if (!RawSignDigestWithPrivateKey(app_data->private_key,
190 from_piece, &result)) {
169 LOG(WARNING) << "Could not sign message in RsaMethodPrivEnc!"; 191 LOG(WARNING) << "Could not sign message in RsaMethodPrivEnc!";
170 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); 192 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
171 return -1; 193 return -1;
172 } 194 }
173 195
174 size_t expected_size = static_cast<size_t>(RSA_size(rsa)); 196 size_t expected_size = static_cast<size_t>(RSA_size(rsa));
175 if (result.size() > expected_size) { 197 if (result.size() > expected_size) {
176 LOG(ERROR) << "RSA Signature size mismatch, actual: " 198 LOG(ERROR) << "RSA Signature size mismatch, actual: "
177 << result.size() << ", expected <= " << expected_size; 199 << result.size() << ", expected <= " << expected_size;
178 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); 200 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
(...skipping 19 matching lines...) Expand all
198 return -1; 220 return -1;
199 } 221 }
200 222
201 int RsaMethodInit(RSA* rsa) { 223 int RsaMethodInit(RSA* rsa) {
202 return 0; 224 return 0;
203 } 225 }
204 226
205 int RsaMethodFinish(RSA* rsa) { 227 int RsaMethodFinish(RSA* rsa) {
206 // Ensure the global JNI reference created with this wrapper is 228 // Ensure the global JNI reference created with this wrapper is
207 // properly destroyed with it. 229 // properly destroyed with it.
208 jobject key = reinterpret_cast<jobject>(RSA_get_app_data(rsa)); 230 RsaAppData* app_data = static_cast<RsaAppData*>(RSA_get_app_data(rsa));
209 if (key != NULL) { 231 if (app_data != NULL) {
210 RSA_set_app_data(rsa, NULL); 232 RSA_set_app_data(rsa, NULL);
211 ReleaseKey(key); 233 ReleaseKey(app_data->private_key);
234 delete app_data;
212 } 235 }
213 // Actual return value is ignored by OpenSSL. There are no docs 236 // Actual return value is ignored by OpenSSL. There are no docs
214 // explaining what this is supposed to be. 237 // explaining what this is supposed to be.
215 return 0; 238 return 0;
216 } 239 }
217 240
218 const RSA_METHOD android_rsa_method = { 241 const RSA_METHOD android_rsa_method = {
219 /* .name = */ "Android signing-only RSA method", 242 /* .name = */ "Android signing-only RSA method",
220 /* .rsa_pub_enc = */ RsaMethodPubEnc, 243 /* .rsa_pub_enc = */ RsaMethodPubEnc,
221 /* .rsa_pub_dec = */ RsaMethodPubDec, 244 /* .rsa_pub_dec = */ RsaMethodPubDec,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 old_num); 290 old_num);
268 if (new_num == NULL) 291 if (new_num == NULL)
269 return false; 292 return false;
270 293
271 if (old_num == NULL) 294 if (old_num == NULL)
272 *num_ptr = new_num; 295 *num_ptr = new_num;
273 return true; 296 return true;
274 } 297 }
275 298
276 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object. 299 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object.
277 // |private_key| is the JNI reference (local or global) to the object. 300 // |private_key| is the JNI reference (local or global) to the object.
agl 2014/07/10 16:33:44 Probably needs to mention |legacy_rsa|.
davidben 2014/07/10 21:47:07 Done.
278 // |pkey| is the EVP_PKEY to setup as a wrapper. 301 // |pkey| is the EVP_PKEY to setup as a wrapper.
279 // Returns true on success, false otherwise. 302 // Returns true on success, false otherwise.
280 // On success, this creates a new global JNI reference to the object 303 // On success, this creates a new global JNI reference to the object
281 // that is owned by and destroyed with the EVP_PKEY. I.e. caller can 304 // that is owned by and destroyed with the EVP_PKEY. I.e. caller can
282 // free |private_key| after the call. 305 // free |private_key| after the call.
283 // IMPORTANT: The EVP_PKEY will *only* work on Android >= 4.2. For older 306 // IMPORTANT: The EVP_PKEY will *only* work on Android >= 4.2. For older
284 // platforms, use GetRsaLegacyKey() instead. 307 // platforms, use GetRsaLegacyKey() instead.
285 bool GetRsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { 308 bool GetRsaPkeyWrapper(jobject private_key,
309 AndroidRSA* legacy_rsa,
310 EVP_PKEY* pkey) {
286 ScopedRSA rsa(RSA_new()); 311 ScopedRSA rsa(RSA_new());
287 RSA_set_method(rsa.get(), &android_rsa_method); 312 RSA_set_method(rsa.get(), &android_rsa_method);
288 313
289 // HACK: RSA_size() doesn't work with custom RSA_METHODs. To ensure that 314 // HACK: RSA_size() doesn't work with custom RSA_METHODs. To ensure that
290 // it will return the right value, set the 'n' field of the RSA object 315 // it will return the right value, set the 'n' field of the RSA object
291 // to match the private key's modulus. 316 // to match the private key's modulus.
317 //
318 // TODO(davidben): After switching to BoringSSL, consider making RSA_size call
319 // into an RSA_METHOD hook.
292 std::vector<uint8> modulus; 320 std::vector<uint8> modulus;
293 if (!GetRSAKeyModulus(private_key, &modulus)) { 321 if (!GetRSAKeyModulus(private_key, &modulus)) {
294 LOG(ERROR) << "Failed to get private key modulus"; 322 LOG(ERROR) << "Failed to get private key modulus";
295 return false; 323 return false;
296 } 324 }
297 if (!SwapBigNumPtrFromBytes(modulus, &rsa.get()->n)) { 325 if (!SwapBigNumPtrFromBytes(modulus, &rsa.get()->n)) {
298 LOG(ERROR) << "Failed to decode private key modulus"; 326 LOG(ERROR) << "Failed to decode private key modulus";
299 return false; 327 return false;
300 } 328 }
301 329
302 ScopedJavaGlobalRef<jobject> global_key; 330 ScopedJavaGlobalRef<jobject> global_key;
303 global_key.Reset(NULL, private_key); 331 global_key.Reset(NULL, private_key);
304 if (global_key.is_null()) { 332 if (global_key.is_null()) {
305 LOG(ERROR) << "Could not create global JNI reference"; 333 LOG(ERROR) << "Could not create global JNI reference";
306 return false; 334 return false;
307 } 335 }
308 RSA_set_app_data(rsa.get(), global_key.Release()); 336 RsaAppData* app_data = new RsaAppData();
337 app_data->private_key = global_key.Release();
338 app_data->legacy_rsa = legacy_rsa;
339 RSA_set_app_data(rsa.get(), app_data);
309 EVP_PKEY_assign_RSA(pkey, rsa.release()); 340 EVP_PKEY_assign_RSA(pkey, rsa.release());
310 return true; 341 return true;
311 } 342 }
312 343
313 // On Android < 4.2, the libkeystore.so ENGINE uses CRYPTO_EX_DATA and is not 344 // On Android < 4.2, the libkeystore.so ENGINE uses CRYPTO_EX_DATA and is not
314 // added to the global engine list. If all references to it are dropped, OpenSSL 345 // added to the global engine list. If all references to it are dropped, OpenSSL
315 // will dlclose the module, leaving a dangling function pointer in the RSA 346 // will dlclose the module, leaving a dangling function pointer in the RSA
316 // CRYPTO_EX_DATA class. To work around this, leak an extra reference to the 347 // CRYPTO_EX_DATA class. To work around this, leak an extra reference to the
317 // ENGINE we extract in GetRsaLegacyKey. 348 // ENGINE we extract in GetRsaLegacyKey.
318 // 349 //
319 // In 4.2, this change avoids the problem: 350 // In 4.2, this change avoids the problem:
320 // https://android.googlesource.com/platform/libcore/+/106a8928fb4249f2f3d4dba1d ddbe73ca5cb3d61 351 // https://android.googlesource.com/platform/libcore/+/106a8928fb4249f2f3d4dba1d ddbe73ca5cb3d61
321 // 352 //
322 // https://crbug.com/381465 353 // https://crbug.com/381465
323 class KeystoreEngineWorkaround { 354 class KeystoreEngineWorkaround {
324 public: 355 public:
325 KeystoreEngineWorkaround() : leaked_engine_(false) {} 356 KeystoreEngineWorkaround() {}
326 357
327 void LeakRsaEngine(EVP_PKEY* pkey) { 358 void LeakEngine(jobject private_key) {
328 if (leaked_engine_) 359 if (!engine_.is_null())
329 return; 360 return;
330 ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey)); 361 ScopedJavaLocalRef<jobject> engine =
331 if (!rsa.get() || 362 GetOpenSSLEngineForPrivateKey(private_key);
332 !rsa.get()->engine || 363 if (engine.is_null()) {
333 strcmp(ENGINE_get_id(rsa.get()->engine), "keystore") ||
334 !ENGINE_init(rsa.get()->engine)) {
335 NOTREACHED(); 364 NOTREACHED();
336 return; 365 return;
337 } 366 }
338 leaked_engine_ = true; 367 engine_.Reset(engine);
339 } 368 }
340 369
341 private: 370 private:
342 bool leaked_engine_; 371 ScopedJavaGlobalRef<jobject> engine_;
343 }; 372 };
344 373
345 void LeakRsaEngine(EVP_PKEY* pkey) { 374 void LeakEngine(jobject private_key) {
346 static base::LazyInstance<KeystoreEngineWorkaround>::Leaky s_instance = 375 static base::LazyInstance<KeystoreEngineWorkaround>::Leaky s_instance =
347 LAZY_INSTANCE_INITIALIZER; 376 LAZY_INSTANCE_INITIALIZER;
348 s_instance.Get().LeakRsaEngine(pkey); 377 s_instance.Get().LeakEngine(private_key);
349 } 378 }
350 379
351 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object 380 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object
352 // for Android 4.0 to 4.1.x. Must only be used on Android < 4.2. 381 // for Android 4.0 to 4.1.x. Must only be used on Android < 4.2.
353 // |private_key| is a JNI reference (local or global) to the object. 382 // |private_key| is a JNI reference (local or global) to the object.
354 // |pkey| is the EVP_PKEY to setup as a wrapper. 383 // |pkey| is the EVP_PKEY to setup as a wrapper.
355 // Returns true on success, false otherwise. 384 // Returns true on success, false otherwise.
356 EVP_PKEY* GetRsaLegacyKey(jobject private_key) { 385 EVP_PKEY* GetRsaLegacyKey(jobject private_key) {
357 EVP_PKEY* sys_pkey = 386 AndroidEVP_PKEY* sys_pkey =
358 GetOpenSSLSystemHandleForPrivateKey(private_key); 387 GetOpenSSLSystemHandleForPrivateKey(private_key);
359 if (sys_pkey != NULL) { 388 if (sys_pkey != NULL) {
360 CRYPTO_add(&sys_pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 389 if (sys_pkey->type != ANDROID_EVP_PKEY_RSA) {
361 LeakRsaEngine(sys_pkey); 390 LOG(ERROR) << "Private key has wrong type!";
362 } else {
363 // GetOpenSSLSystemHandleForPrivateKey() will fail on Android
364 // 4.0.3 and earlier. However, it is possible to get the key
365 // content with PrivateKey.getEncoded() on these platforms.
366 // Note that this method may return NULL on 4.0.4 and later.
367 std::vector<uint8> encoded;
368 if (!GetPrivateKeyEncodedBytes(private_key, &encoded)) {
369 LOG(ERROR) << "Can't get private key data!";
370 return NULL; 391 return NULL;
371 } 392 }
372 const unsigned char* p = 393
373 reinterpret_cast<const unsigned char*>(&encoded[0]); 394 AndroidRSA* sys_rsa = sys_pkey->pkey.rsa;
374 int len = static_cast<int>(encoded.size()); 395 if (sys_rsa->engine) {
375 sys_pkey = d2i_AutoPrivateKey(NULL, &p, len); 396 // |private_key| may not have an engine if the PrivateKey did not come
376 if (sys_pkey == NULL) { 397 // from the key store, such as in unit tests.
377 LOG(ERROR) << "Can't convert private key data!"; 398 if (!strcmp(sys_rsa->engine->id, "keystore")) {
399 LeakEngine(private_key);
400 } else {
401 NOTREACHED();
402 }
403 }
404
405 ScopedEVP_PKEY pkey(EVP_PKEY_new());
406 if (!GetRsaPkeyWrapper(private_key, sys_rsa, pkey.get()))
378 return NULL; 407 return NULL;
379 } 408 return pkey.release();
380 } 409 }
381 return sys_pkey; 410
411 // GetOpenSSLSystemHandleForPrivateKey() will fail on Android 4.0.3 and
412 // earlier. However, it is possible to get the key content with
413 // PrivateKey.getEncoded() on these platforms. Note that this method may
414 // return NULL on 4.0.4 and later.
415 std::vector<uint8> encoded;
416 if (!GetPrivateKeyEncodedBytes(private_key, &encoded)) {
417 LOG(ERROR) << "Can't get private key data!";
418 return NULL;
419 }
420 const unsigned char* p =
421 reinterpret_cast<const unsigned char*>(&encoded[0]);
422 int len = static_cast<int>(encoded.size());
423 EVP_PKEY* pkey = d2i_AutoPrivateKey(NULL, &p, len);
424 if (pkey == NULL) {
425 LOG(ERROR) << "Can't convert private key data!";
426 return NULL;
427 }
428 return pkey;
382 } 429 }
383 430
384 // Custom DSA_METHOD that uses the platform APIs. 431 // Custom DSA_METHOD that uses the platform APIs.
385 // Note that for now, only signing through DSA_sign() is really supported. 432 // Note that for now, only signing through DSA_sign() is really supported.
386 // all other method pointers are either stubs returning errors, or no-ops. 433 // all other method pointers are either stubs returning errors, or no-ops.
387 // See <openssl/dsa.h> for exact declaration of DSA_METHOD. 434 // See <openssl/dsa.h> for exact declaration of DSA_METHOD.
388 // 435 //
389 // Note: There is no DSA_set_app_data() and DSA_get_app_data() functions, 436 // Note: There is no DSA_set_app_data() and DSA_get_app_data() functions,
390 // but RSA_set_app_data() is defined as a simple macro that calls 437 // but RSA_set_app_data() is defined as a simple macro that calls
391 // RSA_set_ex_data() with a hard-coded index of 0, so this code 438 // RSA_set_ex_data() with a hard-coded index of 0, so this code
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 // backing this PrivateKey object. 750 // backing this PrivateKey object.
704 const int kAndroid42ApiLevel = 17; 751 const int kAndroid42ApiLevel = 17;
705 if (base::android::BuildInfo::GetInstance()->sdk_int() < 752 if (base::android::BuildInfo::GetInstance()->sdk_int() <
706 kAndroid42ApiLevel) { 753 kAndroid42ApiLevel) {
707 EVP_PKEY* legacy_key = GetRsaLegacyKey(private_key); 754 EVP_PKEY* legacy_key = GetRsaLegacyKey(private_key);
708 if (legacy_key == NULL) 755 if (legacy_key == NULL)
709 return NULL; 756 return NULL;
710 pkey.reset(legacy_key); 757 pkey.reset(legacy_key);
711 } else { 758 } else {
712 // Running on Android 4.2. 759 // Running on Android 4.2.
713 if (!GetRsaPkeyWrapper(private_key, pkey.get())) 760 if (!GetRsaPkeyWrapper(private_key, NULL, pkey.get()))
714 return NULL; 761 return NULL;
715 } 762 }
716 } 763 }
717 break; 764 break;
718 case PRIVATE_KEY_TYPE_DSA: 765 case PRIVATE_KEY_TYPE_DSA:
719 if (!GetDsaPkeyWrapper(private_key, pkey.get())) 766 if (!GetDsaPkeyWrapper(private_key, pkey.get()))
720 return NULL; 767 return NULL;
721 break; 768 break;
722 case PRIVATE_KEY_TYPE_ECDSA: 769 case PRIVATE_KEY_TYPE_ECDSA:
723 if (!GetEcdsaPkeyWrapper(private_key, pkey.get())) 770 if (!GetEcdsaPkeyWrapper(private_key, pkey.get()))
724 return NULL; 771 return NULL;
725 break; 772 break;
726 default: 773 default:
727 LOG(WARNING) 774 LOG(WARNING)
728 << "GetOpenSSLPrivateKeyWrapper() called with invalid key type"; 775 << "GetOpenSSLPrivateKeyWrapper() called with invalid key type";
729 return NULL; 776 return NULL;
730 } 777 }
731 return pkey.release(); 778 return pkey.release();
732 } 779 }
733 780
734 } // namespace android 781 } // namespace android
735 } // namespace net 782 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698