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

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 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 std::vector<uint8> iv(16);
655 WebKit::WebCryptoAlgorithm algorithm = CreateAesCbcAlgorithm(iv);
656 bool extractable = false;
657 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageSign;
658
659 // Empty JSON
660 std::vector<uint8> json_vec = MakeJsonVector("");
661 EXPECT_FALSE(ImportKeyJwk(
662 json_vec, extractable, algorithm, usage_mask, &handle, &type));
663
664 // Invalid JSON
eroman 2013/10/28 23:02:00 good test cases, thanks!
665 json_vec = MakeJsonVector(
666 "{"
667 "\"kty\" : \"oct\","
668 "\"alg\" : \"A128CBC\","
669 "\"use\" : "
670 );
671 EXPECT_FALSE(ImportKeyJwk(
672 json_vec, extractable, algorithm, usage_mask, &handle, &type));
673
674 // Note, each subtest below resets the dictionary so there is less chance of
675 // failure if they happen to be reordered.
676
677 // Invalid kty
678 base::DictionaryValue dict;
679 dict.SetString("kty", "foo");
680 dict.SetString("alg", "A128CBC");
681 dict.SetString("use", "sig");
682 dict.SetBoolean("extractable", extractable);
683 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
684 json_vec = MakeJsonVector(dict);
685 EXPECT_FALSE(ImportKeyJwk(
686 json_vec, extractable, algorithm, usage_mask, &handle, &type));
687 dict.SetString("kty", "oct");
688
689 // Missing kty
690 dict.Remove("kty", NULL);
691 json_vec = MakeJsonVector(dict);
692 EXPECT_FALSE(ImportKeyJwk(
693 json_vec, extractable, algorithm, usage_mask, &handle, &type));
694 dict.SetString("kty", "oct");
695
696 // Invalid alg
697 dict.SetString("alg", "foo");
698 json_vec = MakeJsonVector(dict);
699 EXPECT_FALSE(ImportKeyJwk(
700 json_vec, extractable, algorithm, usage_mask, &handle, &type));
701 dict.SetString("alg", "A128CBC");
702
703 // Invalid use
704 dict.SetString("use", "foo");
705 json_vec = MakeJsonVector(dict);
706 EXPECT_FALSE(ImportKeyJwk(
707 json_vec, extractable, algorithm, usage_mask, &handle, &type));
708 dict.SetString("use", "sig");
709
710 // Missing k when kty = "oct"
711 dict.Remove("k", NULL);
712 json_vec = MakeJsonVector(dict);
713 EXPECT_FALSE(ImportKeyJwk(
714 json_vec, extractable, algorithm, usage_mask, &handle, &type));
715 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
716
717 // Bad b64 encoding for k
718 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3r #$% jhdY8vOkbIvh4lxTuMao9Y_--hdg");
719 json_vec = MakeJsonVector(dict);
720 EXPECT_FALSE(ImportKeyJwk(
721 json_vec, extractable, algorithm, usage_mask, &handle, &type));
722 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
723
724 // empty k
725 dict.SetString("k", "");
726 json_vec = MakeJsonVector(dict);
727 EXPECT_FALSE(ImportKeyJwk(
728 json_vec, extractable, algorithm, usage_mask, &handle, &type));
729 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
730
731 // TODO(padolph) RSA public key bad data:
eroman 2013/10/28 23:02:00 please add colon after paren.
padolph 2013/10/29 02:25:40 Done.
732 // Missing n or e when kty = "RSA"
733 // Bad encoding for n or e
734 // Size check on n??
735 // Value check on e??
eroman 2013/10/28 23:02:00 We will need a lot of tests to cover all the full
padolph 2013/10/29 02:25:40 Agreed. I wonder if the case-sensitive tests fit b
736 }
737
738 TEST_F(WebCryptoImplTest, ImportJwkInputInconsistent) {
739 // The Web Crypto spec says that if a JWK value is present, but is
740 // inconsistent with the input value, the operation must fail.
741
742 // Collision rules when JWK value is not present: Inputs should be unmodified.
743 scoped_ptr<WebKit::WebCryptoKeyHandle> handle;
744 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypeSecret;
745 bool extractable = true;
746 WebKit::WebCryptoAlgorithm algorithm =
747 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256);
748 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageVerify;
749 base::DictionaryValue dict;
750 dict.SetString("kty", "oct");
751 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
752 std::vector<uint8> json_vec = MakeJsonVector(dict);
753 EXPECT_TRUE(ImportKeyJwk(
754 json_vec, extractable, algorithm, usage_mask, &handle, &type));
755 EXPECT_TRUE(handle.get() != NULL);
756 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, type);
757 EXPECT_TRUE(extractable);
758 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdHmac, algorithm.id());
759 EXPECT_EQ(WebKit::WebCryptoAlgorithmIdSha256,
760 algorithm.hmacParams()->hash().id());
761 EXPECT_EQ(WebKit::WebCryptoKeyUsageVerify, usage_mask);
762 handle.reset();
763
764 // Collision rules when JWK value exists: Fail if inconsistency is found.
765 // Happy path: all input values are consistent with the JWK values
766 dict.Clear();
767 dict.SetString("kty", "oct");
768 dict.SetString("alg", "HS256");
769 dict.SetString("use", "sig");
770 dict.SetBoolean("extractable", true);
771 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
772 json_vec = MakeJsonVector(dict);
773 EXPECT_TRUE(ImportKeyJwk(
774 json_vec, extractable, algorithm, usage_mask, &handle, &type));
775
776 // Fail: Input type (public) is inconsistent with JWK value (secret).
777 type = WebKit::WebCryptoKeyTypePublic;
778 EXPECT_FALSE(ImportKeyJwk(
779 json_vec, extractable, algorithm, usage_mask, &handle, &type));
780 type = WebKit::WebCryptoKeyTypeSecret;
781
782 // Fail: Input extractable (false) is inconsistent with JWK value (true).
783 extractable = false;
784 EXPECT_FALSE(ImportKeyJwk(
785 json_vec, extractable, algorithm, usage_mask, &handle, &type));
786 extractable = true;
787
788 // Fail: Input algorithm (HMAC SHA1) is inconsistent with JWK value
789 // (HMAC SHA256).
790 algorithm = CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha1);
791 EXPECT_FALSE(ImportKeyJwk(
792 json_vec, extractable, algorithm, usage_mask, &handle, &type));
793 algorithm = CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256);
794
795 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value
796 // (sign|verify)
797 usage_mask = WebKit::WebCryptoKeyUsageEncrypt;
798 EXPECT_FALSE(ImportKeyJwk(
799 json_vec, extractable, algorithm, usage_mask, &handle, &type));
800 usage_mask = WebKit::WebCryptoKeyUsageSign | WebKit::WebCryptoKeyUsageVerify;
801
802 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK
803 // value (sign|verify)
804 usage_mask = WebKit::WebCryptoKeyUsageEncrypt |
eroman 2013/10/28 23:02:00 You must have read my mind! After reading the test
padolph 2013/10/29 02:25:40 Yes, a superset is strictly not a subset. :)
805 WebKit::WebCryptoKeyUsageSign | WebKit::WebCryptoKeyUsageVerify;
806 EXPECT_FALSE(ImportKeyJwk(
807 json_vec, extractable, algorithm, usage_mask, &handle, &type));
808 usage_mask = WebKit::WebCryptoKeyUsageSign | WebKit::WebCryptoKeyUsageVerify;
809 }
810
811 TEST_F(WebCryptoImplTest, ImportJwkHappy) {
812
813 // This test verifies the happy path of JWK import, including the application
814 // of the imported key material.
815
816 scoped_ptr<WebKit::WebCryptoKeyHandle> handle;
817 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypeSecret;
818 bool extractable = false;
819 WebKit::WebCryptoAlgorithm algorithm =
820 CreateHmacAlgorithmByHashId(WebKit::WebCryptoAlgorithmIdSha256);
821 WebKit::WebCryptoKeyUsageMask usage_mask = WebKit::WebCryptoKeyUsageSign;
822
823 // Import a symmetric key JWK and HMAC-SHA256 sign()
824 // Uses the first SHA256 test vector from the HMAC sample set above.
825
826 base::DictionaryValue dict;
827 dict.SetString("kty", "oct");
828 dict.SetString("alg", "HS256");
829 dict.SetString("use", "sig");
830 dict.SetBoolean("extractable", false);
831 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg");
832 std::vector<uint8> json_vec = MakeJsonVector(dict);
833
834 ASSERT_TRUE(ImportKeyJwk(
835 json_vec, extractable, algorithm, usage_mask, &handle, &type));
836
837 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::create(
838 handle.release(), type, extractable, algorithm, usage_mask);
839
840 const std::vector<uint8> message_raw = HexStringToBytes(
841 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a"
842 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92"
843 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f"
844 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e");
845
846 WebKit::WebArrayBuffer output;
847
848 ASSERT_TRUE(SignInternal(algorithm, key, message_raw, &output));
849
850 const std::string mac_raw =
851 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b";
852
853 ExpectArrayBufferMatchesHex(mac_raw, output);
854
855 // TODO(padolph)
856 // Import an RSA public key JWK and use it
857 }
858
659 } // namespace content 859 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698