| 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/nss/rsa_key_nss.h" | 5 #include "content/child/webcrypto/nss/rsa_key_nss.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/generate_key_result.h" | 9 #include "content/child/webcrypto/generate_key_result.h" |
| 10 #include "content/child/webcrypto/jwk.h" | 10 #include "content/child/webcrypto/jwk.h" |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 | 300 |
| 301 if (!encoded_key.get()) | 301 if (!encoded_key.get()) |
| 302 return Status::OperationError(); | 302 return Status::OperationError(); |
| 303 | 303 |
| 304 buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len); | 304 buffer->assign(encoded_key->data, encoded_key->data + encoded_key->len); |
| 305 return Status::Success(); | 305 return Status::Success(); |
| 306 } | 306 } |
| 307 | 307 |
| 308 Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm, | 308 Status ImportRsaPrivateKey(const blink::WebCryptoAlgorithm& algorithm, |
| 309 bool extractable, | 309 bool extractable, |
| 310 blink::WebCryptoKeyUsageMask usage_mask, | 310 blink::WebCryptoKeyUsageMask usages, |
| 311 const JwkRsaInfo& params, | 311 const JwkRsaInfo& params, |
| 312 blink::WebCryptoKey* key) { | 312 blink::WebCryptoKey* key) { |
| 313 Status status = NssSupportsRsaPrivateKeyImport(); | 313 Status status = NssSupportsRsaPrivateKeyImport(); |
| 314 if (status.IsError()) | 314 if (status.IsError()) |
| 315 return status; | 315 return status; |
| 316 | 316 |
| 317 CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY; | 317 CK_OBJECT_CLASS obj_class = CKO_PRIVATE_KEY; |
| 318 CK_KEY_TYPE key_type = CKK_RSA; | 318 CK_KEY_TYPE key_type = CKK_RSA; |
| 319 CK_BBOOL ck_false = CK_FALSE; | 319 CK_BBOOL ck_false = CK_FALSE; |
| 320 | 320 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 if (status.IsError()) | 402 if (status.IsError()) |
| 403 return status; | 403 return status; |
| 404 | 404 |
| 405 scoped_ptr<PrivateKeyNss> key_handle( | 405 scoped_ptr<PrivateKeyNss> key_handle( |
| 406 new PrivateKeyNss(private_key.Pass(), CryptoData(pkcs8_data))); | 406 new PrivateKeyNss(private_key.Pass(), CryptoData(pkcs8_data))); |
| 407 | 407 |
| 408 *key = blink::WebCryptoKey::create(key_handle.release(), | 408 *key = blink::WebCryptoKey::create(key_handle.release(), |
| 409 blink::WebCryptoKeyTypePrivate, | 409 blink::WebCryptoKeyTypePrivate, |
| 410 extractable, | 410 extractable, |
| 411 key_algorithm, | 411 key_algorithm, |
| 412 usage_mask); | 412 usages); |
| 413 return Status::Success(); | 413 return Status::Success(); |
| 414 } | 414 } |
| 415 | 415 |
| 416 Status ExportKeySpkiNss(SECKEYPublicKey* key, std::vector<uint8_t>* buffer) { | 416 Status ExportKeySpkiNss(SECKEYPublicKey* key, std::vector<uint8_t>* buffer) { |
| 417 const crypto::ScopedSECItem spki_der( | 417 const crypto::ScopedSECItem spki_der( |
| 418 SECKEY_EncodeDERSubjectPublicKeyInfo(key)); | 418 SECKEY_EncodeDERSubjectPublicKeyInfo(key)); |
| 419 if (!spki_der) | 419 if (!spki_der) |
| 420 return Status::OperationError(); | 420 return Status::OperationError(); |
| 421 | 421 |
| 422 buffer->assign(spki_der->data, spki_der->data + spki_der->len); | 422 buffer->assign(spki_der->data, spki_der->data + spki_der->len); |
| 423 return Status::Success(); | 423 return Status::Success(); |
| 424 } | 424 } |
| 425 | 425 |
| 426 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, | 426 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, |
| 427 bool extractable, | 427 bool extractable, |
| 428 blink::WebCryptoKeyUsageMask usage_mask, | 428 blink::WebCryptoKeyUsageMask usages, |
| 429 const CryptoData& modulus_data, | 429 const CryptoData& modulus_data, |
| 430 const CryptoData& exponent_data, | 430 const CryptoData& exponent_data, |
| 431 blink::WebCryptoKey* key) { | 431 blink::WebCryptoKey* key) { |
| 432 if (!modulus_data.byte_length()) | 432 if (!modulus_data.byte_length()) |
| 433 return Status::ErrorImportRsaEmptyModulus(); | 433 return Status::ErrorImportRsaEmptyModulus(); |
| 434 | 434 |
| 435 if (!exponent_data.byte_length()) | 435 if (!exponent_data.byte_length()) |
| 436 return Status::ErrorImportRsaEmptyExponent(); | 436 return Status::ErrorImportRsaEmptyExponent(); |
| 437 | 437 |
| 438 DCHECK(modulus_data.bytes()); | 438 DCHECK(modulus_data.bytes()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 if (status.IsError()) | 493 if (status.IsError()) |
| 494 return status; | 494 return status; |
| 495 | 495 |
| 496 scoped_ptr<PublicKeyNss> key_handle( | 496 scoped_ptr<PublicKeyNss> key_handle( |
| 497 new PublicKeyNss(pubkey.Pass(), CryptoData(spki_data))); | 497 new PublicKeyNss(pubkey.Pass(), CryptoData(spki_data))); |
| 498 | 498 |
| 499 *key = blink::WebCryptoKey::create(key_handle.release(), | 499 *key = blink::WebCryptoKey::create(key_handle.release(), |
| 500 blink::WebCryptoKeyTypePublic, | 500 blink::WebCryptoKeyTypePublic, |
| 501 extractable, | 501 extractable, |
| 502 key_algorithm, | 502 key_algorithm, |
| 503 usage_mask); | 503 usages); |
| 504 return Status::Success(); | 504 return Status::Success(); |
| 505 } | 505 } |
| 506 | 506 |
| 507 } // namespace | 507 } // namespace |
| 508 | 508 |
| 509 Status RsaHashedAlgorithm::GenerateKey( | 509 Status RsaHashedAlgorithm::GenerateKey( |
| 510 const blink::WebCryptoAlgorithm& algorithm, | 510 const blink::WebCryptoAlgorithm& algorithm, |
| 511 bool extractable, | 511 bool extractable, |
| 512 blink::WebCryptoKeyUsageMask combined_usage_mask, | 512 blink::WebCryptoKeyUsageMask combined_usages, |
| 513 GenerateKeyResult* result) const { | 513 GenerateKeyResult* result) const { |
| 514 Status status = CheckKeyCreationUsages( | 514 Status status = CheckKeyCreationUsages( |
| 515 all_public_key_usages_ | all_private_key_usages_, combined_usage_mask); | 515 all_public_key_usages_ | all_private_key_usages_, combined_usages); |
| 516 if (status.IsError()) | 516 if (status.IsError()) |
| 517 return status; | 517 return status; |
| 518 | 518 |
| 519 const blink::WebCryptoKeyUsageMask public_usage_mask = | 519 const blink::WebCryptoKeyUsageMask public_usages = |
| 520 combined_usage_mask & all_public_key_usages_; | 520 combined_usages & all_public_key_usages_; |
| 521 const blink::WebCryptoKeyUsageMask private_usage_mask = | 521 const blink::WebCryptoKeyUsageMask private_usages = |
| 522 combined_usage_mask & all_private_key_usages_; | 522 combined_usages & all_private_key_usages_; |
| 523 | 523 |
| 524 unsigned int public_exponent = 0; | 524 unsigned int public_exponent = 0; |
| 525 unsigned int modulus_length_bits = 0; | 525 unsigned int modulus_length_bits = 0; |
| 526 status = GetRsaKeyGenParameters(algorithm.rsaHashedKeyGenParams(), | 526 status = GetRsaKeyGenParameters(algorithm.rsaHashedKeyGenParams(), |
| 527 &public_exponent, | 527 &public_exponent, |
| 528 &modulus_length_bits); | 528 &modulus_length_bits); |
| 529 if (status.IsError()) | 529 if (status.IsError()) |
| 530 return status; | 530 return status; |
| 531 | 531 |
| 532 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 532 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 return status; | 583 return status; |
| 584 | 584 |
| 585 scoped_ptr<PrivateKeyNss> private_key_handle( | 585 scoped_ptr<PrivateKeyNss> private_key_handle( |
| 586 new PrivateKeyNss(scoped_sec_private_key.Pass(), CryptoData(pkcs8_data))); | 586 new PrivateKeyNss(scoped_sec_private_key.Pass(), CryptoData(pkcs8_data))); |
| 587 | 587 |
| 588 blink::WebCryptoKey public_key = | 588 blink::WebCryptoKey public_key = |
| 589 blink::WebCryptoKey::create(public_key_handle.release(), | 589 blink::WebCryptoKey::create(public_key_handle.release(), |
| 590 blink::WebCryptoKeyTypePublic, | 590 blink::WebCryptoKeyTypePublic, |
| 591 true, | 591 true, |
| 592 key_algorithm, | 592 key_algorithm, |
| 593 public_usage_mask); | 593 public_usages); |
| 594 | 594 |
| 595 blink::WebCryptoKey private_key = | 595 blink::WebCryptoKey private_key = |
| 596 blink::WebCryptoKey::create(private_key_handle.release(), | 596 blink::WebCryptoKey::create(private_key_handle.release(), |
| 597 blink::WebCryptoKeyTypePrivate, | 597 blink::WebCryptoKeyTypePrivate, |
| 598 extractable, | 598 extractable, |
| 599 key_algorithm, | 599 key_algorithm, |
| 600 private_usage_mask); | 600 private_usages); |
| 601 | 601 |
| 602 result->AssignKeyPair(public_key, private_key); | 602 result->AssignKeyPair(public_key, private_key); |
| 603 return Status::Success(); | 603 return Status::Success(); |
| 604 } | 604 } |
| 605 | 605 |
| 606 Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey( | 606 Status RsaHashedAlgorithm::VerifyKeyUsagesBeforeImportKey( |
| 607 blink::WebCryptoKeyFormat format, | 607 blink::WebCryptoKeyFormat format, |
| 608 blink::WebCryptoKeyUsageMask usage_mask) const { | 608 blink::WebCryptoKeyUsageMask usages) const { |
| 609 switch (format) { | 609 switch (format) { |
| 610 case blink::WebCryptoKeyFormatSpki: | 610 case blink::WebCryptoKeyFormatSpki: |
| 611 return CheckKeyCreationUsages(all_public_key_usages_, usage_mask); | 611 return CheckKeyCreationUsages(all_public_key_usages_, usages); |
| 612 case blink::WebCryptoKeyFormatPkcs8: | 612 case blink::WebCryptoKeyFormatPkcs8: |
| 613 return CheckKeyCreationUsages(all_private_key_usages_, usage_mask); | 613 return CheckKeyCreationUsages(all_private_key_usages_, usages); |
| 614 case blink::WebCryptoKeyFormatJwk: | 614 case blink::WebCryptoKeyFormatJwk: |
| 615 return CheckKeyCreationUsages( | 615 return CheckKeyCreationUsages( |
| 616 all_public_key_usages_ | all_private_key_usages_, usage_mask); | 616 all_public_key_usages_ | all_private_key_usages_, usages); |
| 617 default: | 617 default: |
| 618 return Status::ErrorUnsupportedImportKeyFormat(); | 618 return Status::ErrorUnsupportedImportKeyFormat(); |
| 619 } | 619 } |
| 620 } | 620 } |
| 621 | 621 |
| 622 Status RsaHashedAlgorithm::ImportKeyPkcs8( | 622 Status RsaHashedAlgorithm::ImportKeyPkcs8( |
| 623 const CryptoData& key_data, | 623 const CryptoData& key_data, |
| 624 const blink::WebCryptoAlgorithm& algorithm, | 624 const blink::WebCryptoAlgorithm& algorithm, |
| 625 bool extractable, | 625 bool extractable, |
| 626 blink::WebCryptoKeyUsageMask usage_mask, | 626 blink::WebCryptoKeyUsageMask usages, |
| 627 blink::WebCryptoKey* key) const { | 627 blink::WebCryptoKey* key) const { |
| 628 Status status = NssSupportsRsaPrivateKeyImport(); | 628 Status status = NssSupportsRsaPrivateKeyImport(); |
| 629 if (status.IsError()) | 629 if (status.IsError()) |
| 630 return status; | 630 return status; |
| 631 | 631 |
| 632 if (!key_data.byte_length()) | 632 if (!key_data.byte_length()) |
| 633 return Status::ErrorImportEmptyKeyData(); | 633 return Status::ErrorImportEmptyKeyData(); |
| 634 | 634 |
| 635 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8 | 635 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 PKCS#8 |
| 636 // private key info object. | 636 // private key info object. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 if (status.IsError()) | 671 if (status.IsError()) |
| 672 return status; | 672 return status; |
| 673 | 673 |
| 674 scoped_ptr<PrivateKeyNss> key_handle( | 674 scoped_ptr<PrivateKeyNss> key_handle( |
| 675 new PrivateKeyNss(private_key.Pass(), CryptoData(pkcs8_data))); | 675 new PrivateKeyNss(private_key.Pass(), CryptoData(pkcs8_data))); |
| 676 | 676 |
| 677 *key = blink::WebCryptoKey::create(key_handle.release(), | 677 *key = blink::WebCryptoKey::create(key_handle.release(), |
| 678 blink::WebCryptoKeyTypePrivate, | 678 blink::WebCryptoKeyTypePrivate, |
| 679 extractable, | 679 extractable, |
| 680 key_algorithm, | 680 key_algorithm, |
| 681 usage_mask); | 681 usages); |
| 682 | 682 |
| 683 return Status::Success(); | 683 return Status::Success(); |
| 684 } | 684 } |
| 685 | 685 |
| 686 Status RsaHashedAlgorithm::ImportKeySpki( | 686 Status RsaHashedAlgorithm::ImportKeySpki( |
| 687 const CryptoData& key_data, | 687 const CryptoData& key_data, |
| 688 const blink::WebCryptoAlgorithm& algorithm, | 688 const blink::WebCryptoAlgorithm& algorithm, |
| 689 bool extractable, | 689 bool extractable, |
| 690 blink::WebCryptoKeyUsageMask usage_mask, | 690 blink::WebCryptoKeyUsageMask usages, |
| 691 blink::WebCryptoKey* key) const { | 691 blink::WebCryptoKey* key) const { |
| 692 if (!key_data.byte_length()) | 692 if (!key_data.byte_length()) |
| 693 return Status::ErrorImportEmptyKeyData(); | 693 return Status::ErrorImportEmptyKeyData(); |
| 694 | 694 |
| 695 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject | 695 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject |
| 696 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. | 696 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. |
| 697 SECItem spki_item = MakeSECItemForBuffer(key_data); | 697 SECItem spki_item = MakeSECItemForBuffer(key_data); |
| 698 const ScopedCERTSubjectPublicKeyInfo spki( | 698 const ScopedCERTSubjectPublicKeyInfo spki( |
| 699 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); | 699 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); |
| 700 if (!spki) | 700 if (!spki) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 724 if (status.IsError()) | 724 if (status.IsError()) |
| 725 return status; | 725 return status; |
| 726 | 726 |
| 727 scoped_ptr<PublicKeyNss> key_handle( | 727 scoped_ptr<PublicKeyNss> key_handle( |
| 728 new PublicKeyNss(sec_public_key.Pass(), CryptoData(spki_data))); | 728 new PublicKeyNss(sec_public_key.Pass(), CryptoData(spki_data))); |
| 729 | 729 |
| 730 *key = blink::WebCryptoKey::create(key_handle.release(), | 730 *key = blink::WebCryptoKey::create(key_handle.release(), |
| 731 blink::WebCryptoKeyTypePublic, | 731 blink::WebCryptoKeyTypePublic, |
| 732 extractable, | 732 extractable, |
| 733 key_algorithm, | 733 key_algorithm, |
| 734 usage_mask); | 734 usages); |
| 735 | 735 |
| 736 return Status::Success(); | 736 return Status::Success(); |
| 737 } | 737 } |
| 738 | 738 |
| 739 Status RsaHashedAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key, | 739 Status RsaHashedAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key, |
| 740 std::vector<uint8_t>* buffer) const { | 740 std::vector<uint8_t>* buffer) const { |
| 741 if (key.type() != blink::WebCryptoKeyTypePrivate) | 741 if (key.type() != blink::WebCryptoKeyTypePrivate) |
| 742 return Status::ErrorUnexpectedKeyType(); | 742 return Status::ErrorUnexpectedKeyType(); |
| 743 *buffer = PrivateKeyNss::Cast(key)->pkcs8_data(); | 743 *buffer = PrivateKeyNss::Cast(key)->pkcs8_data(); |
| 744 return Status::Success(); | 744 return Status::Success(); |
| 745 } | 745 } |
| 746 | 746 |
| 747 Status RsaHashedAlgorithm::ExportKeySpki(const blink::WebCryptoKey& key, | 747 Status RsaHashedAlgorithm::ExportKeySpki(const blink::WebCryptoKey& key, |
| 748 std::vector<uint8_t>* buffer) const { | 748 std::vector<uint8_t>* buffer) const { |
| 749 if (key.type() != blink::WebCryptoKeyTypePublic) | 749 if (key.type() != blink::WebCryptoKeyTypePublic) |
| 750 return Status::ErrorUnexpectedKeyType(); | 750 return Status::ErrorUnexpectedKeyType(); |
| 751 *buffer = PublicKeyNss::Cast(key)->spki_data(); | 751 *buffer = PublicKeyNss::Cast(key)->spki_data(); |
| 752 return Status::Success(); | 752 return Status::Success(); |
| 753 } | 753 } |
| 754 | 754 |
| 755 Status RsaHashedAlgorithm::ImportKeyJwk( | 755 Status RsaHashedAlgorithm::ImportKeyJwk( |
| 756 const CryptoData& key_data, | 756 const CryptoData& key_data, |
| 757 const blink::WebCryptoAlgorithm& algorithm, | 757 const blink::WebCryptoAlgorithm& algorithm, |
| 758 bool extractable, | 758 bool extractable, |
| 759 blink::WebCryptoKeyUsageMask usage_mask, | 759 blink::WebCryptoKeyUsageMask usages, |
| 760 blink::WebCryptoKey* key) const { | 760 blink::WebCryptoKey* key) const { |
| 761 const char* jwk_algorithm = | 761 const char* jwk_algorithm = |
| 762 GetJwkAlgorithm(algorithm.rsaHashedImportParams()->hash().id()); | 762 GetJwkAlgorithm(algorithm.rsaHashedImportParams()->hash().id()); |
| 763 | 763 |
| 764 if (!jwk_algorithm) | 764 if (!jwk_algorithm) |
| 765 return Status::ErrorUnexpected(); | 765 return Status::ErrorUnexpected(); |
| 766 | 766 |
| 767 JwkRsaInfo jwk; | 767 JwkRsaInfo jwk; |
| 768 Status status = | 768 Status status = |
| 769 ReadRsaKeyJwk(key_data, jwk_algorithm, extractable, usage_mask, &jwk); | 769 ReadRsaKeyJwk(key_data, jwk_algorithm, extractable, usages, &jwk); |
| 770 if (status.IsError()) | 770 if (status.IsError()) |
| 771 return status; | 771 return status; |
| 772 | 772 |
| 773 // Once the key type is known, verify the usages. | 773 // Once the key type is known, verify the usages. |
| 774 status = CheckKeyCreationUsages( | 774 status = CheckKeyCreationUsages( |
| 775 jwk.is_private_key ? all_private_key_usages_ : all_public_key_usages_, | 775 jwk.is_private_key ? all_private_key_usages_ : all_public_key_usages_, |
| 776 usage_mask); | 776 usages); |
| 777 if (status.IsError()) | 777 if (status.IsError()) |
| 778 return Status::ErrorCreateKeyBadUsages(); | 778 return Status::ErrorCreateKeyBadUsages(); |
| 779 | 779 |
| 780 return jwk.is_private_key | 780 return jwk.is_private_key |
| 781 ? ImportRsaPrivateKey(algorithm, extractable, usage_mask, jwk, key) | 781 ? ImportRsaPrivateKey(algorithm, extractable, usages, jwk, key) |
| 782 : ImportRsaPublicKey(algorithm, | 782 : ImportRsaPublicKey(algorithm, |
| 783 extractable, | 783 extractable, |
| 784 usage_mask, | 784 usages, |
| 785 CryptoData(jwk.n), | 785 CryptoData(jwk.n), |
| 786 CryptoData(jwk.e), | 786 CryptoData(jwk.e), |
| 787 key); | 787 key); |
| 788 } | 788 } |
| 789 | 789 |
| 790 Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key, | 790 Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key, |
| 791 std::vector<uint8_t>* buffer) const { | 791 std::vector<uint8_t>* buffer) const { |
| 792 const char* jwk_algorithm = | 792 const char* jwk_algorithm = |
| 793 GetJwkAlgorithm(key.algorithm().rsaHashedParams()->hash().id()); | 793 GetJwkAlgorithm(key.algorithm().rsaHashedParams()->hash().id()); |
| 794 | 794 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 return Status::Success(); | 835 return Status::Success(); |
| 836 } | 836 } |
| 837 default: | 837 default: |
| 838 return Status::ErrorUnexpected(); | 838 return Status::ErrorUnexpected(); |
| 839 } | 839 } |
| 840 } | 840 } |
| 841 | 841 |
| 842 } // namespace webcrypto | 842 } // namespace webcrypto |
| 843 | 843 |
| 844 } // namespace content | 844 } // namespace content |
| OLD | NEW |