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

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: rebase 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 20
19 namespace { 21 namespace {
20 22
21 std::vector<uint8> HexStringToBytes(const std::string& hex) { 23 std::vector<uint8> HexStringToBytes(const std::string& hex) {
22 std::vector<uint8> bytes; 24 std::vector<uint8> bytes;
23 base::HexStringToBytes(hex, &bytes); 25 base::HexStringToBytes(hex, &bytes);
24 return bytes; 26 return bytes;
25 } 27 }
26 28
27 void ExpectArrayBufferMatchesHex(const std::string& expected_hex, 29 void ExpectArrayBufferMatchesHex(const std::string& expected_hex,
28 const WebKit::WebArrayBuffer& array_buffer) { 30 const WebKit::WebArrayBuffer& array_buffer) {
29 EXPECT_STRCASEEQ( 31 EXPECT_STRCASEEQ(
30 expected_hex.c_str(), 32 expected_hex.c_str(),
31 base::HexEncode( 33 base::HexEncode(
32 array_buffer.data(), array_buffer.byteLength()).c_str()); 34 array_buffer.data(), array_buffer.byteLength()).c_str());
33 } 35 }
34 36
35 WebKit::WebCryptoAlgorithm CreateAlgorithm(WebKit::WebCryptoAlgorithmId id) { 37 std::vector<uint8> MakeJsonVector(const std::string& json_string) {
36 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(id, NULL); 38 return std::vector<uint8>(json_string.begin(), json_string.end());
37 } 39 }
38 40
39 WebKit::WebCryptoAlgorithm CreateHmacAlgorithm( 41 std::vector<uint8> MakeJsonVector(const base::DictionaryValue& dict) {
40 WebKit::WebCryptoAlgorithmId hashId) { 42 std::string json;
41 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate( 43 base::JSONWriter::Write(&dict, &json);
42 WebKit::WebCryptoAlgorithmIdHmac, 44 return MakeJsonVector(json);
43 new WebKit::WebCryptoHmacParams(CreateAlgorithm(hashId)));
44 } 45 }
45 46
46 WebKit::WebCryptoAlgorithm CreateHmacKeyAlgorithm( 47 // Helper for ImportJwkBadJwk; restores JWK JSON dictionary to a good state
47 WebKit::WebCryptoAlgorithmId hashId, 48 void RestoreDictionary(base::DictionaryValue* dict) {
eroman 2013/11/01 20:59:58 nit: can you give it a more specific name?
padolph 2013/11/01 23:08:50 Done.
48 unsigned hash_length) { 49 dict->SetString("kty", "oct");
eroman 2013/11/01 20:59:58 How about calling dict->Clear() first, to remove a
padolph 2013/11/01 23:08:50 Done.
49 // hash_length < 0 means unspecified 50 dict->SetString("alg", "HS256");
50 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate( 51 dict->SetString("use", "sig");
51 WebKit::WebCryptoAlgorithmIdHmac, 52 dict->SetBoolean("extractable", false);
52 new WebKit::WebCryptoHmacKeyParams(CreateAlgorithm(hashId), 53 dict->SetString("k", "Qk3f0DsytU8lfza2auHtaw2xpop9GYyTuH0p5GghxTI=");
53 (hash_length != 0),
54 hash_length));
55 }
56
57 // Returns a pointer to the start of |data|, or NULL if it is empty. This is a
58 // convenience function for getting the pointer, and should not be used beyond
59 // the expected lifetime of |data|.
60 const uint8* Start(const std::vector<uint8>& data) {
61 if (data.empty())
62 return NULL;
63 return &data[0];
64 }
65
66 WebKit::WebCryptoAlgorithm CreateAesCbcAlgorithm(
67 const std::vector<uint8>& iv) {
68 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(
69 WebKit::WebCryptoAlgorithmIdAesCbc,
70 new WebKit::WebCryptoAesCbcParams(Start(iv), iv.size()));
71 }
72
73 WebKit::WebCryptoAlgorithm CreateAesCbcAlgorithm(
74 unsigned short key_length_bits) {
75 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(
76 WebKit::WebCryptoAlgorithmIdAesCbc,
77 new WebKit::WebCryptoAesKeyGenParams(key_length_bits));
78 } 54 }
79 55
80 } // namespace 56 } // namespace
81 57
82 namespace content { 58 namespace content {
83 59
84 class WebCryptoImplTest : public testing::Test { 60 class WebCryptoImplTest : public testing::Test {
85 protected: 61 protected:
86 WebKit::WebCryptoKey ImportSecretKeyFromRawHexString( 62 WebKit::WebCryptoKey ImportSecretKeyFromRawHexString(
87 const std::string& key_hex, 63 const std::string& key_hex,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 168
193 bool DecryptInternal( 169 bool DecryptInternal(
194 const WebKit::WebCryptoAlgorithm& algorithm, 170 const WebKit::WebCryptoAlgorithm& algorithm,
195 const WebKit::WebCryptoKey& key, 171 const WebKit::WebCryptoKey& key,
196 const std::vector<uint8>& data, 172 const std::vector<uint8>& data,
197 WebKit::WebArrayBuffer* buffer) { 173 WebKit::WebArrayBuffer* buffer) {
198 return crypto_.DecryptInternal( 174 return crypto_.DecryptInternal(
199 algorithm, key, Start(data), data.size(), buffer); 175 algorithm, key, Start(data), data.size(), buffer);
200 } 176 }
201 177
178 bool ImportKeyJwk(
179 const std::vector<uint8>& key_data,
180 const WebKit::WebCryptoAlgorithm& algorithm,
181 bool extractable,
182 WebKit::WebCryptoKeyUsageMask usage_mask,
183 WebKit::WebCryptoKey* key) {
184 return crypto_.ImportKeyJwk(Start(key_data),
185 key_data.size(),
186 algorithm,
187 extractable,
188 usage_mask,
189 key);
190 }
191
202 private: 192 private:
203 WebCryptoImpl crypto_; 193 WebCryptoImpl crypto_;
204 }; 194 };
205 195
206 TEST_F(WebCryptoImplTest, DigestSampleSets) { 196 TEST_F(WebCryptoImplTest, DigestSampleSets) {
207 // The results are stored here in hex format for readability. 197 // The results are stored here in hex format for readability.
208 // 198 //
209 // TODO(bryaneyler): Eventually, all these sample test sets should be replaced 199 // TODO(bryaneyler): Eventually, all these sample test sets should be replaced
210 // with the sets here: http://csrc.nist.gov/groups/STM/cavp/index.html#03 200 // with the sets here: http://csrc.nist.gov/groups/STM/cavp/index.html#03
211 // 201 //
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 // mac 360 // mac
371 "4f1ee7cb36c58803a8721d4ac8c4cf8cae5d8832392eed2a96dc59694252801b", 361 "4f1ee7cb36c58803a8721d4ac8c4cf8cae5d8832392eed2a96dc59694252801b",
372 }, 362 },
373 }; 363 };
374 364
375 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests); 365 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests);
376 ++test_index) { 366 ++test_index) {
377 SCOPED_TRACE(test_index); 367 SCOPED_TRACE(test_index);
378 const TestCase& test = kTests[test_index]; 368 const TestCase& test = kTests[test_index];
379 369
380 WebKit::WebCryptoAlgorithm algorithm = CreateHmacAlgorithm(test.algorithm); 370 WebKit::WebCryptoAlgorithm algorithm =
371 CreateHmacAlgorithmByHashId(test.algorithm);
381 372
382 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString( 373 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString(
383 test.key, algorithm, WebKit::WebCryptoKeyUsageSign); 374 test.key, algorithm, WebKit::WebCryptoKeyUsageSign);
384 375
385 std::vector<uint8> message_raw = HexStringToBytes(test.message); 376 std::vector<uint8> message_raw = HexStringToBytes(test.message);
386 377
387 WebKit::WebArrayBuffer output; 378 WebKit::WebArrayBuffer output;
388 379
389 ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output)); 380 ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output));
390 381
(...skipping 25 matching lines...) Expand all
416 algorithm, 407 algorithm,
417 key, 408 key,
418 kLongSignature, 409 kLongSignature,
419 sizeof(kLongSignature), 410 sizeof(kLongSignature),
420 message_raw, 411 message_raw,
421 &signature_match)); 412 &signature_match));
422 EXPECT_FALSE(signature_match); 413 EXPECT_FALSE(signature_match);
423 } 414 }
424 } 415 }
425 416
417 #if !defined(USE_OPENSSL)
418
426 TEST_F(WebCryptoImplTest, AesCbcFailures) { 419 TEST_F(WebCryptoImplTest, AesCbcFailures) {
427 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString( 420 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString(
428 "2b7e151628aed2a6abf7158809cf4f3c", 421 "2b7e151628aed2a6abf7158809cf4f3c",
429 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc), 422 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc),
430 WebKit::WebCryptoKeyUsageEncrypt | WebKit::WebCryptoKeyUsageDecrypt); 423 WebKit::WebCryptoKeyUsageEncrypt | WebKit::WebCryptoKeyUsageDecrypt);
431 424
432 WebKit::WebArrayBuffer output; 425 WebKit::WebArrayBuffer output;
433 426
434 // Use an invalid |iv| (fewer than 16 bytes) 427 // Use an invalid |iv| (fewer than 16 bytes)
435 { 428 {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 &output)); 604 &output));
612 } 605 }
613 } 606 }
614 } 607 }
615 608
616 // TODO (padolph): Add test to verify generated symmetric keys appear random. 609 // TODO (padolph): Add test to verify generated symmetric keys appear random.
617 610
618 611
619 TEST_F(WebCryptoImplTest, GenerateKeyAes) { 612 TEST_F(WebCryptoImplTest, GenerateKeyAes) {
620 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); 613 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
621 ASSERT_TRUE(GenerateKeyInternal(CreateAesCbcAlgorithm(128), &key)); 614 ASSERT_TRUE(GenerateKeyInternal(CreateAesCbcKeyGenAlgorithm(128), &key));
622 EXPECT_TRUE(key.handle()); 615 EXPECT_TRUE(key.handle());
623 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); 616 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type());
624 } 617 }
625 618
626 TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) { 619 TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) {
627 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); 620 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
628 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(0), &key)); 621 EXPECT_FALSE(
629 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(129), &key)); 622 GenerateKeyInternal(CreateAesCbcKeyGenAlgorithm(0), &key));
623 EXPECT_FALSE(
624 GenerateKeyInternal(CreateAesCbcKeyGenAlgorithm(0), &key));
625 EXPECT_FALSE(
626 GenerateKeyInternal(CreateAesCbcKeyGenAlgorithm(129), &key));
630 } 627 }
631 628
629
632 TEST_F(WebCryptoImplTest, GenerateKeyHmac) { 630 TEST_F(WebCryptoImplTest, GenerateKeyHmac) {
633 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); 631 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
634 WebKit::WebCryptoAlgorithm algorithm = 632 WebKit::WebCryptoAlgorithm algorithm =
635 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 128); 633 CreateHmacKeyGenAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 128);
636 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key)); 634 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key));
637 EXPECT_TRUE(key.handle()); 635 EXPECT_TRUE(key.handle());
638 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); 636 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type());
639 } 637 }
640 638
641 TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) { 639 TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) {
642 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); 640 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
643 WebKit::WebCryptoAlgorithm algorithm = 641 WebKit::WebCryptoAlgorithm algorithm =
644 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 0); 642 CreateHmacKeyGenAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 0);
eroman 2013/11/01 20:59:58 thanks, that is a better name.
645 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key)); 643 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key));
646 EXPECT_TRUE(key.handle()); 644 EXPECT_TRUE(key.handle());
647 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); 645 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type());
648 } 646 }
649 647
650 TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) { 648 TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) {
651 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); 649 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
652 650
653 // This fails because the algorithm is null. 651 // This fails because the algorithm is null.
654 EXPECT_FALSE(ImportKeyInternal( 652 EXPECT_FALSE(ImportKeyInternal(
655 WebKit::WebCryptoKeyFormatRaw, 653 WebKit::WebCryptoKeyFormatRaw,
656 HexStringToBytes("00000000000000000000"), 654 HexStringToBytes("00000000000000000000"),
657 WebKit::WebCryptoAlgorithm::createNull(), 655 WebKit::WebCryptoAlgorithm::createNull(),
658 WebKit::WebCryptoKeyUsageSign, 656 WebKit::WebCryptoKeyUsageSign,
659 &key)); 657 &key));
660 } 658 }
661 659
660 #endif //#if !defined(USE_OPENSSL)
661
662 TEST_F(WebCryptoImplTest, ImportJwkBadJwk) {
663
664 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
eroman 2013/11/01 20:59:58 please use WebKit::WebCryptoKey::createNull()
padolph 2013/11/01 23:08:50 Done.
665 WebKit::WebCryptoAlgorithm algorithm = CreateHmacAlgorithmByDigestLen(256);
666 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageSign;
667
668 // Baseline pass: each test below breaks a single item, so we start with a
669 // passing case to make sure each failure caused by the isolated break. Each
670 // breaking subtest below resets the dictionary to this passing case when
671 // complete.
eroman 2013/11/01 20:59:58 useful comment, thanks
672 base::DictionaryValue dict;
673 RestoreDictionary(&dict);
674 std::vector<uint8> json_vec = MakeJsonVector(dict);
675 EXPECT_TRUE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
676
677 // Fail on empty JSON.
678 EXPECT_FALSE(ImportKeyJwk(
679 MakeJsonVector(""), algorithm, false, usage_mask, &key));
680
681 // Fail on invalid JSON.
682 const std::vector<uint8> bad_json_vec = MakeJsonVector(
683 "{"
684 "\"kty\" : \"oct\","
685 "\"alg\" : \"HS256\","
686 "\"use\" : "
687 );
688 EXPECT_FALSE(ImportKeyJwk(bad_json_vec, algorithm, false, usage_mask, &key));
689
690 // Fail on JWK alg present but unrecognized.
691 dict.SetString("alg", "foo");
692 json_vec = MakeJsonVector(dict);
693 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
694 RestoreDictionary(&dict);
695
696 // Fail on both JWK and input algorithm missing.
697 dict.Remove("alg", NULL);
698 json_vec = MakeJsonVector(dict);
699 EXPECT_FALSE(ImportKeyJwk(json_vec,
700 WebKit::WebCryptoAlgorithm::createNull(),
701 false,
702 usage_mask,
703 &key));
704 RestoreDictionary(&dict);
705
706 // Fail on invalid kty.
707 dict.SetString("kty", "foo");
708 json_vec = MakeJsonVector(dict);
709 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
710 RestoreDictionary(&dict);
711
712 // Fail on missing kty.
713 dict.Remove("kty", NULL);
714 json_vec = MakeJsonVector(dict);
715 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
716 RestoreDictionary(&dict);
717
718 // Fail on invalid use.
719 dict.SetString("use", "foo");
720 json_vec = MakeJsonVector(dict);
721 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
722 RestoreDictionary(&dict);
723
724 // Fail on missing k when kty = "oct".
725 dict.Remove("k", NULL);
726 json_vec = MakeJsonVector(dict);
727 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
728 RestoreDictionary(&dict);
729
730 // Fail on bad b64 encoding for k.
731 dict.SetString("k", "Qk3f0DsytU8lfza2au #$% Htaw2xpop9GYyTuH0p5GghxTI=");
732 json_vec = MakeJsonVector(dict);
733 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
734 RestoreDictionary(&dict);
735
736 // Fail on empty k.
737 dict.SetString("k", "");
738 json_vec = MakeJsonVector(dict);
739 EXPECT_FALSE(ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
740 RestoreDictionary(&dict);
741
742 // TODO(padolph) RSA public key bad data:
743 // Missing n or e when kty = "RSA"
744 // Bad encoding for n or e
745 // Size check on n??
746 // Value check on e??
747 }
748
749 TEST_F(WebCryptoImplTest, ImportJwkInputInconsistent) {
750 // The Web Crypto spec says that if a JWK value is present, but is
751 // inconsistent with the input value, the operation must fail.
752
753 // Consistency rules when JWK value is not present: Inputs should be used.
754 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
eroman 2013/11/01 20:59:58 WebCryptoKey::createNull()
padolph 2013/11/01 23:08:50 Done.
755 bool extractable = true;
756 WebKit::WebCryptoAlgorithm algorithm =
757 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256);
758 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageVerify;
759 base::DictionaryValue dict;
760 dict.SetString("kty", "oct");
761 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
762 std::vector<uint8> json_vec = MakeJsonVector(dict);
763 EXPECT_TRUE(ImportKeyJwk(json_vec, algorithm, extractable, usage_mask, &key));
764 EXPECT_TRUE(key.handle());
765 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type());
766 EXPECT_EQ(extractable, key.extractable());
767 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdHmac, key.algorithm().id());
768 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdSha256,
769 key.algorithm().hmacParams()->hash().id());
770 EXPECT_EQ(WebKit::WebCryptoKeyUsageVerify, key.usages());
771 key = WebCryptoImpl::NullKey();
772
773 // Consistency rules when JWK value exists: Fail if inconsistency is found.
774 // Happy path: all input values are consistent with the JWK values
775 dict.Clear();
776 dict.SetString("kty", "oct");
777 dict.SetString("alg", "HS256");
778 dict.SetString("use", "sig");
779 dict.SetBoolean("extractable", true);
780 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
781 json_vec = MakeJsonVector(dict);
782 EXPECT_TRUE(ImportKeyJwk(
783 json_vec, algorithm, extractable, usage_mask, &key));
784
785 // Fail: Input extractable (false) is inconsistent with JWK value (true).
786 EXPECT_FALSE(
787 ImportKeyJwk(json_vec, algorithm, false, usage_mask, &key));
788
789 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value
790 // (HMAC SHA256).
791 EXPECT_FALSE(ImportKeyJwk(json_vec,
792 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc),
793 extractable,
794 usage_mask,
795 &key));
796
797 // Fail: Input algorithm (HMAC SHA1) is inconsistent with JWK value
798 // (HMAC SHA256).
799 EXPECT_FALSE(ImportKeyJwk(
800 json_vec,
801 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha1),
802 extractable,
803 usage_mask,
804 &key));
805
806 // Pass: JWK alg valid but input algorithm isNull: use JWK algorithm value.
807 EXPECT_TRUE(ImportKeyJwk(json_vec,
808 WebKit::WebCryptoAlgorithm::createNull(),
809 extractable,
810 usage_mask,
811 &key));
812 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdHmac, algorithm.id());
813
814 // Pass: JWK alg missing but input algorithm specified: use input value
815 dict.Remove("alg", NULL);
816 EXPECT_TRUE(ImportKeyJwk(
817 MakeJsonVector(dict),
818 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256),
819 extractable,
820 usage_mask,
821 &key));
822 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdHmac, algorithm.id());
823 dict.SetString("alg", "HS256");
824
825 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value
826 // (sign|verify)
827 EXPECT_FALSE(ImportKeyJwk(json_vec,
828 algorithm,
829 extractable,
830 WebKit::WebCryptoKeyUsageEncrypt,
831 &key));
832
833 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK
834 // value (sign|verify)
835 usage_mask = WebKit::WebCryptoKeyUsageEncrypt |
836 WebKit::WebCryptoKeyUsageSign | WebKit::WebCryptoKeyUsageVerify;
837 EXPECT_FALSE(ImportKeyJwk(
838 json_vec, algorithm, extractable, usage_mask, &key));
839 usage_mask = WebKit::WebCryptoKeyUsageSign | WebKit::WebCryptoKeyUsageVerify;
840 }
841
842 TEST_F(WebCryptoImplTest, ImportJwkHappy) {
843
844 // This test verifies the happy path of JWK import, including the application
845 // of the imported key material.
846
847 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey();
848 bool extractable = false;
849 WebKit::WebCryptoAlgorithm algorithm =
850 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256);
851 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageSign;
852
853 // Import a symmetric key JWK and HMAC-SHA256 sign()
854 // Uses the first SHA256 test vector from the HMAC sample set above.
855
856 base::DictionaryValue dict;
857 dict.SetString("kty", "oct");
858 dict.SetString("alg", "HS256");
859 dict.SetString("use", "sig");
860 dict.SetBoolean("extractable", false);
861 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
862 std::vector<uint8> json_vec = MakeJsonVector(dict);
863
864 ASSERT_TRUE(ImportKeyJwk(
865 json_vec, algorithm, extractable, usage_mask, &key));
866
867 const std::vector<uint8> message_raw = HexStringToBytes(
868 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a"
869 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92"
870 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f"
871 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e");
872
873 WebKit::WebArrayBuffer output;
874
875 ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output));
876
877 const std::string mac_raw =
878 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b";
879
880 ExpectArrayBufferMatchesHex(mac_raw, output);
881
882 // TODO(padolph)
883 // Import an RSA public key JWK and use it
884 }
885
662 } // namespace content 886 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698