| 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 "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "content/child/webcrypto/crypto_data.h" | 8 #include "content/child/webcrypto/crypto_data.h" |
| 9 #include "content/child/webcrypto/platform_crypto.h" | 9 #include "content/child/webcrypto/platform_crypto.h" |
| 10 #include "content/child/webcrypto/webcrypto_util.h" | 10 #include "content/child/webcrypto/webcrypto_util.h" |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 algorithm_or_null, | 361 algorithm_or_null, |
| 362 extractable, | 362 extractable, |
| 363 usage_mask, | 363 usage_mask, |
| 364 key); | 364 key); |
| 365 } | 365 } |
| 366 default: | 366 default: |
| 367 return Status::ErrorUnsupported(); | 367 return Status::ErrorUnsupported(); |
| 368 } | 368 } |
| 369 } | 369 } |
| 370 | 370 |
| 371 Status WrapKeyRaw(const blink::WebCryptoKey& wrapping_key, |
| 372 const blink::WebCryptoKey& key_to_wrap, |
| 373 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 374 blink::WebArrayBuffer* buffer) { |
| 375 // A raw key is always a symmetric key. |
| 376 platform::SymKey* platform_key; |
| 377 Status status = ToPlatformSymKey(key_to_wrap, &platform_key); |
| 378 if (status.IsError()) |
| 379 return status; |
| 380 |
| 381 // TODO(padolph): Handle other wrapping algorithms |
| 382 switch (wrapping_algorithm.id()) { |
| 383 case blink::WebCryptoAlgorithmIdAesKw: { |
| 384 platform::SymKey* platform_wrapping_key; |
| 385 status = ToPlatformSymKey(wrapping_key, &platform_wrapping_key); |
| 386 if (status.IsError()) |
| 387 return status; |
| 388 return platform::WrapSymKeyAesKw( |
| 389 platform_wrapping_key, platform_key, buffer); |
| 390 } |
| 391 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: { |
| 392 platform::PublicKey* platform_wrapping_key; |
| 393 status = ToPlatformPublicKey(wrapping_key, &platform_wrapping_key); |
| 394 if (status.IsError()) |
| 395 return status; |
| 396 return platform::WrapSymKeyRsaEs( |
| 397 platform_wrapping_key, platform_key, buffer); |
| 398 } |
| 399 default: |
| 400 return Status::ErrorUnsupported(); |
| 401 } |
| 402 } |
| 403 |
| 371 Status DecryptAesKw(const blink::WebCryptoAlgorithm& algorithm, | 404 Status DecryptAesKw(const blink::WebCryptoAlgorithm& algorithm, |
| 372 const blink::WebCryptoKey& key, | 405 const blink::WebCryptoKey& key, |
| 373 const CryptoData& data, | 406 const CryptoData& data, |
| 374 blink::WebArrayBuffer* buffer) { | 407 blink::WebArrayBuffer* buffer) { |
| 375 platform::SymKey* sym_key; | 408 platform::SymKey* sym_key; |
| 376 Status status = ToPlatformSymKey(key, &sym_key); | 409 Status status = ToPlatformSymKey(key, &sym_key); |
| 377 if (status.IsError()) | 410 if (status.IsError()) |
| 378 return status; | 411 return status; |
| 379 status = CheckAesKwInputSize(data); | 412 status = CheckAesKwInputSize(data); |
| 380 if (status.IsError()) | 413 if (status.IsError()) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 395 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer); | 428 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer); |
| 396 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 429 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
| 397 return DecryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); | 430 return DecryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); |
| 398 case blink::WebCryptoAlgorithmIdAesKw: | 431 case blink::WebCryptoAlgorithmIdAesKw: |
| 399 return DecryptAesKw(algorithm, key, data, buffer); | 432 return DecryptAesKw(algorithm, key, data, buffer); |
| 400 default: | 433 default: |
| 401 return Status::ErrorUnsupported(); | 434 return Status::ErrorUnsupported(); |
| 402 } | 435 } |
| 403 } | 436 } |
| 404 | 437 |
| 438 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm, |
| 439 const blink::WebCryptoKey& key, |
| 440 const CryptoData& data, |
| 441 blink::WebArrayBuffer* buffer) { |
| 442 if (algorithm.id() != key.algorithm().id()) |
| 443 return Status::ErrorUnexpected(); |
| 444 switch (algorithm.id()) { |
| 445 case blink::WebCryptoAlgorithmIdAesCbc: |
| 446 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer); |
| 447 case blink::WebCryptoAlgorithmIdAesGcm: |
| 448 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer); |
| 449 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
| 450 return EncryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); |
| 451 default: |
| 452 return Status::ErrorUnsupported(); |
| 453 } |
| 454 } |
| 455 |
| 405 Status UnwrapKeyDecryptAndImport( | 456 Status UnwrapKeyDecryptAndImport( |
| 406 blink::WebCryptoKeyFormat format, | 457 blink::WebCryptoKeyFormat format, |
| 407 const CryptoData& wrapped_key_data, | 458 const CryptoData& wrapped_key_data, |
| 408 const blink::WebCryptoKey& wrapping_key, | 459 const blink::WebCryptoKey& wrapping_key, |
| 409 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 460 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 410 const blink::WebCryptoAlgorithm& algorithm_or_null, | 461 const blink::WebCryptoAlgorithm& algorithm_or_null, |
| 411 bool extractable, | 462 bool extractable, |
| 412 blink::WebCryptoKeyUsageMask usage_mask, | 463 blink::WebCryptoKeyUsageMask usage_mask, |
| 413 blink::WebCryptoKey* key) { | 464 blink::WebCryptoKey* key) { |
| 414 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey)) | |
| 415 return Status::ErrorUnexpected(); | |
| 416 blink::WebArrayBuffer buffer; | 465 blink::WebArrayBuffer buffer; |
| 417 Status status = DecryptDontCheckKeyUsage( | 466 Status status = DecryptDontCheckKeyUsage( |
| 418 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer); | 467 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer); |
| 419 if (status.IsError()) | 468 if (status.IsError()) |
| 420 return status; | 469 return status; |
| 421 status = ImportKey(format, | 470 status = ImportKey(format, |
| 422 CryptoData(buffer), | 471 CryptoData(buffer), |
| 423 algorithm_or_null, | 472 algorithm_or_null, |
| 424 extractable, | 473 extractable, |
| 425 usage_mask, | 474 usage_mask, |
| 426 key); | 475 key); |
| 427 // NOTE! Returning the details of any ImportKey() failure here would leak | 476 // NOTE! Returning the details of any ImportKey() failure here would leak |
| 428 // information about the plaintext internals of the encrypted key. Instead, | 477 // information about the plaintext internals of the encrypted key. Instead, |
| 429 // collapse any error into the generic Status::Error(). | 478 // collapse any error into the generic Status::Error(). |
| 430 return status.IsError() ? Status::Error() : Status::Success(); | 479 return status.IsError() ? Status::Error() : Status::Success(); |
| 431 } | 480 } |
| 432 | 481 |
| 482 Status WrapKeyExportAndEncrypt( |
| 483 blink::WebCryptoKeyFormat format, |
| 484 const blink::WebCryptoKey& wrapping_key, |
| 485 const blink::WebCryptoKey& key_to_wrap, |
| 486 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 487 blink::WebArrayBuffer* buffer) { |
| 488 blink::WebArrayBuffer exported_data; |
| 489 Status status = ExportKey(format, key_to_wrap, &exported_data); |
| 490 if (status.IsError()) |
| 491 return status; |
| 492 return EncryptDontCheckUsage( |
| 493 wrapping_algorithm, wrapping_key, CryptoData(exported_data), buffer); |
| 494 } |
| 495 |
| 433 } // namespace | 496 } // namespace |
| 434 | 497 |
| 435 void Init() { platform::Init(); } | 498 void Init() { platform::Init(); } |
| 436 | 499 |
| 437 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, | 500 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm, |
| 438 const blink::WebCryptoKey& key, | 501 const blink::WebCryptoKey& key, |
| 439 const CryptoData& data, | 502 const CryptoData& data, |
| 440 blink::WebArrayBuffer* buffer) { | 503 blink::WebArrayBuffer* buffer) { |
| 441 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt)) | 504 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt)) |
| 442 return Status::ErrorUnexpected(); | 505 return Status::ErrorUnexpected(); |
| 443 if (algorithm.id() != key.algorithm().id()) | 506 return EncryptDontCheckUsage(algorithm, key, data, buffer); |
| 444 return Status::ErrorUnexpected(); | |
| 445 | |
| 446 switch (algorithm.id()) { | |
| 447 case blink::WebCryptoAlgorithmIdAesCbc: | |
| 448 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer); | |
| 449 case blink::WebCryptoAlgorithmIdAesGcm: | |
| 450 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer); | |
| 451 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | |
| 452 return EncryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); | |
| 453 default: | |
| 454 return Status::ErrorUnsupported(); | |
| 455 } | |
| 456 } | 507 } |
| 457 | 508 |
| 458 Status Decrypt(const blink::WebCryptoAlgorithm& algorithm, | 509 Status Decrypt(const blink::WebCryptoAlgorithm& algorithm, |
| 459 const blink::WebCryptoKey& key, | 510 const blink::WebCryptoKey& key, |
| 460 const CryptoData& data, | 511 const CryptoData& data, |
| 461 blink::WebArrayBuffer* buffer) { | 512 blink::WebArrayBuffer* buffer) { |
| 462 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt)) | 513 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt)) |
| 463 return Status::ErrorUnexpected(); | 514 return Status::ErrorUnexpected(); |
| 464 return DecryptDontCheckKeyUsage(algorithm, key, data, buffer); | 515 return DecryptDontCheckKeyUsage(algorithm, key, data, buffer); |
| 465 } | 516 } |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 default: | 722 default: |
| 672 return Status::ErrorUnsupported(); | 723 return Status::ErrorUnsupported(); |
| 673 } | 724 } |
| 674 } | 725 } |
| 675 | 726 |
| 676 Status WrapKey(blink::WebCryptoKeyFormat format, | 727 Status WrapKey(blink::WebCryptoKeyFormat format, |
| 677 const blink::WebCryptoKey& wrapping_key, | 728 const blink::WebCryptoKey& wrapping_key, |
| 678 const blink::WebCryptoKey& key_to_wrap, | 729 const blink::WebCryptoKey& key_to_wrap, |
| 679 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 730 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 680 blink::WebArrayBuffer* buffer) { | 731 blink::WebArrayBuffer* buffer) { |
| 681 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey)) | 732 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey)) |
| 682 return Status::ErrorUnexpected(); | 733 return Status::ErrorUnexpected(); |
| 683 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) | 734 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) |
| 684 return Status::ErrorUnexpected(); | 735 return Status::ErrorUnexpected(); |
| 685 | 736 |
| 686 // TODO (padolph): Handle formats other than raw | 737 switch (format) { |
| 687 if (format != blink::WebCryptoKeyFormatRaw) | 738 case blink::WebCryptoKeyFormatRaw: |
| 688 return Status::ErrorUnsupported(); | 739 return WrapKeyRaw(wrapping_key, key_to_wrap, wrapping_algorithm, buffer); |
| 689 // TODO (padolph): Handle key-to-wrap types other than secret/symmetric | 740 case blink::WebCryptoKeyFormatJwk: |
| 690 if (key_to_wrap.type() != blink::WebCryptoKeyTypeSecret) | 741 return WrapKeyExportAndEncrypt( |
| 691 return Status::ErrorUnsupported(); | 742 format, wrapping_key, key_to_wrap, wrapping_algorithm, buffer); |
| 692 | 743 case blink::WebCryptoKeyFormatSpki: |
| 693 platform::SymKey* platform_key; | 744 case blink::WebCryptoKeyFormatPkcs8: |
| 694 Status status = ToPlatformSymKey(key_to_wrap, &platform_key); | 745 return Status::ErrorUnsupported(); // TODO(padolph) |
| 695 if (status.IsError()) | |
| 696 return status; | |
| 697 | |
| 698 // TODO(padolph): Handle other wrapping algorithms | |
| 699 switch (wrapping_algorithm.id()) { | |
| 700 case blink::WebCryptoAlgorithmIdAesKw: { | |
| 701 platform::SymKey* platform_wrapping_key; | |
| 702 status = ToPlatformSymKey(wrapping_key, &platform_wrapping_key); | |
| 703 if (status.IsError()) | |
| 704 return status; | |
| 705 return platform::WrapSymKeyAesKw( | |
| 706 platform_wrapping_key, platform_key, buffer); | |
| 707 } | |
| 708 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: { | |
| 709 platform::PublicKey* platform_wrapping_key; | |
| 710 status = ToPlatformPublicKey(wrapping_key, &platform_wrapping_key); | |
| 711 if (status.IsError()) | |
| 712 return status; | |
| 713 return platform::WrapSymKeyRsaEs( | |
| 714 platform_wrapping_key, platform_key, buffer); | |
| 715 } | |
| 716 default: | 746 default: |
| 747 NOTREACHED(); |
| 717 return Status::ErrorUnsupported(); | 748 return Status::ErrorUnsupported(); |
| 718 } | 749 } |
| 719 } | 750 } |
| 720 | 751 |
| 721 Status UnwrapKey(blink::WebCryptoKeyFormat format, | 752 Status UnwrapKey(blink::WebCryptoKeyFormat format, |
| 722 const CryptoData& wrapped_key_data, | 753 const CryptoData& wrapped_key_data, |
| 723 const blink::WebCryptoKey& wrapping_key, | 754 const blink::WebCryptoKey& wrapping_key, |
| 724 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 755 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 725 const blink::WebCryptoAlgorithm& algorithm_or_null, | 756 const blink::WebCryptoAlgorithm& algorithm_or_null, |
| 726 bool extractable, | 757 bool extractable, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 key); | 815 key); |
| 785 if (status.IsError()) | 816 if (status.IsError()) |
| 786 return status; | 817 return status; |
| 787 | 818 |
| 788 return ValidateDeserializedKey(*key, algorithm, type); | 819 return ValidateDeserializedKey(*key, algorithm, type); |
| 789 } | 820 } |
| 790 | 821 |
| 791 } // namespace webcrypto | 822 } // namespace webcrypto |
| 792 | 823 |
| 793 } // namespace content | 824 } // namespace content |
| OLD | NEW |