Deprecate storageServiceKey in SyncMessage.Keys

This commit is contained in:
Fedor Indutny 2023-10-12 21:42:24 +02:00 committed by GitHub
parent 37b3a6de4b
commit d7b53f3d27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 26 deletions

View file

@ -198,7 +198,7 @@
"@electron/fuses": "1.5.0",
"@formatjs/intl": "2.6.7",
"@mixer/parallel-prettier": "2.0.3",
"@signalapp/mock-server": "4.1.2",
"@signalapp/mock-server": "4.2.0",
"@storybook/addon-a11y": "7.4.5",
"@storybook/addon-actions": "7.4.5",
"@storybook/addon-controls": "7.4.5",

View file

@ -505,7 +505,8 @@ message SyncMessage {
}
message Keys {
optional bytes storageService = 1;
optional bytes storageService = 1; // deprecated: this field will be removed in a future release.
optional bytes master = 2;
}
message Read {

View file

@ -127,6 +127,10 @@ export function decryptDeviceName(
return Bytes.toString(plaintext);
}
export function deriveStorageServiceKey(masterKey: Uint8Array): Uint8Array {
return hmacSha256(masterKey, Bytes.fromString('Storage Service Encryption'));
}
export function deriveStorageManifestKey(
storageServiceKey: Uint8Array,
version: Long = Long.fromNumber(0)

View file

@ -189,6 +189,7 @@ import {
getCallIdFromEra,
updateLocalGroupCallHistoryTimestamp,
} from './util/callDisposition';
import { deriveStorageServiceKey } from './Crypto';
export function isOverHourIntoPast(timestamp: number): boolean {
return isNumber(timestamp) && isOlderThan(timestamp, HOUR);
@ -1350,22 +1351,6 @@ export async function startApp(): Promise<void> {
async function runStorageService() {
StorageService.enableStorageService();
if (window.ConversationController.areWePrimaryDevice()) {
log.warn(
'background/runStorageService: We are primary device; not sending key sync request'
);
return;
}
try {
await singleProtoJobQueue.add(MessageSender.getRequestKeySyncMessage());
} catch (error) {
log.error(
'runStorageService: Failed to queue sync message',
Errors.toLogFormat(error)
);
}
}
async function start() {
@ -1821,6 +1806,26 @@ export async function startApp(): Promise<void> {
}
if (firstRun === true && deviceId !== 1) {
if (!window.storage.get('masterKey')) {
const lastSent = window.storage.get('masterKeyLastRequestTime') ?? 0;
const now = Date.now();
// If we last attempted sync one day in the past, or if we time
// traveled.
if (isOlderThan(lastSent, DAY) || lastSent > now) {
log.warn('connect: masterKey not captured, requesting sync');
await singleProtoJobQueue.add(
MessageSender.getRequestKeySyncMessage()
);
await window.storage.put('masterKeyLastRequestTime', now);
} else {
log.warn(
'connect: masterKey not captured, but sync requested recently.' +
'Not running'
);
}
}
const hasThemeSetting = Boolean(window.storage.get('theme-setting'));
if (
!hasThemeSetting &&
@ -3046,7 +3051,17 @@ export async function startApp(): Promise<void> {
async function onKeysSync(ev: KeysEvent) {
ev.confirm();
const { storageServiceKey } = ev;
const { masterKey } = ev;
let { storageServiceKey } = ev;
if (masterKey == null) {
log.info('onKeysSync: deleting window.masterKey');
await window.storage.remove('masterKey');
} else {
// Override provided storageServiceKey because it is deprecated.
storageServiceKey = deriveStorageServiceKey(masterKey);
await window.storage.put('masterKey', Bytes.toBase64(masterKey));
}
if (storageServiceKey == null) {
log.info('onKeysSync: deleting window.storageKey');

View file

@ -3292,12 +3292,15 @@ export default class MessageReceiver
logUnexpectedUrgentValue(envelope, 'keySync');
if (!sync.storageService) {
if (!sync.storageService && !sync.master) {
return undefined;
}
const ev = new KeysEvent(
sync.storageService,
{
storageServiceKey: dropNull(sync.storageService),
masterKey: dropNull(sync.master),
},
this.removeFromCache.bind(this, envelope)
);

View file

@ -355,12 +355,23 @@ export class FetchLatestEvent extends ConfirmableEvent {
}
}
export type KeysEventData = Readonly<{
storageServiceKey: Uint8Array | undefined;
masterKey: Uint8Array | undefined;
}>;
export class KeysEvent extends ConfirmableEvent {
public readonly storageServiceKey: Uint8Array | undefined;
public readonly masterKey: Uint8Array | undefined;
constructor(
public readonly storageServiceKey: Uint8Array,
{ storageServiceKey, masterKey }: KeysEventData,
confirm: ConfirmCallback
) {
super('keys', confirm);
this.storageServiceKey = storageServiceKey;
this.masterKey = masterKey;
}
}

View file

@ -86,6 +86,8 @@ export type StorageAccessType = {
lastAttemptedToRefreshProfilesAt: number;
lastResortKeyUpdateTime: number;
lastResortKeyUpdateTimePNI: number;
masterKey: string;
masterKeyLastRequestTime: number;
maxPreKeyId: number;
maxPreKeyIdPNI: number;
maxKyberPreKeyId: number;

View file

@ -3901,10 +3901,10 @@
node-gyp-build "^4.2.3"
uuid "^8.3.0"
"@signalapp/mock-server@4.1.2":
version "4.1.2"
resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-4.1.2.tgz#3f497d4cc5cc6613d2a860173ee1d9cee24ce9cd"
integrity sha512-vOFJ8bVQdhII6ZGc34wurxJZ9roeoq4ch0VeorImcyavL5p7d9VbNwpWyOA/VAlfTaUgaiXegVmzK3t52lCQTw==
"@signalapp/mock-server@4.2.0":
version "4.2.0"
resolved "https://registry.yarnpkg.com/@signalapp/mock-server/-/mock-server-4.2.0.tgz#836bf1d8cb38b9f66a6f719205e5000cdc7d184b"
integrity sha512-pungaAf3Pel34yIK00nRtHWQHA9VCRjOH11ZBgrEjiMpdA+LPETCU94Do28Q9Un7T8GmNOJ0+cKAhCKuyo1Fow==
dependencies:
"@signalapp/libsignal-client" "^0.30.2"
debug "^4.3.2"