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/renderer/webcrypto/shared_crypto.h" | 5 #include "content/renderer/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" | |
20 #include "content/public/common/content_paths.h" | 19 #include "content/public/common/content_paths.h" |
21 #include "content/public/renderer/content_renderer_client.h" | 20 #include "content/public/renderer/content_renderer_client.h" |
22 #include "content/renderer/renderer_webkitplatformsupport_impl.h" | 21 #include "content/renderer/renderer_webkitplatformsupport_impl.h" |
23 #include "content/renderer/webcrypto/crypto_data.h" | 22 #include "content/renderer/webcrypto/crypto_data.h" |
24 #include "content/renderer/webcrypto/webcrypto_util.h" | 23 #include "content/renderer/webcrypto/webcrypto_util.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
26 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" | 25 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" |
27 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | 26 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
28 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 27 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
29 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 28 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
273 return blink::WebCryptoAlgorithm::createNull(); | 272 return blink::WebCryptoAlgorithm::createNull(); |
274 } | 273 } |
275 | 274 |
276 // Helper for ImportJwkFailures and ImportJwkOctFailures. Restores the JWK JSON | 275 // Helper for ImportJwkFailures and ImportJwkOctFailures. Restores the JWK JSON |
277 // dictionary to a good state | 276 // dictionary to a good state |
278 void RestoreJwkOctDictionary(base::DictionaryValue* dict) { | 277 void RestoreJwkOctDictionary(base::DictionaryValue* dict) { |
279 dict->Clear(); | 278 dict->Clear(); |
280 dict->SetString("kty", "oct"); | 279 dict->SetString("kty", "oct"); |
281 dict->SetString("alg", "A128CBC"); | 280 dict->SetString("alg", "A128CBC"); |
282 dict->SetString("use", "enc"); | 281 dict->SetString("use", "enc"); |
283 dict->SetBoolean("extractable", false); | 282 dict->SetBoolean("ext", false); |
284 dict->SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); | 283 dict->SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); |
285 } | 284 } |
286 | 285 |
287 // Helper for ImportJwkRsaFailures. Restores the JWK JSON | 286 // Helper for ImportJwkRsaFailures. Restores the JWK JSON |
288 // dictionary to a good state | 287 // dictionary to a good state |
289 void RestoreJwkRsaDictionary(base::DictionaryValue* dict) { | 288 void RestoreJwkRsaDictionary(base::DictionaryValue* dict) { |
290 dict->Clear(); | 289 dict->Clear(); |
291 dict->SetString("kty", "RSA"); | 290 dict->SetString("kty", "RSA"); |
292 dict->SetString("alg", "RSA1_5"); | 291 dict->SetString("alg", "RSA1_5"); |
293 dict->SetString("use", "enc"); | 292 dict->SetString("use", "enc"); |
294 dict->SetBoolean("extractable", false); | 293 dict->SetBoolean("ext", false); |
295 dict->SetString( | 294 dict->SetString( |
296 "n", | 295 "n", |
297 "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk" | 296 "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk" |
298 "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm" | 297 "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm" |
299 "e7PUJHYW1PW6ENTP0ibeiNOfFvs"); | 298 "e7PUJHYW1PW6ENTP0ibeiNOfFvs"); |
300 dict->SetString("e", "AQAB"); | 299 dict->SetString("e", "AQAB"); |
301 } | 300 } |
302 | 301 |
303 blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm( | 302 blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm( |
304 blink::WebCryptoAlgorithmId algorithm_id, | 303 blink::WebCryptoAlgorithmId algorithm_id, |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
527 bool extractable, | 526 bool extractable, |
528 blink::WebCryptoKeyUsageMask usage_mask, | 527 blink::WebCryptoKeyUsageMask usage_mask, |
529 blink::WebCryptoKey* key) { | 528 blink::WebCryptoKey* key) { |
530 return ImportKeyJwk(CryptoData(MakeJsonVector(dict)), | 529 return ImportKeyJwk(CryptoData(MakeJsonVector(dict)), |
531 algorithm, | 530 algorithm, |
532 extractable, | 531 extractable, |
533 usage_mask, | 532 usage_mask, |
534 key); | 533 key); |
535 } | 534 } |
536 | 535 |
536 // Parses an ArrayBuffer of JSON into a dictionary. | |
537 scoped_ptr<base::DictionaryValue> GetJwkDictionary( | |
538 const blink::WebArrayBuffer& json) { | |
539 base::StringPiece json_string(reinterpret_cast<const char*>(json.data()), | |
540 json.byteLength()); | |
541 base::Value* value = base::JSONReader::Read(json_string); | |
542 EXPECT_TRUE(value); | |
543 base::DictionaryValue* dict_value = NULL; | |
544 value->GetAsDictionary(&dict_value); | |
545 return scoped_ptr<base::DictionaryValue>(dict_value); | |
546 } | |
547 | |
548 // Verifies that the JSON in the input ArrayBuffer contains the provided | |
549 // expected values. Exact matches are required on the fields examined. | |
550 ::testing::AssertionResult VerifySymmetricJwk( | |
551 const blink::WebArrayBuffer& json, | |
552 const std::string& alg_expected, | |
553 const std::string& k_expected_hex, | |
554 blink::WebCryptoKeyUsageMask use_mask_expected) { | |
555 | |
556 scoped_ptr<base::DictionaryValue> dict = GetJwkDictionary(json); | |
557 if (!dict.get() || dict->empty()) | |
558 return ::testing::AssertionFailure() << "JSON parsing failed"; | |
559 | |
560 // ---- kty | |
561 std::string value_string; | |
562 if (!dict->GetString("kty", &value_string)) | |
563 return ::testing::AssertionFailure() << "Missing 'kty'"; | |
564 if (value_string != "oct") | |
565 return ::testing::AssertionFailure() | |
566 << "Expected 'kty' to be 'oct' but found " << value_string; | |
567 | |
568 // ---- alg | |
569 if (!dict->GetString("alg", &value_string)) | |
570 return ::testing::AssertionFailure() << "Missing 'alg'"; | |
571 if (value_string != alg_expected) | |
572 return ::testing::AssertionFailure() << "Expected 'alg' to be " | |
573 << alg_expected << " but found " | |
574 << value_string; | |
575 | |
576 // ---- k | |
577 if (!dict->GetString("k", &value_string)) | |
578 return ::testing::AssertionFailure() << "Missing 'k'"; | |
579 std::string k_value; | |
580 if (!webcrypto::Base64DecodeUrlSafe(value_string, &k_value)) | |
581 return ::testing::AssertionFailure() << "Base64DecodeUrlSafe(k) failed"; | |
582 if (!LowerCaseEqualsASCII(base::HexEncode(k_value.data(), k_value.size()), | |
583 k_expected_hex.c_str())) { | |
584 return ::testing::AssertionFailure() << "Expected 'k' to be " | |
585 << k_expected_hex | |
586 << " but found something different"; | |
587 } | |
588 // ---- ext | |
589 // always expect ext == true in this case | |
590 bool ext_value; | |
591 if (!dict->GetBoolean("ext", &ext_value)) | |
592 return ::testing::AssertionFailure() << "Missing 'ext'"; | |
593 if (!ext_value) | |
594 return ::testing::AssertionFailure() | |
595 << "Expected 'ext' to be true but found false"; | |
596 | |
597 // ---- key_ops | |
598 base::ListValue* key_ops; | |
599 if (!dict->GetList("key_ops", &key_ops)) | |
600 return ::testing::AssertionFailure() << "Missing 'key_ops'"; | |
601 blink::WebCryptoKeyUsageMask key_ops_mask = 0; | |
602 Status status = GetWebCryptoUsagesFromJwkKeyOps(key_ops, &key_ops_mask); | |
603 if (status.IsError()) | |
604 return ::testing::AssertionFailure() << "Failure extracting 'key_ops'"; | |
605 if (key_ops_mask != use_mask_expected) | |
606 return ::testing::AssertionFailure() | |
607 << "Expected 'key_ops' mask to be " << use_mask_expected | |
608 << " but found " << key_ops_mask << " (" << value_string << ")"; | |
609 | |
610 return ::testing::AssertionSuccess(); | |
611 } | |
612 | |
537 } // namespace | 613 } // namespace |
538 | 614 |
539 TEST_F(SharedCryptoTest, StatusToString) { | 615 TEST_F(SharedCryptoTest, StatusToString) { |
540 EXPECT_EQ("Success", Status::Success().ToString()); | 616 EXPECT_EQ("Success", Status::Success().ToString()); |
541 EXPECT_EQ("", Status::Error().ToString()); | 617 EXPECT_EQ("", Status::Error().ToString()); |
542 EXPECT_EQ("The requested operation is unsupported", | 618 EXPECT_EQ("The requested operation is unsupported", |
543 Status::ErrorUnsupported().ToString()); | 619 Status::ErrorUnsupported().ToString()); |
544 EXPECT_EQ("The required JWK property \"kty\" was missing", | 620 EXPECT_EQ("The required JWK property \"kty\" was missing", |
545 Status::ErrorJwkPropertyMissing("kty").ToString()); | 621 Status::ErrorJwkPropertyMissing("kty").ToString()); |
546 EXPECT_EQ("The JWK property \"kty\" must be a string", | 622 EXPECT_EQ("The JWK property \"kty\" must be a string", |
(...skipping 19 matching lines...) Expand all Loading... | |
566 blink::WebArrayBuffer output; | 642 blink::WebArrayBuffer output; |
567 ASSERT_STATUS_SUCCESS( | 643 ASSERT_STATUS_SUCCESS( |
568 Digest(test_algorithm, CryptoData(test_input), &output)); | 644 Digest(test_algorithm, CryptoData(test_input), &output)); |
569 ExpectArrayBufferMatches(test_output, output); | 645 ExpectArrayBufferMatches(test_output, output); |
570 } | 646 } |
571 } | 647 } |
572 | 648 |
573 TEST_F(SharedCryptoTest, HMACSampleSets) { | 649 TEST_F(SharedCryptoTest, HMACSampleSets) { |
574 scoped_ptr<base::ListValue> tests; | 650 scoped_ptr<base::ListValue> tests; |
575 ASSERT_TRUE(ReadJsonTestFileToList("hmac.json", &tests)); | 651 ASSERT_TRUE(ReadJsonTestFileToList("hmac.json", &tests)); |
576 | 652 // TODO(padolph): Missing known answer tests for HMAC SHA224, SHA384, and |
653 // SHA512. | |
577 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { | 654 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { |
578 SCOPED_TRACE(test_index); | 655 SCOPED_TRACE(test_index); |
579 base::DictionaryValue* test; | 656 base::DictionaryValue* test; |
580 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); | 657 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); |
581 | 658 |
582 blink::WebCryptoAlgorithm test_hash = GetDigestAlgorithm(test, "hash"); | 659 blink::WebCryptoAlgorithm test_hash = GetDigestAlgorithm(test, "hash"); |
583 const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); | 660 const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); |
584 const std::vector<uint8> test_message = | 661 const std::vector<uint8> test_message = |
585 GetBytesFromHexString(test, "message"); | 662 GetBytesFromHexString(test, "message"); |
586 const std::vector<uint8> test_mac = GetBytesFromHexString(test, "mac"); | 663 const std::vector<uint8> test_mac = GetBytesFromHexString(test, "mac"); |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
912 // This fails because the algorithm is null. | 989 // This fails because the algorithm is null. |
913 EXPECT_STATUS(Status::ErrorMissingAlgorithmImportRawKey(), | 990 EXPECT_STATUS(Status::ErrorMissingAlgorithmImportRawKey(), |
914 ImportKey(blink::WebCryptoKeyFormatRaw, | 991 ImportKey(blink::WebCryptoKeyFormatRaw, |
915 CryptoData(HexStringToBytes("00000000000000000000")), | 992 CryptoData(HexStringToBytes("00000000000000000000")), |
916 blink::WebCryptoAlgorithm::createNull(), | 993 blink::WebCryptoAlgorithm::createNull(), |
917 true, | 994 true, |
918 blink::WebCryptoKeyUsageEncrypt, | 995 blink::WebCryptoKeyUsageEncrypt, |
919 &key)); | 996 &key)); |
920 } | 997 } |
921 | 998 |
999 TEST_F(SharedCryptoTest, ImportJwkKeyUsage) { | |
1000 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | |
1001 base::DictionaryValue dict; | |
1002 dict.SetString("kty", "oct"); | |
1003 dict.SetBoolean("ext", false); | |
1004 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); | |
1005 const blink::WebCryptoAlgorithm aes_cbc_algorithm = | |
1006 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | |
1007 const blink::WebCryptoAlgorithm hmac_algorithm = | |
1008 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | |
1009 const blink::WebCryptoAlgorithm aes_kw_algorithm = | |
1010 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
1011 | |
1012 // Test null usage. | |
1013 base::ListValue* key_ops = new base::ListValue; | |
1014 // Note: the following call makes dict assume ownership of key_ops. | |
1015 dict.Set("key_ops", key_ops); | |
1016 EXPECT_STATUS_SUCCESS( | |
1017 ImportKeyJwkFromDict(dict, aes_cbc_algorithm, false, 0, &key)); | |
1018 EXPECT_EQ(0, key.usages()); | |
1019 | |
1020 // Test each key_ops value translates to the correct Web Crypto value. | |
1021 struct TestCase { | |
1022 const char* jwk_key_op; | |
1023 const char* jwk_alg; | |
1024 const blink::WebCryptoAlgorithm algorithm; | |
1025 const blink::WebCryptoKeyUsage usage; | |
1026 }; | |
1027 // TODO(padolph): Add 'deriveBits' key_ops value once it is supported. | |
1028 const TestCase test_case[] = { | |
1029 {"encrypt", "A128CBC", aes_cbc_algorithm, | |
1030 blink::WebCryptoKeyUsageEncrypt}, | |
1031 {"decrypt", "A128CBC", aes_cbc_algorithm, | |
1032 blink::WebCryptoKeyUsageDecrypt}, | |
1033 {"sign", "HS256", hmac_algorithm, blink::WebCryptoKeyUsageSign}, | |
1034 {"verify", "HS256", hmac_algorithm, blink::WebCryptoKeyUsageVerify}, | |
1035 {"wrapKey", "A128KW", aes_kw_algorithm, blink::WebCryptoKeyUsageWrapKey}, | |
1036 {"unwrapKey", "A128KW", aes_kw_algorithm, | |
1037 blink::WebCryptoKeyUsageUnwrapKey}, | |
1038 {"deriveKey", "HS256", hmac_algorithm, | |
1039 blink::WebCryptoKeyUsageDeriveKey}}; | |
1040 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_case); ++i) { | |
1041 SCOPED_TRACE(i); | |
1042 dict.SetString("alg", test_case[i].jwk_alg); | |
1043 key_ops->Clear(); | |
1044 key_ops->AppendString(test_case[i].jwk_key_op); | |
1045 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( | |
1046 dict, test_case[i].algorithm, false, test_case[i].usage, &key)); | |
1047 EXPECT_EQ(test_case[i].usage, key.usages()); | |
1048 } | |
1049 | |
1050 // Test discrete multiple usages. | |
1051 dict.SetString("alg", "A128CBC"); | |
1052 key_ops->Clear(); | |
1053 key_ops->AppendString("encrypt"); | |
1054 key_ops->AppendString("decrypt"); | |
1055 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( | |
1056 dict, | |
1057 aes_cbc_algorithm, | |
1058 false, | |
1059 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt, | |
1060 &key)); | |
1061 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt, | |
1062 key.usages()); | |
1063 | |
1064 // Test constrained key usage (input usage is a subset of JWK usage). | |
1065 key_ops->Clear(); | |
1066 key_ops->AppendString("encrypt"); | |
1067 key_ops->AppendString("decrypt"); | |
1068 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( | |
1069 dict, aes_cbc_algorithm, false, blink::WebCryptoKeyUsageDecrypt, &key)); | |
1070 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt, key.usages()); | |
1071 | |
1072 // Test failure if input usage is NOT a strict subset of the JWK usage. | |
1073 key_ops->Clear(); | |
1074 key_ops->AppendString("encrypt"); | |
1075 EXPECT_STATUS(Status::ErrorJwkKeyopsInconsistent(), | |
1076 ImportKeyJwkFromDict(dict, | |
1077 aes_cbc_algorithm, | |
1078 false, | |
1079 blink::WebCryptoKeyUsageEncrypt | | |
1080 blink::WebCryptoKeyUsageDecrypt, | |
1081 &key)); | |
1082 | |
1083 // Test 'use' inconsistent with 'key_ops'. | |
1084 dict.SetString("alg", "HS256"); | |
1085 dict.SetString("use", "sig"); | |
1086 key_ops->AppendString("sign"); | |
1087 key_ops->AppendString("verify"); | |
1088 key_ops->AppendString("encrypt"); | |
1089 EXPECT_STATUS(Status::ErrorJwkUseAndKeyopsInconsistent(), | |
1090 ImportKeyJwkFromDict(dict, | |
1091 hmac_algorithm, | |
1092 false, | |
1093 blink::WebCryptoKeyUsageSign | | |
1094 blink::WebCryptoKeyUsageVerify, | |
1095 &key)); | |
1096 | |
1097 // Test JWK composite 'sig' use | |
1098 dict.Remove("key_ops", NULL); | |
1099 dict.SetString("use", "sig"); | |
1100 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( | |
1101 dict, | |
1102 hmac_algorithm, | |
1103 false, | |
1104 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, | |
1105 &key)); | |
1106 EXPECT_EQ(blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, | |
1107 key.usages()); | |
1108 | |
1109 // Test JWK composite use 'enc' usage | |
1110 dict.SetString("alg", "A128CBC"); | |
1111 dict.SetString("use", "enc"); | |
1112 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( | |
1113 dict, | |
1114 aes_cbc_algorithm, | |
1115 false, | |
1116 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt | | |
1117 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey | | |
1118 blink::WebCryptoKeyUsageDeriveKey, | |
1119 &key)); | |
1120 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt | | |
1121 blink::WebCryptoKeyUsageWrapKey | | |
1122 blink::WebCryptoKeyUsageUnwrapKey | | |
1123 blink::WebCryptoKeyUsageDeriveKey, | |
1124 key.usages()); | |
1125 } | |
1126 | |
922 TEST_F(SharedCryptoTest, ImportJwkFailures) { | 1127 TEST_F(SharedCryptoTest, ImportJwkFailures) { |
923 | 1128 |
924 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1129 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
925 blink::WebCryptoAlgorithm algorithm = | 1130 blink::WebCryptoAlgorithm algorithm = |
926 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | 1131 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
927 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; | 1132 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; |
928 | 1133 |
929 // Baseline pass: each test below breaks a single item, so we start with a | 1134 // Baseline pass: each test below breaks a single item, so we start with a |
930 // passing case to make sure each failure is caused by the isolated break. | 1135 // passing case to make sure each failure is caused by the isolated break. |
931 // Each breaking subtest below resets the dictionary to this passing case when | 1136 // 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... | |
981 RestoreJwkOctDictionary(&dict); | 1186 RestoreJwkOctDictionary(&dict); |
982 | 1187 |
983 // Fail on kty wrong type. | 1188 // Fail on kty wrong type. |
984 dict.SetDouble("kty", 0.1); | 1189 dict.SetDouble("kty", 0.1); |
985 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("kty", "string"), | 1190 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("kty", "string"), |
986 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1191 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
987 RestoreJwkOctDictionary(&dict); | 1192 RestoreJwkOctDictionary(&dict); |
988 | 1193 |
989 // Fail on invalid use. | 1194 // Fail on invalid use. |
990 dict.SetString("use", "foo"); | 1195 dict.SetString("use", "foo"); |
991 EXPECT_STATUS(Status::ErrorJwkUnrecognizedUsage(), | 1196 EXPECT_STATUS(Status::ErrorJwkUnrecognizedUse(), |
992 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1197 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
993 RestoreJwkOctDictionary(&dict); | 1198 RestoreJwkOctDictionary(&dict); |
994 | 1199 |
995 // Fail on invalid use (wrong type). | 1200 // Fail on invalid use (wrong type). |
996 dict.SetBoolean("use", true); | 1201 dict.SetBoolean("use", true); |
997 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("use", "string"), | 1202 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("use", "string"), |
998 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1203 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
999 RestoreJwkOctDictionary(&dict); | 1204 RestoreJwkOctDictionary(&dict); |
1000 | 1205 |
1001 // Fail on invalid extractable (wrong type). | 1206 // Fail on invalid extractable (wrong type). |
1002 dict.SetInteger("extractable", 0); | 1207 dict.SetInteger("ext", 0); |
1003 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("extractable", "boolean"), | 1208 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("ext", "boolean"), |
1209 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | |
1210 RestoreJwkOctDictionary(&dict); | |
1211 | |
1212 // Fail on invalid key_ops (wrong type). | |
1213 dict.SetBoolean("key_ops", true); | |
1214 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("key_ops", "list"), | |
1215 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | |
1216 RestoreJwkOctDictionary(&dict); | |
1217 | |
1218 // Fail on invalid key_ops (wrong element value). | |
1219 base::ListValue* key_ops = new base::ListValue; | |
1220 // Note: the following call makes dict assume ownership of key_ops. | |
1221 dict.Set("key_ops", key_ops); | |
1222 key_ops->AppendString("foo"); | |
1223 EXPECT_STATUS(Status::ErrorJwkUnrecognizedKeyop(), | |
1004 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1224 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1005 RestoreJwkOctDictionary(&dict); | 1225 RestoreJwkOctDictionary(&dict); |
1006 } | 1226 } |
1007 | 1227 |
1008 TEST_F(SharedCryptoTest, ImportJwkOctFailures) { | 1228 TEST_F(SharedCryptoTest, ImportJwkOctFailures) { |
1009 | 1229 |
1010 base::DictionaryValue dict; | 1230 base::DictionaryValue dict; |
1011 RestoreJwkOctDictionary(&dict); | 1231 RestoreJwkOctDictionary(&dict); |
1012 blink::WebCryptoAlgorithm algorithm = | 1232 blink::WebCryptoAlgorithm algorithm = |
1013 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | 1233 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1138 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); | 1358 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); |
1139 key = blink::WebCryptoKey::createNull(); | 1359 key = blink::WebCryptoKey::createNull(); |
1140 | 1360 |
1141 // Consistency rules when JWK value exists: Fail if inconsistency is found. | 1361 // Consistency rules when JWK value exists: Fail if inconsistency is found. |
1142 | 1362 |
1143 // Pass: All input values are consistent with the JWK values. | 1363 // Pass: All input values are consistent with the JWK values. |
1144 dict.Clear(); | 1364 dict.Clear(); |
1145 dict.SetString("kty", "oct"); | 1365 dict.SetString("kty", "oct"); |
1146 dict.SetString("alg", "HS256"); | 1366 dict.SetString("alg", "HS256"); |
1147 dict.SetString("use", "sig"); | 1367 dict.SetString("use", "sig"); |
1148 dict.SetBoolean("extractable", false); | 1368 dict.SetBoolean("ext", false); |
1149 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 1369 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
1150 json_vec = MakeJsonVector(dict); | 1370 json_vec = MakeJsonVector(dict); |
1151 EXPECT_STATUS_SUCCESS(ImportKeyJwk( | 1371 EXPECT_STATUS_SUCCESS(ImportKeyJwk( |
1152 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); | 1372 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); |
1153 | 1373 |
1154 // Extractable cases: | 1374 // Extractable cases: |
1155 // 1. input=T, JWK=F ==> fail (inconsistent) | 1375 // 1. input=T, JWK=F ==> fail (inconsistent) |
1156 // 4. input=F, JWK=F ==> pass, result extractable is F | 1376 // 4. input=F, JWK=F ==> pass, result extractable is F |
1157 // 2. input=T, JWK=T ==> pass, result extractable is T | 1377 // 2. input=T, JWK=T ==> pass, result extractable is T |
1158 // 3. input=F, JWK=T ==> pass, result extractable is F | 1378 // 3. input=F, JWK=T ==> pass, result extractable is F |
1159 EXPECT_STATUS( | 1379 EXPECT_STATUS( |
1160 Status::ErrorJwkExtractableInconsistent(), | 1380 Status::ErrorJwkExtInconsistent(), |
1161 ImportKeyJwk(CryptoData(json_vec), algorithm, true, usage_mask, &key)); | 1381 ImportKeyJwk(CryptoData(json_vec), algorithm, true, usage_mask, &key)); |
1162 EXPECT_STATUS_SUCCESS( | 1382 EXPECT_STATUS_SUCCESS( |
1163 ImportKeyJwk(CryptoData(json_vec), algorithm, false, usage_mask, &key)); | 1383 ImportKeyJwk(CryptoData(json_vec), algorithm, false, usage_mask, &key)); |
1164 EXPECT_FALSE(key.extractable()); | 1384 EXPECT_FALSE(key.extractable()); |
1165 dict.SetBoolean("extractable", true); | 1385 dict.SetBoolean("ext", true); |
1166 EXPECT_STATUS_SUCCESS( | 1386 EXPECT_STATUS_SUCCESS( |
1167 ImportKeyJwkFromDict(dict, algorithm, true, usage_mask, &key)); | 1387 ImportKeyJwkFromDict(dict, algorithm, true, usage_mask, &key)); |
1168 EXPECT_TRUE(key.extractable()); | 1388 EXPECT_TRUE(key.extractable()); |
1169 EXPECT_STATUS_SUCCESS( | 1389 EXPECT_STATUS_SUCCESS( |
1170 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1390 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1171 EXPECT_FALSE(key.extractable()); | 1391 EXPECT_FALSE(key.extractable()); |
1172 dict.SetBoolean("extractable", true); // restore previous value | 1392 dict.SetBoolean("ext", true); // restore previous value |
1173 | 1393 |
1174 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value | 1394 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value |
1175 // (HMAC SHA256). | 1395 // (HMAC SHA256). |
1176 EXPECT_STATUS(Status::ErrorJwkAlgorithmInconsistent(), | 1396 EXPECT_STATUS(Status::ErrorJwkAlgorithmInconsistent(), |
1177 ImportKeyJwk(CryptoData(json_vec), | 1397 ImportKeyJwk(CryptoData(json_vec), |
1178 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), | 1398 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
1179 extractable, | 1399 extractable, |
1180 usage_mask, | 1400 usage_mask, |
1181 &key)); | 1401 &key)); |
1182 | 1402 |
(...skipping 21 matching lines...) Expand all Loading... | |
1204 dict, | 1424 dict, |
1205 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), | 1425 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), |
1206 extractable, | 1426 extractable, |
1207 usage_mask, | 1427 usage_mask, |
1208 &key)); | 1428 &key)); |
1209 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); | 1429 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); |
1210 dict.SetString("alg", "HS256"); | 1430 dict.SetString("alg", "HS256"); |
1211 | 1431 |
1212 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value | 1432 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value |
1213 // (sign|verify) | 1433 // (sign|verify) |
1214 EXPECT_STATUS(Status::ErrorJwkUsageInconsistent(), | 1434 EXPECT_STATUS(Status::ErrorJwkUseInconsistent(), |
1215 ImportKeyJwk(CryptoData(json_vec), | 1435 ImportKeyJwk(CryptoData(json_vec), |
1216 algorithm, | 1436 algorithm, |
1217 extractable, | 1437 extractable, |
1218 blink::WebCryptoKeyUsageEncrypt, | 1438 blink::WebCryptoKeyUsageEncrypt, |
1219 &key)); | 1439 &key)); |
1220 | 1440 |
1221 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK | 1441 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK |
1222 // value (sign|verify) | 1442 // value (sign|verify) |
1223 usage_mask = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign | | 1443 usage_mask = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign | |
1224 blink::WebCryptoKeyUsageVerify; | 1444 blink::WebCryptoKeyUsageVerify; |
1225 EXPECT_STATUS( | 1445 EXPECT_STATUS( |
1226 Status::ErrorJwkUsageInconsistent(), | 1446 Status::ErrorJwkUseInconsistent(), |
1227 ImportKeyJwk( | 1447 ImportKeyJwk( |
1228 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); | 1448 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); |
1229 | 1449 |
1230 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, | 1450 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, |
1231 // only certain alg values are permitted. For example, when kty = "RSA" alg | 1451 // only certain alg values are permitted. For example, when kty = "RSA" alg |
1232 // must be of the RSA family, or when kty = "oct" alg must be symmetric | 1452 // must be of the RSA family, or when kty = "oct" alg must be symmetric |
1233 // algorithm. | 1453 // algorithm. |
1454 | |
1455 // TODO(padolph): key_ops consistency tests | |
1234 } | 1456 } |
1235 | 1457 |
1236 TEST_F(SharedCryptoTest, MAYBE(ImportJwkHappy)) { | 1458 TEST_F(SharedCryptoTest, MAYBE(ImportJwkHappy)) { |
1237 | 1459 |
1238 // This test verifies the happy path of JWK import, including the application | 1460 // This test verifies the happy path of JWK import, including the application |
1239 // of the imported key material. | 1461 // of the imported key material. |
1240 | 1462 |
1241 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1463 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1242 bool extractable = false; | 1464 bool extractable = false; |
1243 blink::WebCryptoAlgorithm algorithm = | 1465 blink::WebCryptoAlgorithm algorithm = |
1244 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | 1466 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
1245 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; | 1467 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; |
1246 | 1468 |
1247 // Import a symmetric key JWK and HMAC-SHA256 sign() | 1469 // Import a symmetric key JWK and HMAC-SHA256 sign() |
1248 // Uses the first SHA256 test vector from the HMAC sample set above. | 1470 // Uses the first SHA256 test vector from the HMAC sample set above. |
1249 | 1471 |
1250 base::DictionaryValue dict; | 1472 base::DictionaryValue dict; |
1251 dict.SetString("kty", "oct"); | 1473 dict.SetString("kty", "oct"); |
1252 dict.SetString("alg", "HS256"); | 1474 dict.SetString("alg", "HS256"); |
1253 dict.SetString("use", "sig"); | 1475 dict.SetString("use", "sig"); |
1254 dict.SetBoolean("extractable", false); | 1476 dict.SetBoolean("ext", false); |
1255 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 1477 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
1256 | 1478 |
1257 ASSERT_STATUS_SUCCESS( | 1479 ASSERT_STATUS_SUCCESS( |
1258 ImportKeyJwkFromDict(dict, algorithm, extractable, usage_mask, &key)); | 1480 ImportKeyJwkFromDict(dict, algorithm, extractable, usage_mask, &key)); |
1259 | 1481 |
1260 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, | 1482 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, |
1261 key.algorithm().hmacParams()->hash().id()); | 1483 key.algorithm().hmacParams()->hash().id()); |
1262 | 1484 |
1263 const std::vector<uint8> message_raw = HexStringToBytes( | 1485 const std::vector<uint8> message_raw = HexStringToBytes( |
1264 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a" | 1486 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a" |
1265 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92" | 1487 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92" |
1266 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f" | 1488 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f" |
1267 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e"); | 1489 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e"); |
1268 | 1490 |
1269 blink::WebArrayBuffer output; | 1491 blink::WebArrayBuffer output; |
1270 | 1492 |
1271 ASSERT_STATUS_SUCCESS(Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), | 1493 ASSERT_STATUS_SUCCESS(Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), |
1272 key, | 1494 key, |
1273 CryptoData(message_raw), | 1495 CryptoData(message_raw), |
1274 &output)); | 1496 &output)); |
1275 | 1497 |
1276 const std::string mac_raw = | 1498 const std::string mac_raw = |
1277 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b"; | 1499 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b"; |
1278 | 1500 |
1279 ExpectArrayBufferMatchesHex(mac_raw, output); | 1501 ExpectArrayBufferMatchesHex(mac_raw, output); |
1280 | 1502 |
1281 // TODO(padolph): Import an RSA public key JWK and use it | 1503 // TODO(padolph): Import an RSA public key JWK and use it |
1282 } | 1504 } |
1283 | 1505 |
1506 TEST_F(SharedCryptoTest, MAYBE(ImportExportJwkSymmetricKey)) { | |
1507 // Raw keys are generated by openssl: | |
1508 // % openssl rand -hex <key length bytes> | |
1509 // TODO(padolph): Move this data to external file? Not much unique data here. | |
eroman
2014/03/07 19:33:06
You can remove this comment. I agree fine to leave
padolph
2014/03/09 22:06:36
Done.
| |
1510 const char* const key_hex_128("3f1e7cd4f6f8543f6b1e16002e688623"); | |
eroman
2014/03/07 19:33:06
nit: in chromium code it is more common to use " =
padolph
2014/03/09 22:06:36
Done.
| |
1511 const char* const key_hex_192( | |
1512 "ed91f916dc034eba68a0f9e7f34ddd48b98bd2848109e243"); | |
1513 const char* const key_hex_256( | |
1514 "bd08286b81a74783fd1ccf46b7e05af84ee25ae021210074159e0c4d9d907692"); | |
1515 const char* const key_hex_384( | |
1516 "a22c5441c8b185602283d64c7221de1d0951e706bfc09539435ec0e0ed614e1d406623f2" | |
1517 "b31d31819fec30993380dd82"); | |
1518 const char* const key_hex_512( | |
1519 "5834f639000d4cf82de124fbfd26fb88d463e99f839a76ba41ac88967c80a3f61e1239a4" | |
1520 "52e573dba0750e988152988576efd75b8d0229b7aca2ada2afd392ee"); | |
1521 const blink::WebCryptoAlgorithm aes_cbc_alg = | |
1522 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | |
1523 const blink::WebCryptoAlgorithm aes_gcm_alg = | |
1524 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm); | |
1525 const blink::WebCryptoAlgorithm aes_kw_alg = | |
1526 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
1527 const blink::WebCryptoAlgorithm hmac_sha_1_alg = | |
1528 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1); | |
1529 const blink::WebCryptoAlgorithm hmac_sha_224_alg = | |
1530 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha224); | |
1531 const blink::WebCryptoAlgorithm hmac_sha_256_alg = | |
1532 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | |
1533 const blink::WebCryptoAlgorithm hmac_sha_384_alg = | |
1534 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha384); | |
1535 const blink::WebCryptoAlgorithm hmac_sha_512_alg = | |
1536 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha512); | |
1537 | |
1538 struct TestCase { | |
1539 const char* const key_hex; | |
1540 const blink::WebCryptoAlgorithm algorithm; | |
1541 const blink::WebCryptoKeyUsageMask usage; | |
1542 const char* const jwk_alg; | |
1543 }; | |
1544 | |
1545 // TODO(padolph): Test AES-CTR JWK export, once AES-CTR import works. | |
1546 const TestCase kTests[] = { | |
1547 // AES-CBC 128 | |
1548 {key_hex_128, aes_cbc_alg, | |
1549 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, | |
1550 "A128CBC"}, | |
1551 // AES-CBC 192 | |
1552 {key_hex_192, aes_cbc_alg, blink::WebCryptoKeyUsageEncrypt, "A192CBC"}, | |
1553 // AES-CBC 256 | |
1554 {key_hex_256, aes_cbc_alg, blink::WebCryptoKeyUsageDecrypt, "A256CBC"}, | |
1555 // AES-GCM 128 | |
1556 {key_hex_128, aes_gcm_alg, | |
1557 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, | |
1558 "A128GCM"}, | |
1559 // AES-CGM 192 | |
1560 {key_hex_192, aes_gcm_alg, blink::WebCryptoKeyUsageEncrypt, "A192GCM"}, | |
1561 // AES-GCM 256 | |
1562 {key_hex_256, aes_gcm_alg, blink::WebCryptoKeyUsageDecrypt, "A256GCM"}, | |
1563 // AES-KW 128 | |
1564 {key_hex_128, aes_kw_alg, | |
1565 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, | |
1566 "A128KW"}, | |
1567 // AES-KW 192 | |
1568 {key_hex_192, aes_kw_alg, | |
1569 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, | |
1570 "A192KW"}, | |
1571 // AES-KW 256 | |
1572 {key_hex_256, aes_kw_alg, | |
1573 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, | |
1574 "A256KW"}, | |
1575 // HMAC SHA-1 | |
1576 {key_hex_256, hmac_sha_1_alg, | |
1577 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, "HS1"}, | |
1578 // HMAC SHA-224 | |
1579 {key_hex_256, hmac_sha_224_alg, | |
1580 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, "HS224"}, | |
1581 // HMAC SHA-384 | |
1582 {key_hex_384, hmac_sha_384_alg, blink::WebCryptoKeyUsageSign, "HS384"}, | |
1583 // HMAC SHA-512 | |
1584 {key_hex_512, hmac_sha_512_alg, blink::WebCryptoKeyUsageVerify, "HS512"}, | |
1585 // Large usage value | |
1586 {key_hex_256, aes_cbc_alg, | |
1587 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt | | |
1588 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, | |
1589 "A256CBC"}, | |
1590 // Zero usage value | |
1591 {key_hex_512, hmac_sha_512_alg, 0, "HS512"}, }; | |
1592 | |
1593 // Round-trip import/export each key. | |
1594 | |
1595 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | |
1596 blink::WebArrayBuffer json; | |
1597 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests); | |
1598 ++test_index) { | |
1599 SCOPED_TRACE(test_index); | |
1600 const TestCase& test = kTests[test_index]; | |
1601 | |
1602 // Import a raw key. | |
1603 key = ImportSecretKeyFromRaw( | |
1604 HexStringToBytes(test.key_hex), test.algorithm, test.usage); | |
1605 | |
1606 // Export the key in JWK format and validate. | |
1607 ASSERT_STATUS_SUCCESS(ExportKeyJwk(key, &json)); | |
1608 EXPECT_TRUE( | |
1609 VerifySymmetricJwk(json, test.jwk_alg, test.key_hex, test.usage)); | |
1610 | |
1611 // Import the JWK-formatted key. | |
1612 ASSERT_STATUS_SUCCESS( | |
1613 ImportKeyJwk(CryptoData(json), test.algorithm, true, test.usage, &key)); | |
1614 EXPECT_TRUE(key.handle()); | |
1615 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); | |
1616 EXPECT_EQ(test.algorithm.id(), key.algorithm().id()); | |
1617 EXPECT_EQ(true, key.extractable()); | |
1618 EXPECT_EQ(test.usage, key.usages()); | |
1619 | |
1620 // Export the key in raw format and compare to the original. | |
1621 blink::WebArrayBuffer key_raw_out; | |
1622 ASSERT_STATUS_SUCCESS( | |
1623 ExportKey(blink::WebCryptoKeyFormatRaw, key, &key_raw_out)); | |
1624 ExpectArrayBufferMatchesHex(test.key_hex, key_raw_out); | |
1625 } | |
1626 } | |
1627 | |
1284 TEST_F(SharedCryptoTest, MAYBE(ImportExportSpki)) { | 1628 TEST_F(SharedCryptoTest, MAYBE(ImportExportSpki)) { |
1285 // Passing case: Import a valid RSA key in SPKI format. | 1629 // Passing case: Import a valid RSA key in SPKI format. |
1286 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1630 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1287 ASSERT_STATUS_SUCCESS( | 1631 ASSERT_STATUS_SUCCESS( |
1288 ImportKey(blink::WebCryptoKeyFormatSpki, | 1632 ImportKey(blink::WebCryptoKeyFormatSpki, |
1289 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), | 1633 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), |
1290 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), | 1634 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), |
1291 true, | 1635 true, |
1292 blink::WebCryptoKeyUsageEncrypt, | 1636 blink::WebCryptoKeyUsageEncrypt, |
1293 &key)); | 1637 &key)); |
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2264 test_cipher_text, | 2608 test_cipher_text, |
2265 test_authentication_tag, | 2609 test_authentication_tag, |
2266 &plain_text)); | 2610 &plain_text)); |
2267 } | 2611 } |
2268 } | 2612 } |
2269 } | 2613 } |
2270 | 2614 |
2271 } // namespace webcrypto | 2615 } // namespace webcrypto |
2272 | 2616 |
2273 } // namespace content | 2617 } // namespace content |
OLD | NEW |