| 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 | 151 |
| 152 void ExpectCryptoDataMatchesHex(const std::string& expected_hex, | 152 void ExpectCryptoDataMatchesHex(const std::string& expected_hex, |
| 153 const CryptoData& actual) { | 153 const CryptoData& actual) { |
| 154 EXPECT_STRCASEEQ( | 154 EXPECT_STRCASEEQ( |
| 155 expected_hex.c_str(), | 155 expected_hex.c_str(), |
| 156 base::HexEncode(actual.bytes(), actual.byte_length()).c_str()); | 156 base::HexEncode(actual.bytes(), actual.byte_length()).c_str()); |
| 157 } | 157 } |
| 158 | 158 |
| 159 void ExpectArrayBufferMatchesHex(const std::string& expected_hex, | 159 void ExpectArrayBufferMatchesHex(const std::string& expected_hex, |
| 160 const blink::WebArrayBuffer& array_buffer) { | 160 const blink::WebArrayBuffer& array_buffer) { |
| 161 return ExpectCryptoDataMatchesHex(expected_hex, CryptoData(array_buffer)); | 161 ExpectCryptoDataMatchesHex(expected_hex, CryptoData(array_buffer)); |
| 162 } | 162 } |
| 163 | 163 |
| 164 void ExpectVectorMatches(const std::vector<uint8>& expected, | 164 void ExpectVectorMatches(const std::vector<uint8>& expected, |
| 165 const std::vector<uint8>& actual) { | 165 const std::vector<uint8>& actual) { |
| 166 EXPECT_EQ( | 166 EXPECT_EQ( |
| 167 base::HexEncode(webcrypto::Uint8VectorStart(expected), expected.size()), | 167 base::HexEncode(webcrypto::Uint8VectorStart(expected), expected.size()), |
| 168 base::HexEncode(webcrypto::Uint8VectorStart(actual), actual.size())); | 168 base::HexEncode(webcrypto::Uint8VectorStart(actual), actual.size())); |
| 169 } | 169 } |
| 170 | 170 |
| 171 std::vector<uint8> MakeJsonVector(const std::string& json_string) { | 171 std::vector<uint8> MakeJsonVector(const std::string& json_string) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 return blink::WebCryptoAlgorithm::createNull(); | 277 return blink::WebCryptoAlgorithm::createNull(); |
| 278 } | 278 } |
| 279 | 279 |
| 280 // Helper for ImportJwkFailures and ImportJwkOctFailures. Restores the JWK JSON | 280 // Helper for ImportJwkFailures and ImportJwkOctFailures. Restores the JWK JSON |
| 281 // dictionary to a good state | 281 // dictionary to a good state |
| 282 void RestoreJwkOctDictionary(base::DictionaryValue* dict) { | 282 void RestoreJwkOctDictionary(base::DictionaryValue* dict) { |
| 283 dict->Clear(); | 283 dict->Clear(); |
| 284 dict->SetString("kty", "oct"); | 284 dict->SetString("kty", "oct"); |
| 285 dict->SetString("alg", "A128CBC"); | 285 dict->SetString("alg", "A128CBC"); |
| 286 dict->SetString("use", "enc"); | 286 dict->SetString("use", "enc"); |
| 287 dict->SetBoolean("extractable", false); | 287 dict->SetBoolean("ext", false); |
| 288 dict->SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); | 288 dict->SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); |
| 289 } | 289 } |
| 290 | 290 |
| 291 // Helper for ImportJwkRsaFailures. Restores the JWK JSON | 291 // Helper for ImportJwkRsaFailures. Restores the JWK JSON |
| 292 // dictionary to a good state | 292 // dictionary to a good state |
| 293 void RestoreJwkRsaDictionary(base::DictionaryValue* dict) { | 293 void RestoreJwkRsaDictionary(base::DictionaryValue* dict) { |
| 294 dict->Clear(); | 294 dict->Clear(); |
| 295 dict->SetString("kty", "RSA"); | 295 dict->SetString("kty", "RSA"); |
| 296 dict->SetString("alg", "RSA1_5"); | 296 dict->SetString("alg", "RSA1_5"); |
| 297 dict->SetString("use", "enc"); | 297 dict->SetString("use", "enc"); |
| 298 dict->SetBoolean("extractable", false); | 298 dict->SetBoolean("ext", false); |
| 299 dict->SetString( | 299 dict->SetString( |
| 300 "n", | 300 "n", |
| 301 "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk" | 301 "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk" |
| 302 "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm" | 302 "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm" |
| 303 "e7PUJHYW1PW6ENTP0ibeiNOfFvs"); | 303 "e7PUJHYW1PW6ENTP0ibeiNOfFvs"); |
| 304 dict->SetString("e", "AQAB"); | 304 dict->SetString("e", "AQAB"); |
| 305 } | 305 } |
| 306 | 306 |
| 307 blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm( | 307 blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm( |
| 308 blink::WebCryptoAlgorithmId algorithm_id, | 308 blink::WebCryptoAlgorithmId algorithm_id, |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 bool extractable, | 531 bool extractable, |
| 532 blink::WebCryptoKeyUsageMask usage_mask, | 532 blink::WebCryptoKeyUsageMask usage_mask, |
| 533 blink::WebCryptoKey* key) { | 533 blink::WebCryptoKey* key) { |
| 534 return ImportKeyJwk(CryptoData(MakeJsonVector(dict)), | 534 return ImportKeyJwk(CryptoData(MakeJsonVector(dict)), |
| 535 algorithm, | 535 algorithm, |
| 536 extractable, | 536 extractable, |
| 537 usage_mask, | 537 usage_mask, |
| 538 key); | 538 key); |
| 539 } | 539 } |
| 540 | 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 |
| 541 } // namespace | 618 } // namespace |
| 542 | 619 |
| 543 TEST_F(SharedCryptoTest, StatusToString) { | 620 TEST_F(SharedCryptoTest, StatusToString) { |
| 544 EXPECT_EQ("Success", Status::Success().ToString()); | 621 EXPECT_EQ("Success", Status::Success().ToString()); |
| 545 EXPECT_EQ("", Status::Error().ToString()); | 622 EXPECT_EQ("", Status::Error().ToString()); |
| 546 EXPECT_EQ("The requested operation is unsupported", | 623 EXPECT_EQ("The requested operation is unsupported", |
| 547 Status::ErrorUnsupported().ToString()); | 624 Status::ErrorUnsupported().ToString()); |
| 548 EXPECT_EQ("The required JWK property \"kty\" was missing", | 625 EXPECT_EQ("The required JWK property \"kty\" was missing", |
| 549 Status::ErrorJwkPropertyMissing("kty").ToString()); | 626 Status::ErrorJwkPropertyMissing("kty").ToString()); |
| 550 EXPECT_EQ("The JWK property \"kty\" must be a string", | 627 EXPECT_EQ("The JWK property \"kty\" must be a string", |
| (...skipping 19 matching lines...) Expand all Loading... |
| 570 blink::WebArrayBuffer output; | 647 blink::WebArrayBuffer output; |
| 571 ASSERT_STATUS_SUCCESS( | 648 ASSERT_STATUS_SUCCESS( |
| 572 Digest(test_algorithm, CryptoData(test_input), &output)); | 649 Digest(test_algorithm, CryptoData(test_input), &output)); |
| 573 EXPECT_TRUE(ArrayBufferMatches(test_output, output)); | 650 EXPECT_TRUE(ArrayBufferMatches(test_output, output)); |
| 574 } | 651 } |
| 575 } | 652 } |
| 576 | 653 |
| 577 TEST_F(SharedCryptoTest, HMACSampleSets) { | 654 TEST_F(SharedCryptoTest, HMACSampleSets) { |
| 578 scoped_ptr<base::ListValue> tests; | 655 scoped_ptr<base::ListValue> tests; |
| 579 ASSERT_TRUE(ReadJsonTestFileToList("hmac.json", &tests)); | 656 ASSERT_TRUE(ReadJsonTestFileToList("hmac.json", &tests)); |
| 580 | 657 // TODO(padolph): Missing known answer tests for HMAC SHA224, SHA384, and |
| 658 // SHA512. |
| 581 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { | 659 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { |
| 582 SCOPED_TRACE(test_index); | 660 SCOPED_TRACE(test_index); |
| 583 base::DictionaryValue* test; | 661 base::DictionaryValue* test; |
| 584 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); | 662 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); |
| 585 | 663 |
| 586 blink::WebCryptoAlgorithm test_hash = GetDigestAlgorithm(test, "hash"); | 664 blink::WebCryptoAlgorithm test_hash = GetDigestAlgorithm(test, "hash"); |
| 587 const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); | 665 const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); |
| 588 const std::vector<uint8> test_message = | 666 const std::vector<uint8> test_message = |
| 589 GetBytesFromHexString(test, "message"); | 667 GetBytesFromHexString(test, "message"); |
| 590 const std::vector<uint8> test_mac = GetBytesFromHexString(test, "mac"); | 668 const std::vector<uint8> test_mac = GetBytesFromHexString(test, "mac"); |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 // This fails because the algorithm is null. | 994 // This fails because the algorithm is null. |
| 917 EXPECT_STATUS(Status::ErrorMissingAlgorithmImportRawKey(), | 995 EXPECT_STATUS(Status::ErrorMissingAlgorithmImportRawKey(), |
| 918 ImportKey(blink::WebCryptoKeyFormatRaw, | 996 ImportKey(blink::WebCryptoKeyFormatRaw, |
| 919 CryptoData(HexStringToBytes("00000000000000000000")), | 997 CryptoData(HexStringToBytes("00000000000000000000")), |
| 920 blink::WebCryptoAlgorithm::createNull(), | 998 blink::WebCryptoAlgorithm::createNull(), |
| 921 true, | 999 true, |
| 922 blink::WebCryptoKeyUsageEncrypt, | 1000 blink::WebCryptoKeyUsageEncrypt, |
| 923 &key)); | 1001 &key)); |
| 924 } | 1002 } |
| 925 | 1003 |
| 1004 TEST_F(SharedCryptoTest, ImportJwkKeyUsage) { |
| 1005 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 1006 base::DictionaryValue dict; |
| 1007 dict.SetString("kty", "oct"); |
| 1008 dict.SetBoolean("ext", false); |
| 1009 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); |
| 1010 const blink::WebCryptoAlgorithm aes_cbc_algorithm = |
| 1011 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
| 1012 const blink::WebCryptoAlgorithm hmac_algorithm = |
| 1013 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
| 1014 const blink::WebCryptoAlgorithm aes_kw_algorithm = |
| 1015 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); |
| 1016 |
| 1017 // Test null usage. |
| 1018 base::ListValue* key_ops = new base::ListValue; |
| 1019 // Note: the following call makes dict assume ownership of key_ops. |
| 1020 dict.Set("key_ops", key_ops); |
| 1021 EXPECT_STATUS_SUCCESS( |
| 1022 ImportKeyJwkFromDict(dict, aes_cbc_algorithm, false, 0, &key)); |
| 1023 EXPECT_EQ(0, key.usages()); |
| 1024 |
| 1025 // Test each key_ops value translates to the correct Web Crypto value. |
| 1026 struct TestCase { |
| 1027 const char* jwk_key_op; |
| 1028 const char* jwk_alg; |
| 1029 const blink::WebCryptoAlgorithm algorithm; |
| 1030 const blink::WebCryptoKeyUsage usage; |
| 1031 }; |
| 1032 // TODO(padolph): Add 'deriveBits' key_ops value once it is supported. |
| 1033 const TestCase test_case[] = { |
| 1034 {"encrypt", "A128CBC", aes_cbc_algorithm, |
| 1035 blink::WebCryptoKeyUsageEncrypt}, |
| 1036 {"decrypt", "A128CBC", aes_cbc_algorithm, |
| 1037 blink::WebCryptoKeyUsageDecrypt}, |
| 1038 {"sign", "HS256", hmac_algorithm, blink::WebCryptoKeyUsageSign}, |
| 1039 {"verify", "HS256", hmac_algorithm, blink::WebCryptoKeyUsageVerify}, |
| 1040 {"wrapKey", "A128KW", aes_kw_algorithm, blink::WebCryptoKeyUsageWrapKey}, |
| 1041 {"unwrapKey", "A128KW", aes_kw_algorithm, |
| 1042 blink::WebCryptoKeyUsageUnwrapKey}, |
| 1043 {"deriveKey", "HS256", hmac_algorithm, |
| 1044 blink::WebCryptoKeyUsageDeriveKey}}; |
| 1045 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(test_case); |
| 1046 ++test_index) { |
| 1047 SCOPED_TRACE(test_index); |
| 1048 dict.SetString("alg", test_case[test_index].jwk_alg); |
| 1049 key_ops->Clear(); |
| 1050 key_ops->AppendString(test_case[test_index].jwk_key_op); |
| 1051 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict(dict, |
| 1052 test_case[test_index].algorithm, |
| 1053 false, |
| 1054 test_case[test_index].usage, |
| 1055 &key)); |
| 1056 EXPECT_EQ(test_case[test_index].usage, key.usages()); |
| 1057 } |
| 1058 |
| 1059 // Test discrete multiple usages. |
| 1060 dict.SetString("alg", "A128CBC"); |
| 1061 key_ops->Clear(); |
| 1062 key_ops->AppendString("encrypt"); |
| 1063 key_ops->AppendString("decrypt"); |
| 1064 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( |
| 1065 dict, |
| 1066 aes_cbc_algorithm, |
| 1067 false, |
| 1068 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt, |
| 1069 &key)); |
| 1070 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt, |
| 1071 key.usages()); |
| 1072 |
| 1073 // Test constrained key usage (input usage is a subset of JWK usage). |
| 1074 key_ops->Clear(); |
| 1075 key_ops->AppendString("encrypt"); |
| 1076 key_ops->AppendString("decrypt"); |
| 1077 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( |
| 1078 dict, aes_cbc_algorithm, false, blink::WebCryptoKeyUsageDecrypt, &key)); |
| 1079 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt, key.usages()); |
| 1080 |
| 1081 // Test failure if input usage is NOT a strict subset of the JWK usage. |
| 1082 key_ops->Clear(); |
| 1083 key_ops->AppendString("encrypt"); |
| 1084 EXPECT_STATUS(Status::ErrorJwkKeyopsInconsistent(), |
| 1085 ImportKeyJwkFromDict(dict, |
| 1086 aes_cbc_algorithm, |
| 1087 false, |
| 1088 blink::WebCryptoKeyUsageEncrypt | |
| 1089 blink::WebCryptoKeyUsageDecrypt, |
| 1090 &key)); |
| 1091 |
| 1092 // Test 'use' inconsistent with 'key_ops'. |
| 1093 dict.SetString("alg", "HS256"); |
| 1094 dict.SetString("use", "sig"); |
| 1095 key_ops->AppendString("sign"); |
| 1096 key_ops->AppendString("verify"); |
| 1097 key_ops->AppendString("encrypt"); |
| 1098 EXPECT_STATUS(Status::ErrorJwkUseAndKeyopsInconsistent(), |
| 1099 ImportKeyJwkFromDict(dict, |
| 1100 hmac_algorithm, |
| 1101 false, |
| 1102 blink::WebCryptoKeyUsageSign | |
| 1103 blink::WebCryptoKeyUsageVerify, |
| 1104 &key)); |
| 1105 |
| 1106 // Test JWK composite 'sig' use |
| 1107 dict.Remove("key_ops", NULL); |
| 1108 dict.SetString("use", "sig"); |
| 1109 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( |
| 1110 dict, |
| 1111 hmac_algorithm, |
| 1112 false, |
| 1113 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, |
| 1114 &key)); |
| 1115 EXPECT_EQ(blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, |
| 1116 key.usages()); |
| 1117 |
| 1118 // Test JWK composite use 'enc' usage |
| 1119 dict.SetString("alg", "A128CBC"); |
| 1120 dict.SetString("use", "enc"); |
| 1121 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( |
| 1122 dict, |
| 1123 aes_cbc_algorithm, |
| 1124 false, |
| 1125 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt | |
| 1126 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey | |
| 1127 blink::WebCryptoKeyUsageDeriveKey, |
| 1128 &key)); |
| 1129 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt | |
| 1130 blink::WebCryptoKeyUsageWrapKey | |
| 1131 blink::WebCryptoKeyUsageUnwrapKey | |
| 1132 blink::WebCryptoKeyUsageDeriveKey, |
| 1133 key.usages()); |
| 1134 } |
| 1135 |
| 926 TEST_F(SharedCryptoTest, ImportJwkFailures) { | 1136 TEST_F(SharedCryptoTest, ImportJwkFailures) { |
| 927 | 1137 |
| 928 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1138 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 929 blink::WebCryptoAlgorithm algorithm = | 1139 blink::WebCryptoAlgorithm algorithm = |
| 930 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | 1140 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
| 931 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; | 1141 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; |
| 932 | 1142 |
| 933 // Baseline pass: each test below breaks a single item, so we start with a | 1143 // Baseline pass: each test below breaks a single item, so we start with a |
| 934 // passing case to make sure each failure is caused by the isolated break. | 1144 // passing case to make sure each failure is caused by the isolated break. |
| 935 // Each breaking subtest below resets the dictionary to this passing case when | 1145 // Each breaking subtest below resets the dictionary to this passing case when |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 985 RestoreJwkOctDictionary(&dict); | 1195 RestoreJwkOctDictionary(&dict); |
| 986 | 1196 |
| 987 // Fail on kty wrong type. | 1197 // Fail on kty wrong type. |
| 988 dict.SetDouble("kty", 0.1); | 1198 dict.SetDouble("kty", 0.1); |
| 989 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("kty", "string"), | 1199 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("kty", "string"), |
| 990 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1200 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 991 RestoreJwkOctDictionary(&dict); | 1201 RestoreJwkOctDictionary(&dict); |
| 992 | 1202 |
| 993 // Fail on invalid use. | 1203 // Fail on invalid use. |
| 994 dict.SetString("use", "foo"); | 1204 dict.SetString("use", "foo"); |
| 995 EXPECT_STATUS(Status::ErrorJwkUnrecognizedUsage(), | 1205 EXPECT_STATUS(Status::ErrorJwkUnrecognizedUse(), |
| 996 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1206 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 997 RestoreJwkOctDictionary(&dict); | 1207 RestoreJwkOctDictionary(&dict); |
| 998 | 1208 |
| 999 // Fail on invalid use (wrong type). | 1209 // Fail on invalid use (wrong type). |
| 1000 dict.SetBoolean("use", true); | 1210 dict.SetBoolean("use", true); |
| 1001 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("use", "string"), | 1211 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("use", "string"), |
| 1002 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1212 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 1003 RestoreJwkOctDictionary(&dict); | 1213 RestoreJwkOctDictionary(&dict); |
| 1004 | 1214 |
| 1005 // Fail on invalid extractable (wrong type). | 1215 // Fail on invalid extractable (wrong type). |
| 1006 dict.SetInteger("extractable", 0); | 1216 dict.SetInteger("ext", 0); |
| 1007 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("extractable", "boolean"), | 1217 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("ext", "boolean"), |
| 1218 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 1219 RestoreJwkOctDictionary(&dict); |
| 1220 |
| 1221 // Fail on invalid key_ops (wrong type). |
| 1222 dict.SetBoolean("key_ops", true); |
| 1223 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("key_ops", "list"), |
| 1224 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 1225 RestoreJwkOctDictionary(&dict); |
| 1226 |
| 1227 // Fail on invalid key_ops (wrong element value). |
| 1228 base::ListValue* key_ops = new base::ListValue; |
| 1229 // Note: the following call makes dict assume ownership of key_ops. |
| 1230 dict.Set("key_ops", key_ops); |
| 1231 key_ops->AppendString("foo"); |
| 1232 EXPECT_STATUS(Status::ErrorJwkUnrecognizedKeyop(), |
| 1008 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1233 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 1009 RestoreJwkOctDictionary(&dict); | 1234 RestoreJwkOctDictionary(&dict); |
| 1010 } | 1235 } |
| 1011 | 1236 |
| 1012 TEST_F(SharedCryptoTest, ImportJwkOctFailures) { | 1237 TEST_F(SharedCryptoTest, ImportJwkOctFailures) { |
| 1013 | 1238 |
| 1014 base::DictionaryValue dict; | 1239 base::DictionaryValue dict; |
| 1015 RestoreJwkOctDictionary(&dict); | 1240 RestoreJwkOctDictionary(&dict); |
| 1016 blink::WebCryptoAlgorithm algorithm = | 1241 blink::WebCryptoAlgorithm algorithm = |
| 1017 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | 1242 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); | 1367 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); |
| 1143 key = blink::WebCryptoKey::createNull(); | 1368 key = blink::WebCryptoKey::createNull(); |
| 1144 | 1369 |
| 1145 // Consistency rules when JWK value exists: Fail if inconsistency is found. | 1370 // Consistency rules when JWK value exists: Fail if inconsistency is found. |
| 1146 | 1371 |
| 1147 // Pass: All input values are consistent with the JWK values. | 1372 // Pass: All input values are consistent with the JWK values. |
| 1148 dict.Clear(); | 1373 dict.Clear(); |
| 1149 dict.SetString("kty", "oct"); | 1374 dict.SetString("kty", "oct"); |
| 1150 dict.SetString("alg", "HS256"); | 1375 dict.SetString("alg", "HS256"); |
| 1151 dict.SetString("use", "sig"); | 1376 dict.SetString("use", "sig"); |
| 1152 dict.SetBoolean("extractable", false); | 1377 dict.SetBoolean("ext", false); |
| 1153 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 1378 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
| 1154 json_vec = MakeJsonVector(dict); | 1379 json_vec = MakeJsonVector(dict); |
| 1155 EXPECT_STATUS_SUCCESS(ImportKeyJwk( | 1380 EXPECT_STATUS_SUCCESS(ImportKeyJwk( |
| 1156 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); | 1381 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); |
| 1157 | 1382 |
| 1158 // Extractable cases: | 1383 // Extractable cases: |
| 1159 // 1. input=T, JWK=F ==> fail (inconsistent) | 1384 // 1. input=T, JWK=F ==> fail (inconsistent) |
| 1160 // 4. input=F, JWK=F ==> pass, result extractable is F | 1385 // 4. input=F, JWK=F ==> pass, result extractable is F |
| 1161 // 2. input=T, JWK=T ==> pass, result extractable is T | 1386 // 2. input=T, JWK=T ==> pass, result extractable is T |
| 1162 // 3. input=F, JWK=T ==> pass, result extractable is F | 1387 // 3. input=F, JWK=T ==> pass, result extractable is F |
| 1163 EXPECT_STATUS( | 1388 EXPECT_STATUS( |
| 1164 Status::ErrorJwkExtractableInconsistent(), | 1389 Status::ErrorJwkExtInconsistent(), |
| 1165 ImportKeyJwk(CryptoData(json_vec), algorithm, true, usage_mask, &key)); | 1390 ImportKeyJwk(CryptoData(json_vec), algorithm, true, usage_mask, &key)); |
| 1166 EXPECT_STATUS_SUCCESS( | 1391 EXPECT_STATUS_SUCCESS( |
| 1167 ImportKeyJwk(CryptoData(json_vec), algorithm, false, usage_mask, &key)); | 1392 ImportKeyJwk(CryptoData(json_vec), algorithm, false, usage_mask, &key)); |
| 1168 EXPECT_FALSE(key.extractable()); | 1393 EXPECT_FALSE(key.extractable()); |
| 1169 dict.SetBoolean("extractable", true); | 1394 dict.SetBoolean("ext", true); |
| 1170 EXPECT_STATUS_SUCCESS( | 1395 EXPECT_STATUS_SUCCESS( |
| 1171 ImportKeyJwkFromDict(dict, algorithm, true, usage_mask, &key)); | 1396 ImportKeyJwkFromDict(dict, algorithm, true, usage_mask, &key)); |
| 1172 EXPECT_TRUE(key.extractable()); | 1397 EXPECT_TRUE(key.extractable()); |
| 1173 EXPECT_STATUS_SUCCESS( | 1398 EXPECT_STATUS_SUCCESS( |
| 1174 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1399 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 1175 EXPECT_FALSE(key.extractable()); | 1400 EXPECT_FALSE(key.extractable()); |
| 1176 dict.SetBoolean("extractable", true); // restore previous value | 1401 dict.SetBoolean("ext", true); // restore previous value |
| 1177 | 1402 |
| 1178 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value | 1403 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value |
| 1179 // (HMAC SHA256). | 1404 // (HMAC SHA256). |
| 1180 EXPECT_STATUS(Status::ErrorJwkAlgorithmInconsistent(), | 1405 EXPECT_STATUS(Status::ErrorJwkAlgorithmInconsistent(), |
| 1181 ImportKeyJwk(CryptoData(json_vec), | 1406 ImportKeyJwk(CryptoData(json_vec), |
| 1182 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), | 1407 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
| 1183 extractable, | 1408 extractable, |
| 1184 usage_mask, | 1409 usage_mask, |
| 1185 &key)); | 1410 &key)); |
| 1186 | 1411 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1208 dict, | 1433 dict, |
| 1209 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), | 1434 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), |
| 1210 extractable, | 1435 extractable, |
| 1211 usage_mask, | 1436 usage_mask, |
| 1212 &key)); | 1437 &key)); |
| 1213 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); | 1438 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); |
| 1214 dict.SetString("alg", "HS256"); | 1439 dict.SetString("alg", "HS256"); |
| 1215 | 1440 |
| 1216 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value | 1441 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value |
| 1217 // (sign|verify) | 1442 // (sign|verify) |
| 1218 EXPECT_STATUS(Status::ErrorJwkUsageInconsistent(), | 1443 EXPECT_STATUS(Status::ErrorJwkUseInconsistent(), |
| 1219 ImportKeyJwk(CryptoData(json_vec), | 1444 ImportKeyJwk(CryptoData(json_vec), |
| 1220 algorithm, | 1445 algorithm, |
| 1221 extractable, | 1446 extractable, |
| 1222 blink::WebCryptoKeyUsageEncrypt, | 1447 blink::WebCryptoKeyUsageEncrypt, |
| 1223 &key)); | 1448 &key)); |
| 1224 | 1449 |
| 1225 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK | 1450 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK |
| 1226 // value (sign|verify) | 1451 // value (sign|verify) |
| 1227 usage_mask = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign | | 1452 usage_mask = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign | |
| 1228 blink::WebCryptoKeyUsageVerify; | 1453 blink::WebCryptoKeyUsageVerify; |
| 1229 EXPECT_STATUS( | 1454 EXPECT_STATUS( |
| 1230 Status::ErrorJwkUsageInconsistent(), | 1455 Status::ErrorJwkUseInconsistent(), |
| 1231 ImportKeyJwk( | 1456 ImportKeyJwk( |
| 1232 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); | 1457 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); |
| 1233 | 1458 |
| 1234 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, | 1459 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, |
| 1235 // only certain alg values are permitted. For example, when kty = "RSA" alg | 1460 // only certain alg values are permitted. For example, when kty = "RSA" alg |
| 1236 // must be of the RSA family, or when kty = "oct" alg must be symmetric | 1461 // must be of the RSA family, or when kty = "oct" alg must be symmetric |
| 1237 // algorithm. | 1462 // algorithm. |
| 1463 |
| 1464 // TODO(padolph): key_ops consistency tests |
| 1238 } | 1465 } |
| 1239 | 1466 |
| 1240 TEST_F(SharedCryptoTest, MAYBE(ImportJwkHappy)) { | 1467 TEST_F(SharedCryptoTest, MAYBE(ImportJwkHappy)) { |
| 1241 | 1468 |
| 1242 // This test verifies the happy path of JWK import, including the application | 1469 // This test verifies the happy path of JWK import, including the application |
| 1243 // of the imported key material. | 1470 // of the imported key material. |
| 1244 | 1471 |
| 1245 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1472 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 1246 bool extractable = false; | 1473 bool extractable = false; |
| 1247 blink::WebCryptoAlgorithm algorithm = | 1474 blink::WebCryptoAlgorithm algorithm = |
| 1248 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | 1475 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
| 1249 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; | 1476 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; |
| 1250 | 1477 |
| 1251 // Import a symmetric key JWK and HMAC-SHA256 sign() | 1478 // Import a symmetric key JWK and HMAC-SHA256 sign() |
| 1252 // Uses the first SHA256 test vector from the HMAC sample set above. | 1479 // Uses the first SHA256 test vector from the HMAC sample set above. |
| 1253 | 1480 |
| 1254 base::DictionaryValue dict; | 1481 base::DictionaryValue dict; |
| 1255 dict.SetString("kty", "oct"); | 1482 dict.SetString("kty", "oct"); |
| 1256 dict.SetString("alg", "HS256"); | 1483 dict.SetString("alg", "HS256"); |
| 1257 dict.SetString("use", "sig"); | 1484 dict.SetString("use", "sig"); |
| 1258 dict.SetBoolean("extractable", false); | 1485 dict.SetBoolean("ext", false); |
| 1259 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 1486 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
| 1260 | 1487 |
| 1261 ASSERT_STATUS_SUCCESS( | 1488 ASSERT_STATUS_SUCCESS( |
| 1262 ImportKeyJwkFromDict(dict, algorithm, extractable, usage_mask, &key)); | 1489 ImportKeyJwkFromDict(dict, algorithm, extractable, usage_mask, &key)); |
| 1263 | 1490 |
| 1264 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, | 1491 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, |
| 1265 key.algorithm().hmacParams()->hash().id()); | 1492 key.algorithm().hmacParams()->hash().id()); |
| 1266 | 1493 |
| 1267 const std::vector<uint8> message_raw = HexStringToBytes( | 1494 const std::vector<uint8> message_raw = HexStringToBytes( |
| 1268 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a" | 1495 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a" |
| 1269 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92" | 1496 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92" |
| 1270 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f" | 1497 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f" |
| 1271 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e"); | 1498 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e"); |
| 1272 | 1499 |
| 1273 blink::WebArrayBuffer output; | 1500 blink::WebArrayBuffer output; |
| 1274 | 1501 |
| 1275 ASSERT_STATUS_SUCCESS(Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), | 1502 ASSERT_STATUS_SUCCESS(Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), |
| 1276 key, | 1503 key, |
| 1277 CryptoData(message_raw), | 1504 CryptoData(message_raw), |
| 1278 &output)); | 1505 &output)); |
| 1279 | 1506 |
| 1280 const std::string mac_raw = | 1507 const std::string mac_raw = |
| 1281 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b"; | 1508 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b"; |
| 1282 | 1509 |
| 1283 ExpectArrayBufferMatchesHex(mac_raw, output); | 1510 ExpectArrayBufferMatchesHex(mac_raw, output); |
| 1284 | 1511 |
| 1285 // TODO(padolph): Import an RSA public key JWK and use it | 1512 // TODO(padolph): Import an RSA public key JWK and use it |
| 1286 } | 1513 } |
| 1287 | 1514 |
| 1515 TEST_F(SharedCryptoTest, MAYBE(ImportExportJwkSymmetricKey)) { |
| 1516 // Raw keys are generated by openssl: |
| 1517 // % openssl rand -hex <key length bytes> |
| 1518 const char* const key_hex_128 = "3f1e7cd4f6f8543f6b1e16002e688623"; |
| 1519 const char* const key_hex_192 = |
| 1520 "ed91f916dc034eba68a0f9e7f34ddd48b98bd2848109e243"; |
| 1521 const char* const key_hex_256 = |
| 1522 "bd08286b81a74783fd1ccf46b7e05af84ee25ae021210074159e0c4d9d907692"; |
| 1523 const char* const key_hex_384 = |
| 1524 "a22c5441c8b185602283d64c7221de1d0951e706bfc09539435ec0e0ed614e1d406623f2" |
| 1525 "b31d31819fec30993380dd82"; |
| 1526 const char* const key_hex_512 = |
| 1527 "5834f639000d4cf82de124fbfd26fb88d463e99f839a76ba41ac88967c80a3f61e1239a4" |
| 1528 "52e573dba0750e988152988576efd75b8d0229b7aca2ada2afd392ee"; |
| 1529 const blink::WebCryptoAlgorithm aes_cbc_alg = |
| 1530 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
| 1531 const blink::WebCryptoAlgorithm aes_gcm_alg = |
| 1532 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm); |
| 1533 const blink::WebCryptoAlgorithm aes_kw_alg = |
| 1534 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); |
| 1535 const blink::WebCryptoAlgorithm hmac_sha_1_alg = |
| 1536 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1); |
| 1537 const blink::WebCryptoAlgorithm hmac_sha_224_alg = |
| 1538 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha224); |
| 1539 const blink::WebCryptoAlgorithm hmac_sha_256_alg = |
| 1540 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
| 1541 const blink::WebCryptoAlgorithm hmac_sha_384_alg = |
| 1542 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha384); |
| 1543 const blink::WebCryptoAlgorithm hmac_sha_512_alg = |
| 1544 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha512); |
| 1545 |
| 1546 struct TestCase { |
| 1547 const char* const key_hex; |
| 1548 const blink::WebCryptoAlgorithm algorithm; |
| 1549 const blink::WebCryptoKeyUsageMask usage; |
| 1550 const char* const jwk_alg; |
| 1551 }; |
| 1552 |
| 1553 // TODO(padolph): Test AES-CTR JWK export, once AES-CTR import works. |
| 1554 const TestCase kTests[] = { |
| 1555 // AES-CBC 128 |
| 1556 {key_hex_128, aes_cbc_alg, |
| 1557 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, |
| 1558 "A128CBC"}, |
| 1559 // AES-CBC 192 |
| 1560 {key_hex_192, aes_cbc_alg, blink::WebCryptoKeyUsageEncrypt, "A192CBC"}, |
| 1561 // AES-CBC 256 |
| 1562 {key_hex_256, aes_cbc_alg, blink::WebCryptoKeyUsageDecrypt, "A256CBC"}, |
| 1563 // AES-GCM 128 |
| 1564 {key_hex_128, aes_gcm_alg, |
| 1565 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, |
| 1566 "A128GCM"}, |
| 1567 // AES-CGM 192 |
| 1568 {key_hex_192, aes_gcm_alg, blink::WebCryptoKeyUsageEncrypt, "A192GCM"}, |
| 1569 // AES-GCM 256 |
| 1570 {key_hex_256, aes_gcm_alg, blink::WebCryptoKeyUsageDecrypt, "A256GCM"}, |
| 1571 // AES-KW 128 |
| 1572 {key_hex_128, aes_kw_alg, |
| 1573 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, |
| 1574 "A128KW"}, |
| 1575 // AES-KW 192 |
| 1576 {key_hex_192, aes_kw_alg, |
| 1577 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, |
| 1578 "A192KW"}, |
| 1579 // AES-KW 256 |
| 1580 {key_hex_256, aes_kw_alg, |
| 1581 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, |
| 1582 "A256KW"}, |
| 1583 // HMAC SHA-1 |
| 1584 {key_hex_256, hmac_sha_1_alg, |
| 1585 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, "HS1"}, |
| 1586 // HMAC SHA-384 |
| 1587 {key_hex_384, hmac_sha_384_alg, blink::WebCryptoKeyUsageSign, "HS384"}, |
| 1588 // HMAC SHA-512 |
| 1589 {key_hex_512, hmac_sha_512_alg, blink::WebCryptoKeyUsageVerify, "HS512"}, |
| 1590 // Large usage value |
| 1591 {key_hex_256, aes_cbc_alg, |
| 1592 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt | |
| 1593 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, |
| 1594 "A256CBC"}, |
| 1595 // Zero usage value |
| 1596 {key_hex_512, hmac_sha_512_alg, 0, "HS512"}, }; |
| 1597 |
| 1598 // Round-trip import/export each key. |
| 1599 |
| 1600 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 1601 blink::WebArrayBuffer json; |
| 1602 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests); |
| 1603 ++test_index) { |
| 1604 SCOPED_TRACE(test_index); |
| 1605 const TestCase& test = kTests[test_index]; |
| 1606 |
| 1607 // Import a raw key. |
| 1608 key = ImportSecretKeyFromRaw( |
| 1609 HexStringToBytes(test.key_hex), test.algorithm, test.usage); |
| 1610 |
| 1611 // Export the key in JWK format and validate. |
| 1612 ASSERT_STATUS_SUCCESS(ExportKeyJwk(key, &json)); |
| 1613 EXPECT_TRUE( |
| 1614 VerifySymmetricJwk(json, test.jwk_alg, test.key_hex, test.usage)); |
| 1615 |
| 1616 // Import the JWK-formatted key. |
| 1617 ASSERT_STATUS_SUCCESS( |
| 1618 ImportKeyJwk(CryptoData(json), test.algorithm, true, test.usage, &key)); |
| 1619 EXPECT_TRUE(key.handle()); |
| 1620 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); |
| 1621 EXPECT_EQ(test.algorithm.id(), key.algorithm().id()); |
| 1622 EXPECT_EQ(true, key.extractable()); |
| 1623 EXPECT_EQ(test.usage, key.usages()); |
| 1624 |
| 1625 // Export the key in raw format and compare to the original. |
| 1626 blink::WebArrayBuffer key_raw_out; |
| 1627 ASSERT_STATUS_SUCCESS( |
| 1628 ExportKey(blink::WebCryptoKeyFormatRaw, key, &key_raw_out)); |
| 1629 ExpectArrayBufferMatchesHex(test.key_hex, key_raw_out); |
| 1630 } |
| 1631 } |
| 1632 |
| 1288 TEST_F(SharedCryptoTest, MAYBE(ImportExportSpki)) { | 1633 TEST_F(SharedCryptoTest, MAYBE(ImportExportSpki)) { |
| 1289 // Passing case: Import a valid RSA key in SPKI format. | 1634 // Passing case: Import a valid RSA key in SPKI format. |
| 1290 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1635 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 1291 ASSERT_STATUS_SUCCESS( | 1636 ASSERT_STATUS_SUCCESS( |
| 1292 ImportKey(blink::WebCryptoKeyFormatSpki, | 1637 ImportKey(blink::WebCryptoKeyFormatSpki, |
| 1293 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), | 1638 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), |
| 1294 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), | 1639 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), |
| 1295 true, | 1640 true, |
| 1296 blink::WebCryptoKeyUsageEncrypt, | 1641 blink::WebCryptoKeyUsageEncrypt, |
| 1297 &key)); | 1642 &key)); |
| (...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2308 test_cipher_text, | 2653 test_cipher_text, |
| 2309 test_authentication_tag, | 2654 test_authentication_tag, |
| 2310 &plain_text)); | 2655 &plain_text)); |
| 2311 } | 2656 } |
| 2312 } | 2657 } |
| 2313 } | 2658 } |
| 2314 | 2659 |
| 2315 } // namespace webcrypto | 2660 } // namespace webcrypto |
| 2316 | 2661 |
| 2317 } // namespace content | 2662 } // namespace content |
| OLD | NEW |