OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/child/webcrypto/shared_crypto.h" | 5 #include "content/child/webcrypto/shared_crypto.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
14 #include "base/json/json_writer.h" | 14 #include "base/json/json_writer.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
17 #include "base/path_service.h" | 17 #include "base/path_service.h" |
18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
19 #include "base/strings/string_util.h" | 19 #include "base/values.h" |
20 #include "content/child/webcrypto/crypto_data.h" | 20 #include "content/child/webcrypto/crypto_data.h" |
21 #include "content/child/webcrypto/webcrypto_util.h" | 21 #include "content/child/webcrypto/webcrypto_util.h" |
22 #include "content/public/common/content_paths.h" | 22 #include "content/public/common/content_paths.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
24 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" | 24 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" |
25 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | 25 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
26 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 26 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
27 #include "third_party/WebKit/public/platform/WebCryptoKey.h" | 27 #include "third_party/WebKit/public/platform/WebCryptoKey.h" |
28 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 28 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
29 #include "third_party/re2/re2/re2.h" | 29 #include "third_party/re2/re2/re2.h" |
(...skipping 14 matching lines...) Expand all Loading... |
44 ASSERT_EQ(expected.ToString(), (code).ToString()) | 44 ASSERT_EQ(expected.ToString(), (code).ToString()) |
45 #define EXPECT_STATUS_SUCCESS(code) EXPECT_STATUS(Status::Success(), code) | 45 #define EXPECT_STATUS_SUCCESS(code) EXPECT_STATUS(Status::Success(), code) |
46 #define ASSERT_STATUS_SUCCESS(code) ASSERT_STATUS(Status::Success(), code) | 46 #define ASSERT_STATUS_SUCCESS(code) ASSERT_STATUS(Status::Success(), code) |
47 | 47 |
48 namespace content { | 48 namespace content { |
49 | 49 |
50 namespace webcrypto { | 50 namespace webcrypto { |
51 | 51 |
52 namespace { | 52 namespace { |
53 | 53 |
54 // TODO(eroman): For Linux builds using system NSS, AES-GCM support is a | |
55 // runtime dependency. Test it by trying to import a key. | |
56 // TODO(padolph): Consider caching the result of the import key test. | |
57 bool SupportsAesGcm() { | |
58 std::vector<uint8> key_raw(16, 0); | |
59 | |
60 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | |
61 Status status = ImportKey(blink::WebCryptoKeyFormatRaw, | |
62 CryptoData(key_raw), | |
63 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm), | |
64 true, | |
65 blink::WebCryptoKeyUsageEncrypt, | |
66 &key); | |
67 | |
68 if (status.IsError()) | |
69 EXPECT_STATUS(Status::ErrorUnsupported(), status); | |
70 return status.IsSuccess(); | |
71 } | |
72 | |
73 blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm( | 54 blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm( |
74 blink::WebCryptoAlgorithmId algorithm_id, | 55 blink::WebCryptoAlgorithmId algorithm_id, |
75 unsigned int modulus_length, | 56 unsigned int modulus_length, |
76 const std::vector<uint8>& public_exponent) { | 57 const std::vector<uint8>& public_exponent) { |
77 DCHECK_EQ(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, algorithm_id); | 58 DCHECK_EQ(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, algorithm_id); |
78 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 59 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
79 algorithm_id, | 60 algorithm_id, |
80 new blink::WebCryptoRsaKeyGenParams( | 61 new blink::WebCryptoRsaKeyGenParams( |
81 modulus_length, | 62 modulus_length, |
82 webcrypto::Uint8VectorStart(public_exponent), | 63 webcrypto::Uint8VectorStart(public_exponent), |
(...skipping 22 matching lines...) Expand all Loading... |
105 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 86 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
106 blink::WebCryptoAlgorithmIdAesCbc, | 87 blink::WebCryptoAlgorithmIdAesCbc, |
107 new blink::WebCryptoAesCbcParams(Uint8VectorStart(iv), iv.size())); | 88 new blink::WebCryptoAesCbcParams(Uint8VectorStart(iv), iv.size())); |
108 } | 89 } |
109 | 90 |
110 // Creates and AES-GCM algorithm. | 91 // Creates and AES-GCM algorithm. |
111 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm( | 92 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm( |
112 const std::vector<uint8>& iv, | 93 const std::vector<uint8>& iv, |
113 const std::vector<uint8>& additional_data, | 94 const std::vector<uint8>& additional_data, |
114 unsigned int tag_length_bits) { | 95 unsigned int tag_length_bits) { |
115 EXPECT_TRUE(SupportsAesGcm()); | |
116 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 96 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
117 blink::WebCryptoAlgorithmIdAesGcm, | 97 blink::WebCryptoAlgorithmIdAesGcm, |
118 new blink::WebCryptoAesGcmParams(Uint8VectorStart(iv), | 98 new blink::WebCryptoAesGcmParams(Uint8VectorStart(iv), |
119 iv.size(), | 99 iv.size(), |
120 true, | 100 true, |
121 Uint8VectorStart(additional_data), | 101 Uint8VectorStart(additional_data), |
122 additional_data.size(), | 102 additional_data.size(), |
123 true, | 103 true, |
124 tag_length_bits)); | 104 tag_length_bits)); |
125 } | 105 } |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 return blink::WebCryptoAlgorithm::createNull(); | 272 return blink::WebCryptoAlgorithm::createNull(); |
293 } | 273 } |
294 | 274 |
295 // Helper for ImportJwkFailures and ImportJwkOctFailures. Restores the JWK JSON | 275 // Helper for ImportJwkFailures and ImportJwkOctFailures. Restores the JWK JSON |
296 // dictionary to a good state | 276 // dictionary to a good state |
297 void RestoreJwkOctDictionary(base::DictionaryValue* dict) { | 277 void RestoreJwkOctDictionary(base::DictionaryValue* dict) { |
298 dict->Clear(); | 278 dict->Clear(); |
299 dict->SetString("kty", "oct"); | 279 dict->SetString("kty", "oct"); |
300 dict->SetString("alg", "A128CBC"); | 280 dict->SetString("alg", "A128CBC"); |
301 dict->SetString("use", "enc"); | 281 dict->SetString("use", "enc"); |
302 dict->SetBoolean("ext", false); | 282 dict->SetBoolean("extractable", false); |
303 dict->SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); | 283 dict->SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); |
304 } | 284 } |
305 | 285 |
306 // Helper for ImportJwkRsaFailures. Restores the JWK JSON | 286 // Helper for ImportJwkRsaFailures. Restores the JWK JSON |
307 // dictionary to a good state | 287 // dictionary to a good state |
308 void RestoreJwkRsaDictionary(base::DictionaryValue* dict) { | 288 void RestoreJwkRsaDictionary(base::DictionaryValue* dict) { |
309 dict->Clear(); | 289 dict->Clear(); |
310 dict->SetString("kty", "RSA"); | 290 dict->SetString("kty", "RSA"); |
311 dict->SetString("alg", "RSA1_5"); | 291 dict->SetString("alg", "RSA1_5"); |
312 dict->SetString("use", "enc"); | 292 dict->SetString("use", "enc"); |
313 dict->SetBoolean("ext", false); | 293 dict->SetBoolean("extractable", false); |
314 dict->SetString( | 294 dict->SetString( |
315 "n", | 295 "n", |
316 "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk" | 296 "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk" |
317 "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm" | 297 "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm" |
318 "e7PUJHYW1PW6ENTP0ibeiNOfFvs"); | 298 "e7PUJHYW1PW6ENTP0ibeiNOfFvs"); |
319 dict->SetString("e", "AQAB"); | 299 dict->SetString("e", "AQAB"); |
320 } | 300 } |
321 | 301 |
322 blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm( | 302 blink::WebCryptoAlgorithm CreateRsaHashedImportAlgorithm( |
323 blink::WebCryptoAlgorithmId algorithm_id, | 303 blink::WebCryptoAlgorithmId algorithm_id, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 } | 336 } |
357 | 337 |
358 blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm( | 338 blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm( |
359 unsigned short key_length_bits) { | 339 unsigned short key_length_bits) { |
360 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesCbc, | 340 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesCbc, |
361 key_length_bits); | 341 key_length_bits); |
362 } | 342 } |
363 | 343 |
364 blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm( | 344 blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm( |
365 unsigned short key_length_bits) { | 345 unsigned short key_length_bits) { |
366 EXPECT_TRUE(SupportsAesGcm()); | |
367 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesGcm, | 346 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesGcm, |
368 key_length_bits); | 347 key_length_bits); |
369 } | 348 } |
370 | 349 |
371 blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm( | 350 blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm( |
372 unsigned short key_length_bits) { | 351 unsigned short key_length_bits) { |
373 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesKw, | 352 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesKw, |
374 key_length_bits); | 353 key_length_bits); |
375 } | 354 } |
376 | 355 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 usage_mask, | 443 usage_mask, |
465 private_key)); | 444 private_key)); |
466 EXPECT_FALSE(private_key->isNull()); | 445 EXPECT_FALSE(private_key->isNull()); |
467 EXPECT_TRUE(private_key->handle()); | 446 EXPECT_TRUE(private_key->handle()); |
468 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key->type()); | 447 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key->type()); |
469 EXPECT_EQ(algorithm.id(), private_key->algorithm().id()); | 448 EXPECT_EQ(algorithm.id(), private_key->algorithm().id()); |
470 EXPECT_EQ(extractable, extractable); | 449 EXPECT_EQ(extractable, extractable); |
471 EXPECT_EQ(usage_mask, private_key->usages()); | 450 EXPECT_EQ(usage_mask, private_key->usages()); |
472 } | 451 } |
473 | 452 |
| 453 // TODO(eroman): For Linux builds using system NSS, AES-GCM support is a |
| 454 // runtime dependency. Test it by trying to import a key. |
| 455 bool SupportsAesGcm() { |
| 456 std::vector<uint8> key_raw(16, 0); |
| 457 |
| 458 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 459 Status status = ImportKey(blink::WebCryptoKeyFormatRaw, |
| 460 CryptoData(key_raw), |
| 461 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm), |
| 462 true, |
| 463 blink::WebCryptoKeyUsageEncrypt, |
| 464 &key); |
| 465 |
| 466 if (status.IsError()) |
| 467 EXPECT_EQ(Status::ErrorUnsupported().ToString(), status.ToString()); |
| 468 return status.IsSuccess(); |
| 469 } |
| 470 |
474 Status AesGcmEncrypt(const blink::WebCryptoKey& key, | 471 Status AesGcmEncrypt(const blink::WebCryptoKey& key, |
475 const std::vector<uint8>& iv, | 472 const std::vector<uint8>& iv, |
476 const std::vector<uint8>& additional_data, | 473 const std::vector<uint8>& additional_data, |
477 unsigned int tag_length_bits, | 474 unsigned int tag_length_bits, |
478 const std::vector<uint8>& plain_text, | 475 const std::vector<uint8>& plain_text, |
479 std::vector<uint8>* cipher_text, | 476 std::vector<uint8>* cipher_text, |
480 std::vector<uint8>* authentication_tag) { | 477 std::vector<uint8>* authentication_tag) { |
481 EXPECT_TRUE(SupportsAesGcm()); | |
482 blink::WebCryptoAlgorithm algorithm = | 478 blink::WebCryptoAlgorithm algorithm = |
483 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); | 479 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); |
484 | 480 |
485 blink::WebArrayBuffer output; | 481 blink::WebArrayBuffer output; |
486 Status status = Encrypt(algorithm, key, CryptoData(plain_text), &output); | 482 Status status = Encrypt(algorithm, key, CryptoData(plain_text), &output); |
487 if (status.IsError()) | 483 if (status.IsError()) |
488 return status; | 484 return status; |
489 | 485 |
490 if (output.byteLength() * 8 < tag_length_bits) { | 486 if (output.byteLength() * 8 < tag_length_bits) { |
491 EXPECT_TRUE(false); | 487 EXPECT_TRUE(false); |
(...skipping 11 matching lines...) Expand all Loading... |
503 return Status::Success(); | 499 return Status::Success(); |
504 } | 500 } |
505 | 501 |
506 Status AesGcmDecrypt(const blink::WebCryptoKey& key, | 502 Status AesGcmDecrypt(const blink::WebCryptoKey& key, |
507 const std::vector<uint8>& iv, | 503 const std::vector<uint8>& iv, |
508 const std::vector<uint8>& additional_data, | 504 const std::vector<uint8>& additional_data, |
509 unsigned int tag_length_bits, | 505 unsigned int tag_length_bits, |
510 const std::vector<uint8>& cipher_text, | 506 const std::vector<uint8>& cipher_text, |
511 const std::vector<uint8>& authentication_tag, | 507 const std::vector<uint8>& authentication_tag, |
512 blink::WebArrayBuffer* plain_text) { | 508 blink::WebArrayBuffer* plain_text) { |
513 EXPECT_TRUE(SupportsAesGcm()); | |
514 blink::WebCryptoAlgorithm algorithm = | 509 blink::WebCryptoAlgorithm algorithm = |
515 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); | 510 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); |
516 | 511 |
517 // Join cipher text and authentication tag. | 512 // Join cipher text and authentication tag. |
518 std::vector<uint8> cipher_text_with_tag; | 513 std::vector<uint8> cipher_text_with_tag; |
519 cipher_text_with_tag.reserve(cipher_text.size() + authentication_tag.size()); | 514 cipher_text_with_tag.reserve(cipher_text.size() + authentication_tag.size()); |
520 cipher_text_with_tag.insert( | 515 cipher_text_with_tag.insert( |
521 cipher_text_with_tag.end(), cipher_text.begin(), cipher_text.end()); | 516 cipher_text_with_tag.end(), cipher_text.begin(), cipher_text.end()); |
522 cipher_text_with_tag.insert(cipher_text_with_tag.end(), | 517 cipher_text_with_tag.insert(cipher_text_with_tag.end(), |
523 authentication_tag.begin(), | 518 authentication_tag.begin(), |
524 authentication_tag.end()); | 519 authentication_tag.end()); |
525 | 520 |
526 return Decrypt(algorithm, key, CryptoData(cipher_text_with_tag), plain_text); | 521 return Decrypt(algorithm, key, CryptoData(cipher_text_with_tag), plain_text); |
527 } | 522 } |
528 | 523 |
529 Status ImportKeyJwkFromDict(const base::DictionaryValue& dict, | 524 Status ImportKeyJwkFromDict(const base::DictionaryValue& dict, |
530 const blink::WebCryptoAlgorithm& algorithm, | 525 const blink::WebCryptoAlgorithm& algorithm, |
531 bool extractable, | 526 bool extractable, |
532 blink::WebCryptoKeyUsageMask usage_mask, | 527 blink::WebCryptoKeyUsageMask usage_mask, |
533 blink::WebCryptoKey* key) { | 528 blink::WebCryptoKey* key) { |
534 return ImportKeyJwk(CryptoData(MakeJsonVector(dict)), | 529 return ImportKeyJwk(CryptoData(MakeJsonVector(dict)), |
535 algorithm, | 530 algorithm, |
536 extractable, | 531 extractable, |
537 usage_mask, | 532 usage_mask, |
538 key); | 533 key); |
539 } | 534 } |
540 | 535 |
541 // Parses an ArrayBuffer of JSON into a dictionary. | |
542 scoped_ptr<base::DictionaryValue> GetJwkDictionary( | |
543 const blink::WebArrayBuffer& json) { | |
544 base::StringPiece json_string(reinterpret_cast<const char*>(json.data()), | |
545 json.byteLength()); | |
546 base::Value* value = base::JSONReader::Read(json_string); | |
547 EXPECT_TRUE(value); | |
548 base::DictionaryValue* dict_value = NULL; | |
549 value->GetAsDictionary(&dict_value); | |
550 return scoped_ptr<base::DictionaryValue>(dict_value); | |
551 } | |
552 | |
553 // Verifies that the JSON in the input ArrayBuffer contains the provided | |
554 // expected values. Exact matches are required on the fields examined. | |
555 ::testing::AssertionResult VerifySymmetricJwk( | |
556 const blink::WebArrayBuffer& json, | |
557 const std::string& alg_expected, | |
558 const std::string& k_expected_hex, | |
559 blink::WebCryptoKeyUsageMask use_mask_expected) { | |
560 | |
561 scoped_ptr<base::DictionaryValue> dict = GetJwkDictionary(json); | |
562 if (!dict.get() || dict->empty()) | |
563 return ::testing::AssertionFailure() << "JSON parsing failed"; | |
564 | |
565 // ---- kty | |
566 std::string value_string; | |
567 if (!dict->GetString("kty", &value_string)) | |
568 return ::testing::AssertionFailure() << "Missing 'kty'"; | |
569 if (value_string != "oct") | |
570 return ::testing::AssertionFailure() | |
571 << "Expected 'kty' to be 'oct' but found " << value_string; | |
572 | |
573 // ---- alg | |
574 if (!dict->GetString("alg", &value_string)) | |
575 return ::testing::AssertionFailure() << "Missing 'alg'"; | |
576 if (value_string != alg_expected) | |
577 return ::testing::AssertionFailure() << "Expected 'alg' to be " | |
578 << alg_expected << " but found " | |
579 << value_string; | |
580 | |
581 // ---- k | |
582 if (!dict->GetString("k", &value_string)) | |
583 return ::testing::AssertionFailure() << "Missing 'k'"; | |
584 std::string k_value; | |
585 if (!webcrypto::Base64DecodeUrlSafe(value_string, &k_value)) | |
586 return ::testing::AssertionFailure() << "Base64DecodeUrlSafe(k) failed"; | |
587 if (!LowerCaseEqualsASCII(base::HexEncode(k_value.data(), k_value.size()), | |
588 k_expected_hex.c_str())) { | |
589 return ::testing::AssertionFailure() << "Expected 'k' to be " | |
590 << k_expected_hex | |
591 << " but found something different"; | |
592 } | |
593 // ---- ext | |
594 // always expect ext == true in this case | |
595 bool ext_value; | |
596 if (!dict->GetBoolean("ext", &ext_value)) | |
597 return ::testing::AssertionFailure() << "Missing 'ext'"; | |
598 if (!ext_value) | |
599 return ::testing::AssertionFailure() | |
600 << "Expected 'ext' to be true but found false"; | |
601 | |
602 // ---- key_ops | |
603 base::ListValue* key_ops; | |
604 if (!dict->GetList("key_ops", &key_ops)) | |
605 return ::testing::AssertionFailure() << "Missing 'key_ops'"; | |
606 blink::WebCryptoKeyUsageMask key_ops_mask = 0; | |
607 Status status = GetWebCryptoUsagesFromJwkKeyOps(key_ops, &key_ops_mask); | |
608 if (status.IsError()) | |
609 return ::testing::AssertionFailure() << "Failure extracting 'key_ops'"; | |
610 if (key_ops_mask != use_mask_expected) | |
611 return ::testing::AssertionFailure() | |
612 << "Expected 'key_ops' mask to be " << use_mask_expected | |
613 << " but found " << key_ops_mask << " (" << value_string << ")"; | |
614 | |
615 return ::testing::AssertionSuccess(); | |
616 } | |
617 | |
618 } // namespace | 536 } // namespace |
619 | 537 |
620 TEST_F(SharedCryptoTest, CheckAesGcm) { | |
621 if (!SupportsAesGcm()) { | |
622 LOG(WARNING) << "AES GCM not supported on this platform, so some tests " | |
623 "will be skipped. Consider upgrading local NSS libraries"; | |
624 return; | |
625 } | |
626 } | |
627 | |
628 TEST_F(SharedCryptoTest, StatusToString) { | 538 TEST_F(SharedCryptoTest, StatusToString) { |
629 EXPECT_EQ("Success", Status::Success().ToString()); | 539 EXPECT_EQ("Success", Status::Success().ToString()); |
630 EXPECT_EQ("", Status::Error().ToString()); | 540 EXPECT_EQ("", Status::Error().ToString()); |
631 EXPECT_EQ("The requested operation is unsupported", | 541 EXPECT_EQ("The requested operation is unsupported", |
632 Status::ErrorUnsupported().ToString()); | 542 Status::ErrorUnsupported().ToString()); |
633 EXPECT_EQ("The required JWK property \"kty\" was missing", | 543 EXPECT_EQ("The required JWK property \"kty\" was missing", |
634 Status::ErrorJwkPropertyMissing("kty").ToString()); | 544 Status::ErrorJwkPropertyMissing("kty").ToString()); |
635 EXPECT_EQ("The JWK property \"kty\" must be a string", | 545 EXPECT_EQ("The JWK property \"kty\" must be a string", |
636 Status::ErrorJwkPropertyWrongType("kty", "string").ToString()); | 546 Status::ErrorJwkPropertyWrongType("kty", "string").ToString()); |
637 EXPECT_EQ("The JWK property \"n\" could not be base64 decoded", | 547 EXPECT_EQ("The JWK property \"n\" could not be base64 decoded", |
(...skipping 17 matching lines...) Expand all Loading... |
655 blink::WebArrayBuffer output; | 565 blink::WebArrayBuffer output; |
656 ASSERT_STATUS_SUCCESS( | 566 ASSERT_STATUS_SUCCESS( |
657 Digest(test_algorithm, CryptoData(test_input), &output)); | 567 Digest(test_algorithm, CryptoData(test_input), &output)); |
658 EXPECT_TRUE(ArrayBufferMatches(test_output, output)); | 568 EXPECT_TRUE(ArrayBufferMatches(test_output, output)); |
659 } | 569 } |
660 } | 570 } |
661 | 571 |
662 TEST_F(SharedCryptoTest, HMACSampleSets) { | 572 TEST_F(SharedCryptoTest, HMACSampleSets) { |
663 scoped_ptr<base::ListValue> tests; | 573 scoped_ptr<base::ListValue> tests; |
664 ASSERT_TRUE(ReadJsonTestFileToList("hmac.json", &tests)); | 574 ASSERT_TRUE(ReadJsonTestFileToList("hmac.json", &tests)); |
665 // TODO(padolph): Missing known answer tests for HMAC SHA384, and SHA512. | 575 |
666 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { | 576 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { |
667 SCOPED_TRACE(test_index); | 577 SCOPED_TRACE(test_index); |
668 base::DictionaryValue* test; | 578 base::DictionaryValue* test; |
669 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); | 579 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); |
670 | 580 |
671 blink::WebCryptoAlgorithm test_hash = GetDigestAlgorithm(test, "hash"); | 581 blink::WebCryptoAlgorithm test_hash = GetDigestAlgorithm(test, "hash"); |
672 const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); | 582 const std::vector<uint8> test_key = GetBytesFromHexString(test, "key"); |
673 const std::vector<uint8> test_message = | 583 const std::vector<uint8> test_message = |
674 GetBytesFromHexString(test, "message"); | 584 GetBytesFromHexString(test, "message"); |
675 const std::vector<uint8> test_mac = GetBytesFromHexString(test, "mac"); | 585 const std::vector<uint8> test_mac = GetBytesFromHexString(test, "mac"); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 } | 807 } |
898 } | 808 } |
899 | 809 |
900 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAes)) { | 810 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAes)) { |
901 // Check key generation for each of AES-CBC, AES-GCM, and AES-KW, and for each | 811 // Check key generation for each of AES-CBC, AES-GCM, and AES-KW, and for each |
902 // allowed key length. | 812 // allowed key length. |
903 std::vector<blink::WebCryptoAlgorithm> algorithm; | 813 std::vector<blink::WebCryptoAlgorithm> algorithm; |
904 const unsigned short kKeyLength[] = {128, 192, 256}; | 814 const unsigned short kKeyLength[] = {128, 192, 256}; |
905 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLength); ++i) { | 815 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLength); ++i) { |
906 algorithm.push_back(CreateAesCbcKeyGenAlgorithm(kKeyLength[i])); | 816 algorithm.push_back(CreateAesCbcKeyGenAlgorithm(kKeyLength[i])); |
| 817 algorithm.push_back(CreateAesGcmKeyGenAlgorithm(kKeyLength[i])); |
907 algorithm.push_back(CreateAesKwKeyGenAlgorithm(kKeyLength[i])); | 818 algorithm.push_back(CreateAesKwKeyGenAlgorithm(kKeyLength[i])); |
908 if (SupportsAesGcm()) | |
909 algorithm.push_back(CreateAesGcmKeyGenAlgorithm(kKeyLength[i])); | |
910 } | 819 } |
911 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 820 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
912 std::vector<blink::WebArrayBuffer> keys; | 821 std::vector<blink::WebArrayBuffer> keys; |
913 blink::WebArrayBuffer key_bytes; | 822 blink::WebArrayBuffer key_bytes; |
914 for (size_t i = 0; i < algorithm.size(); ++i) { | 823 for (size_t i = 0; i < algorithm.size(); ++i) { |
915 SCOPED_TRACE(i); | 824 SCOPED_TRACE(i); |
916 // Generate a small sample of keys. | 825 // Generate a small sample of keys. |
917 keys.clear(); | 826 keys.clear(); |
918 for (int j = 0; j < 16; ++j) { | 827 for (int j = 0; j < 16; ++j) { |
919 ASSERT_STATUS_SUCCESS(GenerateSecretKey(algorithm[i], true, 0, &key)); | 828 ASSERT_STATUS_SUCCESS(GenerateSecretKey(algorithm[i], true, 0, &key)); |
(...skipping 14 matching lines...) Expand all Loading... |
934 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAesBadLength)) { | 843 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAesBadLength)) { |
935 const unsigned short kKeyLen[] = {0, 127, 257}; | 844 const unsigned short kKeyLen[] = {0, 127, 257}; |
936 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 845 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
937 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLen); ++i) { | 846 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLen); ++i) { |
938 SCOPED_TRACE(i); | 847 SCOPED_TRACE(i); |
939 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), | 848 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), |
940 GenerateSecretKey( | 849 GenerateSecretKey( |
941 CreateAesCbcKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); | 850 CreateAesCbcKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); |
942 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), | 851 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), |
943 GenerateSecretKey( | 852 GenerateSecretKey( |
| 853 CreateAesGcmKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); |
| 854 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), |
| 855 GenerateSecretKey( |
944 CreateAesKwKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); | 856 CreateAesKwKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); |
945 if (SupportsAesGcm()) { | |
946 EXPECT_STATUS( | |
947 Status::ErrorGenerateKeyLength(), | |
948 GenerateSecretKey( | |
949 CreateAesGcmKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); | |
950 } | |
951 } | 857 } |
952 } | 858 } |
953 | 859 |
954 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyHmac)) { | 860 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyHmac)) { |
955 // Generate a small sample of HMAC keys. | 861 // Generate a small sample of HMAC keys. |
956 std::vector<blink::WebArrayBuffer> keys; | 862 std::vector<blink::WebArrayBuffer> keys; |
957 for (int i = 0; i < 16; ++i) { | 863 for (int i = 0; i < 16; ++i) { |
958 blink::WebArrayBuffer key_bytes; | 864 blink::WebArrayBuffer key_bytes; |
959 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 865 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
960 blink::WebCryptoAlgorithm algorithm = | 866 blink::WebCryptoAlgorithm algorithm = |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1005 // This fails because the algorithm is null. | 911 // This fails because the algorithm is null. |
1006 EXPECT_STATUS(Status::ErrorMissingAlgorithmImportRawKey(), | 912 EXPECT_STATUS(Status::ErrorMissingAlgorithmImportRawKey(), |
1007 ImportKey(blink::WebCryptoKeyFormatRaw, | 913 ImportKey(blink::WebCryptoKeyFormatRaw, |
1008 CryptoData(HexStringToBytes("00000000000000000000")), | 914 CryptoData(HexStringToBytes("00000000000000000000")), |
1009 blink::WebCryptoAlgorithm::createNull(), | 915 blink::WebCryptoAlgorithm::createNull(), |
1010 true, | 916 true, |
1011 blink::WebCryptoKeyUsageEncrypt, | 917 blink::WebCryptoKeyUsageEncrypt, |
1012 &key)); | 918 &key)); |
1013 } | 919 } |
1014 | 920 |
1015 TEST_F(SharedCryptoTest, ImportJwkKeyUsage) { | 921 TEST_F(SharedCryptoTest, ImportJwkFailures) { |
1016 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | |
1017 base::DictionaryValue dict; | |
1018 dict.SetString("kty", "oct"); | |
1019 dict.SetBoolean("ext", false); | |
1020 dict.SetString("k", "GADWrMRHwQfoNaXU5fZvTg=="); | |
1021 const blink::WebCryptoAlgorithm aes_cbc_algorithm = | |
1022 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | |
1023 const blink::WebCryptoAlgorithm hmac_algorithm = | |
1024 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | |
1025 const blink::WebCryptoAlgorithm aes_kw_algorithm = | |
1026 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
1027 | 922 |
1028 // Test null usage. | |
1029 base::ListValue* key_ops = new base::ListValue; | |
1030 // Note: the following call makes dict assume ownership of key_ops. | |
1031 dict.Set("key_ops", key_ops); | |
1032 EXPECT_STATUS_SUCCESS( | |
1033 ImportKeyJwkFromDict(dict, aes_cbc_algorithm, false, 0, &key)); | |
1034 EXPECT_EQ(0, key.usages()); | |
1035 | |
1036 // Test each key_ops value translates to the correct Web Crypto value. | |
1037 struct TestCase { | |
1038 const char* jwk_key_op; | |
1039 const char* jwk_alg; | |
1040 const blink::WebCryptoAlgorithm algorithm; | |
1041 const blink::WebCryptoKeyUsage usage; | |
1042 }; | |
1043 // TODO(padolph): Add 'deriveBits' key_ops value once it is supported. | |
1044 const TestCase test_case[] = { | |
1045 {"encrypt", "A128CBC", aes_cbc_algorithm, | |
1046 blink::WebCryptoKeyUsageEncrypt}, | |
1047 {"decrypt", "A128CBC", aes_cbc_algorithm, | |
1048 blink::WebCryptoKeyUsageDecrypt}, | |
1049 {"sign", "HS256", hmac_algorithm, blink::WebCryptoKeyUsageSign}, | |
1050 {"verify", "HS256", hmac_algorithm, blink::WebCryptoKeyUsageVerify}, | |
1051 {"wrapKey", "A128KW", aes_kw_algorithm, blink::WebCryptoKeyUsageWrapKey}, | |
1052 {"unwrapKey", "A128KW", aes_kw_algorithm, | |
1053 blink::WebCryptoKeyUsageUnwrapKey}, | |
1054 {"deriveKey", "HS256", hmac_algorithm, | |
1055 blink::WebCryptoKeyUsageDeriveKey}}; | |
1056 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(test_case); | |
1057 ++test_index) { | |
1058 SCOPED_TRACE(test_index); | |
1059 dict.SetString("alg", test_case[test_index].jwk_alg); | |
1060 key_ops->Clear(); | |
1061 key_ops->AppendString(test_case[test_index].jwk_key_op); | |
1062 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict(dict, | |
1063 test_case[test_index].algorithm, | |
1064 false, | |
1065 test_case[test_index].usage, | |
1066 &key)); | |
1067 EXPECT_EQ(test_case[test_index].usage, key.usages()); | |
1068 } | |
1069 | |
1070 // Test discrete multiple usages. | |
1071 dict.SetString("alg", "A128CBC"); | |
1072 key_ops->Clear(); | |
1073 key_ops->AppendString("encrypt"); | |
1074 key_ops->AppendString("decrypt"); | |
1075 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( | |
1076 dict, | |
1077 aes_cbc_algorithm, | |
1078 false, | |
1079 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt, | |
1080 &key)); | |
1081 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt, | |
1082 key.usages()); | |
1083 | |
1084 // Test constrained key usage (input usage is a subset of JWK usage). | |
1085 key_ops->Clear(); | |
1086 key_ops->AppendString("encrypt"); | |
1087 key_ops->AppendString("decrypt"); | |
1088 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( | |
1089 dict, aes_cbc_algorithm, false, blink::WebCryptoKeyUsageDecrypt, &key)); | |
1090 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt, key.usages()); | |
1091 | |
1092 // Test failure if input usage is NOT a strict subset of the JWK usage. | |
1093 key_ops->Clear(); | |
1094 key_ops->AppendString("encrypt"); | |
1095 EXPECT_STATUS(Status::ErrorJwkKeyopsInconsistent(), | |
1096 ImportKeyJwkFromDict(dict, | |
1097 aes_cbc_algorithm, | |
1098 false, | |
1099 blink::WebCryptoKeyUsageEncrypt | | |
1100 blink::WebCryptoKeyUsageDecrypt, | |
1101 &key)); | |
1102 | |
1103 // Test 'use' inconsistent with 'key_ops'. | |
1104 dict.SetString("alg", "HS256"); | |
1105 dict.SetString("use", "sig"); | |
1106 key_ops->AppendString("sign"); | |
1107 key_ops->AppendString("verify"); | |
1108 key_ops->AppendString("encrypt"); | |
1109 EXPECT_STATUS(Status::ErrorJwkUseAndKeyopsInconsistent(), | |
1110 ImportKeyJwkFromDict(dict, | |
1111 hmac_algorithm, | |
1112 false, | |
1113 blink::WebCryptoKeyUsageSign | | |
1114 blink::WebCryptoKeyUsageVerify, | |
1115 &key)); | |
1116 | |
1117 // Test JWK composite 'sig' use | |
1118 dict.Remove("key_ops", NULL); | |
1119 dict.SetString("use", "sig"); | |
1120 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( | |
1121 dict, | |
1122 hmac_algorithm, | |
1123 false, | |
1124 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, | |
1125 &key)); | |
1126 EXPECT_EQ(blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, | |
1127 key.usages()); | |
1128 | |
1129 // Test JWK composite use 'enc' usage | |
1130 dict.SetString("alg", "A128CBC"); | |
1131 dict.SetString("use", "enc"); | |
1132 EXPECT_STATUS_SUCCESS(ImportKeyJwkFromDict( | |
1133 dict, | |
1134 aes_cbc_algorithm, | |
1135 false, | |
1136 blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt | | |
1137 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey | | |
1138 blink::WebCryptoKeyUsageDeriveKey, | |
1139 &key)); | |
1140 EXPECT_EQ(blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageEncrypt | | |
1141 blink::WebCryptoKeyUsageWrapKey | | |
1142 blink::WebCryptoKeyUsageUnwrapKey | | |
1143 blink::WebCryptoKeyUsageDeriveKey, | |
1144 key.usages()); | |
1145 } | |
1146 | |
1147 TEST_F(SharedCryptoTest, ImportJwkFailures) { | |
1148 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 923 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1149 blink::WebCryptoAlgorithm algorithm = | 924 blink::WebCryptoAlgorithm algorithm = |
1150 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | 925 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
1151 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; | 926 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; |
1152 | 927 |
1153 // Baseline pass: each test below breaks a single item, so we start with a | 928 // Baseline pass: each test below breaks a single item, so we start with a |
1154 // passing case to make sure each failure is caused by the isolated break. | 929 // passing case to make sure each failure is caused by the isolated break. |
1155 // Each breaking subtest below resets the dictionary to this passing case when | 930 // Each breaking subtest below resets the dictionary to this passing case when |
1156 // complete. | 931 // complete. |
1157 base::DictionaryValue dict; | 932 base::DictionaryValue dict; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 RestoreJwkOctDictionary(&dict); | 980 RestoreJwkOctDictionary(&dict); |
1206 | 981 |
1207 // Fail on kty wrong type. | 982 // Fail on kty wrong type. |
1208 dict.SetDouble("kty", 0.1); | 983 dict.SetDouble("kty", 0.1); |
1209 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("kty", "string"), | 984 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("kty", "string"), |
1210 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 985 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1211 RestoreJwkOctDictionary(&dict); | 986 RestoreJwkOctDictionary(&dict); |
1212 | 987 |
1213 // Fail on invalid use. | 988 // Fail on invalid use. |
1214 dict.SetString("use", "foo"); | 989 dict.SetString("use", "foo"); |
1215 EXPECT_STATUS(Status::ErrorJwkUnrecognizedUse(), | 990 EXPECT_STATUS(Status::ErrorJwkUnrecognizedUsage(), |
1216 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 991 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1217 RestoreJwkOctDictionary(&dict); | 992 RestoreJwkOctDictionary(&dict); |
1218 | 993 |
1219 // Fail on invalid use (wrong type). | 994 // Fail on invalid use (wrong type). |
1220 dict.SetBoolean("use", true); | 995 dict.SetBoolean("use", true); |
1221 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("use", "string"), | 996 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("use", "string"), |
1222 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 997 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1223 RestoreJwkOctDictionary(&dict); | 998 RestoreJwkOctDictionary(&dict); |
1224 | 999 |
1225 // Fail on invalid extractable (wrong type). | 1000 // Fail on invalid extractable (wrong type). |
1226 dict.SetInteger("ext", 0); | 1001 dict.SetInteger("extractable", 0); |
1227 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("ext", "boolean"), | 1002 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("extractable", "boolean"), |
1228 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | |
1229 RestoreJwkOctDictionary(&dict); | |
1230 | |
1231 // Fail on invalid key_ops (wrong type). | |
1232 dict.SetBoolean("key_ops", true); | |
1233 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("key_ops", "list"), | |
1234 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | |
1235 RestoreJwkOctDictionary(&dict); | |
1236 | |
1237 // Fail on invalid key_ops (wrong element value). | |
1238 base::ListValue* key_ops = new base::ListValue; | |
1239 // Note: the following call makes dict assume ownership of key_ops. | |
1240 dict.Set("key_ops", key_ops); | |
1241 key_ops->AppendString("foo"); | |
1242 EXPECT_STATUS(Status::ErrorJwkUnrecognizedKeyop(), | |
1243 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1003 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1244 RestoreJwkOctDictionary(&dict); | 1004 RestoreJwkOctDictionary(&dict); |
1245 } | 1005 } |
1246 | 1006 |
1247 TEST_F(SharedCryptoTest, ImportJwkOctFailures) { | 1007 TEST_F(SharedCryptoTest, ImportJwkOctFailures) { |
| 1008 |
1248 base::DictionaryValue dict; | 1009 base::DictionaryValue dict; |
1249 RestoreJwkOctDictionary(&dict); | 1010 RestoreJwkOctDictionary(&dict); |
1250 blink::WebCryptoAlgorithm algorithm = | 1011 blink::WebCryptoAlgorithm algorithm = |
1251 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | 1012 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
1252 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; | 1013 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; |
1253 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1014 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1254 | 1015 |
1255 // Baseline pass. | 1016 // Baseline pass. |
1256 EXPECT_STATUS_SUCCESS( | 1017 EXPECT_STATUS_SUCCESS( |
1257 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1018 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1289 | 1050 |
1290 // Fail on k actual length (192 bits) inconsistent with the embedded JWK alg | 1051 // Fail on k actual length (192 bits) inconsistent with the embedded JWK alg |
1291 // value (128) for an AES key. | 1052 // value (128) for an AES key. |
1292 dict.SetString("k", "dGhpcyAgaXMgIDI0ICBieXRlcyBsb25n"); | 1053 dict.SetString("k", "dGhpcyAgaXMgIDI0ICBieXRlcyBsb25n"); |
1293 EXPECT_STATUS(Status::ErrorJwkIncorrectKeyLength(), | 1054 EXPECT_STATUS(Status::ErrorJwkIncorrectKeyLength(), |
1294 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1055 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1295 RestoreJwkOctDictionary(&dict); | 1056 RestoreJwkOctDictionary(&dict); |
1296 } | 1057 } |
1297 | 1058 |
1298 TEST_F(SharedCryptoTest, MAYBE(ImportJwkRsaFailures)) { | 1059 TEST_F(SharedCryptoTest, MAYBE(ImportJwkRsaFailures)) { |
| 1060 |
1299 base::DictionaryValue dict; | 1061 base::DictionaryValue dict; |
1300 RestoreJwkRsaDictionary(&dict); | 1062 RestoreJwkRsaDictionary(&dict); |
1301 blink::WebCryptoAlgorithm algorithm = | 1063 blink::WebCryptoAlgorithm algorithm = |
1302 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); | 1064 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
1303 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; | 1065 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; |
1304 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1066 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1305 | 1067 |
1306 // An RSA public key JWK _must_ have an "n" (modulus) and an "e" (exponent) | 1068 // An RSA public key JWK _must_ have an "n" (modulus) and an "e" (exponent) |
1307 // entry, while an RSA private key must have those plus at least a "d" | 1069 // entry, while an RSA private key must have those plus at least a "d" |
1308 // (private exponent) entry. | 1070 // (private exponent) entry. |
1309 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18, | 1071 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18, |
1310 // section 6.3. | 1072 // section 6.3. |
1311 | 1073 |
1312 // Baseline pass. | 1074 // Baseline pass. |
1313 EXPECT_STATUS_SUCCESS( | 1075 EXPECT_STATUS_SUCCESS( |
1314 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1076 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1315 EXPECT_EQ(algorithm.id(), key.algorithm().id()); | 1077 EXPECT_EQ(algorithm.id(), key.algorithm().id()); |
1316 EXPECT_FALSE(key.extractable()); | 1078 EXPECT_FALSE(key.extractable()); |
1317 EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages()); | 1079 EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages()); |
1318 EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type()); | 1080 EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type()); |
1319 | 1081 |
1320 // The following are specific failure cases for when kty = "RSA". | 1082 // The following are specific failure cases for when kty = "RSA". |
1321 | 1083 |
1322 // Fail if either "n" or "e" is not present or malformed. | 1084 // Fail if either "n" or "e" is not present or malformed. |
1323 const std::string kKtyParmName[] = {"n", "e"}; | 1085 const std::string kKtyParmName[] = {"n", "e"}; |
1324 for (size_t idx = 0; idx < ARRAYSIZE_UNSAFE(kKtyParmName); ++idx) { | 1086 for (size_t idx = 0; idx < ARRAYSIZE_UNSAFE(kKtyParmName); ++idx) { |
| 1087 |
1325 // Fail on missing parameter. | 1088 // Fail on missing parameter. |
1326 dict.Remove(kKtyParmName[idx], NULL); | 1089 dict.Remove(kKtyParmName[idx], NULL); |
1327 EXPECT_STATUS_ERROR( | 1090 EXPECT_STATUS_ERROR( |
1328 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1091 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1329 RestoreJwkRsaDictionary(&dict); | 1092 RestoreJwkRsaDictionary(&dict); |
1330 | 1093 |
1331 // Fail on bad b64 parameter encoding. | 1094 // Fail on bad b64 parameter encoding. |
1332 dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0"); | 1095 dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0"); |
1333 EXPECT_STATUS_ERROR( | 1096 EXPECT_STATUS_ERROR( |
1334 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1097 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); | 1137 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); |
1375 key = blink::WebCryptoKey::createNull(); | 1138 key = blink::WebCryptoKey::createNull(); |
1376 | 1139 |
1377 // Consistency rules when JWK value exists: Fail if inconsistency is found. | 1140 // Consistency rules when JWK value exists: Fail if inconsistency is found. |
1378 | 1141 |
1379 // Pass: All input values are consistent with the JWK values. | 1142 // Pass: All input values are consistent with the JWK values. |
1380 dict.Clear(); | 1143 dict.Clear(); |
1381 dict.SetString("kty", "oct"); | 1144 dict.SetString("kty", "oct"); |
1382 dict.SetString("alg", "HS256"); | 1145 dict.SetString("alg", "HS256"); |
1383 dict.SetString("use", "sig"); | 1146 dict.SetString("use", "sig"); |
1384 dict.SetBoolean("ext", false); | 1147 dict.SetBoolean("extractable", false); |
1385 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 1148 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
1386 json_vec = MakeJsonVector(dict); | 1149 json_vec = MakeJsonVector(dict); |
1387 EXPECT_STATUS_SUCCESS(ImportKeyJwk( | 1150 EXPECT_STATUS_SUCCESS(ImportKeyJwk( |
1388 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); | 1151 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); |
1389 | 1152 |
1390 // Extractable cases: | 1153 // Extractable cases: |
1391 // 1. input=T, JWK=F ==> fail (inconsistent) | 1154 // 1. input=T, JWK=F ==> fail (inconsistent) |
1392 // 4. input=F, JWK=F ==> pass, result extractable is F | 1155 // 4. input=F, JWK=F ==> pass, result extractable is F |
1393 // 2. input=T, JWK=T ==> pass, result extractable is T | 1156 // 2. input=T, JWK=T ==> pass, result extractable is T |
1394 // 3. input=F, JWK=T ==> pass, result extractable is F | 1157 // 3. input=F, JWK=T ==> pass, result extractable is F |
1395 EXPECT_STATUS( | 1158 EXPECT_STATUS( |
1396 Status::ErrorJwkExtInconsistent(), | 1159 Status::ErrorJwkExtractableInconsistent(), |
1397 ImportKeyJwk(CryptoData(json_vec), algorithm, true, usage_mask, &key)); | 1160 ImportKeyJwk(CryptoData(json_vec), algorithm, true, usage_mask, &key)); |
1398 EXPECT_STATUS_SUCCESS( | 1161 EXPECT_STATUS_SUCCESS( |
1399 ImportKeyJwk(CryptoData(json_vec), algorithm, false, usage_mask, &key)); | 1162 ImportKeyJwk(CryptoData(json_vec), algorithm, false, usage_mask, &key)); |
1400 EXPECT_FALSE(key.extractable()); | 1163 EXPECT_FALSE(key.extractable()); |
1401 dict.SetBoolean("ext", true); | 1164 dict.SetBoolean("extractable", true); |
1402 EXPECT_STATUS_SUCCESS( | 1165 EXPECT_STATUS_SUCCESS( |
1403 ImportKeyJwkFromDict(dict, algorithm, true, usage_mask, &key)); | 1166 ImportKeyJwkFromDict(dict, algorithm, true, usage_mask, &key)); |
1404 EXPECT_TRUE(key.extractable()); | 1167 EXPECT_TRUE(key.extractable()); |
1405 EXPECT_STATUS_SUCCESS( | 1168 EXPECT_STATUS_SUCCESS( |
1406 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1169 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
1407 EXPECT_FALSE(key.extractable()); | 1170 EXPECT_FALSE(key.extractable()); |
1408 dict.SetBoolean("ext", true); // restore previous value | 1171 dict.SetBoolean("extractable", true); // restore previous value |
1409 | 1172 |
1410 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value | 1173 // Fail: Input algorithm (AES-CBC) is inconsistent with JWK value |
1411 // (HMAC SHA256). | 1174 // (HMAC SHA256). |
1412 EXPECT_STATUS(Status::ErrorJwkAlgorithmInconsistent(), | 1175 EXPECT_STATUS(Status::ErrorJwkAlgorithmInconsistent(), |
1413 ImportKeyJwk(CryptoData(json_vec), | 1176 ImportKeyJwk(CryptoData(json_vec), |
1414 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), | 1177 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
1415 extractable, | 1178 extractable, |
1416 usage_mask, | 1179 usage_mask, |
1417 &key)); | 1180 &key)); |
1418 | 1181 |
(...skipping 21 matching lines...) Expand all Loading... |
1440 dict, | 1203 dict, |
1441 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), | 1204 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256), |
1442 extractable, | 1205 extractable, |
1443 usage_mask, | 1206 usage_mask, |
1444 &key)); | 1207 &key)); |
1445 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); | 1208 EXPECT_EQ(blink::WebCryptoAlgorithmIdHmac, algorithm.id()); |
1446 dict.SetString("alg", "HS256"); | 1209 dict.SetString("alg", "HS256"); |
1447 | 1210 |
1448 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value | 1211 // Fail: Input usage_mask (encrypt) is not a subset of the JWK value |
1449 // (sign|verify) | 1212 // (sign|verify) |
1450 EXPECT_STATUS(Status::ErrorJwkUseInconsistent(), | 1213 EXPECT_STATUS(Status::ErrorJwkUsageInconsistent(), |
1451 ImportKeyJwk(CryptoData(json_vec), | 1214 ImportKeyJwk(CryptoData(json_vec), |
1452 algorithm, | 1215 algorithm, |
1453 extractable, | 1216 extractable, |
1454 blink::WebCryptoKeyUsageEncrypt, | 1217 blink::WebCryptoKeyUsageEncrypt, |
1455 &key)); | 1218 &key)); |
1456 | 1219 |
1457 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK | 1220 // Fail: Input usage_mask (encrypt|sign|verify) is not a subset of the JWK |
1458 // value (sign|verify) | 1221 // value (sign|verify) |
1459 usage_mask = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign | | 1222 usage_mask = blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageSign | |
1460 blink::WebCryptoKeyUsageVerify; | 1223 blink::WebCryptoKeyUsageVerify; |
1461 EXPECT_STATUS( | 1224 EXPECT_STATUS( |
1462 Status::ErrorJwkUseInconsistent(), | 1225 Status::ErrorJwkUsageInconsistent(), |
1463 ImportKeyJwk( | 1226 ImportKeyJwk( |
1464 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); | 1227 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); |
1465 | 1228 |
1466 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, | 1229 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, |
1467 // only certain alg values are permitted. For example, when kty = "RSA" alg | 1230 // only certain alg values are permitted. For example, when kty = "RSA" alg |
1468 // must be of the RSA family, or when kty = "oct" alg must be symmetric | 1231 // must be of the RSA family, or when kty = "oct" alg must be symmetric |
1469 // algorithm. | 1232 // algorithm. |
1470 | |
1471 // TODO(padolph): key_ops consistency tests | |
1472 } | 1233 } |
1473 | 1234 |
1474 TEST_F(SharedCryptoTest, MAYBE(ImportJwkHappy)) { | 1235 TEST_F(SharedCryptoTest, MAYBE(ImportJwkHappy)) { |
| 1236 |
1475 // This test verifies the happy path of JWK import, including the application | 1237 // This test verifies the happy path of JWK import, including the application |
1476 // of the imported key material. | 1238 // of the imported key material. |
1477 | 1239 |
1478 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1240 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1479 bool extractable = false; | 1241 bool extractable = false; |
1480 blink::WebCryptoAlgorithm algorithm = | 1242 blink::WebCryptoAlgorithm algorithm = |
1481 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | 1243 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
1482 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; | 1244 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; |
1483 | 1245 |
1484 // Import a symmetric key JWK and HMAC-SHA256 sign() | 1246 // Import a symmetric key JWK and HMAC-SHA256 sign() |
1485 // Uses the first SHA256 test vector from the HMAC sample set above. | 1247 // Uses the first SHA256 test vector from the HMAC sample set above. |
1486 | 1248 |
1487 base::DictionaryValue dict; | 1249 base::DictionaryValue dict; |
1488 dict.SetString("kty", "oct"); | 1250 dict.SetString("kty", "oct"); |
1489 dict.SetString("alg", "HS256"); | 1251 dict.SetString("alg", "HS256"); |
1490 dict.SetString("use", "sig"); | 1252 dict.SetString("use", "sig"); |
1491 dict.SetBoolean("ext", false); | 1253 dict.SetBoolean("extractable", false); |
1492 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); | 1254 dict.SetString("k", "l3nZEgZCeX8XRwJdWyK3rGB8qwjhdY8vOkbIvh4lxTuMao9Y_--hdg"); |
1493 | 1255 |
1494 ASSERT_STATUS_SUCCESS( | 1256 ASSERT_STATUS_SUCCESS( |
1495 ImportKeyJwkFromDict(dict, algorithm, extractable, usage_mask, &key)); | 1257 ImportKeyJwkFromDict(dict, algorithm, extractable, usage_mask, &key)); |
1496 | 1258 |
1497 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, | 1259 EXPECT_EQ(blink::WebCryptoAlgorithmIdSha256, |
1498 key.algorithm().hmacParams()->hash().id()); | 1260 key.algorithm().hmacParams()->hash().id()); |
1499 | 1261 |
1500 const std::vector<uint8> message_raw = HexStringToBytes( | 1262 const std::vector<uint8> message_raw = HexStringToBytes( |
1501 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a" | 1263 "b1689c2591eaf3c9e66070f8a77954ffb81749f1b00346f9dfe0b2ee905dcc288baf4a" |
1502 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92" | 1264 "92de3f4001dd9f44c468c3d07d6c6ee82faceafc97c2fc0fc0601719d2dcd0aa2aec92" |
1503 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f" | 1265 "d1b0ae933c65eb06a03c9c935c2bad0459810241347ab87e9f11adb30415424c6c7f5f" |
1504 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e"); | 1266 "22a003b8ab8de54f6ded0e3ab9245fa79568451dfa258e"); |
1505 | 1267 |
1506 blink::WebArrayBuffer output; | 1268 blink::WebArrayBuffer output; |
1507 | 1269 |
1508 ASSERT_STATUS_SUCCESS(Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), | 1270 ASSERT_STATUS_SUCCESS(Sign(CreateAlgorithm(blink::WebCryptoAlgorithmIdHmac), |
1509 key, | 1271 key, |
1510 CryptoData(message_raw), | 1272 CryptoData(message_raw), |
1511 &output)); | 1273 &output)); |
1512 | 1274 |
1513 const std::string mac_raw = | 1275 const std::string mac_raw = |
1514 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b"; | 1276 "769f00d3e6a6cc1fb426a14a4f76c6462e6149726e0dee0ec0cf97a16605ac8b"; |
1515 | 1277 |
1516 ExpectArrayBufferMatchesHex(mac_raw, output); | 1278 ExpectArrayBufferMatchesHex(mac_raw, output); |
1517 | 1279 |
1518 // TODO(padolph): Import an RSA public key JWK and use it | 1280 // TODO(padolph): Import an RSA public key JWK and use it |
1519 } | 1281 } |
1520 | 1282 |
1521 TEST_F(SharedCryptoTest, MAYBE(ImportExportJwkSymmetricKey)) { | |
1522 // Raw keys are generated by openssl: | |
1523 // % openssl rand -hex <key length bytes> | |
1524 const char* const key_hex_128 = "3f1e7cd4f6f8543f6b1e16002e688623"; | |
1525 const char* const key_hex_192 = | |
1526 "ed91f916dc034eba68a0f9e7f34ddd48b98bd2848109e243"; | |
1527 const char* const key_hex_256 = | |
1528 "bd08286b81a74783fd1ccf46b7e05af84ee25ae021210074159e0c4d9d907692"; | |
1529 const char* const key_hex_384 = | |
1530 "a22c5441c8b185602283d64c7221de1d0951e706bfc09539435ec0e0ed614e1d406623f2" | |
1531 "b31d31819fec30993380dd82"; | |
1532 const char* const key_hex_512 = | |
1533 "5834f639000d4cf82de124fbfd26fb88d463e99f839a76ba41ac88967c80a3f61e1239a4" | |
1534 "52e573dba0750e988152988576efd75b8d0229b7aca2ada2afd392ee"; | |
1535 const blink::WebCryptoAlgorithm aes_cbc_alg = | |
1536 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | |
1537 const blink::WebCryptoAlgorithm aes_gcm_alg = | |
1538 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm); | |
1539 const blink::WebCryptoAlgorithm aes_kw_alg = | |
1540 webcrypto::CreateAlgorithm(blink::WebCryptoAlgorithmIdAesKw); | |
1541 const blink::WebCryptoAlgorithm hmac_sha_1_alg = | |
1542 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1); | |
1543 const blink::WebCryptoAlgorithm hmac_sha_256_alg = | |
1544 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | |
1545 const blink::WebCryptoAlgorithm hmac_sha_384_alg = | |
1546 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha384); | |
1547 const blink::WebCryptoAlgorithm hmac_sha_512_alg = | |
1548 webcrypto::CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha512); | |
1549 | |
1550 struct TestCase { | |
1551 const char* const key_hex; | |
1552 const blink::WebCryptoAlgorithm algorithm; | |
1553 const blink::WebCryptoKeyUsageMask usage; | |
1554 const char* const jwk_alg; | |
1555 }; | |
1556 | |
1557 // TODO(padolph): Test AES-CTR JWK export, once AES-CTR import works. | |
1558 const TestCase kTests[] = { | |
1559 // AES-CBC 128 | |
1560 {key_hex_128, aes_cbc_alg, | |
1561 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, | |
1562 "A128CBC"}, | |
1563 // AES-CBC 192 | |
1564 {key_hex_192, aes_cbc_alg, blink::WebCryptoKeyUsageEncrypt, "A192CBC"}, | |
1565 // AES-CBC 256 | |
1566 {key_hex_256, aes_cbc_alg, blink::WebCryptoKeyUsageDecrypt, "A256CBC"}, | |
1567 // AES-GCM 128 | |
1568 {key_hex_128, aes_gcm_alg, | |
1569 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt, | |
1570 "A128GCM"}, | |
1571 // AES-CGM 192 | |
1572 {key_hex_192, aes_gcm_alg, blink::WebCryptoKeyUsageEncrypt, "A192GCM"}, | |
1573 // AES-GCM 256 | |
1574 {key_hex_256, aes_gcm_alg, blink::WebCryptoKeyUsageDecrypt, "A256GCM"}, | |
1575 // AES-KW 128 | |
1576 {key_hex_128, aes_kw_alg, | |
1577 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, | |
1578 "A128KW"}, | |
1579 // AES-KW 192 | |
1580 {key_hex_192, aes_kw_alg, | |
1581 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, | |
1582 "A192KW"}, | |
1583 // AES-KW 256 | |
1584 {key_hex_256, aes_kw_alg, | |
1585 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, | |
1586 "A256KW"}, | |
1587 // HMAC SHA-1 | |
1588 {key_hex_256, hmac_sha_1_alg, | |
1589 blink::WebCryptoKeyUsageSign | blink::WebCryptoKeyUsageVerify, "HS1"}, | |
1590 // HMAC SHA-384 | |
1591 {key_hex_384, hmac_sha_384_alg, blink::WebCryptoKeyUsageSign, "HS384"}, | |
1592 // HMAC SHA-512 | |
1593 {key_hex_512, hmac_sha_512_alg, blink::WebCryptoKeyUsageVerify, "HS512"}, | |
1594 // Large usage value | |
1595 {key_hex_256, aes_cbc_alg, | |
1596 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt | | |
1597 blink::WebCryptoKeyUsageWrapKey | blink::WebCryptoKeyUsageUnwrapKey, | |
1598 "A256CBC"}, | |
1599 // Zero usage value | |
1600 {key_hex_512, hmac_sha_512_alg, 0, "HS512"}, }; | |
1601 | |
1602 // Round-trip import/export each key. | |
1603 | |
1604 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | |
1605 blink::WebArrayBuffer json; | |
1606 for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests); | |
1607 ++test_index) { | |
1608 SCOPED_TRACE(test_index); | |
1609 const TestCase& test = kTests[test_index]; | |
1610 | |
1611 // Import a raw key. | |
1612 key = ImportSecretKeyFromRaw( | |
1613 HexStringToBytes(test.key_hex), test.algorithm, test.usage); | |
1614 | |
1615 // Export the key in JWK format and validate. | |
1616 ASSERT_STATUS_SUCCESS(ExportKeyJwk(key, &json)); | |
1617 EXPECT_TRUE( | |
1618 VerifySymmetricJwk(json, test.jwk_alg, test.key_hex, test.usage)); | |
1619 | |
1620 // Import the JWK-formatted key. | |
1621 ASSERT_STATUS_SUCCESS( | |
1622 ImportKeyJwk(CryptoData(json), test.algorithm, true, test.usage, &key)); | |
1623 EXPECT_TRUE(key.handle()); | |
1624 EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type()); | |
1625 EXPECT_EQ(test.algorithm.id(), key.algorithm().id()); | |
1626 EXPECT_EQ(true, key.extractable()); | |
1627 EXPECT_EQ(test.usage, key.usages()); | |
1628 | |
1629 // Export the key in raw format and compare to the original. | |
1630 blink::WebArrayBuffer key_raw_out; | |
1631 ASSERT_STATUS_SUCCESS( | |
1632 ExportKey(blink::WebCryptoKeyFormatRaw, key, &key_raw_out)); | |
1633 ExpectArrayBufferMatchesHex(test.key_hex, key_raw_out); | |
1634 } | |
1635 } | |
1636 | |
1637 TEST_F(SharedCryptoTest, MAYBE(ImportExportSpki)) { | 1283 TEST_F(SharedCryptoTest, MAYBE(ImportExportSpki)) { |
1638 // Passing case: Import a valid RSA key in SPKI format. | 1284 // Passing case: Import a valid RSA key in SPKI format. |
1639 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1285 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
1640 ASSERT_STATUS_SUCCESS( | 1286 ASSERT_STATUS_SUCCESS( |
1641 ImportKey(blink::WebCryptoKeyFormatSpki, | 1287 ImportKey(blink::WebCryptoKeyFormatSpki, |
1642 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), | 1288 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), |
1643 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), | 1289 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), |
1644 true, | 1290 true, |
1645 blink::WebCryptoKeyUsageEncrypt, | 1291 blink::WebCryptoKeyUsageEncrypt, |
1646 &key)); | 1292 &key)); |
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2826 wrapping_algorithm, | 2472 wrapping_algorithm, |
2827 key_algorithm, | 2473 key_algorithm, |
2828 true, | 2474 true, |
2829 blink::WebCryptoKeyUsageSign, | 2475 blink::WebCryptoKeyUsageSign, |
2830 &unwrapped_key)); | 2476 &unwrapped_key)); |
2831 } | 2477 } |
2832 | 2478 |
2833 } // namespace webcrypto | 2479 } // namespace webcrypto |
2834 | 2480 |
2835 } // namespace content | 2481 } // namespace content |
OLD | NEW |