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

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: First real implementation - RSA only Created 7 years, 11 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/dsa.h>
6 #include <openssl/ecdsa.h>
7 #include <openssl/err.h>
8 #include <openssl/evp.h>
9 #include <openssl/rsa.h>
10
11 #include "base/android/jni_android.h"
12 #include "base/android/jni_array.h"
13 #include "base/android/scoped_java_ref.h"
14 #include "base/basictypes.h"
15 #include "base/bind.h"
16 #include "base/callback.h"
17 #include "base/compiler_specific.h"
18 #include "crypto/openssl_util.h"
19 #include "jni/AndroidKeyStoreTestUtil_jni.h"
20 #include "net/android/keystore.h"
21 #include "net/android/keystore_openssl.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 using base::android::AttachCurrentThread;
25 using base::android::ScopedJavaLocalRef;
26 using base::android::ToJavaByteArray;
27
28 // Technical note:
29 //
30 // This source file not only checks that signing with SignWithPrivateKey()
31 // works correctly, it also verifies that the generated signature matches
32 // 100% of what OpenSSL generates when calling RSA_sign(NID_md5_sha1,...),
33 // DSA_sign(0, ...) or ECDSA_sign(0, ...).
34 //
35 // That's crucial to ensure that this function can later be used to
36 // implement client certificate support. More specifically, that it is
37 // possible to create a custom EVP_PKEY that uses SignWithPrivateKey()
38 // internally to perform RSA/DSA/ECDSA signing, as invoked by the
39 // OpenSSL code at ssl/s3_clnt.c:ssl3_send_client_verify().
40 //
41 // Finally, it also checks that using the EVP_PKEY generated with
42 // GetOpenSSLPrivateKeyWrapper() works too as well.
43 //
44
45 namespace net {
46 namespace android {
47
48 namespace {
49
50 JNIEnv* InitEnv() {
51 JNIEnv* env = AttachCurrentThread();
52 static bool inited = false;
53 if (!inited) {
54 RegisterNativesImpl(env);
55 inited = true;
56 }
57 return env;
58 }
59
60 // Implements the callback expected by ERR_print_errors_cb().
61 // used by GetOpenSSLErrorString.
62 int openssl_print_error_callback(const char* msg, size_t msglen, void* u) {
63 std::string* result = reinterpret_cast<std::string*>(u);
64 result->append(msg, msglen);
65 return 1;
66 }
67
68 // Retrieve OpenSSL error as a string
69 std::string GetOpenSSLErrorString(void) {
70 std::string result;
71 ERR_print_errors_cb(openssl_print_error_callback, &result);
72 return result;
73 }
74
75 // Retrieve a JNI local ref from encoded PKCS#8 data.
76 ScopedJavaLocalRef<jobject> GetPKCS8PrivateKey(
77 SSLClientCertType key_type,
78 const unsigned char* pkcs8_bytes,
79 size_t pkcs8_size) {
80 JNIEnv* env = InitEnv();
81 ScopedJavaLocalRef<jbyteArray> bytes(
82 ToJavaByteArray(env,
83 reinterpret_cast<const uint8*>(pkcs8_bytes),
84 pkcs8_size));
85
86 ScopedJavaLocalRef<jobject> key(
87 Java_AndroidKeyStoreTestUtil_CreatePrivateKeyFromPKCS8(
88 env, key_type, bytes.obj()));
89
90 return key;
91 }
92
93 // Create an OpenSSL EVP_PKEY object from a PKCS#8 in-memory content.
94 EVP_PKEY* GetOpenSSLPKCS8PrivateKey(int type,
95 const unsigned char* key_bytes,
96 size_t key_size) {
97 const unsigned char* p = key_bytes;
98 long p_length = static_cast<long>(key_size);
99 return d2i_PrivateKey(type, NULL, &p, p_length);
100 }
101
102 // A simple test RSA 2048-bits key, in PKCS#8 format, the following was
103 // generated with:
104 //
105 // openssl genrsa -out key.pem 2048
106 // openssl pkcs8 -topk8 -inform PEM -outform DER -in key.pem key.pkcs8
107 // xxd -i key.pkcs8
108 //
109 const unsigned char test_rsa_key_pkcs8[] = {
110 0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
111 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
112 0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
113 0x01, 0x00, 0xc0, 0x41, 0x18, 0x86, 0x1c, 0xe3, 0x60, 0xd7, 0xec, 0x38,
114 0x70, 0xd0, 0x35, 0x64, 0x6e, 0x0e, 0x4f, 0xaf, 0x3f, 0x05, 0x57, 0x05,
115 0xc3, 0xe9, 0x8d, 0xc3, 0x92, 0x14, 0xa1, 0xea, 0xab, 0xe3, 0x5f, 0x61,
116 0x70, 0x9a, 0xd7, 0x43, 0x2f, 0xc2, 0x31, 0xd7, 0x8c, 0x65, 0x89, 0xea,
117 0x8b, 0xdb, 0xa7, 0x9f, 0x9e, 0xba, 0xea, 0x48, 0x7d, 0x71, 0x10, 0x11,
118 0x86, 0x9d, 0x55, 0x68, 0xd4, 0x31, 0xa0, 0x33, 0x06, 0x5f, 0x0f, 0x43,
119 0xe5, 0x52, 0x46, 0x8d, 0xc1, 0x26, 0xb2, 0x08, 0xd6, 0xa5, 0x9f, 0x85,
120 0x24, 0xb0, 0x4d, 0x7e, 0x2a, 0x7b, 0x4e, 0xcd, 0x54, 0xe5, 0x11, 0xf8,
121 0x39, 0xf5, 0x13, 0x5c, 0xb4, 0xff, 0x07, 0x82, 0xaf, 0xdc, 0x05, 0x27,
122 0x35, 0x5a, 0x48, 0xc9, 0xa0, 0x3b, 0xe5, 0x03, 0x33, 0x32, 0x9a, 0x60,
123 0xe7, 0x0d, 0xce, 0x23, 0xb7, 0xbf, 0x6e, 0x9e, 0x14, 0x6f, 0xe0, 0x5f,
124 0x36, 0x98, 0xdd, 0x1e, 0xde, 0x29, 0x51, 0x2c, 0x10, 0xc1, 0x4b, 0x07,
125 0x98, 0x60, 0x51, 0x88, 0x75, 0x76, 0x4b, 0xcb, 0x19, 0x22, 0x0c, 0x4e,
126 0xc5, 0x5f, 0xb0, 0x40, 0xb7, 0x6b, 0x5b, 0x45, 0xd7, 0x5d, 0xaa, 0x09,
127 0xe2, 0xdc, 0x8f, 0x6c, 0x07, 0xa7, 0x75, 0x4f, 0x2c, 0x5d, 0xd8, 0xa4,
128 0x2f, 0xdd, 0x8c, 0xc8, 0xa6, 0x3a, 0xaf, 0x5c, 0xf5, 0x2d, 0xbb, 0x4d,
129 0x8c, 0xf4, 0xc7, 0x01, 0x9b, 0x95, 0x1b, 0x51, 0x3d, 0x44, 0x87, 0xa0,
130 0x48, 0x79, 0xc0, 0x79, 0x23, 0x98, 0x86, 0xae, 0x20, 0xa1, 0x67, 0xf0,
131 0x20, 0x03, 0x46, 0x8c, 0xc2, 0x96, 0xdf, 0x22, 0x70, 0xa8, 0xed, 0xef,
132 0x8e, 0xa9, 0x09, 0x32, 0x9d, 0xe5, 0x95, 0x53, 0x36, 0x67, 0x69, 0xfe,
133 0x11, 0x38, 0x74, 0xda, 0x9f, 0x7f, 0xba, 0x17, 0xd3, 0x31, 0x94, 0xd3,
134 0xe3, 0x66, 0xb6, 0x84, 0x79, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
135 0x82, 0x01, 0x00, 0x55, 0xc5, 0x34, 0xe1, 0xb0, 0x45, 0xa8, 0xd0, 0xeb,
136 0xec, 0x0a, 0x38, 0x79, 0x79, 0x82, 0xb8, 0x13, 0xc8, 0xc5, 0x3e, 0xe6,
137 0xa2, 0x05, 0xd3, 0x4e, 0x91, 0xaf, 0xbc, 0x50, 0xb8, 0x57, 0x53, 0x2b,
138 0x1c, 0x57, 0x96, 0x5c, 0xee, 0xf6, 0x81, 0x96, 0xa6, 0xe9, 0x55, 0xeb,
139 0x7f, 0x9e, 0x41, 0xb2, 0xb8, 0xbd, 0xa1, 0xfa, 0x1f, 0xb9, 0x07, 0x15,
140 0xfa, 0x1b, 0xaa, 0x59, 0x8e, 0x59, 0x0c, 0x82, 0xc2, 0x00, 0xd7, 0xac,
141 0x01, 0xc8, 0x6f, 0x3a, 0x56, 0xc7, 0x93, 0x31, 0xde, 0x4b, 0x94, 0xbc,
142 0x64, 0x34, 0x08, 0x0b, 0xaa, 0x7b, 0xdd, 0x63, 0x3c, 0xab, 0xe1, 0x3e,
143 0x71, 0x15, 0xba, 0x46, 0x97, 0x17, 0x90, 0xa7, 0x93, 0x20, 0x4d, 0xf2,
144 0x66, 0x99, 0xa0, 0xdb, 0xd4, 0x48, 0x0e, 0x30, 0x8f, 0x8a, 0xe9, 0xca,
145 0x81, 0xec, 0xd2, 0xf5, 0xe2, 0x6d, 0x79, 0x94, 0x2a, 0x26, 0x47, 0x34,
146 0xa4, 0x2a, 0xf6, 0x31, 0x78, 0x4e, 0xcc, 0xea, 0x1c, 0xf1, 0xa5, 0x64,
147 0x29, 0x32, 0x0d, 0xab, 0xe0, 0x34, 0x5a, 0xec, 0xb7, 0x38, 0xca, 0x96,
148 0x3b, 0x04, 0x42, 0xfc, 0xbc, 0xd0, 0x7b, 0x44, 0xc7, 0x10, 0xa4, 0xac,
149 0x02, 0x12, 0x60, 0xbd, 0x2a, 0xf5, 0x1a, 0x1f, 0xa4, 0x21, 0xc5, 0x83,
150 0x42, 0x25, 0xcb, 0x1a, 0x51, 0xe7, 0x38, 0xe7, 0xa8, 0x21, 0xeb, 0x33,
151 0xf7, 0x0a, 0x78, 0x4d, 0xf9, 0x7c, 0x39, 0x79, 0xa3, 0x36, 0x45, 0x6b,
152 0x68, 0x73, 0x39, 0x15, 0x4b, 0x01, 0x39, 0x45, 0xae, 0xb4, 0xd5, 0x18,
153 0xce, 0xab, 0x7d, 0x0b, 0x94, 0xd2, 0x45, 0x0c, 0xec, 0x88, 0x43, 0x84,
154 0x36, 0x3d, 0x5f, 0x4f, 0x23, 0x90, 0x86, 0x40, 0x2c, 0xd5, 0xdd, 0x93,
155 0x3a, 0x08, 0x16, 0xb1, 0x92, 0x9d, 0x23, 0xe2, 0xc1, 0x56, 0xd8, 0x17,
156 0x2b, 0x72, 0xd1, 0xa0, 0xa8, 0xfc, 0x21, 0x02, 0x81, 0x81, 0x00, 0xf0,
157 0x7f, 0x17, 0x65, 0x8e, 0xd1, 0x5e, 0x30, 0x14, 0xa7, 0x93, 0x37, 0x11,
158 0xde, 0xbe, 0x25, 0xc5, 0x5b, 0x40, 0x60, 0x94, 0x28, 0x9b, 0x88, 0x74,
159 0x47, 0xe2, 0x04, 0x65, 0xc6, 0x30, 0xc3, 0x3c, 0xa1, 0xa6, 0x76, 0x3a,
160 0xb2, 0x8e, 0x5f, 0xec, 0xb6, 0xe4, 0x06, 0x2c, 0x19, 0x24, 0x09, 0x5b,
161 0xc5, 0xa7, 0xf4, 0x06, 0xdb, 0xa3, 0x2b, 0x35, 0xbc, 0x28, 0x91, 0xc4,
162 0xff, 0x61, 0x72, 0x3f, 0xb3, 0x7e, 0x22, 0x4c, 0x52, 0xa7, 0xe3, 0x12,
163 0x29, 0xc4, 0xdd, 0x7f, 0x8c, 0xa6, 0x76, 0x82, 0x82, 0x91, 0x6d, 0xd7,
164 0xec, 0x2d, 0x2f, 0xaa, 0x6a, 0x44, 0x11, 0xdc, 0x5b, 0xa5, 0xb6, 0xfe,
165 0x3d, 0x2c, 0x36, 0x06, 0x84, 0x8a, 0x82, 0xbd, 0x24, 0xe5, 0x0c, 0xd6,
166 0x1a, 0x5f, 0x10, 0x1c, 0x92, 0x9c, 0xdb, 0xce, 0x8f, 0x9e, 0x2f, 0x3d,
167 0x01, 0xd2, 0x75, 0x58, 0xdd, 0x0b, 0x4d, 0x02, 0x81, 0x81, 0x00, 0xcc,
168 0xa5, 0xdd, 0x5f, 0x26, 0x99, 0x91, 0x3a, 0xab, 0x30, 0xf2, 0x01, 0x75,
169 0xe2, 0x59, 0x75, 0x98, 0xc9, 0x32, 0x89, 0x29, 0x36, 0x77, 0x7d, 0x7a,
170 0xa0, 0xee, 0x9d, 0xce, 0xe6, 0xe9, 0x47, 0xd0, 0x2b, 0x6b, 0x69, 0x81,
171 0x1b, 0xd7, 0x19, 0x04, 0x51, 0xb0, 0x72, 0x9c, 0x87, 0x41, 0x7d, 0x94,
172 0x01, 0x3f, 0x36, 0x10, 0x92, 0x9f, 0x2f, 0x7e, 0xf1, 0x49, 0x1f, 0x1b,
173 0x40, 0x9c, 0xbe, 0xa4, 0x37, 0xe8, 0xa4, 0x9c, 0xc3, 0xfd, 0xb0, 0xe0,
174 0x48, 0xb2, 0xd7, 0xc5, 0x41, 0xd1, 0x4e, 0xda, 0xee, 0x4c, 0xbf, 0x45,
175 0xa9, 0xef, 0xe3, 0x1d, 0x9d, 0x99, 0xdf, 0xa3, 0xc3, 0x55, 0x25, 0x22,
176 0xba, 0x32, 0xc4, 0xfe, 0xa0, 0x8f, 0x50, 0xfa, 0x05, 0x64, 0xa5, 0xd9,
177 0x92, 0x2b, 0x27, 0xc9, 0x96, 0x23, 0xe3, 0xe3, 0xeb, 0xde, 0x47, 0xa7,
178 0x3d, 0x33, 0x8d, 0xb6, 0x73, 0x02, 0x85, 0x02, 0x81, 0x80, 0x58, 0xe8,
179 0x63, 0x19, 0xe4, 0x66, 0x7a, 0x4f, 0x84, 0x13, 0x3f, 0x55, 0x48, 0x81,
180 0xf4, 0x01, 0xba, 0xa8, 0x35, 0x70, 0x7e, 0xd5, 0x54, 0x4a, 0x69, 0xd2,
181 0x79, 0x37, 0xee, 0xf8, 0x09, 0xe6, 0xe3, 0x6f, 0x4f, 0x3e, 0xbe, 0x0c,
182 0x6c, 0x9e, 0x01, 0xc0, 0xcb, 0x23, 0x8d, 0x01, 0xee, 0x54, 0x97, 0x5c,
183 0xc6, 0xee, 0x6b, 0xea, 0x9e, 0xb3, 0xc6, 0xb5, 0xbc, 0xb9, 0xc6, 0xfe,
184 0x32, 0x64, 0x2e, 0x30, 0x89, 0x1c, 0xdc, 0xe2, 0x61, 0xb6, 0x8c, 0x6c,
185 0x6c, 0x9f, 0x06, 0x1c, 0x55, 0x1d, 0xd2, 0xb9, 0xba, 0x51, 0xc5, 0x55,
186 0x46, 0x8f, 0x2c, 0x8d, 0x04, 0x85, 0x25, 0xd5, 0xab, 0xb9, 0xae, 0xdb,
187 0xa6, 0x90, 0x82, 0x70, 0x55, 0x54, 0x67, 0xe0, 0x4f, 0xdd, 0x22, 0xf9,
188 0xb4, 0xd3, 0x1b, 0xfd, 0x07, 0x88, 0x2b, 0x20, 0xe4, 0xf5, 0xc9, 0xb3,
189 0xf6, 0xbd, 0xf3, 0x10, 0x24, 0xb1, 0x02, 0x81, 0x80, 0x7b, 0x67, 0x3d,
190 0x51, 0x26, 0x36, 0x8e, 0x23, 0xa1, 0x9d, 0x57, 0x21, 0x58, 0x53, 0x90,
191 0x7c, 0x60, 0x10, 0x5a, 0xff, 0xe8, 0xb1, 0x26, 0x66, 0xac, 0xee, 0xa4,
192 0x54, 0xd6, 0xb1, 0xd9, 0x53, 0xeb, 0x8c, 0x73, 0x2d, 0xe0, 0xa3, 0xc8,
193 0x16, 0x16, 0xcb, 0xa7, 0xa9, 0xc5, 0x07, 0xae, 0x8f, 0x2a, 0x13, 0x82,
194 0x69, 0x78, 0x9e, 0xe1, 0x8c, 0xc3, 0x70, 0x7e, 0x16, 0x5a, 0xd9, 0xa0,
195 0x6b, 0x39, 0x1d, 0x59, 0x95, 0x01, 0xcf, 0x11, 0x88, 0x7a, 0x06, 0x7c,
196 0x89, 0xae, 0x32, 0x1d, 0x23, 0xfe, 0xd2, 0x99, 0xc6, 0xf1, 0x1c, 0x23,
197 0x42, 0x81, 0xd6, 0x4a, 0x36, 0x58, 0x4a, 0xee, 0x6a, 0x01, 0x41, 0xe4,
198 0x61, 0x73, 0xe5, 0x9f, 0xe6, 0x45, 0x8d, 0xc0, 0xfe, 0x5d, 0x6f, 0x4d,
199 0xc4, 0xa5, 0x43, 0x7b, 0x0a, 0xed, 0xa2, 0x8a, 0x9c, 0x0c, 0x95, 0xd4,
200 0x23, 0x8d, 0x34, 0x56, 0xfd, 0x02, 0x81, 0x81, 0x00, 0xe2, 0x05, 0xb1,
201 0xe7, 0x6b, 0xf1, 0xa9, 0xa5, 0xe1, 0x48, 0xb5, 0xe0, 0x76, 0x95, 0xa0,
202 0x7e, 0xb0, 0xa6, 0x32, 0x2d, 0x16, 0x07, 0xe9, 0x30, 0x90, 0xf4, 0xfe,
203 0x54, 0x98, 0x7c, 0xdc, 0xf5, 0x67, 0x87, 0xa1, 0x1c, 0x18, 0x49, 0x06,
204 0x4a, 0xaf, 0xbb, 0xbb, 0xb1, 0x0b, 0xcc, 0x3d, 0x89, 0x2a, 0x70, 0x18,
205 0x39, 0x92, 0x6f, 0xc4, 0xcb, 0x76, 0xe6, 0x1e, 0xd5, 0x72, 0xc1, 0x98,
206 0x75, 0x5c, 0xdb, 0x15, 0x01, 0x1f, 0xb7, 0xcd, 0xc2, 0x88, 0xc5, 0x2c,
207 0x5d, 0x1d, 0x76, 0x1c, 0xd5, 0xcd, 0xb5, 0xa0, 0x18, 0xd7, 0x0d, 0x53,
208 0x43, 0xb7, 0x31, 0x51, 0x30, 0x27, 0xf5, 0x60, 0x8c, 0x8e, 0x17, 0x44,
209 0xac, 0xeb, 0xac, 0xde, 0x39, 0x28, 0x78, 0x02, 0x95, 0xeb, 0x2f, 0xaa,
210 0xd8, 0x26, 0x76, 0xbd, 0xeb, 0x0e, 0x3f, 0x99, 0xe6, 0xb6, 0xf5, 0xcf,
211 0xd3, 0xe2, 0xf4, 0xa2, 0xab
212 };
213
214 // Retrieve a JNI local ref for our test RSA key.
215 ScopedJavaLocalRef<jobject> GetRSATestKey() {
216 return GetPKCS8PrivateKey(CLIENT_CERT_RSA_SIGN,
217 test_rsa_key_pkcs8,
218 sizeof(test_rsa_key_pkcs8));
219 }
220
221 // Retrieve the OpenSSL object for our test RSA key.
222 EVP_PKEY* GetRSATestKeyOpenSSL() {
223 return GetOpenSSLPKCS8PrivateKey(EVP_PKEY_RSA,
224 test_rsa_key_pkcs8,
225 sizeof(test_rsa_key_pkcs8));
226 }
227
228 // Sign a message with OpenSSL, return the result as a string.
229 // |message| is the message to be signed.
230 // |openssl_key| is an OpenSSL EVP_PKEY to use.
231 // |result| receives the result.
232 void SignWithOpenSSL(const base::StringPiece& message,
233 EVP_PKEY* openssl_key,
234 std::string* result) {
235 const unsigned char* digest =
236 reinterpret_cast<const unsigned char*>(message.data());
237 unsigned int digest_len = static_cast<unsigned int>(message.size());
238 // Calling size functions like "RSA_size()" doesn't work at all
239 // with custom RSA_METHOD implementations. That's probably a bug
240 // in OpenSSL, so instead just use a very large buffer.
241 // Note that the code in ssl/s3_clnt.c does something similar.
242 unsigned char openssl_signature[8192];
243 unsigned int openssl_signature_len = 0;
244 int key_type = EVP_PKEY_id(openssl_key);
245 switch (key_type) {
246 case EVP_PKEY_RSA:
247 {
248 RSA* rsa = EVP_PKEY_get1_RSA(openssl_key);
249 ASSERT_TRUE(rsa != NULL);
250 int ret = RSA_sign(NID_md5_sha1,
251 digest,
252 digest_len,
253 openssl_signature,
254 &openssl_signature_len,
255 rsa);
256 ASSERT_EQ(1, ret) << GetOpenSSLErrorString();
257 RSA_free(rsa);
258 }
259 break;
260 case EVP_PKEY_DSA:
261 {
262 DSA* dsa = EVP_PKEY_get1_DSA(openssl_key);
263 ASSERT_TRUE(dsa != NULL);
264 int ret = DSA_sign(0, // ignored by the function
265 digest,
266 digest_len,
267 openssl_signature,
268 &openssl_signature_len,
269 dsa);
270 ASSERT_EQ(1, ret) << GetOpenSSLErrorString();
271 DSA_free(dsa);
272 }
273 break;
274 case EVP_PKEY_EC:
275 {
276 EC_KEY* ecdsa = EVP_PKEY_get1_EC_KEY(openssl_key);
277 ASSERT_TRUE(ecdsa != NULL);
278 int ret = ECDSA_sign(0, // ignored by the function
279 digest,
280 digest_len,
281 openssl_signature,
282 &openssl_signature_len,
283 ecdsa);
284 ASSERT_EQ(1, ret) << GetOpenSSLErrorString();
285 EC_KEY_free(ecdsa);
286 }
287 break;
288 default:
289 LOG(WARNING) << "Invalid OpenSSL key type: " + key_type;
290 return;
291 }
292 result->assign(reinterpret_cast<const char*>(openssl_signature),
293 static_cast<size_t>(openssl_signature_len));
294 }
295
296 // Check that a generated signature for a given message matches
297 // OpenSSL output byte-by-byte.
298 // |message| is the input message.
299 // |signature| is the generated signature for the message.
300 // |openssl_key| is a raw EVP_PKEY for the same private key than the
301 // one which was used to generate the signature.
302 void CompareSignatureWithOpenSSL(const base::StringPiece& message,
303 const base::StringPiece& signature,
304 EVP_PKEY* openssl_key) {
305 std::string openssl_signature;
306 SignWithOpenSSL(message, openssl_key, &openssl_signature);
307
308 ASSERT_EQ(signature.size(), openssl_signature.size());
309 for (size_t n = 0; n < signature.size(); ++n)
310 ASSERT_EQ(openssl_signature[n], signature[n]);
311
312 // All good, just exit.
313 }
314
315 // Check that signing a message with our platform API generates
316 // a result that is identical to calling OpenSSL's RSA_sign() function.
317 // This is a hard requirement for client certificate support.
318 //
319 // |android_key| is a JNI reference to the platform PrivateKey object.
320 // |openssl_key| is a pointer to an OpenSSL key object for the exact
321 // same key content.
322 // |message| is a message.
323 void CheckKeySigning(jobject rsa_key,
324 EVP_PKEY* openssl_key,
325 const base::StringPiece& message) {
326 // First, get the platform signature.
327 std::vector<uint8> android_signature;
328 ASSERT_TRUE(
329 SignWithPrivateKey(rsa_key,
330 message,
331 &android_signature));
332
333 base::StringPiece signature(
334 reinterpret_cast<const char*>(&android_signature[0]),
335 android_signature.size());
336
337 CompareSignatureWithOpenSSL(message, signature, openssl_key);
338 }
339
340 // Check that signing a message with our platform API generates
341 // a result that is identical to calling OpenSSL's RSA_sign() function.
342 // This is a hard requirement for client certificate support.
343 //
344 // |android_key| is a JNI reference to the platform PrivateKey object.
345 // |openssl_key| is a pointer to an OpenSSL key object for the exact
346 // same key content.
347 // |message| is a message.
348 void CheckKeySigningWithWrapper(EVP_PKEY* wrapper_key,
349 EVP_PKEY* openssl_key,
350 const base::StringPiece& message) {
351 // First, get the signature platform signature.
352 std::string wrapper_signature;
353 SignWithOpenSSL(message, wrapper_key, &wrapper_signature);
354 ASSERT_NE(0U, wrapper_signature.size());
355
356 base::StringPiece signature(
357 reinterpret_cast<const char*>(&wrapper_signature[0]),
358 wrapper_signature.size());
359
360 CompareSignatureWithOpenSSL(message, signature, openssl_key);
361 }
362
363 } // namespace
364
365 TEST(AndroidKeyStore,GetPrivateKeySigningTypeRSA) {
366 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE);
367
368 ScopedJavaLocalRef<jobject> rsa_key = GetRSATestKey();
369 ASSERT_FALSE(rsa_key.is_null());
370 EXPECT_EQ(CLIENT_CERT_RSA_SIGN,
371 GetPrivateKeySigningType(rsa_key.obj()));
372 }
373
374 TEST(AndroidKeyStore,SignWithPrivateKeyRSA) {
375 ScopedJavaLocalRef<jobject> rsa_key = GetRSATestKey();
376 ASSERT_FALSE(rsa_key.is_null());
377
378 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> openssl_key(
379 GetRSATestKeyOpenSSL());
380 ASSERT_TRUE(openssl_key.get() != NULL);
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
385 std::string message = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
386 ASSERT_EQ(36U, message.size());
387
388 CheckKeySigning(rsa_key.obj(), openssl_key.get(), message);
389 // All good.
390 }
391
392 TEST(AndroidKeyStore,SignWithWrapperKeyRSA) {
393 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
394
395 ScopedJavaLocalRef<jobject> rsa_key = GetRSATestKey();
396 ASSERT_FALSE(rsa_key.is_null());
397
398 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> wrapper_key(
399 GetOpenSSLPrivateKeyWrapper(rsa_key.obj()));
400 ASSERT_TRUE(wrapper_key.get() != NULL);
401
402 crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> openssl_key(
403 GetRSATestKeyOpenSSL());
404 ASSERT_TRUE(openssl_key.get() != NULL);
405
406 // Message size must be 36 for RSA_sign(NID_md5_sha1,...) to return
407 // without an error.
408 std::string message = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
409 ASSERT_EQ(36U, message.size());
410
411 CheckKeySigningWithWrapper(wrapper_key.get(),
412 openssl_key.get(),
413 message);
414 // All good.
415 }
416
417 // TODO(digit): Add DSA + ECDSA tests.
418
419 } // namespace android
420 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698