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/jwk.h" | 9 #include "content/child/webcrypto/jwk.h" |
10 #include "content/child/webcrypto/nss/key_nss.h" | 10 #include "content/child/webcrypto/nss/key_nss.h" |
11 #include "content/child/webcrypto/nss/util_nss.h" | 11 #include "content/child/webcrypto/nss/util_nss.h" |
12 #include "content/child/webcrypto/status.h" | 12 #include "content/child/webcrypto/status.h" |
13 #include "content/child/webcrypto/webcrypto_util.h" | 13 #include "content/child/webcrypto/webcrypto_util.h" |
14 #include "crypto/scoped_nss_types.h" | 14 #include "crypto/scoped_nss_types.h" |
15 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 15 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
16 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 16 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
17 | 17 |
18 namespace content { | 18 namespace content { |
19 | 19 |
20 namespace webcrypto { | 20 namespace webcrypto { |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, | 24 // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, |
25 // to unsigned long. | 25 // to unsigned long. |
26 bool BigIntegerToLong(const uint8* data, | 26 bool BigIntegerToLong(const uint8_t* data, |
27 unsigned int data_size, | 27 unsigned int data_size, |
28 unsigned long* result) { | 28 unsigned long* result) { |
29 // TODO(eroman): Fix handling of empty biginteger. http://crubg.com/373552 | 29 // TODO(eroman): Fix handling of empty biginteger. http://crubg.com/373552 |
30 if (data_size == 0) | 30 if (data_size == 0) |
31 return false; | 31 return false; |
32 | 32 |
33 *result = 0; | 33 *result = 0; |
34 for (size_t i = 0; i < data_size; ++i) { | 34 for (size_t i = 0; i < data_size; ++i) { |
35 size_t reverse_i = data_size - i - 1; | 35 size_t reverse_i = data_size - i - 1; |
36 | 36 |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 data.byte_length()}; | 303 data.byte_length()}; |
304 templ->push_back(attribute); | 304 templ->push_back(attribute); |
305 } | 305 } |
306 | 306 |
307 void AddOptionalAttribute(CK_ATTRIBUTE_TYPE type, | 307 void AddOptionalAttribute(CK_ATTRIBUTE_TYPE type, |
308 const std::string& data, | 308 const std::string& data, |
309 std::vector<CK_ATTRIBUTE>* templ) { | 309 std::vector<CK_ATTRIBUTE>* templ) { |
310 AddOptionalAttribute(type, CryptoData(data), templ); | 310 AddOptionalAttribute(type, CryptoData(data), templ); |
311 } | 311 } |
312 | 312 |
313 Status ExportKeyPkcs8Nss(SECKEYPrivateKey* key, std::vector<uint8>* buffer) { | 313 Status ExportKeyPkcs8Nss(SECKEYPrivateKey* key, std::vector<uint8_t>* buffer) { |
314 if (key->keyType != rsaKey) | 314 if (key->keyType != rsaKey) |
315 return Status::ErrorUnsupported(); | 315 return Status::ErrorUnsupported(); |
316 | 316 |
317 // TODO(rsleevi): Implement OAEP support according to the spec. | 317 // TODO(rsleevi): Implement OAEP support according to the spec. |
318 | 318 |
319 #if defined(USE_NSS) | 319 #if defined(USE_NSS) |
320 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code. | 320 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code. |
321 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; | 321 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; |
322 const int kPrivateKeyInfoVersion = 0; | 322 const int kPrivateKeyInfoVersion = 0; |
323 | 323 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 crypto::ScopedSECKEYPrivateKey private_key( | 445 crypto::ScopedSECKEYPrivateKey private_key( |
446 SECKEY_CopyPrivateKey(private_key_tmp.get())); | 446 SECKEY_CopyPrivateKey(private_key_tmp.get())); |
447 | 447 |
448 if (!private_key) | 448 if (!private_key) |
449 return Status::OperationError(); | 449 return Status::OperationError(); |
450 | 450 |
451 blink::WebCryptoKeyAlgorithm key_algorithm; | 451 blink::WebCryptoKeyAlgorithm key_algorithm; |
452 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) | 452 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) |
453 return Status::ErrorUnexpected(); | 453 return Status::ErrorUnexpected(); |
454 | 454 |
455 std::vector<uint8> pkcs8_data; | 455 std::vector<uint8_t> pkcs8_data; |
456 status = ExportKeyPkcs8Nss(private_key.get(), &pkcs8_data); | 456 status = ExportKeyPkcs8Nss(private_key.get(), &pkcs8_data); |
457 if (status.IsError()) | 457 if (status.IsError()) |
458 return status; | 458 return status; |
459 | 459 |
460 scoped_ptr<PrivateKeyNss> key_handle( | 460 scoped_ptr<PrivateKeyNss> key_handle( |
461 new PrivateKeyNss(private_key.Pass(), CryptoData(pkcs8_data))); | 461 new PrivateKeyNss(private_key.Pass(), CryptoData(pkcs8_data))); |
462 | 462 |
463 *key = blink::WebCryptoKey::create(key_handle.release(), | 463 *key = blink::WebCryptoKey::create(key_handle.release(), |
464 blink::WebCryptoKeyTypePrivate, | 464 blink::WebCryptoKeyTypePrivate, |
465 extractable, | 465 extractable, |
466 key_algorithm, | 466 key_algorithm, |
467 usage_mask); | 467 usage_mask); |
468 return Status::Success(); | 468 return Status::Success(); |
469 } | 469 } |
470 | 470 |
471 Status ExportKeySpkiNss(SECKEYPublicKey* key, std::vector<uint8>* buffer) { | 471 Status ExportKeySpkiNss(SECKEYPublicKey* key, std::vector<uint8_t>* buffer) { |
472 const crypto::ScopedSECItem spki_der( | 472 const crypto::ScopedSECItem spki_der( |
473 SECKEY_EncodeDERSubjectPublicKeyInfo(key)); | 473 SECKEY_EncodeDERSubjectPublicKeyInfo(key)); |
474 if (!spki_der) | 474 if (!spki_der) |
475 return Status::OperationError(); | 475 return Status::OperationError(); |
476 | 476 |
477 buffer->assign(spki_der->data, spki_der->data + spki_der->len); | 477 buffer->assign(spki_der->data, spki_der->data + spki_der->len); |
478 return Status::Success(); | 478 return Status::Success(); |
479 } | 479 } |
480 | 480 |
481 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, | 481 Status ImportRsaPublicKey(const blink::WebCryptoAlgorithm& algorithm, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 // Import the DER-encoded public key to create an RSA SECKEYPublicKey. | 531 // Import the DER-encoded public key to create an RSA SECKEYPublicKey. |
532 crypto::ScopedSECKEYPublicKey pubkey( | 532 crypto::ScopedSECKEYPublicKey pubkey( |
533 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA)); | 533 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA)); |
534 if (!pubkey) | 534 if (!pubkey) |
535 return Status::OperationError(); | 535 return Status::OperationError(); |
536 | 536 |
537 blink::WebCryptoKeyAlgorithm key_algorithm; | 537 blink::WebCryptoKeyAlgorithm key_algorithm; |
538 if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm)) | 538 if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm)) |
539 return Status::ErrorUnexpected(); | 539 return Status::ErrorUnexpected(); |
540 | 540 |
541 std::vector<uint8> spki_data; | 541 std::vector<uint8_t> spki_data; |
542 Status status = ExportKeySpkiNss(pubkey.get(), &spki_data); | 542 Status status = ExportKeySpkiNss(pubkey.get(), &spki_data); |
543 if (status.IsError()) | 543 if (status.IsError()) |
544 return status; | 544 return status; |
545 | 545 |
546 scoped_ptr<PublicKeyNss> key_handle( | 546 scoped_ptr<PublicKeyNss> key_handle( |
547 new PublicKeyNss(pubkey.Pass(), CryptoData(spki_data))); | 547 new PublicKeyNss(pubkey.Pass(), CryptoData(spki_data))); |
548 | 548 |
549 *key = blink::WebCryptoKey::create(key_handle.release(), | 549 *key = blink::WebCryptoKey::create(key_handle.release(), |
550 blink::WebCryptoKeyTypePublic, | 550 blink::WebCryptoKeyTypePublic, |
551 extractable, | 551 extractable, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 generate_flags_, | 623 generate_flags_, |
624 operation_flags_mask, | 624 operation_flags_mask, |
625 NULL)); | 625 NULL)); |
626 if (!scoped_sec_private_key) | 626 if (!scoped_sec_private_key) |
627 return Status::OperationError(); | 627 return Status::OperationError(); |
628 | 628 |
629 blink::WebCryptoKeyAlgorithm key_algorithm; | 629 blink::WebCryptoKeyAlgorithm key_algorithm; |
630 if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm)) | 630 if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm)) |
631 return Status::ErrorUnexpected(); | 631 return Status::ErrorUnexpected(); |
632 | 632 |
633 std::vector<uint8> spki_data; | 633 std::vector<uint8_t> spki_data; |
634 Status status = ExportKeySpkiNss(sec_public_key, &spki_data); | 634 Status status = ExportKeySpkiNss(sec_public_key, &spki_data); |
635 if (status.IsError()) | 635 if (status.IsError()) |
636 return status; | 636 return status; |
637 | 637 |
638 scoped_ptr<PublicKeyNss> public_key_handle(new PublicKeyNss( | 638 scoped_ptr<PublicKeyNss> public_key_handle(new PublicKeyNss( |
639 crypto::ScopedSECKEYPublicKey(sec_public_key), CryptoData(spki_data))); | 639 crypto::ScopedSECKEYPublicKey(sec_public_key), CryptoData(spki_data))); |
640 | 640 |
641 std::vector<uint8> pkcs8_data; | 641 std::vector<uint8_t> pkcs8_data; |
642 status = ExportKeyPkcs8Nss(scoped_sec_private_key.get(), &pkcs8_data); | 642 status = ExportKeyPkcs8Nss(scoped_sec_private_key.get(), &pkcs8_data); |
643 if (status.IsError()) | 643 if (status.IsError()) |
644 return status; | 644 return status; |
645 | 645 |
646 scoped_ptr<PrivateKeyNss> private_key_handle( | 646 scoped_ptr<PrivateKeyNss> private_key_handle( |
647 new PrivateKeyNss(scoped_sec_private_key.Pass(), CryptoData(pkcs8_data))); | 647 new PrivateKeyNss(scoped_sec_private_key.Pass(), CryptoData(pkcs8_data))); |
648 | 648 |
649 *public_key = blink::WebCryptoKey::create(public_key_handle.release(), | 649 *public_key = blink::WebCryptoKey::create(public_key_handle.release(), |
650 blink::WebCryptoKeyTypePublic, | 650 blink::WebCryptoKeyTypePublic, |
651 true, | 651 true, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); | 712 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); |
713 if (sec_key_type != rsaKey) | 713 if (sec_key_type != rsaKey) |
714 return Status::DataError(); | 714 return Status::DataError(); |
715 | 715 |
716 blink::WebCryptoKeyAlgorithm key_algorithm; | 716 blink::WebCryptoKeyAlgorithm key_algorithm; |
717 if (!CreateRsaHashedPrivateKeyAlgorithm( | 717 if (!CreateRsaHashedPrivateKeyAlgorithm( |
718 algorithm, private_key.get(), &key_algorithm)) | 718 algorithm, private_key.get(), &key_algorithm)) |
719 return Status::ErrorUnexpected(); | 719 return Status::ErrorUnexpected(); |
720 | 720 |
721 // TODO(eroman): This is probably going to be the same as the input. | 721 // TODO(eroman): This is probably going to be the same as the input. |
722 std::vector<uint8> pkcs8_data; | 722 std::vector<uint8_t> pkcs8_data; |
723 status = ExportKeyPkcs8Nss(private_key.get(), &pkcs8_data); | 723 status = ExportKeyPkcs8Nss(private_key.get(), &pkcs8_data); |
724 if (status.IsError()) | 724 if (status.IsError()) |
725 return status; | 725 return status; |
726 | 726 |
727 scoped_ptr<PrivateKeyNss> key_handle( | 727 scoped_ptr<PrivateKeyNss> key_handle( |
728 new PrivateKeyNss(private_key.Pass(), CryptoData(pkcs8_data))); | 728 new PrivateKeyNss(private_key.Pass(), CryptoData(pkcs8_data))); |
729 | 729 |
730 *key = blink::WebCryptoKey::create(key_handle.release(), | 730 *key = blink::WebCryptoKey::create(key_handle.release(), |
731 blink::WebCryptoKeyTypePrivate, | 731 blink::WebCryptoKeyTypePrivate, |
732 extractable, | 732 extractable, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); | 765 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); |
766 if (sec_key_type != rsaKey) | 766 if (sec_key_type != rsaKey) |
767 return Status::DataError(); | 767 return Status::DataError(); |
768 | 768 |
769 blink::WebCryptoKeyAlgorithm key_algorithm; | 769 blink::WebCryptoKeyAlgorithm key_algorithm; |
770 if (!CreateRsaHashedPublicKeyAlgorithm( | 770 if (!CreateRsaHashedPublicKeyAlgorithm( |
771 algorithm, sec_public_key.get(), &key_algorithm)) | 771 algorithm, sec_public_key.get(), &key_algorithm)) |
772 return Status::ErrorUnexpected(); | 772 return Status::ErrorUnexpected(); |
773 | 773 |
774 // TODO(eroman): This is probably going to be the same as the input. | 774 // TODO(eroman): This is probably going to be the same as the input. |
775 std::vector<uint8> spki_data; | 775 std::vector<uint8_t> spki_data; |
776 status = ExportKeySpkiNss(sec_public_key.get(), &spki_data); | 776 status = ExportKeySpkiNss(sec_public_key.get(), &spki_data); |
777 if (status.IsError()) | 777 if (status.IsError()) |
778 return status; | 778 return status; |
779 | 779 |
780 scoped_ptr<PublicKeyNss> key_handle( | 780 scoped_ptr<PublicKeyNss> key_handle( |
781 new PublicKeyNss(sec_public_key.Pass(), CryptoData(spki_data))); | 781 new PublicKeyNss(sec_public_key.Pass(), CryptoData(spki_data))); |
782 | 782 |
783 *key = blink::WebCryptoKey::create(key_handle.release(), | 783 *key = blink::WebCryptoKey::create(key_handle.release(), |
784 blink::WebCryptoKeyTypePublic, | 784 blink::WebCryptoKeyTypePublic, |
785 extractable, | 785 extractable, |
786 key_algorithm, | 786 key_algorithm, |
787 usage_mask); | 787 usage_mask); |
788 | 788 |
789 return Status::Success(); | 789 return Status::Success(); |
790 } | 790 } |
791 | 791 |
792 Status RsaHashedAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key, | 792 Status RsaHashedAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key, |
793 std::vector<uint8>* buffer) const { | 793 std::vector<uint8_t>* buffer) const { |
794 if (key.type() != blink::WebCryptoKeyTypePrivate) | 794 if (key.type() != blink::WebCryptoKeyTypePrivate) |
795 return Status::ErrorUnexpectedKeyType(); | 795 return Status::ErrorUnexpectedKeyType(); |
796 *buffer = PrivateKeyNss::Cast(key)->pkcs8_data(); | 796 *buffer = PrivateKeyNss::Cast(key)->pkcs8_data(); |
797 return Status::Success(); | 797 return Status::Success(); |
798 } | 798 } |
799 | 799 |
800 Status RsaHashedAlgorithm::ExportKeySpki(const blink::WebCryptoKey& key, | 800 Status RsaHashedAlgorithm::ExportKeySpki(const blink::WebCryptoKey& key, |
801 std::vector<uint8>* buffer) const { | 801 std::vector<uint8_t>* buffer) const { |
802 if (key.type() != blink::WebCryptoKeyTypePublic) | 802 if (key.type() != blink::WebCryptoKeyTypePublic) |
803 return Status::ErrorUnexpectedKeyType(); | 803 return Status::ErrorUnexpectedKeyType(); |
804 *buffer = PublicKeyNss::Cast(key)->spki_data(); | 804 *buffer = PublicKeyNss::Cast(key)->spki_data(); |
805 return Status::Success(); | 805 return Status::Success(); |
806 } | 806 } |
807 | 807 |
808 Status RsaHashedAlgorithm::ImportKeyJwk( | 808 Status RsaHashedAlgorithm::ImportKeyJwk( |
809 const CryptoData& key_data, | 809 const CryptoData& key_data, |
810 const blink::WebCryptoAlgorithm& algorithm, | 810 const blink::WebCryptoAlgorithm& algorithm, |
811 bool extractable, | 811 bool extractable, |
(...skipping 22 matching lines...) Expand all Loading... |
834 ? ImportRsaPrivateKey(algorithm, extractable, usage_mask, jwk, key) | 834 ? ImportRsaPrivateKey(algorithm, extractable, usage_mask, jwk, key) |
835 : ImportRsaPublicKey(algorithm, | 835 : ImportRsaPublicKey(algorithm, |
836 extractable, | 836 extractable, |
837 usage_mask, | 837 usage_mask, |
838 CryptoData(jwk.n), | 838 CryptoData(jwk.n), |
839 CryptoData(jwk.e), | 839 CryptoData(jwk.e), |
840 key); | 840 key); |
841 } | 841 } |
842 | 842 |
843 Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key, | 843 Status RsaHashedAlgorithm::ExportKeyJwk(const blink::WebCryptoKey& key, |
844 std::vector<uint8>* buffer) const { | 844 std::vector<uint8_t>* buffer) const { |
845 const char* jwk_algorithm = | 845 const char* jwk_algorithm = |
846 GetJwkAlgorithm(key.algorithm().rsaHashedParams()->hash().id()); | 846 GetJwkAlgorithm(key.algorithm().rsaHashedParams()->hash().id()); |
847 | 847 |
848 if (!jwk_algorithm) | 848 if (!jwk_algorithm) |
849 return Status::ErrorUnexpected(); | 849 return Status::ErrorUnexpected(); |
850 | 850 |
851 switch (key.type()) { | 851 switch (key.type()) { |
852 case blink::WebCryptoKeyTypePublic: { | 852 case blink::WebCryptoKeyTypePublic: { |
853 SECKEYPublicKey* nss_key = PublicKeyNss::Cast(key)->key(); | 853 SECKEYPublicKey* nss_key = PublicKeyNss::Cast(key)->key(); |
854 if (nss_key->keyType != rsaKey) | 854 if (nss_key->keyType != rsaKey) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 return Status::Success(); | 888 return Status::Success(); |
889 } | 889 } |
890 default: | 890 default: |
891 return Status::ErrorUnexpected(); | 891 return Status::ErrorUnexpected(); |
892 } | 892 } |
893 } | 893 } |
894 | 894 |
895 } // namespace webcrypto | 895 } // namespace webcrypto |
896 | 896 |
897 } // namespace content | 897 } // namespace content |
OLD | NEW |