Chromium Code Reviews| Index: content/renderer/webcrypto/platform_crypto_nss.cc |
| diff --git a/content/renderer/webcrypto/platform_crypto_nss.cc b/content/renderer/webcrypto/platform_crypto_nss.cc |
| index 147814bc26ad38474bef15a879a62174c485ec16..e01110587ada39e1504ca765ee9ed962b314d7e2 100644 |
| --- a/content/renderer/webcrypto/platform_crypto_nss.cc |
| +++ b/content/renderer/webcrypto/platform_crypto_nss.cc |
| @@ -1126,8 +1126,7 @@ Status WrapSymKeyAesKw(SymKey* wrapping_key, |
| if (input_length % 8) |
| return Status::ErrorInvalidAesKwDataLength(); |
| - SECItem iv_item = |
| - MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv))); |
| + SECItem iv_item = MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv))); |
| crypto::ScopedSECItem param_item( |
| PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item)); |
| if (!param_item) |
| @@ -1135,8 +1134,7 @@ Status WrapSymKeyAesKw(SymKey* wrapping_key, |
| const unsigned int output_length = input_length + 8; |
| *buffer = blink::WebArrayBuffer::create(output_length, 1); |
| - unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data()); |
| - SECItem wrapped_key_item = {siBuffer, buffer_data, output_length}; |
| + SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); |
| if (SECSuccess != PK11_WrapSymKey(CKM_NSS_AES_KEY_WRAP, |
| param_item.get(), |
| @@ -1160,8 +1158,7 @@ Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data, |
| DCHECK_GE(wrapped_key_data.byte_length(), 24u); |
| DCHECK_EQ(wrapped_key_data.byte_length() % 8, 0u); |
| - SECItem iv_item = |
| - MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv))); |
| + SECItem iv_item = MakeSECItemForBuffer(CryptoData(kAesIv, sizeof(kAesIv))); |
| crypto::ScopedSECItem param_item( |
| PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP, &iv_item)); |
| if (!param_item) |
| @@ -1204,6 +1201,84 @@ Status UnwrapSymKeyAesKw(const CryptoData& wrapped_key_data, |
| return Status::Success(); |
| } |
| +Status WrapSymKeyRsaEs(PublicKey* wrapping_key, |
| + SymKey* key, |
| + blink::WebArrayBuffer* buffer) { |
| + // Check the raw length of the key to be wrapped against the max size allowed |
| + // by the RSA wrapping key. With PKCS#1 v1.5 padding used in this function, |
| + // the maximum data length that can be encrypted is the wrapping_key's modulus |
| + // byte length minus eleven bytes. |
| + const unsigned int input_length_bytes = PK11_GetKeyLength(key->key()); |
| + const unsigned int modulus_length_bytes = |
| + SECKEY_PublicKeyStrength(wrapping_key->key()); |
| + if (input_length_bytes > modulus_length_bytes - 11) |
|
eroman
2014/03/06 04:31:16
Is it possible for modulus_length_bytes to be < 11
padolph
2014/03/10 19:02:54
Extremely unlikely as it would be very bad securit
|
| + return Status::ErrorDataTooLarge(); |
| + |
| + *buffer = blink::WebArrayBuffer::create(modulus_length_bytes, 1); |
| + SECItem wrapped_key_item = MakeSECItemForBuffer(CryptoData(*buffer)); |
| + |
| + if (SECSuccess != |
| + PK11_PubWrapSymKey( |
|
eroman
2014/03/06 04:31:16
is this the automated formatting? I think it needs
padolph
2014/03/10 19:02:54
Yes. I run 'git cl format' before upload now. Will
|
| + CKM_RSA_PKCS, wrapping_key->key(), key->key(), &wrapped_key_item)) { |
| + return Status::Error(); |
| + } |
| + if (wrapped_key_item.len != modulus_length_bytes) |
| + return Status::ErrorUnexpected(); |
| + |
| + return Status::Success(); |
| +} |
| + |
| +Status UnwrapSymKeyRsaEs(const CryptoData& wrapped_key_data, |
| + PrivateKey* wrapping_key, |
| + const blink::WebCryptoAlgorithm& algorithm, |
| + bool extractable, |
| + blink::WebCryptoKeyUsageMask usage_mask, |
| + blink::WebCryptoKey* key) { |
| + |
| + // Verify wrapped_key_data size does not exceed the modulus of the RSA key. |
| + const int modulus_length_bytes = |
| + PK11_GetPrivateModulusLen(wrapping_key->key()); |
| + if (modulus_length_bytes <= 0) |
| + return Status::ErrorUnexpected(); |
| + if (wrapped_key_data.byte_length() > |
| + static_cast<unsigned int>(modulus_length_bytes)) |
| + return Status::ErrorDataTooLarge(); |
| + |
| + // Determine the proper NSS key properties from the input algorithm. |
| + CK_MECHANISM_TYPE mechanism; |
| + CK_FLAGS flags; |
| + Status status = |
| + WebCryptoAlgorithmToNssMechFlags(algorithm, &mechanism, &flags); |
| + if (status.IsError()) |
| + return status; |
| + |
| + SECItem wrapped_key_item = MakeSECItemForBuffer(wrapped_key_data); |
| + |
| + crypto::ScopedPK11SymKey unwrapped_key( |
| + PK11_PubUnwrapSymKeyWithFlagsPerm(wrapping_key->key(), |
| + &wrapped_key_item, |
| + mechanism, |
| + CKA_DECRYPT, |
| + 0, |
| + flags, |
| + false)); |
| + if (!unwrapped_key) |
| + return Status::Error(); |
| + |
| + const unsigned int key_length = PK11_GetKeyLength(unwrapped_key.get()); |
| + |
| + blink::WebCryptoKeyAlgorithm key_algorithm; |
| + if (!CreateSecretKeyAlgorithm(algorithm, key_length, &key_algorithm)) |
| + return Status::ErrorUnexpected(); |
| + |
| + *key = blink::WebCryptoKey::create(new SymKey(unwrapped_key.Pass()), |
| + blink::WebCryptoKeyTypeSecret, |
| + extractable, |
| + key_algorithm, |
| + usage_mask); |
| + return Status::Success(); |
| +} |
| + |
| } // namespace platform |
| } // namespace webcrypto |