Skip to content
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
73 changes: 48 additions & 25 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,10 @@ Similarly, if a web application sets the transform synchronously at creation of
# SFrameTransform # {#sframe}

<p>
The API presented in this section allows applications to process SFrame data using specific cipher suites defined in [[RFC9605]].
The APIs presented in this section allow applications to process SFrame data using specific cipher suites defined in [[RFC9605]].
</p>

<xmp class="idl">
enum SFrameTransformRole {
"encrypt",
"decrypt"
};

// List of supported cipher suites, as defined in [[RFC9605]] section 4.5.
enum SFrameCipherSuite {
"AES_128_CTR_HMAC_SHA256_80",
Expand All @@ -235,20 +230,36 @@ enum SFrameCipherSuite {
};

dictionary SFrameTransformOptions {
SFrameTransformRole role = "encrypt";
required SFrameCipherSuite cipherSuite;
};

typedef [EnforceRange] unsigned long long SmallCryptoKeyID;
typedef (SmallCryptoKeyID or bigint) CryptoKeyID;

[Exposed=(Window,DedicatedWorker)]
interface SFrameTransform : EventTarget {
constructor(optional SFrameTransformOptions options = {});
interface mixin SFrameKeyManagement {
Promise<undefined> setEncryptionKey(CryptoKey key, optional CryptoKeyID keyID);
attribute EventHandler onerror;
};
SFrameTransform includes GenericTransformStream;

[Exposed=Window]
interface SFrameTransform : EventTarget {
constructor(optional SFrameTransformOptions options = {});
};
SFrameTransform includes SFrameKeyManagement;

[Exposed=(Window,DedicatedWorker)]
interface SFrameEncrypterStream : EventTarget {
constructor(optional SFrameTransformOptions options = {});
};
SFrameEncrypterStream includes GenericTransformStream;
SFrameEncrypterStream includes SFrameKeyManagement;

[Exposed=(Window,DedicatedWorker)]
interface SFrameDecrypterStream : EventTarget {
constructor(optional SFrameTransformOptions options = {});
};
SFrameDecrypterStream includes GenericTransformStream;
SFrameDecrypterStream includes SFrameKeyManagement;

enum SFrameTransformErrorEventType {
"authentication",
Expand All @@ -273,42 +284,54 @@ dictionary SFrameTransformErrorEventInit : EventInit {
</xmp>

The <dfn constructor for="SFrameTransform" lt="SFrameTransform(options)"><code>new SFrameTransform(<var>options</var>)</code></dfn> constructor steps are:
1. Let |transformAlgorithm| be an algorithm which takes a |frame| as input and runs the <a href="#sframe-transform-algorithm">SFrame transform algorithm</a> with |this| and |frame|.
1. Let |options| be the method's first argument.
1. Run the [=SFrame initialization algorithm=] with |this| and |options|.

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.
1. Run the [=SFrame initialization algorithm=] with |this| and |options|.
1. Set |this|.`[[role]]` to 'encrypt'.

The <dfn constructor for="SFrameDecrypterStream" lt="SFrameDecrypterStream(options)"><code>new SFrameDecrypterStream(<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'.

## Algorithms ## {#sframe-algorithms}

The <dfn>SFrame initialization algorithm</dfn>, given |this| and |options|, runs these steps:
1. Let |transformAlgorithm| be an algorithm which takes a |frame| as input and runs the [=SFrame transform algorithm=] with |this| and |frame|.
1. Set |this|.`[[transform]]` to a new {{TransformStream}}.
1. <a dfn for="ReadableStream">Set up</a> [=this=].`[[transform]]` with [=TransformStream/set up/transformAlgorithm=] set to |transformAlgorithm|.
1. Let |options| be the method's first argument.
1. Set |this|.`[[role]]` to |options|["{{SFrameTransformOptions/role}}"].
1. Set |this|.`[[cipherSuite]]` to |options|["{{SFrameTransformOptions/cipherSuite}}"].
1. Set |this|.`[[readable]]` to |this|.`[[transform]]`.`[[readable]]`.
1. Set |this|.`[[writable]]` to |this|.`[[transform]]`.`[[writable]]`.

## Algorithm ## {#sframe-transform-algorithm}

The SFrame transform algorithm, given |sframe| as a SFrameTransform object and |frame|, runs these steps:
1. Let |role| be |sframe|.`[[role]]`.
1. If |frame|.`[[owner]]` is a {{RTCRtpSender}}, set |role| to 'encrypt'.
1. If |frame|.`[[owner]]` is a {{RTCRtpReceiver}}, set |role| to 'decrypt'.
The <dfn>SFrame transform algorithm</dfn>, given |this| and |frame|, runs these steps:
1. Let |role| be |this|.`[[role]]`.
1. If |this|.`[[owner]]` is an {{RTCRtpSender}}, set |role| to 'encrypt'.
1. If |this|.`[[owner]]` is an {{RTCRtpReceiver}}, set |role| to 'decrypt'.
1. Let |data| be undefined.
1. If |frame| is a {{BufferSource}}, set |data| to |frame|.
1. If |frame| is a {{RTCEncodedAudioFrame}}, set |data| to |frame|.{{RTCEncodedAudioFrame/data}}
1. If |frame| is a {{RTCEncodedVideoFrame}}, set |data| to |frame|.{{RTCEncodedVideoFrame/data}}
1. If |data| is undefined, abort these steps.
1. Let |buffer| be the result of running the SFrame algorithm with |data|, |sframe|.`[[cipherSuite]]`, and |role| as parameters. This algorithm is defined by [[RFC9605]] and returns an {{ArrayBuffer}}.
1. Let |buffer| be the result of running the SFrame algorithm with |data|, |this|.`[[cipherSuite]]`, and |role| as parameters. This algorithm is defined by [[RFC9605]] and returns an {{ArrayBuffer}}.
1. If the SFrame algorithm exits abruptly with an error, [=queue a task=] to run the following sub steps:
1. If the processing fails on decryption side due to |data| not following the SFrame format, [=fire an event=] named {{SFrameTransform/onerror|error}} at |sframe|,
1. If the processing fails on decryption side due to |data| not following the SFrame format, [=fire an event=] named {{SFrameTransform/onerror|error}} at |this|,
using the {{SFrameTransformErrorEvent}} interface with its {{SFrameTransformErrorEvent/errorType}} attribute set to {{SFrameTransformErrorEventType/syntax}}
and its {{SFrameTransformErrorEvent/frame}} attribute set to |frame|.
1. If the processing fails on decryption side due to the key identifier parsed in |data| being unknown, [=fire an event=] named {{SFrameTransform/onerror|error}} at |sframe|,
1. If the processing fails on decryption side due to the key identifier parsed in |data| being unknown, [=fire an event=] named {{SFrameTransform/onerror|error}} at |this|,
using the {{SFrameTransformErrorEvent}} interface with its {{SFrameTransformErrorEvent/errorType}} attribute set to {{SFrameTransformErrorEventType/keyID}},
its {{SFrameTransformErrorEvent/frame}} attribute set to |frame| and its {{SFrameTransformErrorEvent/keyID}} attribute set to the keyID value parsed in the SFrame header.
1. If the processing fails on decryption side due to validation of the authentication tag, [=fire an event=] named {{SFrameTransform/onerror|error}} at |sframe|,
1. If the processing fails on decryption side due to validation of the authentication tag, [=fire an event=] named {{SFrameTransform/onerror|error}} at |this|,
using the {{SFrameTransformErrorEvent}} interface with its {{SFrameTransformErrorEvent/errorType}} attribute set to {{SFrameTransformErrorEventType/authentication}}
and its {{SFrameTransformErrorEvent/frame}} attribute set to |frame|.
1. Abort these steps.
1. If |frame| is a {{BufferSource}}, set |frame| to |buffer|.
1. If |frame| is a {{RTCEncodedAudioFrame}}, set |frame|.{{RTCEncodedAudioFrame/data}} to |buffer|.
1. If |frame| is a {{RTCEncodedVideoFrame}}, set |frame|.{{RTCEncodedVideoFrame/data}} to |buffer|.
1. [=ReadableStream/Enqueue=] |frame| in |sframe|.`[[transform]]`.
1. [=ReadableStream/Enqueue=] |frame| in |this|.`[[transform]]`.

## Methods ## {#sframe-transform-methods}
The <dfn method for="SFrameTransform">setEncryptionKey(|key|, |keyID|)</dfn> method steps are:
Expand Down