Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept (async) iterables in crypto.subtle.digest #390

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 149 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,21 @@ <h3>Serialization and deserialization steps</h3>
</section>
</section>

<section id="buffersources">
<h2>BufferSources</h2>
<p>
The <dfn id="dfn-BufferSources" data-lt-no-plural>BufferSources</dfn> type represents objects that either are a {{BufferSource}},
or <a data-cite="ECMAScript/control-abstraction-objects.html#sec-common-iteration-interfaces">conform</a>
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>
and produce {{BufferSource}} values when iterated over.
This is checked by the calling functions rather than by Web IDL.
</p>
<pre class=idl>
typedef object BufferSources;
</pre>
</section>

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

Promise&lt;(CryptoKey or CryptoKeyPair)> generateKey(
Expand Down Expand Up @@ -1828,9 +1843,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 +1871,118 @@ <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:
</dt>
<dd>
<div class=note>
<p>
In this case, |data| should <a data-cite="ECMAScript/control-abstraction-objects.html#sec-common-iteration-interfaces">conform</a> 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>.
Otherwise, the call to <a data-cite="ECMAScript/abstract-operations.html#sec-getiterator">`GetIterator`</a> below
will throw a `TypeError`.
</p>
</div>
<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>
Repeat:
</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>
If |value| is `DONE`, 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>
</dl>
</li>
<li>
<p>
Return |promise| and perform the remaining steps [= in parallel =].
Expand All @@ -1873,11 +1998,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
Loading