Skip to content

Commit

Permalink
Accept (async) iterables in crypto.subtle.digest
Browse files Browse the repository at this point in the history
  • Loading branch information
twiss committed Dec 20, 2024
1 parent 0ac8c1b commit d124b53
Showing 1 changed file with 141 additions and 6 deletions.
147 changes: 141 additions & 6 deletions spec/Overview.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
github: "https://github.com/w3c/webcrypto",
shortName: "WebCryptoAPI",
group: "webappsec",
xref: ['html', 'dom', 'webidl', 'infra', 'encoding'],
xref: ['html', 'dom', 'webidl', 'infra', 'encoding', 'streams'],
localBiblio: {
"JWA": {
aliasOf: "RFC7518"
Expand Down Expand Up @@ -1220,6 +1220,19 @@ <h3>Serialization and deserialization steps</h3>
</section>
</section>

<section id="iterable-interfaces">
<h2>Iterable interfaces</h2>
<p>
The <dfn id="dfn-IterableOfBufferSources">IterableOfBufferSources</dfn> type represents objects that conform to the <a data-cite="ECMAScript/control-abstraction-objects.html#sec-iterable-interface">iterable interface</a>, and produce {{BufferSource}} values when iterated over.
The <dfn id="dfn-AsyncIterableOfBufferSources">AsyncIterableOfBufferSources</dfn> type represents objects that conform to the <a data-cite="ECMAScript/control-abstraction-objects.html#sec-asynciterable-interface">async iterable interface</a>, and produce {{BufferSource}} values when asynchronously iterated over.
This is checked by the calling functions rather than by Web IDL.
</p>
<pre class=idl>
typedef object IterableOfBufferSources;
typedef object AsyncIterableOfBufferSources;
</pre>
</section>

<section id="subtlecrypto-interface">
<h2>SubtleCrypto interface</h2>
<p>
Expand Down Expand Up @@ -1254,7 +1267,7 @@ <h2>SubtleCrypto interface</h2>
);
Promise&lt;ArrayBuffer> digest(
AlgorithmIdentifier algorithm,
BufferSource data
(BufferSource or IterableOfBufferSources or AsyncIterableOfBufferSources) data
);

Promise&lt;(CryptoKey or CryptoKeyPair)> generateKey(
Expand Down Expand Up @@ -1828,9 +1841,7 @@ <h4>The digest method</h4>
</li>
<li>
<p>
Let |data| be the result of
[= get a copy of the buffer source |
getting a copy of the bytes held by =] the `data` parameter passed to the
Let |data| be the `data` parameter passed to the
{{SubtleCrypto/digest()}} method.
</p>
</li>
Expand Down Expand Up @@ -1858,6 +1869,112 @@ <h4>The digest method</h4>
Let |promise| be a new Promise.
</p>
</li>
<li>
<dl class="switch">
<dt>If |data| is a {{BufferSource}}:</dt>
<dd>
<p>
Let |bytes| be the result of
[= get a copy of the buffer source |
getting a copy of the bytes held by =] |data|.
</p>
</dd>
<dt>
Otherwise, if |data| conforms to the
<a data-cite="ECMAScript/control-abstraction-objects.html#sec-iterable-interface">iterable interface</a> or
<a data-cite="ECMAScript/control-abstraction-objects.html#sec-asynciterable-interface">async iterable interface</a>:
</dt>
<dd>
<ol>
<li>
<p>
Let |bytes| be an empty [= byte sequence =].
</p>
</li>
<li>
<p>
Let |iterator| be the result of calling
<code><a data-cite="ECMAScript/abstract-operations.html#sec-getiterator">GetIterator</a>(|data|, ASYNC)</code>.
</p>
</li>
<li>
<p>
If an error occurred, return a Promise rejected with
|iterator|.
</p>
</li>
<li>
<p>
[= Queue a microtask =] to perform the remaining steps.
</p>
</li>
<li>
<p>
While <code>|iterator|.[[\Done]]</code> is false:
</p>
<ol>
<li>
<p>
Let |value| be the result of calling
<code><a data-cite="ECMAScript/abstract-operations.html#sec-iteratorstepvalue">IteratorStepValue</a>(|iterator|)</code>.
</p>
</li>
<li>
<p>
If an error occurred, reject |promise| with
|value| and then terminate these steps.
</p>
</li>
<li>
<p>
Let |value| be the result of calling
<code><a data-cite="ECMAScript/control-abstraction-objects.html#await">Await</a>(|value|)</code>.
</p>
</li>
<li>
<p>
If an error occurred, reject |promise| with
|value| and then terminate these steps.
</p>
</li>
<li>
<p>
If |value| is not a {{BufferSource}},
reject |promise| with the result of calling
<code><a data-cite="ECMAScript/abstract-operations.html#sec-asynciteratorclose">AsyncIteratorClose</a></code>
with |iterator| and a {{TypeError}},
and then terminate these steps.
</p>
</li>
<li>
<p>
Append the result of [= get a copy of the buffer source |
getting a copy of the bytes held by =] |value|
to |bytes|.
</p>
</li>
</ol>
</li>
</ol>
<div class=note>
<p>
If the |iterator| returned by <code>GetIterator(|data|, ASYNC)</code>
is the iterator defined by {{ReadableStream}},
the implementation may wish to optimize the steps
above, for example by reading the stream directly,
and/or <a data-cite="streams#transferrable-streams">transferring</a>
the stream to the [= in parallel | parallel =] steps below.
</p>
</div>
</dd>
<dt>Otherwise:</dt>
<dd>
<p>
Return a Promise rejected with a {{TypeError}}.
</p>
</dd>
</dl>
</li>
<li>
<p>
Return |promise| and perform the remaining steps [= in parallel =].
Expand All @@ -1873,11 +1990,29 @@ <h4>The digest method</h4>
and then [= terminate the algorithm =].
</p>
</li>
<li>
<p>
Wait until the microtask queued above (if any) completes.
</p>
<div class=note>
<p>
The implementation may wish to compute the hash digest
incrementally, instead of waiting until all data is
available, in order to conserve memory.
</p>
</div>
</li>
<li>
<p>
If |promise| was rejected with an error,
[= terminate the algorithm =].
</p>
</li>
<li>
<p>
Let |digest| be the result of performing the digest
operation specified by |normalizedAlgorithm| using
|algorithm|, with |data|
|algorithm|, with |bytes|
as |message|.
</p>
</li>
Expand Down

0 comments on commit d124b53

Please sign in to comment.