| Index: third_party/WebKit/Source/modules/crypto/SubtleCrypto.cpp
|
| diff --git a/third_party/WebKit/Source/modules/crypto/SubtleCrypto.cpp b/third_party/WebKit/Source/modules/crypto/SubtleCrypto.cpp
|
| index 5b3f2e83ac1283188ae6045fbc76e562bfc81028..7af51490000d4585f6804414362f8b165a8ed7ff 100644
|
| --- a/third_party/WebKit/Source/modules/crypto/SubtleCrypto.cpp
|
| +++ b/third_party/WebKit/Source/modules/crypto/SubtleCrypto.cpp
|
| @@ -147,15 +147,23 @@ ScriptPromise SubtleCrypto::encrypt(ScriptState* scriptState, const AlgorithmIde
|
| // the data parameter passed to the encrypt method.
|
| Vector<uint8_t> data = copyBytes(rawData);
|
|
|
| - WebCryptoAlgorithm algorithm;
|
| - if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationEncrypt, algorithm, result))
|
| + // 14.3.1.3: Let normalizedAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to algorithm and op set to "encrypt".
|
| + WebCryptoAlgorithm normalizedAlgorithm;
|
| + if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationEncrypt, normalizedAlgorithm, result))
|
| return promise;
|
|
|
| - if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageEncrypt, result))
|
| + // 14.3.1.8: If the name member of normalizedAlgorithm is not equal to the
|
| + // name attribute of the [[algorithm]] internal slot of key then
|
| + // throw an InvalidAccessError.
|
| + //
|
| + // 14.3.1.9: If the [[usages]] internal slot of key does not contain an
|
| + // entry that is "encrypt", then throw an InvalidAccessError.
|
| + if (!key->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageEncrypt, result))
|
| return promise;
|
|
|
| - histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key->key());
|
| - Platform::current()->crypto()->encrypt(algorithm, key->key(), data.data(), data.size(), result->result());
|
| + histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgorithm, key->key());
|
| + Platform::current()->crypto()->encrypt(normalizedAlgorithm, key->key(), data.data(), data.size(), result->result());
|
| return promise;
|
| }
|
|
|
| @@ -173,15 +181,23 @@ ScriptPromise SubtleCrypto::decrypt(ScriptState* scriptState, const AlgorithmIde
|
| // the data parameter passed to the decrypt method.
|
| Vector<uint8_t> data = copyBytes(rawData);
|
|
|
| - WebCryptoAlgorithm algorithm;
|
| - if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDecrypt, algorithm, result))
|
| + // 14.3.2.3: Let normalizedAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to algorithm and op set to "decrypt".
|
| + WebCryptoAlgorithm normalizedAlgorithm;
|
| + if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDecrypt, normalizedAlgorithm, result))
|
| return promise;
|
|
|
| - if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageDecrypt, result))
|
| + // 14.3.2.8: If the name member of normalizedAlgorithm is not equal to the
|
| + // name attribute of the [[algorithm]] internal slot of key then
|
| + // throw an InvalidAccessError.
|
| + //
|
| + // 14.3.2.9: If the [[usages]] internal slot of key does not contain an
|
| + // entry that is "decrypt", then throw an InvalidAccessError.
|
| + if (!key->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageDecrypt, result))
|
| return promise;
|
|
|
| - histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key->key());
|
| - Platform::current()->crypto()->decrypt(algorithm, key->key(), data.data(), data.size(), result->result());
|
| + histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgorithm, key->key());
|
| + Platform::current()->crypto()->decrypt(normalizedAlgorithm, key->key(), data.data(), data.size(), result->result());
|
| return promise;
|
| }
|
|
|
| @@ -199,15 +215,23 @@ ScriptPromise SubtleCrypto::sign(ScriptState* scriptState, const AlgorithmIdenti
|
| // the data parameter passed to the sign method.
|
| Vector<uint8_t> data = copyBytes(rawData);
|
|
|
| - WebCryptoAlgorithm algorithm;
|
| - if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationSign, algorithm, result))
|
| + // 14.3.3.3: Let normalizedAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to algorithm and op set to "sign".
|
| + WebCryptoAlgorithm normalizedAlgorithm;
|
| + if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationSign, normalizedAlgorithm, result))
|
| return promise;
|
|
|
| - if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageSign, result))
|
| + // 14.3.3.8: If the name member of normalizedAlgorithm is not equal to the
|
| + // name attribute of the [[algorithm]] internal slot of key then
|
| + // throw an InvalidAccessError.
|
| + //
|
| + // 14.3.3.9: If the [[usages]] internal slot of key does not contain an
|
| + // entry that is "sign", then throw an InvalidAccessError.
|
| + if (!key->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageSign, result))
|
| return promise;
|
|
|
| - histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key->key());
|
| - Platform::current()->crypto()->sign(algorithm, key->key(), data.data(), data.size(), result->result());
|
| + histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgorithm, key->key());
|
| + Platform::current()->crypto()->sign(normalizedAlgorithm, key->key(), data.data(), data.size(), result->result());
|
| return promise;
|
| }
|
|
|
| @@ -225,19 +249,27 @@ ScriptPromise SubtleCrypto::verifySignature(ScriptState* scriptState, const Algo
|
| // held by the signature parameter passed to the verify method.
|
| Vector<uint8_t> signature = copyBytes(rawSignature);
|
|
|
| - WebCryptoAlgorithm algorithm;
|
| - if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationVerify, algorithm, result))
|
| + // 14.3.4.3: Let normalizedAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to algorithm and op set to "verify".
|
| + WebCryptoAlgorithm normalizedAlgorithm;
|
| + if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationVerify, normalizedAlgorithm, result))
|
| return promise;
|
|
|
| // 14.3.4.5: Let data be the result of getting a copy of the bytes held by
|
| // the data parameter passed to the verify method.
|
| Vector<uint8_t> data = copyBytes(rawData);
|
|
|
| - if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageVerify, result))
|
| + // 14.3.4.9: If the name member of normalizedAlgorithm is not equal to the
|
| + // name attribute of the [[algorithm]] internal slot of key then throw an
|
| + // InvalidAccessError.
|
| + //
|
| + // 14.3.4.10: If the [[usages]] internal slot of key does not contain an
|
| + // entry that is "verify", then throw an InvalidAccessError.
|
| + if (!key->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageVerify, result))
|
| return promise;
|
|
|
| - histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key->key());
|
| - Platform::current()->crypto()->verifySignature(algorithm, key->key(), signature.data(), signature.size(), data.data(), data.size(), result->result());
|
| + histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgorithm, key->key());
|
| + Platform::current()->crypto()->verifySignature(normalizedAlgorithm, key->key(), signature.data(), signature.size(), data.data(), data.size(), result->result());
|
| return promise;
|
| }
|
|
|
| @@ -255,17 +287,21 @@ ScriptPromise SubtleCrypto::digest(ScriptState* scriptState, const AlgorithmIden
|
| // by the data parameter passed to the digest method.
|
| Vector<uint8_t> data = copyBytes(rawData);
|
|
|
| - WebCryptoAlgorithm algorithm;
|
| - if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDigest, algorithm, result))
|
| + // 14.3.5.3: Let normalizedAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to algorithm and op set to "digest".
|
| + WebCryptoAlgorithm normalizedAlgorithm;
|
| + if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDigest, normalizedAlgorithm, result))
|
| return promise;
|
|
|
| - histogramAlgorithm(scriptState->getExecutionContext(), algorithm);
|
| - Platform::current()->crypto()->digest(algorithm, data.data(), data.size(), result->result());
|
| + histogramAlgorithm(scriptState->getExecutionContext(), normalizedAlgorithm);
|
| + Platform::current()->crypto()->digest(normalizedAlgorithm, data.data(), data.size(), result->result());
|
| return promise;
|
| }
|
|
|
| ScriptPromise SubtleCrypto::generateKey(ScriptState* scriptState, const AlgorithmIdentifier& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages)
|
| {
|
| + // Method described by: https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-generateKey
|
| +
|
| CryptoResultImpl* result = CryptoResultImpl::create(scriptState);
|
| ScriptPromise promise = result->promise();
|
|
|
| @@ -276,12 +312,19 @@ ScriptPromise SubtleCrypto::generateKey(ScriptState* scriptState, const Algorith
|
| if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result))
|
| return promise;
|
|
|
| - WebCryptoAlgorithm algorithm;
|
| - if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationGenerateKey, algorithm, result))
|
| + // 14.3.6.2: Let normalizedAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to algorithm and op set to
|
| + // "generateKey".
|
| + WebCryptoAlgorithm normalizedAlgorithm;
|
| + if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationGenerateKey, normalizedAlgorithm, result))
|
| return promise;
|
|
|
| - histogramAlgorithm(scriptState->getExecutionContext(), algorithm);
|
| - Platform::current()->crypto()->generateKey(algorithm, extractable, keyUsages, result->result());
|
| + // NOTE: Steps (8) and (9) disallow empty usages on secret and private
|
| + // keys. This normative requirement is enforced by the platform
|
| + // implementation in the call below.
|
| +
|
| + histogramAlgorithm(scriptState->getExecutionContext(), normalizedAlgorithm);
|
| + Platform::current()->crypto()->generateKey(normalizedAlgorithm, extractable, keyUsages, result->result());
|
| return promise;
|
| }
|
|
|
| @@ -299,25 +342,33 @@ ScriptPromise SubtleCrypto::importKey(ScriptState* scriptState, const String& ra
|
| if (!CryptoKey::parseFormat(rawFormat, format, result))
|
| return promise;
|
|
|
| + WebCryptoKeyUsageMask keyUsages;
|
| + if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result))
|
| + return promise;
|
| +
|
| + // 14.3.9.2: Let normalizedAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to algorithm and op set to
|
| + // "importKey".
|
| + WebCryptoAlgorithm normalizedAlgorithm;
|
| + if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationImportKey, normalizedAlgorithm, result))
|
| + return promise;
|
| +
|
| + // TODO(eroman): Match the procedure given in the spec to more
|
| + // easily provide a normative reference.
|
| if (rawKeyData.isDictionary()) {
|
| if (format != WebCryptoKeyFormatJwk) {
|
| - result->completeWithError(WebCryptoErrorTypeData, "Key data must be a buffer for non-JWK formats");
|
| + result->completeWithError(WebCryptoErrorTypeType, "Key data must be a buffer for non-JWK formats");
|
| return promise;
|
| }
|
| } else if (format == WebCryptoKeyFormatJwk) {
|
| - result->completeWithError(WebCryptoErrorTypeData, "Key data must be an object for JWK import");
|
| + result->completeWithError(WebCryptoErrorTypeType, "Key data must be an object for JWK import");
|
| return promise;
|
| }
|
|
|
| - WebCryptoKeyUsageMask keyUsages;
|
| - if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result))
|
| - return promise;
|
| -
|
| - WebCryptoAlgorithm algorithm;
|
| - if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationImportKey, algorithm, result))
|
| - return promise;
|
| -
|
| Vector<uint8_t> keyData;
|
| +
|
| + // TODO(eroman): Match the procedure given in the spec to more
|
| + // easily provide a normative reference.
|
| if (rawKeyData.isArrayBuffer()) {
|
| keyData = copyBytes(rawKeyData.getAsArrayBuffer());
|
| } else if (rawKeyData.isArrayBufferView()) {
|
| @@ -326,13 +377,15 @@ ScriptPromise SubtleCrypto::importKey(ScriptState* scriptState, const String& ra
|
| if (!copyJwkDictionaryToJson(rawKeyData.getAsDictionary(), keyData, result))
|
| return promise;
|
| }
|
| - histogramAlgorithm(scriptState->getExecutionContext(), algorithm);
|
| - Platform::current()->crypto()->importKey(format, keyData.data(), keyData.size(), algorithm, extractable, keyUsages, result->result());
|
| + histogramAlgorithm(scriptState->getExecutionContext(), normalizedAlgorithm);
|
| + Platform::current()->crypto()->importKey(format, keyData.data(), keyData.size(), normalizedAlgorithm, extractable, keyUsages, result->result());
|
| return promise;
|
| }
|
|
|
| ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& rawFormat, CryptoKey* key)
|
| {
|
| + // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-SubtleCrypto-method-exportKey
|
| +
|
| CryptoResultImpl* result = CryptoResultImpl::create(scriptState);
|
| ScriptPromise promise = result->promise();
|
|
|
| @@ -343,6 +396,8 @@ ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& ra
|
| if (!CryptoKey::parseFormat(rawFormat, format, result))
|
| return promise;
|
|
|
| + // 14.3.10.6: If the [[extractable]] internal slot of key is false, then
|
| + // throw an InvalidAccessError.
|
| if (!key->extractable()) {
|
| result->completeWithError(WebCryptoErrorTypeInvalidAccess, "key is not extractable");
|
| return promise;
|
| @@ -355,6 +410,8 @@ ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& ra
|
|
|
| ScriptPromise SubtleCrypto::wrapKey(ScriptState* scriptState, const String& rawFormat, CryptoKey* key, CryptoKey* wrappingKey, const AlgorithmIdentifier& rawWrapAlgorithm)
|
| {
|
| + // Method described by: https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-wrapKey
|
| +
|
| CryptoResultImpl* result = CryptoResultImpl::create(scriptState);
|
| ScriptPromise promise = result->promise();
|
|
|
| @@ -365,21 +422,40 @@ ScriptPromise SubtleCrypto::wrapKey(ScriptState* scriptState, const String& rawF
|
| if (!CryptoKey::parseFormat(rawFormat, format, result))
|
| return promise;
|
|
|
| - WebCryptoAlgorithm wrapAlgorithm;
|
| - if (!parseAlgorithm(rawWrapAlgorithm, WebCryptoOperationWrapKey, wrapAlgorithm, result))
|
| + // 14.3.11.2: Let normalizedAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to algorithm and op set to "wrapKey".
|
| + //
|
| + // 14.3.11.3: If an error occurred, let normalizedAlgorithm be the result
|
| + // of normalizing an algorithm, with alg set to algorithm and op
|
| + // set to "encrypt".
|
| + WebCryptoAlgorithm normalizedAlgorithm;
|
| + if (!parseAlgorithm(rawWrapAlgorithm, WebCryptoOperationWrapKey, normalizedAlgorithm, result))
|
| return promise;
|
|
|
| + // 14.3.11.9: If the name member of normalizedAlgorithm is not equal to the
|
| + // name attribute of the [[algorithm]] internal slot of
|
| + // wrappingKey then throw an InvalidAccessError.
|
| + //
|
| + // 14.3.11.10: If the [[usages]] internal slot of wrappingKey does not
|
| + // contain an entry that is "wrapKey", then throw an
|
| + // InvalidAccessError.
|
| + if (!wrappingKey->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageWrapKey, result))
|
| + return promise;
|
| +
|
| + // TODO(crbug.com/628416): The error from step 11
|
| + // (NotSupportedError) is thrown after step 12 which does not match
|
| + // the spec order.
|
| +
|
| + // 14.3.11.12: If the [[extractable]] internal slot of key is false, then
|
| + // throw an InvalidAccessError.
|
| if (!key->extractable()) {
|
| result->completeWithError(WebCryptoErrorTypeInvalidAccess, "key is not extractable");
|
| return promise;
|
| }
|
|
|
| - if (!wrappingKey->canBeUsedForAlgorithm(wrapAlgorithm, WebCryptoKeyUsageWrapKey, result))
|
| - return promise;
|
| -
|
| - histogramAlgorithmAndKey(scriptState->getExecutionContext(), wrapAlgorithm, wrappingKey->key());
|
| + histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgorithm, wrappingKey->key());
|
| histogramKey(scriptState->getExecutionContext(), key->key());
|
| - Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKey->key(), wrapAlgorithm, result->result());
|
| + Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKey->key(), normalizedAlgorithm, result->result());
|
| return promise;
|
| }
|
|
|
| @@ -406,45 +482,79 @@ ScriptPromise SubtleCrypto::unwrapKey(ScriptState* scriptState, const String& ra
|
| // method.
|
| Vector<uint8_t> wrappedKey = copyBytes(rawWrappedKey);
|
|
|
| - WebCryptoAlgorithm unwrapAlgorithm;
|
| - if (!parseAlgorithm(rawUnwrapAlgorithm, WebCryptoOperationUnwrapKey, unwrapAlgorithm, result))
|
| - return promise;
|
| -
|
| - WebCryptoAlgorithm unwrappedKeyAlgorithm;
|
| - if (!parseAlgorithm(rawUnwrappedKeyAlgorithm, WebCryptoOperationImportKey, unwrappedKeyAlgorithm, result))
|
| - return promise;
|
| -
|
| - if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, WebCryptoKeyUsageUnwrapKey, result))
|
| - return promise;
|
| -
|
| - histogramAlgorithmAndKey(scriptState->getExecutionContext(), unwrapAlgorithm, unwrappingKey->key());
|
| - histogramAlgorithm(scriptState->getExecutionContext(), unwrappedKeyAlgorithm);
|
| - Platform::current()->crypto()->unwrapKey(format, wrappedKey.data(), wrappedKey.size(), unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages, result->result());
|
| + // 14.3.12.3: Let normalizedAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to algorithm and op set to
|
| + // "unwrapKey".
|
| + //
|
| + // 14.3.12.4: If an error occurred, let normalizedAlgorithm be the result
|
| + // of normalizing an algorithm, with alg set to algorithm and op
|
| + // set to "decrypt".
|
| + WebCryptoAlgorithm normalizedAlgorithm;
|
| + if (!parseAlgorithm(rawUnwrapAlgorithm, WebCryptoOperationUnwrapKey, normalizedAlgorithm, result))
|
| + return promise;
|
| +
|
| + // 14.3.12.6: Let normalizedKeyAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to unwrappedKeyAlgorithm and op set
|
| + // to "importKey".
|
| + WebCryptoAlgorithm normalizedKeyAlgorithm;
|
| + if (!parseAlgorithm(rawUnwrappedKeyAlgorithm, WebCryptoOperationImportKey, normalizedKeyAlgorithm, result))
|
| + return promise;
|
| +
|
| + // 14.3.12.11: If the name member of normalizedAlgorithm is not equal to
|
| + // the name attribute of the [[algorithm]] internal slot of
|
| + // unwrappingKey then throw an InvalidAccessError.
|
| + //
|
| + // 14.3.12.12: If the [[usages]] internal slot of unwrappingKey does not
|
| + // contain an entry that is "unwrapKey", then throw an
|
| + // InvalidAccessError.
|
| + if (!unwrappingKey->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageUnwrapKey, result))
|
| + return promise;
|
| +
|
| + // NOTE: Step (16) disallows empty usages on secret and private keys. This
|
| + // normative requirement is enforced by the platform implementation in the
|
| + // call below.
|
| +
|
| + histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgorithm, unwrappingKey->key());
|
| + histogramAlgorithm(scriptState->getExecutionContext(), normalizedKeyAlgorithm);
|
| + Platform::current()->crypto()->unwrapKey(format, wrappedKey.data(), wrappedKey.size(), unwrappingKey->key(), normalizedAlgorithm, normalizedKeyAlgorithm, extractable, keyUsages, result->result());
|
| return promise;
|
| }
|
|
|
| ScriptPromise SubtleCrypto::deriveBits(ScriptState* scriptState, const AlgorithmIdentifier& rawAlgorithm, CryptoKey* baseKey, unsigned lengthBits)
|
| {
|
| + // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-SubtleCrypto-method-deriveBits
|
| +
|
| CryptoResultImpl* result = CryptoResultImpl::create(scriptState);
|
| ScriptPromise promise = result->promise();
|
|
|
| if (!canAccessWebCrypto(scriptState, result))
|
| return promise;
|
|
|
| - WebCryptoAlgorithm algorithm;
|
| - if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDeriveBits, algorithm, result))
|
| + // 14.3.8.2: Let normalizedAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to algorithm and op set to
|
| + // "deriveBits".
|
| + WebCryptoAlgorithm normalizedAlgorithm;
|
| + if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDeriveBits, normalizedAlgorithm, result))
|
| return promise;
|
|
|
| - if (!baseKey->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageDeriveBits, result))
|
| + // 14.3.8.7: If the name member of normalizedAlgorithm is not equal to the
|
| + // name attribute of the [[algorithm]] internal slot of baseKey
|
| + // then throw an InvalidAccessError.
|
| + //
|
| + // 14.3.8.8: If the [[usages]] internal slot of baseKey does not contain an
|
| + // entry that is "deriveBits", then throw an InvalidAccessError.
|
| + if (!baseKey->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageDeriveBits, result))
|
| return promise;
|
|
|
| - histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, baseKey->key());
|
| - Platform::current()->crypto()->deriveBits(algorithm, baseKey->key(), lengthBits, result->result());
|
| + histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgorithm, baseKey->key());
|
| + Platform::current()->crypto()->deriveBits(normalizedAlgorithm, baseKey->key(), lengthBits, result->result());
|
| return promise;
|
| }
|
|
|
| ScriptPromise SubtleCrypto::deriveKey(ScriptState* scriptState, const AlgorithmIdentifier& rawAlgorithm, CryptoKey* baseKey, const AlgorithmIdentifier& rawDerivedKeyType, bool extractable, const Vector<String>& rawKeyUsages)
|
| {
|
| + // Method described by: https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-deriveKey
|
| +
|
| CryptoResultImpl* result = CryptoResultImpl::create(scriptState);
|
| ScriptPromise promise = result->promise();
|
|
|
| @@ -455,24 +565,48 @@ ScriptPromise SubtleCrypto::deriveKey(ScriptState* scriptState, const AlgorithmI
|
| if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result))
|
| return promise;
|
|
|
| - WebCryptoAlgorithm algorithm;
|
| - if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDeriveBits, algorithm, result))
|
| - return promise;
|
| -
|
| - if (!baseKey->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageDeriveKey, result))
|
| + // 14.3.7.2: Let normalizedAlgorithm be the result of normalizing an
|
| + // algorithm, with alg set to algorithm and op set to
|
| + // "deriveBits".
|
| + WebCryptoAlgorithm normalizedAlgorithm;
|
| + if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDeriveBits, normalizedAlgorithm, result))
|
| return promise;
|
|
|
| - WebCryptoAlgorithm importAlgorithm;
|
| - if (!parseAlgorithm(rawDerivedKeyType, WebCryptoOperationImportKey, importAlgorithm, result))
|
| + // 14.3.7.4: Let normalizedDerivedKeyAlgorithm be the result of normalizing
|
| + // an algorithm, with alg set to derivedKeyType and op set to
|
| + // "importKey".
|
| + WebCryptoAlgorithm normalizedDerivedKeyAlgorithm;
|
| + if (!parseAlgorithm(rawDerivedKeyType, WebCryptoOperationImportKey, normalizedDerivedKeyAlgorithm, result))
|
| return promise;
|
|
|
| + // TODO(eroman): The description in the spec needs to be updated as
|
| + // it doesn't describe algorithm normalization for the Get Key
|
| + // Length parameters (https://github.com/w3c/webcrypto/issues/127)
|
| + // For now reference step 10 which is the closest.
|
| + //
|
| + // 14.3.7.10: If the name member of normalizedDerivedKeyAlgorithm does not
|
| + // identify a registered algorithm that supports the get key length
|
| + // operation, then throw a NotSupportedError.
|
| WebCryptoAlgorithm keyLengthAlgorithm;
|
| if (!parseAlgorithm(rawDerivedKeyType, WebCryptoOperationGetKeyLength, keyLengthAlgorithm, result))
|
| return promise;
|
|
|
| - histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, baseKey->key());
|
| - histogramAlgorithm(scriptState->getExecutionContext(), importAlgorithm);
|
| - Platform::current()->crypto()->deriveKey(algorithm, baseKey->key(), importAlgorithm, keyLengthAlgorithm, extractable, keyUsages, result->result());
|
| + // 14.3.7.11: If the name member of normalizedAlgorithm is not equal to the
|
| + // name attribute of the [[algorithm]] internal slot of baseKey
|
| + // then throw an InvalidAccessError.
|
| + //
|
| + // 14.3.7.12: If the [[usages]] internal slot of baseKey does not contain
|
| + // an entry that is "deriveKey", then throw an InvalidAccessError.
|
| + if (!baseKey->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageDeriveKey, result))
|
| + return promise;
|
| +
|
| + // NOTE: Step (16) disallows empty usages on secret and private keys. This
|
| + // normative requirement is enforced by the platform implementation in the
|
| + // call below.
|
| +
|
| + histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgorithm, baseKey->key());
|
| + histogramAlgorithm(scriptState->getExecutionContext(), normalizedDerivedKeyAlgorithm);
|
| + Platform::current()->crypto()->deriveKey(normalizedAlgorithm, baseKey->key(), normalizedDerivedKeyAlgorithm, keyLengthAlgorithm, extractable, keyUsages, result->result());
|
| return promise;
|
| }
|
|
|
|
|