OLD | NEW |
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 <openssl/bn.h> | 5 #include <openssl/bn.h> |
6 #include <openssl/dsa.h> | 6 #include <openssl/dsa.h> |
7 #include <openssl/ecdsa.h> | 7 #include <openssl/ecdsa.h> |
8 #include <openssl/err.h> | 8 #include <openssl/err.h> |
9 #include <openssl/evp.h> | 9 #include <openssl/evp.h> |
10 #include <openssl/pem.h> | 10 #include <openssl/pem.h> |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 // possible to create a custom EVP_PKEY that uses | 44 // possible to create a custom EVP_PKEY that uses |
45 // RawSignDigestWithPrivateKey() internally to perform RSA/DSA/ECDSA | 45 // RawSignDigestWithPrivateKey() internally to perform RSA/DSA/ECDSA |
46 // signing, as invoked by the OpenSSL code at | 46 // signing, as invoked by the OpenSSL code at |
47 // openssl/ssl/s3_clnt.c:ssl3_send_client_verify(). | 47 // openssl/ssl/s3_clnt.c:ssl3_send_client_verify(). |
48 // | 48 // |
49 // For more details, read the comments in AndroidKeyStore.java. | 49 // For more details, read the comments in AndroidKeyStore.java. |
50 // | 50 // |
51 // Finally, it also checks that using the EVP_PKEY generated with | 51 // Finally, it also checks that using the EVP_PKEY generated with |
52 // GetOpenSSLPrivateKeyWrapper() works correctly. | 52 // GetOpenSSLPrivateKeyWrapper() works correctly. |
53 | 53 |
| 54 using base::android::JavaRef; |
| 55 |
54 namespace net { | 56 namespace net { |
55 namespace android { | 57 namespace android { |
56 | 58 |
57 namespace { | 59 namespace { |
58 | 60 |
59 typedef base::android::ScopedJavaLocalRef<jobject> ScopedJava; | 61 typedef base::android::ScopedJavaLocalRef<jobject> ScopedJava; |
60 | 62 |
61 // Returns true if running on an Android version older than 4.2 | 63 // Returns true if running on an Android version older than 4.2 |
62 bool IsOnAndroidOlderThan_4_2(void) { | 64 bool IsOnAndroidOlderThan_4_2(void) { |
63 const int kAndroid42ApiLevel = 17; | 65 const int kAndroid42ApiLevel = 17; |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 return true; | 350 return true; |
349 } | 351 } |
350 | 352 |
351 // Sign a message with our platform API. | 353 // Sign a message with our platform API. |
352 // | 354 // |
353 // |android_key| is a JNI reference to the platform PrivateKey object. | 355 // |android_key| is a JNI reference to the platform PrivateKey object. |
354 // |openssl_key| is a pointer to an OpenSSL key object for the exact | 356 // |openssl_key| is a pointer to an OpenSSL key object for the exact |
355 // same key content. | 357 // same key content. |
356 // |message| is a message. | 358 // |message| is a message. |
357 // |result| will receive the result. | 359 // |result| will receive the result. |
358 void DoKeySigning(jobject android_key, | 360 void DoKeySigning(const JavaRef<jobject>& android_key, |
359 EVP_PKEY* openssl_key, | 361 EVP_PKEY* openssl_key, |
360 const base::StringPiece& message, | 362 const base::StringPiece& message, |
361 std::string* result) { | 363 std::string* result) { |
362 // First, get the platform signature. | 364 // First, get the platform signature. |
363 std::vector<uint8_t> android_signature; | 365 std::vector<uint8_t> android_signature; |
364 ASSERT_TRUE( | 366 ASSERT_TRUE( |
365 RawSignDigestWithPrivateKey(android_key, | 367 RawSignDigestWithPrivateKey(android_key, |
366 message, | 368 message, |
367 &android_signature)); | 369 &android_signature)); |
368 | 370 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 std::string pkcs8_data; | 408 std::string pkcs8_data; |
407 ASSERT_TRUE(GetPrivateKeyPkcs8Bytes(pkey, &pkcs8_data)); | 409 ASSERT_TRUE(GetPrivateKeyPkcs8Bytes(pkey, &pkcs8_data)); |
408 | 410 |
409 // Create platform PrivateKey object from it. | 411 // Create platform PrivateKey object from it. |
410 ScopedJava key_java = GetPKCS8PrivateKeyJava(PRIVATE_KEY_TYPE_RSA, | 412 ScopedJava key_java = GetPKCS8PrivateKeyJava(PRIVATE_KEY_TYPE_RSA, |
411 pkcs8_data); | 413 pkcs8_data); |
412 ASSERT_FALSE(key_java.is_null()); | 414 ASSERT_FALSE(key_java.is_null()); |
413 | 415 |
414 // Retrieve the corresponding modulus through JNI | 416 // Retrieve the corresponding modulus through JNI |
415 std::vector<uint8_t> modulus_java; | 417 std::vector<uint8_t> modulus_java; |
416 ASSERT_TRUE(GetRSAKeyModulus(key_java.obj(), &modulus_java)); | 418 ASSERT_TRUE(GetRSAKeyModulus(key_java, &modulus_java)); |
417 | 419 |
418 // Create an OpenSSL BIGNUM from it. | 420 // Create an OpenSSL BIGNUM from it. |
419 crypto::ScopedBIGNUM bn( | 421 crypto::ScopedBIGNUM bn( |
420 BN_bin2bn(reinterpret_cast<const unsigned char*>(&modulus_java[0]), | 422 BN_bin2bn(reinterpret_cast<const unsigned char*>(&modulus_java[0]), |
421 static_cast<int>(modulus_java.size()), | 423 static_cast<int>(modulus_java.size()), |
422 NULL)); | 424 NULL)); |
423 ASSERT_TRUE(bn.get()); | 425 ASSERT_TRUE(bn.get()); |
424 | 426 |
425 // Compare it to the one in the RSA key, they must be identical. | 427 // Compare it to the one in the RSA key, they must be identical. |
426 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey.get())); | 428 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey.get())); |
427 ASSERT_TRUE(rsa.get()) << GetOpenSSLErrorString(); | 429 ASSERT_TRUE(rsa.get()) << GetOpenSSLErrorString(); |
428 | 430 |
429 ASSERT_EQ(0, BN_cmp(bn.get(), rsa.get()->n)); | 431 ASSERT_EQ(0, BN_cmp(bn.get(), rsa.get()->n)); |
430 } | 432 } |
431 | 433 |
432 TEST(AndroidKeyStore,GetPrivateKeyTypeRSA) { | 434 TEST(AndroidKeyStore,GetPrivateKeyTypeRSA) { |
433 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); | 435 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); |
434 | 436 |
435 ScopedJava rsa_key = GetRSATestKeyJava(); | 437 ScopedJava rsa_key = GetRSATestKeyJava(); |
436 ASSERT_FALSE(rsa_key.is_null()); | 438 ASSERT_FALSE(rsa_key.is_null()); |
437 EXPECT_EQ(PRIVATE_KEY_TYPE_RSA, | 439 EXPECT_EQ(PRIVATE_KEY_TYPE_RSA, GetPrivateKeyType(rsa_key)); |
438 GetPrivateKeyType(rsa_key.obj())); | |
439 } | 440 } |
440 | 441 |
441 TEST(AndroidKeyStore,SignWithPrivateKeyRSA) { | 442 TEST(AndroidKeyStore,SignWithPrivateKeyRSA) { |
442 ScopedJava rsa_key = GetRSATestKeyJava(); | 443 ScopedJava rsa_key = GetRSATestKeyJava(); |
443 ASSERT_FALSE(rsa_key.is_null()); | 444 ASSERT_FALSE(rsa_key.is_null()); |
444 | 445 |
445 if (IsOnAndroidOlderThan_4_2()) { | 446 if (IsOnAndroidOlderThan_4_2()) { |
446 LOG(INFO) << "This test can't run on Android < 4.2"; | 447 LOG(INFO) << "This test can't run on Android < 4.2"; |
447 return; | 448 return; |
448 } | 449 } |
449 | 450 |
450 crypto::ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestRsaKeyFile)); | 451 crypto::ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestRsaKeyFile)); |
451 ASSERT_TRUE(openssl_key.get()); | 452 ASSERT_TRUE(openssl_key.get()); |
452 | 453 |
453 std::string message = kTestRsaHash; | 454 std::string message = kTestRsaHash; |
454 ASSERT_EQ(36U, message.size()); | 455 ASSERT_EQ(36U, message.size()); |
455 | 456 |
456 std::string signature; | 457 std::string signature; |
457 DoKeySigning(rsa_key.obj(), openssl_key.get(), message, &signature); | 458 DoKeySigning(rsa_key, openssl_key.get(), message, &signature); |
458 ASSERT_TRUE( | 459 ASSERT_TRUE( |
459 CompareSignatureWithOpenSSL(message, signature, openssl_key.get())); | 460 CompareSignatureWithOpenSSL(message, signature, openssl_key.get())); |
460 // All good. | 461 // All good. |
461 } | 462 } |
462 | 463 |
463 TEST(AndroidKeyStore,SignWithWrapperKeyRSA) { | 464 TEST(AndroidKeyStore,SignWithWrapperKeyRSA) { |
464 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 465 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
465 | 466 |
466 ScopedJava rsa_key = GetRSATestKeyJava(); | 467 ScopedJava rsa_key = GetRSATestKeyJava(); |
467 ASSERT_FALSE(rsa_key.is_null()); | 468 ASSERT_FALSE(rsa_key.is_null()); |
468 | 469 |
469 crypto::ScopedEVP_PKEY wrapper_key( | 470 crypto::ScopedEVP_PKEY wrapper_key(GetOpenSSLPrivateKeyWrapper(rsa_key)); |
470 GetOpenSSLPrivateKeyWrapper(rsa_key.obj())); | |
471 ASSERT_TRUE(wrapper_key.get() != NULL); | 471 ASSERT_TRUE(wrapper_key.get() != NULL); |
472 | 472 |
473 crypto::ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestRsaKeyFile)); | 473 crypto::ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestRsaKeyFile)); |
474 ASSERT_TRUE(openssl_key.get()); | 474 ASSERT_TRUE(openssl_key.get()); |
475 | 475 |
476 // Check that RSA_size() works properly on the wrapper key. | 476 // Check that RSA_size() works properly on the wrapper key. |
477 EXPECT_EQ(EVP_PKEY_size(openssl_key.get()), | 477 EXPECT_EQ(EVP_PKEY_size(openssl_key.get()), |
478 EVP_PKEY_size(wrapper_key.get())); | 478 EVP_PKEY_size(wrapper_key.get())); |
479 | 479 |
480 // Message size must be 36 for RSA_sign(NID_md5_sha1,...) to return | 480 // Message size must be 36 for RSA_sign(NID_md5_sha1,...) to return |
481 // without an error. | 481 // without an error. |
482 std::string message = kTestRsaHash; | 482 std::string message = kTestRsaHash; |
483 ASSERT_EQ(36U, message.size()); | 483 ASSERT_EQ(36U, message.size()); |
484 | 484 |
485 std::string signature; | 485 std::string signature; |
486 DoKeySigningWithWrapper(wrapper_key.get(), | 486 DoKeySigningWithWrapper(wrapper_key.get(), |
487 openssl_key.get(), | 487 openssl_key.get(), |
488 message, | 488 message, |
489 &signature); | 489 &signature); |
490 ASSERT_TRUE( | 490 ASSERT_TRUE( |
491 CompareSignatureWithOpenSSL(message, signature, openssl_key.get())); | 491 CompareSignatureWithOpenSSL(message, signature, openssl_key.get())); |
492 } | 492 } |
493 | 493 |
494 TEST(AndroidKeyStore,GetPrivateKeyTypeECDSA) { | 494 TEST(AndroidKeyStore,GetPrivateKeyTypeECDSA) { |
495 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); | 495 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); |
496 | 496 |
497 ScopedJava ecdsa_key = GetECDSATestKeyJava(); | 497 ScopedJava ecdsa_key = GetECDSATestKeyJava(); |
498 ASSERT_FALSE(ecdsa_key.is_null()); | 498 ASSERT_FALSE(ecdsa_key.is_null()); |
499 EXPECT_EQ(PRIVATE_KEY_TYPE_ECDSA, | 499 EXPECT_EQ(PRIVATE_KEY_TYPE_ECDSA, GetPrivateKeyType(ecdsa_key)); |
500 GetPrivateKeyType(ecdsa_key.obj())); | |
501 } | 500 } |
502 | 501 |
503 TEST(AndroidKeyStore,SignWithPrivateKeyECDSA) { | 502 TEST(AndroidKeyStore,SignWithPrivateKeyECDSA) { |
504 ScopedJava ecdsa_key = GetECDSATestKeyJava(); | 503 ScopedJava ecdsa_key = GetECDSATestKeyJava(); |
505 ASSERT_FALSE(ecdsa_key.is_null()); | 504 ASSERT_FALSE(ecdsa_key.is_null()); |
506 | 505 |
507 crypto::ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestEcdsaKeyFile)); | 506 crypto::ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestEcdsaKeyFile)); |
508 ASSERT_TRUE(openssl_key.get()); | 507 ASSERT_TRUE(openssl_key.get()); |
509 | 508 |
510 std::string message = kTestEcdsaHash; | 509 std::string message = kTestEcdsaHash; |
511 std::string signature; | 510 std::string signature; |
512 DoKeySigning(ecdsa_key.obj(), openssl_key.get(), message, &signature); | 511 DoKeySigning(ecdsa_key, openssl_key.get(), message, &signature); |
513 ASSERT_TRUE(VerifyTestECDSASignature(message, signature)); | 512 ASSERT_TRUE(VerifyTestECDSASignature(message, signature)); |
514 } | 513 } |
515 | 514 |
516 TEST(AndroidKeyStore, SignWithWrapperKeyECDSA) { | 515 TEST(AndroidKeyStore, SignWithWrapperKeyECDSA) { |
517 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | 516 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
518 | 517 |
519 ScopedJava ecdsa_key = GetECDSATestKeyJava(); | 518 ScopedJava ecdsa_key = GetECDSATestKeyJava(); |
520 ASSERT_FALSE(ecdsa_key.is_null()); | 519 ASSERT_FALSE(ecdsa_key.is_null()); |
521 | 520 |
522 crypto::ScopedEVP_PKEY wrapper_key( | 521 crypto::ScopedEVP_PKEY wrapper_key(GetOpenSSLPrivateKeyWrapper(ecdsa_key)); |
523 GetOpenSSLPrivateKeyWrapper(ecdsa_key.obj())); | |
524 ASSERT_TRUE(wrapper_key.get()); | 522 ASSERT_TRUE(wrapper_key.get()); |
525 | 523 |
526 crypto::ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestEcdsaKeyFile)); | 524 crypto::ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestEcdsaKeyFile)); |
527 ASSERT_TRUE(openssl_key.get()); | 525 ASSERT_TRUE(openssl_key.get()); |
528 | 526 |
529 // Check that ECDSA size works correctly on the wrapper. | 527 // Check that ECDSA size works correctly on the wrapper. |
530 EXPECT_EQ(EVP_PKEY_size(openssl_key.get()), | 528 EXPECT_EQ(EVP_PKEY_size(openssl_key.get()), |
531 EVP_PKEY_size(wrapper_key.get())); | 529 EVP_PKEY_size(wrapper_key.get())); |
532 | 530 |
533 std::string message = kTestEcdsaHash; | 531 std::string message = kTestEcdsaHash; |
534 std::string signature; | 532 std::string signature; |
535 DoKeySigningWithWrapper(wrapper_key.get(), | 533 DoKeySigningWithWrapper(wrapper_key.get(), |
536 openssl_key.get(), | 534 openssl_key.get(), |
537 message, | 535 message, |
538 &signature); | 536 &signature); |
539 ASSERT_TRUE(VerifyTestECDSASignature(message, signature)); | 537 ASSERT_TRUE(VerifyTestECDSASignature(message, signature)); |
540 } | 538 } |
541 | 539 |
542 } // namespace android | 540 } // namespace android |
543 } // namespace net | 541 } // namespace net |
OLD | NEW |