Skip to content

Commit

Permalink
Add a checkbox for encrypting initial frame bytes. (webrtc#1278)
Browse files Browse the repository at this point in the history
* Add a checkbox for encrypting initial frame bytes.

This allows to experiment with the effect of encrypting
or not encrypting the first bytes of the frame.

* Make eslint happy

* Remove excessive log
  • Loading branch information
alvestrand authored Apr 3, 2020
1 parent 01205fa commit 4318a1f
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/content/peerconnection/endtoend-encryption/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ <h2>Sender and receiver</h2>
</div>
<br>
Crypto key: <input type="text" id="crypto-key">
Encrypt first bytes: <input type="checkbox" id="crypto-offset">
</p>
<p>
<h2>Middlebox</h2>
Expand Down
24 changes: 16 additions & 8 deletions src/content/peerconnection/endtoend-encryption/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,20 @@ const callButton = document.querySelector('button#call');
const hangupButton = document.querySelector('button#hangup');

const cryptoKey = document.querySelector('#crypto-key');
const cryptoOffsetBox = document.querySelector('#crypto-offset');
const banner = document.querySelector('#banner');

startButton.onclick = start;
callButton.onclick = call;
hangupButton.onclick = hangup;

cryptoKey.addEventListener('change', setCryptoKey);
cryptoOffsetBox.addEventListener('change', setCryptoKey);

let startToMiddle;
let startToEnd;
let currentCryptoKey;
let useCryptoOffset;
let currentKeyIdentifier = 0;

let localStream;
Expand Down Expand Up @@ -102,13 +105,15 @@ function encodeFunction(chunk, controller) {
const newData = new ArrayBuffer(chunk.data.byteLength + 5);
const newView = new DataView(newData);

const cryptoOffset = useCryptoOffset? 10 : 0;
// If using crypto offset:
// Do not encrypt the first 10 bytes of the payload. For VP8
// this is the content described in
// https://tools.ietf.org/html/rfc6386#section-9.1
for (let i = 0; i < 10; ++i) {
for (let i = 0; i < cryptoOffset; ++i) {
newView.setInt8(i, view.getInt8(i));
}
for (let i = 10; i < chunk.data.byteLength; ++i) {
for (let i = cryptoOffset; i < chunk.data.byteLength; ++i) {
const keyByte = currentCryptoKey.charCodeAt(i % currentCryptoKey.length);
newView.setInt8(i, view.getInt8(i) ^ keyByte);
}
Expand All @@ -127,8 +132,8 @@ function decodeFunction(chunk, controller) {
const checksum = view.getUint32(chunk.data.byteLength - 4);
if (currentCryptoKey) {
if (checksum !== 0xDEADBEEF) {
console.log('Corrupted frame received');
console.log(checksum.toString(16));
console.log('Corrupted frame received, checksum ' +
checksum.toString(16));
return; // This can happen when the key is set and there is an unencrypted frame in-flight.
}
const keyIdentifier = view.getUint8(chunk.data.byteLength - 5);
Expand All @@ -139,10 +144,12 @@ function decodeFunction(chunk, controller) {

const newData = new ArrayBuffer(chunk.data.byteLength - 5);
const newView = new DataView(newData);
for (let i = 0; i < 10; ++i) {
const cryptoOffset = useCryptoOffset? 10 : 0;

for (let i = 0; i < cryptoOffset; ++i) {
newView.setInt8(i, view.getInt8(i));
}
for (let i = 10; i < chunk.data.byteLength - 5; ++i) {
for (let i = cryptoOffset; i < chunk.data.byteLength - 5; ++i) {
const keyByte = currentCryptoKey.charCodeAt(i % currentCryptoKey.length);
newView.setInt8(i, view.getInt8(i) ^ keyByte);
}
Expand All @@ -154,8 +161,9 @@ function decodeFunction(chunk, controller) {
}

function setCryptoKey(event) {
console.log('Setting crypto key to ' + event.target.value);
currentCryptoKey = event.target.value;
console.log('Setting crypto key to ' + cryptoKey.value);
currentCryptoKey = cryptoKey.value;
useCryptoOffset = !cryptoOffsetBox.checked;
currentKeyIdentifier++;
if (currentCryptoKey) {
banner.innerText = 'Encryption is ON';
Expand Down

0 comments on commit 4318a1f

Please sign in to comment.