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

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: address marcus' nits. 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
« no previous file with comments | « net/android/keystore_openssl.cc ('k') | net/android/net_jni_registrar.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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_path.h"
23 #include "base/file_util.h"
24 #include "base/memory/scoped_handle.h"
25 #include "base/string_util.h"
26 #include "base/strings/string_number_conversions.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 FilePath certs_dir = GetTestCertsDirectory();
119 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 FilePath certs_dir = GetTestCertsDirectory();
169 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
OLDNEW
« no previous file with comments | « net/android/keystore_openssl.cc ('k') | net/android/net_jni_registrar.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698