-
Notifications
You must be signed in to change notification settings - Fork 28
Add decryption/encryption dedicated APIs #288
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -81,15 +81,16 @@ It uses an additional API on {{RTCRtpSender}} and {{RTCRtpReceiver}} to | |||||
| insert the processing into the pipeline. | ||||||
|
|
||||||
| <pre class="idl"> | ||||||
| typedef (SFrameTransform or RTCRtpScriptTransform) RTCRtpTransform; | ||||||
| typedef (SFrameSenderTransform or RTCRtpScriptTransform) RTCRtpSenderTransform; | ||||||
| typedef (SFrameReceiverTransform or RTCRtpScriptTransform) RTCRtpReceiverTransform; | ||||||
|
|
||||||
| // New methods for RTCRtpSender and RTCRtpReceiver | ||||||
| partial interface RTCRtpSender { | ||||||
| attribute RTCRtpTransform? transform; | ||||||
| attribute RTCRtpSenderTransform? transform; | ||||||
| }; | ||||||
|
|
||||||
| partial interface RTCRtpReceiver { | ||||||
| attribute RTCRtpTransform? transform; | ||||||
| attribute RTCRtpReceiverTransform? transform; | ||||||
| }; | ||||||
| </pre> | ||||||
|
|
||||||
|
|
@@ -214,7 +215,7 @@ There is no guarantee on which frame will happen the switch from the previous tr | |||||
| If a web application sets the transform synchronously at creation of the {{RTCRtpSender}} (for instance when calling addTrack), the transform will receive the first frame generated by the {{RTCRtpSender}}'s encoder. | ||||||
| Similarly, if a web application sets the transform synchronously at creation of the {{RTCRtpReceiver}} (for instance when calling addTrack, or at track event handler), the transform will receive the first full frame generated by the {{RTCRtpReceiver}}'s packetizer. | ||||||
|
|
||||||
| # SFrameTransform # {#sframe} | ||||||
| # SFrame transforms # {#sframe} | ||||||
|
|
||||||
| <p> | ||||||
| The APIs presented in this section allow applications to process SFrame data using specific cipher suites defined in [[RFC9605]]. | ||||||
|
|
@@ -237,30 +238,42 @@ dictionary SFrameTransformOptions { | |||||
| typedef [EnforceRange] unsigned long long SmallCryptoKeyID; | ||||||
| typedef (SmallCryptoKeyID or bigint) CryptoKeyID; | ||||||
|
|
||||||
| interface mixin SFrameKeyManagement { | ||||||
| interface mixin SFrameEncrypterManagement { | ||||||
| Promise<undefined> setEncryptionKey(CryptoKey key, optional CryptoKeyID keyID); | ||||||
| attribute EventHandler onerror; | ||||||
| }; | ||||||
|
|
||||||
| interface mixin SFrameDecrypterManagement { | ||||||
| Promise<undefined> addDecryptionKey(CryptoKey key, CryptoKeyID keyID); | ||||||
| Promise<undefined> removeDecryptionKey(CryptoKeyID keyID); | ||||||
| attribute EventHandler onerror; | ||||||
| }; | ||||||
|
|
||||||
| [Exposed=Window] | ||||||
| interface SFrameSenderTransform { | ||||||
| constructor(optional SFrameTransformOptions options = {}); | ||||||
| }; | ||||||
| SFrameSenderTransform includes SFrameEncrypterKeyManagement; | ||||||
|
|
||||||
| [Exposed=Window] | ||||||
| interface SFrameTransform : EventTarget { | ||||||
| interface SFrameReceiverTransform : EventTarget { | ||||||
| constructor(optional SFrameTransformOptions options = {}); | ||||||
| }; | ||||||
| SFrameTransform includes SFrameKeyManagement; | ||||||
| SFrameReceiverTransform includes SFrameDecrypterKeyManagement; | ||||||
|
|
||||||
| [Exposed=(Window,DedicatedWorker)] | ||||||
| interface SFrameEncrypterStream : EventTarget { | ||||||
| constructor(optional SFrameTransformOptions options = {}); | ||||||
| }; | ||||||
| SFrameEncrypterStream includes GenericTransformStream; | ||||||
| SFrameEncrypterStream includes SFrameKeyManagement; | ||||||
| SFrameEncrypterStream includes SFrameEncrypterManagement; | ||||||
|
|
||||||
| [Exposed=(Window,DedicatedWorker)] | ||||||
| interface SFrameDecrypterStream : EventTarget { | ||||||
| constructor(optional SFrameTransformOptions options = {}); | ||||||
| }; | ||||||
| SFrameDecrypterStream includes GenericTransformStream; | ||||||
| SFrameDecrypterStream includes SFrameKeyManagement; | ||||||
| SFrameDecrypterStream includes SFrameDecrypterManagement; | ||||||
|
|
||||||
| enum SFrameTransformErrorEventType { | ||||||
| "authentication", | ||||||
|
|
@@ -284,9 +297,15 @@ dictionary SFrameTransformErrorEventInit : EventInit { | |||||
| }; | ||||||
| </xmp> | ||||||
|
|
||||||
| The <dfn constructor for="SFrameTransform" lt="SFrameTransform(options)"><code>new SFrameTransform(<var>options</var>)</code></dfn> constructor steps are: | ||||||
| The <dfn constructor for="SFrameSenderTransform" lt="SFrameSenderTransform(options)"><code>new SFrameSenderTransform(<var>options</var>)</code></dfn> constructor steps are: | ||||||
| 1. Let |options| be the method's first argument. | ||||||
| 1. Run the [=SFrame initialization algorithm=] with |this| and |options|. | ||||||
| 1. Set |this|.`[[role]]` to 'encrypt'. | ||||||
|
|
||||||
| The <dfn constructor for="SFrameReceiverTransform" lt="SFrameReceiverTransform(options)"><code>new SFrameReceiverTransform(<var>options</var>)</code></dfn> constructor steps are: | ||||||
| 1. Let |options| be the method's first argument. | ||||||
| 1. Run the [=SFrame initialization algorithm=] with |this| and |options|. | ||||||
| 1. Set |this|.`[[role]]` to 'decrypt'. | ||||||
|
|
||||||
| The <dfn constructor for="SFrameEncrypterStream" lt="SFrameEncrypterStream(options)"><code>new SFrameEncrypterStream(<var>options</var>)</code></dfn> constructor steps are: | ||||||
| 1. Let |options| be the method's first argument. | ||||||
|
|
@@ -335,14 +354,38 @@ The <dfn>SFrame transform algorithm</dfn>, given |this| and |frame|, runs these | |||||
| 1. [=ReadableStream/Enqueue=] |frame| in |this|.`[[transform]]`. | ||||||
|
|
||||||
| ## Methods ## {#sframe-transform-methods} | ||||||
| The <dfn method for="SFrameTransform">setEncryptionKey(|key|, |keyID|)</dfn> method steps are: | ||||||
| The <dfn method for="SFrameEncrypterKeyManager">setEncryptionKey(|key|, |keyID|)</dfn> method steps are: | ||||||
| 1. Let |promise| be [=a new promise=]. | ||||||
| 2. If |keyID| is a {{bigint}} which cannot be represented as a integer between 0 and 2<sup>64</sup>-1 inclusive, [=reject=] |promise| with a {{RangeError}} exception. | ||||||
| 3. Otherwise, [=in parallel=], run the following steps: | ||||||
| 1. Set |key| with its optional |keyID| as key material to use for the SFrame transform algorithm, as defined by [[RFC9605]]. | ||||||
| 2. If setting the key material fails, [=reject=] |promise| with an {{InvalidModificationError}} exception and abort these steps. | ||||||
| 3. [=Resolve=] |promise| with undefined. | ||||||
| 4. Return |promise|. | ||||||
| 1. If |keyId| is <code>undefined</code>, run the following steps: | ||||||
| 1. Let |currentKeyId| be |this|.`[[currentKeyId]]` if not undefined or 0 otherwise. | ||||||
| 1. If |currentKeyId| is greater or equal to 2<sup>64</sup>-1, [=reject=] |promise| with a {{RangeError}} exception and abort these steps. | ||||||
| 1. Set |keyId| to |currentKeyId| incremented by 1. | ||||||
| 1. If |keyID| is a {{bigint}} which cannot be represented as a integer between 0 and 2<sup>64</sup>-1 inclusive, [=reject=] |promise| with a {{RangeError}} exception and abort these steps. | ||||||
| 1. Set |this|.`[[currentKeyId]]` to |keyId|. | ||||||
| 1. [=In parallel=], run the following steps: | ||||||
| 1. Set |key| and |keyID| as key material to use for the SFrame transform encryption algorithm, as defined by [[RFC9605]]. | ||||||
| 1. If setting the key material fails, [=queue a task=] to [=reject=] |promise| with an {{InvalidModificationError}} exception and abort these steps. | ||||||
| 1. [=Queue a task=] to [=resolve=] |promise| with undefined. | ||||||
| 1. Return |promise|. | ||||||
|
|
||||||
| The <dfn method for="SFrameDecrypterKeyManager">addEncryptionKey(|key|, |keyID|)</dfn> method steps are: | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| 1. Let |promise| be [=a new promise=]. | ||||||
| 1. If |keyID| is a {{bigint}} which cannot be represented as a integer between 0 and 2<sup>64</sup>-1 inclusive, [=reject=] |promise| with a {{RangeError}} exception, and abort these steps.. | ||||||
| 1. [=In parallel=], run the following steps: | ||||||
| 1. Let |keyStore| be the key store used for the SFrame transform algorithm, as defined by [[RFC9605]]. | ||||||
| 1. Set an entry to |keyStore| with |keyId| as key and |keyValue| as value. This overrides any existing entry to |keyId|. | ||||||
|
Comment on lines
+375
to
+376
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see "key store" matches language in RFC9605, which is nice. But I also wonder if we could use infra here. Is it an https://infra.spec.whatwg.org/#ordered-map ? |
||||||
| 1. If setting the key material fails, [=queue a task=] to [=reject=] |promise| with an {{InvalidModificationError}} exception and abort these steps. | ||||||
| 1. [=Resolve=] |promise| with undefined. | ||||||
| 1. Return |promise|. | ||||||
|
|
||||||
| The <dfn method for="SFrameDecrypterKeyManager">removeEncryptionKey(|key|, |keyID|)</dfn> method steps are: | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| 1. Let |promise| be [=a new promise=]. | ||||||
| 1. If |keyID| is a {{bigint}} which cannot be represented as a integer between 0 and 2<sup>64</sup>-1 inclusive, [=reject=] |promise| with a {{RangeError}} exception, and abort these steps. | ||||||
| 1. [=In parallel=], run the following steps: | ||||||
| 1. Let |keyStore| be the key store used for the SFrame transform algorithm, as defined by [[RFC9605]]. | ||||||
| 1. Remove the entry of |keyStore| at |keyId| if it exits. | ||||||
| 1. [=Resolve=] |promise| with undefined. | ||||||
| 1. Return |promise|. | ||||||
|
|
||||||
|
|
||||||
| # RTCRtpScriptTransform # {#scriptTransform} | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: "Set as" is a bit confusing to me. It's the reverse of (yet similar looking to) "set a to b" which usually means a = b, not b = a... How about: