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 lokiMessageAPI: false */
/* global lokiP2pAPI: false */
/* global Whisper: false */
/* eslint-disable more/no-then */
/* eslint-disable no-unreachable */
@ -1022,47 +1023,140 @@ MessageReceiver.prototype.extend({
}
return this.removeFromCache(envelope);
},
async handlePairingAuthorisationMessage(envelope, pairingAuthorisation) {
async validateAuthorisation(authorisation) {
const {
type,
primaryDevicePubKey,
secondaryDevicePubKey,
signature,
} = pairingAuthorisation;
const sigArrayBuffer = dcodeIO.ByteBuffer.wrap(signature).toArrayBuffer();
if (
type ===
textsecure.protobuf.PairingAuthorisationMessage.Type.PAIRING_REQUEST
) {
window.log.info(
`Received pairing authorisation from ${primaryDevicePubKey}`
requestSignature,
grantSignature,
} = authorisation;
const alreadySecondaryDevice = !!window.storage.get('isSecondaryDevice');
const ourPubKey = textsecure.storage.user.getNumber();
const isRequest =
type === textsecure.protobuf.PairingAuthorisationMessage.Type.REQUEST;
const isGrant =
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 {
await libloki.crypto.verifyPairingAuthorisation(
primaryDevicePubKey,
secondaryDevicePubKey,
sigArrayBuffer,
dcodeIO.ByteBuffer.wrap(grantSignature).toArrayBuffer(),
type
);
validAuthorisation = true;
} catch (e) {
window.log.warn(
'Could not verify pairing grant authorisation signature. Ignoring message.'
);
window.log.error(e);
return false;
}
if (validAuthorisation) {
await libloki.storage.savePairingAuthorisation(
primaryDevicePubKey,
secondaryDevicePubKey,
sigArrayBuffer
);
} else {
}
return true;
},
async handlePairingRequest(pairingRequest) {
const valid = await this.validateAuthorisation(pairingRequest);
if (!valid) {
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(
'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 {
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);
},
handleDataMessage(envelope, msg) {

Loading…
Cancel
Save