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

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 plus more tests 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
46 WebKit::WebCryptoAlgorithm CreateHmacKeyAlgorithm(
47 WebKit::WebCryptoAlgorithmId hashId,
48 unsigned hash_length) {
49 // hash_length < 0 means unspecified
50 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate(
51 WebKit::WebCryptoAlgorithmIdHmac,
52 new WebKit::WebCryptoHmacKeyParams(CreateAlgorithm(hashId),
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 } 45 }
79 46
80 } // namespace 47 } // namespace
81 48
82 namespace content { 49 namespace content {
83 50
84 class WebCryptoImplTest : public testing::Test { 51 class WebCryptoImplTest : public testing::Test {
85 protected: 52 protected:
86 WebKit::WebCryptoKey ImportSecretKeyFromRawHexString( 53 WebKit::WebCryptoKey ImportSecretKeyFromRawHexString(
87 const std::string& key_hex, 54 const std::string& key_hex,
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 161
195 bool DecryptInternal( 162 bool DecryptInternal(
196 const WebKit::WebCryptoAlgorithm& algorithm, 163 const WebKit::WebCryptoAlgorithm& algorithm,
197 const WebKit::WebCryptoKey& key, 164 const WebKit::WebCryptoKey& key,
198 const std::vector<uint8>& data, 165 const std::vector<uint8>& data,
199 WebKit::WebArrayBuffer* buffer) { 166 WebKit::WebArrayBuffer* buffer) {
200 return crypto_.DecryptInternal( 167 return crypto_.DecryptInternal(
201 algorithm, key, Start(data), data.size(), buffer); 168 algorithm, key, Start(data), data.size(), buffer);
202 } 169 }
203 170
171 bool ImportKeyJwk(
172 const std::vector<uint8>& key_data,
173 bool extractable,
174 const WebKit::WebCryptoAlgorithm& algorithm,
175 WebKit::WebCryptoKeyUsageMask usage_mask,
176 scoped_ptr<WebKit::WebCryptoKeyHandle>* handle,
177 WebKit::WebCryptoKeyType* type) {
178 return crypto_.ImportKeyJwk(Start(key_data),
179 key_data.size(),
180 extractable,
181 algorithm,
182 usage_mask,
183 handle,
184 type);
185 }
186
204 private: 187 private:
205 WebCryptoImpl crypto_; 188 WebCryptoImpl crypto_;
206 }; 189 };
207 190
208 TEST_F(WebCryptoImplTest, DigestSampleSets) { 191 TEST_F(WebCryptoImplTest, DigestSampleSets) {
209 // The results are stored here in hex format for readability. 192 // The results are stored here in hex format for readability.
210 // 193 //
211 // TODO(bryaneyler): Eventually, all these sample test sets should be replaced 194 // TODO(bryaneyler): Eventually, all these sample test sets should be replaced
212 // with the sets here: http://csrc.nist.gov/groups/STM/cavp/index.html#03 195 // with the sets here: http://csrc.nist.gov/groups/STM/cavp/index.html#03
213 // 196 //
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 // mac 355 // mac
373 "4f1ee7cb36c58803a8721d4ac8c4cf8cae5d8832392eed2a96dc59694252801b", 356 "4f1ee7cb36c58803a8721d4ac8c4cf8cae5d8832392eed2a96dc59694252801b",
374 }, 357 },
375 }; 358 };
376 359
377 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests); 360 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests);
378 ++test_index) { 361 ++test_index) {
379 SCOPED_TRACE(test_index); 362 SCOPED_TRACE(test_index);
380 const TestCase& test = kTests[test_index]; 363 const TestCase& test = kTests[test_index];
381 364
382 WebKit::WebCryptoAlgorithm algorithm = CreateHmacAlgorithm(test.algorithm); 365 WebKit::WebCryptoAlgorithm algorithm =
366 CreateHmacAlgorithmByHashId(test.algorithm);
383 367
384 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString( 368 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString(
385 test.key, algorithm, WebKit::WebCryptoKeyUsageSign); 369 test.key, algorithm, WebKit::WebCryptoKeyUsageSign);
386 370
387 std::vector<uint8> message_raw = HexStringToBytes(test.message); 371 std::vector<uint8> message_raw = HexStringToBytes(test.message);
388 372
389 WebKit::WebArrayBuffer output; 373 WebKit::WebArrayBuffer output;
390 374
391 ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output)); 375 ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output));
392 376
(...skipping 25 matching lines...) Expand all
418 algorithm, 402 algorithm,
419 key, 403 key,
420 kLongSignature, 404 kLongSignature,
421 sizeof(kLongSignature), 405 sizeof(kLongSignature),
422 message_raw, 406 message_raw,
423 &signature_match)); 407 &signature_match));
424 EXPECT_FALSE(signature_match); 408 EXPECT_FALSE(signature_match);
425 } 409 }
426 } 410 }
427 411
412 #if !defined(USE_OPENSSL)
413
428 TEST_F(WebCryptoImplTest, AesCbcFailures) { 414 TEST_F(WebCryptoImplTest, AesCbcFailures) {
429 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString( 415 WebKit::WebCryptoKey key = ImportSecretKeyFromRawHexString(
430 "2b7e151628aed2a6abf7158809cf4f3c", 416 "2b7e151628aed2a6abf7158809cf4f3c",
431 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc), 417 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc),
432 WebKit::WebCryptoKeyUsageEncrypt | WebKit::WebCryptoKeyUsageDecrypt); 418 WebKit::WebCryptoKeyUsageEncrypt | WebKit::WebCryptoKeyUsageDecrypt);
433 419
434 WebKit::WebArrayBuffer output; 420 WebKit::WebArrayBuffer output;
435 421
436 // Use an invalid |iv| (fewer than 16 bytes) 422 // Use an invalid |iv| (fewer than 16 bytes)
437 { 423 {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 key, 599 key,
614 &cipher_text[0], 600 &cipher_text[0],
615 cipher_text.size() - 3, 601 cipher_text.size() - 3,
616 &output)); 602 &output));
617 } 603 }
618 } 604 }
619 } 605 }
620 606
621 // TODO (padolph): Add test to verify generated symmetric keys appear random. 607 // TODO (padolph): Add test to verify generated symmetric keys appear random.
622 608
623
624 TEST_F(WebCryptoImplTest, GenerateKeyAes) { 609 TEST_F(WebCryptoImplTest, GenerateKeyAes) {
625 scoped_ptr<WebKit::WebCryptoKeyHandle> result; 610 scoped_ptr<WebKit::WebCryptoKeyHandle> result;
626 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic; 611 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic;
627 ASSERT_TRUE(GenerateKeyInternal(CreateAesCbcAlgorithm(128), &result, &type)); 612 ASSERT_TRUE(
613 GenerateKeyInternal(CreateAesCbcKeyGenAlgorithm(128), &result, &type));
628 EXPECT_TRUE(result); 614 EXPECT_TRUE(result);
629 EXPECT_EQ(type, WebKit::WebCryptoKeyTypeSecret); 615 EXPECT_EQ(type, WebKit::WebCryptoKeyTypeSecret);
630 } 616 }
631 617
632 TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) { 618 TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) {
633 scoped_ptr<WebKit::WebCryptoKeyHandle> result; 619 scoped_ptr<WebKit::WebCryptoKeyHandle> result;
634 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic; 620 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic;
635 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(0), &result, &type)); 621 EXPECT_FALSE(
636 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(129), &result, &type)); 622 GenerateKeyInternal(CreateAesCbcKeyGenAlgorithm(0), &result, &type));
623 EXPECT_FALSE(
624 GenerateKeyInternal(CreateAesCbcKeyGenAlgorithm(129), &result, &type));
637 } 625 }
638 626
627
639 TEST_F(WebCryptoImplTest, GenerateKeyHmac) { 628 TEST_F(WebCryptoImplTest, GenerateKeyHmac) {
640 scoped_ptr<WebKit::WebCryptoKeyHandle> result; 629 scoped_ptr<WebKit::WebCryptoKeyHandle> result;
641 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic; 630 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic;
642 WebKit::WebCryptoAlgorithm algorithm = 631 WebKit::WebCryptoAlgorithm algorithm =
643 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 128); 632 CreateHmacKeyGenAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 128);
644 ASSERT_TRUE(GenerateKeyInternal(algorithm, &result, &type)); 633 ASSERT_TRUE(GenerateKeyInternal(algorithm, &result, &type));
645 EXPECT_TRUE(result); 634 EXPECT_TRUE(result);
646 EXPECT_EQ(type, WebKit::WebCryptoKeyTypeSecret); 635 EXPECT_EQ(type, WebKit::WebCryptoKeyTypeSecret);
647 } 636 }
648 637
649 TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) { 638 TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) {
650 scoped_ptr<WebKit::WebCryptoKeyHandle> result; 639 scoped_ptr<WebKit::WebCryptoKeyHandle> result;
651 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic; 640 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic;
652 WebKit::WebCryptoAlgorithm algorithm = 641 WebKit::WebCryptoAlgorithm algorithm =
653 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 0); 642 CreateHmacKeyGenAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 0);
654 ASSERT_TRUE(GenerateKeyInternal(algorithm, &result, &type)); 643 ASSERT_TRUE(GenerateKeyInternal(algorithm, &result, &type));
655 EXPECT_TRUE(result); 644 EXPECT_TRUE(result);
656 EXPECT_EQ(type, WebKit::WebCryptoKeyTypeSecret); 645 EXPECT_EQ(type, WebKit::WebCryptoKeyTypeSecret);
657 } 646 }
658 647
648 #endif //#if !defined(USE_OPENSSL)
649
650 TEST_F(WebCryptoImplTest, ImportJwkBadJwk) {
651
652 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypeSecret;
653 scoped_ptr<WebKit::WebCryptoKeyHandle> handle;
654 WebKit::WebCryptoAlgorithm algorithm = CreateHmacAlgorithmByKeyLen(256);
655 const bool extractable = false;
656 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageSign;
657
658 // Baseline pass: each test below breaks a single item, so we start with a
659 // passing case to make sure each failure caused by the isolated break. Each
660 // breaking subtest below resets the dictionary to this passing case when
661 // complete.
662 const std::string key_val("oct");
663 const std::string alg_val("HS256");
664 const std::string use_val("sig");
665 const std::string k_val("Qk3f0DsytU8lfza2auHtaw2xpop9GYyTuH0p5GghxTI=");
666 base::DictionaryValue dict;
667 dict.SetString("kty", key_val);
668 dict.SetString("alg", alg_val);
669 dict.SetString("use", use_val);
670 dict.SetBoolean("extractable", extractable);
671 dict.SetString("k", k_val);
672 std::vector<uint8> json_vec = MakeJsonVector(dict);
673 EXPECT_TRUE(ImportKeyJwk(
674 json_vec, extractable, algorithm, usage_mask, &handle, &type));
675
676 // Fail on empty JSON.
677 EXPECT_FALSE(ImportKeyJwk(
678 MakeJsonVector(""), extractable, algorithm, usage_mask, &handle, &type));
679
680 // Fail on invalid JSON.
681 const std::vector<uint8> bad_json_vec = MakeJsonVector(
682 "{"
683 "\"kty\" : \"oct\","
684 "\"alg\" : \"HS256\","
685 "\"use\" : "
686 );
687 EXPECT_FALSE(ImportKeyJwk(
688 bad_json_vec, extractable, algorithm, usage_mask, &handle, &type));
689
690 // Fail on Null input algorithm.
691 EXPECT_FALSE(ImportKeyJwk(json_vec,
692 extractable,
693 WebKit::WebCryptoAlgorithm::createNull(),
694 usage_mask,
695 &handle,
696 &type));
697
698 // Fail on Null input handle pointer.
699 EXPECT_FALSE(
700 ImportKeyJwk(json_vec, extractable, algorithm, usage_mask, NULL, &type));
701
702 // Fail on Null input type pointer.
703 EXPECT_FALSE(ImportKeyJwk(
704 json_vec, extractable, algorithm, usage_mask, &handle, NULL));
705
706 // Fail on input algorithm mismatch.
707 EXPECT_FALSE(ImportKeyJwk(json_vec,
708 extractable,
709 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc),
710 usage_mask,
711 &handle,
712 &type));
713
714 // Fail on input algorithm mismatch (inner hash algorithm).
715 EXPECT_FALSE(ImportKeyJwk(json_vec,
716 extractable,
717 CreateHmacAlgorithmByKeyLen(512),
718 usage_mask,
719 &handle,
720 &type));
721
722 // Fail on invalid kty.
723 dict.SetString("kty", "foo");
724 json_vec = MakeJsonVector(dict);
725 EXPECT_FALSE(ImportKeyJwk(
726 json_vec, extractable, algorithm, usage_mask, &handle, &type));
727 dict.SetString("kty", key_val);
eroman 2013/10/29 03:03:46 I actually preferred the duplication of these cons
padolph 2013/10/29 22:57:01 Done.
728
729 // Fail on missing kty.
730 dict.Remove("kty", NULL);
731 json_vec = MakeJsonVector(dict);
732 EXPECT_FALSE(ImportKeyJwk(
733 json_vec, extractable, algorithm, usage_mask, &handle, &type));
734 dict.SetString("kty", key_val);
735
736 // Fail on invalid alg.
737 dict.SetString("alg", "foo");
738 json_vec = MakeJsonVector(dict);
739 EXPECT_FALSE(ImportKeyJwk(
740 json_vec, extractable, algorithm, usage_mask, &handle, &type));
741 dict.SetString("alg", alg_val);
742
743 // Fail on invalid use.
744 dict.SetString("use", "foo");
745 json_vec = MakeJsonVector(dict);
746 EXPECT_FALSE(ImportKeyJwk(
747 json_vec, extractable, algorithm, usage_mask, &handle, &type));
748 dict.SetString("use", use_val);
749
750 // Fail on missing k when kty = "oct".
751 dict.Remove("k", NULL);
752 json_vec = MakeJsonVector(dict);
753 EXPECT_FALSE(ImportKeyJwk(
754 json_vec, extractable, algorithm, usage_mask, &handle, &type));
755 dict.SetString("k", k_val);
756
757 // Fail on bad b64 encoding for k.
758 dict.SetString("k", "Qk3f0DsytU8lfza2au #$% Htaw2xpop9GYyTuH0p5GghxTI=");
759 json_vec = MakeJsonVector(dict);
760 EXPECT_FALSE(ImportKeyJwk(
761 json_vec, extractable, algorithm, usage_mask, &handle, &type));
762 dict.SetString("k", k_val);
763
764 // Fail on empty k.
765 dict.SetString("k", "");
766 json_vec = MakeJsonVector(dict);
767 EXPECT_FALSE(ImportKeyJwk(
768 json_vec, extractable, algorithm, usage_mask, &handle, &type));
769 dict.SetString("k", k_val);
770
771 // TODO(padolph) RSA public key bad data:
772 // Missing n or e when kty = "RSA"
773 // Bad encoding for n or e
774 // Size check on n??
775 // Value check on e??
776 }
777
778 TEST_F(WebCryptoImplTest, ImportJwkInputInconsistent) {
779 // The Web Crypto spec says that if a JWK value is present, but is
780 // inconsistent with the input value, the operation must fail.
781
782 // Collision rules when JWK value is not present: Inputs should be unmodified.
783 scoped_ptr<WebKit::WebCryptoKeyHandle> handle;
784 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypeSecret;
785 bool extractable = true;
786 WebKit::WebCryptoAlgorithm algorithm =
787 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256);
788 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageVerify;
789 base::DictionaryValue dict;
790 dict.SetString("kty", "oct");
791 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
792 std::vector<uint8> json_vec = MakeJsonVector(dict);
793 EXPECT_TRUE(ImportKeyJwk(
794 json_vec, extractable, algorithm, usage_mask, &handle, &type));
795 EXPECT_TRUE(handle.get() != NULL);
796 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, type);
797 EXPECT_TRUE(extractable);
798 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdHmac, algorithm.id());
799 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdSha256,
800 algorithm.hmacParams()->hash().id());
801 EXPECT_EQ(WebKit::WebCryptoKeyUsageVerify, usage_mask);
802 handle.reset();
803
804 // Collision rules when JWK value exists: Fail if inconsistency is found.
805 // Happy path: all input values are consistent with the JWK values
806 dict.Clear();
807 dict.SetString("kty", "oct");
808 dict.SetString("alg", "HS256");
809 dict.SetString("use", "sig");
810 dict.SetBoolean("extractable", true);
811 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
812 json_vec = MakeJsonVector(dict);
813 EXPECT_TRUE(ImportKeyJwk(
814 json_vec, extractable, algorithm, usage_mask, &handle, &type));
815
816 // Fail: Input type (public) is inconsistent with JWK value (secret).
817 type = WebKit::WebCryptoKeyTypePublic;
818 EXPECT_FALSE(ImportKeyJwk(
819 json_vec, extractable, algorithm, usage_mask, &handle, &type));
820 type = WebKit::WebCryptoKeyTypeSecret;
821
822 // Fail: Input extractable (false) is inconsistent with JWK value (true).
823 extractable = false;
824 EXPECT_FALSE(ImportKeyJwk(
825 json_vec, extractable, algorithm, usage_mask, &handle, &type));
826 extractable = true;
827
828 // Fail: Input algorithm (HMAC SHA1) is inconsistent with JWK value
829 // (HMAC SHA256).
830 algorithm = CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha1);
831 EXPECT_FALSE(ImportKeyJwk(
832 json_vec, extractable, algorithm, usage_mask, &handle, &type));
833 algorithm = CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256);
834
835 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value
836 // (sign|verify)
837 usage_mask = WebKit::WebCryptoKeyUsageEncrypt;
838 EXPECT_FALSE(ImportKeyJwk(
839 json_vec, extractable, algorithm, usage_mask, &handle, &type));
840 usage_mask = WebKit::WebCryptoKeyUsageSign | WebKit::WebCryptoKeyUsageVerify;
841
842 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK
843 // value (sign|verify)
844 usage_mask = WebKit::WebCryptoKeyUsageEncrypt |
845 WebKit::WebCryptoKeyUsageSign | WebKit::WebCryptoKeyUsageVerify;
846 EXPECT_FALSE(ImportKeyJwk(
847 json_vec, extractable, algorithm, usage_mask, &handle, &type));
848 usage_mask = WebKit::WebCryptoKeyUsageSign | WebKit::WebCryptoKeyUsageVerify;
849 }
850
851 TEST_F(WebCryptoImplTest, ImportJwkHappy) {
852
853 // This test verifies the happy path of JWK import, including the application
854 // of the imported key material.
855
856 scoped_ptr<WebKit::WebCryptoKeyHandle> handle;
857 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypeSecret;
858 bool extractable = false;
859 WebKit::WebCryptoAlgorithm algorithm =
860 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256);
861 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageSign;
862
863 // Import a symmetric key JWK and HMAC-SHA256 sign()
864 // Uses the first SHA256 test vector from the HMAC sample set above.
865
866 base::DictionaryValue dict;
867 dict.SetString("kty", "oct");
868 dict.SetString("alg", "HS256");
869 dict.SetString("use", "sig");
870 dict.SetBoolean("extractable", false);
871 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
872 std::vector<uint8> json_vec = MakeJsonVector(dict);
873
874 ASSERT_TRUE(ImportKeyJwk(
875 json_vec, extractable, algorithm, usage_mask, &handle, &type));
876
877 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::create(
878 handle.release(), type, extractable, algorithm, usage_mask);
879
880 const std::vector<uint8> message_raw = HexStringToBytes(
881 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a"
882 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92"
883 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f"
884 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e");
885
886 WebKit::WebArrayBuffer output;
887
888 ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output));
889
890 const std::string mac_raw =
891 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b";
892
893 ExpectArrayBufferMatchesHex(mac_raw, output);
894
895 // TODO(padolph)
896 // Import an RSA public key JWK and use it
897 }
898
659 } // namespace content 899 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698