Chromium Code Reviews| 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 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 ¶m_item, | 1033 ¶m_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 ¶m_item, | 1046 ¶m_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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |