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

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

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 int padding) { 129 int padding) {
130 NOTIMPLEMENTED(); 130 NOTIMPLEMENTED();
131 RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); 131 RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
132 return -1; 132 return -1;
133 } 133 }
134 134
135 // See RSA_eay_private_encrypt in 135 // See RSA_eay_private_encrypt in
136 // third_party/openssl/openssl/crypto/rsa/rsa_eay.c for the default 136 // third_party/openssl/openssl/crypto/rsa/rsa_eay.c for the default
137 // implementation of this function. 137 // implementation of this function.
138 int RsaMethodPrivEnc(int flen, 138 int RsaMethodPrivEnc(int flen,
139 const unsigned char *from, 139 const unsigned char* from,
140 unsigned char *to, 140 unsigned char* to,
141 RSA *rsa, 141 RSA* rsa,
142 int padding) { 142 int padding) {
143 DCHECK_EQ(RSA_PKCS1_PADDING, padding); 143 DCHECK_EQ(RSA_PKCS1_PADDING, padding);
144 if (padding != RSA_PKCS1_PADDING) { 144 if (padding != RSA_PKCS1_PADDING) {
145 // TODO(davidben): If we need to, we can implement RSA_NO_PADDING 145 // TODO(davidben): If we need to, we can implement RSA_NO_PADDING
146 // by using javax.crypto.Cipher and picking either the 146 // by using javax.crypto.Cipher and picking either the
147 // "RSA/ECB/NoPadding" or "RSA/ECB/PKCS1Padding" transformation as 147 // "RSA/ECB/NoPadding" or "RSA/ECB/PKCS1Padding" transformation as
148 // appropriate. I believe support for both of these was added in 148 // appropriate. I believe support for both of these was added in
149 // the same Android version as the "NONEwithRSA" 149 // the same Android version as the "NONEwithRSA"
150 // java.security.Signature algorithm, so the same version checks 150 // java.security.Signature algorithm, so the same version checks
151 // for GetRsaLegacyKey should work. 151 // for GetRsaLegacyKey should work.
(...skipping 14 matching lines...) Expand all
166 // For RSA keys, this function behaves as RSA_private_encrypt with 166 // For RSA keys, this function behaves as RSA_private_encrypt with
167 // PKCS#1 padding. 167 // PKCS#1 padding.
168 if (!RawSignDigestWithPrivateKey(private_key, from_piece, &result)) { 168 if (!RawSignDigestWithPrivateKey(private_key, from_piece, &result)) {
169 LOG(WARNING) << "Could not sign message in RsaMethodPrivEnc!"; 169 LOG(WARNING) << "Could not sign message in RsaMethodPrivEnc!";
170 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); 170 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
171 return -1; 171 return -1;
172 } 172 }
173 173
174 size_t expected_size = static_cast<size_t>(RSA_size(rsa)); 174 size_t expected_size = static_cast<size_t>(RSA_size(rsa));
175 if (result.size() > expected_size) { 175 if (result.size() > expected_size) {
176 LOG(ERROR) << "RSA Signature size mismatch, actual: " 176 LOG(ERROR) << "RSA Signature size mismatch, actual: " << result.size()
177 << result.size() << ", expected <= " << expected_size; 177 << ", expected <= " << expected_size;
178 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); 178 RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
179 return -1; 179 return -1;
180 } 180 }
181 181
182 // Copy result to OpenSSL-provided buffer. RawSignDigestWithPrivateKey 182 // Copy result to OpenSSL-provided buffer. RawSignDigestWithPrivateKey
183 // should pad with leading 0s, but if it doesn't, pad the result. 183 // should pad with leading 0s, but if it doesn't, pad the result.
184 size_t zero_pad = expected_size - result.size(); 184 size_t zero_pad = expected_size - result.size();
185 memset(to, 0, zero_pad); 185 memset(to, 0, zero_pad);
186 memcpy(to + zero_pad, &result[0], result.size()); 186 memcpy(to + zero_pad, &result[0], result.size());
187 187
(...skipping 21 matching lines...) Expand all
209 if (key != NULL) { 209 if (key != NULL) {
210 RSA_set_app_data(rsa, NULL); 210 RSA_set_app_data(rsa, NULL);
211 ReleaseKey(key); 211 ReleaseKey(key);
212 } 212 }
213 // Actual return value is ignored by OpenSSL. There are no docs 213 // Actual return value is ignored by OpenSSL. There are no docs
214 // explaining what this is supposed to be. 214 // explaining what this is supposed to be.
215 return 0; 215 return 0;
216 } 216 }
217 217
218 const RSA_METHOD android_rsa_method = { 218 const RSA_METHOD android_rsa_method = {
219 /* .name = */ "Android signing-only RSA method", 219 /* .name = */ "Android signing-only RSA method",
220 /* .rsa_pub_enc = */ RsaMethodPubEnc, 220 /* .rsa_pub_enc = */ RsaMethodPubEnc,
221 /* .rsa_pub_dec = */ RsaMethodPubDec, 221 /* .rsa_pub_dec = */ RsaMethodPubDec,
222 /* .rsa_priv_enc = */ RsaMethodPrivEnc, 222 /* .rsa_priv_enc = */ RsaMethodPrivEnc,
223 /* .rsa_priv_dec = */ RsaMethodPrivDec, 223 /* .rsa_priv_dec = */ RsaMethodPrivDec,
224 /* .rsa_mod_exp = */ NULL, 224 /* .rsa_mod_exp = */ NULL,
225 /* .bn_mod_exp = */ NULL, 225 /* .bn_mod_exp = */ NULL,
226 /* .init = */ RsaMethodInit, 226 /* .init = */ RsaMethodInit,
227 /* .finish = */ RsaMethodFinish, 227 /* .finish = */ RsaMethodFinish,
228 // This flag is necessary to tell OpenSSL to avoid checking the content 228 // This flag is necessary to tell OpenSSL to avoid checking the content
229 // (i.e. internal fields) of the private key. Otherwise, it will complain 229 // (i.e. internal fields) of the private key. Otherwise, it will complain
230 // it's not valid for the certificate. 230 // it's not valid for the certificate.
231 /* .flags = */ RSA_METHOD_FLAG_NO_CHECK, 231 /* .flags = */ RSA_METHOD_FLAG_NO_CHECK,
232 /* .app_data = */ NULL, 232 /* .app_data = */ NULL,
233 /* .rsa_sign = */ NULL, 233 /* .rsa_sign = */ NULL,
234 /* .rsa_verify = */ NULL, 234 /* .rsa_verify = */ NULL,
235 /* .rsa_keygen = */ NULL, 235 /* .rsa_keygen = */ NULL,
236 }; 236 };
237 237
238 // Copy the contents of an encoded big integer into an existing BIGNUM. 238 // Copy the contents of an encoded big integer into an existing BIGNUM.
239 // This function modifies |*num| in-place. 239 // This function modifies |*num| in-place.
240 // |new_bytes| is the byte encoding of the new value. 240 // |new_bytes| is the byte encoding of the new value.
241 // |num| points to the BIGNUM which will be assigned with the new value. 241 // |num| points to the BIGNUM which will be assigned with the new value.
242 // Returns true on success, false otherwise. On failure, |*num| is 242 // Returns true on success, false otherwise. On failure, |*num| is
243 // not modified. 243 // not modified.
244 bool CopyBigNumFromBytes(const std::vector<uint8>& new_bytes, 244 bool CopyBigNumFromBytes(const std::vector<uint8>& new_bytes, BIGNUM* num) {
245 BIGNUM* num) { 245 BIGNUM* ret = BN_bin2bn(reinterpret_cast<const unsigned char*>(&new_bytes[0]),
246 BIGNUM* ret = BN_bin2bn( 246 static_cast<int>(new_bytes.size()),
247 reinterpret_cast<const unsigned char*>(&new_bytes[0]), 247 num);
248 static_cast<int>(new_bytes.size()),
249 num);
250 return (ret != NULL); 248 return (ret != NULL);
251 } 249 }
252 250
253 // Decode the contents of an encoded big integer and either create a new 251 // Decode the contents of an encoded big integer and either create a new
254 // BIGNUM object (if |*num_ptr| is NULL on input) or copy it (if 252 // BIGNUM object (if |*num_ptr| is NULL on input) or copy it (if
255 // |*num_ptr| is not NULL). 253 // |*num_ptr| is not NULL).
256 // |new_bytes| is the byte encoding of the new value. 254 // |new_bytes| is the byte encoding of the new value.
257 // |num_ptr| is the address of a BIGNUM pointer. |*num_ptr| can be NULL. 255 // |num_ptr| is the address of a BIGNUM pointer. |*num_ptr| can be NULL.
258 // Returns true on success, false otherwise. On failure, |*num_ptr| is 256 // Returns true on success, false otherwise. On failure, |*num_ptr| is
259 // not modified. On success, |*num_ptr| will always be non-NULL and 257 // not modified. On success, |*num_ptr| will always be non-NULL and
260 // point to a valid BIGNUM object. 258 // point to a valid BIGNUM object.
261 bool SwapBigNumPtrFromBytes(const std::vector<uint8>& new_bytes, 259 bool SwapBigNumPtrFromBytes(const std::vector<uint8>& new_bytes,
262 BIGNUM** num_ptr) { 260 BIGNUM** num_ptr) {
263 BIGNUM* old_num = *num_ptr; 261 BIGNUM* old_num = *num_ptr;
264 BIGNUM* new_num = BN_bin2bn( 262 BIGNUM* new_num =
265 reinterpret_cast<const unsigned char*>(&new_bytes[0]), 263 BN_bin2bn(reinterpret_cast<const unsigned char*>(&new_bytes[0]),
266 static_cast<int>(new_bytes.size()), 264 static_cast<int>(new_bytes.size()),
267 old_num); 265 old_num);
268 if (new_num == NULL) 266 if (new_num == NULL)
269 return false; 267 return false;
270 268
271 if (old_num == NULL) 269 if (old_num == NULL)
272 *num_ptr = new_num; 270 *num_ptr = new_num;
273 return true; 271 return true;
274 } 272 }
275 273
276 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object. 274 // 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. 275 // |private_key| is the JNI reference (local or global) to the object.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 EVP_PKEY_assign_RSA(pkey, rsa.release()); 307 EVP_PKEY_assign_RSA(pkey, rsa.release());
310 return true; 308 return true;
311 } 309 }
312 310
313 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object 311 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object
314 // for Android 4.0 to 4.1.x. Must only be used on Android < 4.2. 312 // for Android 4.0 to 4.1.x. Must only be used on Android < 4.2.
315 // |private_key| is a JNI reference (local or global) to the object. 313 // |private_key| is a JNI reference (local or global) to the object.
316 // |pkey| is the EVP_PKEY to setup as a wrapper. 314 // |pkey| is the EVP_PKEY to setup as a wrapper.
317 // Returns true on success, false otherwise. 315 // Returns true on success, false otherwise.
318 EVP_PKEY* GetRsaLegacyKey(jobject private_key) { 316 EVP_PKEY* GetRsaLegacyKey(jobject private_key) {
319 EVP_PKEY* sys_pkey = 317 EVP_PKEY* sys_pkey = GetOpenSSLSystemHandleForPrivateKey(private_key);
320 GetOpenSSLSystemHandleForPrivateKey(private_key);
321 if (sys_pkey != NULL) { 318 if (sys_pkey != NULL) {
322 CRYPTO_add(&sys_pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); 319 CRYPTO_add(&sys_pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
323 } else { 320 } else {
324 // GetOpenSSLSystemHandleForPrivateKey() will fail on Android 321 // GetOpenSSLSystemHandleForPrivateKey() will fail on Android
325 // 4.0.3 and earlier. However, it is possible to get the key 322 // 4.0.3 and earlier. However, it is possible to get the key
326 // content with PrivateKey.getEncoded() on these platforms. 323 // content with PrivateKey.getEncoded() on these platforms.
327 // Note that this method may return NULL on 4.0.4 and later. 324 // Note that this method may return NULL on 4.0.4 and later.
328 std::vector<uint8> encoded; 325 std::vector<uint8> encoded;
329 if (!GetPrivateKeyEncodedBytes(private_key, &encoded)) { 326 if (!GetPrivateKeyEncodedBytes(private_key, &encoded)) {
330 LOG(ERROR) << "Can't get private key data!"; 327 LOG(ERROR) << "Can't get private key data!";
(...skipping 14 matching lines...) Expand all
345 // Custom DSA_METHOD that uses the platform APIs. 342 // Custom DSA_METHOD that uses the platform APIs.
346 // Note that for now, only signing through DSA_sign() is really supported. 343 // Note that for now, only signing through DSA_sign() is really supported.
347 // all other method pointers are either stubs returning errors, or no-ops. 344 // all other method pointers are either stubs returning errors, or no-ops.
348 // See <openssl/dsa.h> for exact declaration of DSA_METHOD. 345 // See <openssl/dsa.h> for exact declaration of DSA_METHOD.
349 // 346 //
350 // Note: There is no DSA_set_app_data() and DSA_get_app_data() functions, 347 // Note: There is no DSA_set_app_data() and DSA_get_app_data() functions,
351 // but RSA_set_app_data() is defined as a simple macro that calls 348 // but RSA_set_app_data() is defined as a simple macro that calls
352 // RSA_set_ex_data() with a hard-coded index of 0, so this code 349 // RSA_set_ex_data() with a hard-coded index of 0, so this code
353 // does the same thing here. 350 // does the same thing here.
354 351
355 DSA_SIG* DsaMethodDoSign(const unsigned char* dgst, 352 DSA_SIG* DsaMethodDoSign(const unsigned char* dgst, int dlen, DSA* dsa) {
356 int dlen,
357 DSA* dsa) {
358 // Extract the JNI reference to the PrivateKey object. 353 // Extract the JNI reference to the PrivateKey object.
359 jobject private_key = reinterpret_cast<jobject>(DSA_get_ex_data(dsa, 0)); 354 jobject private_key = reinterpret_cast<jobject>(DSA_get_ex_data(dsa, 0));
360 if (private_key == NULL) 355 if (private_key == NULL)
361 return NULL; 356 return NULL;
362 357
363 // Sign the message with it, calling platform APIs. 358 // Sign the message with it, calling platform APIs.
364 std::vector<uint8> signature; 359 std::vector<uint8> signature;
365 if (!RawSignDigestWithPrivateKey( 360 if (!RawSignDigestWithPrivateKey(
366 private_key, 361 private_key,
367 base::StringPiece( 362 base::StringPiece(reinterpret_cast<const char*>(dgst),
368 reinterpret_cast<const char*>(dgst), 363 static_cast<size_t>(dlen)),
369 static_cast<size_t>(dlen)),
370 &signature)) { 364 &signature)) {
371 return NULL; 365 return NULL;
372 } 366 }
373 367
374 // Note: With DSA, the actual signature might be smaller than DSA_size(). 368 // Note: With DSA, the actual signature might be smaller than DSA_size().
375 size_t max_expected_size = static_cast<size_t>(DSA_size(dsa)); 369 size_t max_expected_size = static_cast<size_t>(DSA_size(dsa));
376 if (signature.size() > max_expected_size) { 370 if (signature.size() > max_expected_size) {
377 LOG(ERROR) << "DSA Signature size mismatch, actual: " 371 LOG(ERROR) << "DSA Signature size mismatch, actual: " << signature.size()
378 << signature.size() << ", expected <= " 372 << ", expected <= " << max_expected_size;
379 << max_expected_size;
380 return NULL; 373 return NULL;
381 } 374 }
382 375
383 // Convert the signature into a DSA_SIG object. 376 // Convert the signature into a DSA_SIG object.
384 const unsigned char* sigbuf = 377 const unsigned char* sigbuf =
385 reinterpret_cast<const unsigned char*>(&signature[0]); 378 reinterpret_cast<const unsigned char*>(&signature[0]);
386 int siglen = static_cast<size_t>(signature.size()); 379 int siglen = static_cast<size_t>(signature.size());
387 DSA_SIG* dsa_sig = d2i_DSA_SIG(NULL, &sigbuf, siglen); 380 DSA_SIG* dsa_sig = d2i_DSA_SIG(NULL, &sigbuf, siglen);
388 return dsa_sig; 381 return dsa_sig;
389 } 382 }
390 383
391 int DsaMethodSignSetup(DSA* dsa, 384 int DsaMethodSignSetup(DSA* dsa, BN_CTX* ctx_in, BIGNUM** kinvp, BIGNUM** rp) {
392 BN_CTX* ctx_in,
393 BIGNUM** kinvp,
394 BIGNUM** rp) {
395 NOTIMPLEMENTED(); 385 NOTIMPLEMENTED();
396 DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_INVALID_DIGEST_TYPE); 386 DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_INVALID_DIGEST_TYPE);
397 return -1; 387 return -1;
398 } 388 }
399 389
400 int DsaMethodDoVerify(const unsigned char* dgst, 390 int DsaMethodDoVerify(const unsigned char* dgst,
401 int dgst_len, 391 int dgst_len,
402 DSA_SIG* sig, 392 DSA_SIG* sig,
403 DSA* dsa) { 393 DSA* dsa) {
404 NOTIMPLEMENTED(); 394 NOTIMPLEMENTED();
405 DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_INVALID_DIGEST_TYPE); 395 DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_INVALID_DIGEST_TYPE);
406 return -1; 396 return -1;
407 } 397 }
408 398
409 int DsaMethodFinish(DSA* dsa) { 399 int DsaMethodFinish(DSA* dsa) {
410 // Free the global JNI reference that was created with this 400 // Free the global JNI reference that was created with this
411 // wrapper key. 401 // wrapper key.
412 jobject key = reinterpret_cast<jobject>(DSA_get_ex_data(dsa,0)); 402 jobject key = reinterpret_cast<jobject>(DSA_get_ex_data(dsa, 0));
413 if (key != NULL) { 403 if (key != NULL) {
414 DSA_set_ex_data(dsa, 0, NULL); 404 DSA_set_ex_data(dsa, 0, NULL);
415 ReleaseKey(key); 405 ReleaseKey(key);
416 } 406 }
417 // Actual return value is ignored by OpenSSL. There are no docs 407 // Actual return value is ignored by OpenSSL. There are no docs
418 // explaining what this is supposed to be. 408 // explaining what this is supposed to be.
419 return 0; 409 return 0;
420 } 410 }
421 411
422 const DSA_METHOD android_dsa_method = { 412 const DSA_METHOD android_dsa_method = {
423 /* .name = */ "Android signing-only DSA method", 413 /* .name = */ "Android signing-only DSA method",
424 /* .dsa_do_sign = */ DsaMethodDoSign, 414 /* .dsa_do_sign = */ DsaMethodDoSign,
425 /* .dsa_sign_setup = */ DsaMethodSignSetup, 415 /* .dsa_sign_setup = */ DsaMethodSignSetup,
426 /* .dsa_do_verify = */ DsaMethodDoVerify, 416 /* .dsa_do_verify = */ DsaMethodDoVerify,
427 /* .dsa_mod_exp = */ NULL, 417 /* .dsa_mod_exp = */ NULL,
428 /* .bn_mod_exp = */ NULL, 418 /* .bn_mod_exp = */ NULL,
429 /* .init = */ NULL, // nothing to do here. 419 /* .init = */ NULL, // nothing to do here.
430 /* .finish = */ DsaMethodFinish, 420 /* .finish = */ DsaMethodFinish,
431 /* .flags = */ 0, 421 /* .flags = */ 0,
432 /* .app_data = */ NULL, 422 /* .app_data = */ NULL,
433 /* .dsa_paramgem = */ NULL, 423 /* .dsa_paramgem = */ NULL,
434 /* .dsa_keygen = */ NULL 424 /* .dsa_keygen = */ NULL};
435 };
436 425
437 // Setup an EVP_PKEY to wrap an existing DSA platform PrivateKey object. 426 // Setup an EVP_PKEY to wrap an existing DSA platform PrivateKey object.
438 // |private_key| is a JNI reference (local or global) to the object. 427 // |private_key| is a JNI reference (local or global) to the object.
439 // |pkey| is the EVP_PKEY to setup as a wrapper. 428 // |pkey| is the EVP_PKEY to setup as a wrapper.
440 // Returns true on success, false otherwise. 429 // Returns true on success, false otherwise.
441 // On success, this creates a global JNI reference to the same object 430 // On success, this creates a global JNI reference to the same object
442 // that will be owned by and destroyed with the EVP_PKEY. 431 // that will be owned by and destroyed with the EVP_PKEY.
443 bool GetDsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { 432 bool GetDsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) {
444 ScopedDSA dsa(DSA_new()); 433 ScopedDSA dsa(DSA_new());
445 DSA_set_method(dsa.get(), &android_dsa_method); 434 DSA_set_method(dsa.get(), &android_dsa_method);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 // This callback shall never be called with the current OpenSSL 492 // This callback shall never be called with the current OpenSSL
504 // implementation (the library only ever duplicates EX_DATA items 493 // implementation (the library only ever duplicates EX_DATA items
505 // for SSL and BIO objects). But provide this to catch regressions 494 // for SSL and BIO objects). But provide this to catch regressions
506 // in the future. 495 // in the future.
507 CHECK(false) << "ExDataDup was called for ECDSA custom key !?"; 496 CHECK(false) << "ExDataDup was called for ECDSA custom key !?";
508 // Return value is currently ignored by OpenSSL. 497 // Return value is currently ignored by OpenSSL.
509 return 0; 498 return 0;
510 } 499 }
511 500
512 class EcdsaExDataIndex { 501 class EcdsaExDataIndex {
513 public: 502 public:
514 int ex_data_index() { return ex_data_index_; } 503 int ex_data_index() { return ex_data_index_; }
515 504
516 EcdsaExDataIndex() { 505 EcdsaExDataIndex() {
517 ex_data_index_ = ECDSA_get_ex_new_index(0, // argl 506 ex_data_index_ = ECDSA_get_ex_new_index(0, // argl
518 NULL, // argp 507 NULL, // argp
519 NULL, // new_func 508 NULL, // new_func
520 ExDataDup, // dup_func 509 ExDataDup, // dup_func
521 ExDataFree); // free_func 510 ExDataFree); // free_func
522 } 511 }
523 512
524 private: 513 private:
525 int ex_data_index_; 514 int ex_data_index_;
526 }; 515 };
527 516
528 // Returns the index of the custom EX_DATA used to store the JNI reference. 517 // Returns the index of the custom EX_DATA used to store the JNI reference.
529 int EcdsaGetExDataIndex(void) { 518 int EcdsaGetExDataIndex(void) {
530 // Use a LazyInstance to perform thread-safe lazy initialization. 519 // Use a LazyInstance to perform thread-safe lazy initialization.
531 // Use a leaky one, since OpenSSL doesn't provide a way to release 520 // Use a leaky one, since OpenSSL doesn't provide a way to release
532 // allocated EX_DATA indices. 521 // allocated EX_DATA indices.
533 static base::LazyInstance<EcdsaExDataIndex>::Leaky s_instance = 522 static base::LazyInstance<EcdsaExDataIndex>::Leaky s_instance =
534 LAZY_INSTANCE_INITIALIZER; 523 LAZY_INSTANCE_INITIALIZER;
535 return s_instance.Get().ex_data_index(); 524 return s_instance.Get().ex_data_index();
536 } 525 }
537 526
538 ECDSA_SIG* EcdsaMethodDoSign(const unsigned char* dgst, 527 ECDSA_SIG* EcdsaMethodDoSign(const unsigned char* dgst,
539 int dgst_len, 528 int dgst_len,
540 const BIGNUM* inv, 529 const BIGNUM* inv,
541 const BIGNUM* rp, 530 const BIGNUM* rp,
542 EC_KEY* eckey) { 531 EC_KEY* eckey) {
543 // Retrieve private key JNI reference. 532 // Retrieve private key JNI reference.
544 jobject private_key = reinterpret_cast<jobject>( 533 jobject private_key = reinterpret_cast<jobject>(
545 ECDSA_get_ex_data(eckey, EcdsaGetExDataIndex())); 534 ECDSA_get_ex_data(eckey, EcdsaGetExDataIndex()));
546 if (!private_key) { 535 if (!private_key) {
547 LOG(WARNING) << "Null JNI reference passed to EcdsaMethodDoSign!"; 536 LOG(WARNING) << "Null JNI reference passed to EcdsaMethodDoSign!";
548 return NULL; 537 return NULL;
549 } 538 }
550 // Sign message with it through JNI. 539 // Sign message with it through JNI.
551 std::vector<uint8> signature; 540 std::vector<uint8> signature;
552 base::StringPiece digest( 541 base::StringPiece digest(reinterpret_cast<const char*>(dgst),
553 reinterpret_cast<const char*>(dgst), 542 static_cast<size_t>(dgst_len));
554 static_cast<size_t>(dgst_len)); 543 if (!RawSignDigestWithPrivateKey(private_key, digest, &signature)) {
555 if (!RawSignDigestWithPrivateKey(
556 private_key, digest, &signature)) {
557 LOG(WARNING) << "Could not sign message in EcdsaMethodDoSign!"; 544 LOG(WARNING) << "Could not sign message in EcdsaMethodDoSign!";
558 return NULL; 545 return NULL;
559 } 546 }
560 547
561 // Note: With ECDSA, the actual signature may be smaller than 548 // Note: With ECDSA, the actual signature may be smaller than
562 // ECDSA_size(). 549 // ECDSA_size().
563 size_t max_expected_size = static_cast<size_t>(ECDSA_size(eckey)); 550 size_t max_expected_size = static_cast<size_t>(ECDSA_size(eckey));
564 if (signature.size() > max_expected_size) { 551 if (signature.size() > max_expected_size) {
565 LOG(ERROR) << "ECDSA Signature size mismatch, actual: " 552 LOG(ERROR) << "ECDSA Signature size mismatch, actual: " << signature.size()
566 << signature.size() << ", expected <= " 553 << ", expected <= " << max_expected_size;
567 << max_expected_size;
568 return NULL; 554 return NULL;
569 } 555 }
570 556
571 // Convert signature to ECDSA_SIG object 557 // Convert signature to ECDSA_SIG object
572 const unsigned char* sigbuf = 558 const unsigned char* sigbuf =
573 reinterpret_cast<const unsigned char*>(&signature[0]); 559 reinterpret_cast<const unsigned char*>(&signature[0]);
574 long siglen = static_cast<long>(signature.size()); 560 long siglen = static_cast<long>(signature.size());
575 return d2i_ECDSA_SIG(NULL, &sigbuf, siglen); 561 return d2i_ECDSA_SIG(NULL, &sigbuf, siglen);
576 } 562 }
577 563
578 int EcdsaMethodSignSetup(EC_KEY* eckey, 564 int EcdsaMethodSignSetup(EC_KEY* eckey,
579 BN_CTX* ctx, 565 BN_CTX* ctx,
580 BIGNUM** kinv, 566 BIGNUM** kinv,
581 BIGNUM** r) { 567 BIGNUM** r) {
582 NOTIMPLEMENTED(); 568 NOTIMPLEMENTED();
583 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_ERR_EC_LIB); 569 ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_ERR_EC_LIB);
584 return -1; 570 return -1;
585 } 571 }
586 572
587 int EcdsaMethodDoVerify(const unsigned char* dgst, 573 int EcdsaMethodDoVerify(const unsigned char* dgst,
588 int dgst_len, 574 int dgst_len,
589 const ECDSA_SIG* sig, 575 const ECDSA_SIG* sig,
590 EC_KEY* eckey) { 576 EC_KEY* eckey) {
591 NOTIMPLEMENTED(); 577 NOTIMPLEMENTED();
592 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_ERR_EC_LIB); 578 ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_ERR_EC_LIB);
593 return -1; 579 return -1;
594 } 580 }
595 581
596 const ECDSA_METHOD android_ecdsa_method = { 582 const ECDSA_METHOD android_ecdsa_method = {
597 /* .name = */ "Android signing-only ECDSA method", 583 /* .name = */ "Android signing-only ECDSA method",
598 /* .ecdsa_do_sign = */ EcdsaMethodDoSign, 584 /* .ecdsa_do_sign = */ EcdsaMethodDoSign,
599 /* .ecdsa_sign_setup = */ EcdsaMethodSignSetup, 585 /* .ecdsa_sign_setup = */ EcdsaMethodSignSetup,
600 /* .ecdsa_do_verify = */ EcdsaMethodDoVerify, 586 /* .ecdsa_do_verify = */ EcdsaMethodDoVerify,
601 /* .flags = */ 0, 587 /* .flags = */ 0,
602 /* .app_data = */ NULL, 588 /* .app_data = */ NULL,
603 }; 589 };
604 590
605 // Setup an EVP_PKEY to wrap an existing platform PrivateKey object. 591 // Setup an EVP_PKEY to wrap an existing platform PrivateKey object.
606 // |private_key| is the JNI reference (local or global) to the object. 592 // |private_key| is the JNI reference (local or global) to the object.
607 // |pkey| is the EVP_PKEY to setup as a wrapper. 593 // |pkey| is the EVP_PKEY to setup as a wrapper.
608 // Returns true on success, false otherwise. 594 // Returns true on success, false otherwise.
609 // On success, this creates a global JNI reference to the object that 595 // On success, this creates a global JNI reference to the object that
610 // is owned by and destroyed with the EVP_PKEY. I.e. the caller shall 596 // is owned by and destroyed with the EVP_PKEY. I.e. the caller shall
611 // always free |private_key| after the call. 597 // always free |private_key| after the call.
612 bool GetEcdsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { 598 bool GetEcdsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) {
(...skipping 17 matching lines...) Expand all
630 return false; 616 return false;
631 } 617 }
632 EC_KEY_set_group(eckey.get(), group.release()); 618 EC_KEY_set_group(eckey.get(), group.release());
633 619
634 ScopedJavaGlobalRef<jobject> global_key; 620 ScopedJavaGlobalRef<jobject> global_key;
635 global_key.Reset(NULL, private_key); 621 global_key.Reset(NULL, private_key);
636 if (global_key.is_null()) { 622 if (global_key.is_null()) {
637 LOG(ERROR) << "Can't create global JNI reference"; 623 LOG(ERROR) << "Can't create global JNI reference";
638 return false; 624 return false;
639 } 625 }
640 ECDSA_set_ex_data(eckey.get(), 626 ECDSA_set_ex_data(eckey.get(), EcdsaGetExDataIndex(), global_key.Release());
641 EcdsaGetExDataIndex(),
642 global_key.Release());
643 627
644 EVP_PKEY_assign_EC_KEY(pkey, eckey.release()); 628 EVP_PKEY_assign_EC_KEY(pkey, eckey.release());
645 return true; 629 return true;
646 } 630 }
647 631
648 } // namespace 632 } // namespace
649 633
650 EVP_PKEY* GetOpenSSLPrivateKeyWrapper(jobject private_key) { 634 EVP_PKEY* GetOpenSSLPrivateKeyWrapper(jobject private_key) {
651 // Create new empty EVP_PKEY instance. 635 // Create new empty EVP_PKEY instance.
652 ScopedEVP_PKEY pkey(EVP_PKEY_new()); 636 ScopedEVP_PKEY pkey(EVP_PKEY_new());
653 if (!pkey.get()) 637 if (!pkey.get())
654 return NULL; 638 return NULL;
655 639
656 // Create sub key type, depending on private key's algorithm type. 640 // Create sub key type, depending on private key's algorithm type.
657 PrivateKeyType key_type = GetPrivateKeyType(private_key); 641 PrivateKeyType key_type = GetPrivateKeyType(private_key);
658 switch (key_type) { 642 switch (key_type) {
659 case PRIVATE_KEY_TYPE_RSA: 643 case PRIVATE_KEY_TYPE_RSA: {
660 { 644 // Route around platform bug: if Android < 4.2, then
661 // Route around platform bug: if Android < 4.2, then 645 // base::android::RawSignDigestWithPrivateKey() cannot work, so
662 // base::android::RawSignDigestWithPrivateKey() cannot work, so 646 // instead, obtain a raw EVP_PKEY* to the system object
663 // instead, obtain a raw EVP_PKEY* to the system object 647 // backing this PrivateKey object.
664 // backing this PrivateKey object. 648 const int kAndroid42ApiLevel = 17;
665 const int kAndroid42ApiLevel = 17; 649 if (base::android::BuildInfo::GetInstance()->sdk_int() <
666 if (base::android::BuildInfo::GetInstance()->sdk_int() < 650 kAndroid42ApiLevel) {
667 kAndroid42ApiLevel) { 651 EVP_PKEY* legacy_key = GetRsaLegacyKey(private_key);
668 EVP_PKEY* legacy_key = GetRsaLegacyKey(private_key); 652 if (legacy_key == NULL)
669 if (legacy_key == NULL) 653 return NULL;
670 return NULL; 654 pkey.reset(legacy_key);
671 pkey.reset(legacy_key); 655 } else {
672 } else { 656 // Running on Android 4.2.
673 // Running on Android 4.2. 657 if (!GetRsaPkeyWrapper(private_key, pkey.get()))
674 if (!GetRsaPkeyWrapper(private_key, pkey.get())) 658 return NULL;
675 return NULL;
676 }
677 } 659 }
678 break; 660 } break;
679 case PRIVATE_KEY_TYPE_DSA: 661 case PRIVATE_KEY_TYPE_DSA:
680 if (!GetDsaPkeyWrapper(private_key, pkey.get())) 662 if (!GetDsaPkeyWrapper(private_key, pkey.get()))
681 return NULL; 663 return NULL;
682 break; 664 break;
683 case PRIVATE_KEY_TYPE_ECDSA: 665 case PRIVATE_KEY_TYPE_ECDSA:
684 if (!GetEcdsaPkeyWrapper(private_key, pkey.get())) 666 if (!GetEcdsaPkeyWrapper(private_key, pkey.get()))
685 return NULL; 667 return NULL;
686 break; 668 break;
687 default: 669 default:
688 LOG(WARNING) 670 LOG(WARNING)
689 << "GetOpenSSLPrivateKeyWrapper() called with invalid key type"; 671 << "GetOpenSSLPrivateKeyWrapper() called with invalid key type";
690 return NULL; 672 return NULL;
691 } 673 }
692 return pkey.release(); 674 return pkey.release();
693 } 675 }
694 676
695 } // namespace android 677 } // namespace android
696 } // namespace net 678 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698