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

Side by Side Diff: content/child/webcrypto/shared_crypto.cc

Issue 195893034: [webcrypto] Add JWK symmetric key RSAES-PKCS1-v1_5 wrap / unwrap for NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: upload HEAD~2 Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/child/webcrypto/jwk.cc ('k') | content/child/webcrypto/shared_crypto_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/child/webcrypto/jwk.cc ('k') | content/child/webcrypto/shared_crypto_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698