Skip to content

Commit

Permalink
Merge pull request #24 from mozilla/tls13-psk-mode; r=vladikoff,marti…
Browse files Browse the repository at this point in the history
…nthomson

Add preliminary TLS1.3 PSK-mode implementation.
  • Loading branch information
rfk authored Feb 14, 2019
2 parents 68678df + fea659d commit 57146da
Show file tree
Hide file tree
Showing 33 changed files with 15,820 additions and 1,402 deletions.
5 changes: 4 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ jobs:
shell: /bin/bash --login
command: |
sudo npm install -g npm@6
npm install
npm ci
DISPLAY=:99 FIREFOX_BIN=./firefox/firefox-bin npm test
- store_artifacts:
path: ./coverage/

- run: npm run lint
workflows:
version: 2
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Build with coverage info enabled.
dist/FxAccountsPairingChannel.babel.umd.coverage.js

# Logs
logs
*.log
Expand Down
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,15 @@ It will be used by the Firefox Accounts pairing flow, with one side
of the channel being web content from https://accounts.firefox.com and
the other side of the channel being a signed-in Firefox instance.

The connection will *eventually* be secured using a pre-shared key
and TLS1.3, but that code is still in progress. To parallelize
client development we've published an initial version with a
correctly-shapred API but no meaningful security.

API
===

The main abstraction is the `InsecurePairingChannel` class.
The main abstraction is the `PairingChannel` class.
One side of the connection can create a new channel like this:

```
const channel = await InsecurePairingChannel.create(CHANNEL_SERVER_URL);
const channel = await PairingChannel.create(CHANNEL_SERVER_URL);
console.log(channel.channelId, channel.channelKey);
```

Expand All @@ -29,7 +25,7 @@ the intended client, perhaps by scanning a QR code. It can then
connect to the channel like this:

```
const channel = await InsecurePairingChannel.connect(CHANNEL_SERVER_URL, channelId, channelKey);
const channel = await PairingChannel.connect(CHANNEL_SERVER_URL, channelId, channelKey);
```

Both ends of the channel can then send and receive messages using a websocket-like
Expand All @@ -46,4 +42,14 @@ channel.addEventListener("message", event => {

You can try out a more complete demo of this API by loading
`./demo/test_client.html` and `./demo/test_server.html` in
parallel webpages and watching them pass messages back and forth.
parallel webpages and watching them pass messages back and forth.


Crypto
======

Under the hood, the `PairingChannel` implements the "externally-provisioned
pre-shared key" mode of [TLS1.3](https://tools.ietf.org/html/rfc8446).
Each side of the channel can thus be assured that its peer is in posession
of the `channelKey`, and that their traffic is protected from anyone who
does not possess this key.
6 changes: 3 additions & 3 deletions demo/test_client.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ <h2>fxa-pairing-tls demo client</h2>
<script src="../dist/FxAccountsPairingChannel.babel.umd.js"></script>
<script>
$(() => {
const {InsecurePairingChannel, hexToBytes} = FxAccountsPairingChannel;
const {PairingChannel, base64urlToBytes} = FxAccountsPairingChannel;
const CHANNEL_SERVER = 'wss://dev.channelserver.nonprod.cloudops.mozgcp.net';
$("#code-value").val("")
$("#chat-history").val("")
$("#code-value").on("keypress", async evt => {
if (evt.keyCode !== 13) { return }
const [channelId, pskHex] = $("#code-value").val().split("#");
const psk = hexToBytes(pskHex);
const channel = await InsecurePairingChannel.connect(CHANNEL_SERVER, channelId, psk);
const psk = base64urlToBytes(pskHex);
const channel = await PairingChannel.connect(CHANNEL_SERVER, channelId, psk);
channel.addEventListener("message", event => {
const {msg} = event.detail.data;
$("#chat-history").val($("#chat-history").val() + "\nthem>> " + msg)
Expand Down
7 changes: 3 additions & 4 deletions demo/test_server.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@ <h2>fxa-pairing-tls demo server</h2>
<script src="../dist/FxAccountsPairingChannel.babel.umd.js"></script>
<script>
$(async () => {
// TODO: do we want to export InsecurePairingChannel directly?
const {InsecurePairingChannel, bytesToHex} = FxAccountsPairingChannel;
const {PairingChannel, bytesToBase64url} = FxAccountsPairingChannel;
const CHANNEL_SERVER = 'wss://dev.channelserver.nonprod.cloudops.mozgcp.net';
$("#chat-history").val("");
const channel = await InsecurePairingChannel.create(CHANNEL_SERVER);
$("#code-value").text(`${channel.channelId}#${bytesToHex(channel.channelKey)}`);
const channel = await PairingChannel.create(CHANNEL_SERVER);
$("#code-value").text(`${channel.channelId}#${bytesToBase64url(channel.channelKey)}`);
channel.addEventListener("message", event => {
const {msg} = event.detail.data;
$("#chat-history").val($("#chat-history").val() + "\nthem>> " + msg);
Expand Down
Loading

0 comments on commit 57146da

Please sign in to comment.