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(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