| <!doctype html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| </head> |
| <body> |
| <script> |
| |
| promise_test(async (test) => { |
| const pc = new RTCPeerConnection(); |
| const senderTransform = new SFrameTransform(); |
| const receiverTransform = new SFrameTransform(); |
| const sender1 = pc.addTransceiver('audio').sender; |
| const sender2 = pc.addTransceiver('video').sender; |
| const receiver1 = pc.getReceivers()[0]; |
| const receiver2 = pc.getReceivers()[1]; |
| |
| sender1.transform = senderTransform; |
| receiver1.transform = receiverTransform; |
| assert_throws_dom("InvalidStateError", () => sender2.transform = senderTransform); |
| assert_throws_dom("InvalidStateError", () => receiver2.transform = receiverTransform); |
| |
| sender1.transform = senderTransform; |
| receiver1.transform = receiverTransform; |
| |
| sender1.transform = null; |
| receiver1.transform = null; |
| }, "Cannot reuse attached transforms"); |
| |
| test(() => { |
| const senderTransform = new SFrameTransform(); |
| |
| assert_true(senderTransform.readable instanceof ReadableStream); |
| assert_true(senderTransform.writable instanceof WritableStream); |
| }, "SFrameTransform exposes readable and writable"); |
| |
| promise_test(async (test) => { |
| const pc = new RTCPeerConnection(); |
| const senderTransform = new SFrameTransform(); |
| const receiverTransform = new SFrameTransform(); |
| const sender1 = pc.addTransceiver('audio').sender; |
| const sender2 = pc.addTransceiver('video').sender; |
| const receiver1 = pc.getReceivers()[0]; |
| const receiver2 = pc.getReceivers()[1]; |
| |
| assert_false(senderTransform.readable.locked, "sender readable before"); |
| assert_false(senderTransform.writable.locked, "sender writable before"); |
| assert_false(receiverTransform.readable.locked, "receiver readable before"); |
| assert_false(receiverTransform.writable.locked, "receiver writable before"); |
| |
| sender1.transform = senderTransform; |
| receiver1.transform = receiverTransform; |
| |
| assert_true(senderTransform.readable.locked, "sender readable during"); |
| assert_true(senderTransform.writable.locked, "sender writable during"); |
| assert_true(receiverTransform.readable.locked, "receiver readable during"); |
| assert_true(receiverTransform.writable.locked, "receiver writable during"); |
| |
| sender1.transform = null; |
| receiver1.transform = null; |
| |
| assert_true(senderTransform.readable.locked, "sender readable after"); |
| assert_true(senderTransform.writable.locked, "sender writable after"); |
| assert_true(receiverTransform.readable.locked, "receiver readable after"); |
| assert_true(receiverTransform.writable.locked, "receiver writable after"); |
| }, "readable/writable are locked when attached and after being attached"); |
| |
| promise_test(async (test) => { |
| const key = await crypto.subtle.importKey("raw", new Uint8Array([143, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]); |
| |
| const senderTransform = new SFrameTransform({ role : 'encrypt', authenticationSize: 10 }); |
| senderTransform.setEncryptionKey(key); |
| |
| const receiverTransform = new SFrameTransform({ role : 'decrypt', authenticationSize: 10 }); |
| receiverTransform.setEncryptionKey(key); |
| |
| const writer = senderTransform.writable.getWriter(); |
| const reader = receiverTransform.readable.getReader(); |
| |
| senderTransform.readable.pipeTo(receiverTransform.writable); |
| |
| const sent = new ArrayBuffer(8); |
| const view = new Int8Array(sent); |
| for (let cptr = 0; cptr < sent.byteLength; ++cptr) |
| view[cptr] = cptr; |
| |
| writer.write(sent); |
| const received = await reader.read(); |
| |
| assert_equals(received.value.byteLength, 8); |
| const view2 = new Int8Array(received.value); |
| for (let cptr = 0; cptr < sent.byteLength; ++cptr) |
| assert_equals(view2[cptr], view[cptr]); |
| }, "SFrame with array buffer - authentication size 10"); |
| |
| promise_test(async (test) => { |
| const key = await crypto.subtle.importKey("raw", new Uint8Array([143, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]); |
| |
| const senderTransform = new SFrameTransform({ role : 'encrypt', authenticationSize: 10 }); |
| const senderWriter = senderTransform.writable.getWriter(); |
| const senderReader = senderTransform.readable.getReader(); |
| |
| const receiverTransform = new SFrameTransform({ role : 'decrypt', authenticationSize: 10 }); |
| const receiverWriter = receiverTransform.writable.getWriter(); |
| const receiverReader = receiverTransform.readable.getReader(); |
| |
| senderTransform.setEncryptionKey(key); |
| receiverTransform.setEncryptionKey(key); |
| |
| const chunk = new ArrayBuffer(8); |
| |
| // decryption should fail, leading to an empty array buffer. |
| await receiverWriter.write(chunk); |
| let received = await receiverReader.read(); |
| assert_equals(received.value.byteLength, 0); |
| |
| // We write again but this time with a chunk we can decrypt. |
| await senderWriter.write(chunk); |
| const encrypted = await senderReader.read(); |
| await receiverWriter.write(encrypted.value); |
| received = await receiverReader.read(); |
| assert_equals(received.value.byteLength, 8); |
| }, "SFrame decryption with array buffer that is too small"); |
| |
| promise_test(async (test) => { |
| const key = await crypto.subtle.importKey("raw", new Uint8Array([143, 77, 43, 10, 72, 19, 37, 67, 236, 219, 24, 93, 26, 165, 91, 178]), "HKDF", false, ["deriveBits", "deriveKey"]); |
| |
| const receiverTransform = new SFrameTransform({ role : 'decrypt', authenticationSize: 10 }); |
| const receiverWriter = receiverTransform.writable.getWriter(); |
| receiverTransform.setEncryptionKey(key); |
| |
| // decryption should fail, leading to erroring the transform. |
| await promise_rejects_js(test, TypeError, receiverWriter.write({ })); |
| await promise_rejects_js(test, TypeError, receiverWriter.closed); |
| }, "SFrame transform gets errored if trying to process unexpected value types"); |
| |
| </script> |
| </body> |
| </html> |