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

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

Powered by Google App Engine
This is Rietveld 408576698