OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/child/webcrypto/shared_crypto.h" | 5 #include "content/child/webcrypto/shared_crypto.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
14 #include "base/json/json_writer.h" | 14 #include "base/json/json_writer.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
17 #include "base/path_service.h" | 17 #include "base/path_service.h" |
18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
19 #include "base/values.h" | 19 #include "base/strings/string_util.h" |
20 #include "content/child/webcrypto/crypto_data.h" | 20 #include "content/child/webcrypto/crypto_data.h" |
21 #include "content/child/webcrypto/webcrypto_util.h" | 21 #include "content/child/webcrypto/webcrypto_util.h" |
22 #include "content/public/common/content_paths.h" | 22 #include "content/public/common/content_paths.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
24 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" | 24 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" |
25 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | 25 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
26 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 26 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
27 #include "third_party/WebKit/public/platform/WebCryptoKey.h" | 27 #include "third_party/WebKit/public/platform/WebCryptoKey.h" |
28 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 28 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
29 #include "third_party/re2/re2/re2.h" | 29 #include "third_party/re2/re2/re2.h" |
(...skipping 14 matching lines...) Expand all Loading... |
44 ASSERT_EQ(expected.ToString(), (code).ToString()) | 44 ASSERT_EQ(expected.ToString(), (code).ToString()) |
45 #define EXPECT_STATUS_SUCCESS(code) EXPECT_STATUS(Status::Success(), code) | 45 #define EXPECT_STATUS_SUCCESS(code) EXPECT_STATUS(Status::Success(), code) |
46 #define ASSERT_STATUS_SUCCESS(code) ASSERT_STATUS(Status::Success(), code) | 46 #define ASSERT_STATUS_SUCCESS(code) ASSERT_STATUS(Status::Success(), code) |
47 | 47 |
48 namespace content { | 48 namespace content { |
49 | 49 |
50 namespace webcrypto { | 50 namespace webcrypto { |
51 | 51 |
52 namespace { | 52 namespace { |
53 | 53 |
| 54 // TODO(eroman): For Linux builds using system NSS, AES-GCM support is a |
| 55 // runtime dependency. Test it by trying to import a key. |
| 56 // TODO(padolph): Consider caching the result of the import key test. |
| 57 bool SupportsAesGcm() { |
| 58 std::vector<uint8> key_raw(16, 0); |
| 59 |
| 60 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 61 Status status = ImportKey(blink::WebCryptoKeyFormatRaw, |
| 62 CryptoData(key_raw), |
| 63 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm), |
| 64 true, |
| 65 blink::WebCryptoKeyUsageEncrypt, |
| 66 &key); |
| 67 |
| 68 if (status.IsError()) |
| 69 EXPECT_STATUS(Status::ErrorUnsupported(), status); |
| 70 return status.IsSuccess(); |
| 71 } |
| 72 |
54 blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm( | 73 blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm( |
55 blink::WebCryptoAlgorithmId algorithm_id, | 74 blink::WebCryptoAlgorithmId algorithm_id, |
56 unsigned int modulus_length, | 75 unsigned int modulus_length, |
57 const std::vector<uint8>& public_exponent) { | 76 const std::vector<uint8>& public_exponent) { |
58 DCHECK_EQ(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, algorithm_id); | 77 DCHECK_EQ(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, algorithm_id); |
59 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 78 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
60 algorithm_id, | 79 algorithm_id, |
61 new blink::WebCryptoRsaKeyGenParams( | 80 new blink::WebCryptoRsaKeyGenParams( |
62 modulus_length, | 81 modulus_length, |
63 webcrypto::Uint8VectorStart(public_exponent), | 82 webcrypto::Uint8VectorStart(public_exponent), |
(...skipping 22 matching lines...) Expand all Loading... |
86 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 105 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
87 blink::WebCryptoAlgorithmIdAesCbc, | 106 blink::WebCryptoAlgorithmIdAesCbc, |
88 new blink::WebCryptoAesCbcParams(Uint8VectorStart(iv), iv.size())); | 107 new blink::WebCryptoAesCbcParams(Uint8VectorStart(iv), iv.size())); |
89 } | 108 } |
90 | 109 |
91 // Creates and AES-GCM algorithm. | 110 // Creates and AES-GCM algorithm. |
92 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm( | 111 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm( |
93 const std::vector<uint8>& iv, | 112 const std::vector<uint8>& iv, |
94 const std::vector<uint8>& additional_data, | 113 const std::vector<uint8>& additional_data, |
95 unsigned int tag_length_bits) { | 114 unsigned int tag_length_bits) { |
| 115 EXPECT_TRUE(SupportsAesGcm()); |
96 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 116 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
97 blink::WebCryptoAlgorithmIdAesGcm, | 117 blink::WebCryptoAlgorithmIdAesGcm, |
98 new blink::WebCryptoAesGcmParams(Uint8VectorStart(iv), | 118 new blink::WebCryptoAesGcmParams(Uint8VectorStart(iv), |
99 iv.size(), | 119 iv.size(), |
100 true, | 120 true, |
101 Uint8VectorStart(additional_data), | 121 Uint8VectorStart(additional_data), |
102 additional_data.size(), | 122 additional_data.size(), |
103 true, | 123 true, |
104 tag_length_bits)); | 124 tag_length_bits)); |
105 } | 125 } |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 return blink::WebCryptoAlgorithm::createNull(); | 292 return blink::WebCryptoAlgorithm::createNull(); |
273 } | 293 } |
274 | 294 |
275 // Helper for ImportJwkFailures and ImportJwkOctFailures. Restores the JWK JSON | 295 // Helper for ImportJwkFailures and ImportJwkOctFailures. Restores the JWK JSON |
276 // dictionary to a good state | 296 // dictionary to a good state |
277 void RestoreJwkOctDictionary(base::DictionaryValue* dict) { | 297 void RestoreJwkOctDictionary(base::DictionaryValue* dict) { |
278 dict->Clear(); | 298 dict->Clear(); |
279 dict->SetString("kty", "oct"); | 299 dict->SetString("kty", "oct"); |
280 dict->SetString("alg", "A128CBC"); | 300 dict->SetString("alg", "A128CBC"); |
281 dict->SetString("use", "enc"); | 301 dict->SetString("use", "enc"); |
282 dict->SetBoolean("extractable", false); | 302 dict->SetBoolean("ext", false); |
283 dict->SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); | 303 dict->SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); |
284 } | 304 } |
285 | 305 |
286 // Helper for ImportJwkRsaFailures. Restores the JWK JSON | 306 // Helper for ImportJwkRsaFailures. Restores the JWK JSON |
287 // dictionary to a good state | 307 // dictionary to a good state |
288 void RestoreJwkRsaDictionary(base::DictionaryValue* dict) { | 308 void RestoreJwkRsaDictionary(base::DictionaryValue* dict) { |
289 dict->Clear(); | 309 dict->Clear(); |
290 dict->SetString("kty", "RSA"); | 310 dict->SetString("kty", "RSA"); |
291 dict->SetString("alg", "RSA1_5"); | 311 dict->SetString("alg", "RSA1_5"); |
292 dict->SetString("use", "enc"); | 312 dict->SetString("use", "enc"); |
293 dict->SetBoolean("extractable", false); | 313 dict->SetBoolean("ext", false); |
294 dict->SetString( | 314 dict->SetString( |
295 "n", | 315 "n", |
296 "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk" | 316 "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk" |
297 "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm" | 317 "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm" |
298 "e7PUJHYW1PW6ENTP0ibeiNOfFvs"); | 318 "e7PUJHYW1PW6ENTP0ibeiNOfFvs"); |
299 dict->SetString("e", "AQAB"); | 319 dict->SetString("e", "AQAB"); |
300 } | 320 } |
301 | 321 |
302 blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm( | 322 blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm( |
303 blink::WebCryptoAlgorithmId algorithm_id, | 323 blink::WebCryptoAlgorithmId algorithm_id, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 } | 356 } |
337 | 357 |
338 blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm( | 358 blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm( |
339 unsigned short key_length_bits) { | 359 unsigned short key_length_bits) { |
340 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesCbc, | 360 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesCbc, |
341 key_length_bits); | 361 key_length_bits); |
342 } | 362 } |
343 | 363 |
344 blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm( | 364 blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm( |
345 unsigned short key_length_bits) { | 365 unsigned short key_length_bits) { |
| 366 EXPECT_TRUE(SupportsAesGcm()); |
346 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesGcm, | 367 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesGcm, |
347 key_length_bits); | 368 key_length_bits); |
348 } | 369 } |
349 | 370 |
350 blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm( | 371 blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm( |
351 unsigned short key_length_bits) { | 372 unsigned short key_length_bits) { |
352 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesKw, | 373 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesKw, |
353 key_length_bits); | 374 key_length_bits); |
354 } | 375 } |
355 | 376 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 usage_mask, | 464 usage_mask, |
444 private_key)); | 465 private_key)); |
445 EXPECT_FALSE(private_key->isNull()); | 466 EXPECT_FALSE(private_key->isNull()); |
446 EXPECT_TRUE(private_key->handle()); | 467 EXPECT_TRUE(private_key->handle()); |
447 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key->type()); | 468 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key->type()); |
448 EXPECT_EQ(algorithm.id(), private_key->algorithm().id()); | 469 EXPECT_EQ(algorithm.id(), private_key->algorithm().id()); |
449 EXPECT_EQ(extractable, extractable); | 470 EXPECT_EQ(extractable, extractable); |
450 EXPECT_EQ(usage_mask, private_key->usages()); | 471 EXPECT_EQ(usage_mask, private_key->usages()); |
451 } | 472 } |
452 | 473 |
453 // TODO(eroman): For Linux builds using system NSS, AES-GCM support is a | |
454 // runtime dependency. Test it by trying to import a key. | |
455 bool SupportsAesGcm() { | |
456 std::vector<uint8> key_raw(16, 0); | |
457 | |
458 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | |
459 Status status = ImportKey(blink::WebCryptoKeyFormatRaw, | |
460 CryptoData(key_raw), | |
461 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm), | |
462 true, | |
463 blink::WebCryptoKeyUsageEncrypt, | |
464 &key); | |
465 | |
466 if (status.IsError()) | |
467 EXPECT_EQ(Status::ErrorUnsupported().ToString(), status.ToString()); | |
468 return status.IsSuccess(); | |
469 } | |
470 | |
471 Status AesGcmEncrypt(const blink::WebCryptoKey& key, | 474 Status AesGcmEncrypt(const blink::WebCryptoKey& key, |
472 const std::vector<uint8>& iv, | 475 const std::vector<uint8>& iv, |
473 const std::vector<uint8>& additional_data, | 476 const std::vector<uint8>& additional_data, |
474 unsigned int tag_length_bits, | 477 unsigned int tag_length_bits, |
475 const std::vector<uint8>& plain_text, | 478 const std::vector<uint8>& plain_text, |
476 std::vector<uint8>* cipher_text, | 479 std::vector<uint8>* cipher_text, |
477 std::vector<uint8>* authentication_tag) { | 480 std::vector<uint8>* authentication_tag) { |
| 481 EXPECT_TRUE(SupportsAesGcm()); |
478 blink::WebCryptoAlgorithm algorithm = | 482 blink::WebCryptoAlgorithm algorithm = |
479 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); | 483 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); |
480 | 484 |
481 blink::WebArrayBuffer output; | 485 blink::WebArrayBuffer output; |
482 Status status = Encrypt(algorithm, key, CryptoData(plain_text), &output); | 486 Status status = Encrypt(algorithm, key, CryptoData(plain_text), &output); |
483 if (status.IsError()) | 487 if (status.IsError()) |
484 return status; | 488 return status; |
485 | 489 |
486 if (output.byteLength() * 8 < tag_length_bits) { | 490 if (output.byteLength() * 8 < tag_length_bits) { |
487 EXPECT_TRUE(false); | 491 EXPECT_TRUE(false); |
(...skipping 11 matching lines...) Expand all Loading... |
499 return Status::Success(); | 503 return Status::Success(); |
500 } | 504 } |
501 | 505 |
502 Status AesGcmDecrypt(const blink::WebCryptoKey& key, | 506 Status AesGcmDecrypt(const blink::WebCryptoKey& key, |
503 const std::vector<uint8>& iv, | 507 const std::vector<uint8>& iv, |
504 const std::vector<uint8>& additional_data, | 508 const std::vector<uint8>& additional_data, |
505 unsigned int tag_length_bits, | 509 unsigned int tag_length_bits, |
506 const std::vector<uint8>& cipher_text, | 510 const std::vector<uint8>& cipher_text, |
507 const std::vector<uint8>& authentication_tag, | 511 const std::vector<uint8>& authentication_tag, |
508 blink::WebArrayBuffer* plain_text) { | 512 blink::WebArrayBuffer* plain_text) { |
| 513 EXPECT_TRUE(SupportsAesGcm()); |
509 blink::WebCryptoAlgorithm algorithm = | 514 blink::WebCryptoAlgorithm algorithm = |
510 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); | 515 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); |
511 | 516 |
512 // Join cipher text and authentication tag. | 517 // Join cipher text and authentication tag. |
513 std::vector<uint8> cipher_text_with_tag; | 518 std::vector<uint8> cipher_text_with_tag; |
514 cipher_text_with_tag.reserve(cipher_text.size() + authentication_tag.size()); | 519 cipher_text_with_tag.reserve(cipher_text.size() + authentication_tag.size()); |
515 cipher_text_with_tag.insert( | 520 cipher_text_with_tag.insert( |
516 cipher_text_with_tag.end(), cipher_text.begin(), cipher_text.end()); | 521 cipher_text_with_tag.end(), cipher_text.begin(), cipher_text.end()); |
517 cipher_text_with_tag.insert(cipher_text_with_tag.end(), | 522 cipher_text_with_tag.insert(cipher_text_with_tag.end(), |
518 authentication_tag.begin(), | 523 authentication_tag.begin(), |
519 authentication_tag.end()); | 524 authentication_tag.end()); |
520 | 525 |
521 return Decrypt(algorithm, key, CryptoData(cipher_text_with_tag), plain_text); | 526 return Decrypt(algorithm, key, CryptoData(cipher_text_with_tag), plain_text); |
522 } | 527 } |
523 | 528 |
524 Status ImportKeyJwkFromDict(const base::DictionaryValue& dict, | 529 Status ImportKeyJwkFromDict(const base::DictionaryValue& dict, |
525 const blink::WebCryptoAlgorithm& algorithm, | 530 const blink::WebCryptoAlgorithm& algorithm, |
526 bool extractable, | 531 bool extractable, |
527 blink::WebCryptoKeyUsageMask usage_mask, | 532 blink::WebCryptoKeyUsageMask usage_mask, |
528 blink::WebCryptoKey* key) { | 533 blink::WebCryptoKey* key) { |
529 return ImportKeyJwk(CryptoData(MakeJsonVector(dict)), | 534 return ImportKeyJwk(CryptoData(MakeJsonVector(dict)), |
530 algorithm, | 535 algorithm, |
531 extractable, | 536 extractable, |
532 usage_mask, | 537 usage_mask, |
533 key); | 538 key); |
534 } | 539 } |
535 | 540 |
| 541 // Parses an ArrayBuffer of JSON into a dictionary. |
| 542 scoped_ptr<base::DictionaryValue> GetJwkDictionary( |
| 543 const blink::WebArrayBuffer& json) { |
| 544 base::StringPiece json_string(reinterpret_cast<const char*>(json.data()), |
| 545 json.byteLength()); |
| 546 base::Value* value = base::JSONReader::Read(json_string); |
| 547 EXPECT_TRUE(value); |
| 548 base::DictionaryValue* dict_value = NULL; |
| 549 value->GetAsDictionary(&dict_value); |
| 550 return scoped_ptr<base::DictionaryValue>(dict_value); |
| 551 } |
| 552 |
| 553 // Verifies that the JSON in the input ArrayBuffer contains the provided |
| 554 // expected values. Exact matches are required on the fields examined. |
| 555 ::testing::AssertionResult VerifySymmetricJwk( |
| 556 const blink::WebArrayBuffer& json, |
| 557 const std::string& alg_expected, |
| 558 const std::string& k_expected_hex, |
| 559 blink::WebCryptoKeyUsageMask use_mask_expected) { |
| 560 |
| 561 scoped_ptr<base::DictionaryValue> dict = GetJwkDictionary(json); |
| 562 if (!dict.get() || dict->empty()) |
| 563 return ::testing::AssertionFailure() << "JSON parsing failed"; |
| 564 |
| 565 // ---- kty |
| 566 std::string value_string; |
| 567 if (!dict->GetString("kty", &value_string)) |
| 568 return ::testing::AssertionFailure() << "Missing 'kty'"; |
| 569 if (value_string != "oct") |
| 570 return ::testing::AssertionFailure() |
| 571 << "Expected 'kty' to be 'oct' but found " << value_string; |
| 572 |
| 573 // ---- alg |
| 574 if (!dict->GetString("alg", &value_string)) |
| 575 return ::testing::AssertionFailure() << "Missing 'alg'"; |
| 576 if (value_string != alg_expected) |
| 577 return ::testing::AssertionFailure() << "Expected 'alg' to be " |
| 578 << alg_expected << " but found " |
| 579 << value_string; |
| 580 |
| 581 // ---- k |
| 582 if (!dict->GetString("k", &value_string)) |
| 583 return ::testing::AssertionFailure() << "Missing 'k'"; |
| 584 std::string k_value; |
| 585 if (!webcrypto::Base64DecodeUrlSafe(value_string, &k_value)) |
| 586 return ::testing::AssertionFailure() << "Base64DecodeUrlSafe(k) failed"; |
| 587 if (!LowerCaseEqualsASCII(base::HexEncode(k_value.data(), k_value.size()), |
| 588 k_expected_hex.c_str())) { |
| 589 return ::testing::AssertionFailure() << "Expected 'k' to be " |
| 590 << k_expected_hex |
| 591 << " but found something different"; |
| 592 } |
| 593 // ---- ext |
| 594 // always expect ext == true in this case |
| 595 bool ext_value; |
| 596 if (!dict->GetBoolean("ext", &ext_value)) |
| 597 return ::testing::AssertionFailure() << "Missing 'ext'"; |
| 598 if (!ext_value) |
| 599 return ::testing::AssertionFailure() |
| 600 << "Expected 'ext' to be true but found false"; |
| 601 |
| 602 // ---- key_ops |
| 603 base::ListValue* key_ops; |
| 604 if (!dict->GetList("key_ops", &key_ops)) |
| 605 return ::testing::AssertionFailure() << "Missing 'key_ops'"; |
| 606 blink::WebCryptoKeyUsageMask key_ops_mask = 0; |
| 607 Status status = GetWebCryptoUsagesFromJwkKeyOps(key_ops, &key_ops_mask); |
| 608 if (status.IsError()) |
| 609 return ::testing::AssertionFailure() << "Failure extracting 'key_ops'"; |
| 610 if (key_ops_mask != use_mask_expected) |
| 611 return ::testing::AssertionFailure() |
| 612 << "Expected 'key_ops' mask to be " << use_mask_expected |
| 613 << " but found " << key_ops_mask << " (" << value_string << ")"; |
| 614 |
| 615 return ::testing::AssertionSuccess(); |
| 616 } |
| 617 |
536 } // namespace | 618 } // namespace |
537 | 619 |
| 620 TEST_F(SharedCryptoTest, CheckAesGcm) { |
| 621 if (!SupportsAesGcm()) { |
| 622 LOG(WARNING) << "AES GCM not supported on this platform, so some tests " |
| 623 "will be skipped. Consider upgrading local NSS libraries"; |
| 624 return; |
| 625 } |
| 626 } |
| 627 |
538 TEST_F(SharedCryptoTest, StatusToString) { | 628 TEST_F(SharedCryptoTest, StatusToString) { |
539 EXPECT_EQ("Success", Status::Success().ToString()); | 629 EXPECT_EQ("Success", Status::Success().ToString()); |
540 EXPECT_EQ("", Status::Error().ToString()); | 630 EXPECT_EQ("", Status::Error().ToString()); |
541 EXPECT_EQ("The requested operation is unsupported", | 631 EXPECT_EQ("The requested operation is unsupported", |
542 Status::ErrorUnsupported().ToString()); | 632 Status::ErrorUnsupported().ToString()); |
543 EXPECT_EQ("The required JWK property \"kty\" was missing", | 633 EXPECT_EQ("The required JWK property \"kty\" was missing", |
544 Status::ErrorJwkPropertyMissing("kty").ToString()); | 634 Status::ErrorJwkPropertyMissing("kty").ToString()); |
545 EXPECT_EQ("The JWK property \"kty\" must be a string", | 635 EXPECT_EQ("The JWK property \"kty\" must be a string", |
546 Status::ErrorJwkPropertyWrongType("kty", "string").ToString()); | 636 Status::ErrorJwkPropertyWrongType("kty", "string").ToString()); |
547 EXPECT_EQ("The JWK property \"n\" could not be base64 decoded", | 637 EXPECT_EQ("The JWK property \"n\" could not be base64 decoded", |
(...skipping 17 matching lines...) Expand all Loading... |
565 blink::WebArrayBuffer output; | 655 blink::WebArrayBuffer output; |
566 ASSERT_STATUS_SUCCESS( | 656 ASSERT_STATUS_SUCCESS( |
567 Digest(test_algorithm, CryptoData(test_input), &output)); | 657 Digest(test_algorithm, CryptoData(test_input), &output)); |
568 EXPECT_TRUE(ArrayBufferMatches(test_output, output)); | 658 EXPECT_TRUE(ArrayBufferMatches(test_output, output)); |
569 } | 659 } |
570 } | 660 } |
571 | 661 |
572 TEST_F(SharedCryptoTest, HMACSampleSets) { | 662 TEST_F(SharedCryptoTest, HMACSampleSets) { |
573 scoped_ptr<base::ListValue> tests; | 663 scoped_ptr<base::ListValue> tests; |
574 ASSERT_TRUE(ReadJsonTestFileToList("hmac.json", &tests)); | 664 ASSERT_TRUE(ReadJsonTestFileToList("hmac.json", &tests)); |
575 | 665 // TODO(padolph): Missing known answer tests for HMAC SHA384, and SHA512. |
576 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { | 666 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { |
577 SCOPED_TRACE(test_index); | 667 SCOPED_TRACE(test_index); |
578 base::DictionaryValue* test; | 668 base::DictionaryValue* test; |
579 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); | 669 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); |
580 | 670 |
581 blink::WebCryptoAlgorithm test_hash = GetDigestAlgorithm(test, "hash"); | 671 blink::WebCryptoAlgorithm test_hash = GetDigestAlgorithm(test, "hash"); |
582 const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); | 672 const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); |
583 const std::vector<uint8> test_message = | 673 const std::vector<uint8> test_message = |
584 GetBytesFromHexString(test, "message"); | 674 GetBytesFromHexString(test, "message"); |
585 const std::vector<uint8> test_mac = GetBytesFromHexString(test, "mac"); | 675 const std::vector<uint8> test_mac = GetBytesFromHexString(test, "mac"); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 } | 897 } |
808 } | 898 } |
809 | 899 |
810 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAes)) { | 900 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAes)) { |
811 // Check key generation for each of AES-CBC, AES-GCM, and AES-KW, and for each | 901 // Check key generation for each of AES-CBC, AES-GCM, and AES-KW, and for each |
812 // allowed key length. | 902 // allowed key length. |
813 std::vector<blink::WebCryptoAlgorithm> algorithm; | 903 std::vector<blink::WebCryptoAlgorithm> algorithm; |
814 const unsigned short kKeyLength[] = {128, 192, 256}; | 904 const unsigned short kKeyLength[] = {128, 192, 256}; |
815 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLength); ++i) { | 905 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLength); ++i) { |
816 algorithm.push_back(CreateAesCbcKeyGenAlgorithm(kKeyLength[i])); | 906 algorithm.push_back(CreateAesCbcKeyGenAlgorithm(kKeyLength[i])); |
817 algorithm.push_back(CreateAesGcmKeyGenAlgorithm(kKeyLength[i])); | |
818 algorithm.push_back(CreateAesKwKeyGenAlgorithm(kKeyLength[i])); | 907 algorithm.push_back(CreateAesKwKeyGenAlgorithm(kKeyLength[i])); |
| 908 if (SupportsAesGcm()) |
| 909 algorithm.push_back(CreateAesGcmKeyGenAlgorithm(kKeyLength[i])); |
819 } | 910 } |
820 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 911 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
821 std::vector<blink::WebArrayBuffer> keys; | 912 std::vector<blink::WebArrayBuffer> keys; |
822 blink::WebArrayBuffer key_bytes; | 913 blink::WebArrayBuffer key_bytes; |
823 for (size_t i = 0; i < algorithm.size(); ++i) { | 914 for (size_t i = 0; i < algorithm.size(); ++i) { |
824 SCOPED_TRACE(i); | 915 SCOPED_TRACE(i); |
825 // Generate a small sample of keys. | 916 // Generate a small sample of keys. |
826 keys.clear(); | 917 keys.clear(); |
827 for (int j = 0; j < 16; ++j) { | 918 for (int j = 0; j < 16; ++j) { |
828 ASSERT_STATUS_SUCCESS(GenerateSecretKey(algorithm[i], true, 0, &key)); | 919 ASSERT_STATUS_SUCCESS(GenerateSecretKey(algorithm[i], true, 0, &key)); |
(...skipping 14 matching lines...) Expand all Loading... |
843 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAesBadLength)) { | 934 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAesBadLength)) { |
844 const unsigned short kKeyLen[] = {0, 127, 257}; | 935 const unsigned short kKeyLen[] = {0, 127, 257}; |
845 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 936 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
846 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLen); ++i) { | 937 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLen); ++i) { |
847 SCOPED_TRACE(i); | 938 SCOPED_TRACE(i); |
848 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), | 939 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), |
849 GenerateSecretKey( | 940 GenerateSecretKey( |
850 CreateAesCbcKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); | 941 CreateAesCbcKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); |
851 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), | 942 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), |
852 GenerateSecretKey( | 943 GenerateSecretKey( |
853 CreateAesGcmKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); | |
854 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), | |
855 GenerateSecretKey( | |
856 CreateAesKwKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); | 944 CreateAesKwKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); |
| 945 if (SupportsAesGcm()) { |
| 946 EXPECT_STATUS( |
| 947 Status::ErrorGenerateKeyLength(), |
| 948 GenerateSecretKey( |
| 949 CreateAesGcmKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); |
| 950 } |
857 } | 951 } |
858 } | 952 } |
859 | 953 |
860 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyHmac)) { | 954 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyHmac)) { |
861 // Generate a small sample of HMAC keys. | 955 // Generate a small sample of HMAC keys. |
862 std::vector<blink::WebArrayBuffer> keys; | 956 std::vector<blink::WebArrayBuffer> keys; |
863 for (int i = 0; i < 16; ++i) { | 957 for (int i = 0; i < 16; ++i) { |
864 blink::WebArrayBuffer key_bytes; | 958 blink::WebArrayBuffer key_bytes; |
865 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 959 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
866 blink::WebCryptoAlgorithm algorithm = | 960 blink::WebCryptoAlgorithm algorithm = |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 // This fails because the algorithm is null. | 1005 // This fails because the algorithm is null. |
912 EXPECT_STATUS(Status::ErrorMissingAlgorithmImportRawKey(), | 1006 EXPECT_STATUS(Status::ErrorMissingAlgorithmImportRawKey(), |
913 ImportKey(blink::WebCryptoKeyFormatRaw, | 1007 ImportKey(blink::WebCryptoKeyFormatRaw, |
914 CryptoData(HexStringToBytes("00000000000000000000")), | 1008 CryptoData(HexStringToBytes("00000000000000000000")), |
915 blink::WebCryptoAlgorithm::createNull(), | 1009 blink::WebCryptoAlgorithm::createNull(), |
916 true, | 1010 true, |
917 blink::WebCryptoKeyUsageEncrypt, | 1011 blink::WebCryptoKeyUsageEncrypt, |
918 &key)); | 1012 &key)); |
919 } | 1013 } |
920 | 1014 |
| 1015 TEST_F(SharedCryptoTest, ImportJwkKeyUsage) { |
| 1016 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 1017 base::DictionaryValue dict; |
| 1018 dict.SetString("kty", "oct"); |
| 1019 dict.SetBoolean("ext", false); |
| 1020 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); |
| 1021 const blink::WebCryptoAlgorithm aes_cbc_algorithm = |
| 1022 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
| 1023 const blink::WebCryptoAlgorithm hmac_algorithm = |
| 1024 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
| 1025 const blink::WebCryptoAlgorithm aes_kw_algorithm = |
| 1026 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); |
| 1027 |
| 1028 // Test null usage. |
| 1029 base::ListValue* key_ops = new base::ListValue; |
| 1030 // Note: the following call makes dict assume ownership of key_ops. |
| 1031 dict.Set("key_ops", key_ops); |
| 1032 EXPECT_STATUS_SUCCESS( |
| 1033 ImportKeyJwkFromDict(dict, aes_cbc_algorithm, false, 0, &key)); |
| 1034 EXPECT_EQ(0, key.usages()); |
| 1035 |
| 1036 // Test each key_ops value translates to the correct Web Crypto value. |
| 1037 struct TestCase { |
| 1038 const char* jwk_key_op; |
| 1039 const char* jwk_alg; |
| 1040 const blink::WebCryptoAlgorithm algorithm; |
| 1041 const blink::WebCryptoKeyUsage usage; |
| 1042 }; |
| 1043 // TODO(padolph): Add 'deriveBits' key_ops value once it is supported. |
| 1044 const TestCase test_case[] = { |
| 1045 {"encrypt", "A128CBC", aes_cbc_algorithm, |
| 1046 blink::WebCryptoKeyUsageEncrypt}, |
| 1047 {"decrypt", "A128CBC", aes_cbc_algorithm, |
| 1048 blink::WebCryptoKeyUsageDecrypt}, |
| 1049 {"sign", "HS256", hmac_algorithm, blink::WebCryptoKeyUsageSign}, |
| 1050 {"verify", "HS256", hmac_algorithm, blink::WebCryptoKeyUsageVerify}, |
| 1051 {"wrapKey", "A128KW", aes_kw_algorithm, blink::WebCryptoKeyUsageWrapKey}, |
| 1052 {"unwrapKey", "A128KW", aes_kw_algorithm, |
| 1053 blink::WebCryptoKeyUsageUnwrapKey}, |
| 1054 {"deriveKey", "HS256", hmac_algorithm, |
| 1055 blink::WebCryptoKeyUsageDeriveKey}}; |
| 1056 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(test_case); |
| 1057 ++test_index) { |
| 1058 SCOPED_TRACE(test_index); |
| 1059 dict.SetString("alg", test_case[test_index].jwk_alg); |
| 1060 key_ops->Clear(); |
| 1061 key_ops->AppendString(test_case[test_index].jwk_key_op); |
| 1062 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict(dict, |
| 1063 test_case[test_index].algorithm, |
| 1064 false, |
| 1065 test_case[test_index].usage, |
| 1066 &key)); |
| 1067 EXPECT_EQ(test_case[test_index].usage, key.usages()); |
| 1068 } |
| 1069 |
| 1070 // Test discrete multiple usages. |
| 1071 dict.SetString("alg", "A128CBC"); |
| 1072 key_ops->Clear(); |
| 1073 key_ops->AppendString("encrypt"); |
| 1074 key_ops->AppendString("decrypt"); |
| 1075 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( |
| 1076 dict, |
| 1077 aes_cbc_algorithm, |
| 1078 false, |
| 1079 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt, |
| 1080 &key)); |
| 1081 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt, |
| 1082 key.usages()); |
| 1083 |
| 1084 // Test constrained key usage (input usage is a subset of JWK usage). |
| 1085 key_ops->Clear(); |
| 1086 key_ops->AppendString("encrypt"); |
| 1087 key_ops->AppendString("decrypt"); |
| 1088 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( |
| 1089 dict, aes_cbc_algorithm, false, blink::WebCryptoKeyUsageDecrypt, &key)); |
| 1090 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt, key.usages()); |
| 1091 |
| 1092 // Test failure if input usage is NOT a strict subset of the JWK usage. |
| 1093 key_ops->Clear(); |
| 1094 key_ops->AppendString("encrypt"); |
| 1095 EXPECT_STATUS(Status::ErrorJwkKeyopsInconsistent(), |
| 1096 ImportKeyJwkFromDict(dict, |
| 1097 aes_cbc_algorithm, |
| 1098 false, |
| 1099 blink::WebCryptoKeyUsageEncrypt | |
| 1100 blink::WebCryptoKeyUsageDecrypt, |
| 1101 &key)); |
| 1102 |
| 1103 // Test 'use' inconsistent with 'key_ops'. |
| 1104 dict.SetString("alg", "HS256"); |
| 1105 dict.SetString("use", "sig"); |
| 1106 key_ops->AppendString("sign"); |
| 1107 key_ops->AppendString("verify"); |
| 1108 key_ops->AppendString("encrypt"); |
| 1109 EXPECT_STATUS(Status::ErrorJwkUseAndKeyopsInconsistent(), |
| 1110 ImportKeyJwkFromDict(dict, |
| 1111 hmac_algorithm, |
| 1112 false, |
| 1113 blink::WebCryptoKeyUsageSign | |
| 1114 blink::WebCryptoKeyUsageVerify, |
| 1115 &key)); |
| 1116 |
| 1117 // Test JWK composite 'sig' use |
| 1118 dict.Remove("key_ops", NULL); |
| 1119 dict.SetString("use", "sig"); |
| 1120 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( |
| 1121 dict, |
| 1122 hmac_algorithm, |
| 1123 false, |
| 1124 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, |
| 1125 &key)); |
| 1126 EXPECT_EQ(blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, |
| 1127 key.usages()); |
| 1128 |
| 1129 // Test JWK composite use 'enc' usage |
| 1130 dict.SetString("alg", "A128CBC"); |
| 1131 dict.SetString("use", "enc"); |
| 1132 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( |
| 1133 dict, |
| 1134 aes_cbc_algorithm, |
| 1135 false, |
| 1136 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt | |
| 1137 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey | |
| 1138 blink::WebCryptoKeyUsageDeriveKey, |
| 1139 &key)); |
| 1140 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt | |
| 1141 blink::WebCryptoKeyUsageWrapKey | |
| 1142 blink::WebCryptoKeyUsageUnwrapKey | |
| 1143 blink::WebCryptoKeyUsageDeriveKey, |
| 1144 key.usages()); |
| 1145 } |
| 1146 |
921 TEST_F(SharedCryptoTest, ImportJwkFailures) { | 1147 TEST_F(SharedCryptoTest, ImportJwkFailures) { |
922 | |
923 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1148 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
924 blink::WebCryptoAlgorithm algorithm = | 1149 blink::WebCryptoAlgorithm algorithm = |
925 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | 1150 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
926 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; | 1151 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; |
927 | 1152 |
928 // Baseline pass: each test below breaks a single item, so we start with a | 1153 // Baseline pass: each test below breaks a single item, so we start with a |
929 // passing case to make sure each failure is caused by the isolated break. | 1154 // passing case to make sure each failure is caused by the isolated break. |
930 // Each breaking subtest below resets the dictionary to this passing case when | 1155 // Each breaking subtest below resets the dictionary to this passing case when |
931 // complete. | 1156 // complete. |
932 base::DictionaryValue dict; | 1157 base::DictionaryValue dict; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 RestoreJwkOctDictionary(&dict); | 1205 RestoreJwkOctDictionary(&dict); |
981 | 1206 |
982 // Fail on kty wrong type. | 1207 // Fail on kty wrong type. |
983 dict.SetDouble("kty", 0.1); | 1208 dict.SetDouble("kty", 0.1); |
984 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("kty", "string"), | 1209 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("kty", "string"), |
985 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1210 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
986 RestoreJwkOctDictionary(&dict); | 1211 RestoreJwkOctDictionary(&dict); |
987 | 1212 |
988 // Fail on invalid use. | 1213 // Fail on invalid use. |
989 dict.SetString("use", "foo"); | 1214 dict.SetString("use", "foo"); |
990 EXPECT_STATUS(Status::ErrorJwkUnrecognizedUsage(), | 1215 EXPECT_STATUS(Status::ErrorJwkUnrecognizedUse(), |
991 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1216 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
992 RestoreJwkOctDictionary(&dict); | 1217 RestoreJwkOctDictionary(&dict); |
993 | 1218 |
994 // Fail on invalid use (wrong type). | 1219 // Fail on invalid use (wrong type). |
995 dict.SetBoolean("use", true); | 1220 dict.SetBoolean("use", true); |
996 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("use", "string"), | 1221 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("use", "string"), |
997 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1222 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
998 RestoreJwkOctDictionary(&dict); | 1223 RestoreJwkOctDictionary(&dict); |
999 | 1224 |
1000 // Fail on invalid extractable (wrong type). | 1225 // Fail on invalid extractable (wrong type). |
1001 dict.SetInteger("extractable", 0); | 1226 dict.SetInteger("ext", 0); |
1002 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("extractable", "boolean"), | 1227 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("ext", "boolean"), |
| 1228 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 1229 RestoreJwkOctDictionary(&dict); |
| 1230 |
| 1231 // Fail on invalid key_ops (wrong type). |
| 1232 dict.SetBoolean("key_ops", true); |
| 1233 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("key_ops", "list"), |
| 1234 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 1235 RestoreJwkOctDictionary(&dict); |
| 1236 |
| 1237 // Fail on invalid key_ops (wrong element value). |
| 1238 base::ListValue* key_ops = new base::ListValue; |
| 1239 // Note: the following call makes dict assume ownership of key_ops. |
| 1240 dict.Set("key_ops", key_ops); |
| 1241 key_ops->AppendString("foo"); |
| 1242 EXPECT_STATUS(Status::ErrorJwkUnrecognizedKeyop(), |
1003 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1243 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1004 RestoreJwkOctDictionary(&dict); | 1244 RestoreJwkOctDictionary(&dict); |
1005 } | 1245 } |
1006 | 1246 |
1007 TEST_F(SharedCryptoTest, ImportJwkOctFailures) { | 1247 TEST_F(SharedCryptoTest, ImportJwkOctFailures) { |
1008 | |
1009 base::DictionaryValue dict; | 1248 base::DictionaryValue dict; |
1010 RestoreJwkOctDictionary(&dict); | 1249 RestoreJwkOctDictionary(&dict); |
1011 blink::WebCryptoAlgorithm algorithm = | 1250 blink::WebCryptoAlgorithm algorithm = |
1012 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | 1251 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
1013 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; | 1252 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; |
1014 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1253 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1015 | 1254 |
1016 // Baseline pass. | 1255 // Baseline pass. |
1017 EXPECT_STATUS_SUCCESS( | 1256 EXPECT_STATUS_SUCCESS( |
1018 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1257 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 | 1289 |
1051 // Fail on k actual length (192 bits) inconsistent with the embedded JWK alg | 1290 // Fail on k actual length (192 bits) inconsistent with the embedded JWK alg |
1052 // value (128) for an AES key. | 1291 // value (128) for an AES key. |
1053 dict.SetString("k", "dGhpcyAgaXMgIDI0ICBieXRlcyBsb25n"); | 1292 dict.SetString("k", "dGhpcyAgaXMgIDI0ICBieXRlcyBsb25n"); |
1054 EXPECT_STATUS(Status::ErrorJwkIncorrectKeyLength(), | 1293 EXPECT_STATUS(Status::ErrorJwkIncorrectKeyLength(), |
1055 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1294 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1056 RestoreJwkOctDictionary(&dict); | 1295 RestoreJwkOctDictionary(&dict); |
1057 } | 1296 } |
1058 | 1297 |
1059 TEST_F(SharedCryptoTest, MAYBE(ImportJwkRsaFailures)) { | 1298 TEST_F(SharedCryptoTest, MAYBE(ImportJwkRsaFailures)) { |
1060 | |
1061 base::DictionaryValue dict; | 1299 base::DictionaryValue dict; |
1062 RestoreJwkRsaDictionary(&dict); | 1300 RestoreJwkRsaDictionary(&dict); |
1063 blink::WebCryptoAlgorithm algorithm = | 1301 blink::WebCryptoAlgorithm algorithm = |
1064 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); | 1302 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
1065 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; | 1303 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; |
1066 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1304 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1067 | 1305 |
1068 // An RSA public key JWK _must_ have an "n" (modulus) and an "e" (exponent) | 1306 // An RSA public key JWK _must_ have an "n" (modulus) and an "e" (exponent) |
1069 // entry, while an RSA private key must have those plus at least a "d" | 1307 // entry, while an RSA private key must have those plus at least a "d" |
1070 // (private exponent) entry. | 1308 // (private exponent) entry. |
1071 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18, | 1309 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18, |
1072 // section 6.3. | 1310 // section 6.3. |
1073 | 1311 |
1074 // Baseline pass. | 1312 // Baseline pass. |
1075 EXPECT_STATUS_SUCCESS( | 1313 EXPECT_STATUS_SUCCESS( |
1076 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1314 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1077 EXPECT_EQ(algorithm.id(), key.algorithm().id()); | 1315 EXPECT_EQ(algorithm.id(), key.algorithm().id()); |
1078 EXPECT_FALSE(key.extractable()); | 1316 EXPECT_FALSE(key.extractable()); |
1079 EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages()); | 1317 EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages()); |
1080 EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type()); | 1318 EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type()); |
1081 | 1319 |
1082 // The following are specific failure cases for when kty = "RSA". | 1320 // The following are specific failure cases for when kty = "RSA". |
1083 | 1321 |
1084 // Fail if either "n" or "e" is not present or malformed. | 1322 // Fail if either "n" or "e" is not present or malformed. |
1085 const std::string kKtyParmName[] = {"n", "e"}; | 1323 const std::string kKtyParmName[] = {"n", "e"}; |
1086 for (size_t idx = 0; idx < ARRAYSIZE_UNSAFE(kKtyParmName); ++idx) { | 1324 for (size_t idx = 0; idx < ARRAYSIZE_UNSAFE(kKtyParmName); ++idx) { |
1087 | |
1088 // Fail on missing parameter. | 1325 // Fail on missing parameter. |
1089 dict.Remove(kKtyParmName[idx], NULL); | 1326 dict.Remove(kKtyParmName[idx], NULL); |
1090 EXPECT_STATUS_ERROR( | 1327 EXPECT_STATUS_ERROR( |
1091 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1328 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1092 RestoreJwkRsaDictionary(&dict); | 1329 RestoreJwkRsaDictionary(&dict); |
1093 | 1330 |
1094 // Fail on bad b64 parameter encoding. | 1331 // Fail on bad b64 parameter encoding. |
1095 dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0"); | 1332 dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0"); |
1096 EXPECT_STATUS_ERROR( | 1333 EXPECT_STATUS_ERROR( |
1097 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1334 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); | 1374 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); |
1138 key = blink::WebCryptoKey::createNull(); | 1375 key = blink::WebCryptoKey::createNull(); |
1139 | 1376 |
1140 // Consistency rules when JWK value exists: Fail if inconsistency is found. | 1377 // Consistency rules when JWK value exists: Fail if inconsistency is found. |
1141 | 1378 |
1142 // Pass: All input values are consistent with the JWK values. | 1379 // Pass: All input values are consistent with the JWK values. |
1143 dict.Clear(); | 1380 dict.Clear(); |
1144 dict.SetString("kty", "oct"); | 1381 dict.SetString("kty", "oct"); |
1145 dict.SetString("alg", "HS256"); | 1382 dict.SetString("alg", "HS256"); |
1146 dict.SetString("use", "sig"); | 1383 dict.SetString("use", "sig"); |
1147 dict.SetBoolean("extractable", false); | 1384 dict.SetBoolean("ext", false); |
1148 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 1385 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
1149 json_vec = MakeJsonVector(dict); | 1386 json_vec = MakeJsonVector(dict); |
1150 EXPECT_STATUS_SUCCESS(ImportKeyJwk( | 1387 EXPECT_STATUS_SUCCESS(ImportKeyJwk( |
1151 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); | 1388 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); |
1152 | 1389 |
1153 // Extractable cases: | 1390 // Extractable cases: |
1154 // 1. input=T, JWK=F ==> fail (inconsistent) | 1391 // 1. input=T, JWK=F ==> fail (inconsistent) |
1155 // 4. input=F, JWK=F ==> pass, result extractable is F | 1392 // 4. input=F, JWK=F ==> pass, result extractable is F |
1156 // 2. input=T, JWK=T ==> pass, result extractable is T | 1393 // 2. input=T, JWK=T ==> pass, result extractable is T |
1157 // 3. input=F, JWK=T ==> pass, result extractable is F | 1394 // 3. input=F, JWK=T ==> pass, result extractable is F |
1158 EXPECT_STATUS( | 1395 EXPECT_STATUS( |
1159 Status::ErrorJwkExtractableInconsistent(), | 1396 Status::ErrorJwkExtInconsistent(), |
1160 ImportKeyJwk(CryptoData(json_vec), algorithm, true, usage_mask, &key)); | 1397 ImportKeyJwk(CryptoData(json_vec), algorithm, true, usage_mask, &key)); |
1161 EXPECT_STATUS_SUCCESS( | 1398 EXPECT_STATUS_SUCCESS( |
1162 ImportKeyJwk(CryptoData(json_vec), algorithm, false, usage_mask, &key)); | 1399 ImportKeyJwk(CryptoData(json_vec), algorithm, false, usage_mask, &key)); |
1163 EXPECT_FALSE(key.extractable()); | 1400 EXPECT_FALSE(key.extractable()); |
1164 dict.SetBoolean("extractable", true); | 1401 dict.SetBoolean("ext", true); |
1165 EXPECT_STATUS_SUCCESS( | 1402 EXPECT_STATUS_SUCCESS( |
1166 ImportKeyJwkFromDict(dict, algorithm, true, usage_mask, &key)); | 1403 ImportKeyJwkFromDict(dict, algorithm, true, usage_mask, &key)); |
1167 EXPECT_TRUE(key.extractable()); | 1404 EXPECT_TRUE(key.extractable()); |
1168 EXPECT_STATUS_SUCCESS( | 1405 EXPECT_STATUS_SUCCESS( |
1169 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1406 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1170 EXPECT_FALSE(key.extractable()); | 1407 EXPECT_FALSE(key.extractable()); |
1171 dict.SetBoolean("extractable", true); // restore previous value | 1408 dict.SetBoolean("ext", true); // restore previous value |
1172 | 1409 |
1173 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value | 1410 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value |
1174 // (HMAC SHA256). | 1411 // (HMAC SHA256). |
1175 EXPECT_STATUS(Status::ErrorJwkAlgorithmInconsistent(), | 1412 EXPECT_STATUS(Status::ErrorJwkAlgorithmInconsistent(), |
1176 ImportKeyJwk(CryptoData(json_vec), | 1413 ImportKeyJwk(CryptoData(json_vec), |
1177 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), | 1414 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
1178 extractable, | 1415 extractable, |
1179 usage_mask, | 1416 usage_mask, |
1180 &key)); | 1417 &key)); |
1181 | 1418 |
(...skipping 21 matching lines...) Expand all Loading... |
1203 dict, | 1440 dict, |
1204 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), | 1441 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), |
1205 extractable, | 1442 extractable, |
1206 usage_mask, | 1443 usage_mask, |
1207 &key)); | 1444 &key)); |
1208 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); | 1445 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); |
1209 dict.SetString("alg", "HS256"); | 1446 dict.SetString("alg", "HS256"); |
1210 | 1447 |
1211 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value | 1448 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value |
1212 // (sign|verify) | 1449 // (sign|verify) |
1213 EXPECT_STATUS(Status::ErrorJwkUsageInconsistent(), | 1450 EXPECT_STATUS(Status::ErrorJwkUseInconsistent(), |
1214 ImportKeyJwk(CryptoData(json_vec), | 1451 ImportKeyJwk(CryptoData(json_vec), |
1215 algorithm, | 1452 algorithm, |
1216 extractable, | 1453 extractable, |
1217 blink::WebCryptoKeyUsageEncrypt, | 1454 blink::WebCryptoKeyUsageEncrypt, |
1218 &key)); | 1455 &key)); |
1219 | 1456 |
1220 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK | 1457 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK |
1221 // value (sign|verify) | 1458 // value (sign|verify) |
1222 usage_mask = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign | | 1459 usage_mask = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign | |
1223 blink::WebCryptoKeyUsageVerify; | 1460 blink::WebCryptoKeyUsageVerify; |
1224 EXPECT_STATUS( | 1461 EXPECT_STATUS( |
1225 Status::ErrorJwkUsageInconsistent(), | 1462 Status::ErrorJwkUseInconsistent(), |
1226 ImportKeyJwk( | 1463 ImportKeyJwk( |
1227 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); | 1464 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); |
1228 | 1465 |
1229 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, | 1466 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, |
1230 // only certain alg values are permitted. For example, when kty = "RSA" alg | 1467 // only certain alg values are permitted. For example, when kty = "RSA" alg |
1231 // must be of the RSA family, or when kty = "oct" alg must be symmetric | 1468 // must be of the RSA family, or when kty = "oct" alg must be symmetric |
1232 // algorithm. | 1469 // algorithm. |
| 1470 |
| 1471 // TODO(padolph): key_ops consistency tests |
1233 } | 1472 } |
1234 | 1473 |
1235 TEST_F(SharedCryptoTest, MAYBE(ImportJwkHappy)) { | 1474 TEST_F(SharedCryptoTest, MAYBE(ImportJwkHappy)) { |
1236 | |
1237 // This test verifies the happy path of JWK import, including the application | 1475 // This test verifies the happy path of JWK import, including the application |
1238 // of the imported key material. | 1476 // of the imported key material. |
1239 | 1477 |
1240 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1478 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1241 bool extractable = false; | 1479 bool extractable = false; |
1242 blink::WebCryptoAlgorithm algorithm = | 1480 blink::WebCryptoAlgorithm algorithm = |
1243 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | 1481 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
1244 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; | 1482 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; |
1245 | 1483 |
1246 // Import a symmetric key JWK and HMAC-SHA256 sign() | 1484 // Import a symmetric key JWK and HMAC-SHA256 sign() |
1247 // Uses the first SHA256 test vector from the HMAC sample set above. | 1485 // Uses the first SHA256 test vector from the HMAC sample set above. |
1248 | 1486 |
1249 base::DictionaryValue dict; | 1487 base::DictionaryValue dict; |
1250 dict.SetString("kty", "oct"); | 1488 dict.SetString("kty", "oct"); |
1251 dict.SetString("alg", "HS256"); | 1489 dict.SetString("alg", "HS256"); |
1252 dict.SetString("use", "sig"); | 1490 dict.SetString("use", "sig"); |
1253 dict.SetBoolean("extractable", false); | 1491 dict.SetBoolean("ext", false); |
1254 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 1492 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
1255 | 1493 |
1256 ASSERT_STATUS_SUCCESS( | 1494 ASSERT_STATUS_SUCCESS( |
1257 ImportKeyJwkFromDict(dict, algorithm, extractable, usage_mask, &key)); | 1495 ImportKeyJwkFromDict(dict, algorithm, extractable, usage_mask, &key)); |
1258 | 1496 |
1259 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, | 1497 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, |
1260 key.algorithm().hmacParams()->hash().id()); | 1498 key.algorithm().hmacParams()->hash().id()); |
1261 | 1499 |
1262 const std::vector<uint8> message_raw = HexStringToBytes( | 1500 const std::vector<uint8> message_raw = HexStringToBytes( |
1263 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a" | 1501 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a" |
1264 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92" | 1502 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92" |
1265 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f" | 1503 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f" |
1266 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e"); | 1504 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e"); |
1267 | 1505 |
1268 blink::WebArrayBuffer output; | 1506 blink::WebArrayBuffer output; |
1269 | 1507 |
1270 ASSERT_STATUS_SUCCESS(Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), | 1508 ASSERT_STATUS_SUCCESS(Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), |
1271 key, | 1509 key, |
1272 CryptoData(message_raw), | 1510 CryptoData(message_raw), |
1273 &output)); | 1511 &output)); |
1274 | 1512 |
1275 const std::string mac_raw = | 1513 const std::string mac_raw = |
1276 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b"; | 1514 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b"; |
1277 | 1515 |
1278 ExpectArrayBufferMatchesHex(mac_raw, output); | 1516 ExpectArrayBufferMatchesHex(mac_raw, output); |
1279 | 1517 |
1280 // TODO(padolph): Import an RSA public key JWK and use it | 1518 // TODO(padolph): Import an RSA public key JWK and use it |
1281 } | 1519 } |
1282 | 1520 |
| 1521 TEST_F(SharedCryptoTest, MAYBE(ImportExportJwkSymmetricKey)) { |
| 1522 // Raw keys are generated by openssl: |
| 1523 // % openssl rand -hex <key length bytes> |
| 1524 const char* const key_hex_128 = "3f1e7cd4f6f8543f6b1e16002e688623"; |
| 1525 const char* const key_hex_192 = |
| 1526 "ed91f916dc034eba68a0f9e7f34ddd48b98bd2848109e243"; |
| 1527 const char* const key_hex_256 = |
| 1528 "bd08286b81a74783fd1ccf46b7e05af84ee25ae021210074159e0c4d9d907692"; |
| 1529 const char* const key_hex_384 = |
| 1530 "a22c5441c8b185602283d64c7221de1d0951e706bfc09539435ec0e0ed614e1d406623f2" |
| 1531 "b31d31819fec30993380dd82"; |
| 1532 const char* const key_hex_512 = |
| 1533 "5834f639000d4cf82de124fbfd26fb88d463e99f839a76ba41ac88967c80a3f61e1239a4" |
| 1534 "52e573dba0750e988152988576efd75b8d0229b7aca2ada2afd392ee"; |
| 1535 const blink::WebCryptoAlgorithm aes_cbc_alg = |
| 1536 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
| 1537 const blink::WebCryptoAlgorithm aes_gcm_alg = |
| 1538 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm); |
| 1539 const blink::WebCryptoAlgorithm aes_kw_alg = |
| 1540 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); |
| 1541 const blink::WebCryptoAlgorithm hmac_sha_1_alg = |
| 1542 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1); |
| 1543 const blink::WebCryptoAlgorithm hmac_sha_256_alg = |
| 1544 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
| 1545 const blink::WebCryptoAlgorithm hmac_sha_384_alg = |
| 1546 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha384); |
| 1547 const blink::WebCryptoAlgorithm hmac_sha_512_alg = |
| 1548 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha512); |
| 1549 |
| 1550 struct TestCase { |
| 1551 const char* const key_hex; |
| 1552 const blink::WebCryptoAlgorithm algorithm; |
| 1553 const blink::WebCryptoKeyUsageMask usage; |
| 1554 const char* const jwk_alg; |
| 1555 }; |
| 1556 |
| 1557 // TODO(padolph): Test AES-CTR JWK export, once AES-CTR import works. |
| 1558 const TestCase kTests[] = { |
| 1559 // AES-CBC 128 |
| 1560 {key_hex_128, aes_cbc_alg, |
| 1561 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, |
| 1562 "A128CBC"}, |
| 1563 // AES-CBC 192 |
| 1564 {key_hex_192, aes_cbc_alg, blink::WebCryptoKeyUsageEncrypt, "A192CBC"}, |
| 1565 // AES-CBC 256 |
| 1566 {key_hex_256, aes_cbc_alg, blink::WebCryptoKeyUsageDecrypt, "A256CBC"}, |
| 1567 // AES-GCM 128 |
| 1568 {key_hex_128, aes_gcm_alg, |
| 1569 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, |
| 1570 "A128GCM"}, |
| 1571 // AES-CGM 192 |
| 1572 {key_hex_192, aes_gcm_alg, blink::WebCryptoKeyUsageEncrypt, "A192GCM"}, |
| 1573 // AES-GCM 256 |
| 1574 {key_hex_256, aes_gcm_alg, blink::WebCryptoKeyUsageDecrypt, "A256GCM"}, |
| 1575 // AES-KW 128 |
| 1576 {key_hex_128, aes_kw_alg, |
| 1577 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, |
| 1578 "A128KW"}, |
| 1579 // AES-KW 192 |
| 1580 {key_hex_192, aes_kw_alg, |
| 1581 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, |
| 1582 "A192KW"}, |
| 1583 // AES-KW 256 |
| 1584 {key_hex_256, aes_kw_alg, |
| 1585 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, |
| 1586 "A256KW"}, |
| 1587 // HMAC SHA-1 |
| 1588 {key_hex_256, hmac_sha_1_alg, |
| 1589 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, "HS1"}, |
| 1590 // HMAC SHA-384 |
| 1591 {key_hex_384, hmac_sha_384_alg, blink::WebCryptoKeyUsageSign, "HS384"}, |
| 1592 // HMAC SHA-512 |
| 1593 {key_hex_512, hmac_sha_512_alg, blink::WebCryptoKeyUsageVerify, "HS512"}, |
| 1594 // Large usage value |
| 1595 {key_hex_256, aes_cbc_alg, |
| 1596 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt | |
| 1597 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, |
| 1598 "A256CBC"}, |
| 1599 // Zero usage value |
| 1600 {key_hex_512, hmac_sha_512_alg, 0, "HS512"}, }; |
| 1601 |
| 1602 // Round-trip import/export each key. |
| 1603 |
| 1604 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 1605 blink::WebArrayBuffer json; |
| 1606 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests); |
| 1607 ++test_index) { |
| 1608 SCOPED_TRACE(test_index); |
| 1609 const TestCase& test = kTests[test_index]; |
| 1610 |
| 1611 // Skip AES-GCM tests where not supported. |
| 1612 if (test.algorithm.id() == blink::WebCryptoAlgorithmIdAesGcm && |
| 1613 !SupportsAesGcm()) { |
| 1614 continue; |
| 1615 } |
| 1616 |
| 1617 // Import a raw key. |
| 1618 key = ImportSecretKeyFromRaw( |
| 1619 HexStringToBytes(test.key_hex), test.algorithm, test.usage); |
| 1620 |
| 1621 // Export the key in JWK format and validate. |
| 1622 ASSERT_STATUS_SUCCESS(ExportKeyJwk(key, &json)); |
| 1623 EXPECT_TRUE( |
| 1624 VerifySymmetricJwk(json, test.jwk_alg, test.key_hex, test.usage)); |
| 1625 |
| 1626 // Import the JWK-formatted key. |
| 1627 ASSERT_STATUS_SUCCESS( |
| 1628 ImportKeyJwk(CryptoData(json), test.algorithm, true, test.usage, &key)); |
| 1629 EXPECT_TRUE(key.handle()); |
| 1630 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); |
| 1631 EXPECT_EQ(test.algorithm.id(), key.algorithm().id()); |
| 1632 EXPECT_EQ(true, key.extractable()); |
| 1633 EXPECT_EQ(test.usage, key.usages()); |
| 1634 |
| 1635 // Export the key in raw format and compare to the original. |
| 1636 blink::WebArrayBuffer key_raw_out; |
| 1637 ASSERT_STATUS_SUCCESS( |
| 1638 ExportKey(blink::WebCryptoKeyFormatRaw, key, &key_raw_out)); |
| 1639 ExpectArrayBufferMatchesHex(test.key_hex, key_raw_out); |
| 1640 } |
| 1641 } |
| 1642 |
1283 TEST_F(SharedCryptoTest, MAYBE(ImportExportSpki)) { | 1643 TEST_F(SharedCryptoTest, MAYBE(ImportExportSpki)) { |
1284 // Passing case: Import a valid RSA key in SPKI format. | 1644 // Passing case: Import a valid RSA key in SPKI format. |
1285 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1645 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1286 ASSERT_STATUS_SUCCESS( | 1646 ASSERT_STATUS_SUCCESS( |
1287 ImportKey(blink::WebCryptoKeyFormatSpki, | 1647 ImportKey(blink::WebCryptoKeyFormatSpki, |
1288 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), | 1648 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), |
1289 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), | 1649 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), |
1290 true, | 1650 true, |
1291 blink::WebCryptoKeyUsageEncrypt, | 1651 blink::WebCryptoKeyUsageEncrypt, |
1292 &key)); | 1652 &key)); |
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2472 wrapping_algorithm, | 2832 wrapping_algorithm, |
2473 key_algorithm, | 2833 key_algorithm, |
2474 true, | 2834 true, |
2475 blink::WebCryptoKeyUsageSign, | 2835 blink::WebCryptoKeyUsageSign, |
2476 &unwrapped_key)); | 2836 &unwrapped_key)); |
2477 } | 2837 } |
2478 | 2838 |
2479 } // namespace webcrypto | 2839 } // namespace webcrypto |
2480 | 2840 |
2481 } // namespace content | 2841 } // namespace content |
OLD | NEW |