Chromium Code Reviews| 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/jwk.h" | 9 #include "content/child/webcrypto/jwk.h" |
| 10 #include "content/child/webcrypto/platform_crypto.h" | 10 #include "content/child/webcrypto/platform_crypto.h" |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 if (status.IsError()) | 152 if (status.IsError()) |
| 153 return status; | 153 return status; |
| 154 | 154 |
| 155 // RSAES decryption does not support empty input | 155 // RSAES decryption does not support empty input |
| 156 if (!data.byte_length()) | 156 if (!data.byte_length()) |
| 157 return Status::ErrorDataTooSmall(); | 157 return Status::ErrorDataTooSmall(); |
| 158 | 158 |
| 159 return platform::DecryptRsaEsPkcs1v1_5(private_key, data, buffer); | 159 return platform::DecryptRsaEsPkcs1v1_5(private_key, data, buffer); |
| 160 } | 160 } |
| 161 | 161 |
| 162 Status EncryptRsaOaep(const blink::WebCryptoAlgorithm& algorithm, | |
| 163 const blink::WebCryptoKey& key, | |
| 164 const CryptoData& data, | |
| 165 std::vector<uint8>* buffer) { | |
| 166 platform::PublicKey* public_key; | |
| 167 Status status = ToPlatformPublicKey(key, &public_key); | |
| 168 if (status.IsError()) | |
| 169 return status; | |
| 170 | |
| 171 const blink::WebCryptoRsaOaepParams* params = algorithm.rsaOaepParams(); | |
| 172 if (!params) | |
| 173 return Status::ErrorUnexpected(); | |
| 174 | |
| 175 return platform::EncryptRsaOaep(public_key, | |
| 176 key.algorithm().rsaHashedParams()->hash(), | |
| 177 CryptoData(params->optionalLabel()), | |
| 178 data, | |
| 179 buffer); | |
| 180 } | |
| 181 | |
| 182 Status DecryptRsaOaep(const blink::WebCryptoAlgorithm& algorithm, | |
| 183 const blink::WebCryptoKey& key, | |
| 184 const CryptoData& data, | |
| 185 std::vector<uint8>* buffer) { | |
| 186 platform::PrivateKey* private_key; | |
| 187 Status status = ToPlatformPrivateKey(key, &private_key); | |
| 188 if (status.IsError()) | |
| 189 return status; | |
| 190 | |
| 191 const blink::WebCryptoRsaOaepParams* params = algorithm.rsaOaepParams(); | |
| 192 if (!params) | |
| 193 return Status::ErrorUnexpected(); | |
| 194 | |
| 195 return platform::DecryptRsaOaep(private_key, | |
| 196 key.algorithm().rsaHashedParams()->hash(), | |
| 197 CryptoData(params->optionalLabel()), | |
| 198 data, | |
| 199 buffer); | |
| 200 } | |
| 201 | |
| 162 Status SignHmac(const blink::WebCryptoAlgorithm& algorithm, | 202 Status SignHmac(const blink::WebCryptoAlgorithm& algorithm, |
| 163 const blink::WebCryptoKey& key, | 203 const blink::WebCryptoKey& key, |
| 164 const CryptoData& data, | 204 const CryptoData& data, |
| 165 std::vector<uint8>* buffer) { | 205 std::vector<uint8>* buffer) { |
| 166 platform::SymKey* sym_key; | 206 platform::SymKey* sym_key; |
| 167 Status status = ToPlatformSymKey(key, &sym_key); | 207 Status status = ToPlatformSymKey(key, &sym_key); |
| 168 if (status.IsError()) | 208 if (status.IsError()) |
| 169 return status; | 209 return status; |
| 170 | 210 |
| 171 return platform::SignHmac( | 211 return platform::SignHmac( |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 428 std::vector<uint8>* buffer) { | 468 std::vector<uint8>* buffer) { |
| 429 if (algorithm.id() != key.algorithm().id()) | 469 if (algorithm.id() != key.algorithm().id()) |
| 430 return Status::ErrorUnexpected(); | 470 return Status::ErrorUnexpected(); |
| 431 switch (algorithm.id()) { | 471 switch (algorithm.id()) { |
| 432 case blink::WebCryptoAlgorithmIdAesCbc: | 472 case blink::WebCryptoAlgorithmIdAesCbc: |
| 433 return EncryptDecryptAesCbc(DECRYPT, algorithm, key, data, buffer); | 473 return EncryptDecryptAesCbc(DECRYPT, algorithm, key, data, buffer); |
| 434 case blink::WebCryptoAlgorithmIdAesGcm: | 474 case blink::WebCryptoAlgorithmIdAesGcm: |
| 435 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer); | 475 return EncryptDecryptAesGcm(DECRYPT, algorithm, key, data, buffer); |
| 436 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 476 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
| 437 return DecryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); | 477 return DecryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); |
| 478 case blink::WebCryptoAlgorithmIdRsaOaep: | |
| 479 return DecryptRsaOaep(algorithm, key, data, buffer); | |
| 438 case blink::WebCryptoAlgorithmIdAesKw: | 480 case blink::WebCryptoAlgorithmIdAesKw: |
| 439 return DecryptAesKw(algorithm, key, data, buffer); | 481 return DecryptAesKw(algorithm, key, data, buffer); |
| 440 default: | 482 default: |
| 441 return Status::ErrorUnsupported(); | 483 return Status::ErrorUnsupported(); |
| 442 } | 484 } |
| 443 } | 485 } |
| 444 | 486 |
| 445 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm, | 487 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm, |
| 446 const blink::WebCryptoKey& key, | 488 const blink::WebCryptoKey& key, |
| 447 const CryptoData& data, | 489 const CryptoData& data, |
| 448 std::vector<uint8>* buffer) { | 490 std::vector<uint8>* buffer) { |
| 449 if (algorithm.id() != key.algorithm().id()) | 491 if (algorithm.id() != key.algorithm().id()) |
| 450 return Status::ErrorUnexpected(); | 492 return Status::ErrorUnexpected(); |
| 451 switch (algorithm.id()) { | 493 switch (algorithm.id()) { |
| 452 case blink::WebCryptoAlgorithmIdAesCbc: | 494 case blink::WebCryptoAlgorithmIdAesCbc: |
| 453 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer); | 495 return EncryptDecryptAesCbc(ENCRYPT, algorithm, key, data, buffer); |
| 454 case blink::WebCryptoAlgorithmIdAesGcm: | 496 case blink::WebCryptoAlgorithmIdAesGcm: |
| 455 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer); | 497 return EncryptDecryptAesGcm(ENCRYPT, algorithm, key, data, buffer); |
| 456 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 498 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
| 457 return EncryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); | 499 return EncryptRsaEsPkcs1v1_5(algorithm, key, data, buffer); |
| 500 case blink::WebCryptoAlgorithmIdRsaOaep: | |
| 501 return EncryptRsaOaep(algorithm, key, data, buffer); | |
| 458 default: | 502 default: |
| 459 return Status::ErrorUnsupported(); | 503 return Status::ErrorUnsupported(); |
| 460 } | 504 } |
| 461 } | 505 } |
| 462 | 506 |
| 463 Status UnwrapKeyDecryptAndImport( | 507 Status UnwrapKeyDecryptAndImport( |
| 464 blink::WebCryptoKeyFormat format, | 508 blink::WebCryptoKeyFormat format, |
| 465 const CryptoData& wrapped_key_data, | 509 const CryptoData& wrapped_key_data, |
| 466 const blink::WebCryptoKey& wrapping_key, | 510 const blink::WebCryptoKey& wrapping_key, |
| 467 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 511 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 755 const blink::WebCryptoKey& wrapping_key, | 799 const blink::WebCryptoKey& wrapping_key, |
| 756 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 800 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 757 std::vector<uint8>* buffer) { | 801 std::vector<uint8>* buffer) { |
| 758 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey)) | 802 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey)) |
| 759 return Status::ErrorUnexpected(); | 803 return Status::ErrorUnexpected(); |
| 760 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) | 804 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) |
| 761 return Status::ErrorUnexpected(); | 805 return Status::ErrorUnexpected(); |
| 762 | 806 |
| 763 switch (format) { | 807 switch (format) { |
| 764 case blink::WebCryptoKeyFormatRaw: | 808 case blink::WebCryptoKeyFormatRaw: |
| 765 return WrapKeyRaw(key_to_wrap, wrapping_key, wrapping_algorithm, buffer); | 809 if (wrapping_algorithm.id() == blink::WebCryptoAlgorithmIdAesKw) { |
| 810 // AES-KW is a special case, due to NSS's implementation only | |
| 811 // supporting C_Wrap/C_Unwrap with AES-KW | |
|
Ryan Sleevi
2014/05/14 01:26:00
This does feel kinda hacky. It could be wrapped in
| |
| 812 return WrapKeyRaw( | |
| 813 key_to_wrap, wrapping_key, wrapping_algorithm, buffer); | |
| 814 } else { | |
| 815 return WrapKeyExportAndEncrypt( | |
| 816 format, key_to_wrap, wrapping_key, wrapping_algorithm, buffer); | |
| 817 } | |
| 766 case blink::WebCryptoKeyFormatJwk: | 818 case blink::WebCryptoKeyFormatJwk: |
| 767 return WrapKeyExportAndEncrypt( | 819 return WrapKeyExportAndEncrypt( |
| 768 format, key_to_wrap, wrapping_key, wrapping_algorithm, buffer); | 820 format, key_to_wrap, wrapping_key, wrapping_algorithm, buffer); |
| 769 case blink::WebCryptoKeyFormatSpki: | 821 case blink::WebCryptoKeyFormatSpki: |
| 770 case blink::WebCryptoKeyFormatPkcs8: | 822 case blink::WebCryptoKeyFormatPkcs8: |
| 771 return Status::ErrorUnsupported(); // TODO(padolph) | 823 return Status::ErrorUnsupported(); // TODO(padolph) |
| 772 default: | 824 default: |
| 773 NOTREACHED(); | 825 NOTREACHED(); |
| 774 return Status::ErrorUnsupported(); | 826 return Status::ErrorUnsupported(); |
| 775 } | 827 } |
| 776 } | 828 } |
| 777 | 829 |
| 778 Status UnwrapKey(blink::WebCryptoKeyFormat format, | 830 Status UnwrapKey(blink::WebCryptoKeyFormat format, |
| 779 const CryptoData& wrapped_key_data, | 831 const CryptoData& wrapped_key_data, |
| 780 const blink::WebCryptoKey& wrapping_key, | 832 const blink::WebCryptoKey& wrapping_key, |
| 781 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 833 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 782 const blink::WebCryptoAlgorithm& algorithm, | 834 const blink::WebCryptoAlgorithm& algorithm, |
| 783 bool extractable, | 835 bool extractable, |
| 784 blink::WebCryptoKeyUsageMask usage_mask, | 836 blink::WebCryptoKeyUsageMask usage_mask, |
| 785 blink::WebCryptoKey* key) { | 837 blink::WebCryptoKey* key) { |
| 786 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey)) | 838 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey)) |
| 787 return Status::ErrorUnexpected(); | 839 return Status::ErrorUnexpected(); |
| 788 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) | 840 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) |
| 789 return Status::ErrorUnexpected(); | 841 return Status::ErrorUnexpected(); |
| 790 | 842 |
| 791 switch (format) { | 843 switch (format) { |
| 792 case blink::WebCryptoKeyFormatRaw: | 844 case blink::WebCryptoKeyFormatRaw: |
| 793 return UnwrapKeyRaw(wrapped_key_data, | 845 if (wrapping_algorithm.id() == blink::WebCryptoAlgorithmIdAesKw) { |
|
padolph
2014/05/14 02:14:41
I don't understand the special-casing here. Unwrap
Ryan Sleevi
2014/05/14 02:34:30
Correct. Much of the pk11wrap layer is not situate
| |
| 794 wrapping_key, | 846 // AES-KW is a special case, due to NSS's implementation only |
| 795 wrapping_algorithm, | 847 // supporting C_Wrap/C_Unwrap with AES-KW |
| 796 algorithm, | 848 return UnwrapKeyRaw(wrapped_key_data, |
| 797 extractable, | 849 wrapping_key, |
| 798 usage_mask, | 850 wrapping_algorithm, |
| 799 key); | 851 algorithm, |
| 852 extractable, | |
| 853 usage_mask, | |
| 854 key); | |
| 855 } else { | |
| 856 return UnwrapKeyDecryptAndImport(format, | |
|
eroman
2014/05/14 01:50:47
I thought style was to not use an "else" after a r
Ryan Sleevi
2014/05/14 02:34:30
D'oh! Well spotted.
| |
| 857 wrapped_key_data, | |
| 858 wrapping_key, | |
| 859 wrapping_algorithm, | |
| 860 algorithm, | |
| 861 extractable, | |
| 862 usage_mask, | |
| 863 key); | |
| 864 } | |
| 800 case blink::WebCryptoKeyFormatJwk: | 865 case blink::WebCryptoKeyFormatJwk: |
| 801 return UnwrapKeyDecryptAndImport(format, | 866 return UnwrapKeyDecryptAndImport(format, |
| 802 wrapped_key_data, | 867 wrapped_key_data, |
| 803 wrapping_key, | 868 wrapping_key, |
| 804 wrapping_algorithm, | 869 wrapping_algorithm, |
| 805 algorithm, | 870 algorithm, |
| 806 extractable, | 871 extractable, |
| 807 usage_mask, | 872 usage_mask, |
| 808 key); | 873 key); |
| 809 case blink::WebCryptoKeyFormatSpki: | 874 case blink::WebCryptoKeyFormatSpki: |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 844 usage_mask, | 909 usage_mask, |
| 845 key); | 910 key); |
| 846 if (status.IsError()) | 911 if (status.IsError()) |
| 847 return false; | 912 return false; |
| 848 return ValidateDeserializedKey(*key, algorithm, type); | 913 return ValidateDeserializedKey(*key, algorithm, type); |
| 849 } | 914 } |
| 850 | 915 |
| 851 } // namespace webcrypto | 916 } // namespace webcrypto |
| 852 | 917 |
| 853 } // namespace content | 918 } // namespace content |
| OLD | NEW |