Changeset 209200 in webkit
- Timestamp:
- Dec 1, 2016 1:45:31 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 21 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r209199 r209200 1 2016-12-01 Jiewen Tan <jiewen_tan@apple.com> 2 3 Update SubtleCrypto::unwrapKey to match the latest spec 4 https://bugs.webkit.org/show_bug.cgi?id=164747 5 <rdar://problem/29258198> 6 7 Reviewed by Brent Fulgham. 8 9 * crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private-expected.txt: Added. 10 * crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private.html: Added. 11 * crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public-expected.txt: Added. 12 * crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public.html: Added. 13 * crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key-expected.txt: Added. 14 * crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key.html: Added. 15 * crypto/subtle/aes-kw-import-key-unwrap-raw-key-expected.txt: Added. 16 * crypto/subtle/aes-kw-import-key-unwrap-raw-key.html: Added. 17 * crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key-expected.txt: Added. 18 * crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key.html: Added. 19 * crypto/subtle/unwrapKey-malformed-parameters-expected.txt: Added. 20 * crypto/subtle/unwrapKey-malformed-parameters.html: Added. 21 * crypto/workers/subtle/aes-cbc-import-key-unwrap-key-expected.txt: Added. 22 * crypto/workers/subtle/aes-cbc-import-key-unwrap-key.html: Added. 23 * crypto/workers/subtle/aes-kw-import-key-unwrap-key-expected.txt: Added. 24 * crypto/workers/subtle/aes-kw-import-key-unwrap-key.html: Added. 25 * crypto/workers/subtle/resources/aes-cbc-import-key-unwrap-key.js: Added. 26 * crypto/workers/subtle/resources/aes-kw-import-key-unwrap-key.js: Added. 27 * crypto/workers/subtle/resources/rsa-oaep-import-key-unwrap-key.js: Added. 28 * crypto/workers/subtle/rsa-oaep-import-key-unwrap-key-expected.txt: Added. 29 * crypto/workers/subtle/rsa-oaep-import-key-unwrap-key.html: Added. 30 1 31 2016-12-01 Dave Hyatt <hyatt@apple.com> 2 32 -
trunk/LayoutTests/imported/w3c/ChangeLog
r209191 r209200 1 2016-12-01 Jiewen Tan <jiewen_tan@apple.com> 2 3 Update SubtleCrypto::unwrapKey to match the latest spec 4 https://bugs.webkit.org/show_bug.cgi?id=164747 5 <rdar://problem/29258198> 6 7 Reviewed by Brent Fulgham. 8 9 * WebCryptoAPI/idlharness-expected.txt: 10 1 11 2016-12-01 Jiewen Tan <jiewen_tan@apple.com> 2 12 -
trunk/LayoutTests/imported/w3c/WebCryptoAPI/idlharness-expected.txt
r209191 r209200 66 66 PASS SubtleCrypto interface: crypto.subtle must inherit property "wrapKey" with the proper type (10) 67 67 PASS SubtleCrypto interface: calling wrapKey(KeyFormat,CryptoKey,CryptoKey,AlgorithmIdentifier) on crypto.subtle with too few arguments must throw TypeError 68 FAIL SubtleCrypto interface: crypto.subtle must inherit property "unwrapKey" with the proper type (11) assert_inherits: property "unwrapKey" not found in prototype chain 69 FAIL SubtleCrypto interface: calling unwrapKey(KeyFormat,BufferSource,CryptoKey,AlgorithmIdentifier,AlgorithmIdentifier,boolean,[object Object]) on crypto.subtle with too few arguments must throw TypeError assert_inherits: property "unwrapKey" not found in prototype chain 68 PASS SubtleCrypto interface: crypto.subtle must inherit property "unwrapKey" with the proper type (11) 69 PASS SubtleCrypto interface: calling unwrapKey(KeyFormat,BufferSource,CryptoKey,AlgorithmIdentifier,AlgorithmIdentifier,boolean,[object Object]) on crypto.subtle with too few arguments must throw TypeError 70 70 -
trunk/Source/WebCore/ChangeLog
r209199 r209200 1 2016-12-01 Jiewen Tan <jiewen_tan@apple.com> 2 3 Update SubtleCrypto::unwrapKey to match the latest spec 4 https://bugs.webkit.org/show_bug.cgi?id=164747 5 <rdar://problem/29258198> 6 7 Reviewed by Brent Fulgham. 8 9 This patch does following few things: 10 1. It updates the SubtleCrypto::unwrapKey method to match the latest spec: 11 https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-unwrapKey. 12 It also refers to the latest Editor's Draft to a certain degree: 13 https://w3c.github.io/webcrypto/Overview.html#SubtleCrypto-method-unwrapKey. 14 2. It implements unwrapKey operations of the following algorithms: AES-KW. 15 16 Tests: crypto/subtle/aes-cbc-import-key-unwrap-jwk-rsa-key-private.html 17 crypto/subtle/aes-cbc-import-key-uwrap-jwk-rsa-key-public.html 18 crypto/subtle/aes-kw-generate-key-wrap-key-unwrap-key.html 19 crypto/subtle/aes-kw-import-key-unwrap-raw-key.html 20 crypto/subtle/rsa-oaep-import-key-unwrap-jwk-oct-key.html 21 crypto/subtle/unwrapKey-malformed-parameters.html 22 crypto/workers/subtle/aes-cbc-import-key-unwrap-key.html 23 crypto/workers/subtle/aes-kw-import-key-unwrap-key.html 24 crypto/workers/subtle/rsa-oaep-import-key-unwrap-key.html 25 26 * bindings/js/JSSubtleCryptoCustom.cpp: 27 (WebCore::normalizeCryptoAlgorithmParameters): 28 (WebCore::jsSubtleCryptoFunctionWrapKeyPromise): 29 Add some comments. 30 (WebCore::jsSubtleCryptoFunctionUnwrapKeyPromise): 31 (WebCore::JSSubtleCrypto::unwrapKey): 32 * crypto/CryptoAlgorithm.cpp: 33 (WebCore::CryptoAlgorithm::unwrapKey): 34 * crypto/CryptoAlgorithm.h: 35 * crypto/SubtleCrypto.idl: 36 * crypto/algorithms/CryptoAlgorithmAES_KW.cpp: 37 (WebCore::CryptoAlgorithmAES_KW::unwrapKey): 38 * crypto/algorithms/CryptoAlgorithmAES_KW.h: 39 * crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp: 40 (WebCore::CryptoAlgorithmAES_KW::platformUnwrapKey): 41 * crypto/mac/CryptoAlgorithmAES_KWMac.cpp: 42 (WebCore::unwrapKeyAES_KW): 43 (WebCore::CryptoAlgorithmAES_KW::platformUnwrapKey): 44 (WebCore::CryptoAlgorithmAES_KW::platformDecrypt): 45 1 46 2016-12-01 Dave Hyatt <hyatt@apple.com> 2 47 -
trunk/Source/WebCore/bindings/js/JSSubtleCryptoCustom.cpp
r209191 r209200 37 37 #include "JSCryptoKeyPair.h" 38 38 #include "JSDOMPromise.h" 39 #include "JSDOMWrapper.h" 39 40 #include "JSHmacKeyParams.h" 40 41 #include "JSJsonWebKey.h" … … 64 65 ImportKey, 65 66 WrapKey, 67 UnwrapKey 66 68 }; 67 69 … … 233 235 break; 234 236 case Operations::WrapKey: 237 case Operations::UnwrapKey: 235 238 switch (*identifier) { 236 239 case CryptoAlgorithmIdentifier::AES_KW: … … 954 957 return; 955 958 } 959 // The following operation should be performed asynchronously. 956 960 wrapAlgorithm->encrypt(WTFMove(wrapParams), wrappingKey.releaseNonNull(), WTFMove(bytes), WTFMove(callback), WTFMove(exceptionCallback), *context, workQueue); 957 961 }; … … 960 964 }; 961 965 966 // The following operation should be performed synchronously. 962 967 exportAlgorithm->exportKey(format, key.releaseNonNull(), WTFMove(callback), WTFMove(exceptionCallback)); 963 968 } 964 969 970 static void jsSubtleCryptoFunctionUnwrapKeyPromise(ExecState& state, Ref<DeferredPromise>&& promise) 971 { 972 VM& vm = state.vm(); 973 auto scope = DECLARE_THROW_SCOPE(vm); 974 975 if (UNLIKELY(state.argumentCount() < 7)) { 976 promise->reject<JSValue>(createNotEnoughArgumentsError(&state)); 977 return; 978 } 979 980 auto format = convertEnumeration<SubtleCrypto::KeyFormat>(state, state.uncheckedArgument(0)); 981 RETURN_IF_EXCEPTION(scope, void()); 982 983 auto wrappedKey = toVector(state, state.uncheckedArgument(1)); 984 RETURN_IF_EXCEPTION(scope, void()); 985 986 auto unwrappingKey = toCryptoKey(state, state.uncheckedArgument(2)); 987 RETURN_IF_EXCEPTION(scope, void()); 988 989 auto catchScope = DECLARE_CATCH_SCOPE(vm); 990 bool isDecryption = false; 991 auto unwrapParams = normalizeCryptoAlgorithmParameters(state, state.uncheckedArgument(3), Operations::UnwrapKey); 992 if (catchScope.exception()) { 993 catchScope.clearException(); 994 unwrapParams = normalizeCryptoAlgorithmParameters(state, state.uncheckedArgument(3), Operations::Decrypt); 995 RETURN_IF_EXCEPTION(scope, void()); 996 isDecryption = true; 997 } 998 999 auto unwrappedKeyAlgorithm = normalizeCryptoAlgorithmParameters(state, state.uncheckedArgument(4), Operations::ImportKey); 1000 RETURN_IF_EXCEPTION(scope, void()); 1001 1002 auto extractable = state.uncheckedArgument(5).toBoolean(&state); 1003 RETURN_IF_EXCEPTION(scope, void()); 1004 1005 auto keyUsages = cryptoKeyUsageBitmapFromJSValue(state, state.uncheckedArgument(6)); 1006 RETURN_IF_EXCEPTION(scope, void()); 1007 1008 if (unwrapParams->identifier != unwrappingKey->algorithmIdentifier()) { 1009 promise->reject(INVALID_ACCESS_ERR, ASCIILiteral("Unwrapping CryptoKey doesn't match unwrap AlgorithmIdentifier")); 1010 return; 1011 } 1012 1013 if (!unwrappingKey->allows(CryptoKeyUsageUnwrapKey)) { 1014 promise->reject(INVALID_ACCESS_ERR, ASCIILiteral("Unwrapping CryptoKey doesn't support unwrapKey operation")); 1015 return; 1016 } 1017 1018 auto importAlgorithm = createAlgorithm(state, unwrappedKeyAlgorithm->identifier); 1019 RETURN_IF_EXCEPTION(scope, void()); 1020 1021 auto unwrapAlgorithm = createAlgorithm(state, unwrappingKey->algorithmIdentifier()); 1022 RETURN_IF_EXCEPTION(scope, void()); 1023 1024 auto callback = [promise = promise.copyRef(), format, importAlgorithm, unwrappedKeyAlgorithm = WTFMove(unwrappedKeyAlgorithm), extractable, keyUsages](const Vector<uint8_t>& bytes) mutable { 1025 ExecState& state = *(promise->globalObject()->globalExec()); 1026 VM& vm = state.vm(); 1027 auto scope = DECLARE_THROW_SCOPE(vm); 1028 1029 KeyData keyData; 1030 switch (format) { 1031 case SubtleCrypto::KeyFormat::Spki: 1032 case SubtleCrypto::KeyFormat::Pkcs8: 1033 case SubtleCrypto::KeyFormat::Raw: 1034 keyData = bytes; 1035 break; 1036 case SubtleCrypto::KeyFormat::Jwk: { 1037 String jwkString(reinterpret_cast_ptr<const char*>(bytes.data()), bytes.size()); 1038 JSC::JSLockHolder locker(vm); 1039 auto jwk = JSONParse(&state, jwkString); 1040 if (!jwk) { 1041 promise->reject(DataError, ASCIILiteral("WrappedKey cannot be converted to a JSON object")); 1042 return; 1043 } 1044 keyData = toKeyData(state, format, jwk); 1045 RETURN_IF_EXCEPTION(scope, void()); 1046 } 1047 } 1048 1049 auto callback = [promise = promise.copyRef()](CryptoKey& key) mutable { 1050 if ((key.type() == CryptoKeyType::Private || key.type() == CryptoKeyType::Secret) && !key.usagesBitmap()) { 1051 rejectWithException(WTFMove(promise), SYNTAX_ERR); 1052 return; 1053 } 1054 promise->resolve(key); 1055 }; 1056 auto exceptionCallback = [promise = WTFMove(promise)](ExceptionCode ec) mutable { 1057 rejectWithException(WTFMove(promise), ec); 1058 }; 1059 1060 // The following operation should be performed synchronously. 1061 importAlgorithm->importKey(format, WTFMove(keyData), WTFMove(unwrappedKeyAlgorithm), extractable, keyUsages, WTFMove(callback), WTFMove(exceptionCallback)); 1062 }; 1063 auto exceptionCallback = [capturedPromise = WTFMove(promise)](ExceptionCode ec) mutable { 1064 rejectWithException(WTFMove(capturedPromise), ec); 1065 }; 1066 1067 if (!isDecryption) { 1068 // The 11 December 2014 version of the specification suggests we should perform the following task asynchronously: 1069 // https://www.w3.org/TR/WebCryptoAPI/#SubtleCrypto-method-unwrapKey 1070 // It is not beneficial for less time consuming operations. Therefore, we perform it synchronously. 1071 unwrapAlgorithm->unwrapKey(unwrappingKey.releaseNonNull(), WTFMove(wrappedKey), WTFMove(callback), WTFMove(exceptionCallback)); 1072 return; 1073 } 1074 auto subtle = jsDynamicDowncast<JSSubtleCrypto*>(state.thisValue()); 1075 ASSERT(subtle); 1076 // The following operation should be performed asynchronously. 1077 unwrapAlgorithm->decrypt(WTFMove(unwrapParams), unwrappingKey.releaseNonNull(), WTFMove(wrappedKey), WTFMove(callback), WTFMove(exceptionCallback), *scriptExecutionContextFromExecState(&state), subtle->wrapped().workQueue()); 1078 } 1079 965 1080 JSValue JSSubtleCrypto::encrypt(ExecState& state) 966 1081 { … … 1018 1133 } 1019 1134 1135 JSValue JSSubtleCrypto::unwrapKey(ExecState& state) 1136 { 1137 return callPromiseFunction<jsSubtleCryptoFunctionUnwrapKeyPromise, PromiseExecutionScope::WindowOrWorker>(state); 1138 } 1139 1020 1140 } // namespace WebCore 1021 1141 -
trunk/Source/WebCore/crypto/CryptoAlgorithm.cpp
r209164 r209200 78 78 } 79 79 80 void CryptoAlgorithm::unwrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&& exceptionCallback) 81 { 82 exceptionCallback(NOT_SUPPORTED_ERR); 83 } 84 80 85 ExceptionOr<void> CryptoAlgorithm::encrypt(const CryptoAlgorithmParametersDeprecated&, const CryptoKey&, const CryptoOperationData&, VectorCallback&&, VoidCallback&&) 81 86 { -
trunk/Source/WebCore/crypto/CryptoAlgorithm.h
r209164 r209200 74 74 virtual void exportKey(SubtleCrypto::KeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&); 75 75 virtual void wrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&); 76 virtual void unwrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&); 76 77 77 78 // The following will be deprecated. -
trunk/Source/WebCore/crypto/SubtleCrypto.idl
r209191 r209200 44 44 [Custom] Promise<any> exportKey(KeyFormat format, CryptoKey key); 45 45 [Custom] Promise<any> wrapKey(KeyFormat format, CryptoKey key, CryptoKey wrappingKey, AlgorithmIdentifier wrapAlgorithm); 46 [Custom] Promise<CryptoKey> unwrapKey(KeyFormat format, BufferSource wrappedKey, CryptoKey unwrappingKey, AlgorithmIdentifier unwrapAlgorithm, AlgorithmIdentifier unwrappedKeyAlgorithm, boolean extractable, sequence<KeyUsage> keyUsages); 46 47 }; -
trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.cpp
r209155 r209200 168 168 } 169 169 170 void CryptoAlgorithmAES_KW::unwrapKey(Ref<CryptoKey>&& key, Vector<uint8_t>&& data, VectorCallback&& callback, ExceptionCallback&& exceptionCallback) 171 { 172 platformUnwrapKey(WTFMove(key), WTFMove(data), WTFMove(callback), WTFMove(exceptionCallback)); 173 } 174 170 175 ExceptionOr<void> CryptoAlgorithmAES_KW::encryptForWrapKey(const CryptoAlgorithmParametersDeprecated&, const CryptoKey& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback) 171 176 { -
trunk/Source/WebCore/crypto/algorithms/CryptoAlgorithmAES_KW.h
r209155 r209200 48 48 void exportKey(SubtleCrypto::KeyFormat, Ref<CryptoKey>&&, KeyDataCallback&&, ExceptionCallback&&) final; 49 49 void wrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&) final; 50 void unwrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&) final; 50 51 51 52 ExceptionOr<void> encryptForWrapKey(const CryptoAlgorithmParametersDeprecated&, const CryptoKey&, const CryptoOperationData&, VectorCallback&&, VoidCallback&& failureCallback) final; … … 56 57 bool keyAlgorithmMatches(const CryptoKey&) const; 57 58 void platformWrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&); 59 void platformUnwrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&); 58 60 ExceptionOr<void> platformEncrypt(const CryptoKeyAES&, const CryptoOperationData&, VectorCallback&&, VoidCallback&& failureCallback); 59 61 ExceptionOr<void> platformDecrypt(const CryptoKeyAES&, const CryptoOperationData&, VectorCallback&&, VoidCallback&& failureCallback); -
trunk/Source/WebCore/crypto/gnutls/CryptoAlgorithmAES_KWGnuTLS.cpp
r209155 r209200 39 39 } 40 40 41 void CryptoAlgorithmAES_KW::platformUnwrapKey(Ref<CryptoKey>&&, Vector<uint8_t>&&, VectorCallback&&, ExceptionCallback&&) 42 { 43 notImplemented(); 44 } 45 41 46 ExceptionOr<void> CryptoAlgorithmAES_KW::platformEncrypt(const CryptoKeyAES&, const CryptoOperationData&, VectorCallback&&, VoidCallback&&) 42 47 { -
trunk/Source/WebCore/crypto/mac/CryptoAlgorithmAES_KWMac.cpp
r209155 r209200 48 48 } 49 49 50 // FIXME: We should change data to Vector<uint8_t> type once WebKitSubtleCrypto is deprecated. 51 // https://bugs.webkit.org/show_bug.cgi?id=164939 52 static ExceptionOr<Vector<uint8_t>> unwrapKeyAES_KW(const Vector<uint8_t>& key, const uint8_t* data, size_t dataLength) 53 { 54 Vector<uint8_t> result(CCSymmetricUnwrappedSize(kCCWRAPAES, dataLength)); 55 size_t resultSize = result.size(); 56 57 if (resultSize % 8) 58 return Exception { OperationError }; 59 60 if (CCSymmetricKeyUnwrap(kCCWRAPAES, CCrfc3394_iv, CCrfc3394_ivLen, key.data(), key.size(), data, dataLength, result.data(), &resultSize)) 61 return Exception { OperationError }; 62 63 result.shrink(resultSize); 64 return WTFMove(result); 65 } 66 50 67 void CryptoAlgorithmAES_KW::platformWrapKey(Ref<CryptoKey>&& key, Vector<uint8_t>&& data, VectorCallback&& callback, ExceptionCallback&& exceptionCallback) 51 68 { 52 69 auto& aesKey = downcast<CryptoKeyAES>(key.get()); 53 70 auto result = wrapKeyAES_KW(aesKey.key(), data.data(), data.size()); 71 if (result.hasException()) { 72 exceptionCallback(result.releaseException().code()); 73 return; 74 } 75 callback(result.releaseReturnValue()); 76 } 77 78 void CryptoAlgorithmAES_KW::platformUnwrapKey(Ref<CryptoKey>&& key, Vector<uint8_t>&& data, VectorCallback&& callback, ExceptionCallback&& exceptionCallback) 79 { 80 auto& aesKey = downcast<CryptoKeyAES>(key.get()); 81 auto result = unwrapKeyAES_KW(aesKey.key(), data.data(), data.size()); 54 82 if (result.hasException()) { 55 83 exceptionCallback(result.releaseException().code()); … … 79 107 ExceptionOr<void> CryptoAlgorithmAES_KW::platformDecrypt(const CryptoKeyAES& key, const CryptoOperationData& data, VectorCallback&& callback, VoidCallback&& failureCallback) 80 108 { 81 Vector<uint8_t> result(CCSymmetricUnwrappedSize(kCCWRAPAES, data.second)); 82 size_t resultSize = result.size(); 83 84 if (resultSize % 8) { 109 auto result = unwrapKeyAES_KW(key.key(), data.first, data.second); 110 if (result.hasException()) { 85 111 failureCallback(); 86 112 return { }; 87 113 } 88 89 int status = CCSymmetricKeyUnwrap(kCCWRAPAES, CCrfc3394_iv, CCrfc3394_ivLen, key.key().data(), key.key().size(), data.first, data.second, result.data(), &resultSize); 90 if (status) { 91 failureCallback(); 92 return { }; 93 } 94 result.shrink(resultSize); 95 callback(result); 96 return { }; 97 } 114 callback(result.releaseReturnValue()); 115 return { };} 98 116 99 117 } // namespace WebCore
Note: See TracChangeset
for help on using the changeset viewer.