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

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

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

Powered by Google App Engine
This is Rietveld 408576698