Social Graph: read-only state sync with primary device

This commit is contained in:
Josh Perez 2020-07-06 20:56:56 -04:00 committed by Scott Nonnenberg
parent 12745a2c79
commit 8502d23576
19 changed files with 1035 additions and 57 deletions

View file

@ -1675,6 +1675,8 @@
addQueuedEventListener('viewSync', onViewSync);
addQueuedEventListener('messageRequestResponse', onMessageRequestResponse);
addQueuedEventListener('profileKeyUpdate', onProfileKeyUpdate);
addQueuedEventListener('fetchLatest', onFetchLatestSync);
addQueuedEventListener('keys', onKeysSync);
window.Signal.AttachmentDownloads.start({
getMessageReceiver: () => messageReceiver,
@ -1688,6 +1690,7 @@
if (connectCount === 1) {
window.Signal.Stickers.downloadQueuedPacks();
await window.textsecure.messaging.sendRequestKeySyncMessage();
}
// On startup after upgrading to a new version, request a contact sync
@ -2728,6 +2731,45 @@
Whisper.ViewSyncs.onSync(sync);
}
async function onFetchLatestSync(ev) {
ev.confirm();
const { eventType } = ev;
const FETCH_LATEST_ENUM = textsecure.protobuf.SyncMessage.FetchLatest.Type;
switch (eventType) {
case FETCH_LATEST_ENUM.LOCAL_PROFILE:
// Intentionally do nothing since we'll be receiving the storage manifest request
// and will update local profile along with that.
break;
case FETCH_LATEST_ENUM.STORAGE_MANIFEST:
window.log.info('onFetchLatestSync: fetching latest manifest');
await window.Signal.Util.runStorageServiceSyncJob();
break;
default:
window.log.info(
`onFetchLatestSync: Unknown type encountered ${eventType}`
);
}
}
async function onKeysSync(ev) {
ev.confirm();
const { storageServiceKey } = ev;
if (storageServiceKey) {
window.log.info('onKeysSync: received keys');
const storageServiceKeyBase64 = window.Signal.Crypto.arrayBufferToBase64(
storageServiceKey
);
storage.put('storageKey', storageServiceKeyBase64);
await window.Signal.Util.runStorageServiceSyncJob();
}
}
async function onMessageRequestResponse(ev) {
ev.confirm();

View file

@ -39,6 +39,14 @@
writeNewAttachmentData,
} = window.Signal.Migrations;
const { addStickerPackReference } = window.Signal.Data;
const {
arrayBufferToBase64,
base64ToArrayBuffer,
deriveAccessKey,
getRandomBytes,
stringFromBytes,
verifyAccessKey,
} = window.Signal.Crypto;
const COLORS = [
'red',
@ -760,6 +768,8 @@
verified
);
}
return keyChange;
},
sendVerifySyncMessage(e164, uuid, state) {
// Because syncVerification sends a (null) message to the target of the verify and
@ -1754,11 +1764,7 @@
// If we've never fetched user's profile, we default to what we have
if (sealedSender === SEALED_SENDER.UNKNOWN) {
const info = {
accessKey:
accessKey ||
window.Signal.Crypto.arrayBufferToBase64(
window.Signal.Crypto.getRandomBytes(16)
),
accessKey: accessKey || arrayBufferToBase64(getRandomBytes(16)),
// Indicates that a client is capable of receiving uuid-only messages.
// Not used yet.
uuidCapable,
@ -1777,9 +1783,7 @@
accessKey:
accessKey && sealedSender === SEALED_SENDER.ENABLED
? accessKey
: window.Signal.Crypto.arrayBufferToBase64(
window.Signal.Crypto.getRandomBytes(16)
),
: arrayBufferToBase64(getRandomBytes(16)),
// Indicates that a client is capable of receiving uuid-only messages.
// Not used yet.
uuidCapable,
@ -2343,9 +2347,7 @@
});
}
const identityKey = window.Signal.Crypto.base64ToArrayBuffer(
profile.identityKey
);
const identityKey = base64ToArrayBuffer(profile.identityKey);
const changed = await textsecure.storage.protocol.saveIdentity(
`${id}.1`,
identityKey,
@ -2375,9 +2377,9 @@
sealedSender: SEALED_SENDER.UNRESTRICTED,
});
} else if (accessKey && profile.unidentifiedAccess) {
const haveCorrectKey = await window.Signal.Crypto.verifyAccessKey(
window.Signal.Crypto.base64ToArrayBuffer(accessKey),
window.Signal.Crypto.base64ToArrayBuffer(profile.unidentifiedAccess)
const haveCorrectKey = await verifyAccessKey(
base64ToArrayBuffer(accessKey),
base64ToArrayBuffer(profile.unidentifiedAccess)
);
if (haveCorrectKey) {
@ -2466,8 +2468,8 @@
}
// decode
const keyBuffer = window.Signal.Crypto.base64ToArrayBuffer(key);
const data = window.Signal.Crypto.base64ToArrayBuffer(encryptedName);
const keyBuffer = base64ToArrayBuffer(key);
const data = base64ToArrayBuffer(encryptedName);
// decrypt
const { given, family } = await textsecure.crypto.decryptProfileName(
@ -2476,10 +2478,8 @@
);
// encode
const profileName = window.Signal.Crypto.stringFromBytes(given);
const profileFamilyName = family
? window.Signal.Crypto.stringFromBytes(family)
: null;
const profileFamilyName = family ? stringFromBytes(family) : null;
const profileName = given ? stringFromBytes(given) : null;
// set
this.set({ profileName, profileFamilyName });
@ -2494,7 +2494,7 @@
if (!key) {
return;
}
const keyBuffer = window.Signal.Crypto.base64ToArrayBuffer(key);
const keyBuffer = base64ToArrayBuffer(key);
// decrypt
const decrypted = await textsecure.crypto.decryptProfile(
@ -2577,15 +2577,9 @@
return;
}
const profileKeyBuffer = window.Signal.Crypto.base64ToArrayBuffer(
profileKey
);
const accessKeyBuffer = await window.Signal.Crypto.deriveAccessKey(
profileKeyBuffer
);
const accessKey = window.Signal.Crypto.arrayBufferToBase64(
accessKeyBuffer
);
const profileKeyBuffer = base64ToArrayBuffer(profileKey);
const accessKeyBuffer = await deriveAccessKey(profileKeyBuffer);
const accessKey = arrayBufferToBase64(accessKeyBuffer);
this.set({ accessKey });
},
async deriveProfileKeyVersionIfNeeded() {