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 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 return Status::Success(); | 548 return Status::Success(); |
549 } | 549 } |
550 | 550 |
551 namespace { | 551 namespace { |
552 | 552 |
553 typedef scoped_ptr<CERTSubjectPublicKeyInfo, | 553 typedef scoped_ptr<CERTSubjectPublicKeyInfo, |
554 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo, | 554 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo, |
555 SECKEY_DestroySubjectPublicKeyInfo> > | 555 SECKEY_DestroySubjectPublicKeyInfo> > |
556 ScopedCERTSubjectPublicKeyInfo; | 556 ScopedCERTSubjectPublicKeyInfo; |
557 | 557 |
558 // Validates an NSS KeyType against a WebCrypto algorithm. Some NSS KeyTypes | 558 // Validates an NSS KeyType against a WebCrypto import algorithm. |
559 // contain enough information to fabricate a Web Crypto algorithm, which is | 559 bool ValidateNssKeyTypeAgainstInputAlgorithm( |
560 // returned if the input algorithm isNull(). This function indicates failure by | |
561 // returning a Null algorithm. | |
562 blink::WebCryptoAlgorithm ResolveNssKeyTypeWithInputAlgorithm( | |
563 KeyType key_type, | 560 KeyType key_type, |
564 const blink::WebCryptoAlgorithm& algorithm_or_null) { | 561 const blink::WebCryptoAlgorithm& algorithm) { |
565 switch (key_type) { | 562 switch (key_type) { |
566 case rsaKey: | 563 case rsaKey: |
567 // NSS's rsaKey KeyType maps to keys with SEC_OID_PKCS1_RSA_ENCRYPTION and | 564 return IsAlgorithmRsa(algorithm); |
568 // according to RFCs 4055/5756 this can be used for both encryption and | |
569 // signatures. However, this is not specific enough to build a compatible | |
570 // Web Crypto algorithm, since in Web Crypto, RSA encryption and signature | |
571 // algorithms are distinct. So if the input algorithm isNull() here, we | |
572 // have to fail. | |
573 if (!algorithm_or_null.isNull() && IsAlgorithmRsa(algorithm_or_null)) | |
574 return algorithm_or_null; | |
575 break; | |
576 case dsaKey: | 565 case dsaKey: |
577 case ecKey: | 566 case ecKey: |
578 case rsaPssKey: | 567 case rsaPssKey: |
579 case rsaOaepKey: | 568 case rsaOaepKey: |
580 // TODO(padolph): Handle other key types. | 569 // TODO(padolph): Handle other key types. |
581 break; | 570 break; |
582 default: | 571 default: |
583 break; | 572 break; |
584 } | 573 } |
585 return blink::WebCryptoAlgorithm::createNull(); | 574 return false; |
586 } | 575 } |
587 | 576 |
588 } // namespace | 577 } // namespace |
589 | 578 |
590 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm_or_null, | 579 Status ImportKeySpki(const blink::WebCryptoAlgorithm& algorithm, |
591 const CryptoData& key_data, | 580 const CryptoData& key_data, |
592 bool extractable, | 581 bool extractable, |
593 blink::WebCryptoKeyUsageMask usage_mask, | 582 blink::WebCryptoKeyUsageMask usage_mask, |
594 blink::WebCryptoKey* key) { | 583 blink::WebCryptoKey* key) { |
595 | 584 |
596 DCHECK(key); | 585 DCHECK(key); |
597 | 586 |
598 if (!key_data.byte_length()) | 587 if (!key_data.byte_length()) |
599 return Status::ErrorImportEmptyKeyData(); | 588 return Status::ErrorImportEmptyKeyData(); |
600 DCHECK(key_data.bytes()); | 589 DCHECK(key_data.bytes()); |
601 | 590 |
602 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject | 591 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject |
603 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. | 592 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. |
604 SECItem spki_item = MakeSECItemForBuffer(key_data); | 593 SECItem spki_item = MakeSECItemForBuffer(key_data); |
605 const ScopedCERTSubjectPublicKeyInfo spki( | 594 const ScopedCERTSubjectPublicKeyInfo spki( |
606 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); | 595 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); |
607 if (!spki) | 596 if (!spki) |
608 return Status::Error(); | 597 return Status::Error(); |
609 | 598 |
610 crypto::ScopedSECKEYPublicKey sec_public_key( | 599 crypto::ScopedSECKEYPublicKey sec_public_key( |
611 SECKEY_ExtractPublicKey(spki.get())); | 600 SECKEY_ExtractPublicKey(spki.get())); |
612 if (!sec_public_key) | 601 if (!sec_public_key) |
613 return Status::Error(); | 602 return Status::Error(); |
614 | 603 |
615 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); | 604 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); |
616 blink::WebCryptoAlgorithm algorithm = | 605 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) |
617 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); | |
618 if (algorithm.isNull()) | |
619 return Status::Error(); | 606 return Status::Error(); |
620 | 607 |
621 blink::WebCryptoKeyAlgorithm key_algorithm; | 608 blink::WebCryptoKeyAlgorithm key_algorithm; |
622 if (!CreatePublicKeyAlgorithm( | 609 if (!CreatePublicKeyAlgorithm( |
623 algorithm, sec_public_key.get(), &key_algorithm)) | 610 algorithm, sec_public_key.get(), &key_algorithm)) |
624 return Status::ErrorUnexpected(); | 611 return Status::ErrorUnexpected(); |
625 | 612 |
626 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), | 613 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), |
627 blink::WebCryptoKeyTypePublic, | 614 blink::WebCryptoKeyTypePublic, |
628 extractable, | 615 extractable, |
(...skipping 10 matching lines...) Expand all Loading... |
639 return Status::Error(); | 626 return Status::Error(); |
640 | 627 |
641 DCHECK(spki_der->data); | 628 DCHECK(spki_der->data); |
642 DCHECK(spki_der->len); | 629 DCHECK(spki_der->len); |
643 | 630 |
644 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); | 631 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); |
645 | 632 |
646 return Status::Success(); | 633 return Status::Success(); |
647 } | 634 } |
648 | 635 |
649 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm_or_null, | 636 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm, |
650 const CryptoData& key_data, | 637 const CryptoData& key_data, |
651 bool extractable, | 638 bool extractable, |
652 blink::WebCryptoKeyUsageMask usage_mask, | 639 blink::WebCryptoKeyUsageMask usage_mask, |
653 blink::WebCryptoKey* key) { | 640 blink::WebCryptoKey* key) { |
654 | 641 |
655 DCHECK(key); | 642 DCHECK(key); |
656 | 643 |
657 if (!key_data.byte_length()) | 644 if (!key_data.byte_length()) |
658 return Status::ErrorImportEmptyKeyData(); | 645 return Status::ErrorImportEmptyKeyData(); |
659 DCHECK(key_data.bytes()); | 646 DCHECK(key_data.bytes()); |
(...skipping 12 matching lines...) Expand all Loading... |
672 false, // isPrivate | 659 false, // isPrivate |
673 KU_ALL, // usage | 660 KU_ALL, // usage |
674 &seckey_private_key, | 661 &seckey_private_key, |
675 NULL) != SECSuccess) { | 662 NULL) != SECSuccess) { |
676 return Status::Error(); | 663 return Status::Error(); |
677 } | 664 } |
678 DCHECK(seckey_private_key); | 665 DCHECK(seckey_private_key); |
679 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); | 666 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); |
680 | 667 |
681 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); | 668 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); |
682 blink::WebCryptoAlgorithm algorithm = | 669 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) |
683 ResolveNssKeyTypeWithInputAlgorithm(sec_key_type, algorithm_or_null); | |
684 if (algorithm.isNull()) | |
685 return Status::Error(); | 670 return Status::Error(); |
686 | 671 |
687 blink::WebCryptoKeyAlgorithm key_algorithm; | 672 blink::WebCryptoKeyAlgorithm key_algorithm; |
688 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) | 673 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) |
689 return Status::ErrorUnexpected(); | 674 return Status::ErrorUnexpected(); |
690 | 675 |
691 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), | 676 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), |
692 blink::WebCryptoKeyTypePrivate, | 677 blink::WebCryptoKeyTypePrivate, |
693 extractable, | 678 extractable, |
694 key_algorithm, | 679 key_algorithm, |
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 key_algorithm, | 1215 key_algorithm, |
1231 usage_mask); | 1216 usage_mask); |
1232 return Status::Success(); | 1217 return Status::Success(); |
1233 } | 1218 } |
1234 | 1219 |
1235 } // namespace platform | 1220 } // namespace platform |
1236 | 1221 |
1237 } // namespace webcrypto | 1222 } // namespace webcrypto |
1238 | 1223 |
1239 } // namespace content | 1224 } // namespace content |
OLD | NEW |