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 |