OLD | NEW |
---|---|
(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/dsa.h> | |
6 #include <openssl/ecdsa.h> | |
7 #include <openssl/err.h> | |
8 #include <openssl/evp.h> | |
9 #include <openssl/rsa.h> | |
10 #include <openssl/x509.h> | |
11 | |
12 #include "base/android/build_info.h" | |
13 #include "base/android/jni_android.h" | |
14 #include "base/android/jni_array.h" | |
15 #include "base/android/scoped_java_ref.h" | |
16 #include "base/basictypes.h" | |
17 #include "base/bind.h" | |
18 #include "base/callback.h" | |
19 #include "base/compiler_specific.h" | |
20 #include "base/file_path.h" | |
21 #include "base/file_util.h" | |
22 #include "crypto/openssl_util.h" | |
23 #include "jni/AndroidKeyStoreTestUtil_jni.h" | |
24 #include "net/android/keystore.h" | |
25 #include "net/android/keystore_openssl.h" | |
26 #include "net/base/test_data_directory.h" | |
27 #include "testing/gtest/include/gtest/gtest.h" | |
28 | |
29 using base::android::AttachCurrentThread; | |
30 using base::android::ScopedJavaLocalRef; | |
31 using base::android::ToJavaByteArray; | |
32 | |
33 // Technical note: | |
34 // | |
35 // This source file not only checks that signing with SignWithPrivateKey() | |
36 // works correctly, it also verifies that the generated signature matches | |
37 // 100% of what OpenSSL generates when calling RSA_sign(NID_md5_sha1,...), | |
38 // DSA_sign(0, ...) or ECDSA_sign(0, ...). | |
39 // | |
40 // That's crucial to ensure that this function can later be used to | |
41 // implement client certificate support. More specifically, that it is | |
42 // possible to create a custom EVP_PKEY that uses SignWithPrivateKey() | |
43 // internally to perform RSA/DSA/ECDSA signing, as invoked by the | |
44 // OpenSSL code at ssl/s3_clnt.c:ssl3_send_client_verify(). | |
45 // | |
46 // Finally, it also checks that using the EVP_PKEY generated with | |
47 // GetOpenSSLPrivateKeyWrapper() works correctly. | |
48 // | |
49 | |
50 namespace net { | |
51 namespace android { | |
52 | |
53 namespace { | |
54 | |
55 JNIEnv* InitEnv() { | |
56 JNIEnv* env = AttachCurrentThread(); | |
57 static bool inited = false; | |
58 if (!inited) { | |
59 RegisterNativesImpl(env); | |
60 inited = true; | |
61 } | |
62 return env; | |
63 } | |
64 | |
65 // Returns true if running on an Android version older than 4.2 | |
66 bool IsOnAndroidOlderThan_4_2(void) { | |
67 const int kAndroid42ApiLevel = 17; | |
68 int level = base::android::BuildInfo::GetInstance()->sdk_int(); | |
69 return level < kAndroid42ApiLevel; | |
70 } | |
71 | |
72 // Implements the callback expected by ERR_print_errors_cb(). | |
73 // used by GetOpenSSLErrorString below. | |
74 int openssl_print_error_callback(const char* msg, size_t msglen, void* u) { | |
75 std::string* result = reinterpret_cast<std::string*>(u); | |
76 result->append(msg, msglen); | |
77 return 1; | |
78 } | |
79 | |
80 // Retrieves the OpenSSL error as a string | |
81 std::string GetOpenSSLErrorString(void) { | |
82 std::string result; | |
83 ERR_print_errors_cb(openssl_print_error_callback, &result); | |
84 return result; | |
85 } | |
86 | |
87 // Retrieve a JNI local ref from encoded PKCS#8 data. | |
88 ScopedJavaLocalRef<jobject> GetPKCS8PrivateKey( | |
89 PrivateKeyType key_type, | |
90 const std::string& pkcs8_key) { | |
91 JNIEnv* env = InitEnv(); | |
92 ScopedJavaLocalRef<jbyteArray> bytes( | |
93 ToJavaByteArray(env, | |
94 reinterpret_cast<const uint8*>(pkcs8_key.data()), | |
95 pkcs8_key.size())); | |
96 | |
97 ScopedJavaLocalRef<jobject> key( | |
98 Java_AndroidKeyStoreTestUtil_createPrivateKeyFromPKCS8( | |
99 env, key_type, bytes.obj())); | |
100 | |
101 return key; | |
102 } | |
103 | |
104 // Create an OpenSSL EVP_PKEY object from a PKCS#8 in-memory content. | |
105 EVP_PKEY* GetOpenSSLPKCS8PrivateKey(int type, const std::string& key) { | |
106 const unsigned char* p = | |
107 reinterpret_cast<const unsigned char*>(key.data()); | |
108 long p_length = static_cast<long>(key.size()); | |
109 return d2i_PrivateKey(type, NULL, &p, p_length); | |
110 } | |
111 | |
112 // Load a given key file into a string. Assert on error. | |
113 // |filename| is the key file name. | |
114 // |bytes| will receive the raw key data. | |
115 void ImportKeyFile(const char* filename, | |
116 std::string& bytes) { | |
117 FilePath certs_dir = GetTestCertsDirectory(); | |
118 FilePath file_path = certs_dir.AppendASCII(filename); | |
119 ASSERT_TRUE(file_util::ReadFileToString(file_path, &bytes)) << | |
120 "Could not load key file: " << filename; | |
121 } | |
122 | |
123 const char kTestRsaKeyFile[] = "android-test-key-rsa.pkcs8"; | |
124 | |
125 // Retrieve a JNI local ref for our test RSA key. | |
126 ScopedJavaLocalRef<jobject> GetRSATestKey() { | |
127 std::string key; | |
128 ImportKeyFile(kTestRsaKeyFile, key); | |
129 return GetPKCS8PrivateKey(PRIVATE_KEY_TYPE_RSA, key); | |
130 } | |
131 | |
132 // Retrieve the OpenSSL object for our test RSA key. | |
133 EVP_PKEY* GetRSATestKeyOpenSSL() { | |
134 std::string key; | |
135 ImportKeyFile(kTestRsaKeyFile, key); | |
136 return GetOpenSSLPKCS8PrivateKey(EVP_PKEY_RSA, key); | |
137 } | |
138 | |
139 const char kTestDsaKeyFile[] = "android-test-key-dsa.pkcs8"; | |
140 const char kTestDsaPublicKeyFile[] = "android-test-key-dsa-public.der"; | |
141 | |
142 // Retrieve a JNI local ref for our test DSA key. | |
143 ScopedJavaLocalRef<jobject> GetDSATestKey() { | |
144 std::string key; | |
145 ImportKeyFile(kTestDsaKeyFile, key); | |
146 return GetPKCS8PrivateKey(PRIVATE_KEY_TYPE_DSA, key); | |
147 } | |
148 | |
149 // Retrieve the OpenSSL object for our test DSA key. | |
150 EVP_PKEY* GetDSATestKeyOpenSSL() { | |
151 std::string key; | |
152 ImportKeyFile(kTestDsaKeyFile, key); | |
153 return GetOpenSSLPKCS8PrivateKey(EVP_PKEY_DSA, key); | |
154 } | |
155 | |
156 // Call this function to verify that one message signed with our | |
157 // test DSA private key is correct. Since DSA signing introduces | |
158 // random elements in the signature, it is not possible to compare | |
159 // signature bits directly. However, one can use the public key | |
160 // to do the check. | |
161 void VerifyTestDSASignature(const base::StringPiece& message, | |
162 const base::StringPiece& signature) { | |
163 std::string public_key; | |
164 ImportKeyFile(kTestDsaPublicKeyFile, public_key); | |
165 const unsigned char* p = | |
166 reinterpret_cast<const unsigned char*>(public_key.data()); | |
167 long length = static_cast<long>(public_key.size()); | |
168 DSA* pub_key = d2i_DSA_PUBKEY(NULL, &p, length); | |
169 ASSERT_TRUE(pub_key != NULL); | |
170 | |
171 const unsigned char* digest = | |
172 reinterpret_cast<const unsigned char*>(message.data()); | |
173 int digest_len = static_cast<int>(message.size()); | |
174 const unsigned char* sigbuf = | |
175 reinterpret_cast<const unsigned char*>(signature.data()); | |
176 int siglen = static_cast<int>(signature.size()); | |
177 | |
178 ASSERT_EQ(1, DSA_verify(0, digest, digest_len, sigbuf, siglen, pub_key)); | |
179 DSA_free(pub_key); | |
180 } | |
181 | |
182 const char kTestEcdsaKeyFile[] = "android-test-key-ecdsa.pkcs8"; | |
183 const char kTestEcdsaPublicKeyFile[] = "android-test-key-ecdsa-public.der"; | |
184 | |
185 // Retrieve a JNI local ref for our test ECDSA key. | |
186 ScopedJavaLocalRef<jobject> GetECDSATestKey() { | |
187 std::string key; | |
188 ImportKeyFile(kTestEcdsaKeyFile, key); | |
189 return GetPKCS8PrivateKey(PRIVATE_KEY_TYPE_ECDSA, key); | |
190 } | |
191 | |
192 // Retrieve the OpenSSL object for our test ECDSA key. | |
193 EVP_PKEY* GetECDSATestKeyOpenSSL() { | |
194 std::string key; | |
195 ImportKeyFile(kTestEcdsaKeyFile, key); | |
196 return GetOpenSSLPKCS8PrivateKey(EVP_PKEY_EC, key); | |
197 } | |
198 | |
199 // Call this function to verify that one message signed with our | |
200 // test DSA private key is correct. Since DSA signing introduces | |
201 // random elements in the signature, it is not possible to compare | |
202 // signature bits directly. However, one can use the public key | |
203 // to do the check. | |
204 void VerifyTestECDSASignature(const base::StringPiece& message, | |
205 const base::StringPiece& signature) { | |
206 std::string public_key; | |
207 ImportKeyFile(kTestEcdsaPublicKeyFile, public_key); | |
208 const unsigned char* p = | |
209 reinterpret_cast<const unsigned char*>(public_key.data()); | |
210 long length = static_cast<long>(public_key.size()); | |
211 EC_KEY* pub_key = d2i_EC_PUBKEY(NULL, &p, length); | |
212 ASSERT_TRUE(pub_key != NULL); | |
213 | |
214 const unsigned char* digest = | |
215 reinterpret_cast<const unsigned char*>(message.data()); | |
216 int digest_len = static_cast<int>(message.size()); | |
217 const unsigned char* sigbuf = | |
218 reinterpret_cast<const unsigned char*>(signature.data()); | |
219 int siglen = static_cast<int>(signature.size()); | |
220 | |
221 ASSERT_EQ( | |
222 1, ECDSA_verify(0, digest, digest_len, sigbuf, siglen, pub_key)); | |
Ryan Sleevi
2013/01/31 03:09:53
BUG: If this ASSERT fails, you end up leaking pub_
digit1
2013/01/31 17:44:30
Ah, I didn't realize we didn't want memory leaks,
| |
223 EC_KEY_free(pub_key); | |
224 } | |
225 | |
226 // Sign a message with OpenSSL, return the result as a string. | |
227 // |message| is the message to be signed. | |
228 // |openssl_key| is an OpenSSL EVP_PKEY to use. | |
229 // |result| receives the result. | |
230 void SignWithOpenSSL(const base::StringPiece& message, | |
231 EVP_PKEY* openssl_key, | |
232 std::string* result) { | |
233 const unsigned char* digest = | |
234 reinterpret_cast<const unsigned char*>(message.data()); | |
235 unsigned int digest_len = static_cast<unsigned int>(message.size()); | |
236 // Calling size functions like "RSA_size()" doesn't work at all | |
237 // with custom RSA_METHOD implementations. That's probably a bug | |
238 // in OpenSSL, so instead just use a very large buffer. | |
239 // Note that the code in ssl/s3_clnt.c does something similar. | |
Ryan Sleevi
2013/01/31 03:09:53
This does not seem like something we should rely o
digit1
2013/01/31 17:44:30
I've update the code appropriately.
| |
240 unsigned char openssl_signature[8192]; | |
241 unsigned int openssl_signature_len = 0; | |
242 int key_type = EVP_PKEY_id(openssl_key); | |
243 switch (key_type) { | |
244 case EVP_PKEY_RSA: | |
245 { | |
246 RSA* rsa = EVP_PKEY_get1_RSA(openssl_key); | |
247 ASSERT_TRUE(rsa != NULL); | |
Ryan Sleevi
2013/01/31 03:09:53
nit: ASSERT_TRUE(rsa) (and same throughout this fi
| |
248 int ret = RSA_sign(NID_md5_sha1, | |
249 digest, | |
250 digest_len, | |
251 openssl_signature, | |
252 &openssl_signature_len, | |
253 rsa); | |
254 ASSERT_EQ(1, ret) << GetOpenSSLErrorString(); | |
255 RSA_free(rsa); | |
256 } | |
257 break; | |
258 case EVP_PKEY_DSA: | |
259 { | |
260 DSA* dsa = EVP_PKEY_get1_DSA(openssl_key); | |
261 ASSERT_TRUE(dsa != NULL); | |
262 int ret = DSA_sign(0, // ignored by the function | |
263 digest, | |
264 digest_len, | |
265 openssl_signature, | |
266 &openssl_signature_len, | |
267 dsa); | |
268 ASSERT_EQ(1, ret) << GetOpenSSLErrorString(); | |
269 DSA_free(dsa); | |
270 } | |
271 break; | |
272 case EVP_PKEY_EC: | |
273 { | |
274 EC_KEY* ecdsa = EVP_PKEY_get1_EC_KEY(openssl_key); | |
275 ASSERT_TRUE(ecdsa != NULL); | |
276 int ret = ECDSA_sign(0, // ignored by the function | |
277 digest, | |
278 digest_len, | |
279 openssl_signature, | |
280 &openssl_signature_len, | |
281 ecdsa); | |
282 ASSERT_EQ(1, ret) << GetOpenSSLErrorString(); | |
283 EC_KEY_free(ecdsa); | |
284 } | |
285 break; | |
286 default: | |
287 LOG(WARNING) << "Invalid OpenSSL key type: " + key_type; | |
288 return; | |
289 } | |
290 result->assign(reinterpret_cast<const char*>(openssl_signature), | |
291 static_cast<size_t>(openssl_signature_len)); | |
292 } | |
293 | |
294 // Check that a generated signature for a given message matches | |
295 // OpenSSL output byte-by-byte. | |
296 // |message| is the input message. | |
297 // |signature| is the generated signature for the message. | |
298 // |openssl_key| is a raw EVP_PKEY for the same private key than the | |
299 // one which was used to generate the signature. | |
300 void CompareSignatureWithOpenSSL(const base::StringPiece& message, | |
301 const base::StringPiece& signature, | |
302 EVP_PKEY* openssl_key) { | |
303 std::string openssl_signature; | |
304 SignWithOpenSSL(message, openssl_key, &openssl_signature); | |
305 | |
306 ASSERT_EQ(signature.size(), openssl_signature.size()); | |
307 for (size_t n = 0; n < signature.size(); ++n) | |
308 ASSERT_EQ(openssl_signature[n], signature[n]); | |
309 | |
310 // All good, just exit. | |
311 } | |
312 | |
313 // Sign a message with our platform API. | |
314 // | |
315 // |android_key| is a JNI reference to the platform PrivateKey object. | |
316 // |openssl_key| is a pointer to an OpenSSL key object for the exact | |
317 // same key content. | |
318 // |message| is a message. | |
319 // |result| will receive the result. | |
320 void DoKeySigning(jobject android_key, | |
321 EVP_PKEY* openssl_key, | |
322 const base::StringPiece& message, | |
323 std::string* result) { | |
324 // First, get the platform signature. | |
325 std::vector<uint8> android_signature; | |
326 ASSERT_TRUE( | |
327 SignWithPrivateKey(android_key, | |
328 message, | |
329 &android_signature)); | |
330 | |
331 result->assign( | |
332 reinterpret_cast<const char*>(&android_signature[0]), | |
333 android_signature.size()); | |
334 } | |
335 | |
336 // Sign a message with our OpenSSL EVP_PKEY wrapper around platform | |
337 // APIS. | |
338 // | |
339 // |android_key| is a JNI reference to the platform PrivateKey object. | |
340 // |openssl_key| is a pointer to an OpenSSL key object for the exact | |
341 // same key content. | |
342 // |message| is a message. | |
343 // |result| will receive the result. | |
344 void DoKeySigningWithWrapper(EVP_PKEY* wrapper_key, | |
345 EVP_PKEY* openssl_key, | |
346 const base::StringPiece& message, | |
347 std::string* result) { | |
348 // First, get the platform signature. | |
349 std::string wrapper_signature; | |
350 SignWithOpenSSL(message, wrapper_key, &wrapper_signature); | |
351 ASSERT_NE(0U, wrapper_signature.size()); | |
352 | |
353 result->assign( | |
354 reinterpret_cast<const char*>(&wrapper_signature[0]), | |
355 wrapper_signature.size()); | |
356 } | |
357 | |
358 } // namespace | |
359 | |
360 TEST(AndroidKeyStore,GetPrivateKeyTypeRSA) { | |
361 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); | |
362 | |
363 ScopedJavaLocalRef<jobject> rsa_key = GetRSATestKey(); | |
364 ASSERT_FALSE(rsa_key.is_null()); | |
365 EXPECT_EQ(PRIVATE_KEY_TYPE_RSA, | |
366 GetPrivateKeyType(rsa_key.obj())); | |
367 } | |
368 | |
369 TEST(AndroidKeyStore,SignWithPrivateKeyRSA) { | |
370 ScopedJavaLocalRef<jobject> rsa_key = GetRSATestKey(); | |
371 ASSERT_FALSE(rsa_key.is_null()); | |
372 | |
373 if (IsOnAndroidOlderThan_4_2()) { | |
374 LOG(INFO) << "This test can't run on Android < 4.2"; | |
375 return; | |
376 } | |
377 | |
378 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> openssl_key( | |
379 GetRSATestKeyOpenSSL()); | |
380 ASSERT_TRUE(openssl_key.get() != NULL); | |
Ryan Sleevi
2013/01/31 03:09:53
Drop the != NULL (same as before and same througho
digit1
2013/01/31 17:44:30
I was just using the recommendations from the GTes
| |
381 | |
382 // Message size must be 36 for RSA_sign(NID_md5_sha1,...) to return | |
383 // without an error. | |
384 // See third_party/openssl/openssl/crypto/rsa/rsa_sign.c | |
Ryan Sleevi
2013/01/31 03:09:53
You don't need to cross-reference this. The 36 byt
| |
385 std::string message = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
386 ASSERT_EQ(36U, message.size()); | |
387 | |
388 std::string signature; | |
389 DoKeySigning(rsa_key.obj(), openssl_key.get(), message, &signature); | |
390 CompareSignatureWithOpenSSL(message, signature, openssl_key.get()); | |
391 // All good. | |
392 } | |
393 | |
394 TEST(AndroidKeyStore,SignWithWrapperKeyRSA) { | |
395 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | |
396 | |
397 ScopedJavaLocalRef<jobject> rsa_key = GetRSATestKey(); | |
398 ASSERT_FALSE(rsa_key.is_null()); | |
399 | |
400 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> wrapper_key( | |
401 GetOpenSSLPrivateKeyWrapper(rsa_key.obj())); | |
402 ASSERT_TRUE(wrapper_key.get() != NULL); | |
403 | |
404 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> openssl_key( | |
405 GetRSATestKeyOpenSSL()); | |
406 ASSERT_TRUE(openssl_key.get() != NULL); | |
407 | |
408 // Message size must be 36 for RSA_sign(NID_md5_sha1,...) to return | |
409 // without an error. | |
410 std::string message = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
411 ASSERT_EQ(36U, message.size()); | |
412 | |
413 std::string signature; | |
414 DoKeySigningWithWrapper(wrapper_key.get(), | |
415 openssl_key.get(), | |
416 message, | |
417 &signature); | |
418 CompareSignatureWithOpenSSL(message, signature, openssl_key.get()); | |
419 // All good. | |
420 } | |
421 | |
422 TEST(AndroidKeyStore,GetPrivateKeyTypeDSA) { | |
423 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); | |
424 | |
425 ScopedJavaLocalRef<jobject> dsa_key = GetDSATestKey(); | |
426 ASSERT_FALSE(dsa_key.is_null()); | |
427 EXPECT_EQ(PRIVATE_KEY_TYPE_DSA, | |
428 GetPrivateKeyType(dsa_key.obj())); | |
429 } | |
430 | |
431 TEST(AndroidKeyStore,SignWithPrivateKeyDSA) { | |
432 ScopedJavaLocalRef<jobject> dsa_key = GetDSATestKey(); | |
433 ASSERT_FALSE(dsa_key.is_null()); | |
434 | |
435 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> openssl_key( | |
436 GetDSATestKeyOpenSSL()); | |
437 ASSERT_TRUE(openssl_key.get() != NULL); | |
438 | |
439 std::string message = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
440 ASSERT_EQ(36U, message.size()); | |
441 | |
442 std::string signature; | |
443 DoKeySigning(dsa_key.obj(), openssl_key.get(), message, &signature); | |
444 VerifyTestDSASignature(message, signature); | |
445 // All good. | |
446 } | |
447 | |
448 TEST(AndroidKeyStore,SignWithWrapperKeyDSA) { | |
449 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | |
450 | |
451 ScopedJavaLocalRef<jobject> dsa_key = GetDSATestKey(); | |
452 ASSERT_FALSE(dsa_key.is_null()); | |
453 | |
454 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> wrapper_key( | |
455 GetOpenSSLPrivateKeyWrapper(dsa_key.obj())); | |
456 ASSERT_TRUE(wrapper_key.get() != NULL); | |
457 | |
458 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> openssl_key( | |
459 GetDSATestKeyOpenSSL()); | |
460 ASSERT_TRUE(openssl_key.get() != NULL); | |
461 | |
462 std::string message = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
463 std::string signature; | |
464 DoKeySigningWithWrapper(wrapper_key.get(), | |
465 openssl_key.get(), | |
466 message, | |
467 &signature); | |
468 VerifyTestDSASignature(message, signature); | |
469 // All good. | |
470 } | |
471 | |
472 TEST(AndroidKeyStore,GetPrivateKeyTypeECDSA) { | |
473 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); | |
474 | |
475 ScopedJavaLocalRef<jobject> ecdsa_key = GetECDSATestKey(); | |
476 ASSERT_FALSE(ecdsa_key.is_null()); | |
477 EXPECT_EQ(PRIVATE_KEY_TYPE_ECDSA, | |
478 GetPrivateKeyType(ecdsa_key.obj())); | |
479 } | |
480 | |
481 TEST(AndroidKeyStore,SignWithPrivateKeyECDSA) { | |
482 ScopedJavaLocalRef<jobject> ecdsa_key = GetECDSATestKey(); | |
483 ASSERT_FALSE(ecdsa_key.is_null()); | |
484 | |
485 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> openssl_key( | |
486 GetECDSATestKeyOpenSSL()); | |
487 ASSERT_TRUE(openssl_key.get() != NULL); | |
488 | |
489 std::string message = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
490 std::string signature; | |
491 DoKeySigning(ecdsa_key.obj(), openssl_key.get(), message, &signature); | |
492 VerifyTestECDSASignature(message, signature); | |
493 // All good. | |
494 } | |
495 | |
496 TEST(AndroidKeyStore, SignWithWrapperKeyECDSA) { | |
497 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); | |
498 | |
499 ScopedJavaLocalRef<jobject> ecdsa_key = GetECDSATestKey(); | |
500 ASSERT_FALSE(ecdsa_key.is_null()); | |
501 | |
502 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> wrapper_key( | |
503 GetOpenSSLPrivateKeyWrapper(ecdsa_key.obj())); | |
504 ASSERT_TRUE(wrapper_key.get() != NULL); | |
505 | |
506 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> openssl_key( | |
507 GetECDSATestKeyOpenSSL()); | |
508 ASSERT_TRUE(openssl_key.get() != NULL); | |
509 | |
510 std::string message = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
511 std::string signature; | |
512 DoKeySigningWithWrapper(wrapper_key.get(), | |
513 openssl_key.get(), | |
514 message, | |
515 &signature); | |
516 VerifyTestECDSASignature(message, signature); | |
517 // All good. | |
518 } | |
519 | |
520 } // namespace android | |
521 } // namespace net | |
OLD | NEW |