| 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/status.h" | 10 #include "content/child/webcrypto/status.h" |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 | 204 |
| 205 return platform::VerifyRsaSsaPkcs1v1_5( | 205 return platform::VerifyRsaSsaPkcs1v1_5( |
| 206 public_key, | 206 public_key, |
| 207 key.algorithm().rsaHashedParams()->hash(), | 207 key.algorithm().rsaHashedParams()->hash(), |
| 208 signature, | 208 signature, |
| 209 data, | 209 data, |
| 210 signature_match); | 210 signature_match); |
| 211 } | 211 } |
| 212 | 212 |
| 213 Status ImportKeyRaw(const CryptoData& key_data, | 213 Status ImportKeyRaw(const CryptoData& key_data, |
| 214 const blink::WebCryptoAlgorithm& algorithm_or_null, | 214 const blink::WebCryptoAlgorithm& algorithm, |
| 215 bool extractable, | 215 bool extractable, |
| 216 blink::WebCryptoKeyUsageMask usage_mask, | 216 blink::WebCryptoKeyUsageMask usage_mask, |
| 217 blink::WebCryptoKey* key) { | 217 blink::WebCryptoKey* key) { |
| 218 if (algorithm_or_null.isNull()) | 218 switch (algorithm.id()) { |
| 219 return Status::ErrorMissingAlgorithmImportRawKey(); | |
| 220 | |
| 221 switch (algorithm_or_null.id()) { | |
| 222 case blink::WebCryptoAlgorithmIdAesCtr: | 219 case blink::WebCryptoAlgorithmIdAesCtr: |
| 223 case blink::WebCryptoAlgorithmIdAesCbc: | 220 case blink::WebCryptoAlgorithmIdAesCbc: |
| 224 case blink::WebCryptoAlgorithmIdAesGcm: | 221 case blink::WebCryptoAlgorithmIdAesGcm: |
| 225 case blink::WebCryptoAlgorithmIdAesKw: | 222 case blink::WebCryptoAlgorithmIdAesKw: |
| 226 if (!IsValidAesKeyLengthBytes(key_data.byte_length())) | 223 if (!IsValidAesKeyLengthBytes(key_data.byte_length())) |
| 227 return Status::Error(); | 224 return Status::Error(); |
| 228 // Fallthrough intentional! | 225 // Fallthrough intentional! |
| 229 case blink::WebCryptoAlgorithmIdHmac: | 226 case blink::WebCryptoAlgorithmIdHmac: |
| 230 return platform::ImportKeyRaw( | 227 return platform::ImportKeyRaw( |
| 231 algorithm_or_null, key_data, extractable, usage_mask, key); | 228 algorithm, key_data, extractable, usage_mask, key); |
| 232 default: | 229 default: |
| 233 return Status::ErrorUnsupported(); | 230 return Status::ErrorUnsupported(); |
| 234 } | 231 } |
| 235 } | 232 } |
| 236 | 233 |
| 237 // Returns the key format to use for structured cloning. | 234 // Returns the key format to use for structured cloning. |
| 238 blink::WebCryptoKeyFormat GetCloneFormatForKeyType( | 235 blink::WebCryptoKeyFormat GetCloneFormatForKeyType( |
| 239 blink::WebCryptoKeyType type) { | 236 blink::WebCryptoKeyType type) { |
| 240 switch (type) { | 237 switch (type) { |
| 241 case blink::WebCryptoKeyTypeSecret: | 238 case blink::WebCryptoKeyTypeSecret: |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 if (aeskw_input_data.byte_length() < 24) | 314 if (aeskw_input_data.byte_length() < 24) |
| 318 return Status::ErrorDataTooSmall(); | 315 return Status::ErrorDataTooSmall(); |
| 319 if (aeskw_input_data.byte_length() % 8) | 316 if (aeskw_input_data.byte_length() % 8) |
| 320 return Status::ErrorInvalidAesKwDataLength(); | 317 return Status::ErrorInvalidAesKwDataLength(); |
| 321 return Status::Success(); | 318 return Status::Success(); |
| 322 } | 319 } |
| 323 | 320 |
| 324 Status UnwrapKeyRaw(const CryptoData& wrapped_key_data, | 321 Status UnwrapKeyRaw(const CryptoData& wrapped_key_data, |
| 325 const blink::WebCryptoKey& wrapping_key, | 322 const blink::WebCryptoKey& wrapping_key, |
| 326 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 323 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 327 const blink::WebCryptoAlgorithm& algorithm_or_null, | 324 const blink::WebCryptoAlgorithm& algorithm, |
| 328 bool extractable, | 325 bool extractable, |
| 329 blink::WebCryptoKeyUsageMask usage_mask, | 326 blink::WebCryptoKeyUsageMask usage_mask, |
| 330 blink::WebCryptoKey* key) { | 327 blink::WebCryptoKey* key) { |
| 331 // Must provide an algorithm when unwrapping a raw key | |
| 332 if (algorithm_or_null.isNull()) | |
| 333 return Status::ErrorMissingAlgorithmUnwrapRawKey(); | |
| 334 | |
| 335 // TODO(padolph): Handle other wrapping algorithms | 328 // TODO(padolph): Handle other wrapping algorithms |
| 336 switch (wrapping_algorithm.id()) { | 329 switch (wrapping_algorithm.id()) { |
| 337 case blink::WebCryptoAlgorithmIdAesKw: { | 330 case blink::WebCryptoAlgorithmIdAesKw: { |
| 338 platform::SymKey* platform_wrapping_key; | 331 platform::SymKey* platform_wrapping_key; |
| 339 Status status = ToPlatformSymKey(wrapping_key, &platform_wrapping_key); | 332 Status status = ToPlatformSymKey(wrapping_key, &platform_wrapping_key); |
| 340 if (status.IsError()) | 333 if (status.IsError()) |
| 341 return status; | 334 return status; |
| 342 status = CheckAesKwInputSize(wrapped_key_data); | 335 status = CheckAesKwInputSize(wrapped_key_data); |
| 343 if (status.IsError()) | 336 if (status.IsError()) |
| 344 return status; | 337 return status; |
| 345 return platform::UnwrapSymKeyAesKw(wrapped_key_data, | 338 return platform::UnwrapSymKeyAesKw(wrapped_key_data, |
| 346 platform_wrapping_key, | 339 platform_wrapping_key, |
| 347 algorithm_or_null, | 340 algorithm, |
| 348 extractable, | 341 extractable, |
| 349 usage_mask, | 342 usage_mask, |
| 350 key); | 343 key); |
| 351 } | 344 } |
| 352 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: { | 345 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: { |
| 353 platform::PrivateKey* platform_wrapping_key; | 346 platform::PrivateKey* platform_wrapping_key; |
| 354 Status status = | 347 Status status = |
| 355 ToPlatformPrivateKey(wrapping_key, &platform_wrapping_key); | 348 ToPlatformPrivateKey(wrapping_key, &platform_wrapping_key); |
| 356 if (status.IsError()) | 349 if (status.IsError()) |
| 357 return status; | 350 return status; |
| 358 if (!wrapped_key_data.byte_length()) | 351 if (!wrapped_key_data.byte_length()) |
| 359 return Status::ErrorDataTooSmall(); | 352 return Status::ErrorDataTooSmall(); |
| 360 return platform::UnwrapSymKeyRsaEs(wrapped_key_data, | 353 return platform::UnwrapSymKeyRsaEs(wrapped_key_data, |
| 361 platform_wrapping_key, | 354 platform_wrapping_key, |
| 362 algorithm_or_null, | 355 algorithm, |
| 363 extractable, | 356 extractable, |
| 364 usage_mask, | 357 usage_mask, |
| 365 key); | 358 key); |
| 366 } | 359 } |
| 367 default: | 360 default: |
| 368 return Status::ErrorUnsupported(); | 361 return Status::ErrorUnsupported(); |
| 369 } | 362 } |
| 370 } | 363 } |
| 371 | 364 |
| 372 Status WrapKeyRaw(const blink::WebCryptoKey& wrapping_key, | 365 Status WrapKeyRaw(const blink::WebCryptoKey& wrapping_key, |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 default: | 445 default: |
| 453 return Status::ErrorUnsupported(); | 446 return Status::ErrorUnsupported(); |
| 454 } | 447 } |
| 455 } | 448 } |
| 456 | 449 |
| 457 Status UnwrapKeyDecryptAndImport( | 450 Status UnwrapKeyDecryptAndImport( |
| 458 blink::WebCryptoKeyFormat format, | 451 blink::WebCryptoKeyFormat format, |
| 459 const CryptoData& wrapped_key_data, | 452 const CryptoData& wrapped_key_data, |
| 460 const blink::WebCryptoKey& wrapping_key, | 453 const blink::WebCryptoKey& wrapping_key, |
| 461 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 454 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 462 const blink::WebCryptoAlgorithm& algorithm_or_null, | 455 const blink::WebCryptoAlgorithm& algorithm, |
| 463 bool extractable, | 456 bool extractable, |
| 464 blink::WebCryptoKeyUsageMask usage_mask, | 457 blink::WebCryptoKeyUsageMask usage_mask, |
| 465 blink::WebCryptoKey* key) { | 458 blink::WebCryptoKey* key) { |
| 466 blink::WebArrayBuffer buffer; | 459 blink::WebArrayBuffer buffer; |
| 467 Status status = DecryptDontCheckKeyUsage( | 460 Status status = DecryptDontCheckKeyUsage( |
| 468 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer); | 461 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer); |
| 469 if (status.IsError()) | 462 if (status.IsError()) |
| 470 return status; | 463 return status; |
| 471 status = ImportKey(format, | 464 status = ImportKey( |
| 472 CryptoData(buffer), | 465 format, CryptoData(buffer), algorithm, extractable, usage_mask, key); |
| 473 algorithm_or_null, | |
| 474 extractable, | |
| 475 usage_mask, | |
| 476 key); | |
| 477 // NOTE! Returning the details of any ImportKey() failure here would leak | 466 // NOTE! Returning the details of any ImportKey() failure here would leak |
| 478 // information about the plaintext internals of the encrypted key. Instead, | 467 // information about the plaintext internals of the encrypted key. Instead, |
| 479 // collapse any error into the generic Status::Error(). | 468 // collapse any error into the generic Status::Error(). |
| 480 return status.IsError() ? Status::Error() : Status::Success(); | 469 return status.IsError() ? Status::Error() : Status::Success(); |
| 481 } | 470 } |
| 482 | 471 |
| 483 Status WrapKeyExportAndEncrypt( | 472 Status WrapKeyExportAndEncrypt( |
| 484 blink::WebCryptoKeyFormat format, | 473 blink::WebCryptoKeyFormat format, |
| 485 const blink::WebCryptoKey& wrapping_key, | 474 const blink::WebCryptoKey& wrapping_key, |
| 486 const blink::WebCryptoKey& key_to_wrap, | 475 const blink::WebCryptoKey& key_to_wrap, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 public_key, | 600 public_key, |
| 612 private_key); | 601 private_key); |
| 613 } | 602 } |
| 614 default: | 603 default: |
| 615 return Status::ErrorUnsupported(); | 604 return Status::ErrorUnsupported(); |
| 616 } | 605 } |
| 617 } | 606 } |
| 618 | 607 |
| 619 Status ImportKey(blink::WebCryptoKeyFormat format, | 608 Status ImportKey(blink::WebCryptoKeyFormat format, |
| 620 const CryptoData& key_data, | 609 const CryptoData& key_data, |
| 621 const blink::WebCryptoAlgorithm& algorithm_or_null, | 610 const blink::WebCryptoAlgorithm& algorithm, |
| 622 bool extractable, | 611 bool extractable, |
| 623 blink::WebCryptoKeyUsageMask usage_mask, | 612 blink::WebCryptoKeyUsageMask usage_mask, |
| 624 blink::WebCryptoKey* key) { | 613 blink::WebCryptoKey* key) { |
| 625 switch (format) { | 614 switch (format) { |
| 626 case blink::WebCryptoKeyFormatRaw: | 615 case blink::WebCryptoKeyFormatRaw: |
| 627 return ImportKeyRaw( | 616 return ImportKeyRaw(key_data, algorithm, extractable, usage_mask, key); |
| 628 key_data, algorithm_or_null, extractable, usage_mask, key); | |
| 629 case blink::WebCryptoKeyFormatSpki: | 617 case blink::WebCryptoKeyFormatSpki: |
| 630 return platform::ImportKeySpki( | 618 return platform::ImportKeySpki( |
| 631 algorithm_or_null, key_data, extractable, usage_mask, key); | 619 algorithm, key_data, extractable, usage_mask, key); |
| 632 case blink::WebCryptoKeyFormatPkcs8: | 620 case blink::WebCryptoKeyFormatPkcs8: |
| 633 return platform::ImportKeyPkcs8( | 621 return platform::ImportKeyPkcs8( |
| 634 algorithm_or_null, key_data, extractable, usage_mask, key); | 622 algorithm, key_data, extractable, usage_mask, key); |
| 635 case blink::WebCryptoKeyFormatJwk: | 623 case blink::WebCryptoKeyFormatJwk: |
| 636 return ImportKeyJwk( | 624 return ImportKeyJwk(key_data, algorithm, extractable, usage_mask, key); |
| 637 key_data, algorithm_or_null, extractable, usage_mask, key); | |
| 638 default: | 625 default: |
| 639 return Status::ErrorUnsupported(); | 626 return Status::ErrorUnsupported(); |
| 640 } | 627 } |
| 641 } | 628 } |
| 642 | 629 |
| 643 // TODO(eroman): Move this to anonymous namespace. | 630 // TODO(eroman): Move this to anonymous namespace. |
| 644 Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format, | 631 Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format, |
| 645 const blink::WebCryptoKey& key, | 632 const blink::WebCryptoKey& key, |
| 646 blink::WebArrayBuffer* buffer) { | 633 blink::WebArrayBuffer* buffer) { |
| 647 switch (format) { | 634 switch (format) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 default: | 734 default: |
| 748 NOTREACHED(); | 735 NOTREACHED(); |
| 749 return Status::ErrorUnsupported(); | 736 return Status::ErrorUnsupported(); |
| 750 } | 737 } |
| 751 } | 738 } |
| 752 | 739 |
| 753 Status UnwrapKey(blink::WebCryptoKeyFormat format, | 740 Status UnwrapKey(blink::WebCryptoKeyFormat format, |
| 754 const CryptoData& wrapped_key_data, | 741 const CryptoData& wrapped_key_data, |
| 755 const blink::WebCryptoKey& wrapping_key, | 742 const blink::WebCryptoKey& wrapping_key, |
| 756 const blink::WebCryptoAlgorithm& wrapping_algorithm, | 743 const blink::WebCryptoAlgorithm& wrapping_algorithm, |
| 757 const blink::WebCryptoAlgorithm& algorithm_or_null, | 744 const blink::WebCryptoAlgorithm& algorithm, |
| 758 bool extractable, | 745 bool extractable, |
| 759 blink::WebCryptoKeyUsageMask usage_mask, | 746 blink::WebCryptoKeyUsageMask usage_mask, |
| 760 blink::WebCryptoKey* key) { | 747 blink::WebCryptoKey* key) { |
| 761 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey)) | 748 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey)) |
| 762 return Status::ErrorUnexpected(); | 749 return Status::ErrorUnexpected(); |
| 763 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) | 750 if (wrapping_algorithm.id() != wrapping_key.algorithm().id()) |
| 764 return Status::ErrorUnexpected(); | 751 return Status::ErrorUnexpected(); |
| 765 | 752 |
| 766 switch (format) { | 753 switch (format) { |
| 767 case blink::WebCryptoKeyFormatRaw: | 754 case blink::WebCryptoKeyFormatRaw: |
| 768 return UnwrapKeyRaw(wrapped_key_data, | 755 return UnwrapKeyRaw(wrapped_key_data, |
| 769 wrapping_key, | 756 wrapping_key, |
| 770 wrapping_algorithm, | 757 wrapping_algorithm, |
| 771 algorithm_or_null, | 758 algorithm, |
| 772 extractable, | 759 extractable, |
| 773 usage_mask, | 760 usage_mask, |
| 774 key); | 761 key); |
| 775 case blink::WebCryptoKeyFormatJwk: | 762 case blink::WebCryptoKeyFormatJwk: |
| 776 return UnwrapKeyDecryptAndImport(format, | 763 return UnwrapKeyDecryptAndImport(format, |
| 777 wrapped_key_data, | 764 wrapped_key_data, |
| 778 wrapping_key, | 765 wrapping_key, |
| 779 wrapping_algorithm, | 766 wrapping_algorithm, |
| 780 algorithm_or_null, | 767 algorithm, |
| 781 extractable, | 768 extractable, |
| 782 usage_mask, | 769 usage_mask, |
| 783 key); | 770 key); |
| 784 case blink::WebCryptoKeyFormatSpki: | 771 case blink::WebCryptoKeyFormatSpki: |
| 785 case blink::WebCryptoKeyFormatPkcs8: | 772 case blink::WebCryptoKeyFormatPkcs8: |
| 786 return Status::ErrorUnsupported(); // TODO(padolph) | 773 return Status::ErrorUnsupported(); // TODO(padolph) |
| 787 default: | 774 default: |
| 788 NOTREACHED(); | 775 NOTREACHED(); |
| 789 return Status::ErrorUnsupported(); | 776 return Status::ErrorUnsupported(); |
| 790 } | 777 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 816 key); | 803 key); |
| 817 if (status.IsError()) | 804 if (status.IsError()) |
| 818 return status; | 805 return status; |
| 819 | 806 |
| 820 return ValidateDeserializedKey(*key, algorithm, type); | 807 return ValidateDeserializedKey(*key, algorithm, type); |
| 821 } | 808 } |
| 822 | 809 |
| 823 } // namespace webcrypto | 810 } // namespace webcrypto |
| 824 | 811 |
| 825 } // namespace content | 812 } // namespace content |
| OLD | NEW |