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

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: 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 const SECItem* key_data = PK11_GetKeyData(key->key()); 802 const SECItem* key_data = PK11_GetKeyData(key->key());
803 if (!key_data) 803 if (!key_data)
804 return Status::Error(); 804 return Status::OperationError();
805 805
806 *buffer = CreateArrayBuffer(key_data->data, key_data->len); 806 *buffer = CreateArrayBuffer(key_data->data, key_data->len);
807 807
808 return Status::Success(); 808 return Status::Success();
809 } 809 }
810 810
811 namespace { 811 namespace {
812 812
813 typedef scoped_ptr<CERTSubjectPublicKeyInfo, 813 typedef scoped_ptr<CERTSubjectPublicKeyInfo,
814 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo, 814 crypto::NSSDestroyer<CERTSubjectPublicKeyInfo,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 if (!key_data.byte_length()) 847 if (!key_data.byte_length())
848 return Status::ErrorImportEmptyKeyData(); 848 return Status::ErrorImportEmptyKeyData();
849 DCHECK(key_data.bytes()); 849 DCHECK(key_data.bytes());
850 850
851 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject 851 // The binary blob 'key_data' is expected to be a DER-encoded ASN.1 Subject
852 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo. 852 // Public Key Info. Decode this to a CERTSubjectPublicKeyInfo.
853 SECItem spki_item = MakeSECItemForBuffer(key_data); 853 SECItem spki_item = MakeSECItemForBuffer(key_data);
854 const ScopedCERTSubjectPublicKeyInfo spki( 854 const ScopedCERTSubjectPublicKeyInfo spki(
855 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item)); 855 SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_item));
856 if (!spki) 856 if (!spki)
857 return Status::Error(); 857 return Status::OperationError();
Ryan Sleevi 2014/04/22 23:45:50 DataError - Note that this handling is not defined
eroman 2014/04/23 00:11:30 Done.
858 858
859 crypto::ScopedSECKEYPublicKey sec_public_key( 859 crypto::ScopedSECKEYPublicKey sec_public_key(
860 SECKEY_ExtractPublicKey(spki.get())); 860 SECKEY_ExtractPublicKey(spki.get()));
861 if (!sec_public_key) 861 if (!sec_public_key)
862 return Status::Error(); 862 return Status::OperationError();
Ryan Sleevi 2014/04/22 23:45:50 DataError
863 863
864 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get()); 864 const KeyType sec_key_type = SECKEY_GetPublicKeyType(sec_public_key.get());
865 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) 865 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm))
866 return Status::Error(); 866 return Status::OperationError();
Ryan Sleevi 2014/04/22 23:45:50 DataError
867 867
868 blink::WebCryptoKeyAlgorithm key_algorithm; 868 blink::WebCryptoKeyAlgorithm key_algorithm;
869 if (!CreatePublicKeyAlgorithm( 869 if (!CreatePublicKeyAlgorithm(
870 algorithm, sec_public_key.get(), &key_algorithm)) 870 algorithm, sec_public_key.get(), &key_algorithm))
871 return Status::ErrorUnexpected(); 871 return Status::ErrorUnexpected();
872 872
873 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()), 873 *key = blink::WebCryptoKey::create(new PublicKey(sec_public_key.Pass()),
874 blink::WebCryptoKeyTypePublic, 874 blink::WebCryptoKeyTypePublic,
875 extractable, 875 extractable,
876 key_algorithm, 876 key_algorithm,
877 usage_mask); 877 usage_mask);
878 878
879 return Status::Success(); 879 return Status::Success();
880 } 880 }
881 881
882 Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) { 882 Status ExportKeySpki(PublicKey* key, blink::WebArrayBuffer* buffer) {
883 const crypto::ScopedSECItem spki_der( 883 const crypto::ScopedSECItem spki_der(
884 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key())); 884 SECKEY_EncodeDERSubjectPublicKeyInfo(key->key()));
Ryan Sleevi 2014/04/22 23:45:50 FWIW, this doesn't match what the spec says - or a
eroman 2014/04/23 00:11:30 Can you explain? As in the OID is not guaranteed t
Ryan Sleevi 2014/04/23 00:17:56 Correct. You have no guarantee that the OID - or t
eroman 2014/04/23 00:36:14 I will document it for now. How do you suggest pro
885 if (!spki_der) 885 if (!spki_der)
886 return Status::Error(); 886 return Status::OperationError();
Ryan Sleevi 2014/04/22 23:45:50 Not a valid return from this function.
eroman 2014/04/23 00:11:30 Can you explain?
Ryan Sleevi 2014/04/23 00:17:56 This operation is not allowed to fail.
eroman 2014/04/23 00:36:14 I will add a note.
887 887
888 DCHECK(spki_der->data); 888 DCHECK(spki_der->data);
889 DCHECK(spki_der->len); 889 DCHECK(spki_der->len);
890 890
891 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len); 891 *buffer = CreateArrayBuffer(spki_der->data, spki_der->len);
892 892
893 return Status::Success(); 893 return Status::Success();
894 } 894 }
895 895
896 Status ExportRsaPublicKey(PublicKey* key, 896 Status ExportRsaPublicKey(PublicKey* key,
(...skipping 22 matching lines...) Expand all
919 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code. 919 // PK11_ExportDERPrivateKeyInfo isn't available. Use our fallback code.
920 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; 920 const SECOidTag algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
921 const int kPrivateKeyInfoVersion = 0; 921 const int kPrivateKeyInfoVersion = 0;
922 922
923 SECKEYPrivateKeyInfo private_key_info = {}; 923 SECKEYPrivateKeyInfo private_key_info = {};
924 RSAPrivateKey rsa_private_key = {}; 924 RSAPrivateKey rsa_private_key = {};
925 scoped_ptr<RSAPrivateKey, FreeRsaPrivateKey> free_private_key( 925 scoped_ptr<RSAPrivateKey, FreeRsaPrivateKey> free_private_key(
926 &rsa_private_key); 926 &rsa_private_key);
927 927
928 if (!InitRSAPrivateKey(key->key(), &rsa_private_key)) 928 if (!InitRSAPrivateKey(key->key(), &rsa_private_key))
929 return Status::Error(); 929 return Status::OperationError();
930 930
931 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); 931 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
932 if (!arena.get()) 932 if (!arena.get())
933 return Status::Error(); 933 return Status::OperationError();
934 934
935 if (!SEC_ASN1EncodeItem(arena.get(), 935 if (!SEC_ASN1EncodeItem(arena.get(),
936 &private_key_info.privateKey, 936 &private_key_info.privateKey,
937 &rsa_private_key, 937 &rsa_private_key,
938 RSAPrivateKeyTemplate)) 938 RSAPrivateKeyTemplate))
939 return Status::Error(); 939 return Status::OperationError();
940 940
941 if (SECSuccess != 941 if (SECSuccess !=
942 SECOID_SetAlgorithmID( 942 SECOID_SetAlgorithmID(
943 arena.get(), &private_key_info.algorithm, algorithm, NULL)) 943 arena.get(), &private_key_info.algorithm, algorithm, NULL))
944 return Status::Error(); 944 return Status::OperationError();
945 945
946 if (!SEC_ASN1EncodeInteger( 946 if (!SEC_ASN1EncodeInteger(
947 arena.get(), &private_key_info.version, kPrivateKeyInfoVersion)) 947 arena.get(), &private_key_info.version, kPrivateKeyInfoVersion))
948 return Status::Error(); 948 return Status::OperationError();
949 949
950 crypto::ScopedSECItem encoded_key( 950 crypto::ScopedSECItem encoded_key(
951 SEC_ASN1EncodeItem(NULL, 951 SEC_ASN1EncodeItem(NULL,
952 NULL, 952 NULL,
953 &private_key_info, 953 &private_key_info,
954 SEC_ASN1_GET(SECKEY_PrivateKeyInfoTemplate))); 954 SEC_ASN1_GET(SECKEY_PrivateKeyInfoTemplate)));
955 #else // defined(USE_NSS) 955 #else // defined(USE_NSS)
956 crypto::ScopedSECItem encoded_key( 956 crypto::ScopedSECItem encoded_key(
957 PK11_ExportDERPrivateKeyInfo(key->key(), NULL)); 957 PK11_ExportDERPrivateKeyInfo(key->key(), NULL));
958 #endif // defined(USE_NSS) 958 #endif // defined(USE_NSS)
959 959
960 if (!encoded_key.get()) 960 if (!encoded_key.get())
961 return Status::Error(); 961 return Status::OperationError();
Ryan Sleevi 2014/04/22 23:45:50 None of these are spec-compliant return values.
eroman 2014/04/23 00:11:30 Not sure what you mean by this. Is your concern th
Ryan Sleevi 2014/04/23 00:17:56 That they're not allowed to fail. I agree, it's a
eroman 2014/04/23 00:36:14 I think the spec should allow for such failures.
962 962
963 *buffer = CreateArrayBuffer(encoded_key->data, encoded_key->len); 963 *buffer = CreateArrayBuffer(encoded_key->data, encoded_key->len);
964 return Status::Success(); 964 return Status::Success();
965 } 965 }
966 966
967 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm, 967 Status ImportKeyPkcs8(const blink::WebCryptoAlgorithm& algorithm,
968 const CryptoData& key_data, 968 const CryptoData& key_data,
969 bool extractable, 969 bool extractable,
970 blink::WebCryptoKeyUsageMask usage_mask, 970 blink::WebCryptoKeyUsageMask usage_mask,
971 blink::WebCryptoKey* key) { 971 blink::WebCryptoKey* key) {
(...skipping 12 matching lines...) Expand all
984 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot()); 984 crypto::ScopedPK11Slot slot(PK11_GetInternalSlot());
985 if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot.get(), 985 if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot.get(),
986 &pki_der, 986 &pki_der,
987 NULL, // nickname 987 NULL, // nickname
988 NULL, // publicValue 988 NULL, // publicValue
989 false, // isPerm 989 false, // isPerm
990 false, // isPrivate 990 false, // isPrivate
991 KU_ALL, // usage 991 KU_ALL, // usage
992 &seckey_private_key, 992 &seckey_private_key,
993 NULL) != SECSuccess) { 993 NULL) != SECSuccess) {
994 return Status::Error(); 994 return Status::OperationError();
Ryan Sleevi 2014/04/22 23:45:50 DataError
eroman 2014/04/23 00:11:30 Done.
995 } 995 }
996 DCHECK(seckey_private_key); 996 DCHECK(seckey_private_key);
997 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key); 997 crypto::ScopedSECKEYPrivateKey private_key(seckey_private_key);
998 998
999 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get()); 999 const KeyType sec_key_type = SECKEY_GetPrivateKeyType(private_key.get());
1000 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm)) 1000 if (!ValidateNssKeyTypeAgainstInputAlgorithm(sec_key_type, algorithm))
1001 return Status::Error(); 1001 return Status::OperationError();
Ryan Sleevi 2014/04/22 23:45:50 DataError
eroman 2014/04/23 00:11:30 Done.
1002 1002
1003 blink::WebCryptoKeyAlgorithm key_algorithm; 1003 blink::WebCryptoKeyAlgorithm key_algorithm;
1004 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm)) 1004 if (!CreatePrivateKeyAlgorithm(algorithm, private_key.get(), &key_algorithm))
1005 return Status::ErrorUnexpected(); 1005 return Status::ErrorUnexpected();
1006 1006
1007 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()), 1007 *key = blink::WebCryptoKey::create(new PrivateKey(private_key.Pass()),
1008 blink::WebCryptoKeyTypePrivate, 1008 blink::WebCryptoKeyTypePrivate,
1009 extractable, 1009 extractable,
1010 key_algorithm, 1010 key_algorithm,
1011 usage_mask); 1011 usage_mask);
(...skipping 14 matching lines...) Expand all
1026 SECItem param_item = {siBuffer, NULL, 0}; 1026 SECItem param_item = {siBuffer, NULL, 0};
1027 SECItem data_item = MakeSECItemForBuffer(data); 1027 SECItem data_item = MakeSECItemForBuffer(data);
1028 // First call is to figure out the length. 1028 // First call is to figure out the length.
1029 SECItem signature_item = {siBuffer, NULL, 0}; 1029 SECItem signature_item = {siBuffer, NULL, 0};
1030 1030
1031 if (PK11_SignWithSymKey(key->key(), 1031 if (PK11_SignWithSymKey(key->key(),
1032 PK11_GetMechanism(key->key()), 1032 PK11_GetMechanism(key->key()),
1033 &param_item, 1033 &param_item,
1034 &signature_item, 1034 &signature_item,
1035 &data_item) != SECSuccess) { 1035 &data_item) != SECSuccess) {
1036 return Status::Error(); 1036 return Status::OperationError();
1037 } 1037 }
1038 1038
1039 DCHECK_NE(0u, signature_item.len); 1039 DCHECK_NE(0u, signature_item.len);
1040 1040
1041 *buffer = blink::WebArrayBuffer::create(signature_item.len, 1); 1041 *buffer = blink::WebArrayBuffer::create(signature_item.len, 1);
1042 signature_item.data = reinterpret_cast<unsigned char*>(buffer->data()); 1042 signature_item.data = reinterpret_cast<unsigned char*>(buffer->data());
1043 1043
1044 if (PK11_SignWithSymKey(key->key(), 1044 if (PK11_SignWithSymKey(key->key(),
1045 PK11_GetMechanism(key->key()), 1045 PK11_GetMechanism(key->key()),
1046 &param_item, 1046 &param_item,
1047 &signature_item, 1047 &signature_item,
1048 &data_item) != SECSuccess) { 1048 &data_item) != SECSuccess) {
1049 return Status::Error(); 1049 return Status::OperationError();
1050 } 1050 }
1051 1051
1052 DCHECK_EQ(buffer->byteLength(), signature_item.len); 1052 DCHECK_EQ(buffer->byteLength(), signature_item.len);
1053 return Status::Success(); 1053 return Status::Success();
1054 } 1054 }
1055 1055
1056 // ----------------------------------- 1056 // -----------------------------------
1057 // RsaEsPkcs1v1_5 1057 // RsaEsPkcs1v1_5
1058 // ----------------------------------- 1058 // -----------------------------------
1059 1059
(...skipping 11 matching lines...) Expand all
1071 1071
1072 *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1); 1072 *buffer = blink::WebArrayBuffer::create(encrypted_length_bytes, 1);
1073 unsigned char* const buffer_data = 1073 unsigned char* const buffer_data =
1074 reinterpret_cast<unsigned char*>(buffer->data()); 1074 reinterpret_cast<unsigned char*>(buffer->data());
1075 1075
1076 if (PK11_PubEncryptPKCS1(key->key(), 1076 if (PK11_PubEncryptPKCS1(key->key(),
1077 buffer_data, 1077 buffer_data,
1078 const_cast<unsigned char*>(data.bytes()), 1078 const_cast<unsigned char*>(data.bytes()),
1079 data.byte_length(), 1079 data.byte_length(),
1080 NULL) != SECSuccess) { 1080 NULL) != SECSuccess) {
1081 return Status::Error(); 1081 return Status::OperationError();
1082 } 1082 }
1083 return Status::Success(); 1083 return Status::Success();
1084 } 1084 }
1085 1085
1086 Status DecryptRsaEsPkcs1v1_5(PrivateKey* key, 1086 Status DecryptRsaEsPkcs1v1_5(PrivateKey* key,
1087 const CryptoData& data, 1087 const CryptoData& data,
1088 blink::WebArrayBuffer* buffer) { 1088 blink::WebArrayBuffer* buffer) {
1089 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key()); 1089 const int modulus_length_bytes = PK11_GetPrivateModulusLen(key->key());
1090 if (modulus_length_bytes <= 0) 1090 if (modulus_length_bytes <= 0)
1091 return Status::ErrorUnexpected(); 1091 return Status::ErrorUnexpected();
1092 const unsigned int max_output_length_bytes = modulus_length_bytes; 1092 const unsigned int max_output_length_bytes = modulus_length_bytes;
1093 1093
1094 *buffer = blink::WebArrayBuffer::create(max_output_length_bytes, 1); 1094 *buffer = blink::WebArrayBuffer::create(max_output_length_bytes, 1);
1095 unsigned char* const buffer_data = 1095 unsigned char* const buffer_data =
1096 reinterpret_cast<unsigned char*>(buffer->data()); 1096 reinterpret_cast<unsigned char*>(buffer->data());
1097 1097
1098 unsigned int output_length_bytes = 0; 1098 unsigned int output_length_bytes = 0;
1099 if (PK11_PrivDecryptPKCS1(key->key(), 1099 if (PK11_PrivDecryptPKCS1(key->key(),
1100 buffer_data, 1100 buffer_data,
1101 &output_length_bytes, 1101 &output_length_bytes,
1102 max_output_length_bytes, 1102 max_output_length_bytes,
1103 const_cast<unsigned char*>(data.bytes()), 1103 const_cast<unsigned char*>(data.bytes()),
1104 data.byte_length()) != SECSuccess) { 1104 data.byte_length()) != SECSuccess) {
1105 return Status::Error(); 1105 return Status::OperationError();
1106 } 1106 }
1107 DCHECK_LE(output_length_bytes, max_output_length_bytes); 1107 DCHECK_LE(output_length_bytes, max_output_length_bytes);
1108 ShrinkBuffer(buffer, output_length_bytes); 1108 ShrinkBuffer(buffer, output_length_bytes);
1109 return Status::Success(); 1109 return Status::Success();
1110 } 1110 }
1111 1111
1112 // ----------------------------------- 1112 // -----------------------------------
1113 // RsaSsaPkcs1v1_5 1113 // RsaSsaPkcs1v1_5
1114 // ----------------------------------- 1114 // -----------------------------------
1115 1115
(...skipping 20 matching lines...) Expand all
1136 default: 1136 default:
1137 return Status::ErrorUnsupported(); 1137 return Status::ErrorUnsupported();
1138 } 1138 }
1139 1139
1140 crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0)); 1140 crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0));
1141 if (SEC_SignData(signature_item.get(), 1141 if (SEC_SignData(signature_item.get(),
1142 data.bytes(), 1142 data.bytes(),
1143 data.byte_length(), 1143 data.byte_length(),
1144 key->key(), 1144 key->key(),
1145 sign_alg_tag) != SECSuccess) { 1145 sign_alg_tag) != SECSuccess) {
1146 return Status::Error(); 1146 return Status::OperationError();
1147 } 1147 }
1148 1148
1149 *buffer = CreateArrayBuffer(signature_item->data, signature_item->len); 1149 *buffer = CreateArrayBuffer(signature_item->data, signature_item->len);
1150 return Status::Success(); 1150 return Status::Success();
1151 } 1151 }
1152 1152
1153 Status VerifyRsaSsaPkcs1v1_5(PublicKey* key, 1153 Status VerifyRsaSsaPkcs1v1_5(PublicKey* key,
1154 const blink::WebCryptoAlgorithm& hash, 1154 const blink::WebCryptoAlgorithm& hash,
1155 const CryptoData& signature, 1155 const CryptoData& signature,
1156 const CryptoData& data, 1156 const CryptoData& data,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm, 1215 Status GenerateRsaKeyPair(const blink::WebCryptoAlgorithm& algorithm,
1216 bool extractable, 1216 bool extractable,
1217 blink::WebCryptoKeyUsageMask usage_mask, 1217 blink::WebCryptoKeyUsageMask usage_mask,
1218 unsigned int modulus_length_bits, 1218 unsigned int modulus_length_bits,
1219 const CryptoData& public_exponent, 1219 const CryptoData& public_exponent,
1220 const blink::WebCryptoAlgorithm& hash_or_null, 1220 const blink::WebCryptoAlgorithm& hash_or_null,
1221 blink::WebCryptoKey* public_key, 1221 blink::WebCryptoKey* public_key,
1222 blink::WebCryptoKey* private_key) { 1222 blink::WebCryptoKey* private_key) {
1223 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); 1223 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
1224 if (!slot) 1224 if (!slot)
1225 return Status::Error(); 1225 return Status::OperationError();
1226 1226
1227 unsigned long public_exponent_long; 1227 unsigned long public_exponent_long;
1228 if (!BigIntegerToLong(public_exponent.bytes(), 1228 if (!BigIntegerToLong(public_exponent.bytes(),
1229 public_exponent.byte_length(), 1229 public_exponent.byte_length(),
1230 &public_exponent_long) || 1230 &public_exponent_long) ||
1231 !public_exponent_long) { 1231 !public_exponent_long) {
1232 return Status::ErrorGenerateKeyPublicExponent(); 1232 return Status::ErrorGenerateKeyPublicExponent();
1233 } 1233 }
1234 1234
1235 PK11RSAGenParams rsa_gen_params; 1235 PK11RSAGenParams rsa_gen_params;
(...skipping 29 matching lines...) Expand all
1265 crypto::ScopedSECKEYPrivateKey scoped_sec_private_key( 1265 crypto::ScopedSECKEYPrivateKey scoped_sec_private_key(
1266 PK11_GenerateKeyPairWithOpFlags(slot.get(), 1266 PK11_GenerateKeyPairWithOpFlags(slot.get(),
1267 CKM_RSA_PKCS_KEY_PAIR_GEN, 1267 CKM_RSA_PKCS_KEY_PAIR_GEN,
1268 &rsa_gen_params, 1268 &rsa_gen_params,
1269 &sec_public_key, 1269 &sec_public_key,
1270 attribute_flags, 1270 attribute_flags,
1271 operation_flags, 1271 operation_flags,
1272 operation_flags_mask, 1272 operation_flags_mask,
1273 NULL)); 1273 NULL));
1274 if (!private_key) 1274 if (!private_key)
1275 return Status::Error(); 1275 return Status::OperationError();
1276 1276
1277 blink::WebCryptoKeyAlgorithm key_algorithm; 1277 blink::WebCryptoKeyAlgorithm key_algorithm;
1278 if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm)) 1278 if (!CreatePublicKeyAlgorithm(algorithm, sec_public_key, &key_algorithm))
1279 return Status::ErrorUnexpected(); 1279 return Status::ErrorUnexpected();
1280 1280
1281 *public_key = blink::WebCryptoKey::create( 1281 *public_key = blink::WebCryptoKey::create(
1282 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)), 1282 new PublicKey(crypto::ScopedSECKEYPublicKey(sec_public_key)),
1283 blink::WebCryptoKeyTypePublic, 1283 blink::WebCryptoKeyTypePublic,
1284 true, 1284 true,
1285 key_algorithm, 1285 key_algorithm,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 unsigned keylen_bytes, 1317 unsigned keylen_bytes,
1318 blink::WebCryptoKey* key) { 1318 blink::WebCryptoKey* key) {
1319 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm); 1319 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm);
1320 blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret; 1320 blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret;
1321 1321
1322 if (mech == CKM_INVALID_MECHANISM) 1322 if (mech == CKM_INVALID_MECHANISM)
1323 return Status::ErrorUnsupported(); 1323 return Status::ErrorUnsupported();
1324 1324
1325 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); 1325 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
1326 if (!slot) 1326 if (!slot)
1327 return Status::Error(); 1327 return Status::OperationError();
1328 1328
1329 crypto::ScopedPK11SymKey pk11_key( 1329 crypto::ScopedPK11SymKey pk11_key(
1330 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); 1330 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL));
1331 1331
1332 if (!pk11_key) 1332 if (!pk11_key)
1333 return Status::Error(); 1333 return Status::OperationError();
1334 1334
1335 blink::WebCryptoKeyAlgorithm key_algorithm; 1335 blink::WebCryptoKeyAlgorithm key_algorithm;
1336 if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm)) 1336 if (!CreateSecretKeyAlgorithm(algorithm, keylen_bytes, &key_algorithm))
1337 return Status::ErrorUnexpected(); 1337 return Status::ErrorUnexpected();
1338 1338
1339 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()), 1339 *key = blink::WebCryptoKey::create(new SymKey(pk11_key.Pass()),
1340 key_type, 1340 key_type,
1341 extractable, 1341 extractable,
1342 key_algorithm, 1342 key_algorithm,
1343 usage_mask); 1343 usage_mask);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1380 const SEC_ASN1Template rsa_public_key_template[] = { 1380 const SEC_ASN1Template rsa_public_key_template[] = {
1381 {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(RsaPublicKeyData)}, 1381 {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(RsaPublicKeyData)},
1382 {SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, modulus), }, 1382 {SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, modulus), },
1383 {SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, exponent), }, 1383 {SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, exponent), },
1384 {0, }}; 1384 {0, }};
1385 1385
1386 // DER-encode the public key. 1386 // DER-encode the public key.
1387 crypto::ScopedSECItem pubkey_der( 1387 crypto::ScopedSECItem pubkey_der(
1388 SEC_ASN1EncodeItem(NULL, NULL, &pubkey_in, rsa_public_key_template)); 1388 SEC_ASN1EncodeItem(NULL, NULL, &pubkey_in, rsa_public_key_template));
1389 if (!pubkey_der) 1389 if (!pubkey_der)
1390 return Status::Error(); 1390 return Status::OperationError();
1391 1391
1392 // Import the DER-encoded public key to create an RSA SECKEYPublicKey. 1392 // Import the DER-encoded public key to create an RSA SECKEYPublicKey.
1393 crypto::ScopedSECKEYPublicKey pubkey( 1393 crypto::ScopedSECKEYPublicKey pubkey(
1394 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA)); 1394 SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA));
1395 if (!pubkey) 1395 if (!pubkey)
1396 return Status::Error(); 1396 return Status::OperationError();
Ryan Sleevi 2014/04/22 23:45:50 Not spec compliant return values
1397 1397
1398 blink::WebCryptoKeyAlgorithm key_algorithm; 1398 blink::WebCryptoKeyAlgorithm key_algorithm;
1399 if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm)) 1399 if (!CreatePublicKeyAlgorithm(algorithm, pubkey.get(), &key_algorithm))
1400 return Status::ErrorUnexpected(); 1400 return Status::ErrorUnexpected();
1401 1401
1402 *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()), 1402 *key = blink::WebCryptoKey::create(new PublicKey(pubkey.Pass()),
1403 blink::WebCryptoKeyTypePublic, 1403 blink::WebCryptoKeyTypePublic,
1404 extractable, 1404 extractable,
1405 key_algorithm, 1405 key_algorithm,
1406 usage_mask); 1406 usage_mask);
(...skipping 24 matching lines...) Expand all
1431 1431
1432 const unsigned int output_length = input_length + 8; 1432 const unsigned int output_length = input_length + 8;
1433 *buffer = blink::WebArrayBuffer::create(output_length, 1); 1433 *buffer = blink::WebArrayBuffer::create(output_length, 1);
1434 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); 1434 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer));
1435 1435
1436 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, 1436 if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP,
1437 param_item.get(), 1437 param_item.get(),
1438 wrapping_key->key(), 1438 wrapping_key->key(),
1439 key->key(), 1439 key->key(),
1440 &wrapped_key_item)) { 1440 &wrapped_key_item)) {
1441 return Status::Error(); 1441 return Status::OperationError();
1442 } 1442 }
1443 if (output_length != wrapped_key_item.len) 1443 if (output_length != wrapped_key_item.len)
1444 return Status::ErrorUnexpected(); 1444 return Status::ErrorUnexpected();
1445 1445
1446 return Status::Success(); 1446 return Status::Success();
1447 } 1447 }
1448 1448
1449 Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data, 1449 Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data,
1450 SymKey* wrapping_key, 1450 SymKey* wrapping_key,
1451 const blink::WebCryptoAlgorithm& algorithm, 1451 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). 1486 // temporarily viewed as a symmetric key to be unwrapped (decrypted).
1487 crypto::ScopedPK11SymKey decrypted; 1487 crypto::ScopedPK11SymKey decrypted;
1488 Status status = DoUnwrapSymKeyAesKw( 1488 Status status = DoUnwrapSymKeyAesKw(
1489 data, wrapping_key, CKK_GENERIC_SECRET, CKA_ENCRYPT, &decrypted); 1489 data, wrapping_key, CKK_GENERIC_SECRET, CKA_ENCRYPT, &decrypted);
1490 if (status.IsError()) 1490 if (status.IsError())
1491 return status; 1491 return status;
1492 1492
1493 // Once the decrypt is complete, extract the resultant raw bytes from NSS and 1493 // Once the decrypt is complete, extract the resultant raw bytes from NSS and
1494 // return them to the caller. 1494 // return them to the caller.
1495 if (PK11_ExtractKeyValue(decrypted.get()) != SECSuccess) 1495 if (PK11_ExtractKeyValue(decrypted.get()) != SECSuccess)
1496 return Status::Error(); 1496 return Status::OperationError();
1497 const SECItem* const key_data = PK11_GetKeyData(decrypted.get()); 1497 const SECItem* const key_data = PK11_GetKeyData(decrypted.get());
1498 if (!key_data) 1498 if (!key_data)
1499 return Status::Error(); 1499 return Status::OperationError();
1500 *buffer = webcrypto::CreateArrayBuffer(key_data->data, key_data->len); 1500 *buffer = webcrypto::CreateArrayBuffer(key_data->data, key_data->len);
1501 1501
1502 return Status::Success(); 1502 return Status::Success();
1503 } 1503 }
1504 1504
1505 Status WrapSymKeyRsaEs(PublicKey* wrapping_key, 1505 Status WrapSymKeyRsaEs(PublicKey* wrapping_key,
1506 SymKey* key, 1506 SymKey* key,
1507 blink::WebArrayBuffer* buffer) { 1507 blink::WebArrayBuffer* buffer) {
1508 // Check the raw length of the key to be wrapped against the max size allowed 1508 // 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, 1509 // 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 1510 // the maximum data length that can be encrypted is the wrapping_key's modulus
1511 // byte length minus eleven bytes. 1511 // byte length minus eleven bytes.
1512 const unsigned int input_length_bytes = PK11_GetKeyLength(key->key()); 1512 const unsigned int input_length_bytes = PK11_GetKeyLength(key->key());
1513 const unsigned int modulus_length_bytes = 1513 const unsigned int modulus_length_bytes =
1514 SECKEY_PublicKeyStrength(wrapping_key->key()); 1514 SECKEY_PublicKeyStrength(wrapping_key->key());
1515 if (modulus_length_bytes < 11 || 1515 if (modulus_length_bytes < 11 ||
1516 modulus_length_bytes - 11 < input_length_bytes) 1516 modulus_length_bytes - 11 < input_length_bytes)
1517 return Status::ErrorDataTooLarge(); 1517 return Status::ErrorDataTooLarge();
1518 1518
1519 *buffer = blink::WebArrayBuffer::create(modulus_length_bytes, 1); 1519 *buffer = blink::WebArrayBuffer::create(modulus_length_bytes, 1);
1520 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); 1520 SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer));
1521 1521
1522 if (SECSuccess != 1522 if (SECSuccess !=
1523 PK11_PubWrapSymKey( 1523 PK11_PubWrapSymKey(
1524 CKM_RSA_PKCS, wrapping_key->key(), key->key(), &wrapped_key_item)) { 1524 CKM_RSA_PKCS, wrapping_key->key(), key->key(), &wrapped_key_item)) {
1525 return Status::Error(); 1525 return Status::OperationError();
1526 } 1526 }
1527 if (wrapped_key_item.len != modulus_length_bytes) 1527 if (wrapped_key_item.len != modulus_length_bytes)
1528 return Status::ErrorUnexpected(); 1528 return Status::ErrorUnexpected();
1529 1529
1530 return Status::Success(); 1530 return Status::Success();
1531 } 1531 }
1532 1532
1533 Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data, 1533 Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data,
1534 PrivateKey* wrapping_key, 1534 PrivateKey* wrapping_key,
1535 const blink::WebCryptoAlgorithm& algorithm, 1535 const blink::WebCryptoAlgorithm& algorithm,
(...skipping 22 matching lines...) Expand all
1558 1558
1559 crypto::ScopedPK11SymKey unwrapped_key( 1559 crypto::ScopedPK11SymKey unwrapped_key(
1560 PK11_PubUnwrapSymKeyWithFlagsPerm(wrapping_key->key(), 1560 PK11_PubUnwrapSymKeyWithFlagsPerm(wrapping_key->key(),
1561 &wrapped_key_item, 1561 &wrapped_key_item,
1562 mechanism, 1562 mechanism,
1563 CKA_DECRYPT, 1563 CKA_DECRYPT,
1564 0, 1564 0,
1565 flags, 1565 flags,
1566 false)); 1566 false));
1567 if (!unwrapped_key) 1567 if (!unwrapped_key)
1568 return Status::Error(); 1568 return Status::OperationError();
1569 1569
1570 const unsigned int key_length = PK11_GetKeyLength(unwrapped_key.get()); 1570 const unsigned int key_length = PK11_GetKeyLength(unwrapped_key.get());
1571 1571
1572 blink::WebCryptoKeyAlgorithm key_algorithm; 1572 blink::WebCryptoKeyAlgorithm key_algorithm;
1573 if (!CreateSecretKeyAlgorithm(algorithm, key_length, &key_algorithm)) 1573 if (!CreateSecretKeyAlgorithm(algorithm, key_length, &key_algorithm))
1574 return Status::ErrorUnexpected(); 1574 return Status::ErrorUnexpected();
1575 1575
1576 *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()), 1576 *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()),
1577 blink::WebCryptoKeyTypeSecret, 1577 blink::WebCryptoKeyTypeSecret,
1578 extractable, 1578 extractable,
1579 key_algorithm, 1579 key_algorithm,
1580 usage_mask); 1580 usage_mask);
1581 return Status::Success(); 1581 return Status::Success();
1582 } 1582 }
1583 1583
1584 } // namespace platform 1584 } // namespace platform
1585 1585
1586 } // namespace webcrypto 1586 } // namespace webcrypto
1587 1587
1588 } // namespace content 1588 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698