@@ -1138,6 +1138,74 @@ GC::Ref<WebIDL::Promise> SubtleCrypto::encapsulate_key(AlgorithmIdentifier encap
11381138 return promise;
11391139}
11401140
1141+ // https://wicg.github.io/webcrypto-modern-algos/#dfn-SubtleCrypto-method-encapsulateBits
1142+ GC::Ref<WebIDL::Promise> SubtleCrypto::encapsulate_bits (AlgorithmIdentifier encapsulation_algorithm, GC::Ref<CryptoKey> encapsulation_key)
1143+ {
1144+ auto & realm = this ->realm ();
1145+
1146+ // 1. Let encapsulationAlgorithm and encapsulationKey be the encapsulationAlgorithm and encapsulationKey
1147+ // parameters passed to the encapsulateBits() method, respectively.
1148+
1149+ // 2. Let normalizedEncapsulationAlgorithm be the result of normalizing an algorithm, with alg set to
1150+ // encapsulationAlgorithm and op set to "encapsulate".
1151+ auto maybe_normalized_encapsulation_algorithm = normalize_an_algorithm (realm, encapsulation_algorithm, " encapsulate" _string);
1152+
1153+ // 3. If an error occurred, return a Promise rejected with normalizedEncapsulationAlgorithm.
1154+ if (maybe_normalized_encapsulation_algorithm.is_error ()) {
1155+ return WebIDL::create_rejected_promise_from_exception (realm, maybe_normalized_encapsulation_algorithm.release_error ());
1156+ }
1157+ auto normalized_encapsulation_algorithm = maybe_normalized_encapsulation_algorithm.release_value ();
1158+
1159+ // 4. Let realm be the relevant realm of this.
1160+
1161+ // 5. Let promise be a new Promise.
1162+ auto promise = WebIDL::create_promise (realm);
1163+
1164+ // 6. Return promise and perform the remaining steps in parallel.
1165+ Platform::EventLoopPlugin::the ().deferred_invoke (GC::create_function (realm.heap (), [&realm, normalized_encapsulation_algorithm = move (normalized_encapsulation_algorithm), promise, encapsulation_key = encapsulation_key]() mutable -> void {
1166+ HTML::TemporaryExecutionContext context (realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes);
1167+ // 7. If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task
1168+ // source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
1169+
1170+ // 8. If the name member of normalizedEncapsulationAlgorithm is not equal to the name attribute of the [[algorithm]]
1171+ // internal slot of encapsulationKey then throw an InvalidAccessError.
1172+ if (normalized_encapsulation_algorithm.parameter ->name != encapsulation_key->algorithm_name ()) {
1173+ WebIDL::reject_promise (realm, promise, WebIDL::InvalidAccessError::create (realm, " Invalid encapsulation key algorithm" _utf16));
1174+ return ;
1175+ }
1176+
1177+ // 9. If the [[usages]] internal slot of encapsulationKey does not contain an entry that is "encapsulateBits", then
1178+ // throw an InvalidAccessError.
1179+ if (encapsulation_key->internal_usages ().contains_slow (Bindings::KeyUsage::Encapsulatebits)) {
1180+ WebIDL::reject_promise (realm, promise, WebIDL::InvalidAccessError::create (realm, " Invalid encapsulation key usages" _utf16));
1181+ return ;
1182+ }
1183+
1184+ // 10. Let encapsulatedBits be the result of performing the encapsulate operation specified by the [[algorithm]]
1185+ // internal slot of encapsulationKey using encapsulationKey.
1186+ auto maybe_encapsulated_bits = normalized_encapsulation_algorithm.methods ->encapsulate (*normalized_encapsulation_algorithm.parameter , encapsulation_key);
1187+ if (maybe_encapsulated_bits.is_error ()) {
1188+ WebIDL::reject_promise (realm, promise, Bindings::exception_to_throw_completion (realm.vm (), maybe_encapsulated_bits.release_error ()).release_value ());
1189+ return ;
1190+ }
1191+ auto encapsulated_bits = maybe_encapsulated_bits.release_value ();
1192+
1193+ // 11. Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.
1194+ // 12. Let result be the result of converting encapsulatedBits to an ECMAScript Object in realm, as defined by [WebIDL].
1195+ auto maybe_result = encapsulated_bits->to_object (realm);
1196+ if (maybe_result.is_error ()) {
1197+ WebIDL::reject_promise (realm, promise, maybe_result.release_error ().value ());
1198+ return ;
1199+ }
1200+ auto const result = maybe_result.release_value ();
1201+
1202+ // 13. Resolve promise with result.
1203+ WebIDL::resolve_promise (realm, promise, result);
1204+ }));
1205+
1206+ return promise;
1207+ }
1208+
11411209SupportedAlgorithmsMap& supported_algorithms_internal ()
11421210{
11431211 static SupportedAlgorithmsMap s_supported_algorithms;
0 commit comments