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 <secerr.h> | 9 #include <secerr.h> |
10 #include <sechash.h> | 10 #include <sechash.h> |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 SymKey* key, | 218 SymKey* key, |
219 const CryptoData& iv, | 219 const CryptoData& iv, |
220 const CryptoData& data, | 220 const CryptoData& data, |
221 blink::WebArrayBuffer* buffer) { | 221 blink::WebArrayBuffer* buffer) { |
222 CK_ATTRIBUTE_TYPE operation = (mode == ENCRYPT) ? CKA_ENCRYPT : CKA_DECRYPT; | 222 CK_ATTRIBUTE_TYPE operation = (mode == ENCRYPT) ? CKA_ENCRYPT : CKA_DECRYPT; |
223 | 223 |
224 SECItem iv_item = MakeSECItemForBuffer(iv); | 224 SECItem iv_item = MakeSECItemForBuffer(iv); |
225 | 225 |
226 crypto::ScopedSECItem param(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item)); | 226 crypto::ScopedSECItem param(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item)); |
227 if (!param) | 227 if (!param) |
228 return Status::Error(); | 228 return Status::OperationError(); |
229 | 229 |
230 crypto::ScopedPK11Context context(PK11_CreateContextBySymKey( | 230 crypto::ScopedPK11Context context(PK11_CreateContextBySymKey( |
231 CKM_AES_CBC_PAD, operation, key->key(), param.get())); | 231 CKM_AES_CBC_PAD, operation, key->key(), param.get())); |
232 | 232 |
233 if (!context.get()) | 233 if (!context.get()) |
234 return Status::Error(); | 234 return Status::OperationError(); |
235 | 235 |
236 // Oddly PK11_CipherOp takes input and output lengths as "int" rather than | 236 // Oddly PK11_CipherOp takes input and output lengths as "int" rather than |
237 // "unsigned int". Do some checks now to avoid integer overflowing. | 237 // "unsigned int". Do some checks now to avoid integer overflowing. |
238 if (data.byte_length() >= INT_MAX - AES_BLOCK_SIZE) { | 238 if (data.byte_length() >= INT_MAX - AES_BLOCK_SIZE) { |
239 // TODO(eroman): Handle this by chunking the input fed into NSS. Right now | 239 // TODO(eroman): Handle this by chunking the input fed into NSS. Right now |
240 // it doesn't make much difference since the one-shot API would end up | 240 // it doesn't make much difference since the one-shot API would end up |
241 // blowing out the memory and crashing anyway. | 241 // blowing out the memory and crashing anyway. |
242 return Status::ErrorDataTooLarge(); | 242 return Status::ErrorDataTooLarge(); |
243 } | 243 } |
244 | 244 |
245 // PK11_CipherOp does an invalid memory access when given empty decryption | 245 // PK11_CipherOp does an invalid memory access when given empty decryption |
246 // input, or input which is not a multiple of the block size. See also | 246 // input, or input which is not a multiple of the block size. See also |
247 // https://bugzilla.mozilla.com/show_bug.cgi?id=921687. | 247 // https://bugzilla.mozilla.com/show_bug.cgi?id=921687. |
248 if (operation == CKA_DECRYPT && | 248 if (operation == CKA_DECRYPT && |
249 (data.byte_length() == 0 || (data.byte_length() % AES_BLOCK_SIZE != 0))) { | 249 (data.byte_length() == 0 || (data.byte_length() % AES_BLOCK_SIZE != 0))) { |
250 return Status::Error(); | 250 return Status::OperationError(); |
251 } | 251 } |
252 | 252 |
253 // TODO(eroman): Refine the output buffer size. It can be computed exactly for | 253 // TODO(eroman): Refine the output buffer size. It can be computed exactly for |
254 // encryption, and can be smaller for decryption. | 254 // encryption, and can be smaller for decryption. |
255 unsigned int output_max_len = data.byte_length() + AES_BLOCK_SIZE; | 255 unsigned int output_max_len = data.byte_length() + AES_BLOCK_SIZE; |
256 CHECK_GT(output_max_len, data.byte_length()); | 256 CHECK_GT(output_max_len, data.byte_length()); |
257 | 257 |
258 *buffer = blink::WebArrayBuffer::create(output_max_len, 1); | 258 *buffer = blink::WebArrayBuffer::create(output_max_len, 1); |
259 | 259 |
260 unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data()); | 260 unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data()); |
261 | 261 |
262 int output_len; | 262 int output_len; |
263 if (SECSuccess != PK11_CipherOp(context.get(), | 263 if (SECSuccess != PK11_CipherOp(context.get(), |
264 buffer_data, | 264 buffer_data, |
265 &output_len, | 265 &output_len, |
266 buffer->byteLength(), | 266 buffer->byteLength(), |
267 data.bytes(), | 267 data.bytes(), |
268 data.byte_length())) { | 268 data.byte_length())) { |
269 return Status::Error(); | 269 return Status::OperationError(); |
270 } | 270 } |
271 | 271 |
272 unsigned int final_output_chunk_len; | 272 unsigned int final_output_chunk_len; |
273 if (SECSuccess != PK11_DigestFinal(context.get(), | 273 if (SECSuccess != PK11_DigestFinal(context.get(), |
274 buffer_data + output_len, | 274 buffer_data + output_len, |
275 &final_output_chunk_len, | 275 &final_output_chunk_len, |
276 output_max_len - output_len)) { | 276 output_max_len - output_len)) { |
277 return Status::Error(); | 277 return Status::OperationError(); |
278 } | 278 } |
279 | 279 |
280 ShrinkBuffer(buffer, final_output_chunk_len + output_len); | 280 ShrinkBuffer(buffer, final_output_chunk_len + output_len); |
281 return Status::Success(); | 281 return Status::Success(); |
282 } | 282 } |
283 | 283 |
284 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is | 284 // Helper to either encrypt or decrypt for AES-GCM. The result of encryption is |
285 // the concatenation of the ciphertext and the authentication tag. Similarly, | 285 // the concatenation of the ciphertext and the authentication tag. Similarly, |
286 // this is the expectation for the input to decryption. | 286 // this is the expectation for the input to decryption. |
287 Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode, | 287 Status AesGcmEncryptDecrypt(EncryptOrDecrypt mode, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 SECStatus result = func(key->key(), | 344 SECStatus result = func(key->key(), |
345 CKM_AES_GCM, | 345 CKM_AES_GCM, |
346 ¶m, | 346 ¶m, |
347 buffer_data, | 347 buffer_data, |
348 &output_len, | 348 &output_len, |
349 buffer->byteLength(), | 349 buffer->byteLength(), |
350 data.bytes(), | 350 data.bytes(), |
351 data.byte_length()); | 351 data.byte_length()); |
352 | 352 |
353 if (result != SECSuccess) | 353 if (result != SECSuccess) |
354 return Status::Error(); | 354 return Status::OperationError(); |
355 | 355 |
356 // Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug | 356 // Unfortunately the buffer needs to be shrunk for decryption (see the NSS bug |
357 // above). | 357 // above). |
358 ShrinkBuffer(buffer, output_len); | 358 ShrinkBuffer(buffer, output_len); |
359 | 359 |
360 return Status::Success(); | 360 return Status::Success(); |
361 } | 361 } |
362 | 362 |
363 CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism( | 363 CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism( |
364 const blink::WebCryptoAlgorithm& algorithm) { | 364 const blink::WebCryptoAlgorithm& algorithm) { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
518 CKM_NSS_AES_KEY_WRAP, | 518 CKM_NSS_AES_KEY_WRAP, |
519 param_item.get(), | 519 param_item.get(), |
520 &cipher_text, | 520 &cipher_text, |
521 mechanism, | 521 mechanism, |
522 flags, | 522 flags, |
523 plaintext_length)); | 523 plaintext_length)); |
524 // TODO(padolph): Use NSS PORT_GetError() and friends to report a more | 524 // TODO(padolph): Use NSS PORT_GetError() and friends to report a more |
525 // accurate error, providing if doesn't leak any information to web pages | 525 // accurate error, providing if doesn't leak any information to web pages |
526 // about other web crypto users, key details, etc. | 526 // about other web crypto users, key details, etc. |
527 if (!new_key) | 527 if (!new_key) |
528 return Status::Error(); | 528 return Status::OperationError(); |
529 | 529 |
530 #if defined(USE_NSS) | 530 #if defined(USE_NSS) |
531 // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=981170 | 531 // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=981170 |
532 // which was fixed in NSS 3.16.0. | 532 // which was fixed in NSS 3.16.0. |
533 // If unwrap fails, NSS nevertheless returns a valid-looking PK11SymKey, | 533 // If unwrap fails, NSS nevertheless returns a valid-looking PK11SymKey, |
534 // with a reasonable length but with key data pointing to uninitialized | 534 // with a reasonable length but with key data pointing to uninitialized |
535 // memory. | 535 // memory. |
536 // To understand this workaround see the fix for 981170: | 536 // To understand this workaround see the fix for 981170: |
537 // https://hg.mozilla.org/projects/nss/rev/753bb69e543c | 537 // https://hg.mozilla.org/projects/nss/rev/753bb69e543c |
538 if (!NSS_VersionCheck("3.16") && PORT_GetError() == SEC_ERROR_BAD_DATA) | 538 if (!NSS_VersionCheck("3.16") && PORT_GetError() == SEC_ERROR_BAD_DATA) |
539 return Status::Error(); | 539 return Status::OperationError(); |
540 #endif | 540 #endif |
541 | 541 |
542 *unwrapped_key = new_key.Pass(); | 542 *unwrapped_key = new_key.Pass(); |
543 return Status::Success(); | 543 return Status::Success(); |
544 } | 544 } |
545 | 545 |
546 void CopySECItemToVector(const SECItem& item, std::vector<uint8>* out) { | 546 void CopySECItemToVector(const SECItem& item, std::vector<uint8>* out) { |
547 out->assign(item.data, item.data + item.len); | 547 out->assign(item.data, item.data + item.len); |
548 } | 548 } |
549 | 549 |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
716 | 716 |
717 private: | 717 private: |
718 Status Init() { | 718 Status Init() { |
719 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm_id_); | 719 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm_id_); |
720 | 720 |
721 if (hash_type == HASH_AlgNULL) | 721 if (hash_type == HASH_AlgNULL) |
722 return Status::ErrorUnsupported(); | 722 return Status::ErrorUnsupported(); |
723 | 723 |
724 hash_context_ = HASH_Create(hash_type); | 724 hash_context_ = HASH_Create(hash_type); |
725 if (!hash_context_) | 725 if (!hash_context_) |
726 return Status::Error(); | 726 return Status::OperationError(); |
727 | 727 |
728 HASH_Begin(hash_context_); | 728 HASH_Begin(hash_context_); |
729 | 729 |
730 return Status::Success(); | 730 return Status::Success(); |
731 } | 731 } |
732 | 732 |
733 Status FinishInternal(unsigned char* result, unsigned int* result_size) { | 733 Status FinishInternal(unsigned char* result, unsigned int* result_size) { |
734 if (!hash_context_) { | 734 if (!hash_context_) { |
735 Status error = Init(); | 735 Status error = Init(); |
736 if (!error.IsSuccess()) | 736 if (!error.IsSuccess()) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
773 crypto::ScopedPK11SymKey pk11_sym_key( | 773 crypto::ScopedPK11SymKey pk11_sym_key( |
774 PK11_ImportSymKeyWithFlags(slot.get(), | 774 PK11_ImportSymKeyWithFlags(slot.get(), |
775 mechanism, | 775 mechanism, |
776 PK11_OriginUnwrap, | 776 PK11_OriginUnwrap, |
777 CKA_FLAGS_ONLY, | 777 CKA_FLAGS_ONLY, |
778 &key_item, | 778 &key_item, |
779 flags, | 779 flags, |
780 false, | 780 false, |
781 NULL)); | 781 NULL)); |
782 if (!pk11_sym_key.get()) | 782 if (!pk11_sym_key.get()) |
783 return Status::Error(); | 783 return Status::OperationError(); |
784 | 784 |
785 blink::WebCryptoKeyAlgorithm key_algorithm; | 785 blink::WebCryptoKeyAlgorithm key_algorithm; |
786 if (!CreateSecretKeyAlgorithm( | 786 if (!CreateSecretKeyAlgorithm( |
787 algorithm, key_data.byte_length(), &key_algorithm)) | 787 algorithm, key_data.byte_length(), &key_algorithm)) |
788 return Status::ErrorUnexpected(); | 788 return Status::ErrorUnexpected(); |
789 | 789 |
790 *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()), | 790 *key = blink::WebCryptoKey::create(new SymKey(pk11_sym_key.Pass()), |
791 blink::WebCryptoKeyTypeSecret, | 791 blink::WebCryptoKeyTypeSecret, |
792 extractable, | 792 extractable, |
793 key_algorithm, | 793 key_algorithm, |
794 usage_mask); | 794 usage_mask); |
795 return Status::Success(); | 795 return Status::Success(); |
796 } | 796 } |
797 | 797 |
798 Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) { | 798 Status ExportKeyRaw(SymKey* key, blink::WebArrayBuffer* buffer) { |
799 if (PK11_ExtractKeyValue(key->key()) != SECSuccess) | 799 if (PK11_ExtractKeyValue(key->key()) != SECSuccess) |
800 return Status::Error(); | 800 return Status::OperationError(); |
801 | 801 |
802 // NOTE: the spec does not define any other failures for exporting, so | |
803 // technically none of the subsequent errors are spec compliant. | |
802 const SECItem* key_data = PK11_GetKeyData(key->key()); | 804 const SECItem* key_data = PK11_GetKeyData(key->key()); |
803 if (!key_data) | 805 if (!key_data) |
804 return Status::Error(); | 806 return Status::OperationError(); |
805 | 807 |
806 *buffer = CreateArrayBuffer(key_data->data, key_data->len); | 808 *buffer = CreateArrayBuffer(key_data->data, key_data->len); |
807 | 809 |
808 return Status::Success(); | 810 return Status::Success(); |
809 } | 811 } |
810 | 812 |
811 namespace { | 813 namespace { |
812 | 814 |
813 typedef scoped_ptr<CERTSubjectPublicKeyInfo, | 815 typedef scoped_ptr<CERTSubjectPublicKeyInfo, |
814 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo, | 816 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
847 if (!key_data.byte_length()) | 849 if (!key_data.byte_length()) |
848 return Status::ErrorImportEmptyKeyData(); | 850 return Status::ErrorImportEmptyKeyData(); |
849 DCHECK(key_data.bytes()); | 851 DCHECK(key_data.bytes()); |
850 | 852 |
851 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject | 853 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject |
852 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. | 854 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. |
853 SECItem spki_item = MakeSECItemForBuffer(key_data); | 855 SECItem spki_item = MakeSECItemForBuffer(key_data); |
854 const ScopedCERTSubjectPublicKeyInfo spki( | 856 const ScopedCERTSubjectPublicKeyInfo spki( |
855 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); | 857 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); |
856 if (!spki) | 858 if (!spki) |
857 return Status::Error(); | 859 return Status::DataError(); |
858 | 860 |
859 crypto::ScopedSECKEYPublicKey sec_public_key( | 861 crypto::ScopedSECKEYPublicKey sec_public_key( |
860 SECKEY_ExtractPublicKey(spki.get())); | 862 SECKEY_ExtractPublicKey(spki.get())); |
861 if (!sec_public_key) | 863 if (!sec_public_key) |
862 return Status::Error(); | 864 return Status::DataError(); |
863 | 865 |
864 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); | 866 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); |
865 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) | 867 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) |
866 return Status::Error(); | 868 return Status::DataError(); |
867 | 869 |
868 blink::WebCryptoKeyAlgorithm key_algorithm; | 870 blink::WebCryptoKeyAlgorithm key_algorithm; |
869 if (!CreatePublicKeyAlgorithm( | 871 if (!CreatePublicKeyAlgorithm( |
870 algorithm, sec_public_key.get(), &key_algorithm)) | 872 algorithm, sec_public_key.get(), &key_algorithm)) |
871 return Status::ErrorUnexpected(); | 873 return Status::ErrorUnexpected(); |
872 | 874 |
873 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), | 875 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), |
874 blink::WebCryptoKeyTypePublic, | 876 blink::WebCryptoKeyTypePublic, |
875 extractable, | 877 extractable, |
876 key_algorithm, | 878 key_algorithm, |
877 usage_mask); | 879 usage_mask); |
878 | 880 |
879 return Status::Success(); | 881 return Status::Success(); |
880 } | 882 } |
881 | 883 |
882 Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) { | 884 Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) { |
883 const crypto::ScopedSECItem spki_der( | 885 const crypto::ScopedSECItem spki_der( |
884 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key())); | 886 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key())); |
887 // NOTE: the spec does not define any other failures for exporting, so | |
888 // technically none of the subsequent errors are spec compliant. | |
885 if (!spki_der) | 889 if (!spki_der) |
886 return Status::Error(); | 890 return Status::OperationError(); |
887 | 891 |
888 DCHECK(spki_der->data); | 892 DCHECK(spki_der->data); |
889 DCHECK(spki_der->len); | 893 DCHECK(spki_der->len); |
890 | 894 |
891 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); | 895 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); |
892 | 896 |
893 return Status::Success(); | 897 return Status::Success(); |
894 } | 898 } |
895 | 899 |
896 Status ExportRsaPublicKey(PublicKey* key, | 900 Status ExportRsaPublicKey(PublicKey* key, |
(...skipping 21 matching lines...) Expand all Loading... | |
918 #if defined(USE_NSS) | 922 #if defined(USE_NSS) |
919 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code. | 923 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code. |
920 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; | 924 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; |
921 const int kPrivateKeyInfoVersion = 0; | 925 const int kPrivateKeyInfoVersion = 0; |
922 | 926 |
923 SECKEYPrivateKeyInfo private_key_info = {}; | 927 SECKEYPrivateKeyInfo private_key_info = {}; |
924 RSAPrivateKey rsa_private_key = {}; | 928 RSAPrivateKey rsa_private_key = {}; |
925 scoped_ptr<RSAPrivateKey, FreeRsaPrivateKey> free_private_key( | 929 scoped_ptr<RSAPrivateKey, FreeRsaPrivateKey> free_private_key( |
926 &rsa_private_key); | 930 &rsa_private_key); |
927 | 931 |
932 // NOTE: the spec does not define any other failures for exporting, so | |
933 // technically none of the subsequent errors are spec compliant. | |
Ryan Sleevi
2014/04/24 01:17:01
Filed http://crbug.com/366427 to track this - I di
eroman
2014/04/24 02:34:37
Done.
| |
928 if (!InitRSAPrivateKey(key->key(), &rsa_private_key)) | 934 if (!InitRSAPrivateKey(key->key(), &rsa_private_key)) |
929 return Status::Error(); | 935 return Status::OperationError(); |
930 | 936 |
931 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); | 937 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); |
932 if (!arena.get()) | 938 if (!arena.get()) |
933 return Status::Error(); | 939 return Status::OperationError(); |
934 | 940 |
935 if (!SEC_ASN1EncodeItem(arena.get(), | 941 if (!SEC_ASN1EncodeItem(arena.get(), |
936 &private_key_info.privateKey, | 942 &private_key_info.privateKey, |
937 &rsa_private_key, | 943 &rsa_private_key, |
938 RSAPrivateKeyTemplate)) | 944 RSAPrivateKeyTemplate)) |
939 return Status::Error(); | 945 return Status::OperationError(); |
940 | 946 |
941 if (SECSuccess != | 947 if (SECSuccess != |
942 SECOID_SetAlgorithmID( | 948 SECOID_SetAlgorithmID( |
943 arena.get(), &private_key_info.algorithm, algorithm, NULL)) | 949 arena.get(), &private_key_info.algorithm, algorithm, NULL)) |
944 return Status::Error(); | 950 return Status::OperationError(); |
945 | 951 |
946 if (!SEC_ASN1EncodeInteger( | 952 if (!SEC_ASN1EncodeInteger( |
947 arena.get(), &private_key_info.version, kPrivateKeyInfoVersion)) | 953 arena.get(), &private_key_info.version, kPrivateKeyInfoVersion)) |
948 return Status::Error(); | 954 return Status::OperationError(); |
949 | 955 |
950 crypto::ScopedSECItem encoded_key( | 956 crypto::ScopedSECItem encoded_key( |
951 SEC_ASN1EncodeItem(NULL, | 957 SEC_ASN1EncodeItem(NULL, |
952 NULL, | 958 NULL, |
953 &private_key_info, | 959 &private_key_info, |
954 SEC_ASN1_GET(SECKEY_PrivateKeyInfoTemplate))); | 960 SEC_ASN1_GET(SECKEY_PrivateKeyInfoTemplate))); |
955 #else // defined(USE_NSS) | 961 #else // defined(USE_NSS) |
956 crypto::ScopedSECItem encoded_key( | 962 crypto::ScopedSECItem encoded_key( |
957 PK11_ExportDERPrivateKeyInfo(key->key(), NULL)); | 963 PK11_ExportDERPrivateKeyInfo(key->key(), NULL)); |
958 #endif // defined(USE_NSS) | 964 #endif // defined(USE_NSS) |
959 | 965 |
960 if (!encoded_key.get()) | 966 if (!encoded_key.get()) |
961 return Status::Error(); | 967 return Status::OperationError(); |
962 | 968 |
963 *buffer = CreateArrayBuffer(encoded_key->data, encoded_key->len); | 969 *buffer = CreateArrayBuffer(encoded_key->data, encoded_key->len); |
964 return Status::Success(); | 970 return Status::Success(); |
965 } | 971 } |
966 | 972 |
967 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm, | 973 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm, |
968 const CryptoData& key_data, | 974 const CryptoData& key_data, |
969 bool extractable, | 975 bool extractable, |
970 blink::WebCryptoKeyUsageMask usage_mask, | 976 blink::WebCryptoKeyUsageMask usage_mask, |
971 blink::WebCryptoKey* key) { | 977 blink::WebCryptoKey* key) { |
(...skipping 12 matching lines...) Expand all Loading... | |
984 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); | 990 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); |
985 if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot.get(), | 991 if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot.get(), |
986 &pki_der, | 992 &pki_der, |
987 NULL, // nickname | 993 NULL, // nickname |
988 NULL, // publicValue | 994 NULL, // publicValue |
989 false, // isPerm | 995 false, // isPerm |
990 false, // isPrivate | 996 false, // isPrivate |
991 KU_ALL, // usage | 997 KU_ALL, // usage |
992 &seckey_private_key, | 998 &seckey_private_key, |
993 NULL) != SECSuccess) { | 999 NULL) != SECSuccess) { |
994 return Status::Error(); | 1000 return Status::DataError(); |
995 } | 1001 } |
996 DCHECK(seckey_private_key); | 1002 DCHECK(seckey_private_key); |
997 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); | 1003 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); |
998 | 1004 |
999 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); | 1005 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); |
1000 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) | 1006 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) |
1001 return Status::Error(); | 1007 return Status::DataError(); |
1002 | 1008 |
1003 blink::WebCryptoKeyAlgorithm key_algorithm; | 1009 blink::WebCryptoKeyAlgorithm key_algorithm; |
1004 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) | 1010 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) |
1005 return Status::ErrorUnexpected(); | 1011 return Status::ErrorUnexpected(); |
1006 | 1012 |
1007 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), | 1013 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), |
1008 blink::WebCryptoKeyTypePrivate, | 1014 blink::WebCryptoKeyTypePrivate, |
1009 extractable, | 1015 extractable, |
1010 key_algorithm, | 1016 key_algorithm, |
1011 usage_mask); | 1017 usage_mask); |
(...skipping 14 matching lines...) Expand all Loading... | |
1026 SECItem param_item = {siBuffer, NULL, 0}; | 1032 SECItem param_item = {siBuffer, NULL, 0}; |
1027 SECItem data_item = MakeSECItemForBuffer(data); | 1033 SECItem data_item = MakeSECItemForBuffer(data); |
1028 // First call is to figure out the length. | 1034 // First call is to figure out the length. |
1029 SECItem signature_item = {siBuffer, NULL, 0}; | 1035 SECItem signature_item = {siBuffer, NULL, 0}; |
1030 | 1036 |
1031 if (PK11_SignWithSymKey(key->key(), | 1037 if (PK11_SignWithSymKey(key->key(), |
1032 PK11_GetMechanism(key->key()), | 1038 PK11_GetMechanism(key->key()), |
1033 ¶m_item, | 1039 ¶m_item, |
1034 &signature_item, | 1040 &signature_item, |
1035 &data_item) != SECSuccess) { | 1041 &data_item) != SECSuccess) { |
1036 return Status::Error(); | 1042 return Status::OperationError(); |
1037 } | 1043 } |
1038 | 1044 |
1039 DCHECK_NE(0u, signature_item.len); | 1045 DCHECK_NE(0u, signature_item.len); |
1040 | 1046 |
1041 *buffer = blink::WebArrayBuffer::create(signature_item.len, 1); | 1047 *buffer = blink::WebArrayBuffer::create(signature_item.len, 1); |
1042 signature_item.data = reinterpret_cast<unsigned char*>(buffer->data()); | 1048 signature_item.data = reinterpret_cast<unsigned char*>(buffer->data()); |
1043 | 1049 |
1044 if (PK11_SignWithSymKey(key->key(), | 1050 if (PK11_SignWithSymKey(key->key(), |
1045 PK11_GetMechanism(key->key()), | 1051 PK11_GetMechanism(key->key()), |
1046 ¶m_item, | 1052 ¶m_item, |
1047 &signature_item, | 1053 &signature_item, |
1048 &data_item) != SECSuccess) { | 1054 &data_item) != SECSuccess) { |
1049 return Status::Error(); | 1055 return Status::OperationError(); |
1050 } | 1056 } |
1051 | 1057 |
1052 DCHECK_EQ(buffer->byteLength(), signature_item.len); | 1058 DCHECK_EQ(buffer->byteLength(), signature_item.len); |
1053 return Status::Success(); | 1059 return Status::Success(); |
1054 } | 1060 } |
1055 | 1061 |
1056 // ----------------------------------- | 1062 // ----------------------------------- |
1057 // RsaEsPkcs1v1_5 | 1063 // RsaEsPkcs1v1_5 |
1058 // ----------------------------------- | 1064 // ----------------------------------- |
1059 | 1065 |
(...skipping 11 matching lines...) Expand all Loading... | |
1071 | 1077 |
1072 *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1); | 1078 *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1); |
1073 unsigned char* const buffer_data = | 1079 unsigned char* const buffer_data = |
1074 reinterpret_cast<unsigned char*>(buffer->data()); | 1080 reinterpret_cast<unsigned char*>(buffer->data()); |
1075 | 1081 |
1076 if (PK11_PubEncryptPKCS1(key->key(), | 1082 if (PK11_PubEncryptPKCS1(key->key(), |
1077 buffer_data, | 1083 buffer_data, |
1078 const_cast<unsigned char*>(data.bytes()), | 1084 const_cast<unsigned char*>(data.bytes()), |
1079 data.byte_length(), | 1085 data.byte_length(), |
1080 NULL) != SECSuccess) { | 1086 NULL) != SECSuccess) { |
1081 return Status::Error(); | 1087 return Status::OperationError(); |
1082 } | 1088 } |
1083 return Status::Success(); | 1089 return Status::Success(); |
1084 } | 1090 } |
1085 | 1091 |
1086 Status DecryptRsaEsPkcs1v1_5(PrivateKey* key, | 1092 Status DecryptRsaEsPkcs1v1_5(PrivateKey* key, |
1087 const CryptoData& data, | 1093 const CryptoData& data, |
1088 blink::WebArrayBuffer* buffer) { | 1094 blink::WebArrayBuffer* buffer) { |
1089 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key()); | 1095 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key()); |
1090 if (modulus_length_bytes <= 0) | 1096 if (modulus_length_bytes <= 0) |
1091 return Status::ErrorUnexpected(); | 1097 return Status::ErrorUnexpected(); |
1092 const unsigned int max_output_length_bytes = modulus_length_bytes; | 1098 const unsigned int max_output_length_bytes = modulus_length_bytes; |
1093 | 1099 |
1094 *buffer = blink::WebArrayBuffer::create(max_output_length_bytes, 1); | 1100 *buffer = blink::WebArrayBuffer::create(max_output_length_bytes, 1); |
1095 unsigned char* const buffer_data = | 1101 unsigned char* const buffer_data = |
1096 reinterpret_cast<unsigned char*>(buffer->data()); | 1102 reinterpret_cast<unsigned char*>(buffer->data()); |
1097 | 1103 |
1098 unsigned int output_length_bytes = 0; | 1104 unsigned int output_length_bytes = 0; |
1099 if (PK11_PrivDecryptPKCS1(key->key(), | 1105 if (PK11_PrivDecryptPKCS1(key->key(), |
1100 buffer_data, | 1106 buffer_data, |
1101 &output_length_bytes, | 1107 &output_length_bytes, |
1102 max_output_length_bytes, | 1108 max_output_length_bytes, |
1103 const_cast<unsigned char*>(data.bytes()), | 1109 const_cast<unsigned char*>(data.bytes()), |
1104 data.byte_length()) != SECSuccess) { | 1110 data.byte_length()) != SECSuccess) { |
1105 return Status::Error(); | 1111 return Status::OperationError(); |
1106 } | 1112 } |
1107 DCHECK_LE(output_length_bytes, max_output_length_bytes); | 1113 DCHECK_LE(output_length_bytes, max_output_length_bytes); |
1108 ShrinkBuffer(buffer, output_length_bytes); | 1114 ShrinkBuffer(buffer, output_length_bytes); |
1109 return Status::Success(); | 1115 return Status::Success(); |
1110 } | 1116 } |
1111 | 1117 |
1112 // ----------------------------------- | 1118 // ----------------------------------- |
1113 // RsaSsaPkcs1v1_5 | 1119 // RsaSsaPkcs1v1_5 |
1114 // ----------------------------------- | 1120 // ----------------------------------- |
1115 | 1121 |
(...skipping 20 matching lines...) Expand all Loading... | |
1136 default: | 1142 default: |
1137 return Status::ErrorUnsupported(); | 1143 return Status::ErrorUnsupported(); |
1138 } | 1144 } |
1139 | 1145 |
1140 crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0)); | 1146 crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0)); |
1141 if (SEC_SignData(signature_item.get(), | 1147 if (SEC_SignData(signature_item.get(), |
1142 data.bytes(), | 1148 data.bytes(), |
1143 data.byte_length(), | 1149 data.byte_length(), |
1144 key->key(), | 1150 key->key(), |
1145 sign_alg_tag) != SECSuccess) { | 1151 sign_alg_tag) != SECSuccess) { |
1146 return Status::Error(); | 1152 return Status::OperationError(); |
1147 } | 1153 } |
1148 | 1154 |
1149 *buffer = CreateArrayBuffer(signature_item->data, signature_item->len); | 1155 *buffer = CreateArrayBuffer(signature_item->data, signature_item->len); |
1150 return Status::Success(); | 1156 return Status::Success(); |
1151 } | 1157 } |
1152 | 1158 |
1153 Status VerifyRsaSsaPkcs1v1_5(PublicKey* key, | 1159 Status VerifyRsaSsaPkcs1v1_5(PublicKey* key, |
1154 const blink::WebCryptoAlgorithm& hash, | 1160 const blink::WebCryptoAlgorithm& hash, |
1155 const CryptoData& signature, | 1161 const CryptoData& signature, |
1156 const CryptoData& data, | 1162 const CryptoData& data, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1215 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, | 1221 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, |
1216 bool extractable, | 1222 bool extractable, |
1217 blink::WebCryptoKeyUsageMask usage_mask, | 1223 blink::WebCryptoKeyUsageMask usage_mask, |
1218 unsigned int modulus_length_bits, | 1224 unsigned int modulus_length_bits, |
1219 const CryptoData& public_exponent, | 1225 const CryptoData& public_exponent, |
1220 const blink::WebCryptoAlgorithm& hash_or_null, | 1226 const blink::WebCryptoAlgorithm& hash_or_null, |
1221 blink::WebCryptoKey* public_key, | 1227 blink::WebCryptoKey* public_key, |
1222 blink::WebCryptoKey* private_key) { | 1228 blink::WebCryptoKey* private_key) { |
1223 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 1229 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
1224 if (!slot) | 1230 if (!slot) |
1225 return Status::Error(); | 1231 return Status::OperationError(); |
1226 | 1232 |
1227 unsigned long public_exponent_long; | 1233 unsigned long public_exponent_long; |
1228 if (!BigIntegerToLong(public_exponent.bytes(), | 1234 if (!BigIntegerToLong(public_exponent.bytes(), |
1229 public_exponent.byte_length(), | 1235 public_exponent.byte_length(), |
1230 &public_exponent_long) || | 1236 &public_exponent_long) || |
1231 !public_exponent_long) { | 1237 !public_exponent_long) { |
1232 return Status::ErrorGenerateKeyPublicExponent(); | 1238 return Status::ErrorGenerateKeyPublicExponent(); |
1233 } | 1239 } |
1234 | 1240 |
1235 PK11RSAGenParams rsa_gen_params; | 1241 PK11RSAGenParams rsa_gen_params; |
(...skipping 29 matching lines...) Expand all Loading... | |
1265 crypto::ScopedSECKEYPrivateKey scoped_sec_private_key( | 1271 crypto::ScopedSECKEYPrivateKey scoped_sec_private_key( |
1266 PK11_GenerateKeyPairWithOpFlags(slot.get(), | 1272 PK11_GenerateKeyPairWithOpFlags(slot.get(), |
1267 CKM_RSA_PKCS_KEY_PAIR_GEN, | 1273 CKM_RSA_PKCS_KEY_PAIR_GEN, |
1268 &rsa_gen_params, | 1274 &rsa_gen_params, |
1269 &sec_public_key, | 1275 &sec_public_key, |
1270 attribute_flags, | 1276 attribute_flags, |
1271 operation_flags, | 1277 operation_flags, |
1272 operation_flags_mask, | 1278 operation_flags_mask, |
1273 NULL)); | 1279 NULL)); |
1274 if (!private_key) | 1280 if (!private_key) |
1275 return Status::Error(); | 1281 return Status::OperationError(); |
1276 | 1282 |
1277 blink::WebCryptoKeyAlgorithm key_algorithm; | 1283 blink::WebCryptoKeyAlgorithm key_algorithm; |
1278 if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm)) | 1284 if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm)) |
1279 return Status::ErrorUnexpected(); | 1285 return Status::ErrorUnexpected(); |
1280 | 1286 |
1281 *public_key = blink::WebCryptoKey::create( | 1287 *public_key = blink::WebCryptoKey::create( |
1282 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), | 1288 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), |
1283 blink::WebCryptoKeyTypePublic, | 1289 blink::WebCryptoKeyTypePublic, |
1284 true, | 1290 true, |
1285 key_algorithm, | 1291 key_algorithm, |
1286 usage_mask); | 1292 usage_mask); |
1287 *private_key = | 1293 *private_key = |
1288 blink::WebCryptoKey::create(new PrivateKey(scoped_sec_private_key.Pass()), | 1294 blink::WebCryptoKey::create(new PrivateKey(scoped_sec_private_key.Pass()), |
1289 blink::WebCryptoKeyTypePrivate, | 1295 blink::WebCryptoKeyTypePrivate, |
1290 extractable, | 1296 extractable, |
1291 key_algorithm, | 1297 key_algorithm, |
1292 usage_mask); | 1298 usage_mask); |
1293 | 1299 |
1294 return Status::Success(); | 1300 return Status::Success(); |
1295 } | 1301 } |
1296 | 1302 |
1297 void Init() { crypto::EnsureNSSInit(); } | 1303 void Init() { crypto::EnsureNSSInit(); } |
1298 | 1304 |
1299 Status DigestSha(blink::WebCryptoAlgorithmId algorithm, | 1305 Status DigestSha(blink::WebCryptoAlgorithmId algorithm, |
1300 const CryptoData& data, | 1306 const CryptoData& data, |
1301 blink::WebArrayBuffer* buffer) { | 1307 blink::WebArrayBuffer* buffer) { |
1302 DigestorNSS digestor(algorithm); | 1308 DigestorNSS digestor(algorithm); |
1303 Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length()); | 1309 Status error = digestor.ConsumeWithStatus(data.bytes(), data.byte_length()); |
1310 // NOTE: the spec does not define any other failures for digest, so | |
1311 // technically none of the subsequent errors are spec compliant. | |
1304 if (!error.IsSuccess()) | 1312 if (!error.IsSuccess()) |
1305 return error; | 1313 return error; |
1306 return digestor.FinishWithWebArrayAndStatus(buffer); | 1314 return digestor.FinishWithWebArrayAndStatus(buffer); |
1307 } | 1315 } |
1308 | 1316 |
1309 scoped_ptr<blink::WebCryptoDigestor> CreateDigestor( | 1317 scoped_ptr<blink::WebCryptoDigestor> CreateDigestor( |
1310 blink::WebCryptoAlgorithmId algorithm_id) { | 1318 blink::WebCryptoAlgorithmId algorithm_id) { |
1311 return scoped_ptr<blink::WebCryptoDigestor>(new DigestorNSS(algorithm_id)); | 1319 return scoped_ptr<blink::WebCryptoDigestor>(new DigestorNSS(algorithm_id)); |
1312 } | 1320 } |
1313 | 1321 |
1314 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, | 1322 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm, |
1315 bool extractable, | 1323 bool extractable, |
1316 blink::WebCryptoKeyUsageMask usage_mask, | 1324 blink::WebCryptoKeyUsageMask usage_mask, |
1317 unsigned keylen_bytes, | 1325 unsigned keylen_bytes, |
1318 blink::WebCryptoKey* key) { | 1326 blink::WebCryptoKey* key) { |
1319 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm); | 1327 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm); |
1320 blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret; | 1328 blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret; |
1321 | 1329 |
1322 if (mech == CKM_INVALID_MECHANISM) | 1330 if (mech == CKM_INVALID_MECHANISM) |
1323 return Status::ErrorUnsupported(); | 1331 return Status::ErrorUnsupported(); |
1324 | 1332 |
1325 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 1333 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
1326 if (!slot) | 1334 if (!slot) |
1327 return Status::Error(); | 1335 return Status::OperationError(); |
1328 | 1336 |
1329 crypto::ScopedPK11SymKey pk11_key( | 1337 crypto::ScopedPK11SymKey pk11_key( |
1330 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); | 1338 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); |
1331 | 1339 |
1332 if (!pk11_key) | 1340 if (!pk11_key) |
1333 return Status::Error(); | 1341 return Status::OperationError(); |
1334 | 1342 |
1335 blink::WebCryptoKeyAlgorithm key_algorithm; | 1343 blink::WebCryptoKeyAlgorithm key_algorithm; |
1336 if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm)) | 1344 if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm)) |
1337 return Status::ErrorUnexpected(); | 1345 return Status::ErrorUnexpected(); |
1338 | 1346 |
1339 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), | 1347 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), |
1340 key_type, | 1348 key_type, |
1341 extractable, | 1349 extractable, |
1342 key_algorithm, | 1350 key_algorithm, |
1343 usage_mask); | 1351 usage_mask); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1380 const SEC_ASN1Template rsa_public_key_template[] = { | 1388 const SEC_ASN1Template rsa_public_key_template[] = { |
1381 {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(RsaPublicKeyData)}, | 1389 {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(RsaPublicKeyData)}, |
1382 {SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, modulus), }, | 1390 {SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, modulus), }, |
1383 {SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, exponent), }, | 1391 {SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, exponent), }, |
1384 {0, }}; | 1392 {0, }}; |
1385 | 1393 |
1386 // DER-encode the public key. | 1394 // DER-encode the public key. |
1387 crypto::ScopedSECItem pubkey_der( | 1395 crypto::ScopedSECItem pubkey_der( |
1388 SEC_ASN1EncodeItem(NULL, NULL, &pubkey_in, rsa_public_key_template)); | 1396 SEC_ASN1EncodeItem(NULL, NULL, &pubkey_in, rsa_public_key_template)); |
1389 if (!pubkey_der) | 1397 if (!pubkey_der) |
1390 return Status::Error(); | 1398 return Status::OperationError(); |
1391 | 1399 |
1392 // Import the DER-encoded public key to create an RSA SECKEYPublicKey. | 1400 // Import the DER-encoded public key to create an RSA SECKEYPublicKey. |
1393 crypto::ScopedSECKEYPublicKey pubkey( | 1401 crypto::ScopedSECKEYPublicKey pubkey( |
1394 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA)); | 1402 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA)); |
1395 if (!pubkey) | 1403 if (!pubkey) |
1396 return Status::Error(); | 1404 return Status::OperationError(); |
1397 | 1405 |
1398 blink::WebCryptoKeyAlgorithm key_algorithm; | 1406 blink::WebCryptoKeyAlgorithm key_algorithm; |
1399 if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm)) | 1407 if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm)) |
1400 return Status::ErrorUnexpected(); | 1408 return Status::ErrorUnexpected(); |
1401 | 1409 |
1402 *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()), | 1410 *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()), |
1403 blink::WebCryptoKeyTypePublic, | 1411 blink::WebCryptoKeyTypePublic, |
1404 extractable, | 1412 extractable, |
1405 key_algorithm, | 1413 key_algorithm, |
1406 usage_mask); | 1414 usage_mask); |
(...skipping 24 matching lines...) Expand all Loading... | |
1431 | 1439 |
1432 const unsigned int output_length = input_length + 8; | 1440 const unsigned int output_length = input_length + 8; |
1433 *buffer = blink::WebArrayBuffer::create(output_length, 1); | 1441 *buffer = blink::WebArrayBuffer::create(output_length, 1); |
1434 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); | 1442 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); |
1435 | 1443 |
1436 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, | 1444 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, |
1437 param_item.get(), | 1445 param_item.get(), |
1438 wrapping_key->key(), | 1446 wrapping_key->key(), |
1439 key->key(), | 1447 key->key(), |
1440 &wrapped_key_item)) { | 1448 &wrapped_key_item)) { |
1441 return Status::Error(); | 1449 return Status::OperationError(); |
1442 } | 1450 } |
1443 if (output_length != wrapped_key_item.len) | 1451 if (output_length != wrapped_key_item.len) |
1444 return Status::ErrorUnexpected(); | 1452 return Status::ErrorUnexpected(); |
1445 | 1453 |
1446 return Status::Success(); | 1454 return Status::Success(); |
1447 } | 1455 } |
1448 | 1456 |
1449 Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data, | 1457 Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data, |
1450 SymKey* wrapping_key, | 1458 SymKey* wrapping_key, |
1451 const blink::WebCryptoAlgorithm& algorithm, | 1459 const blink::WebCryptoAlgorithm& algorithm, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1486 // temporarily viewed as a symmetric key to be unwrapped (decrypted). | 1494 // temporarily viewed as a symmetric key to be unwrapped (decrypted). |
1487 crypto::ScopedPK11SymKey decrypted; | 1495 crypto::ScopedPK11SymKey decrypted; |
1488 Status status = DoUnwrapSymKeyAesKw( | 1496 Status status = DoUnwrapSymKeyAesKw( |
1489 data, wrapping_key, CKK_GENERIC_SECRET, CKA_ENCRYPT, &decrypted); | 1497 data, wrapping_key, CKK_GENERIC_SECRET, CKA_ENCRYPT, &decrypted); |
1490 if (status.IsError()) | 1498 if (status.IsError()) |
1491 return status; | 1499 return status; |
1492 | 1500 |
1493 // Once the decrypt is complete, extract the resultant raw bytes from NSS and | 1501 // Once the decrypt is complete, extract the resultant raw bytes from NSS and |
1494 // return them to the caller. | 1502 // return them to the caller. |
1495 if (PK11_ExtractKeyValue(decrypted.get()) != SECSuccess) | 1503 if (PK11_ExtractKeyValue(decrypted.get()) != SECSuccess) |
1496 return Status::Error(); | 1504 return Status::OperationError(); |
1497 const SECItem* const key_data = PK11_GetKeyData(decrypted.get()); | 1505 const SECItem* const key_data = PK11_GetKeyData(decrypted.get()); |
1498 if (!key_data) | 1506 if (!key_data) |
1499 return Status::Error(); | 1507 return Status::OperationError(); |
1500 *buffer = webcrypto::CreateArrayBuffer(key_data->data, key_data->len); | 1508 *buffer = webcrypto::CreateArrayBuffer(key_data->data, key_data->len); |
1501 | 1509 |
1502 return Status::Success(); | 1510 return Status::Success(); |
1503 } | 1511 } |
1504 | 1512 |
1505 Status WrapSymKeyRsaEs(PublicKey* wrapping_key, | 1513 Status WrapSymKeyRsaEs(PublicKey* wrapping_key, |
1506 SymKey* key, | 1514 SymKey* key, |
1507 blink::WebArrayBuffer* buffer) { | 1515 blink::WebArrayBuffer* buffer) { |
1508 // Check the raw length of the key to be wrapped against the max size allowed | 1516 // Check the raw length of the key to be wrapped against the max size allowed |
1509 // by the RSA wrapping key. With PKCS#1 v1.5 padding used in this function, | 1517 // by the RSA wrapping key. With PKCS#1 v1.5 padding used in this function, |
1510 // the maximum data length that can be encrypted is the wrapping_key's modulus | 1518 // the maximum data length that can be encrypted is the wrapping_key's modulus |
1511 // byte length minus eleven bytes. | 1519 // byte length minus eleven bytes. |
1512 const unsigned int input_length_bytes = PK11_GetKeyLength(key->key()); | 1520 const unsigned int input_length_bytes = PK11_GetKeyLength(key->key()); |
1513 const unsigned int modulus_length_bytes = | 1521 const unsigned int modulus_length_bytes = |
1514 SECKEY_PublicKeyStrength(wrapping_key->key()); | 1522 SECKEY_PublicKeyStrength(wrapping_key->key()); |
1515 if (modulus_length_bytes < 11 || | 1523 if (modulus_length_bytes < 11 || |
1516 modulus_length_bytes - 11 < input_length_bytes) | 1524 modulus_length_bytes - 11 < input_length_bytes) |
1517 return Status::ErrorDataTooLarge(); | 1525 return Status::ErrorDataTooLarge(); |
1518 | 1526 |
1519 *buffer = blink::WebArrayBuffer::create(modulus_length_bytes, 1); | 1527 *buffer = blink::WebArrayBuffer::create(modulus_length_bytes, 1); |
1520 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); | 1528 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); |
1521 | 1529 |
1522 if (SECSuccess != | 1530 if (SECSuccess != |
1523 PK11_PubWrapSymKey( | 1531 PK11_PubWrapSymKey( |
1524 CKM_RSA_PKCS, wrapping_key->key(), key->key(), &wrapped_key_item)) { | 1532 CKM_RSA_PKCS, wrapping_key->key(), key->key(), &wrapped_key_item)) { |
1525 return Status::Error(); | 1533 return Status::OperationError(); |
1526 } | 1534 } |
1527 if (wrapped_key_item.len != modulus_length_bytes) | 1535 if (wrapped_key_item.len != modulus_length_bytes) |
1528 return Status::ErrorUnexpected(); | 1536 return Status::ErrorUnexpected(); |
1529 | 1537 |
1530 return Status::Success(); | 1538 return Status::Success(); |
1531 } | 1539 } |
1532 | 1540 |
1533 Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data, | 1541 Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data, |
1534 PrivateKey* wrapping_key, | 1542 PrivateKey* wrapping_key, |
1535 const blink::WebCryptoAlgorithm& algorithm, | 1543 const blink::WebCryptoAlgorithm& algorithm, |
(...skipping 22 matching lines...) Expand all Loading... | |
1558 | 1566 |
1559 crypto::ScopedPK11SymKey unwrapped_key( | 1567 crypto::ScopedPK11SymKey unwrapped_key( |
1560 PK11_PubUnwrapSymKeyWithFlagsPerm(wrapping_key->key(), | 1568 PK11_PubUnwrapSymKeyWithFlagsPerm(wrapping_key->key(), |
1561 &wrapped_key_item, | 1569 &wrapped_key_item, |
1562 mechanism, | 1570 mechanism, |
1563 CKA_DECRYPT, | 1571 CKA_DECRYPT, |
1564 0, | 1572 0, |
1565 flags, | 1573 flags, |
1566 false)); | 1574 false)); |
1567 if (!unwrapped_key) | 1575 if (!unwrapped_key) |
1568 return Status::Error(); | 1576 return Status::OperationError(); |
1569 | 1577 |
1570 const unsigned int key_length = PK11_GetKeyLength(unwrapped_key.get()); | 1578 const unsigned int key_length = PK11_GetKeyLength(unwrapped_key.get()); |
1571 | 1579 |
1572 blink::WebCryptoKeyAlgorithm key_algorithm; | 1580 blink::WebCryptoKeyAlgorithm key_algorithm; |
1573 if (!CreateSecretKeyAlgorithm(algorithm, key_length, &key_algorithm)) | 1581 if (!CreateSecretKeyAlgorithm(algorithm, key_length, &key_algorithm)) |
1574 return Status::ErrorUnexpected(); | 1582 return Status::ErrorUnexpected(); |
1575 | 1583 |
1576 *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()), | 1584 *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()), |
1577 blink::WebCryptoKeyTypeSecret, | 1585 blink::WebCryptoKeyTypeSecret, |
1578 extractable, | 1586 extractable, |
1579 key_algorithm, | 1587 key_algorithm, |
1580 usage_mask); | 1588 usage_mask); |
1581 return Status::Success(); | 1589 return Status::Success(); |
1582 } | 1590 } |
1583 | 1591 |
1584 } // namespace platform | 1592 } // namespace platform |
1585 | 1593 |
1586 } // namespace webcrypto | 1594 } // namespace webcrypto |
1587 | 1595 |
1588 } // namespace content | 1596 } // namespace content |
OLD | NEW |