Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(324)

Side by Side Diff: content/child/webcrypto/platform_crypto_nss.cc

Issue 243433006: [webcrypto] Set the error type for failures. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
344 SECStatus result = func(key->key(), 344 SECStatus result = func(key->key(),
345 CKM_AES_GCM, 345 CKM_AES_GCM,
346 &param, 346 &param,
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
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
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
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
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
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
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
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 &param_item, 1039 &param_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 &param_item, 1052 &param_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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698