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

Side by Side Diff: components/webcrypto/test/rsa_oaep_unittest.cc

Issue 1304063015: [refactor] Rename the webcrypto/openssl and webcrypto/test directories. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@jwk_refactor
Patch Set: Created 5 years, 3 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 2014 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 "base/logging.h"
6 #include "base/stl_util.h"
7 #include "components/webcrypto/algorithm_dispatch.h"
8 #include "components/webcrypto/crypto_data.h"
9 #include "components/webcrypto/jwk.h"
10 #include "components/webcrypto/status.h"
11 #include "components/webcrypto/test/test_helpers.h"
12 #include "components/webcrypto/webcrypto_util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
15 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
16
17 namespace webcrypto {
18
19 namespace {
20
21 // Creates an RSA-OAEP algorithm
22 blink::WebCryptoAlgorithm CreateRsaOaepAlgorithm(
23 const std::vector<uint8_t>& label) {
24 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
25 blink::WebCryptoAlgorithmIdRsaOaep,
26 new blink::WebCryptoRsaOaepParams(
27 !label.empty(), vector_as_array(&label),
28 static_cast<unsigned int>(label.size())));
29 }
30
31 scoped_ptr<base::DictionaryValue> CreatePublicKeyJwkDict() {
32 scoped_ptr<base::DictionaryValue> jwk(new base::DictionaryValue());
33 jwk->SetString("kty", "RSA");
34 jwk->SetString("n",
35 Base64EncodeUrlSafe(HexStringToBytes(kPublicKeyModulusHex)));
36 jwk->SetString("e",
37 Base64EncodeUrlSafe(HexStringToBytes(kPublicKeyExponentHex)));
38 return jwk.Pass();
39 }
40
41 // Import a PKCS#8 private key that uses RSAPrivateKey with the
42 // id-rsaEncryption OID.
43 TEST(WebCryptoRsaOaepTest, ImportPkcs8WithRsaEncryption) {
44 blink::WebCryptoKey private_key;
45 ASSERT_EQ(Status::Success(),
46 ImportKey(blink::WebCryptoKeyFormatPkcs8,
47 CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
48 CreateRsaHashedImportAlgorithm(
49 blink::WebCryptoAlgorithmIdRsaOaep,
50 blink::WebCryptoAlgorithmIdSha1),
51 true, blink::WebCryptoKeyUsageDecrypt, &private_key));
52 }
53
54 TEST(WebCryptoRsaOaepTest, ImportPublicJwkWithNoAlg) {
55 scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
56
57 blink::WebCryptoKey public_key;
58 ASSERT_EQ(
59 Status::Success(),
60 ImportKeyJwkFromDict(*jwk.get(), CreateRsaHashedImportAlgorithm(
61 blink::WebCryptoAlgorithmIdRsaOaep,
62 blink::WebCryptoAlgorithmIdSha1),
63 true, blink::WebCryptoKeyUsageEncrypt, &public_key));
64 }
65
66 TEST(WebCryptoRsaOaepTest, ImportPublicJwkWithMatchingAlg) {
67 scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
68 jwk->SetString("alg", "RSA-OAEP");
69
70 blink::WebCryptoKey public_key;
71 ASSERT_EQ(
72 Status::Success(),
73 ImportKeyJwkFromDict(*jwk.get(), CreateRsaHashedImportAlgorithm(
74 blink::WebCryptoAlgorithmIdRsaOaep,
75 blink::WebCryptoAlgorithmIdSha1),
76 true, blink::WebCryptoKeyUsageEncrypt, &public_key));
77 }
78
79 TEST(WebCryptoRsaOaepTest, ImportPublicJwkWithMismatchedAlgFails) {
80 scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
81 jwk->SetString("alg", "RSA-OAEP-512");
82
83 blink::WebCryptoKey public_key;
84 ASSERT_EQ(
85 Status::ErrorJwkAlgorithmInconsistent(),
86 ImportKeyJwkFromDict(*jwk.get(), CreateRsaHashedImportAlgorithm(
87 blink::WebCryptoAlgorithmIdRsaOaep,
88 blink::WebCryptoAlgorithmIdSha1),
89 true, blink::WebCryptoKeyUsageEncrypt, &public_key));
90 }
91
92 TEST(WebCryptoRsaOaepTest, ImportPublicJwkWithMismatchedTypeFails) {
93 scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
94 jwk->SetString("kty", "oct");
95 jwk->SetString("alg", "RSA-OAEP");
96
97 blink::WebCryptoKey public_key;
98 ASSERT_EQ(
99 Status::ErrorJwkUnexpectedKty("RSA"),
100 ImportKeyJwkFromDict(*jwk.get(), CreateRsaHashedImportAlgorithm(
101 blink::WebCryptoAlgorithmIdRsaOaep,
102 blink::WebCryptoAlgorithmIdSha1),
103 true, blink::WebCryptoKeyUsageEncrypt, &public_key));
104 }
105
106 TEST(WebCryptoRsaOaepTest, ExportPublicJwk) {
107 struct TestData {
108 blink::WebCryptoAlgorithmId hash_alg;
109 const char* expected_jwk_alg;
110 } kTestData[] = {{blink::WebCryptoAlgorithmIdSha1, "RSA-OAEP"},
111 {blink::WebCryptoAlgorithmIdSha256, "RSA-OAEP-256"},
112 {blink::WebCryptoAlgorithmIdSha384, "RSA-OAEP-384"},
113 {blink::WebCryptoAlgorithmIdSha512, "RSA-OAEP-512"}};
114 for (size_t i = 0; i < arraysize(kTestData); ++i) {
115 const TestData& test_data = kTestData[i];
116 SCOPED_TRACE(test_data.expected_jwk_alg);
117
118 scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
119 jwk->SetString("alg", test_data.expected_jwk_alg);
120
121 // Import the key in a known-good format
122 blink::WebCryptoKey public_key;
123 ASSERT_EQ(Status::Success(),
124 ImportKeyJwkFromDict(
125 *jwk.get(),
126 CreateRsaHashedImportAlgorithm(
127 blink::WebCryptoAlgorithmIdRsaOaep, test_data.hash_alg),
128 true, blink::WebCryptoKeyUsageEncrypt, &public_key));
129
130 // Now export the key as JWK and verify its contents
131 std::vector<uint8_t> jwk_data;
132 ASSERT_EQ(Status::Success(),
133 ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &jwk_data));
134 EXPECT_TRUE(VerifyPublicJwk(jwk_data, test_data.expected_jwk_alg,
135 kPublicKeyModulusHex, kPublicKeyExponentHex,
136 blink::WebCryptoKeyUsageEncrypt));
137 }
138 }
139
140 TEST(WebCryptoRsaOaepTest, EncryptDecryptKnownAnswerTest) {
141 scoped_ptr<base::ListValue> tests;
142 ASSERT_TRUE(ReadJsonTestFileToList("rsa_oaep.json", &tests));
143
144 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
145 SCOPED_TRACE(test_index);
146
147 base::DictionaryValue* test = NULL;
148 ASSERT_TRUE(tests->GetDictionary(test_index, &test));
149
150 blink::WebCryptoAlgorithm digest_algorithm =
151 GetDigestAlgorithm(test, "hash");
152 ASSERT_FALSE(digest_algorithm.isNull());
153 std::vector<uint8_t> public_key_der =
154 GetBytesFromHexString(test, "public_key");
155 std::vector<uint8_t> private_key_der =
156 GetBytesFromHexString(test, "private_key");
157 std::vector<uint8_t> ciphertext = GetBytesFromHexString(test, "ciphertext");
158 std::vector<uint8_t> plaintext = GetBytesFromHexString(test, "plaintext");
159 std::vector<uint8_t> label = GetBytesFromHexString(test, "label");
160
161 blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
162 blink::WebCryptoAlgorithmIdRsaOaep, digest_algorithm.id());
163 blink::WebCryptoKey public_key;
164 blink::WebCryptoKey private_key;
165
166 ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
167 public_key_der, private_key_der, import_algorithm, false,
168 blink::WebCryptoKeyUsageEncrypt, blink::WebCryptoKeyUsageDecrypt,
169 &public_key, &private_key));
170
171 blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
172 std::vector<uint8_t> decrypted_data;
173 ASSERT_EQ(Status::Success(),
174 Decrypt(op_algorithm, private_key, CryptoData(ciphertext),
175 &decrypted_data));
176 EXPECT_BYTES_EQ(plaintext, decrypted_data);
177 std::vector<uint8_t> encrypted_data;
178 ASSERT_EQ(Status::Success(),
179 Encrypt(op_algorithm, public_key, CryptoData(plaintext),
180 &encrypted_data));
181 std::vector<uint8_t> redecrypted_data;
182 ASSERT_EQ(Status::Success(),
183 Decrypt(op_algorithm, private_key, CryptoData(encrypted_data),
184 &redecrypted_data));
185 EXPECT_BYTES_EQ(plaintext, redecrypted_data);
186 }
187 }
188
189 TEST(WebCryptoRsaOaepTest, EncryptWithLargeMessageFails) {
190 const blink::WebCryptoAlgorithmId kHash = blink::WebCryptoAlgorithmIdSha1;
191 const size_t kHashSize = 20;
192
193 scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
194
195 blink::WebCryptoKey public_key;
196 ASSERT_EQ(Status::Success(),
197 ImportKeyJwkFromDict(
198 *jwk.get(), CreateRsaHashedImportAlgorithm(
199 blink::WebCryptoAlgorithmIdRsaOaep, kHash),
200 true, blink::WebCryptoKeyUsageEncrypt, &public_key));
201
202 // The maximum size of an encrypted message is:
203 // modulus length
204 // - 1 (leading octet)
205 // - hash size (maskedSeed)
206 // - hash size (lHash portion of maskedDB)
207 // - 1 (at least one octet for the padding string)
208 size_t kMaxMessageSize = (kModulusLengthBits / 8) - 2 - (2 * kHashSize);
209
210 // The label has no influence on the maximum message size. For simplicity,
211 // use the empty string.
212 std::vector<uint8_t> label;
213 blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
214
215 // Test that a message just before the boundary succeeds.
216 std::string large_message;
217 large_message.resize(kMaxMessageSize - 1, 'A');
218
219 std::vector<uint8_t> ciphertext;
220 ASSERT_EQ(Status::Success(), Encrypt(op_algorithm, public_key,
221 CryptoData(large_message), &ciphertext));
222
223 // Test that a message at the boundary succeeds.
224 large_message.resize(kMaxMessageSize, 'A');
225 ciphertext.clear();
226
227 ASSERT_EQ(Status::Success(), Encrypt(op_algorithm, public_key,
228 CryptoData(large_message), &ciphertext));
229
230 // Test that a message greater than the largest size fails.
231 large_message.resize(kMaxMessageSize + 1, 'A');
232 ciphertext.clear();
233
234 ASSERT_EQ(Status::OperationError(),
235 Encrypt(op_algorithm, public_key, CryptoData(large_message),
236 &ciphertext));
237 }
238
239 // Ensures that if the selected hash algorithm for the RSA-OAEP message is too
240 // large, then it is rejected, independent of the actual message to be
241 // encrypted.
242 // For example, a 1024-bit RSA key is too small to accomodate a message that
243 // uses OAEP with SHA-512, since it requires 1040 bits to encode
244 // (2 * hash size + 2 padding bytes).
245 TEST(WebCryptoRsaOaepTest, EncryptWithLargeDigestFails) {
246 const blink::WebCryptoAlgorithmId kHash = blink::WebCryptoAlgorithmIdSha512;
247
248 scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
249
250 blink::WebCryptoKey public_key;
251 ASSERT_EQ(Status::Success(),
252 ImportKeyJwkFromDict(
253 *jwk.get(), CreateRsaHashedImportAlgorithm(
254 blink::WebCryptoAlgorithmIdRsaOaep, kHash),
255 true, blink::WebCryptoKeyUsageEncrypt, &public_key));
256
257 // The label has no influence on the maximum message size. For simplicity,
258 // use the empty string.
259 std::vector<uint8_t> label;
260 blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
261
262 std::string small_message("A");
263 std::vector<uint8_t> ciphertext;
264 // This is an operation error, as the internal consistency checking of the
265 // algorithm parameters is up to the implementation.
266 ASSERT_EQ(Status::OperationError(),
267 Encrypt(op_algorithm, public_key, CryptoData(small_message),
268 &ciphertext));
269 }
270
271 TEST(WebCryptoRsaOaepTest, DecryptWithLargeMessageFails) {
272 blink::WebCryptoKey private_key;
273 ASSERT_EQ(Status::Success(),
274 ImportKey(blink::WebCryptoKeyFormatPkcs8,
275 CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
276 CreateRsaHashedImportAlgorithm(
277 blink::WebCryptoAlgorithmIdRsaOaep,
278 blink::WebCryptoAlgorithmIdSha1),
279 true, blink::WebCryptoKeyUsageDecrypt, &private_key));
280
281 // The label has no influence on the maximum message size. For simplicity,
282 // use the empty string.
283 std::vector<uint8_t> label;
284 blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
285
286 std::string large_dummy_message(kModulusLengthBits / 8, 'A');
287 std::vector<uint8_t> plaintext;
288
289 ASSERT_EQ(Status::OperationError(),
290 Decrypt(op_algorithm, private_key, CryptoData(large_dummy_message),
291 &plaintext));
292 }
293
294 TEST(WebCryptoRsaOaepTest, WrapUnwrapRawKey) {
295 blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
296 blink::WebCryptoAlgorithmIdRsaOaep, blink::WebCryptoAlgorithmIdSha1);
297 blink::WebCryptoKey public_key;
298 blink::WebCryptoKey private_key;
299
300 ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
301 HexStringToBytes(kPublicKeySpkiDerHex),
302 HexStringToBytes(kPrivateKeyPkcs8DerHex), import_algorithm, false,
303 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageWrapKey,
304 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageUnwrapKey,
305 &public_key, &private_key));
306
307 std::vector<uint8_t> label;
308 blink::WebCryptoAlgorithm wrapping_algorithm = CreateRsaOaepAlgorithm(label);
309
310 const std::string key_hex = "000102030405060708090A0B0C0D0E0F";
311 const blink::WebCryptoAlgorithm key_algorithm =
312 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
313
314 blink::WebCryptoKey key =
315 ImportSecretKeyFromRaw(HexStringToBytes(key_hex), key_algorithm,
316 blink::WebCryptoKeyUsageEncrypt);
317 ASSERT_FALSE(key.isNull());
318
319 std::vector<uint8_t> wrapped_key;
320 ASSERT_EQ(Status::Success(),
321 WrapKey(blink::WebCryptoKeyFormatRaw, key, public_key,
322 wrapping_algorithm, &wrapped_key));
323
324 // Verify that |wrapped_key| can be decrypted and yields the key data.
325 // Because |private_key| supports both decrypt and unwrap, this is valid.
326 std::vector<uint8_t> decrypted_key;
327 ASSERT_EQ(Status::Success(),
328 Decrypt(wrapping_algorithm, private_key, CryptoData(wrapped_key),
329 &decrypted_key));
330 EXPECT_BYTES_EQ_HEX(key_hex, decrypted_key);
331
332 // Now attempt to unwrap the key, which should also decrypt the data.
333 blink::WebCryptoKey unwrapped_key;
334 ASSERT_EQ(Status::Success(),
335 UnwrapKey(blink::WebCryptoKeyFormatRaw, CryptoData(wrapped_key),
336 private_key, wrapping_algorithm, key_algorithm, true,
337 blink::WebCryptoKeyUsageEncrypt, &unwrapped_key));
338 ASSERT_FALSE(unwrapped_key.isNull());
339
340 std::vector<uint8_t> raw_key;
341 ASSERT_EQ(Status::Success(),
342 ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key));
343 EXPECT_BYTES_EQ_HEX(key_hex, raw_key);
344 }
345
346 TEST(WebCryptoRsaOaepTest, WrapUnwrapJwkSymKey) {
347 // The public and private portions of a 2048-bit RSA key with the
348 // id-rsaEncryption OID
349 const char kPublicKey2048SpkiDerHex[] =
350 "30820122300d06092a864886f70d01010105000382010f003082010a0282010100c5d8ce"
351 "137a38168c8ab70229cfa5accc640567159750a312ce2e7d54b6e2fdd59b300c6a6c9764"
352 "f8de6f00519cdb90111453d273a967462786480621f9e7cee5b73d63358448e7183a3a68"
353 "e991186359f26aa88fbca5f53e673e502e4c5a2ba5068aeba60c9d0c44d872458d1b1e2f"
354 "7f339f986076d516e93dc750f0b7680b6f5f02bc0d5590495be04c4ae59d34ba17bc5d08"
355 "a93c75cfda2828f4a55b153af912038438276cb4a14f8116ca94db0ea9893652d02fc606"
356 "36f19975e3d79a4d8ea8bfed6f8e0a24b63d243b08ea70a086ad56dd6341d733711c89ca"
357 "749d4a80b3e6ecd2f8e53731eadeac2ea77788ee55d7b4b47c0f2523fbd61b557c16615d"
358 "5d0203010001";
359 const char kPrivateKey2048Pkcs8DerHex[] =
360 "308204bd020100300d06092a864886f70d0101010500048204a7308204a3020100028201"
361 "0100c5d8ce137a38168c8ab70229cfa5accc640567159750a312ce2e7d54b6e2fdd59b30"
362 "0c6a6c9764f8de6f00519cdb90111453d273a967462786480621f9e7cee5b73d63358448"
363 "e7183a3a68e991186359f26aa88fbca5f53e673e502e4c5a2ba5068aeba60c9d0c44d872"
364 "458d1b1e2f7f339f986076d516e93dc750f0b7680b6f5f02bc0d5590495be04c4ae59d34"
365 "ba17bc5d08a93c75cfda2828f4a55b153af912038438276cb4a14f8116ca94db0ea98936"
366 "52d02fc60636f19975e3d79a4d8ea8bfed6f8e0a24b63d243b08ea70a086ad56dd6341d7"
367 "33711c89ca749d4a80b3e6ecd2f8e53731eadeac2ea77788ee55d7b4b47c0f2523fbd61b"
368 "557c16615d5d02030100010282010074b70feb41a0b0fcbc207670400556c9450042ede3"
369 "d4383fb1ce8f3558a6d4641d26dd4c333fa4db842d2b9cf9d2354d3e16ad027a9f682d8c"
370 "f4145a1ad97b9edcd8a41c402bd9d8db10f62f43df854cdccbbb2100834f083f53ed6d42"
371 "b1b729a59072b004a4e945fc027db15e9c121d1251464d320d4774d5732df6b3dbf751f4"
372 "9b19c9db201e19989c883bbaad5333db47f64f6f7a95b8d4936b10d945aa3f794cfaab62"
373 "e7d47686129358914f3b8085f03698a650ab5b8c7e45813f2b0515ec05b6e5195b6a7c2a"
374 "0d36969745f431ded4fd059f6aa361a4649541016d356297362b778e90f077d48815b339"
375 "ec6f43aba345df93e67fcb6c2cb5b4544e9be902818100e9c90abe5f9f32468c5b6d630c"
376 "54a4d7d75e29a72cf792f21e242aac78fd7995c42dfd4ae871d2619ff7096cb05baa78e3"
377 "23ecab338401a8059adf7a0d8be3b21edc9a9c82c5605634a2ec81ec053271721351868a"
378 "4c2e50c689d7cef94e31ff23658af5843366e2b289c5bf81d72756a7b93487dd8770d69c"
379 "1f4e089d6d89f302818100d8a58a727c4e209132afd9933b98c89aca862a01cc0be74133"
380 "bee517909e5c379e526895ac4af11780c1fe91194c777c9670b6423f0f5a32fd7691a622"
381 "113eef4bed2ef863363a335fd55b0e75088c582437237d7f3ed3f0a643950237bc6e6277"
382 "ccd0d0a1b4170aa1047aa7ffa7c8c54be10e8c7327ae2e0885663963817f6f02818100e5"
383 "aed9ba4d71b7502e6748a1ce247ecb7bd10c352d6d9256031cdf3c11a65e44b0b7ca2945"
384 "134671195af84c6b3bb3d10ebf65ae916f38bd5dbc59a0ad1c69b8beaf57cb3a8335f19b"
385 "c7117b576987b48331cd9fd3d1a293436b7bb5e1a35c6560de4b5688ea834367cb0997eb"
386 "b578f59ed4cb724c47dba94d3b484c1876dcd70281807f15bc7d2406007cac2b138a96af"
387 "2d1e00276b84da593132c253fcb73212732dfd25824c2a615bc3d9b7f2c8d2fa542d3562"
388 "b0c7738e61eeff580a6056239fb367ea9e5efe73d4f846033602e90c36a78db6fa8ea792"
389 "0769675ec58e237bd994d189c8045a96f5dd3a4f12547257ce224e3c9af830a4da3c0eab"
390 "9227a0035ae9028180067caea877e0b23090fc689322b71fbcce63d6596e66ab5fcdbaa0"
391 "0d49e93aba8effb4518c2da637f209028401a68f344865b4956b032c69acde51d29177ca"
392 "3db99fdbf5e74848ed4fa7bdfc2ebb60e2aaa5354770a763e1399ab7a2099762d525fea0"
393 "37f3e1972c45a477e66db95c9609bb27f862700ef93379930786cf751b";
394 blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
395 blink::WebCryptoAlgorithmIdRsaOaep, blink::WebCryptoAlgorithmIdSha1);
396 blink::WebCryptoKey public_key;
397 blink::WebCryptoKey private_key;
398
399 ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
400 HexStringToBytes(kPublicKey2048SpkiDerHex),
401 HexStringToBytes(kPrivateKey2048Pkcs8DerHex), import_algorithm, false,
402 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageWrapKey,
403 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageUnwrapKey,
404 &public_key, &private_key));
405
406 std::vector<uint8_t> label;
407 blink::WebCryptoAlgorithm wrapping_algorithm = CreateRsaOaepAlgorithm(label);
408
409 const std::string key_hex = "000102030405060708090a0b0c0d0e0f";
410 const blink::WebCryptoAlgorithm key_algorithm =
411 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
412
413 blink::WebCryptoKey key =
414 ImportSecretKeyFromRaw(HexStringToBytes(key_hex), key_algorithm,
415 blink::WebCryptoKeyUsageEncrypt);
416 ASSERT_FALSE(key.isNull());
417
418 std::vector<uint8_t> wrapped_key;
419 ASSERT_EQ(Status::Success(),
420 WrapKey(blink::WebCryptoKeyFormatJwk, key, public_key,
421 wrapping_algorithm, &wrapped_key));
422
423 // Verify that |wrapped_key| can be decrypted and yields a valid JWK object.
424 // Because |private_key| supports both decrypt and unwrap, this is valid.
425 std::vector<uint8_t> decrypted_jwk;
426 ASSERT_EQ(Status::Success(),
427 Decrypt(wrapping_algorithm, private_key, CryptoData(wrapped_key),
428 &decrypted_jwk));
429 EXPECT_TRUE(VerifySecretJwk(decrypted_jwk, "A128CBC", key_hex,
430 blink::WebCryptoKeyUsageEncrypt));
431
432 // Now attempt to unwrap the key, which should also decrypt the data.
433 blink::WebCryptoKey unwrapped_key;
434 ASSERT_EQ(Status::Success(),
435 UnwrapKey(blink::WebCryptoKeyFormatJwk, CryptoData(wrapped_key),
436 private_key, wrapping_algorithm, key_algorithm, true,
437 blink::WebCryptoKeyUsageEncrypt, &unwrapped_key));
438 ASSERT_FALSE(unwrapped_key.isNull());
439
440 std::vector<uint8_t> raw_key;
441 ASSERT_EQ(Status::Success(),
442 ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key));
443 EXPECT_BYTES_EQ_HEX(key_hex, raw_key);
444 }
445
446 TEST(WebCryptoRsaOaepTest, ImportExportJwkRsaPublicKey) {
447 struct TestCase {
448 const blink::WebCryptoAlgorithmId hash;
449 const blink::WebCryptoKeyUsageMask usage;
450 const char* const jwk_alg;
451 };
452 const TestCase kTests[] = {{blink::WebCryptoAlgorithmIdSha1,
453 blink::WebCryptoKeyUsageEncrypt,
454 "RSA-OAEP"},
455 {blink::WebCryptoAlgorithmIdSha256,
456 blink::WebCryptoKeyUsageEncrypt,
457 "RSA-OAEP-256"},
458 {blink::WebCryptoAlgorithmIdSha384,
459 blink::WebCryptoKeyUsageEncrypt,
460 "RSA-OAEP-384"},
461 {blink::WebCryptoAlgorithmIdSha512,
462 blink::WebCryptoKeyUsageEncrypt,
463 "RSA-OAEP-512"}};
464
465 for (size_t test_index = 0; test_index < arraysize(kTests); ++test_index) {
466 SCOPED_TRACE(test_index);
467 const TestCase& test = kTests[test_index];
468
469 const blink::WebCryptoAlgorithm import_algorithm =
470 CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaOaep,
471 test.hash);
472
473 // Import the spki to create a public key
474 blink::WebCryptoKey public_key;
475 ASSERT_EQ(Status::Success(),
476 ImportKey(blink::WebCryptoKeyFormatSpki,
477 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
478 import_algorithm, true, test.usage, &public_key));
479
480 // Export the public key as JWK and verify its contents
481 std::vector<uint8_t> jwk;
482 ASSERT_EQ(Status::Success(),
483 ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &jwk));
484 EXPECT_TRUE(VerifyPublicJwk(jwk, test.jwk_alg, kPublicKeyModulusHex,
485 kPublicKeyExponentHex, test.usage));
486
487 // Import the JWK back in to create a new key
488 blink::WebCryptoKey public_key2;
489 ASSERT_EQ(Status::Success(),
490 ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(jwk),
491 import_algorithm, true, test.usage, &public_key2));
492 ASSERT_TRUE(public_key2.handle());
493 EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key2.type());
494 EXPECT_TRUE(public_key2.extractable());
495 EXPECT_EQ(import_algorithm.id(), public_key2.algorithm().id());
496
497 // TODO(eroman): Export the SPKI and verify matches.
498 }
499 }
500
501 } // namespace
502
503 } // namespace webcrypto
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698