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