increase roomSecret length to 264 chars and implement roomSecret regeneration functionality

This commit is contained in:
schlagmichdoch 2023-05-09 03:17:08 +02:00
parent 241ea4f988
commit 8d640be3a2
3 changed files with 49 additions and 3 deletions

View file

@ -171,6 +171,9 @@ class PairDropServer {
case 'pair-device-cancel': case 'pair-device-cancel':
this._onPairDeviceCancel(sender); this._onPairDeviceCancel(sender);
break; break;
case 'regenerate-room-secret':
this._onRegenerateRoomSecret(sender, message);
break
case 'resend-peers': case 'resend-peers':
this._notifyPeers(sender); this._notifyPeers(sender);
break; break;
@ -205,7 +208,7 @@ class PairDropServer {
_onRoomSecrets(sender, message) { _onRoomSecrets(sender, message) {
const roomSecrets = message.roomSecrets.filter(roomSecret => { const roomSecrets = message.roomSecrets.filter(roomSecret => {
return /^[\x00-\x7F]{64}$/.test(roomSecret); return /^[\x00-\x7F]{64,256}$/.test(roomSecret);
}) })
this._joinSecretRooms(sender, roomSecrets); this._joinSecretRooms(sender, roomSecrets);
} }
@ -233,7 +236,7 @@ class PairDropServer {
} }
_onPairDeviceInitiate(sender) { _onPairDeviceInitiate(sender) {
let roomSecret = randomizer.getRandomString(64); let roomSecret = randomizer.getRandomString(256);
let roomKey = this._createRoomKey(sender, roomSecret); let roomKey = this._createRoomKey(sender, roomSecret);
if (sender.roomKey) this._removeRoomKey(sender.roomKey); if (sender.roomKey) this._removeRoomKey(sender.roomKey);
sender.roomKey = roomKey; sender.roomKey = roomKey;
@ -246,16 +249,19 @@ class PairDropServer {
} }
_onPairDeviceJoin(sender, message) { _onPairDeviceJoin(sender, message) {
// rate limit implementation: max 10 attempts every 10s
if (sender.roomKeyRate >= 10) { if (sender.roomKeyRate >= 10) {
this._send(sender, { type: 'pair-device-join-key-rate-limit' }); this._send(sender, { type: 'pair-device-join-key-rate-limit' });
return; return;
} }
sender.roomKeyRate += 1; sender.roomKeyRate += 1;
setTimeout(_ => sender.roomKeyRate -= 1, 10000); setTimeout(_ => sender.roomKeyRate -= 1, 10000);
if (!this._roomSecrets[message.roomKey] || sender.id === this._roomSecrets[message.roomKey].creator.id) { if (!this._roomSecrets[message.roomKey] || sender.id === this._roomSecrets[message.roomKey].creator.id) {
this._send(sender, { type: 'pair-device-join-key-invalid' }); this._send(sender, { type: 'pair-device-join-key-invalid' });
return; return;
} }
const roomSecret = this._roomSecrets[message.roomKey].roomSecret; const roomSecret = this._roomSecrets[message.roomKey].roomSecret;
const creator = this._roomSecrets[message.roomKey].creator; const creator = this._roomSecrets[message.roomKey].creator;
this._removeRoomKey(message.roomKey); this._removeRoomKey(message.roomKey);
@ -275,14 +281,31 @@ class PairDropServer {
_onPairDeviceCancel(sender) { _onPairDeviceCancel(sender) {
if (sender.roomKey) { if (sender.roomKey) {
this._removeRoomKey(sender.roomKey);
this._send(sender, { this._send(sender, {
type: 'pair-device-canceled', type: 'pair-device-canceled',
roomKey: sender.roomKey, roomKey: sender.roomKey,
}); });
this._removeRoomKey(sender.roomKey);
} }
} }
_onRegenerateRoomSecret(sender, message) {
const oldRoomSecret = message.roomSecret;
const newRoomSecret = randomizer.getRandomString(256);
// notify all other peers
for (const peerId in this._rooms[oldRoomSecret]) {
const peer = this._rooms[oldRoomSecret][peerId];
this._send(peer, {
type: 'room-secret-regenerated',
oldRoomSecret: oldRoomSecret,
newRoomSecret: newRoomSecret,
});
peer.removeRoomSecret(oldRoomSecret);
}
delete this._rooms[oldRoomSecret];
}
_createRoomKey(creator, roomSecret) { _createRoomKey(creator, roomSecret) {
let roomKey; let roomKey;
do { do {

View file

@ -12,6 +12,7 @@ class ServerConnection {
if (navigator.connection) navigator.connection.addEventListener('change', _ => this._reconnect()); if (navigator.connection) navigator.connection.addEventListener('change', _ => this._reconnect());
Events.on('room-secrets', e => this._sendRoomSecrets(e.detail)); Events.on('room-secrets', e => this._sendRoomSecrets(e.detail));
Events.on('room-secrets-deleted', e => this.send({ type: 'room-secrets-deleted', roomSecrets: e.detail})); Events.on('room-secrets-deleted', e => this.send({ type: 'room-secrets-deleted', roomSecrets: e.detail}));
Events.on('regenerate-room-secret', e => this.send({ type: 'regenerate-room-secret', roomSecret: e.detail}));
Events.on('resend-peers', _ => this.send({ type: 'resend-peers'})); Events.on('resend-peers', _ => this.send({ type: 'resend-peers'}));
Events.on('pair-device-initiate', _ => this._onPairDeviceInitiate()); Events.on('pair-device-initiate', _ => this._onPairDeviceInitiate());
Events.on('pair-device-join', e => this._onPairDeviceJoin(e.detail)); Events.on('pair-device-join', e => this._onPairDeviceJoin(e.detail));
@ -105,6 +106,9 @@ class ServerConnection {
case 'secret-room-deleted': case 'secret-room-deleted':
Events.fire('secret-room-deleted', msg.roomSecret); Events.fire('secret-room-deleted', msg.roomSecret);
break; break;
case 'room-secret-regenerated':
Events.fire('room-secret-regenerated', msg);
break;
default: default:
console.error('WS receive: unknown message type', msg); console.error('WS receive: unknown message type', msg);
} }
@ -808,6 +812,7 @@ class PeersManager {
Events.on('peer-connected', e => this._onPeerConnected(e.detail.peerId)); Events.on('peer-connected', e => this._onPeerConnected(e.detail.peerId));
Events.on('peer-disconnected', e => this._onPeerDisconnected(e.detail)); Events.on('peer-disconnected', e => this._onPeerDisconnected(e.detail));
Events.on('secret-room-deleted', e => this._onSecretRoomDeleted(e.detail)); Events.on('secret-room-deleted', e => this._onSecretRoomDeleted(e.detail));
Events.on('room-secret-regenerated', e => this._onRoomSecretRegenerated(e.detail));
Events.on('display-name', e => this._onDisplayName(e.detail.message.displayName)); Events.on('display-name', e => this._onDisplayName(e.detail.message.displayName));
Events.on('self-display-name-changed', e => this._notifyPeersDisplayNameChanged(e.detail)); Events.on('self-display-name-changed', e => this._notifyPeersDisplayNameChanged(e.detail));
Events.on('notify-peer-display-name-changed', e => this._notifyPeerDisplayNameChanged(e.detail)); Events.on('notify-peer-display-name-changed', e => this._notifyPeerDisplayNameChanged(e.detail));
@ -913,6 +918,13 @@ class PeersManager {
} }
} }
_onRoomSecretRegenerated(message) {
PersistentStorage.updateRoomSecret(message.oldRoomSecret, message.newRoomSecret).then(_ => {
console.log("successfully regenerated room secret");
Events.fire("room-secrets", [message.newRoomSecret]);
})
}
_notifyPeersDisplayNameChanged(newDisplayName) { _notifyPeersDisplayNameChanged(newDisplayName) {
this._displayName = newDisplayName ? newDisplayName : this._originalDisplayName; this._displayName = newDisplayName ? newDisplayName : this._originalDisplayName;
for (const peerId in this.peers) { for (const peerId in this.peers) {

View file

@ -104,6 +104,9 @@ class ServerConnection {
case 'secret-room-deleted': case 'secret-room-deleted':
Events.fire('secret-room-deleted', msg.roomSecret); Events.fire('secret-room-deleted', msg.roomSecret);
break; break;
case 'room-secret-regenerated':
Events.fire('room-secret-regenerated', msg);
break;
case 'request': case 'request':
case 'header': case 'header':
case 'partition': case 'partition':
@ -860,6 +863,7 @@ class PeersManager {
Events.on('peer-connected', e => this._onPeerConnected(e.detail.peerId)); Events.on('peer-connected', e => this._onPeerConnected(e.detail.peerId));
Events.on('peer-disconnected', e => this._onPeerDisconnected(e.detail)); Events.on('peer-disconnected', e => this._onPeerDisconnected(e.detail));
Events.on('secret-room-deleted', e => this._onSecretRoomDeleted(e.detail)); Events.on('secret-room-deleted', e => this._onSecretRoomDeleted(e.detail));
Events.on('room-secret-regenerated', e => this._onRoomSecretRegenerated(e.detail));
Events.on('display-name', e => this._onDisplayName(e.detail.message.displayName)); Events.on('display-name', e => this._onDisplayName(e.detail.message.displayName));
Events.on('self-display-name-changed', e => this._notifyPeersDisplayNameChanged(e.detail)); Events.on('self-display-name-changed', e => this._notifyPeersDisplayNameChanged(e.detail));
Events.on('notify-peer-display-name-changed', e => this._notifyPeerDisplayNameChanged(e.detail)); Events.on('notify-peer-display-name-changed', e => this._notifyPeerDisplayNameChanged(e.detail));
@ -992,6 +996,13 @@ class PeersManager {
} }
} }
_onRoomSecretRegenerated(message) {
PersistentStorage.updateRoomSecret(message.oldRoomSecret, message.newRoomSecret).then(_ => {
console.log("successfully regenerated room secret");
Events.fire("room-secrets", [message.newRoomSecret]);
})
}
_notifyPeersDisplayNameChanged(newDisplayName) { _notifyPeersDisplayNameChanged(newDisplayName) {
this._displayName = newDisplayName ? newDisplayName : this._originalDisplayName; this._displayName = newDisplayName ? newDisplayName : this._originalDisplayName;
for (const peerId in this.peers) { for (const peerId in this.peers) {