Merge pull request #430 from sachaaaaa/handle_incoming_authorisation

[multi-device] Handle incoming pairing authorisation message
pull/438/head
sachaaaaa 6 years ago committed by GitHub
commit 5eab2098b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -16,6 +16,7 @@
/* global localServerPort: false */ /* global localServerPort: false */
/* global lokiMessageAPI: false */ /* global lokiMessageAPI: false */
/* global lokiP2pAPI: false */ /* global lokiP2pAPI: false */
/* global Whisper: false */
/* eslint-disable more/no-then */ /* eslint-disable more/no-then */
/* eslint-disable no-unreachable */ /* eslint-disable no-unreachable */
@ -1022,47 +1023,140 @@ MessageReceiver.prototype.extend({
} }
return this.removeFromCache(envelope); return this.removeFromCache(envelope);
}, },
async handlePairingAuthorisationMessage(envelope, pairingAuthorisation) { async validateAuthorisation(authorisation) {
const { const {
type, type,
primaryDevicePubKey, primaryDevicePubKey,
secondaryDevicePubKey, secondaryDevicePubKey,
signature, requestSignature,
} = pairingAuthorisation; grantSignature,
const sigArrayBuffer = dcodeIO.ByteBuffer.wrap(signature).toArrayBuffer(); } = authorisation;
if ( const alreadySecondaryDevice = !!window.storage.get('isSecondaryDevice');
type === const ourPubKey = textsecure.storage.user.getNumber();
textsecure.protobuf.PairingAuthorisationMessage.Type.PAIRING_REQUEST const isRequest =
) { type === textsecure.protobuf.PairingAuthorisationMessage.Type.REQUEST;
window.log.info( const isGrant =
`Received pairing authorisation from ${primaryDevicePubKey}` type === textsecure.protobuf.PairingAuthorisationMessage.Type.GRANT;
if (!primaryDevicePubKey || !secondaryDevicePubKey) {
window.log.warn(
'Received a pairing request with missing pubkeys. Ignored.'
);
return false;
} else if (!requestSignature) {
window.log.warn(
'Received a pairing request with missing request signature. Ignored.'
);
return false;
} else if (isRequest && alreadySecondaryDevice) {
window.log.warn(
'Received a pairing request while being a secondary device. Ignored.'
);
return false;
} else if (isRequest && authorisation.primaryDevicePubKey !== ourPubKey) {
window.log.warn(
'Received a pairing request addressed to another pubkey. Ignored.'
);
return false;
} else if (authorisation.secondaryDevicePubKey === ourPubKey) {
window.log.warn('Received a pairing request from ourselves. Ignored.');
return false;
}
try {
await libloki.crypto.verifyPairingAuthorisation(
primaryDevicePubKey,
secondaryDevicePubKey,
dcodeIO.ByteBuffer.wrap(requestSignature).toArrayBuffer(),
type
);
} catch (e) {
window.log.warn(
'Could not verify pairing request authorisation signature. Ignoring message.'
); );
let validAuthorisation = false; window.log.error(e);
return false;
}
if (isGrant) {
try { try {
await libloki.crypto.verifyPairingAuthorisation( await libloki.crypto.verifyPairingAuthorisation(
primaryDevicePubKey, primaryDevicePubKey,
secondaryDevicePubKey, secondaryDevicePubKey,
sigArrayBuffer, dcodeIO.ByteBuffer.wrap(grantSignature).toArrayBuffer(),
type type
); );
validAuthorisation = true;
} catch (e) { } catch (e) {
window.log.warn(
'Could not verify pairing grant authorisation signature. Ignoring message.'
);
window.log.error(e); window.log.error(e);
return false;
} }
if (validAuthorisation) { }
await libloki.storage.savePairingAuthorisation( return true;
primaryDevicePubKey, },
secondaryDevicePubKey, async handlePairingRequest(pairingRequest) {
sigArrayBuffer const valid = await this.validateAuthorisation(pairingRequest);
); if (!valid) {
} else { return;
}
await window.libloki.storage.savePairingAuthorisation(pairingRequest);
Whisper.events.trigger(
'devicePairingRequestReceived',
pairingRequest.secondaryDevicePubKey
);
},
async handleAuthorisationForSelf(pairingAuthorisation) {
const valid = await this.validateAuthorisation(pairingAuthorisation);
if (!valid) {
return;
}
const { type, primaryDevicePubKey } = pairingAuthorisation;
if (type === textsecure.protobuf.PairingAuthorisationMessage.Type.GRANT) {
// Authorisation received to become a secondary device
window.log.info(
`Received pairing authorisation from ${primaryDevicePubKey}`
);
const alreadySecondaryDevice = window.storage.get('isSecondaryDevice');
if (alreadySecondaryDevice) {
window.log.warn( window.log.warn(
'Could not verify pairing authorisation signature. Ignoring message.' 'Received an unexpected pairing authorisation (device is already paired as secondary device). Ignoring.'
); );
return;
} }
await libloki.storage.savePairingAuthorisation(pairingAuthorisation);
// Set current device as secondary.
// This will ensure the authorisation is sent
// along with each friend request.
window.storage.remove('secondaryDeviceStatus');
window.storage.put('isSecondaryDevice', true);
Whisper.events.trigger('secondaryDeviceRegistration');
} else { } else {
window.log.warn('Unimplemented pairing authorisation message type'); window.log.warn('Unimplemented pairing authorisation message type');
} }
},
async handleAuthorisationForContact(pairingAuthorisation) {
const valid = await this.validateAuthorisation(pairingAuthorisation);
if (!valid) {
return;
}
const { primaryDevicePubKey, secondaryDevicePubKey } = pairingAuthorisation;
// ensure the primary device is a friend
const c = window.ConversationController.get(primaryDevicePubKey);
if (!c || !c.isFriend()) {
return;
}
await libloki.storage.savePairingAuthorisation(pairingAuthorisation);
// send friend accept?
window.libloki.api.sendBackgroundMessage(secondaryDevicePubKey);
},
async handlePairingAuthorisationMessage(envelope, pairingAuthorisation) {
const { type, secondaryDevicePubKey } = pairingAuthorisation;
if (type === textsecure.protobuf.PairingAuthorisationMessage.Type.REQUEST) {
await this.handlePairingRequest(pairingAuthorisation);
} else if (secondaryDevicePubKey === textsecure.storage.user.getNumber()) {
await this.handleAuthorisationForSelf(pairingAuthorisation);
} else {
await this.handleAuthorisationForContact(pairingAuthorisation);
}
return this.removeFromCache(envelope); return this.removeFromCache(envelope);
}, },
handleDataMessage(envelope, msg) { handleDataMessage(envelope, msg) {

Loading…
Cancel
Save