OLD | NEW |
| (Empty) |
1 // Copyright 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 "webcrypto_impl.h" | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "base/logging.h" | |
9 #include "base/memory/ref_counted.h" | |
10 #include "base/strings/string_number_conversions.h" | |
11 #include "content/public/renderer/content_renderer_client.h" | |
12 #include "content/renderer/renderer_webkitplatformsupport_impl.h" | |
13 #include "content/renderer/webcrypto_impl.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | |
15 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" | |
16 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | |
17 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | |
18 | |
19 namespace { | |
20 | |
21 std::vector<uint8> HexStringToBytes(const std::string& hex) { | |
22 std::vector<uint8> bytes; | |
23 base::HexStringToBytes(hex, &bytes); | |
24 return bytes; | |
25 } | |
26 | |
27 void ExpectArrayBufferMatchesHex(const std::string& expected_hex, | |
28 const WebKit::WebArrayBuffer& array_buffer) { | |
29 EXPECT_STRCASEEQ( | |
30 expected_hex.c_str(), | |
31 base::HexEncode( | |
32 array_buffer.data(), array_buffer.byteLength()).c_str()); | |
33 } | |
34 | |
35 WebKit::WebCryptoAlgorithm CreateAlgorithm(WebKit::WebCryptoAlgorithmId id) { | |
36 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(id, NULL); | |
37 } | |
38 | |
39 WebKit::WebCryptoAlgorithm CreateHmacAlgorithm( | |
40 WebKit::WebCryptoAlgorithmId hashId) { | |
41 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate( | |
42 WebKit::WebCryptoAlgorithmIdHmac, | |
43 new WebKit::WebCryptoHmacParams(CreateAlgorithm(hashId))); | |
44 } | |
45 | |
46 } // namespace | |
47 | |
48 namespace content { | |
49 | |
50 class WebCryptoImplTest : public testing::Test { | |
51 protected: | |
52 WebKit::WebCryptoKey ImportSecretKeyFromRawHexString( | |
53 const std::string& key_hex, | |
54 const WebKit::WebCryptoAlgorithm& algorithm, | |
55 WebKit::WebCryptoKeyUsageMask usage) { | |
56 WebKit::WebCryptoKeyType type; | |
57 scoped_ptr<WebKit::WebCryptoKeyHandle> handle; | |
58 | |
59 std::vector<uint8> key_raw = HexStringToBytes(key_hex); | |
60 | |
61 EXPECT_TRUE(crypto_.ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw, | |
62 key_raw.data(), | |
63 key_raw.size(), | |
64 algorithm, | |
65 usage, | |
66 &handle, | |
67 &type)); | |
68 | |
69 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, type); | |
70 EXPECT_TRUE(handle.get()); | |
71 | |
72 return WebKit::WebCryptoKey::create( | |
73 handle.release(), type, false, algorithm, usage); | |
74 } | |
75 | |
76 // Forwarding methods to gain access to protected methods of | |
77 // WebCryptoImpl. | |
78 | |
79 bool DigestInternal( | |
80 const WebKit::WebCryptoAlgorithm& algorithm, | |
81 const unsigned char* data, | |
82 unsigned data_size, | |
83 WebKit::WebArrayBuffer* buffer) { | |
84 return crypto_.DigestInternal(algorithm, data, data_size, buffer); | |
85 } | |
86 | |
87 bool ImportKeyInternal( | |
88 WebKit::WebCryptoKeyFormat format, | |
89 const unsigned char* key_data, | |
90 unsigned key_data_size, | |
91 const WebKit::WebCryptoAlgorithm& algorithm, | |
92 WebKit::WebCryptoKeyUsageMask usage_mask, | |
93 scoped_ptr<WebKit::WebCryptoKeyHandle>* handle, | |
94 WebKit::WebCryptoKeyType* type) { | |
95 return crypto_.ImportKeyInternal( | |
96 format, key_data, key_data_size, algorithm, usage_mask, handle, type); | |
97 } | |
98 | |
99 bool SignInternal( | |
100 const WebKit::WebCryptoAlgorithm& algorithm, | |
101 const WebKit::WebCryptoKey& key, | |
102 const unsigned char* data, | |
103 unsigned data_size, | |
104 WebKit::WebArrayBuffer* buffer) { | |
105 return crypto_.SignInternal(algorithm, key, data, data_size, buffer); | |
106 } | |
107 | |
108 bool VerifySignatureInternal( | |
109 const WebKit::WebCryptoAlgorithm& algorithm, | |
110 const WebKit::WebCryptoKey& key, | |
111 const unsigned char* signature, | |
112 unsigned signature_size, | |
113 const unsigned char* data, | |
114 unsigned data_size, | |
115 bool* signature_match) { | |
116 return crypto_.VerifySignatureInternal(algorithm, | |
117 key, | |
118 signature, | |
119 signature_size, | |
120 data, | |
121 data_size, | |
122 signature_match); | |
123 } | |
124 | |
125 private: | |
126 WebCryptoImpl crypto_; | |
127 }; | |
128 | |
129 TEST_F(WebCryptoImplTest, DigestSampleSets) { | |
130 // The results are stored here in hex format for readability. | |
131 // | |
132 // TODO(bryaneyler): Eventually, all these sample test sets should be replaced | |
133 // with the sets here: http://csrc.nist.gov/groups/STM/cavp/index.html#03 | |
134 // | |
135 // Results were generated using the command sha{1,224,256,384,512}sum. | |
136 struct TestCase { | |
137 WebKit::WebCryptoAlgorithmId algorithm; | |
138 const std::string hex_input; | |
139 const char* hex_result; | |
140 }; | |
141 | |
142 const TestCase kTests[] = { | |
143 { WebKit::WebCryptoAlgorithmIdSha1, "", | |
144 "da39a3ee5e6b4b0d3255bfef95601890afd80709" | |
145 }, | |
146 { WebKit::WebCryptoAlgorithmIdSha224, "", | |
147 "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f" | |
148 }, | |
149 { WebKit::WebCryptoAlgorithmIdSha256, "", | |
150 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" | |
151 }, | |
152 { WebKit::WebCryptoAlgorithmIdSha384, "", | |
153 "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274e" | |
154 "debfe76f65fbd51ad2f14898b95b" | |
155 }, | |
156 { WebKit::WebCryptoAlgorithmIdSha512, "", | |
157 "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0" | |
158 "d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", | |
159 }, | |
160 { WebKit::WebCryptoAlgorithmIdSha1, "00", | |
161 "5ba93c9db0cff93f52b521d7420e43f6eda2784f", | |
162 }, | |
163 { WebKit::WebCryptoAlgorithmIdSha224, "00", | |
164 "fff9292b4201617bdc4d3053fce02734166a683d7d858a7f5f59b073", | |
165 }, | |
166 { WebKit::WebCryptoAlgorithmIdSha256, "00", | |
167 "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d", | |
168 }, | |
169 { WebKit::WebCryptoAlgorithmIdSha384, "00", | |
170 "bec021b4f368e3069134e012c2b4307083d3a9bdd206e24e5f0d86e13d6636655933" | |
171 "ec2b413465966817a9c208a11717", | |
172 }, | |
173 { WebKit::WebCryptoAlgorithmIdSha512, "00", | |
174 "b8244d028981d693af7b456af8efa4cad63d282e19ff14942c246e50d9351d22704a" | |
175 "802a71c3580b6370de4ceb293c324a8423342557d4e5c38438f0e36910ee", | |
176 }, | |
177 { WebKit::WebCryptoAlgorithmIdSha1, "000102030405", | |
178 "868460d98d09d8bbb93d7b6cdd15cc7fbec676b9", | |
179 }, | |
180 { WebKit::WebCryptoAlgorithmIdSha224, "000102030405", | |
181 "7d92e7f1cad1818ed1d13ab41f04ebabfe1fef6bb4cbeebac34c29bc", | |
182 }, | |
183 { WebKit::WebCryptoAlgorithmIdSha256, "000102030405", | |
184 "17e88db187afd62c16e5debf3e6527cd006bc012bc90b51a810cd80c2d511f43", | |
185 }, | |
186 { WebKit::WebCryptoAlgorithmIdSha384, "000102030405", | |
187 "79f4738706fce9650ac60266675c3cd07298b09923850d525604d040e6e448adc7dc" | |
188 "22780d7e1b95bfeaa86a678e4552", | |
189 }, | |
190 { WebKit::WebCryptoAlgorithmIdSha512, "000102030405", | |
191 "2f3831bccc94cf061bcfa5f8c23c1429d26e3bc6b76edad93d9025cb91c903af6cf9" | |
192 "c935dc37193c04c2c66e7d9de17c358284418218afea2160147aaa912f4c", | |
193 }, | |
194 }; | |
195 | |
196 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests); | |
197 ++test_index) { | |
198 SCOPED_TRACE(test_index); | |
199 const TestCase& test = kTests[test_index]; | |
200 | |
201 WebKit::WebCryptoAlgorithm algorithm = CreateAlgorithm(test.algorithm); | |
202 std::vector<uint8> input = HexStringToBytes(test.hex_input); | |
203 | |
204 WebKit::WebArrayBuffer output; | |
205 ASSERT_TRUE(DigestInternal(algorithm, input.data(), input.size(), &output)); | |
206 ExpectArrayBufferMatchesHex(test.hex_result, output); | |
207 } | |
208 } | |
209 | |
210 TEST_F(WebCryptoImplTest, HMACSampleSets) { | |
211 struct TestCase { | |
212 WebKit::WebCryptoAlgorithmId algorithm; | |
213 const char* key; | |
214 const char* message; | |
215 const char* mac; | |
216 }; | |
217 | |
218 const TestCase kTests[] = { | |
219 // Empty sets. Result generated via OpenSSL commandline tool. These | |
220 // particular results are also posted on the Wikipedia page examples: | |
221 // http://en.wikipedia.org/wiki/Hash-based_message_authentication_code | |
222 { | |
223 WebKit::WebCryptoAlgorithmIdSha1, | |
224 "", | |
225 "", | |
226 // openssl dgst -sha1 -hmac "" < /dev/null | |
227 "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d", | |
228 }, | |
229 { | |
230 WebKit::WebCryptoAlgorithmIdSha256, | |
231 "", | |
232 "", | |
233 // openssl dgst -sha256 -hmac "" < /dev/null | |
234 "b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad", | |
235 }, | |
236 // For this data, see http://csrc.nist.gov/groups/STM/cavp/index.html#07 | |
237 // Download: | |
238 // http://csrc.nist.gov/groups/STM/cavp/documents/mac/hmactestvectors.zip | |
239 // L=20 set 45 | |
240 { | |
241 WebKit::WebCryptoAlgorithmIdSha1, | |
242 // key | |
243 "59785928d72516e31272", | |
244 // message | |
245 "a3ce8899df1022e8d2d539b47bf0e309c66f84095e21438ec355bf119ce5fdcb4e73a6" | |
246 "19cdf36f25b369d8c38ff419997f0c59830108223606e31223483fd39edeaa4d3f0d21" | |
247 "198862d239c9fd26074130ff6c86493f5227ab895c8f244bd42c7afce5d147a20a5907" | |
248 "98c68e708e964902d124dadecdbda9dbd0051ed710e9bf", | |
249 // mac | |
250 "3c8162589aafaee024fc9a5ca50dd2336fe3eb28", | |
251 }, | |
252 // L=20 set 299 | |
253 { | |
254 WebKit::WebCryptoAlgorithmIdSha1, | |
255 // key | |
256 "ceb9aedf8d6efcf0ae52bea0fa99a9e26ae81bacea0cff4d5eecf201e3bca3c3577480" | |
257 "621b818fd717ba99d6ff958ea3d59b2527b019c343bb199e648090225867d994607962" | |
258 "f5866aa62930d75b58f6", | |
259 // message | |
260 "99958aa459604657c7bf6e4cdfcc8785f0abf06ffe636b5b64ecd931bd8a4563055924" | |
261 "21fc28dbcccb8a82acea2be8e54161d7a78e0399a6067ebaca3f2510274dc9f92f2c8a" | |
262 "e4265eec13d7d42e9f8612d7bc258f913ecb5a3a5c610339b49fb90e9037b02d684fc6" | |
263 "0da835657cb24eab352750c8b463b1a8494660d36c3ab2", | |
264 // mac | |
265 "4ac41ab89f625c60125ed65ffa958c6b490ea670", | |
266 }, | |
267 // L=32, set 30 | |
268 { | |
269 WebKit::WebCryptoAlgorithmIdSha256, | |
270 // key | |
271 "9779d9120642797f1747025d5b22b7ac607cab08e1758f2f3a46c8be1e25c53b8c6a8f" | |
272 "58ffefa176", | |
273 // message | |
274 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a" | |
275 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92" | |
276 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f" | |
277 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e", | |
278 // mac | |
279 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b", | |
280 }, | |
281 // L=32, set 224 | |
282 { | |
283 WebKit::WebCryptoAlgorithmIdSha256, | |
284 // key | |
285 "4b7ab133efe99e02fc89a28409ee187d579e774f4cba6fc223e13504e3511bef8d4f63" | |
286 "8b9aca55d4a43b8fbd64cf9d74dcc8c9e8d52034898c70264ea911a3fd70813fa73b08" | |
287 "3371289b", | |
288 // message | |
289 "138efc832c64513d11b9873c6fd4d8a65dbf367092a826ddd587d141b401580b798c69" | |
290 "025ad510cff05fcfbceb6cf0bb03201aaa32e423d5200925bddfadd418d8e30e18050e" | |
291 "b4f0618eb9959d9f78c1157d4b3e02cd5961f138afd57459939917d9144c95d8e6a94c" | |
292 "8f6d4eef3418c17b1ef0b46c2a7188305d9811dccb3d99", | |
293 // mac | |
294 "4f1ee7cb36c58803a8721d4ac8c4cf8cae5d8832392eed2a96dc59694252801b", | |
295 }, | |
296 }; | |
297 | |
298 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests); | |
299 ++test_index) { | |
300 SCOPED_TRACE(test_index); | |
301 const TestCase& test = kTests[test_index]; | |
302 | |
303 WebKit::WebCryptoAlgorithm algorithm = CreateHmacAlgorithm(test.algorithm); | |
304 | |
305 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString( | |
306 test.key, algorithm, WebKit::WebCryptoKeyUsageSign); | |
307 | |
308 std::vector<uint8> message_raw = HexStringToBytes(test.message); | |
309 | |
310 WebKit::WebArrayBuffer output; | |
311 | |
312 ASSERT_TRUE(SignInternal( | |
313 algorithm, key, message_raw.data(), message_raw.size(), &output)); | |
314 | |
315 ExpectArrayBufferMatchesHex(test.mac, output); | |
316 | |
317 bool signature_match = false; | |
318 EXPECT_TRUE(VerifySignatureInternal( | |
319 algorithm, | |
320 key, | |
321 static_cast<const unsigned char*>(output.data()), | |
322 output.byteLength(), | |
323 message_raw.data(), | |
324 message_raw.size(), | |
325 &signature_match)); | |
326 EXPECT_TRUE(signature_match); | |
327 | |
328 // Ensure truncated signature does not verify by passing one less byte. | |
329 EXPECT_TRUE(VerifySignatureInternal( | |
330 algorithm, | |
331 key, | |
332 static_cast<const unsigned char*>(output.data()), | |
333 output.byteLength() - 1, | |
334 message_raw.data(), | |
335 message_raw.size(), | |
336 &signature_match)); | |
337 EXPECT_FALSE(signature_match); | |
338 | |
339 // Ensure extra long signature does not cause issues and fails. | |
340 const unsigned char kLongSignature[1024] = { 0 }; | |
341 EXPECT_TRUE(VerifySignatureInternal( | |
342 algorithm, | |
343 key, | |
344 kLongSignature, | |
345 sizeof(kLongSignature), | |
346 message_raw.data(), | |
347 message_raw.size(), | |
348 &signature_match)); | |
349 EXPECT_FALSE(signature_match); | |
350 } | |
351 } | |
352 | |
353 } // namespace content | |
OLD | NEW |