Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / webcrypto / algorithms / aes_cbc_unittest.cc
blob657c4a4c4325ee5f6c9f1a74464c050f04cff1f3
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.
5 #include "base/stl_util.h"
6 #include "components/webcrypto/algorithm_dispatch.h"
7 #include "components/webcrypto/algorithms/test_helpers.h"
8 #include "components/webcrypto/crypto_data.h"
9 #include "components/webcrypto/status.h"
10 #include "components/webcrypto/webcrypto_util.h"
11 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
12 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
14 namespace webcrypto {
16 namespace {
18 // Creates an AES-CBC algorithm.
19 blink::WebCryptoAlgorithm CreateAesCbcAlgorithm(
20 const std::vector<uint8_t>& iv) {
21 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
22 blink::WebCryptoAlgorithmIdAesCbc,
23 new blink::WebCryptoAesCbcParams(vector_as_array(&iv),
24 static_cast<unsigned int>(iv.size())));
27 blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm(
28 unsigned short key_length_bits) {
29 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesCbc,
30 key_length_bits);
33 blink::WebCryptoKey GetTestAesCbcKey() {
34 const std::string key_hex = "2b7e151628aed2a6abf7158809cf4f3c";
35 blink::WebCryptoKey key = ImportSecretKeyFromRaw(
36 HexStringToBytes(key_hex),
37 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
38 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
40 // Verify exported raw key is identical to the imported data
41 std::vector<uint8_t> raw_key;
42 EXPECT_EQ(Status::Success(),
43 ExportKey(blink::WebCryptoKeyFormatRaw, key, &raw_key));
44 EXPECT_BYTES_EQ_HEX(key_hex, raw_key);
45 return key;
48 class WebCryptoAesCbcTest : public WebCryptoTestBase {};
50 TEST_F(WebCryptoAesCbcTest, InputTooLarge) {
51 std::vector<uint8_t> output;
53 std::vector<uint8_t> iv(16);
55 // Give an input that is too large. It would cause integer overflow when
56 // narrowing the ciphertext size to an int, since OpenSSL operates on signed
57 // int lengths NOT unsigned.
59 // Pretend the input is large. Don't pass data pointer as NULL in case that
60 // is special cased; the implementation shouldn't actually dereference the
61 // data.
62 CryptoData input(&iv[0], INT_MAX - 3);
64 EXPECT_EQ(
65 Status::ErrorDataTooLarge(),
66 Encrypt(CreateAesCbcAlgorithm(iv), GetTestAesCbcKey(), input, &output));
67 EXPECT_EQ(
68 Status::ErrorDataTooLarge(),
69 Decrypt(CreateAesCbcAlgorithm(iv), GetTestAesCbcKey(), input, &output));
72 TEST_F(WebCryptoAesCbcTest, ExportKeyUnsupportedFormat) {
73 std::vector<uint8_t> output;
75 // Fail exporting the key in SPKI and PKCS#8 formats (not allowed for secret
76 // keys).
77 EXPECT_EQ(
78 Status::ErrorUnsupportedExportKeyFormat(),
79 ExportKey(blink::WebCryptoKeyFormatSpki, GetTestAesCbcKey(), &output));
80 EXPECT_EQ(
81 Status::ErrorUnsupportedExportKeyFormat(),
82 ExportKey(blink::WebCryptoKeyFormatPkcs8, GetTestAesCbcKey(), &output));
85 // Tests importing of keys (in a variety of formats), errors during import,
86 // encryption, and decryption, using known answers.
87 TEST_F(WebCryptoAesCbcTest, KnownAnswerEncryptDecrypt) {
88 scoped_ptr<base::ListValue> tests;
89 ASSERT_TRUE(ReadJsonTestFileToList("aes_cbc.json", &tests));
91 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
92 SCOPED_TRACE(test_index);
93 base::DictionaryValue* test;
94 ASSERT_TRUE(tests->GetDictionary(test_index, &test));
96 blink::WebCryptoKeyFormat key_format = GetKeyFormatFromJsonTestCase(test);
97 std::vector<uint8_t> key_data =
98 GetKeyDataFromJsonTestCase(test, key_format);
99 std::string import_error = "Success";
100 test->GetString("import_error", &import_error);
102 // Import the key.
103 blink::WebCryptoKey key;
104 Status status = ImportKey(
105 key_format, CryptoData(key_data),
106 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true,
107 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
108 &key);
109 ASSERT_EQ(import_error, StatusToString(status));
110 if (status.IsError())
111 continue;
113 // Test encryption.
114 if (test->HasKey("plain_text")) {
115 std::vector<uint8_t> test_plain_text =
116 GetBytesFromHexString(test, "plain_text");
118 std::vector<uint8_t> test_iv = GetBytesFromHexString(test, "iv");
120 std::string encrypt_error = "Success";
121 test->GetString("encrypt_error", &encrypt_error);
123 std::vector<uint8_t> output;
124 status = Encrypt(CreateAesCbcAlgorithm(test_iv), key,
125 CryptoData(test_plain_text), &output);
126 ASSERT_EQ(encrypt_error, StatusToString(status));
127 if (status.IsError())
128 continue;
130 std::vector<uint8_t> test_cipher_text =
131 GetBytesFromHexString(test, "cipher_text");
133 EXPECT_BYTES_EQ(test_cipher_text, output);
136 // Test decryption.
137 if (test->HasKey("cipher_text")) {
138 std::vector<uint8_t> test_cipher_text =
139 GetBytesFromHexString(test, "cipher_text");
141 std::vector<uint8_t> test_iv = GetBytesFromHexString(test, "iv");
143 std::string decrypt_error = "Success";
144 test->GetString("decrypt_error", &decrypt_error);
146 std::vector<uint8_t> output;
147 status = Decrypt(CreateAesCbcAlgorithm(test_iv), key,
148 CryptoData(test_cipher_text), &output);
149 ASSERT_EQ(decrypt_error, StatusToString(status));
150 if (status.IsError())
151 continue;
153 std::vector<uint8_t> test_plain_text =
154 GetBytesFromHexString(test, "plain_text");
156 EXPECT_BYTES_EQ(test_plain_text, output);
161 // TODO(eroman): Do this same test for AES-GCM, AES-KW, AES-CTR ?
162 TEST_F(WebCryptoAesCbcTest, GenerateKeyIsRandom) {
163 // Check key generation for each allowed key length.
164 std::vector<blink::WebCryptoAlgorithm> algorithm;
165 const unsigned short kKeyLength[] = {128, 256};
166 for (size_t key_length_i = 0; key_length_i < arraysize(kKeyLength);
167 ++key_length_i) {
168 blink::WebCryptoKey key;
170 std::vector<std::vector<uint8_t>> keys;
171 std::vector<uint8_t> key_bytes;
173 // Generate a small sample of keys.
174 for (int j = 0; j < 16; ++j) {
175 ASSERT_EQ(Status::Success(),
176 GenerateSecretKey(
177 CreateAesCbcKeyGenAlgorithm(kKeyLength[key_length_i]), true,
178 blink::WebCryptoKeyUsageEncrypt, &key));
179 EXPECT_TRUE(key.handle());
180 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
181 ASSERT_EQ(Status::Success(),
182 ExportKey(blink::WebCryptoKeyFormatRaw, key, &key_bytes));
183 EXPECT_EQ(key_bytes.size() * 8,
184 key.algorithm().aesParams()->lengthBits());
185 keys.push_back(key_bytes);
187 // Ensure all entries in the key sample set are unique. This is a simplistic
188 // estimate of whether the generated keys appear random.
189 EXPECT_FALSE(CopiesExist(keys));
193 TEST_F(WebCryptoAesCbcTest, GenerateKeyBadLength) {
194 const unsigned short kKeyLen[] = {0, 127, 257};
195 blink::WebCryptoKey key;
196 for (size_t i = 0; i < arraysize(kKeyLen); ++i) {
197 SCOPED_TRACE(i);
198 EXPECT_EQ(Status::ErrorGenerateAesKeyLength(),
199 GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(kKeyLen[i]), true,
200 blink::WebCryptoKeyUsageEncrypt, &key));
204 TEST_F(WebCryptoAesCbcTest, ImportKeyEmptyUsage) {
205 blink::WebCryptoKey key;
206 ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
207 ImportKey(blink::WebCryptoKeyFormatRaw,
208 CryptoData(std::vector<uint8_t>(16)),
209 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true,
210 0, &key));
213 // If key_ops is specified but empty, no key usages are allowed for the key.
214 TEST_F(WebCryptoAesCbcTest, ImportKeyJwkEmptyKeyOps) {
215 blink::WebCryptoKey key;
216 base::DictionaryValue dict;
217 dict.SetString("kty", "oct");
218 dict.SetBoolean("ext", false);
219 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
220 dict.Set("key_ops", new base::ListValue); // Takes ownership.
222 // The JWK does not contain encrypt usages.
223 EXPECT_EQ(Status::ErrorJwkKeyopsInconsistent(),
224 ImportKeyJwkFromDict(
225 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
226 blink::WebCryptoKeyUsageEncrypt, &key));
228 // The JWK does not contain sign usage (nor is it applicable).
229 EXPECT_EQ(Status::ErrorCreateKeyBadUsages(),
230 ImportKeyJwkFromDict(
231 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
232 blink::WebCryptoKeyUsageSign, &key));
235 // If key_ops is missing, then any key usages can be specified.
236 TEST_F(WebCryptoAesCbcTest, ImportKeyJwkNoKeyOps) {
237 blink::WebCryptoKey key;
238 base::DictionaryValue dict;
239 dict.SetString("kty", "oct");
240 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
242 EXPECT_EQ(Status::Success(),
243 ImportKeyJwkFromDict(
244 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
245 blink::WebCryptoKeyUsageEncrypt, &key));
247 EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages());
249 // The JWK does not contain sign usage (nor is it applicable).
250 EXPECT_EQ(Status::ErrorCreateKeyBadUsages(),
251 ImportKeyJwkFromDict(
252 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
253 blink::WebCryptoKeyUsageVerify, &key));
256 TEST_F(WebCryptoAesCbcTest, ImportKeyJwkKeyOpsEncryptDecrypt) {
257 blink::WebCryptoKey key;
258 base::DictionaryValue dict;
259 dict.SetString("kty", "oct");
260 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
261 base::ListValue* key_ops = new base::ListValue;
262 dict.Set("key_ops", key_ops); // Takes ownership.
264 key_ops->AppendString("encrypt");
266 EXPECT_EQ(Status::Success(),
267 ImportKeyJwkFromDict(
268 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
269 blink::WebCryptoKeyUsageEncrypt, &key));
271 EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages());
273 key_ops->AppendString("decrypt");
275 EXPECT_EQ(Status::Success(),
276 ImportKeyJwkFromDict(
277 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
278 blink::WebCryptoKeyUsageDecrypt, &key));
280 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt, key.usages());
282 EXPECT_EQ(
283 Status::Success(),
284 ImportKeyJwkFromDict(
285 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
286 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt,
287 &key));
289 EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
290 key.usages());
293 // Test failure if input usage is NOT a strict subset of the JWK usage.
294 TEST_F(WebCryptoAesCbcTest, ImportKeyJwkKeyOpsNotSuperset) {
295 blink::WebCryptoKey key;
296 base::DictionaryValue dict;
297 dict.SetString("kty", "oct");
298 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
299 base::ListValue* key_ops = new base::ListValue;
300 dict.Set("key_ops", key_ops); // Takes ownership.
302 key_ops->AppendString("encrypt");
304 EXPECT_EQ(
305 Status::ErrorJwkKeyopsInconsistent(),
306 ImportKeyJwkFromDict(
307 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
308 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
309 &key));
312 TEST_F(WebCryptoAesCbcTest, ImportKeyJwkUseEnc) {
313 blink::WebCryptoKey key;
314 base::DictionaryValue dict;
315 dict.SetString("kty", "oct");
316 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
318 // Test JWK composite use 'enc' usage
319 dict.SetString("alg", "A128CBC");
320 dict.SetString("use", "enc");
321 EXPECT_EQ(
322 Status::Success(),
323 ImportKeyJwkFromDict(
324 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
325 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt |
326 blink::WebCryptoKeyUsageWrapKey |
327 blink::WebCryptoKeyUsageUnwrapKey,
328 &key));
329 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt |
330 blink::WebCryptoKeyUsageWrapKey |
331 blink::WebCryptoKeyUsageUnwrapKey,
332 key.usages());
335 TEST_F(WebCryptoAesCbcTest, ImportJwkInvalidJson) {
336 blink::WebCryptoKey key;
337 // Fail on empty JSON.
338 EXPECT_EQ(
339 Status::ErrorJwkNotDictionary(),
340 ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(MakeJsonVector("")),
341 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
342 blink::WebCryptoKeyUsageEncrypt, &key));
344 // Fail on invalid JSON.
345 const std::vector<uint8_t> bad_json_vec = MakeJsonVector(
347 "\"kty\" : \"oct\","
348 "\"alg\" : \"HS256\","
349 "\"use\" : ");
350 EXPECT_EQ(Status::ErrorJwkNotDictionary(),
351 ImportKey(blink::WebCryptoKeyFormatJwk, CryptoData(bad_json_vec),
352 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
353 blink::WebCryptoKeyUsageEncrypt, &key));
356 // Fail on inconsistent key_ops - asking for "encrypt" however JWK contains
357 // only "foo".
358 TEST_F(WebCryptoAesCbcTest, ImportJwkKeyOpsLacksUsages) {
359 blink::WebCryptoKey key;
361 base::DictionaryValue dict;
362 dict.SetString("kty", "oct");
363 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg");
365 base::ListValue* key_ops = new base::ListValue;
366 // Note: the following call makes dict assume ownership of key_ops.
367 dict.Set("key_ops", key_ops);
368 key_ops->AppendString("foo");
369 EXPECT_EQ(Status::ErrorJwkKeyopsInconsistent(),
370 ImportKeyJwkFromDict(
371 dict, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), false,
372 blink::WebCryptoKeyUsageEncrypt, &key));
375 TEST_F(WebCryptoAesCbcTest, ImportExportJwk) {
376 const blink::WebCryptoAlgorithm algorithm =
377 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
379 // AES-CBC 128
380 ImportExportJwkSymmetricKey(
381 128, algorithm,
382 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt,
383 "A128CBC");
385 // AES-CBC 256
386 ImportExportJwkSymmetricKey(256, algorithm, blink::WebCryptoKeyUsageDecrypt,
387 "A256CBC");
389 // Large usage value
390 ImportExportJwkSymmetricKey(
391 256, algorithm,
392 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt |
393 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey,
394 "A256CBC");
397 // AES 192-bit is not allowed: http://crbug.com/381829
398 TEST_F(WebCryptoAesCbcTest, GenerateAesCbc192) {
399 blink::WebCryptoKey key;
400 Status status = GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(192), true,
401 blink::WebCryptoKeyUsageEncrypt, &key);
402 ASSERT_EQ(Status::ErrorAes192BitUnsupported(), status);
405 // AES 192-bit is not allowed: http://crbug.com/381829
406 TEST_F(WebCryptoAesCbcTest, UnwrapAesCbc192) {
407 std::vector<uint8_t> wrapping_key_data(16, 0);
408 std::vector<uint8_t> wrapped_key = HexStringToBytes(
409 "1A07ACAB6C906E50883173C29441DB1DE91D34F45C435B5F99C822867FB3956F");
411 blink::WebCryptoKey wrapping_key = ImportSecretKeyFromRaw(
412 wrapping_key_data, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
413 blink::WebCryptoKeyUsageUnwrapKey);
415 blink::WebCryptoKey unwrapped_key;
416 ASSERT_EQ(
417 Status::ErrorAes192BitUnsupported(),
418 UnwrapKey(blink::WebCryptoKeyFormatRaw, CryptoData(wrapped_key),
419 wrapping_key, CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw),
420 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), true,
421 blink::WebCryptoKeyUsageEncrypt, &unwrapped_key));
424 // Try importing an AES-CBC key with unsupported key usages using raw
425 // format. AES-CBC keys support the following usages:
426 // 'encrypt', 'decrypt', 'wrapKey', 'unwrapKey'
427 TEST_F(WebCryptoAesCbcTest, ImportKeyBadUsage_Raw) {
428 const blink::WebCryptoAlgorithm algorithm =
429 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
431 blink::WebCryptoKeyUsageMask bad_usages[] = {
432 blink::WebCryptoKeyUsageSign,
433 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageDecrypt,
434 blink::WebCryptoKeyUsageDeriveBits,
435 blink::WebCryptoKeyUsageUnwrapKey | blink::WebCryptoKeyUsageVerify,
438 std::vector<uint8_t> key_bytes(16);
440 for (size_t i = 0; i < arraysize(bad_usages); ++i) {
441 SCOPED_TRACE(i);
443 blink::WebCryptoKey key;
444 ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
445 ImportKey(blink::WebCryptoKeyFormatRaw, CryptoData(key_bytes),
446 algorithm, true, bad_usages[i], &key));
450 // Generate an AES-CBC key with invalid usages. AES-CBC supports:
451 // 'encrypt', 'decrypt', 'wrapKey', 'unwrapKey'
452 TEST_F(WebCryptoAesCbcTest, GenerateKeyBadUsages) {
453 blink::WebCryptoKeyUsageMask bad_usages[] = {
454 blink::WebCryptoKeyUsageSign,
455 blink::WebCryptoKeyUsageVerify,
456 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageVerify,
459 for (size_t i = 0; i < arraysize(bad_usages); ++i) {
460 SCOPED_TRACE(i);
462 blink::WebCryptoKey key;
464 ASSERT_EQ(Status::ErrorCreateKeyBadUsages(),
465 GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(128), true,
466 bad_usages[i], &key));
470 // Generate an AES-CBC key with no usages.
471 TEST_F(WebCryptoAesCbcTest, GenerateKeyEmptyUsages) {
472 blink::WebCryptoKey key;
474 ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(),
475 GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(128), true, 0, &key));
478 // Generate an AES-CBC key and an RSA key pair. Use the AES-CBC key to wrap the
479 // key pair (using SPKI format for public key, PKCS8 format for private key).
480 // Then unwrap the wrapped key pair and verify that the key data is the same.
481 TEST_F(WebCryptoAesCbcTest, WrapUnwrapRoundtripSpkiPkcs8) {
482 // Generate the wrapping key.
483 blink::WebCryptoKey wrapping_key;
484 ASSERT_EQ(Status::Success(),
485 GenerateSecretKey(CreateAesCbcKeyGenAlgorithm(128), true,
486 blink::WebCryptoKeyUsageWrapKey |
487 blink::WebCryptoKeyUsageUnwrapKey,
488 &wrapping_key));
490 // Generate an RSA key pair to be wrapped.
491 const unsigned int modulus_length = 256;
492 const std::vector<uint8_t> public_exponent = HexStringToBytes("010001");
494 blink::WebCryptoKey public_key;
495 blink::WebCryptoKey private_key;
496 ASSERT_EQ(Status::Success(),
497 GenerateKeyPair(CreateRsaHashedKeyGenAlgorithm(
498 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
499 blink::WebCryptoAlgorithmIdSha256,
500 modulus_length, public_exponent),
501 true, blink::WebCryptoKeyUsageSign, &public_key,
502 &private_key));
504 // Export key pair as SPKI + PKCS8
505 std::vector<uint8_t> public_key_spki;
506 ASSERT_EQ(Status::Success(), ExportKey(blink::WebCryptoKeyFormatSpki,
507 public_key, &public_key_spki));
509 std::vector<uint8_t> private_key_pkcs8;
510 ASSERT_EQ(Status::Success(), ExportKey(blink::WebCryptoKeyFormatPkcs8,
511 private_key, &private_key_pkcs8));
513 // Wrap the key pair.
514 blink::WebCryptoAlgorithm wrap_algorithm =
515 CreateAesCbcAlgorithm(std::vector<uint8_t>(16, 0));
517 std::vector<uint8_t> wrapped_public_key;
518 ASSERT_EQ(Status::Success(),
519 WrapKey(blink::WebCryptoKeyFormatSpki, public_key, wrapping_key,
520 wrap_algorithm, &wrapped_public_key));
522 std::vector<uint8_t> wrapped_private_key;
523 ASSERT_EQ(Status::Success(),
524 WrapKey(blink::WebCryptoKeyFormatPkcs8, private_key, wrapping_key,
525 wrap_algorithm, &wrapped_private_key));
527 // Unwrap the key pair.
528 blink::WebCryptoAlgorithm rsa_import_algorithm =
529 CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5,
530 blink::WebCryptoAlgorithmIdSha256);
532 blink::WebCryptoKey unwrapped_public_key;
534 ASSERT_EQ(
535 Status::Success(),
536 UnwrapKey(blink::WebCryptoKeyFormatSpki, CryptoData(wrapped_public_key),
537 wrapping_key, wrap_algorithm, rsa_import_algorithm, true,
538 blink::WebCryptoKeyUsageVerify, &unwrapped_public_key));
540 blink::WebCryptoKey unwrapped_private_key;
542 ASSERT_EQ(
543 Status::Success(),
544 UnwrapKey(blink::WebCryptoKeyFormatPkcs8, CryptoData(wrapped_private_key),
545 wrapping_key, wrap_algorithm, rsa_import_algorithm, true,
546 blink::WebCryptoKeyUsageSign, &unwrapped_private_key));
548 // Export unwrapped key pair as SPKI + PKCS8
549 std::vector<uint8_t> unwrapped_public_key_spki;
550 ASSERT_EQ(Status::Success(),
551 ExportKey(blink::WebCryptoKeyFormatSpki, unwrapped_public_key,
552 &unwrapped_public_key_spki));
554 std::vector<uint8_t> unwrapped_private_key_pkcs8;
555 ASSERT_EQ(Status::Success(),
556 ExportKey(blink::WebCryptoKeyFormatPkcs8, unwrapped_private_key,
557 &unwrapped_private_key_pkcs8));
559 EXPECT_EQ(public_key_spki, unwrapped_public_key_spki);
560 EXPECT_EQ(private_key_pkcs8, unwrapped_private_key_pkcs8);
562 EXPECT_NE(public_key_spki, wrapped_public_key);
563 EXPECT_NE(private_key_pkcs8, wrapped_private_key);
566 } // namespace
568 } // namespace webcrypto