Handle PniChangeNumber
This commit is contained in:
parent
412f07d2a2
commit
79b48115e6
32 changed files with 1086 additions and 485 deletions
|
@ -7,7 +7,7 @@ import { omit } from 'lodash';
|
|||
import EventTarget from './EventTarget';
|
||||
import type { WebAPIType } from './WebAPI';
|
||||
import { HTTPError } from './Errors';
|
||||
import type { KeyPairType } from './Types.d';
|
||||
import type { KeyPairType, PniKeyMaterialType } from './Types.d';
|
||||
import ProvisioningCipher from './ProvisioningCipher';
|
||||
import type { IncomingWebSocketRequest } from './WebsocketResources';
|
||||
import createTaskWithTimeout from './TaskWithTimeout';
|
||||
|
@ -332,6 +332,7 @@ export default class AccountManager extends EventTarget {
|
|||
}
|
||||
const keys = await this.generateKeys(SIGNED_KEY_GEN_BATCH_SIZE, uuidKind);
|
||||
await this.server.registerKeys(keys, uuidKind);
|
||||
await this.confirmKeys(keys, uuidKind);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -649,16 +650,10 @@ export default class AccountManager extends EventTarget {
|
|||
|
||||
const identityKeyMap = {
|
||||
...(storage.get('identityKeyMap') || {}),
|
||||
[ourUuid]: {
|
||||
pubKey: Bytes.toBase64(aciKeyPair.pubKey),
|
||||
privKey: Bytes.toBase64(aciKeyPair.privKey),
|
||||
},
|
||||
[ourUuid]: aciKeyPair,
|
||||
...(pniKeyPair
|
||||
? {
|
||||
[ourPni]: {
|
||||
pubKey: Bytes.toBase64(pniKeyPair.pubKey),
|
||||
privKey: Bytes.toBase64(pniKeyPair.privKey),
|
||||
},
|
||||
[ourPni]: pniKeyPair,
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
|
@ -702,30 +697,18 @@ export default class AccountManager extends EventTarget {
|
|||
|
||||
log.info('AccountManager.updatePNIIdentity: generating new keys');
|
||||
|
||||
return this.queueTask(async () => {
|
||||
const keys = await this.generateKeys(
|
||||
SIGNED_KEY_GEN_BATCH_SIZE,
|
||||
UUIDKind.PNI,
|
||||
identityKeyPair
|
||||
);
|
||||
await this.server.registerKeys(keys, UUIDKind.PNI);
|
||||
await this.confirmKeys(keys, UUIDKind.PNI);
|
||||
|
||||
await this.queueTask(async () => {
|
||||
// Server has accepted our keys which means we have the latest PNI identity
|
||||
// now that doesn't conflict the PNI identity of the primary device.
|
||||
log.info(
|
||||
'AccountManager.updatePNIIdentity: updating identity key ' +
|
||||
'and registration id'
|
||||
);
|
||||
const { pubKey, privKey } = identityKeyPair;
|
||||
|
||||
const pni = storage.user.getCheckedUuid(UUIDKind.PNI);
|
||||
const identityKeyMap = {
|
||||
...(storage.get('identityKeyMap') || {}),
|
||||
[pni.toString()]: {
|
||||
pubKey: Bytes.toBase64(pubKey),
|
||||
privKey: Bytes.toBase64(privKey),
|
||||
},
|
||||
[pni.toString()]: identityKeyPair,
|
||||
};
|
||||
|
||||
const aci = storage.user.getCheckedUuid(UUIDKind.ACI);
|
||||
|
@ -744,6 +727,26 @@ export default class AccountManager extends EventTarget {
|
|||
|
||||
await storage.protocol.hydrateCaches();
|
||||
});
|
||||
|
||||
// Intentionally not awaiting becase `updatePNIIdentity` runs on an
|
||||
// Encrypted queue of MessageReceiver and we don't want to await remote
|
||||
// endpoints and block message processing.
|
||||
this.queueTask(async () => {
|
||||
try {
|
||||
const keys = await this.generateKeys(
|
||||
SIGNED_KEY_GEN_BATCH_SIZE,
|
||||
UUIDKind.PNI,
|
||||
identityKeyPair
|
||||
);
|
||||
await this.server.registerKeys(keys, UUIDKind.PNI);
|
||||
await this.confirmKeys(keys, UUIDKind.PNI);
|
||||
} catch (error) {
|
||||
log.error(
|
||||
'updatePNIIdentity: Failed to upload PNI prekeys. Moving on',
|
||||
Errors.toLogFormat(error)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Takes the same object returned by generateKeys
|
||||
|
@ -841,30 +844,50 @@ export default class AccountManager extends EventTarget {
|
|||
this.dispatchEvent(new Event('registration'));
|
||||
}
|
||||
|
||||
async setPni(pni: string): Promise<void> {
|
||||
async setPni(pni: string, keyMaterial?: PniKeyMaterialType): Promise<void> {
|
||||
const { storage } = window.textsecure;
|
||||
|
||||
const oldPni = storage.user.getUuid(UUIDKind.PNI)?.toString();
|
||||
if (oldPni === pni) {
|
||||
if (oldPni === pni && !keyMaterial) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.info(`AccountManager.setPni(${pni}): updating from ${oldPni}`);
|
||||
|
||||
if (oldPni) {
|
||||
await Promise.all([
|
||||
storage.put(
|
||||
'identityKeyMap',
|
||||
omit(storage.get('identityKeyMap') || {}, oldPni)
|
||||
),
|
||||
storage.put(
|
||||
'registrationIdMap',
|
||||
omit(storage.get('registrationIdMap') || {}, oldPni)
|
||||
),
|
||||
]);
|
||||
await storage.protocol.removeOurOldPni(new UUID(oldPni));
|
||||
}
|
||||
|
||||
log.info(`AccountManager.setPni: updating pni from ${oldPni} to ${pni}`);
|
||||
await storage.user.setPni(pni);
|
||||
|
||||
await storage.protocol.hydrateCaches();
|
||||
if (keyMaterial) {
|
||||
await storage.protocol.updateOurPniKeyMaterial(
|
||||
new UUID(pni),
|
||||
keyMaterial
|
||||
);
|
||||
|
||||
// Intentionally not awaiting since this is processed on encrypted queue
|
||||
// of MessageReceiver.
|
||||
this.queueTask(async () => {
|
||||
try {
|
||||
const keys = await this.generateKeys(
|
||||
SIGNED_KEY_GEN_BATCH_SIZE,
|
||||
UUIDKind.PNI
|
||||
);
|
||||
await this.server.registerKeys(keys, UUIDKind.PNI);
|
||||
await this.confirmKeys(keys, UUIDKind.PNI);
|
||||
} catch (error) {
|
||||
log.error(
|
||||
'setPni: Failed to upload PNI prekeys. Moving on',
|
||||
Errors.toLogFormat(error)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// PNI has changed and credentials are no longer valid
|
||||
await storage.put('groupCredentials', []);
|
||||
} else {
|
||||
log.warn(`AccountManager.setPni(${pni}): no key material`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,7 +101,6 @@ import {
|
|||
MessageRequestResponseEvent,
|
||||
FetchLatestEvent,
|
||||
KeysEvent,
|
||||
PNIIdentityEvent,
|
||||
StickerPackEvent,
|
||||
ReadSyncEvent,
|
||||
ViewSyncEvent,
|
||||
|
@ -256,8 +255,6 @@ export default class MessageReceiver
|
|||
|
||||
private stoppingProcessing?: boolean;
|
||||
|
||||
private pendingPNIIdentityEvent?: PNIIdentityEvent;
|
||||
|
||||
constructor({ server, storage, serverTrustRoot }: MessageReceiverOptions) {
|
||||
super();
|
||||
|
||||
|
@ -376,6 +373,14 @@ export default class MessageReceiver
|
|||
)
|
||||
)
|
||||
: ourUuid,
|
||||
updatedPni: decoded.updatedPni
|
||||
? new UUID(
|
||||
normalizeUuid(
|
||||
decoded.updatedPni,
|
||||
'MessageReceiver.handleRequest.updatedPni'
|
||||
)
|
||||
)
|
||||
: undefined,
|
||||
timestamp: decoded.timestamp?.toNumber(),
|
||||
content: dropNull(decoded.content),
|
||||
serverGuid: decoded.serverGuid,
|
||||
|
@ -535,11 +540,6 @@ export default class MessageReceiver
|
|||
handler: (ev: KeysEvent) => void
|
||||
): void;
|
||||
|
||||
public override addEventListener(
|
||||
name: 'pniIdentity',
|
||||
handler: (ev: PNIIdentityEvent) => void
|
||||
): void;
|
||||
|
||||
public override addEventListener(
|
||||
name: 'sticker-pack',
|
||||
handler: (ev: StickerPackEvent) => void
|
||||
|
@ -671,13 +671,6 @@ export default class MessageReceiver
|
|||
this.isEmptied = true;
|
||||
|
||||
this.maybeScheduleRetryTimeout();
|
||||
|
||||
// Emit PNI identity event after processing the queue
|
||||
const { pendingPNIIdentityEvent } = this;
|
||||
this.pendingPNIIdentityEvent = undefined;
|
||||
if (pendingPNIIdentityEvent) {
|
||||
await this.dispatchAndWait(pendingPNIIdentityEvent);
|
||||
}
|
||||
};
|
||||
|
||||
const waitForDecryptedQueue = async () => {
|
||||
|
@ -772,6 +765,9 @@ export default class MessageReceiver
|
|||
destinationUuid: new UUID(
|
||||
decoded.destinationUuid || item.destinationUuid || ourUuid.toString()
|
||||
),
|
||||
updatedPni: decoded.updatedPni
|
||||
? new UUID(decoded.updatedPni)
|
||||
: undefined,
|
||||
timestamp: decoded.timestamp?.toNumber(),
|
||||
content: dropNull(decoded.content),
|
||||
serverGuid: decoded.serverGuid,
|
||||
|
@ -902,16 +898,6 @@ export default class MessageReceiver
|
|||
items.map(async ({ data, envelope }) => {
|
||||
try {
|
||||
const { destinationUuid } = envelope;
|
||||
const uuidKind =
|
||||
this.storage.user.getOurUuidKind(destinationUuid);
|
||||
if (uuidKind === UUIDKind.Unknown) {
|
||||
log.warn(
|
||||
'MessageReceiver.decryptAndCacheBatch: ' +
|
||||
`Rejecting envelope ${getEnvelopeId(envelope)}, ` +
|
||||
`unknown uuid: ${destinationUuid}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let stores = storesMap.get(destinationUuid.toString());
|
||||
if (!stores) {
|
||||
|
@ -935,8 +921,7 @@ export default class MessageReceiver
|
|||
|
||||
const result = await this.queueEncryptedEnvelope(
|
||||
stores,
|
||||
envelope,
|
||||
uuidKind
|
||||
envelope
|
||||
);
|
||||
if (result.plaintext) {
|
||||
decrypted.push({
|
||||
|
@ -972,6 +957,7 @@ export default class MessageReceiver
|
|||
sourceUuid: envelope.sourceUuid,
|
||||
sourceDevice: envelope.sourceDevice,
|
||||
destinationUuid: envelope.destinationUuid.toString(),
|
||||
updatedPni: envelope.updatedPni?.toString(),
|
||||
serverGuid: envelope.serverGuid,
|
||||
serverTimestamp: envelope.serverTimestamp,
|
||||
decrypted: Bytes.toBase64(plaintext),
|
||||
|
@ -1089,13 +1075,23 @@ export default class MessageReceiver
|
|||
|
||||
private async queueEncryptedEnvelope(
|
||||
stores: LockedStores,
|
||||
envelope: ProcessedEnvelope,
|
||||
uuidKind: UUIDKind
|
||||
envelope: ProcessedEnvelope
|
||||
): Promise<DecryptResult> {
|
||||
let logId = getEnvelopeId(envelope);
|
||||
log.info(`queueing ${uuidKind} envelope`, logId);
|
||||
log.info('queueing envelope', logId);
|
||||
|
||||
const task = async (): Promise<DecryptResult> => {
|
||||
const { destinationUuid } = envelope;
|
||||
const uuidKind = this.storage.user.getOurUuidKind(destinationUuid);
|
||||
if (uuidKind === UUIDKind.Unknown) {
|
||||
log.warn(
|
||||
'MessageReceiver.decryptAndCacheBatch: ' +
|
||||
`Rejecting envelope ${getEnvelopeId(envelope)}, ` +
|
||||
`unknown uuid: ${destinationUuid}`
|
||||
);
|
||||
return { plaintext: undefined, envelope };
|
||||
}
|
||||
|
||||
const unsealedEnvelope = await this.unsealEnvelope(
|
||||
stores,
|
||||
envelope,
|
||||
|
@ -1311,6 +1307,19 @@ export default class MessageReceiver
|
|||
content.senderKeyDistributionMessage
|
||||
);
|
||||
}
|
||||
|
||||
// Some sync messages have to be fully processed in the middle of
|
||||
// decryption queue since subsequent envelopes use their key material.
|
||||
const { syncMessage } = content;
|
||||
if (syncMessage?.pniIdentity) {
|
||||
await this.handlePNIIdentity(envelope, syncMessage.pniIdentity);
|
||||
return { plaintext: undefined, envelope };
|
||||
}
|
||||
|
||||
if (syncMessage?.pniChangeNumber) {
|
||||
await this.handlePNIChangeNumber(envelope, syncMessage.pniChangeNumber);
|
||||
return { plaintext: undefined, envelope };
|
||||
}
|
||||
} catch (error) {
|
||||
log.error(
|
||||
'MessageReceiver.decryptEnvelope: Failed to process sender ' +
|
||||
|
@ -2575,6 +2584,9 @@ export default class MessageReceiver
|
|||
if (envelope.sourceDevice == ourDeviceId) {
|
||||
throw new Error('Received sync message from our own device');
|
||||
}
|
||||
if (syncMessage.pniIdentity) {
|
||||
return;
|
||||
}
|
||||
if (syncMessage.sent) {
|
||||
const sentMessage = syncMessage.sent;
|
||||
|
||||
|
@ -2615,7 +2627,7 @@ export default class MessageReceiver
|
|||
|
||||
if (this.isInvalidGroupData(sentMessage.message, envelope)) {
|
||||
this.removeFromCache(envelope);
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
await this.checkGroupV1Data(sentMessage.message);
|
||||
|
@ -2633,11 +2645,11 @@ export default class MessageReceiver
|
|||
}
|
||||
if (syncMessage.contacts) {
|
||||
this.handleContacts(envelope, syncMessage.contacts);
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
if (syncMessage.groups) {
|
||||
this.handleGroups(envelope, syncMessage.groups);
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
if (syncMessage.blocked) {
|
||||
return this.handleBlocked(envelope, syncMessage.blocked);
|
||||
|
@ -2645,7 +2657,7 @@ export default class MessageReceiver
|
|||
if (syncMessage.request) {
|
||||
log.info('Got SyncMessage Request');
|
||||
this.removeFromCache(envelope);
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
if (syncMessage.read && syncMessage.read.length) {
|
||||
return this.handleRead(envelope, syncMessage.read);
|
||||
|
@ -2653,7 +2665,7 @@ export default class MessageReceiver
|
|||
if (syncMessage.verified) {
|
||||
log.info('Got verified sync message, dropping');
|
||||
this.removeFromCache(envelope);
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
if (syncMessage.configuration) {
|
||||
return this.handleConfiguration(envelope, syncMessage.configuration);
|
||||
|
@ -2682,9 +2694,6 @@ export default class MessageReceiver
|
|||
if (syncMessage.keys) {
|
||||
return this.handleKeys(envelope, syncMessage.keys);
|
||||
}
|
||||
if (syncMessage.pniIdentity) {
|
||||
return this.handlePNIIdentity(envelope, syncMessage.pniIdentity);
|
||||
}
|
||||
if (syncMessage.viewed && syncMessage.viewed.length) {
|
||||
return this.handleViewed(envelope, syncMessage.viewed);
|
||||
}
|
||||
|
@ -2693,7 +2702,6 @@ export default class MessageReceiver
|
|||
log.warn(
|
||||
`handleSyncMessage/${getEnvelopeId(envelope)}: Got empty SyncMessage`
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
private async handleConfiguration(
|
||||
|
@ -2813,6 +2821,7 @@ export default class MessageReceiver
|
|||
return this.dispatchAndWait(ev);
|
||||
}
|
||||
|
||||
// Runs on TaskType.Encrypted queue
|
||||
private async handlePNIIdentity(
|
||||
envelope: ProcessedEnvelope,
|
||||
{ publicKey, privateKey }: Proto.SyncMessage.IPniIdentity
|
||||
|
@ -2823,22 +2832,47 @@ export default class MessageReceiver
|
|||
|
||||
if (!publicKey || !privateKey) {
|
||||
log.warn('MessageReceiver: empty pni identity sync message');
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
const ev = new PNIIdentityEvent(
|
||||
{ publicKey, privateKey },
|
||||
this.removeFromCache.bind(this, envelope)
|
||||
);
|
||||
const manager = window.getAccountManager();
|
||||
await manager.updatePNIIdentity({ privKey: privateKey, pubKey: publicKey });
|
||||
}
|
||||
|
||||
if (this.isEmptied) {
|
||||
log.info('MessageReceiver: emitting pni identity sync message');
|
||||
return this.dispatchAndWait(ev);
|
||||
// Runs on TaskType.Encrypted queue
|
||||
private async handlePNIChangeNumber(
|
||||
envelope: ProcessedEnvelope,
|
||||
{
|
||||
identityKeyPair,
|
||||
signedPreKey,
|
||||
registrationId,
|
||||
}: Proto.SyncMessage.IPniChangeNumber
|
||||
): Promise<void> {
|
||||
log.info('MessageReceiver: got pni change number sync message');
|
||||
|
||||
logUnexpectedUrgentValue(envelope, 'pniIdentitySync');
|
||||
|
||||
const { updatedPni } = envelope;
|
||||
if (!updatedPni) {
|
||||
log.warn('MessageReceiver: missing pni in change number sync message');
|
||||
return;
|
||||
}
|
||||
|
||||
log.info('MessageReceiver: scheduling pni identity sync message');
|
||||
this.pendingPNIIdentityEvent?.confirm();
|
||||
this.pendingPNIIdentityEvent = ev;
|
||||
if (
|
||||
!Bytes.isNotEmpty(identityKeyPair) ||
|
||||
!Bytes.isNotEmpty(signedPreKey) ||
|
||||
!isNumber(registrationId)
|
||||
) {
|
||||
log.warn('MessageReceiver: empty pni change number sync message');
|
||||
return;
|
||||
}
|
||||
|
||||
const manager = window.getAccountManager();
|
||||
await manager.setPni(updatedPni.toString(), {
|
||||
identityKeyPair,
|
||||
signedPreKey,
|
||||
registrationId,
|
||||
});
|
||||
}
|
||||
|
||||
private async handleStickerPackOperation(
|
||||
|
|
7
ts/textsecure/Types.d.ts
vendored
7
ts/textsecure/Types.d.ts
vendored
|
@ -87,6 +87,7 @@ export type ProcessedEnvelope = Readonly<{
|
|||
sourceUuid?: UUIDStringType;
|
||||
sourceDevice?: number;
|
||||
destinationUuid: UUID;
|
||||
updatedPni?: UUID;
|
||||
timestamp: number;
|
||||
content?: Uint8Array;
|
||||
serverGuid: string;
|
||||
|
@ -270,3 +271,9 @@ export interface CallbackResultType {
|
|||
export interface IRequestHandler {
|
||||
handleRequest(request: IncomingWebSocketRequest): void;
|
||||
}
|
||||
|
||||
export type PniKeyMaterialType = Readonly<{
|
||||
identityKeyPair: Uint8Array;
|
||||
signedPreKey: Uint8Array;
|
||||
registrationId: number;
|
||||
}>;
|
||||
|
|
|
@ -566,7 +566,6 @@ type DirectoryV3OptionsType = Readonly<{
|
|||
directoryVersion: 3;
|
||||
directoryV3Url: string;
|
||||
directoryV3MRENCLAVE: string;
|
||||
directoryV3Root: string;
|
||||
}>;
|
||||
|
||||
type OptionalDirectoryFieldsType = {
|
||||
|
@ -578,7 +577,6 @@ type OptionalDirectoryFieldsType = {
|
|||
directoryV2CodeHashes?: unknown;
|
||||
directoryV3Url?: unknown;
|
||||
directoryV3MRENCLAVE?: unknown;
|
||||
directoryV3Root?: unknown;
|
||||
};
|
||||
|
||||
type DirectoryOptionsType = OptionalDirectoryFieldsType &
|
||||
|
@ -803,6 +801,11 @@ export type GetGroupCredentialsOptionsType = Readonly<{
|
|||
endDayInMs: number;
|
||||
}>;
|
||||
|
||||
export type GetGroupCredentialsResultType = Readonly<{
|
||||
pni?: string | null;
|
||||
credentials: ReadonlyArray<GroupCredentialType>;
|
||||
}>;
|
||||
|
||||
export type WebAPIType = {
|
||||
startRegistration(): unknown;
|
||||
finishRegistration(baton: unknown): void;
|
||||
|
@ -831,7 +834,7 @@ export type WebAPIType = {
|
|||
getGroupAvatar: (key: string) => Promise<Uint8Array>;
|
||||
getGroupCredentials: (
|
||||
options: GetGroupCredentialsOptionsType
|
||||
) => Promise<Array<GroupCredentialType>>;
|
||||
) => Promise<GetGroupCredentialsResultType>;
|
||||
getGroupExternalCredential: (
|
||||
options: GroupCredentialsType
|
||||
) => Promise<Proto.GroupExternalCredential>;
|
||||
|
@ -1205,8 +1208,7 @@ export function initialize({
|
|||
},
|
||||
});
|
||||
} else if (directoryConfig.directoryVersion === 3) {
|
||||
const { directoryV3Url, directoryV3MRENCLAVE, directoryV3Root } =
|
||||
directoryConfig;
|
||||
const { directoryV3Url, directoryV3MRENCLAVE } = directoryConfig;
|
||||
|
||||
cds = new CDSI({
|
||||
logger: log,
|
||||
|
@ -1214,7 +1216,6 @@ export function initialize({
|
|||
|
||||
url: directoryV3Url,
|
||||
mrenclave: directoryV3MRENCLAVE,
|
||||
root: directoryV3Root,
|
||||
certificateAuthority,
|
||||
version,
|
||||
|
||||
|
@ -2510,7 +2511,7 @@ export function initialize({
|
|||
async function getGroupCredentials({
|
||||
startDayInMs,
|
||||
endDayInMs,
|
||||
}: GetGroupCredentialsOptionsType): Promise<Array<GroupCredentialType>> {
|
||||
}: GetGroupCredentialsOptionsType): Promise<GetGroupCredentialsResultType> {
|
||||
const startDayInSeconds = startDayInMs / durations.SECOND;
|
||||
const endDayInSeconds = endDayInMs / durations.SECOND;
|
||||
const response = (await _ajax({
|
||||
|
@ -2522,7 +2523,7 @@ export function initialize({
|
|||
responseType: 'json',
|
||||
})) as CredentialResponseType;
|
||||
|
||||
return response.credentials;
|
||||
return response;
|
||||
}
|
||||
|
||||
async function getGroupExternalCredential(
|
||||
|
|
|
@ -10,20 +10,16 @@ import { CDSSocketManagerBase } from './CDSSocketManagerBase';
|
|||
|
||||
export type CDSIOptionsType = Readonly<{
|
||||
mrenclave: string;
|
||||
root: string;
|
||||
}> &
|
||||
CDSSocketManagerBaseOptionsType;
|
||||
|
||||
export class CDSI extends CDSSocketManagerBase<CDSISocket, CDSIOptionsType> {
|
||||
private readonly mrenclave: Buffer;
|
||||
|
||||
private readonly trustedCaCert: Buffer;
|
||||
|
||||
constructor(options: CDSIOptionsType) {
|
||||
super(options);
|
||||
|
||||
this.mrenclave = Buffer.from(Bytes.fromHex(options.mrenclave));
|
||||
this.trustedCaCert = Buffer.from(options.root);
|
||||
}
|
||||
|
||||
protected override getSocketUrl(): string {
|
||||
|
@ -37,7 +33,6 @@ export class CDSI extends CDSSocketManagerBase<CDSISocket, CDSIOptionsType> {
|
|||
logger: this.logger,
|
||||
socket,
|
||||
mrenclave: this.mrenclave,
|
||||
trustedCaCert: this.trustedCaCert,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
import { Cds2Client } from '@signalapp/libsignal-client';
|
||||
|
||||
import { strictAssert } from '../../util/assert';
|
||||
import { DAY } from '../../util/durations';
|
||||
import { SignalService as Proto } from '../../protobuf';
|
||||
import { CDSSocketBase, CDSSocketState } from './CDSSocketBase';
|
||||
import type { CDSSocketBaseOptionsType } from './CDSSocketBase';
|
||||
|
||||
export type CDSISocketOptionsType = Readonly<{
|
||||
mrenclave: Buffer;
|
||||
trustedCaCert: Buffer;
|
||||
}> &
|
||||
CDSSocketBaseOptionsType;
|
||||
|
||||
|
@ -30,15 +28,14 @@ export class CDSISocket extends CDSSocketBase<CDSISocketOptionsType> {
|
|||
await this.socketIterator.next();
|
||||
strictAssert(!done, 'CDSI socket closed before handshake');
|
||||
|
||||
const earliestValidTimestamp = new Date(Date.now() - DAY);
|
||||
const earliestValidTimestamp = new Date();
|
||||
|
||||
strictAssert(
|
||||
this.privCdsClient === undefined,
|
||||
'CDSI handshake called twice'
|
||||
);
|
||||
this.privCdsClient = Cds2Client.new_NOT_FOR_PRODUCTION(
|
||||
this.privCdsClient = Cds2Client.new(
|
||||
this.options.mrenclave,
|
||||
this.options.trustedCaCert,
|
||||
attestationMessage,
|
||||
earliestValidTimestamp
|
||||
);
|
||||
|
|
|
@ -357,20 +357,6 @@ export class KeysEvent extends ConfirmableEvent {
|
|||
}
|
||||
}
|
||||
|
||||
export type PNIIdentityEventData = Readonly<{
|
||||
publicKey: Uint8Array;
|
||||
privateKey: Uint8Array;
|
||||
}>;
|
||||
|
||||
export class PNIIdentityEvent extends ConfirmableEvent {
|
||||
constructor(
|
||||
public readonly data: PNIIdentityEventData,
|
||||
confirm: ConfirmCallback
|
||||
) {
|
||||
super('pniIdentity', confirm);
|
||||
}
|
||||
}
|
||||
|
||||
export type StickerPackEventData = Readonly<{
|
||||
id?: string;
|
||||
key?: string;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue