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/platform_crypto.h" | 5 #include "content/child/webcrypto/platform_crypto.h" |
6 | 6 |
7 #include <cryptohi.h> | 7 #include <cryptohi.h> |
8 #include <pk11pub.h> | 8 #include <pk11pub.h> |
9 #include <sechash.h> | 9 #include <sechash.h> |
10 | 10 |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 return Status::Success(); | 610 return Status::Success(); |
611 } | 611 } |
612 | 612 |
613 namespace { | 613 namespace { |
614 | 614 |
615 typedef scoped_ptr<CERTSubjectPublicKeyInfo, | 615 typedef scoped_ptr<CERTSubjectPublicKeyInfo, |
616 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo, | 616 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo, |
617 SECKEY_DestroySubjectPublicKeyInfo> > | 617 SECKEY_DestroySubjectPublicKeyInfo> > |
618 ScopedCERTSubjectPublicKeyInfo; | 618 ScopedCERTSubjectPublicKeyInfo; |
619 | 619 |
620 // Validates an NSS KeyType against a WebCrypto algorithm. Some NSS KeyTypes | 620 // Validates an NSS KeyType against a WebCrypto import algorithm. |
621 // contain enough information to fabricate a Web Crypto algorithm, which is | 621 bool ValidateNssKeyTypeAgainstInputAlgorithm( |
622 // returned if the input algorithm isNull(). This function indicates failure by | |
623 // returning a Null algorithm. | |
624 blink::WebCryptoAlgorithm ResolveNssKeyTypeWithInputAlgorithm( | |
625 KeyType key_type, | 622 KeyType key_type, |
626 const blink::WebCryptoAlgorithm& algorithm_or_null) { | 623 const blink::WebCryptoAlgorithm& algorithm) { |
627 switch (key_type) { | 624 switch (key_type) { |
628 case rsaKey: | 625 case rsaKey: |
629 // NSS's rsaKey KeyType maps to keys with SEC_OID_PKCS1_RSA_ENCRYPTION and | 626 return IsAlgorithmRsa(algorithm); |
630 // according to RFCs 4055/5756 this can be used for both encryption and | |
631 // signatures. However, this is not specific enough to build a compatible | |
632 // Web Crypto algorithm, since in Web Crypto, RSA encryption and signature | |
633 // algorithms are distinct. So if the input algorithm isNull() here, we | |
634 // have to fail. | |
635 if (!algorithm_or_null.isNull() && IsAlgorithmRsa(algorithm_or_null)) | |
636 return algorithm_or_null; | |
637 break; | |
638 case dsaKey: | 627 case dsaKey: |
639 case ecKey: | 628 case ecKey: |
640 case rsaPssKey: | 629 case rsaPssKey: |
641 case rsaOaepKey: | 630 case rsaOaepKey: |
642 // TODO(padolph): Handle other key types. | 631 // TODO(padolph): Handle other key types. |
643 break; | 632 break; |
644 default: | 633 default: |
645 break; | 634 break; |
646 } | 635 } |
647 return blink::WebCryptoAlgorithm::createNull(); | 636 return false; |
648 } | 637 } |
649 | 638 |
650 } // namespace | 639 } // namespace |
651 | 640 |
652 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm_or_null, | 641 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm, |
653 const CryptoData& key_data, | 642 const CryptoData& key_data, |
654 bool extractable, | 643 bool extractable, |
655 blink::WebCryptoKeyUsageMask usage_mask, | 644 blink::WebCryptoKeyUsageMask usage_mask, |
656 blink::WebCryptoKey* key) { | 645 blink::WebCryptoKey* key) { |
657 | 646 |
658 DCHECK(key); | 647 DCHECK(key); |
659 | 648 |
660 if (!key_data.byte_length()) | 649 if (!key_data.byte_length()) |
661 return Status::ErrorImportEmptyKeyData(); | 650 return Status::ErrorImportEmptyKeyData(); |
662 DCHECK(key_data.bytes()); | 651 DCHECK(key_data.bytes()); |
663 | 652 |
664 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject | 653 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject |
665 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. | 654 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. |
666 SECItem spki_item = MakeSECItemForBuffer(key_data); | 655 SECItem spki_item = MakeSECItemForBuffer(key_data); |
667 const ScopedCERTSubjectPublicKeyInfo spki( | 656 const ScopedCERTSubjectPublicKeyInfo spki( |
668 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); | 657 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); |
669 if (!spki) | 658 if (!spki) |
670 return Status::Error(); | 659 return Status::Error(); |
671 | 660 |
672 crypto::ScopedSECKEYPublicKey sec_public_key( | 661 crypto::ScopedSECKEYPublicKey sec_public_key( |
673 SECKEY_ExtractPublicKey(spki.get())); | 662 SECKEY_ExtractPublicKey(spki.get())); |
674 if (!sec_public_key) | 663 if (!sec_public_key) |
675 return Status::Error(); | 664 return Status::Error(); |
676 | 665 |
677 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); | 666 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); |
678 blink::WebCryptoAlgorithm algorithm = | 667 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) |
679 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); | |
680 if (algorithm.isNull()) | |
681 return Status::Error(); | 668 return Status::Error(); |
682 | 669 |
683 blink::WebCryptoKeyAlgorithm key_algorithm; | 670 blink::WebCryptoKeyAlgorithm key_algorithm; |
684 if (!CreatePublicKeyAlgorithm( | 671 if (!CreatePublicKeyAlgorithm( |
685 algorithm, sec_public_key.get(), &key_algorithm)) | 672 algorithm, sec_public_key.get(), &key_algorithm)) |
686 return Status::ErrorUnexpected(); | 673 return Status::ErrorUnexpected(); |
687 | 674 |
688 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), | 675 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), |
689 blink::WebCryptoKeyTypePublic, | 676 blink::WebCryptoKeyTypePublic, |
690 extractable, | 677 extractable, |
(...skipping 10 matching lines...) Expand all Loading... |
701 return Status::Error(); | 688 return Status::Error(); |
702 | 689 |
703 DCHECK(spki_der->data); | 690 DCHECK(spki_der->data); |
704 DCHECK(spki_der->len); | 691 DCHECK(spki_der->len); |
705 | 692 |
706 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); | 693 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); |
707 | 694 |
708 return Status::Success(); | 695 return Status::Success(); |
709 } | 696 } |
710 | 697 |
711 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm_or_null, | 698 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm, |
712 const CryptoData& key_data, | 699 const CryptoData& key_data, |
713 bool extractable, | 700 bool extractable, |
714 blink::WebCryptoKeyUsageMask usage_mask, | 701 blink::WebCryptoKeyUsageMask usage_mask, |
715 blink::WebCryptoKey* key) { | 702 blink::WebCryptoKey* key) { |
716 | 703 |
717 DCHECK(key); | 704 DCHECK(key); |
718 | 705 |
719 if (!key_data.byte_length()) | 706 if (!key_data.byte_length()) |
720 return Status::ErrorImportEmptyKeyData(); | 707 return Status::ErrorImportEmptyKeyData(); |
721 DCHECK(key_data.bytes()); | 708 DCHECK(key_data.bytes()); |
(...skipping 12 matching lines...) Expand all Loading... |
734 false, // isPrivate | 721 false, // isPrivate |
735 KU_ALL, // usage | 722 KU_ALL, // usage |
736 &seckey_private_key, | 723 &seckey_private_key, |
737 NULL) != SECSuccess) { | 724 NULL) != SECSuccess) { |
738 return Status::Error(); | 725 return Status::Error(); |
739 } | 726 } |
740 DCHECK(seckey_private_key); | 727 DCHECK(seckey_private_key); |
741 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); | 728 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); |
742 | 729 |
743 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); | 730 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); |
744 blink::WebCryptoAlgorithm algorithm = | 731 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) |
745 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); | |
746 if (algorithm.isNull()) | |
747 return Status::Error(); | 732 return Status::Error(); |
748 | 733 |
749 blink::WebCryptoKeyAlgorithm key_algorithm; | 734 blink::WebCryptoKeyAlgorithm key_algorithm; |
750 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) | 735 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) |
751 return Status::ErrorUnexpected(); | 736 return Status::ErrorUnexpected(); |
752 | 737 |
753 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), | 738 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), |
754 blink::WebCryptoKeyTypePrivate, | 739 blink::WebCryptoKeyTypePrivate, |
755 extractable, | 740 extractable, |
756 key_algorithm, | 741 key_algorithm, |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1338 key_algorithm, | 1323 key_algorithm, |
1339 usage_mask); | 1324 usage_mask); |
1340 return Status::Success(); | 1325 return Status::Success(); |
1341 } | 1326 } |
1342 | 1327 |
1343 } // namespace platform | 1328 } // namespace platform |
1344 | 1329 |
1345 } // namespace webcrypto | 1330 } // namespace webcrypto |
1346 | 1331 |
1347 } // namespace content | 1332 } // namespace content |
OLD | NEW |