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 3 // found in the LICENSE file. 4 5 #include <openssl/bn.h> 6 #include <openssl/dsa.h> 7 #include <openssl/ecdsa.h> 8 #include <openssl/err.h> 9 #include <openssl/evp.h> 10 #include <openssl/pem.h> 11 #include <openssl/rsa.h> 12 #include <openssl/x509.h> 13 14 #include "base/android/build_info.h" 15 #include "base/android/jni_android.h" 16 #include "base/android/jni_array.h" 17 #include "base/android/scoped_java_ref.h" 18 #include "base/basictypes.h" 19 #include "base/bind.h" 20 #include "base/callback.h" 21 #include "base/compiler_specific.h" 22 #include "base/file_util.h" 23 #include "base/files/file_path.h" 24 #include "base/memory/scoped_handle.h" 25 #include "base/strings/string_number_conversions.h" 26 #include "base/strings/string_util.h" 27 #include "crypto/openssl_util.h" 28 #include "jni/AndroidKeyStoreTestUtil_jni.h" 29 #include "net/android/keystore.h" 30 #include "net/android/keystore_openssl.h" 31 #include "net/base/test_data_directory.h" 32 #include "testing/gtest/include/gtest/gtest.h" 33 34 // Technical note: 35 // 36 // This source file not only checks that signing with 37 // RawSignDigestWithPrivateKey() works correctly, it also verifies that 38 // the generated signature matches 100% of what OpenSSL generates when 39 // calling RSA_sign(NID_md5_sha1,...), DSA_sign(0, ...) or 40 // ECDSA_sign(0, ...). 41 // 42 // That's crucial to ensure that this function can later be used to 43 // implement client certificate support. More specifically, that it is 44 // possible to create a custom EVP_PKEY that uses 45 // RawSignDigestWithPrivateKey() internally to perform RSA/DSA/ECDSA 46 // signing, as invoked by the OpenSSL code at 47 // openssl/ssl/s3_clnt.c:ssl3_send_client_verify(). 48 // 49 // For more details, read the comments in AndroidKeyStore.java. 50 // 51 // Finally, it also checks that using the EVP_PKEY generated with 52 // GetOpenSSLPrivateKeyWrapper() works correctly. 53 54 namespace net { 55 namespace android { 56 57 namespace { 58 59 typedef crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> ScopedEVP_PKEY; 60 typedef crypto::ScopedOpenSSL<RSA, RSA_free> ScopedRSA; 61 typedef crypto::ScopedOpenSSL<DSA, DSA_free> ScopedDSA; 62 typedef crypto::ScopedOpenSSL<EC_KEY, EC_KEY_free> ScopedEC_KEY; 63 typedef crypto::ScopedOpenSSL<BIGNUM, BN_free> ScopedBIGNUM; 64 65 typedef crypto::ScopedOpenSSL< 66 PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free> 67 ScopedPKCS8_PRIV_KEY_INFO; 68 69 typedef base::android::ScopedJavaLocalRef<jobject> ScopedJava; 70 71 JNIEnv* InitEnv() { 72 JNIEnv* env = base::android::AttachCurrentThread(); 73 static bool inited = false; 74 if (!inited) { 75 RegisterNativesImpl(env); 76 inited = true; 77 } 78 return env; 79 } 80 81 // Returns true if running on an Android version older than 4.2 82 bool IsOnAndroidOlderThan_4_2(void) { 83 const int kAndroid42ApiLevel = 17; 84 int level = base::android::BuildInfo::GetInstance()->sdk_int(); 85 return level < kAndroid42ApiLevel; 86 } 87 88 // Implements the callback expected by ERR_print_errors_cb(). 89 // used by GetOpenSSLErrorString below. 90 int openssl_print_error_callback(const char* msg, size_t msglen, void* u) { 91 std::string* result = reinterpret_cast<std::string*>(u); 92 result->append(msg, msglen); 93 return 1; 94 } 95 96 // Retrieves the OpenSSL error as a string 97 std::string GetOpenSSLErrorString(void) { 98 std::string result; 99 ERR_print_errors_cb(openssl_print_error_callback, &result); 100 return result; 101 } 102 103 // Resize a string to |size| bytes of data, then return its data buffer 104 // address cast as an 'unsigned char*', as expected by OpenSSL functions. 105 // |str| the target string. 106 // |size| the number of bytes to write into the string. 107 // Return the string's new buffer in memory, as an 'unsigned char*' 108 // pointer. 109 unsigned char* OpenSSLWriteInto(std::string* str, size_t size) { 110 return reinterpret_cast<unsigned char*>(WriteInto(str, size + 1)); 111 } 112 113 // Load a given private key file into an EVP_PKEY. 114 // |filename| is the key file path. 115 // Returns a new EVP_PKEY on success, NULL on failure. 116 EVP_PKEY* ImportPrivateKeyFile(const char* filename) { 117 // Load file in memory. 118 base::FilePath certs_dir = GetTestCertsDirectory(); 119 base::FilePath file_path = certs_dir.AppendASCII(filename); 120 ScopedStdioHandle handle(base::OpenFile(file_path, "rb")); 121 if (!handle.get()) { 122 LOG(ERROR) << "Could not open private key file: " << filename; 123 return NULL; 124 } 125 // Assume it is PEM_encoded. Load it as an EVP_PKEY. 126 EVP_PKEY* pkey = PEM_read_PrivateKey(handle.get(), NULL, NULL, NULL); 127 if (!pkey) { 128 LOG(ERROR) << "Could not load public key file: " << filename 129 << ", " << GetOpenSSLErrorString(); 130 return NULL; 131 } 132 return pkey; 133 } 134 135 // Convert a private key into its PKCS#8 encoded representation. 136 // |pkey| is the EVP_PKEY handle for the private key. 137 // |pkcs8| will receive the PKCS#8 bytes. 138 // Returns true on success, false otherwise. 139 bool GetPrivateKeyPkcs8Bytes(const ScopedEVP_PKEY& pkey, 140 std::string* pkcs8) { 141 // Convert to PKCS#8 object. 142 ScopedPKCS8_PRIV_KEY_INFO p8_info(EVP_PKEY2PKCS8(pkey.get())); 143 if (!p8_info.get()) { 144 LOG(ERROR) << "Can't get PKCS#8 private key from EVP_PKEY: " 145 << GetOpenSSLErrorString(); 146 return false; 147 } 148 149 // Then convert it 150 int len = i2d_PKCS8_PRIV_KEY_INFO(p8_info.get(), NULL); 151 unsigned char* p = OpenSSLWriteInto(pkcs8, static_cast<size_t>(len)); 152 i2d_PKCS8_PRIV_KEY_INFO(p8_info.get(), &p); 153 return true; 154 } 155 156 bool ImportPrivateKeyFileAsPkcs8(const char* filename, 157 std::string* pkcs8) { 158 ScopedEVP_PKEY pkey(ImportPrivateKeyFile(filename)); 159 if (!pkey.get()) 160 return false; 161 return GetPrivateKeyPkcs8Bytes(pkey, pkcs8); 162 } 163 164 // Same as ImportPrivateKey, but for public ones. 165 EVP_PKEY* ImportPublicKeyFile(const char* filename) { 166 // Load file as PEM data. 167 base::FilePath certs_dir = GetTestCertsDirectory(); 168 base::FilePath file_path = certs_dir.AppendASCII(filename); 169 ScopedStdioHandle handle(base::OpenFile(file_path, "rb")); 170 if (!handle.get()) { 171 LOG(ERROR) << "Could not open public key file: " << filename; 172 return NULL; 173 } 174 EVP_PKEY* pkey = PEM_read_PUBKEY(handle.get(), NULL, NULL, NULL); 175 if (!pkey) { 176 LOG(ERROR) << "Could not load public key file: " << filename 177 << ", " << GetOpenSSLErrorString(); 178 return NULL; 179 } 180 return pkey; 181 } 182 183 // Retrieve a JNI local ref from encoded PKCS#8 data. 184 ScopedJava GetPKCS8PrivateKeyJava(PrivateKeyType key_type, 185 const std::string& pkcs8_key) { 186 JNIEnv* env = InitEnv(); 187 base::android::ScopedJavaLocalRef<jbyteArray> bytes( 188 base::android::ToJavaByteArray( 189 env, 190 reinterpret_cast<const uint8*>(pkcs8_key.data()), 191 pkcs8_key.size())); 192 193 ScopedJava key( 194 Java_AndroidKeyStoreTestUtil_createPrivateKeyFromPKCS8( 195 env, key_type, bytes.obj())); 196 197 return key; 198 } 199 200 const char kTestRsaKeyFile[] = "android-test-key-rsa.pem"; 201 202 // The RSA test hash must be 36 bytes exactly. 203 const char kTestRsaHash[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 204 205 // Retrieve a JNI local ref for our test RSA key. 206 ScopedJava GetRSATestKeyJava() { 207 std::string key; 208 if (!ImportPrivateKeyFileAsPkcs8(kTestRsaKeyFile, &key)) 209 return ScopedJava(); 210 return GetPKCS8PrivateKeyJava(PRIVATE_KEY_TYPE_RSA, key); 211 } 212 213 const char kTestDsaKeyFile[] = "android-test-key-dsa.pem"; 214 const char kTestDsaPublicKeyFile[] = "android-test-key-dsa-public.pem"; 215 216 // The DSA test hash must be 20 bytes exactly. 217 const char kTestDsaHash[] = "0123456789ABCDEFGHIJ"; 218 219 // Retrieve a JNI local ref for our test DSA key. 220 ScopedJava GetDSATestKeyJava() { 221 std::string key; 222 if (!ImportPrivateKeyFileAsPkcs8(kTestDsaKeyFile, &key)) 223 return ScopedJava(); 224 return GetPKCS8PrivateKeyJava(PRIVATE_KEY_TYPE_DSA, key); 225 } 226 227 // Call this function to verify that one message signed with our 228 // test DSA private key is correct. Since DSA signing introduces 229 // random elements in the signature, it is not possible to compare 230 // signature bits directly. However, one can use the public key 231 // to do the check. 232 bool VerifyTestDSASignature(const base::StringPiece& message, 233 const base::StringPiece& signature) { 234 ScopedEVP_PKEY pkey(ImportPublicKeyFile(kTestDsaPublicKeyFile)); 235 if (!pkey.get()) 236 return false; 237 238 ScopedDSA pub_key(EVP_PKEY_get1_DSA(pkey.get())); 239 if (!pub_key.get()) { 240 LOG(ERROR) << "Could not get DSA public key: " 241 << GetOpenSSLErrorString(); 242 return false; 243 } 244 245 const unsigned char* digest = 246 reinterpret_cast<const unsigned char*>(message.data()); 247 int digest_len = static_cast<int>(message.size()); 248 const unsigned char* sigbuf = 249 reinterpret_cast<const unsigned char*>(signature.data()); 250 int siglen = static_cast<int>(signature.size()); 251 252 int ret = DSA_verify( 253 0, digest, digest_len, sigbuf, siglen, pub_key.get()); 254 if (ret != 1) { 255 LOG(ERROR) << "DSA_verify() failed: " << GetOpenSSLErrorString(); 256 return false; 257 } 258 return true; 259 } 260 261 const char kTestEcdsaKeyFile[] = "android-test-key-ecdsa.pem"; 262 const char kTestEcdsaPublicKeyFile[] = "android-test-key-ecdsa-public.pem"; 263 264 // The test hash for ECDSA keys must be 20 bytes exactly. 265 const char kTestEcdsaHash[] = "0123456789ABCDEFGHIJ"; 266 267 // Retrieve a JNI local ref for our test ECDSA key. 268 ScopedJava GetECDSATestKeyJava() { 269 std::string key; 270 if (!ImportPrivateKeyFileAsPkcs8(kTestEcdsaKeyFile, &key)) 271 return ScopedJava(); 272 return GetPKCS8PrivateKeyJava(PRIVATE_KEY_TYPE_ECDSA, key); 273 } 274 275 // Call this function to verify that one message signed with our 276 // test DSA private key is correct. Since DSA signing introduces 277 // random elements in the signature, it is not possible to compare 278 // signature bits directly. However, one can use the public key 279 // to do the check. 280 bool VerifyTestECDSASignature(const base::StringPiece& message, 281 const base::StringPiece& signature) { 282 ScopedEVP_PKEY pkey(ImportPublicKeyFile(kTestEcdsaPublicKeyFile)); 283 if (!pkey.get()) 284 return false; 285 ScopedEC_KEY pub_key(EVP_PKEY_get1_EC_KEY(pkey.get())); 286 if (!pub_key.get()) { 287 LOG(ERROR) << "Could not get ECDSA public key: " 288 << GetOpenSSLErrorString(); 289 return false; 290 } 291 292 const unsigned char* digest = 293 reinterpret_cast<const unsigned char*>(message.data()); 294 int digest_len = static_cast<int>(message.size()); 295 const unsigned char* sigbuf = 296 reinterpret_cast<const unsigned char*>(signature.data()); 297 int siglen = static_cast<int>(signature.size()); 298 299 int ret = ECDSA_verify( 300 0, digest, digest_len, sigbuf, siglen, pub_key.get()); 301 if (ret != 1) { 302 LOG(ERROR) << "ECDSA_verify() failed: " << GetOpenSSLErrorString(); 303 return false; 304 } 305 return true; 306 } 307 308 // Sign a message with OpenSSL, return the result as a string. 309 // |message| is the message to be signed. 310 // |openssl_key| is an OpenSSL EVP_PKEY to use. 311 // |result| receives the result. 312 // Returns true on success, false otherwise. 313 bool SignWithOpenSSL(const base::StringPiece& message, 314 EVP_PKEY* openssl_key, 315 std::string* result) { 316 const unsigned char* digest = 317 reinterpret_cast<const unsigned char*>(message.data()); 318 unsigned int digest_len = static_cast<unsigned int>(message.size()); 319 std::string signature; 320 size_t signature_size; 321 size_t max_signature_size; 322 int key_type = EVP_PKEY_id(openssl_key); 323 switch (key_type) { 324 case EVP_PKEY_RSA: 325 { 326 ScopedRSA rsa(EVP_PKEY_get1_RSA(openssl_key)); 327 if (!rsa.get()) { 328 LOG(ERROR) << "Could not get RSA from EVP_PKEY: " 329 << GetOpenSSLErrorString(); 330 return false; 331 } 332 // With RSA, the signature will always be RSA_size() bytes. 333 max_signature_size = static_cast<size_t>(RSA_size(rsa.get())); 334 unsigned char* p = OpenSSLWriteInto(&signature, 335 max_signature_size); 336 unsigned int p_len = 0; 337 int ret = RSA_sign( 338 NID_md5_sha1, digest, digest_len, p, &p_len, rsa.get()); 339 if (ret != 1) { 340 LOG(ERROR) << "RSA_sign() failed: " << GetOpenSSLErrorString(); 341 return false; 342 } 343 signature_size = static_cast<size_t>(p_len); 344 break; 345 } 346 case EVP_PKEY_DSA: 347 { 348 ScopedDSA dsa(EVP_PKEY_get1_DSA(openssl_key)); 349 if (!dsa.get()) { 350 LOG(ERROR) << "Could not get DSA from EVP_PKEY: " 351 << GetOpenSSLErrorString(); 352 return false; 353 } 354 // Note, the actual signature can be smaller than DSA_size() 355 max_signature_size = static_cast<size_t>(DSA_size(dsa.get())); 356 unsigned char* p = OpenSSLWriteInto(&signature, 357 max_signature_size); 358 unsigned int p_len = 0; 359 // Note: first parameter is ignored by function. 360 int ret = DSA_sign(0, digest, digest_len, p, &p_len, dsa.get()); 361 if (ret != 1) { 362 LOG(ERROR) << "DSA_sign() failed: " << GetOpenSSLErrorString(); 363 return false; 364 } 365 signature_size = static_cast<size_t>(p_len); 366 break; 367 } 368 case EVP_PKEY_EC: 369 { 370 ScopedEC_KEY ecdsa(EVP_PKEY_get1_EC_KEY(openssl_key)); 371 if (!ecdsa.get()) { 372 LOG(ERROR) << "Could not get EC_KEY from EVP_PKEY: " 373 << GetOpenSSLErrorString(); 374 return false; 375 } 376 // Note, the actual signature can be smaller than ECDSA_size() 377 max_signature_size = ECDSA_size(ecdsa.get()); 378 unsigned char* p = OpenSSLWriteInto(&signature, 379 max_signature_size); 380 unsigned int p_len = 0; 381 // Note: first parameter is ignored by function. 382 int ret = ECDSA_sign( 383 0, digest, digest_len, p, &p_len, ecdsa.get()); 384 if (ret != 1) { 385 LOG(ERROR) << "ECDSA_sign() fialed: " << GetOpenSSLErrorString(); 386 return false; 387 } 388 signature_size = static_cast<size_t>(p_len); 389 break; 390 } 391 default: 392 LOG(WARNING) << "Invalid OpenSSL key type: " << key_type; 393 return false; 394 } 395 396 if (signature_size == 0) { 397 LOG(ERROR) << "Signature is empty!"; 398 return false; 399 } 400 if (signature_size > max_signature_size) { 401 LOG(ERROR) << "Signature size mismatch, actual " << signature_size 402 << ", expected <= " << max_signature_size; 403 return false; 404 } 405 signature.resize(signature_size); 406 result->swap(signature); 407 return true; 408 } 409 410 // Check that a generated signature for a given message matches 411 // OpenSSL output byte-by-byte. 412 // |message| is the input message. 413 // |signature| is the generated signature for the message. 414 // |openssl_key| is a raw EVP_PKEY for the same private key than the 415 // one which was used to generate the signature. 416 // Returns true on success, false otherwise. 417 bool CompareSignatureWithOpenSSL(const base::StringPiece& message, 418 const base::StringPiece& signature, 419 EVP_PKEY* openssl_key) { 420 std::string openssl_signature; 421 SignWithOpenSSL(message, openssl_key, &openssl_signature); 422 423 if (signature.size() != openssl_signature.size()) { 424 LOG(ERROR) << "Signature size mismatch, actual " 425 << signature.size() << ", expected " 426 << openssl_signature.size(); 427 return false; 428 } 429 for (size_t n = 0; n < signature.size(); ++n) { 430 if (openssl_signature[n] != signature[n]) { 431 LOG(ERROR) << "Signature byte mismatch at index " << n 432 << "actual " << signature[n] << ", expected " 433 << openssl_signature[n]; 434 LOG(ERROR) << "Actual signature : " 435 << base::HexEncode(signature.data(), signature.size()); 436 LOG(ERROR) << "Expected signature: " 437 << base::HexEncode(openssl_signature.data(), 438 openssl_signature.size()); 439 return false; 440 } 441 } 442 return true; 443 } 444 445 // Sign a message with our platform API. 446 // 447 // |android_key| is a JNI reference to the platform PrivateKey object. 448 // |openssl_key| is a pointer to an OpenSSL key object for the exact 449 // same key content. 450 // |message| is a message. 451 // |result| will receive the result. 452 void DoKeySigning(jobject android_key, 453 EVP_PKEY* openssl_key, 454 const base::StringPiece& message, 455 std::string* result) { 456 // First, get the platform signature. 457 std::vector<uint8> android_signature; 458 ASSERT_TRUE( 459 RawSignDigestWithPrivateKey(android_key, 460 message, 461 &android_signature)); 462 463 result->assign( 464 reinterpret_cast<const char*>(&android_signature[0]), 465 android_signature.size()); 466 } 467 468 // Sign a message with our OpenSSL EVP_PKEY wrapper around platform 469 // APIS. 470 // 471 // |android_key| is a JNI reference to the platform PrivateKey object. 472 // |openssl_key| is a pointer to an OpenSSL key object for the exact 473 // same key content. 474 // |message| is a message. 475 // |result| will receive the result. 476 void DoKeySigningWithWrapper(EVP_PKEY* wrapper_key, 477 EVP_PKEY* openssl_key, 478 const base::StringPiece& message, 479 std::string* result) { 480 // First, get the platform signature. 481 std::string wrapper_signature; 482 SignWithOpenSSL(message, wrapper_key, &wrapper_signature); 483 ASSERT_NE(0U, wrapper_signature.size()); 484 485 result->assign( 486 reinterpret_cast<const char*>(&wrapper_signature[0]), 487 wrapper_signature.size()); 488 } 489 490 } // namespace 491 492 TEST(AndroidKeyStore,GetRSAKeyModulus) { 493 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); 494 InitEnv(); 495 496 // Load the test RSA key. 497 ScopedEVP_PKEY pkey(ImportPrivateKeyFile(kTestRsaKeyFile)); 498 ASSERT_TRUE(pkey.get()); 499 500 // Convert it to encoded PKCS#8 bytes. 501 std::string pkcs8_data; 502 ASSERT_TRUE(GetPrivateKeyPkcs8Bytes(pkey, &pkcs8_data)); 503 504 // Create platform PrivateKey object from it. 505 ScopedJava key_java = GetPKCS8PrivateKeyJava(PRIVATE_KEY_TYPE_RSA, 506 pkcs8_data); 507 ASSERT_FALSE(key_java.is_null()); 508 509 // Retrieve the corresponding modulus through JNI 510 std::vector<uint8> modulus_java; 511 ASSERT_TRUE(GetRSAKeyModulus(key_java.obj(), &modulus_java)); 512 513 // Create an OpenSSL BIGNUM from it. 514 ScopedBIGNUM bn( 515 BN_bin2bn( 516 reinterpret_cast<const unsigned char*>(&modulus_java[0]), 517 static_cast<int>(modulus_java.size()), 518 NULL)); 519 ASSERT_TRUE(bn.get()); 520 521 // Compare it to the one in the RSA key, they must be identical. 522 ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey.get())); 523 ASSERT_TRUE(rsa.get()) << GetOpenSSLErrorString(); 524 525 ASSERT_EQ(0, BN_cmp(bn.get(), rsa.get()->n)); 526 } 527 528 TEST(AndroidKeyStore,GetDSAKeyParamQ) { 529 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); 530 InitEnv(); 531 532 // Load the test DSA key. 533 ScopedEVP_PKEY pkey(ImportPrivateKeyFile(kTestDsaKeyFile)); 534 ASSERT_TRUE(pkey.get()); 535 536 // Convert it to encoded PKCS#8 bytes. 537 std::string pkcs8_data; 538 ASSERT_TRUE(GetPrivateKeyPkcs8Bytes(pkey, &pkcs8_data)); 539 540 // Create platform PrivateKey object from it. 541 ScopedJava key_java = GetPKCS8PrivateKeyJava(PRIVATE_KEY_TYPE_DSA, 542 pkcs8_data); 543 ASSERT_FALSE(key_java.is_null()); 544 545 // Retrieve the corresponding Q parameter through JNI 546 std::vector<uint8> q_java; 547 ASSERT_TRUE(GetDSAKeyParamQ(key_java.obj(), &q_java)); 548 549 // Create an OpenSSL BIGNUM from it. 550 ScopedBIGNUM bn( 551 BN_bin2bn( 552 reinterpret_cast<const unsigned char*>(&q_java[0]), 553 static_cast<int>(q_java.size()), 554 NULL)); 555 ASSERT_TRUE(bn.get()); 556 557 // Compare it to the one in the RSA key, they must be identical. 558 ScopedDSA dsa(EVP_PKEY_get1_DSA(pkey.get())); 559 ASSERT_TRUE(dsa.get()) << GetOpenSSLErrorString(); 560 561 ASSERT_EQ(0, BN_cmp(bn.get(), dsa.get()->q)); 562 } 563 564 TEST(AndroidKeyStore,GetPrivateKeyTypeRSA) { 565 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); 566 567 ScopedJava rsa_key = GetRSATestKeyJava(); 568 ASSERT_FALSE(rsa_key.is_null()); 569 EXPECT_EQ(PRIVATE_KEY_TYPE_RSA, 570 GetPrivateKeyType(rsa_key.obj())); 571 } 572 573 TEST(AndroidKeyStore,SignWithPrivateKeyRSA) { 574 ScopedJava rsa_key = GetRSATestKeyJava(); 575 ASSERT_FALSE(rsa_key.is_null()); 576 577 if (IsOnAndroidOlderThan_4_2()) { 578 LOG(INFO) << "This test can't run on Android < 4.2"; 579 return; 580 } 581 582 ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestRsaKeyFile)); 583 ASSERT_TRUE(openssl_key.get()); 584 585 std::string message = kTestRsaHash; 586 ASSERT_EQ(36U, message.size()); 587 588 std::string signature; 589 DoKeySigning(rsa_key.obj(), openssl_key.get(), message, &signature); 590 ASSERT_TRUE( 591 CompareSignatureWithOpenSSL(message, signature, openssl_key.get())); 592 // All good. 593 } 594 595 TEST(AndroidKeyStore,SignWithWrapperKeyRSA) { 596 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 597 598 ScopedJava rsa_key = GetRSATestKeyJava(); 599 ASSERT_FALSE(rsa_key.is_null()); 600 601 ScopedEVP_PKEY wrapper_key(GetOpenSSLPrivateKeyWrapper(rsa_key.obj())); 602 ASSERT_TRUE(wrapper_key.get() != NULL); 603 604 ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestRsaKeyFile)); 605 ASSERT_TRUE(openssl_key.get()); 606 607 // Check that RSA_size() works properly on the wrapper key. 608 EXPECT_EQ(EVP_PKEY_size(openssl_key.get()), 609 EVP_PKEY_size(wrapper_key.get())); 610 611 // Message size must be 36 for RSA_sign(NID_md5_sha1,...) to return 612 // without an error. 613 std::string message = kTestRsaHash; 614 ASSERT_EQ(36U, message.size()); 615 616 std::string signature; 617 DoKeySigningWithWrapper(wrapper_key.get(), 618 openssl_key.get(), 619 message, 620 &signature); 621 ASSERT_TRUE( 622 CompareSignatureWithOpenSSL(message, signature, openssl_key.get())); 623 } 624 625 TEST(AndroidKeyStore,GetPrivateKeyTypeDSA) { 626 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); 627 628 ScopedJava dsa_key = GetDSATestKeyJava(); 629 ASSERT_FALSE(dsa_key.is_null()); 630 EXPECT_EQ(PRIVATE_KEY_TYPE_DSA, 631 GetPrivateKeyType(dsa_key.obj())); 632 } 633 634 TEST(AndroidKeyStore,SignWithPrivateKeyDSA) { 635 ScopedJava dsa_key = GetDSATestKeyJava(); 636 ASSERT_FALSE(dsa_key.is_null()); 637 638 ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestDsaKeyFile)); 639 ASSERT_TRUE(openssl_key.get()); 640 641 std::string message = kTestDsaHash; 642 ASSERT_EQ(20U, message.size()); 643 644 std::string signature; 645 DoKeySigning(dsa_key.obj(), openssl_key.get(), message, &signature); 646 ASSERT_TRUE(VerifyTestDSASignature(message, signature)); 647 } 648 649 TEST(AndroidKeyStore,SignWithWrapperKeyDSA) { 650 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 651 652 ScopedJava dsa_key = GetDSATestKeyJava(); 653 ASSERT_FALSE(dsa_key.is_null()); 654 655 ScopedEVP_PKEY wrapper_key( 656 GetOpenSSLPrivateKeyWrapper(dsa_key.obj())); 657 ASSERT_TRUE(wrapper_key.get()); 658 659 ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestDsaKeyFile)); 660 ASSERT_TRUE(openssl_key.get()); 661 662 // Check that DSA_size() works correctly on the wrapper. 663 EXPECT_EQ(EVP_PKEY_size(openssl_key.get()), 664 EVP_PKEY_size(wrapper_key.get())); 665 666 std::string message = kTestDsaHash; 667 std::string signature; 668 DoKeySigningWithWrapper(wrapper_key.get(), 669 openssl_key.get(), 670 message, 671 &signature); 672 ASSERT_TRUE(VerifyTestDSASignature(message, signature)); 673 } 674 675 TEST(AndroidKeyStore,GetPrivateKeyTypeECDSA) { 676 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); 677 678 ScopedJava ecdsa_key = GetECDSATestKeyJava(); 679 ASSERT_FALSE(ecdsa_key.is_null()); 680 EXPECT_EQ(PRIVATE_KEY_TYPE_ECDSA, 681 GetPrivateKeyType(ecdsa_key.obj())); 682 } 683 684 TEST(AndroidKeyStore,SignWithPrivateKeyECDSA) { 685 ScopedJava ecdsa_key = GetECDSATestKeyJava(); 686 ASSERT_FALSE(ecdsa_key.is_null()); 687 688 ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestEcdsaKeyFile)); 689 ASSERT_TRUE(openssl_key.get()); 690 691 std::string message = kTestEcdsaHash; 692 std::string signature; 693 DoKeySigning(ecdsa_key.obj(), openssl_key.get(), message, &signature); 694 ASSERT_TRUE(VerifyTestECDSASignature(message, signature)); 695 } 696 697 TEST(AndroidKeyStore, SignWithWrapperKeyECDSA) { 698 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 699 700 ScopedJava ecdsa_key = GetECDSATestKeyJava(); 701 ASSERT_FALSE(ecdsa_key.is_null()); 702 703 ScopedEVP_PKEY wrapper_key( 704 GetOpenSSLPrivateKeyWrapper(ecdsa_key.obj())); 705 ASSERT_TRUE(wrapper_key.get()); 706 707 ScopedEVP_PKEY openssl_key(ImportPrivateKeyFile(kTestEcdsaKeyFile)); 708 ASSERT_TRUE(openssl_key.get()); 709 710 // Check that ECDSA size works correctly on the wrapper. 711 EXPECT_EQ(EVP_PKEY_size(openssl_key.get()), 712 EVP_PKEY_size(wrapper_key.get())); 713 714 std::string message = kTestEcdsaHash; 715 std::string signature; 716 DoKeySigningWithWrapper(wrapper_key.get(), 717 openssl_key.get(), 718 message, 719 &signature); 720 ASSERT_TRUE(VerifyTestECDSASignature(message, signature)); 721 } 722 723 } // namespace android 724 } // namespace net 725