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

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: fix typo 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 // With RSA, the signature will always be RSA_size() bytes.
320 openssl_signature.resize(static_cast<size_t>(RSA_size(rsa.get())));
321 unsigned char* p =
322 reinterpret_cast<unsigned char*>(&openssl_signature[0]);
323 unsigned int p_len = 0;
324 int ret = RSA_sign(
325 NID_md5_sha1, digest, digest_len, p, &p_len, rsa.get());
326 ASSERT_EQ(1, ret) << GetOpenSSLErrorString();
327 ASSERT_EQ(static_cast<size_t>(p_len), openssl_signature.size());
328 }
329 break;
330 case EVP_PKEY_DSA:
331 {
332 ScopedDSA dsa(EVP_PKEY_get1_DSA(openssl_key));
333 ASSERT_TRUE(dsa.get());
334 // Note, the actual signature can be smaller than DSA_size()
335 openssl_signature.resize(
336 static_cast<size_t>(DSA_size(dsa.get())));
337 unsigned char* p =
338 reinterpret_cast<unsigned char*>(&openssl_signature[0]);
339 unsigned int p_len = 0;
340 // Note: first parameter is ignored by function.
341 int ret = DSA_sign(0, digest, digest_len, p, &p_len, dsa.get());
342 ASSERT_EQ(1, ret) << GetOpenSSLErrorString();
343 ASSERT_LT(0U, p_len);
344 ASSERT_LE(static_cast<size_t>(p_len), openssl_signature.size());
345 openssl_signature.resize(static_cast<size_t>(p_len));
346 }
347 break;
348 case EVP_PKEY_EC:
349 {
350 ScopedEC_KEY ecdsa(EVP_PKEY_get1_EC_KEY(openssl_key));
351 ASSERT_TRUE(ecdsa.get());
352 // Note, the actual signature can be smaller than ECDSA_size()
353 openssl_signature.resize(ECDSA_size(ecdsa.get()));
354 unsigned char* p =
355 reinterpret_cast<unsigned char*>(&openssl_signature[0]);
356 unsigned int p_len = 0;
357 // Note: first parameter is ignored by function.
358 int ret = ECDSA_sign(
359 0, digest, digest_len, p, &p_len, ecdsa.get());
360 ASSERT_EQ(1, ret) << GetOpenSSLErrorString();
361 ASSERT_LT(0U, p_len);
362 ASSERT_LE(static_cast<size_t>(p_len), openssl_signature.size());
363 openssl_signature.resize(static_cast<size_t>(p_len));
364 }
365 break;
366 default:
367 LOG(WARNING) << "Invalid OpenSSL key type: " << key_type;
368 return;
369 }
370 result->assign(reinterpret_cast<const char*>(&openssl_signature[0]),
371 openssl_signature.size());
372 }
373
374 // Check that a generated signature for a given message matches
375 // OpenSSL output byte-by-byte.
376 // |message| is the input message.
377 // |signature| is the generated signature for the message.
378 // |openssl_key| is a raw EVP_PKEY for the same private key than the
379 // one which was used to generate the signature.
380 void CompareSignatureWithOpenSSL(const base::StringPiece& message,
381 const base::StringPiece& signature,
382 EVP_PKEY* openssl_key) {
383 std::string openssl_signature;
384 SignWithOpenSSL(message, openssl_key, &openssl_signature);
385
386 ASSERT_EQ(signature.size(), openssl_signature.size());
387 for (size_t n = 0; n < signature.size(); ++n)
388 ASSERT_EQ(openssl_signature[n], signature[n]);
389
390 // All good, just exit.
391 }
392
393 // Sign a message with our platform API.
394 //
395 // |android_key| is a JNI reference to the platform PrivateKey object.
396 // |openssl_key| is a pointer to an OpenSSL key object for the exact
397 // same key content.
398 // |message| is a message.
399 // |result| will receive the result.
400 void DoKeySigning(jobject android_key,
401 EVP_PKEY* openssl_key,
402 const base::StringPiece& message,
403 std::string* result) {
404 // First, get the platform signature.
405 std::vector<uint8> android_signature;
406 ASSERT_TRUE(
407 RawSignDigestWithPrivateKey(android_key,
408 message,
409 &android_signature));
410
411 result->assign(
412 reinterpret_cast<const char*>(&android_signature[0]),
413 android_signature.size());
414 }
415
416 // Sign a message with our OpenSSL EVP_PKEY wrapper around platform
417 // APIS.
418 //
419 // |android_key| is a JNI reference to the platform PrivateKey object.
420 // |openssl_key| is a pointer to an OpenSSL key object for the exact
421 // same key content.
422 // |message| is a message.
423 // |result| will receive the result.
424 void DoKeySigningWithWrapper(EVP_PKEY* wrapper_key,
425 EVP_PKEY* openssl_key,
426 const base::StringPiece& message,
427 std::string* result) {
428 // First, get the platform signature.
429 std::string wrapper_signature;
430 SignWithOpenSSL(message, wrapper_key, &wrapper_signature);
431 ASSERT_NE(0U, wrapper_signature.size());
432
433 result->assign(
434 reinterpret_cast<const char*>(&wrapper_signature[0]),
435 wrapper_signature.size());
436 }
437
438 } // namespace
439
440 TEST(AndroidKeyStore,GetRSAKeyModulus) {
441 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE);
442 InitEnv();
443
444 // Load the test RSA key.
445 ScopedEVP_PKEY pkey(NULL);
446 ImportPrivateKeyFile(kTestRsaKeyFile, pkey);
447
448 // Convert it to encoded PKCS#8 bytes.
449 std::string pkcs8_data;
450 GetPrivateKeyPkcs8Bytes(pkey, &pkcs8_data);
451
452 // Create platform PrivateKey object from it.
453 ScopedJavaLocalRef<jobject> key_java = GetPKCS8PrivateKeyJava(
454 PRIVATE_KEY_TYPE_RSA, pkcs8_data);
455 ASSERT_FALSE(key_java.is_null());
456
457 // Retrieve the corresponding modulus through JNI
458 std::vector<uint8> modulus_java;
459 ASSERT_TRUE(GetRSAKeyModulus(key_java.obj(), &modulus_java));
460
461 // Create an OpenSSL BIGNUM from it.
462 ScopedBIGNUM bn(
463 BN_bin2bn(
464 reinterpret_cast<const unsigned char*>(&modulus_java[0]),
465 static_cast<int>(modulus_java.size()),
466 NULL));
467 ASSERT_TRUE(bn.get());
468
469 // Compare it to the one in the RSA key, they must be identical.
470 ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey.get()));
471 ASSERT_TRUE(rsa.get()) << GetOpenSSLErrorString();
472
473 ASSERT_EQ(0, BN_cmp(bn.get(), rsa.get()->n));
474 }
475
476 TEST(AndroidKeyStore,GetDSAKeyParamQ) {
477 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE);
478 InitEnv();
479
480 // Load the test DSA key.
481 ScopedEVP_PKEY pkey(NULL);
482 ImportPrivateKeyFile(kTestDsaKeyFile, pkey);
483
484 // Convert it to encoded PKCS#8 bytes.
485 std::string pkcs8_data;
486 GetPrivateKeyPkcs8Bytes(pkey, &pkcs8_data);
487
488 // Create platform PrivateKey object from it.
489 ScopedJavaLocalRef<jobject> key_java = GetPKCS8PrivateKeyJava(
490 PRIVATE_KEY_TYPE_DSA, pkcs8_data);
491 ASSERT_FALSE(key_java.is_null());
492
493 // Retrieve the corresponding Q parameter through JNI
494 std::vector<uint8> q_java;
495 ASSERT_TRUE(GetDSAKeyParamQ(key_java.obj(), &q_java));
496
497 // Create an OpenSSL BIGNUM from it.
498 ScopedBIGNUM bn(
499 BN_bin2bn(
500 reinterpret_cast<const unsigned char*>(&q_java[0]),
501 static_cast<int>(q_java.size()),
502 NULL));
503 ASSERT_TRUE(bn.get());
504
505 // Compare it to the one in the RSA key, they must be identical.
506 ScopedDSA dsa(EVP_PKEY_get1_DSA(pkey.get()));
507 ASSERT_TRUE(dsa.get()) << GetOpenSSLErrorString();
508
509 ASSERT_EQ(0, BN_cmp(bn.get(), dsa.get()->q));
510 }
511
512 TEST(AndroidKeyStore,GetPrivateKeyTypeRSA) {
513 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE);
514
515 ScopedJavaLocalRef<jobject> rsa_key = GetRSATestKeyJava();
516 ASSERT_FALSE(rsa_key.is_null());
517 EXPECT_EQ(PRIVATE_KEY_TYPE_RSA,
518 GetPrivateKeyType(rsa_key.obj()));
519 }
520
521 TEST(AndroidKeyStore,SignWithPrivateKeyRSA) {
522 ScopedJavaLocalRef<jobject> rsa_key = GetRSATestKeyJava();
523 ASSERT_FALSE(rsa_key.is_null());
524
525 if (IsOnAndroidOlderThan_4_2()) {
526 LOG(INFO) << "This test can't run on Android < 4.2";
527 return;
528 }
529
530 ScopedEVP_PKEY openssl_key;
531 ImportPrivateKeyFile(kTestRsaKeyFile, openssl_key);
532
533 std::string message = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
534 ASSERT_EQ(36U, message.size());
535
536 std::string signature;
537 DoKeySigning(rsa_key.obj(), openssl_key.get(), message, &signature);
538 CompareSignatureWithOpenSSL(message, signature, openssl_key.get());
539 // All good.
540 }
541
542 TEST(AndroidKeyStore,SignWithWrapperKeyRSA) {
543 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
544
545 ScopedJavaLocalRef<jobject> rsa_key = GetRSATestKeyJava();
546 ASSERT_FALSE(rsa_key.is_null());
547
548 ScopedEVP_PKEY wrapper_key(GetOpenSSLPrivateKeyWrapper(rsa_key.obj()));
549 ASSERT_TRUE(wrapper_key.get() != NULL);
550
551 ScopedEVP_PKEY openssl_key;
552 ImportPrivateKeyFile(kTestRsaKeyFile, openssl_key);
553
554 // Check that RSA_size() works properly on the wrapper key.
555 EXPECT_EQ(EVP_PKEY_size(openssl_key.get()),
556 EVP_PKEY_size(wrapper_key.get()));
557
558 // Message size must be 36 for RSA_sign(NID_md5_sha1,...) to return
559 // without an error.
560 std::string message = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
561 ASSERT_EQ(36U, message.size());
562
563 std::string signature;
564 DoKeySigningWithWrapper(wrapper_key.get(),
565 openssl_key.get(),
566 message,
567 &signature);
568 CompareSignatureWithOpenSSL(message, signature, openssl_key.get());
569 // All good.
570 }
571
572 TEST(AndroidKeyStore,GetPrivateKeyTypeDSA) {
573 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE);
574
575 ScopedJavaLocalRef<jobject> dsa_key = GetDSATestKeyJava();
576 ASSERT_FALSE(dsa_key.is_null());
577 EXPECT_EQ(PRIVATE_KEY_TYPE_DSA,
578 GetPrivateKeyType(dsa_key.obj()));
579 }
580
581 TEST(AndroidKeyStore,SignWithPrivateKeyDSA) {
582 ScopedJavaLocalRef<jobject> dsa_key = GetDSATestKeyJava();
583 ASSERT_FALSE(dsa_key.is_null());
584
585 ScopedEVP_PKEY openssl_key;
586 ImportPrivateKeyFile(kTestDsaKeyFile, openssl_key);
587
588 std::string message = "0123456789ABCDEFGHIJ";
589 ASSERT_EQ(20U, message.size());
590
591 std::string signature;
592 DoKeySigning(dsa_key.obj(), openssl_key.get(), message, &signature);
593 VerifyTestDSASignature(message, signature);
594 // All good.
595 }
596
597 TEST(AndroidKeyStore,SignWithWrapperKeyDSA) {
598 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
599
600 ScopedJavaLocalRef<jobject> dsa_key = GetDSATestKeyJava();
601 ASSERT_FALSE(dsa_key.is_null());
602
603 ScopedEVP_PKEY wrapper_key(
604 GetOpenSSLPrivateKeyWrapper(dsa_key.obj()));
605 ASSERT_TRUE(wrapper_key.get() != NULL);
606
607 ScopedEVP_PKEY openssl_key;
608 ImportPrivateKeyFile(kTestDsaKeyFile, openssl_key);
609
610 // Check that DSA_size() works correctly on the wrapper.
611 EXPECT_EQ(EVP_PKEY_size(openssl_key.get()),
612 EVP_PKEY_size(wrapper_key.get()));
613
614 std::string message = "0123456789ABCDEFGHIJ";
615 std::string signature;
616 DoKeySigningWithWrapper(wrapper_key.get(),
617 openssl_key.get(),
618 message,
619 &signature);
620 VerifyTestDSASignature(message, signature);
621 // All good.
622 }
623
624 TEST(AndroidKeyStore,GetPrivateKeyTypeECDSA) {
625 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE);
626
627 ScopedJavaLocalRef<jobject> ecdsa_key = GetECDSATestKeyJava();
628 ASSERT_FALSE(ecdsa_key.is_null());
629 EXPECT_EQ(PRIVATE_KEY_TYPE_ECDSA,
630 GetPrivateKeyType(ecdsa_key.obj()));
631 }
632
633 TEST(AndroidKeyStore,SignWithPrivateKeyECDSA) {
634 ScopedJavaLocalRef<jobject> ecdsa_key = GetECDSATestKeyJava();
635 ASSERT_FALSE(ecdsa_key.is_null());
636
637 ScopedEVP_PKEY openssl_key;
638 ImportPrivateKeyFile(kTestEcdsaKeyFile, openssl_key);
639
640 std::string message = "0123456789ABCDEFGHIJ";
641 std::string signature;
642 DoKeySigning(ecdsa_key.obj(), openssl_key.get(), message, &signature);
643 VerifyTestECDSASignature(message, signature);
644 // All good.
645 }
646
647 TEST(AndroidKeyStore, SignWithWrapperKeyECDSA) {
648 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
649
650 ScopedJavaLocalRef<jobject> ecdsa_key = GetECDSATestKeyJava();
651 ASSERT_FALSE(ecdsa_key.is_null());
652
653 ScopedEVP_PKEY wrapper_key(
654 GetOpenSSLPrivateKeyWrapper(ecdsa_key.obj()));
655 ASSERT_TRUE(wrapper_key.get() != NULL);
656
657 ScopedEVP_PKEY openssl_key;
658 ImportPrivateKeyFile(kTestEcdsaKeyFile, openssl_key);
659
660 // Check that ECDSA size works correctly on the wrapper.
661 EXPECT_EQ(EVP_PKEY_size(openssl_key.get()),
662 EVP_PKEY_size(wrapper_key.get()));
663
664 std::string message = "0123456789ABCDEFGHIJ";
665 std::string signature;
666 DoKeySigningWithWrapper(wrapper_key.get(),
667 openssl_key.get(),
668 message,
669 &signature);
670 VerifyTestECDSASignature(message, signature);
671 // All good.
672 }
673
674 } // namespace android
675 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698