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

Side by Side Diff: content/renderer/webcrypto/webcrypto_impl_unittest.cc

Issue 25906002: [webcrypto] Add JWK import for HMAC and AES-CBC key. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixes for eroman and aproskuryakov Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "webcrypto_impl.h" 5 #include "webcrypto_impl.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/json/json_writer.h"
8 #include "base/logging.h" 9 #include "base/logging.h"
9 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
10 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
11 #include "content/public/renderer/content_renderer_client.h" 12 #include "content/public/renderer/content_renderer_client.h"
12 #include "content/renderer/renderer_webkitplatformsupport_impl.h" 13 #include "content/renderer/renderer_webkitplatformsupport_impl.h"
13 #include "content/renderer/webcrypto/webcrypto_impl.h" 14 #include "content/renderer/webcrypto/webcrypto_impl.h"
15 #include "content/renderer/webcrypto/webcrypto_util.h"
14 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" 17 #include "third_party/WebKit/public/platform/WebArrayBuffer.h"
16 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" 18 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
17 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" 19 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
18 #include "third_party/WebKit/public/platform/WebCryptoKey.h" 20 #include "third_party/WebKit/public/platform/WebCryptoKey.h"
19 21
22 namespace content {
23
20 namespace { 24 namespace {
21 25
22 std::vector<uint8> HexStringToBytes(const std::string& hex) { 26 std::vector<uint8> HexStringToBytes(const std::string& hex) {
23 std::vector<uint8> bytes; 27 std::vector<uint8> bytes;
24 base::HexStringToBytes(hex, &bytes); 28 base::HexStringToBytes(hex, &bytes);
25 return bytes; 29 return bytes;
26 } 30 }
27 31
28 void ExpectArrayBufferMatchesHex(const std::string& expected_hex, 32 void ExpectArrayBufferMatchesHex(const std::string& expected_hex,
29 const WebKit::WebArrayBuffer& array_buffer) { 33 const WebKit::WebArrayBuffer& array_buffer) {
30 EXPECT_STRCASEEQ( 34 EXPECT_STRCASEEQ(
31 expected_hex.c_str(), 35 expected_hex.c_str(),
32 base::HexEncode( 36 base::HexEncode(
33 array_buffer.data(), array_buffer.byteLength()).c_str()); 37 array_buffer.data(), array_buffer.byteLength()).c_str());
34 } 38 }
35 39
36 WebKit::WebCryptoAlgorithm CreateAlgorithm(WebKit::WebCryptoAlgorithmId id) { 40 std::vector<uint8> MakeJsonVector(const std::string& json_string) {
37 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(id, NULL); 41 return std::vector<uint8>(json_string.begin(), json_string.end());
38 } 42 }
39 43
40 WebKit::WebCryptoAlgorithm CreateHmacAlgorithm( 44 std::vector<uint8> MakeJsonVector(const base::DictionaryValue& dict) {
41 WebKit::WebCryptoAlgorithmId hashId) { 45 std::string json;
42 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate( 46 base::JSONWriter::Write(&dict, &json);
43 WebKit::WebCryptoAlgorithmIdHmac, 47 return MakeJsonVector(json);
44 new WebKit::WebCryptoHmacParams(CreateAlgorithm(hashId)));
45 } 48 }
46 49
47 WebKit::WebCryptoAlgorithm CreateHmacKeyAlgorithm( 50 // Helper for ImportJwkBadJwk; restores JWK JSON dictionary to a good state
48 WebKit::WebCryptoAlgorithmId hashId, 51 void RestoreDictionaryForImportBadJwkTest(base::DictionaryValue* dict) {
49 unsigned hash_length) { 52 dict->Clear();
50 // hash_length < 0 means unspecified 53 dict->SetString("kty", "oct");
51 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate( 54 dict->SetString("alg", "A128CBC");
52 WebKit::WebCryptoAlgorithmIdHmac, 55 dict->SetString("use", "enc");
53 new WebKit::WebCryptoHmacKeyParams(CreateAlgorithm(hashId), 56 dict->SetBoolean("extractable", false);
54 (hash_length != 0), 57 dict->SetString("k", "GADWrMRHwQfoNaXU5fZvTg==");
55 hash_length));
56 }
57
58 // Returns a pointer to the start of |data|, or NULL if it is empty. This is a
59 // convenience function for getting the pointer, and should not be used beyond
60 // the expected lifetime of |data|.
61 const uint8* Start(const std::vector<uint8>& data) {
62 if (data.empty())
63 return NULL;
64 return &data[0];
65 }
66
67 WebKit::WebCryptoAlgorithm CreateAesCbcAlgorithm(
68 const std::vector<uint8>& iv) {
69 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(
70 WebKit::WebCryptoAlgorithmIdAesCbc,
71 new WebKit::WebCryptoAesCbcParams(Start(iv), iv.size()));
72 }
73
74 WebKit::WebCryptoAlgorithm CreateAesCbcAlgorithm(
75 unsigned short key_length_bits) {
76 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(
77 WebKit::WebCryptoAlgorithmIdAesCbc,
78 new WebKit::WebCryptoAesKeyGenParams(key_length_bits));
79 } 58 }
80 59
81 WebKit::WebCryptoAlgorithm CreateRsaAlgorithm( 60 WebKit::WebCryptoAlgorithm CreateRsaAlgorithm(
82 WebKit::WebCryptoAlgorithmId algorithm_id, 61 WebKit::WebCryptoAlgorithmId algorithm_id,
83 unsigned modulus_length, 62 unsigned modulus_length,
84 const std::vector<uint8>& public_exponent) { 63 const std::vector<uint8>& public_exponent) {
85 DCHECK(algorithm_id == WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || 64 DCHECK(algorithm_id == WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
86 algorithm_id == WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 || 65 algorithm_id == WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
87 algorithm_id == WebKit::WebCryptoAlgorithmIdRsaOaep); 66 algorithm_id == WebKit::WebCryptoAlgorithmIdRsaOaep);
88 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate( 67 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(
89 algorithm_id, 68 algorithm_id,
90 new WebKit::WebCryptoRsaKeyGenParams( 69 new WebKit::WebCryptoRsaKeyGenParams(
91 modulus_length, Start(public_exponent), public_exponent.size())); 70 modulus_length,
71 Start(public_exponent),
72 public_exponent.size()));
92 } 73 }
93 74
94 } // namespace 75 } // namespace
95 76
96 namespace content {
97
98 class WebCryptoImplTest : public testing::Test { 77 class WebCryptoImplTest : public testing::Test {
99 protected: 78 protected:
100 WebKit::WebCryptoKey ImportSecretKeyFromRawHexString( 79 WebKit::WebCryptoKey ImportSecretKeyFromRawHexString(
101 const std::string& key_hex, 80 const std::string& key_hex,
102 const WebKit::WebCryptoAlgorithm& algorithm, 81 const WebKit::WebCryptoAlgorithm& algorithm,
103 WebKit::WebCryptoKeyUsageMask usage) { 82 WebKit::WebCryptoKeyUsageMask usage) {
104 std::vector<uint8> key_raw = HexStringToBytes(key_hex); 83 std::vector<uint8> key_raw = HexStringToBytes(key_hex);
105 84
106 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); 85 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
107 bool extractable = true; 86 bool extractable = true;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 195
217 bool DecryptInternal( 196 bool DecryptInternal(
218 const WebKit::WebCryptoAlgorithm& algorithm, 197 const WebKit::WebCryptoAlgorithm& algorithm,
219 const WebKit::WebCryptoKey& key, 198 const WebKit::WebCryptoKey& key,
220 const std::vector<uint8>& data, 199 const std::vector<uint8>& data,
221 WebKit::WebArrayBuffer* buffer) { 200 WebKit::WebArrayBuffer* buffer) {
222 return crypto_.DecryptInternal( 201 return crypto_.DecryptInternal(
223 algorithm, key, Start(data), data.size(), buffer); 202 algorithm, key, Start(data), data.size(), buffer);
224 } 203 }
225 204
205 bool ImportKeyJwk(
206 const std::vector<uint8>& key_data,
207 const WebKit::WebCryptoAlgorithm& algorithm,
208 bool extractable,
209 WebKit::WebCryptoKeyUsageMask usage_mask,
210 WebKit::WebCryptoKey* key) {
211 return crypto_.ImportKeyJwk(Start(key_data),
212 key_data.size(),
213 algorithm,
214 extractable,
215 usage_mask,
216 key);
217 }
218
226 private: 219 private:
227 WebCryptoImpl crypto_; 220 WebCryptoImpl crypto_;
228 }; 221 };
229 222
230 TEST_F(WebCryptoImplTest, DigestSampleSets) { 223 TEST_F(WebCryptoImplTest, DigestSampleSets) {
231 // The results are stored here in hex format for readability. 224 // The results are stored here in hex format for readability.
232 // 225 //
233 // TODO(bryaneyler): Eventually, all these sample test sets should be replaced 226 // TODO(bryaneyler): Eventually, all these sample test sets should be replaced
234 // with the sets here: http://csrc.nist.gov/groups/STM/cavp/index.html#03 227 // with the sets here: http://csrc.nist.gov/groups/STM/cavp/index.html#03
235 // 228 //
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 // mac 387 // mac
395 "4f1ee7cb36c58803a8721d4ac8c4cf8cae5d8832392eed2a96dc59694252801b", 388 "4f1ee7cb36c58803a8721d4ac8c4cf8cae5d8832392eed2a96dc59694252801b",
396 }, 389 },
397 }; 390 };
398 391
399 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests); 392 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests);
400 ++test_index) { 393 ++test_index) {
401 SCOPED_TRACE(test_index); 394 SCOPED_TRACE(test_index);
402 const TestCase& test = kTests[test_index]; 395 const TestCase& test = kTests[test_index];
403 396
404 WebKit::WebCryptoAlgorithm algorithm = CreateHmacAlgorithm(test.algorithm); 397 WebKit::WebCryptoAlgorithm algorithm =
398 CreateHmacAlgorithmByHashId(test.algorithm);
405 399
406 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString( 400 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString(
407 test.key, algorithm, WebKit::WebCryptoKeyUsageSign); 401 test.key, algorithm, WebKit::WebCryptoKeyUsageSign);
408 402
409 std::vector<uint8> message_raw = HexStringToBytes(test.message); 403 std::vector<uint8> message_raw = HexStringToBytes(test.message);
410 404
411 WebKit::WebArrayBuffer output; 405 WebKit::WebArrayBuffer output;
412 406
413 ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output)); 407 ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output));
414 408
(...skipping 25 matching lines...) Expand all
440 algorithm, 434 algorithm,
441 key, 435 key,
442 kLongSignature, 436 kLongSignature,
443 sizeof(kLongSignature), 437 sizeof(kLongSignature),
444 message_raw, 438 message_raw,
445 &signature_match)); 439 &signature_match));
446 EXPECT_FALSE(signature_match); 440 EXPECT_FALSE(signature_match);
447 } 441 }
448 } 442 }
449 443
444 #if !defined(USE_OPENSSL)
445
450 TEST_F(WebCryptoImplTest, AesCbcFailures) { 446 TEST_F(WebCryptoImplTest, AesCbcFailures) {
451 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString( 447 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString(
452 "2b7e151628aed2a6abf7158809cf4f3c", 448 "2b7e151628aed2a6abf7158809cf4f3c",
453 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc), 449 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc),
454 WebKit::WebCryptoKeyUsageEncrypt | WebKit::WebCryptoKeyUsageDecrypt); 450 WebKit::WebCryptoKeyUsageEncrypt | WebKit::WebCryptoKeyUsageDecrypt);
455 451
456 WebKit::WebArrayBuffer output; 452 WebKit::WebArrayBuffer output;
457 453
458 // Use an invalid |iv| (fewer than 16 bytes) 454 // Use an invalid |iv| (fewer than 16 bytes)
459 { 455 {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 &output)); 631 &output));
636 } 632 }
637 } 633 }
638 } 634 }
639 635
640 // TODO (padolph): Add test to verify generated symmetric keys appear random. 636 // TODO (padolph): Add test to verify generated symmetric keys appear random.
641 637
642 638
643 TEST_F(WebCryptoImplTest, GenerateKeyAes) { 639 TEST_F(WebCryptoImplTest, GenerateKeyAes) {
644 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); 640 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
645 ASSERT_TRUE(GenerateKeyInternal(CreateAesCbcAlgorithm(128), &key)); 641 ASSERT_TRUE(GenerateKeyInternal(CreateAesCbcKeyGenAlgorithm(128), &key));
646 EXPECT_TRUE(key.handle()); 642 EXPECT_TRUE(key.handle());
647 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); 643 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type());
648 } 644 }
649 645
650 TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) { 646 TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) {
651 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); 647 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
652 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(0), &key)); 648 EXPECT_FALSE(
653 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(129), &key)); 649 GenerateKeyInternal(CreateAesCbcKeyGenAlgorithm(0), &key));
650 EXPECT_FALSE(
651 GenerateKeyInternal(CreateAesCbcKeyGenAlgorithm(0), &key));
652 EXPECT_FALSE(
653 GenerateKeyInternal(CreateAesCbcKeyGenAlgorithm(129), &key));
654 } 654 }
655 655
656
656 TEST_F(WebCryptoImplTest, GenerateKeyHmac) { 657 TEST_F(WebCryptoImplTest, GenerateKeyHmac) {
657 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); 658 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
658 WebKit::WebCryptoAlgorithm algorithm = 659 WebKit::WebCryptoAlgorithm algorithm =
659 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 128); 660 CreateHmacKeyGenAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 128);
660 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key)); 661 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key));
661 EXPECT_TRUE(key.handle()); 662 EXPECT_TRUE(key.handle());
662 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); 663 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type());
663 } 664 }
664 665
665 TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) { 666 TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) {
666 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); 667 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
667 WebKit::WebCryptoAlgorithm algorithm = 668 WebKit::WebCryptoAlgorithm algorithm =
668 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 0); 669 CreateHmacKeyGenAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 0);
669 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key)); 670 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key));
670 EXPECT_TRUE(key.handle()); 671 EXPECT_TRUE(key.handle());
671 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); 672 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type());
672 } 673 }
673 674
674 TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) { 675 TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) {
675 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); 676 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
676 677
677 // This fails because the algorithm is null. 678 // This fails because the algorithm is null.
678 EXPECT_FALSE(ImportKeyInternal( 679 EXPECT_FALSE(ImportKeyInternal(
679 WebKit::WebCryptoKeyFormatRaw, 680 WebKit::WebCryptoKeyFormatRaw,
680 HexStringToBytes("00000000000000000000"), 681 HexStringToBytes("00000000000000000000"),
681 WebKit::WebCryptoAlgorithm::createNull(), 682 WebKit::WebCryptoAlgorithm::createNull(),
682 WebKit::WebCryptoKeyUsageSign, 683 WebKit::WebCryptoKeyUsageSign,
683 &key)); 684 &key));
684 } 685 }
685 686
687 #endif //#if !defined(USE_OPENSSL)
688
689 TEST_F(WebCryptoImplTest, ImportJwkBadJwk) {
690
691 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
692 WebKit::WebCryptoAlgorithm algorithm =
693 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc);
694 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageEncrypt;
695
696 // Baseline pass: each test below breaks a single item, so we start with a
697 // passing case to make sure each failure is caused by the isolated break.
698 // Each breaking subtest below resets the dictionary to this passing case when
699 // complete.
700 base::DictionaryValue dict;
701 RestoreDictionaryForImportBadJwkTest(&dict);
702 std::vector<uint8> json_vec = MakeJsonVector(dict);
703 EXPECT_TRUE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
704
705 // Fail on empty JSON.
706 EXPECT_FALSE(ImportKeyJwk(
707 MakeJsonVector(""), algorithm, false, usage_mask, &key));
708
709 // Fail on invalid JSON.
710 const std::vector<uint8> bad_json_vec = MakeJsonVector(
711 "{"
712 "\"kty\" : \"oct\","
713 "\"alg\" : \"HS256\","
714 "\"use\" : "
715 );
716 EXPECT_FALSE(ImportKeyJwk(bad_json_vec, algorithm, false, usage_mask, &key));
717
718 // Fail on JWK alg present but unrecognized.
719 dict.SetString("alg", "A127CBC");
720 json_vec = MakeJsonVector(dict);
721 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
722 RestoreDictionaryForImportBadJwkTest(&dict);
723
724 // Fail on both JWK and input algorithm missing.
725 dict.Remove("alg", NULL);
726 json_vec = MakeJsonVector(dict);
727 EXPECT_FALSE(ImportKeyJwk(json_vec,
728 WebKit::WebCryptoAlgorithm::createNull(),
729 false,
730 usage_mask,
731 &key));
732 RestoreDictionaryForImportBadJwkTest(&dict);
733
734 // Fail on invalid kty.
735 dict.SetString("kty", "foo");
736 json_vec = MakeJsonVector(dict);
737 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
738 RestoreDictionaryForImportBadJwkTest(&dict);
739
740 // Fail on missing kty.
741 dict.Remove("kty", NULL);
742 json_vec = MakeJsonVector(dict);
743 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
744 RestoreDictionaryForImportBadJwkTest(&dict);
745
746 // Fail on invalid use.
747 dict.SetString("use", "foo");
748 json_vec = MakeJsonVector(dict);
749 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
750 RestoreDictionaryForImportBadJwkTest(&dict);
751
752 // Fail on missing k when kty = "oct".
753 dict.Remove("k", NULL);
754 json_vec = MakeJsonVector(dict);
755 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
756 RestoreDictionaryForImportBadJwkTest(&dict);
757
758 // Fail on bad b64 encoding for k.
759 dict.SetString("k", "Qk3f0DsytU8lfza2au #$% Htaw2xpop9GYyTuH0p5GghxTI=");
760 json_vec = MakeJsonVector(dict);
761 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
762 RestoreDictionaryForImportBadJwkTest(&dict);
763
764 // Fail on empty k.
765 dict.SetString("k", "");
766 json_vec = MakeJsonVector(dict);
767 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
768 RestoreDictionaryForImportBadJwkTest(&dict);
769
770 // Fail on k actual length (120 bits) inconsistent with the embedded JWK alg
771 // value (128) for an AES key.
772 dict.SetString("k", "AVj42h0Y5aqGtE3yluKL");
773 json_vec = MakeJsonVector(dict);
774 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
775 RestoreDictionaryForImportBadJwkTest(&dict);
776
777 // TODO(padolph) RSA public key bad data:
778 // Missing n or e when kty = "RSA"
779 // Bad encoding for n or e
780 // Size check on n??
781 // Value check on e??
782 }
783
784 TEST_F(WebCryptoImplTest, ImportJwkInputConsistency) {
785 // The Web Crypto spec says that if a JWK value is present, but is
786 // inconsistent with the input value, the operation must fail.
787
788 // Consistency rules when JWK value is not present: Inputs should be used.
789 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
790 bool extractable = false;
791 WebKit::WebCryptoAlgorithm algorithm =
792 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256);
793 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageVerify;
794 base::DictionaryValue dict;
795 dict.SetString("kty", "oct");
796 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
797 std::vector<uint8> json_vec = MakeJsonVector(dict);
798 EXPECT_TRUE(ImportKeyJwk(json_vec, algorithm, extractable, usage_mask, &key));
799 EXPECT_TRUE(key.handle());
800 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type());
801 EXPECT_EQ(extractable, key.extractable());
802 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdHmac, key.algorithm().id());
803 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdSha256,
804 key.algorithm().hmacParams()->hash().id());
805 EXPECT_EQ(WebKit::WebCryptoKeyUsageVerify, key.usages());
806 key = WebKit::WebCryptoKey::createNull();
807
808 // Consistency rules when JWK value exists: Fail if inconsistency is found.
809
810 // Pass: All input values are consistent with the JWK values.
811 dict.Clear();
812 dict.SetString("kty", "oct");
813 dict.SetString("alg", "HS256");
814 dict.SetString("use", "sig");
815 dict.SetBoolean("extractable", false);
816 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
817 json_vec = MakeJsonVector(dict);
818 EXPECT_TRUE(ImportKeyJwk(
819 json_vec, algorithm, extractable, usage_mask, &key));
820
821 // Extractable cases:
822 // 1. input=T, JWK=F ==> fail (inconsistent)
823 // 4. input=F, JWK=F ==> pass, result extractable is F
824 // 2. input=T, JWK=T ==> pass, result extractable is T
825 // 3. input=F, JWK=T ==> pass, result extractable is F
826 EXPECT_FALSE(
827 ImportKeyJwk(json_vec, algorithm, true, usage_mask, &key));
828 EXPECT_TRUE(
829 ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
830 EXPECT_FALSE(key.extractable());
831 dict.SetBoolean("extractable", true);
832 EXPECT_TRUE(
833 ImportKeyJwk(MakeJsonVector(dict), algorithm, true, usage_mask, &key));
834 EXPECT_TRUE(key.extractable());
835 EXPECT_TRUE(
836 ImportKeyJwk(MakeJsonVector(dict), algorithm, false, usage_mask, &key));
837 EXPECT_FALSE(key.extractable());
838 dict.SetBoolean("extractable", true); // restore previous value
839
840 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value
841 // (HMAC SHA256).
842 EXPECT_FALSE(ImportKeyJwk(json_vec,
843 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc),
844 extractable,
845 usage_mask,
846 &key));
847
848 // Fail: Input algorithm (HMAC SHA1) is inconsistent with JWK value
849 // (HMAC SHA256).
850 EXPECT_FALSE(ImportKeyJwk(
851 json_vec,
852 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha1),
853 extractable,
854 usage_mask,
855 &key));
856
857 // Pass: JWK alg valid but input algorithm isNull: use JWK algorithm value.
858 EXPECT_TRUE(ImportKeyJwk(json_vec,
859 WebKit::WebCryptoAlgorithm::createNull(),
860 extractable,
861 usage_mask,
862 &key));
863 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdHmac, algorithm.id());
864
865 // Pass: JWK alg missing but input algorithm specified: use input value
866 dict.Remove("alg", NULL);
867 EXPECT_TRUE(ImportKeyJwk(
868 MakeJsonVector(dict),
869 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256),
870 extractable,
871 usage_mask,
872 &key));
873 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdHmac, algorithm.id());
874 dict.SetString("alg", "HS256");
875
876 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value
877 // (sign|verify)
878 EXPECT_FALSE(ImportKeyJwk(json_vec,
879 algorithm,
880 extractable,
881 WebKit::WebCryptoKeyUsageEncrypt,
882 &key));
883
884 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK
885 // value (sign|verify)
886 usage_mask = WebKit::WebCryptoKeyUsageEncrypt |
887 WebKit::WebCryptoKeyUsageSign | WebKit::WebCryptoKeyUsageVerify;
888 EXPECT_FALSE(ImportKeyJwk(
889 json_vec, algorithm, extractable, usage_mask, &key));
890 usage_mask = WebKit::WebCryptoKeyUsageSign | WebKit::WebCryptoKeyUsageVerify;
891 }
892
893 TEST_F(WebCryptoImplTest, ImportJwkHappy) {
894
895 // This test verifies the happy path of JWK import, including the application
896 // of the imported key material.
897
898 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull();
899 bool extractable = false;
900 WebKit::WebCryptoAlgorithm algorithm =
901 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256);
902 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageSign;
903
904 // Import a symmetric key JWK and HMAC-SHA256 sign()
905 // Uses the first SHA256 test vector from the HMAC sample set above.
906
907 base::DictionaryValue dict;
908 dict.SetString("kty", "oct");
909 dict.SetString("alg", "HS256");
910 dict.SetString("use", "sig");
911 dict.SetBoolean("extractable", false);
912 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
913 std::vector<uint8> json_vec = MakeJsonVector(dict);
914
915 ASSERT_TRUE(ImportKeyJwk(
916 json_vec, algorithm, extractable, usage_mask, &key));
917
918 const std::vector<uint8> message_raw = HexStringToBytes(
919 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a"
920 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92"
921 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f"
922 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e");
923
924 WebKit::WebArrayBuffer output;
925
926 ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output));
927
928 const std::string mac_raw =
929 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b";
930
931 ExpectArrayBufferMatchesHex(mac_raw, output);
932
933 // TODO(padolph)
934 // Import an RSA public key JWK and use it
935 }
936
686 #if !defined(USE_OPENSSL) 937 #if !defined(USE_OPENSSL)
687 938
688 TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) { 939 TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) {
689 940
690 // Note: using unrealistic short key lengths here to avoid bogging down tests. 941 // Note: using unrealistic short key lengths here to avoid bogging down tests.
691 942
692 // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation. 943 // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation.
693 const unsigned modulus_length = 256; 944 const unsigned modulus_length = 256;
694 const std::vector<uint8> public_exponent = HexStringToBytes("010001"); 945 const std::vector<uint8> public_exponent = HexStringToBytes("010001");
695 WebKit::WebCryptoAlgorithm algorithm = 946 WebKit::WebCryptoAlgorithm algorithm =
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type()); 1037 EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type());
787 EXPECT_EQ(extractable, public_key.extractable()); 1038 EXPECT_EQ(extractable, public_key.extractable());
788 EXPECT_EQ(extractable, private_key.extractable()); 1039 EXPECT_EQ(extractable, private_key.extractable());
789 EXPECT_EQ(usage_mask, public_key.usages()); 1040 EXPECT_EQ(usage_mask, public_key.usages());
790 EXPECT_EQ(usage_mask, private_key.usages()); 1041 EXPECT_EQ(usage_mask, private_key.usages());
791 } 1042 }
792 1043
793 #endif // #if !defined(USE_OPENSSL) 1044 #endif // #if !defined(USE_OPENSSL)
794 1045
795 } // namespace content 1046 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698