Skip to content

Commit c790de2

Browse files
tete17gmta
authored andcommitted
LibWeb: Implement encapsulateBits method for SubtleCrypto
None of the current algorithms supports the method but the future post quantum algorithms will do so.
1 parent b36a702 commit c790de2

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

Libraries/LibWeb/Crypto/SubtleCrypto.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
11411209
SupportedAlgorithmsMap& supported_algorithms_internal()
11421210
{
11431211
static SupportedAlgorithmsMap s_supported_algorithms;

Libraries/LibWeb/Crypto/SubtleCrypto.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class SubtleCrypto final : public Bindings::PlatformObject {
4444
GC::Ref<WebIDL::Promise> unwrap_key(Bindings::KeyFormat format, KeyDataType wrapped_key, GC::Ref<CryptoKey> unwrapping_key, AlgorithmIdentifier unwrap_algorithm, AlgorithmIdentifier unwrapped_key_algorithm, bool extractable, Vector<Bindings::KeyUsage> key_usages);
4545

4646
GC::Ref<WebIDL::Promise> encapsulate_key(AlgorithmIdentifier encapsulation_algorithm, GC::Ref<CryptoKey> encapsulation_key, AlgorithmIdentifier shared_key_algorithm, bool extractable, Vector<Bindings::KeyUsage> key_usages);
47+
GC::Ref<WebIDL::Promise> encapsulate_bits(AlgorithmIdentifier encapsulation_algorithm, GC::Ref<CryptoKey> encapsulation_key);
4748

4849
private:
4950
explicit SubtleCrypto(JS::Realm&);

Libraries/LibWeb/Crypto/SubtleCrypto.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,5 @@ interface SubtleCrypto {
7777

7878
// https://wicg.github.io/webcrypto-modern-algos/#partial-subtlecrypto-interface
7979
Promise<EncapsulatedKey> encapsulateKey(AlgorithmIdentifier encapsulationAlgorithm, CryptoKey encapsulationKey, AlgorithmIdentifier sharedKeyAlgorithm, boolean extractable, sequence<KeyUsage> keyUsages);
80+
Promise<EncapsulatedBits> encapsulateBits(AlgorithmIdentifier encapsulationAlgorithm, CryptoKey encapsulationKey);
8081
};

0 commit comments

Comments
 (0)