mirror of
https://github.com/schlagmichdoch/PairDrop.git
synced 2025-04-22 15:56:17 -04:00
[security] Add security number to PeerUI to make verification of peer-to-peer encryption possible.
This commit is contained in:
parent
e9b23bfdb0
commit
c5d0eaa034
9 changed files with 131 additions and 23 deletions
|
@ -568,7 +568,7 @@ class RTCPeer extends Peer {
|
|||
|
||||
_onChannelOpened(event) {
|
||||
console.log('RTC: channel opened with', this._peerId);
|
||||
Events.fire('peer-connected', this._peerId);
|
||||
Events.fire('peer-connected', {peerId: this._peerId, connectionHash: this.getConnectionHash()});
|
||||
const channel = event.channel || event.target;
|
||||
channel.binaryType = 'arraybuffer';
|
||||
channel.onmessage = e => this._onMessage(e.data);
|
||||
|
@ -578,6 +578,32 @@ class RTCPeer extends Peer {
|
|||
this._channel = channel;
|
||||
}
|
||||
|
||||
getConnectionHash() {
|
||||
const localDescriptionLines = this._conn.localDescription.sdp.split("\r\n");
|
||||
const remoteDescriptionLines = this._conn.remoteDescription.sdp.split("\r\n");
|
||||
let localConnectionFingerprint, remoteConnectionFingerprint;
|
||||
for (let i=0; i<localDescriptionLines.length; i++) {
|
||||
if (localDescriptionLines[i].startsWith("a=fingerprint:")) {
|
||||
localConnectionFingerprint = localDescriptionLines[i].substring(14);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (let i=0; i<remoteDescriptionLines.length; i++) {
|
||||
if (remoteDescriptionLines[i].startsWith("a=fingerprint:")) {
|
||||
remoteConnectionFingerprint = remoteDescriptionLines[i].substring(14);
|
||||
break;
|
||||
}
|
||||
}
|
||||
const combinedFingerprints = this._isCaller
|
||||
? localConnectionFingerprint + remoteConnectionFingerprint
|
||||
: remoteConnectionFingerprint + localConnectionFingerprint;
|
||||
let hash = cyrb53(combinedFingerprints).toString();
|
||||
while (hash.length < 16) {
|
||||
hash = "0" + hash;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
_onBeforeUnload(e) {
|
||||
if (this._busy) {
|
||||
e.preventDefault();
|
||||
|
@ -679,11 +705,16 @@ class WSPeer extends Peer {
|
|||
}
|
||||
|
||||
onServerMessage(message) {
|
||||
Events.fire('peer-connected', message.sender.id)
|
||||
Events.fire('peer-connected', {peerId: message.sender.id, connectionHash: this.getConnectionHash()})
|
||||
if (this._peerId) return;
|
||||
this._peerId = message.sender.id;
|
||||
this._sendSignal();
|
||||
}
|
||||
|
||||
getConnectionHash() {
|
||||
// Todo: implement SubtleCrypto asymmetric encryption and create connectionHash from public keys
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
class PeersManager {
|
||||
|
|
|
@ -19,7 +19,7 @@ class PeersUI {
|
|||
|
||||
constructor() {
|
||||
Events.on('peer-joined', e => this._onPeerJoined(e.detail));
|
||||
Events.on('peer-connected', e => this._onPeerConnected(e.detail));
|
||||
Events.on('peer-connected', e => this._onPeerConnected(e.detail.peerId, e.detail.connectionHash));
|
||||
Events.on('peer-disconnected', e => this._onPeerDisconnected(e.detail));
|
||||
Events.on('peers', e => this._onPeers(e.detail));
|
||||
Events.on('set-progress', e => this._onSetProgress(e.detail));
|
||||
|
@ -63,9 +63,9 @@ class PeersUI {
|
|||
this.peers[peer.id] = peer;
|
||||
}
|
||||
|
||||
_onPeerConnected(peerId) {
|
||||
_onPeerConnected(peerId, connectionHash) {
|
||||
if(this.peers[peerId] && !$(peerId))
|
||||
new PeerUI(this.peers[peerId]);
|
||||
new PeerUI(this.peers[peerId], connectionHash);
|
||||
}
|
||||
|
||||
_redrawPeer(peer) {
|
||||
|
@ -235,17 +235,21 @@ class PeerUI {
|
|||
<div class="name font-subheading"></div>
|
||||
<div class="device-name font-body2"></div>
|
||||
<div class="status font-body2"></div>
|
||||
<span class="connection-hash font-body2" title="To verify the security of the end-to-end encryption, compare this security number on both devices"></span>
|
||||
</label>`;
|
||||
|
||||
this.$el.querySelector('svg use').setAttribute('xlink:href', this._icon());
|
||||
this.$el.querySelector('.name').textContent = this._displayName();
|
||||
this.$el.querySelector('.device-name').textContent = this._deviceName();
|
||||
this.$el.querySelector('.connection-hash').textContent =
|
||||
this._connectionHash.substring(0, 4) + " " + this._connectionHash.substring(4, 8) + " " + this._connectionHash.substring(8, 12) + " " + this._connectionHash.substring(12, 16);
|
||||
}
|
||||
|
||||
constructor(peer) {
|
||||
constructor(peer, connectionHash) {
|
||||
this._peer = peer;
|
||||
this._roomType = peer.roomType;
|
||||
this._roomSecret = peer.roomSecret;
|
||||
this._connectionHash = connectionHash;
|
||||
this._initDom();
|
||||
this._bindListeners();
|
||||
$$('x-peers').appendChild(this.$el);
|
||||
|
|
|
@ -381,6 +381,24 @@ const mime = (() => {
|
|||
|
||||
})();
|
||||
|
||||
/*
|
||||
cyrb53 (c) 2018 bryc (github.com/bryc)
|
||||
A fast and simple hash function with decent collision resistance.
|
||||
Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity.
|
||||
Public domain. Attribution appreciated.
|
||||
*/
|
||||
const cyrb53 = function(str, seed = 0) {
|
||||
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
|
||||
for (let i = 0, ch; i < str.length; i++) {
|
||||
ch = str.charCodeAt(i);
|
||||
h1 = Math.imul(h1 ^ ch, 2654435761);
|
||||
h2 = Math.imul(h2 ^ ch, 1597334677);
|
||||
}
|
||||
h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909);
|
||||
h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909);
|
||||
return 4294967296 * (2097151 & h2) + (h1>>>0);
|
||||
};
|
||||
|
||||
function arrayBufferToBase64(buffer) {
|
||||
var binary = '';
|
||||
var bytes = new Uint8Array(buffer);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue