Mirror CDS requests

This commit is contained in:
Fedor Indutny 2022-08-18 17:31:12 -07:00 committed by GitHub
parent de84dc06c8
commit d036803df9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 173 additions and 97 deletions

View File

@ -375,20 +375,22 @@ async function prepareUrl(
const theme = await getResolvedThemeSetting(); const theme = await getResolvedThemeSetting();
const directoryConfig = directoryConfigSchema.safeParse({ const directoryConfig = directoryConfigSchema.safeParse({
directoryVersion: config.get<number | undefined>('directoryVersion') || 1, directoryType: config.get<string | undefined>('directoryType') || 'legacy',
directoryUrl: config.get<string | null>('directoryUrl') || undefined, directoryUrl: config.get<string | null>('directoryUrl') || undefined,
directoryEnclaveId: directoryEnclaveId:
config.get<string | null>('directoryEnclaveId') || undefined, config.get<string | null>('directoryEnclaveId') || undefined,
directoryTrustAnchor: directoryTrustAnchor:
config.get<string | null>('directoryTrustAnchor') || undefined, config.get<string | null>('directoryTrustAnchor') || undefined,
directoryV2Url: config.get<string | null>('directoryV2Url') || undefined, directoryCDSIUrl:
directoryV2PublicKey: config.get<string | null>('directoryCDSIUrl') || undefined,
config.get<string | null>('directoryV2PublicKey') || undefined, directoryCDSIMRENCLAVE:
directoryV2CodeHashes: config.get<string | null>('directoryCDSIMRENCLAVE') || undefined,
config.get<Array<string> | null>('directoryV2CodeHashes') || undefined, directoryCDSHUrl:
directoryV3Url: config.get<string | null>('directoryV3Url') || undefined, config.get<string | null>('directoryCDSHUrl') || undefined,
directoryV3MRENCLAVE: directoryCDSHPublicKey:
config.get<string | null>('directoryV3MRENCLAVE') || undefined, config.get<string | null>('directoryCDSHPublicKey') || undefined,
directoryCDSHCodeHashes:
config.get<Array<string> | null>('directoryCDSHCodeHashes') || undefined,
}); });
if (!directoryConfig.success) { if (!directoryConfig.success) {
throw new Error( throw new Error(

View File

@ -1,15 +1,15 @@
{ {
"serverUrl": "https://chat.staging.signal.org", "serverUrl": "https://chat.staging.signal.org",
"storageUrl": "https://storage-staging.signal.org", "storageUrl": "https://storage-staging.signal.org",
"directoryVersion": 3, "directoryType": "cdsi",
"directoryUrl": null, "directoryUrl": null,
"directoryEnclaveId": null, "directoryEnclaveId": null,
"directoryTrustAnchor": null, "directoryTrustAnchor": null,
"directoryV2Url": null, "directoryCDSIUrl": "https://cdsi.staging.signal.org",
"directoryV2PublicKey": null, "directoryCDSIMRENCLAVE": "ef4787a56a154ac6d009138cac17155acd23cfe4329281252365dd7c252e7fbf",
"directoryV2CodeHashes": null, "directoryCDSHUrl": null,
"directoryV3Url": "https://cdsi.staging.signal.org", "directoryCDSHPublicKey": null,
"directoryV3MRENCLAVE": "ddc7b9b1cbcc932e24b9905e26c4ecbea3f9b7effd033f9e96488c2e8449f64e", "directoryCDSHCodeHashes": null,
"cdn": { "cdn": {
"0": "https://cdn-staging.signal.org", "0": "https://cdn-staging.signal.org",
"2": "https://cdn2-staging.signal.org" "2": "https://cdn2-staging.signal.org"

View File

@ -1,10 +1,12 @@
{ {
"serverUrl": "https://chat.signal.org", "serverUrl": "https://chat.signal.org",
"storageUrl": "https://storage.signal.org", "storageUrl": "https://storage.signal.org",
"directoryVersion": 1, "directoryType": "mirrored-cdsi",
"directoryUrl": "https://api.directory.signal.org", "directoryUrl": "https://api.directory.signal.org",
"directoryEnclaveId": "c98e00a4e3ff977a56afefe7362a27e4961e4f19e211febfbb19b897e6b80b15", "directoryEnclaveId": "c98e00a4e3ff977a56afefe7362a27e4961e4f19e211febfbb19b897e6b80b15",
"directoryTrustAnchor": "-----BEGIN CERTIFICATE-----\nMIIFSzCCA7OgAwIBAgIJANEHdl0yo7CUMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNV\nBAYTAlVTMQswCQYDVQQIDAJDQTEUMBIGA1UEBwwLU2FudGEgQ2xhcmExGjAYBgNV\nBAoMEUludGVsIENvcnBvcmF0aW9uMTAwLgYDVQQDDCdJbnRlbCBTR1ggQXR0ZXN0\nYXRpb24gUmVwb3J0IFNpZ25pbmcgQ0EwIBcNMTYxMTE0MTUzNzMxWhgPMjA0OTEy\nMzEyMzU5NTlaMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEUMBIGA1UEBwwL\nU2FudGEgQ2xhcmExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0aW9uMTAwLgYDVQQD\nDCdJbnRlbCBTR1ggQXR0ZXN0YXRpb24gUmVwb3J0IFNpZ25pbmcgQ0EwggGiMA0G\nCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCfPGR+tXc8u1EtJzLA10Feu1Wg+p7e\nLmSRmeaCHbkQ1TF3Nwl3RmpqXkeGzNLd69QUnWovYyVSndEMyYc3sHecGgfinEeh\nrgBJSEdsSJ9FpaFdesjsxqzGRa20PYdnnfWcCTvFoulpbFR4VBuXnnVLVzkUvlXT\nL/TAnd8nIZk0zZkFJ7P5LtePvykkar7LcSQO85wtcQe0R1Raf/sQ6wYKaKmFgCGe\nNpEJUmg4ktal4qgIAxk+QHUxQE42sxViN5mqglB0QJdUot/o9a/V/mMeH8KvOAiQ\nbyinkNndn+Bgk5sSV5DFgF0DffVqmVMblt5p3jPtImzBIH0QQrXJq39AT8cRwP5H\nafuVeLHcDsRp6hol4P+ZFIhu8mmbI1u0hH3W/0C2BuYXB5PC+5izFFh/nP0lc2Lf\n6rELO9LZdnOhpL1ExFOq9H/B8tPQ84T3Sgb4nAifDabNt/zu6MmCGo5U8lwEFtGM\nRoOaX4AS+909x00lYnmtwsDVWv9vBiJCXRsCAwEAAaOByTCBxjBgBgNVHR8EWTBX\nMFWgU6BRhk9odHRwOi8vdHJ1c3RlZHNlcnZpY2VzLmludGVsLmNvbS9jb250ZW50\nL0NSTC9TR1gvQXR0ZXN0YXRpb25SZXBvcnRTaWduaW5nQ0EuY3JsMB0GA1UdDgQW\nBBR4Q3t2pn680K9+QjfrNXw7hwFRPDAfBgNVHSMEGDAWgBR4Q3t2pn680K9+Qjfr\nNXw7hwFRPDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkq\nhkiG9w0BAQsFAAOCAYEAeF8tYMXICvQqeXYQITkV2oLJsp6J4JAqJabHWxYJHGir\nIEqucRiJSSx+HjIJEUVaj8E0QjEud6Y5lNmXlcjqRXaCPOqK0eGRz6hi+ripMtPZ\nsFNaBwLQVV905SDjAzDzNIDnrcnXyB4gcDFCvwDFKKgLRjOB/WAqgscDUoGq5ZVi\nzLUzTqiQPmULAQaB9c6Oti6snEFJiCQ67JLyW/E83/frzCmO5Ru6WjU4tmsmy8Ra\nUd4APK0wZTGtfPXU7w+IBdG5Ez0kE1qzxGQaL4gINJ1zMyleDnbuS8UicjJijvqA\n152Sq049ESDz+1rRGc2NVEqh1KaGXmtXvqxXcTB+Ljy5Bw2ke0v8iGngFBPqCTVB\n3op5KBG3RjbF6RRSzwzuWfL7QErNC8WEy5yDVARzTA5+xmBc388v9Dm21HGfcC8O\nDD+gT9sSpssq0ascmvH49MOgjt1yoysLtdCtJW/9FZpoOypaHx0R+mJTLwPXVMrv\nDaVzWh5aiEx+idkSGMnX\n-----END CERTIFICATE-----\n", "directoryTrustAnchor": "-----BEGIN CERTIFICATE-----\nMIIFSzCCA7OgAwIBAgIJANEHdl0yo7CUMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNV\nBAYTAlVTMQswCQYDVQQIDAJDQTEUMBIGA1UEBwwLU2FudGEgQ2xhcmExGjAYBgNV\nBAoMEUludGVsIENvcnBvcmF0aW9uMTAwLgYDVQQDDCdJbnRlbCBTR1ggQXR0ZXN0\nYXRpb24gUmVwb3J0IFNpZ25pbmcgQ0EwIBcNMTYxMTE0MTUzNzMxWhgPMjA0OTEy\nMzEyMzU5NTlaMH4xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEUMBIGA1UEBwwL\nU2FudGEgQ2xhcmExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0aW9uMTAwLgYDVQQD\nDCdJbnRlbCBTR1ggQXR0ZXN0YXRpb24gUmVwb3J0IFNpZ25pbmcgQ0EwggGiMA0G\nCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCfPGR+tXc8u1EtJzLA10Feu1Wg+p7e\nLmSRmeaCHbkQ1TF3Nwl3RmpqXkeGzNLd69QUnWovYyVSndEMyYc3sHecGgfinEeh\nrgBJSEdsSJ9FpaFdesjsxqzGRa20PYdnnfWcCTvFoulpbFR4VBuXnnVLVzkUvlXT\nL/TAnd8nIZk0zZkFJ7P5LtePvykkar7LcSQO85wtcQe0R1Raf/sQ6wYKaKmFgCGe\nNpEJUmg4ktal4qgIAxk+QHUxQE42sxViN5mqglB0QJdUot/o9a/V/mMeH8KvOAiQ\nbyinkNndn+Bgk5sSV5DFgF0DffVqmVMblt5p3jPtImzBIH0QQrXJq39AT8cRwP5H\nafuVeLHcDsRp6hol4P+ZFIhu8mmbI1u0hH3W/0C2BuYXB5PC+5izFFh/nP0lc2Lf\n6rELO9LZdnOhpL1ExFOq9H/B8tPQ84T3Sgb4nAifDabNt/zu6MmCGo5U8lwEFtGM\nRoOaX4AS+909x00lYnmtwsDVWv9vBiJCXRsCAwEAAaOByTCBxjBgBgNVHR8EWTBX\nMFWgU6BRhk9odHRwOi8vdHJ1c3RlZHNlcnZpY2VzLmludGVsLmNvbS9jb250ZW50\nL0NSTC9TR1gvQXR0ZXN0YXRpb25SZXBvcnRTaWduaW5nQ0EuY3JsMB0GA1UdDgQW\nBBR4Q3t2pn680K9+QjfrNXw7hwFRPDAfBgNVHSMEGDAWgBR4Q3t2pn680K9+Qjfr\nNXw7hwFRPDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADANBgkq\nhkiG9w0BAQsFAAOCAYEAeF8tYMXICvQqeXYQITkV2oLJsp6J4JAqJabHWxYJHGir\nIEqucRiJSSx+HjIJEUVaj8E0QjEud6Y5lNmXlcjqRXaCPOqK0eGRz6hi+ripMtPZ\nsFNaBwLQVV905SDjAzDzNIDnrcnXyB4gcDFCvwDFKKgLRjOB/WAqgscDUoGq5ZVi\nzLUzTqiQPmULAQaB9c6Oti6snEFJiCQ67JLyW/E83/frzCmO5Ru6WjU4tmsmy8Ra\nUd4APK0wZTGtfPXU7w+IBdG5Ez0kE1qzxGQaL4gINJ1zMyleDnbuS8UicjJijvqA\n152Sq049ESDz+1rRGc2NVEqh1KaGXmtXvqxXcTB+Ljy5Bw2ke0v8iGngFBPqCTVB\n3op5KBG3RjbF6RRSzwzuWfL7QErNC8WEy5yDVARzTA5+xmBc388v9Dm21HGfcC8O\nDD+gT9sSpssq0ascmvH49MOgjt1yoysLtdCtJW/9FZpoOypaHx0R+mJTLwPXVMrv\nDaVzWh5aiEx+idkSGMnX\n-----END CERTIFICATE-----\n",
"directoryCDSIUrl": "https://cdsi.signal.org",
"directoryCDSIMRENCLAVE": "ef4787a56a154ac6d009138cac17155acd23cfe4329281252365dd7c252e7fbf",
"cdn": { "cdn": {
"0": "https://cdn.signal.org", "0": "https://cdn.signal.org",
"2": "https://cdn2.signal.org" "2": "https://cdn2.signal.org"

View File

@ -1,4 +1,4 @@
// Copyright 2021-2021 Signal Messenger, LLC // Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
package signalservice; package signalservice;
@ -25,6 +25,10 @@ message CDSClientRequest {
// After receiving a new token from the server, send back a message just // After receiving a new token from the server, send back a message just
// containing a token_ack. // containing a token_ack.
optional bool token_ack = 7; optional bool token_ack = 7;
// Request that, if the server allows, both ACI and PNI be returned even
// if the aci_uak_pairs don't match.
optional bool return_acis_without_uaks = 8;
} }
message CDSClientResponse { message CDSClientResponse {

View File

@ -9,6 +9,9 @@ import * as log from './logging/log';
export type ConfigKeyType = export type ConfigKeyType =
| 'desktop.announcementGroup' | 'desktop.announcementGroup'
| 'desktop.calling.audioLevelForSpeaking' | 'desktop.calling.audioLevelForSpeaking'
| 'desktop.cdsi'
| 'desktop.cdsi.returnAcisWithoutUaks'
| 'desktop.cdsi.mirroring'
| 'desktop.clientExpiration' | 'desktop.clientExpiration'
| 'desktop.groupCallOutboundRing' | 'desktop.groupCallOutboundRing'
| 'desktop.internalUser' | 'desktop.internalUser'

View File

@ -326,9 +326,9 @@ export class Bootstrap {
}, },
updatesEnabled: false, updatesEnabled: false,
directoryVersion: 3, directoreType: 'cdsi',
directoryV3Url: url, directoryCDSIUrl: url,
directoryV3MRENCLAVE: directoryCDSIMRENCLAVE:
'51133fecb3fa18aaf0c8f64cb763656d3272d9faaacdb26ae7df082e414fb142', '51133fecb3fa18aaf0c8f64cb763656d3272d9faaacdb26ae7df082e414fb142',
...this.options.extraConfig, ...this.options.extraConfig,

View File

@ -33,13 +33,18 @@ import { toLogFormat } from '../types/errors';
import { isPackIdValid, redactPackId } from '../types/Stickers'; import { isPackIdValid, redactPackId } from '../types/Stickers';
import type { UUID, UUIDStringType } from '../types/UUID'; import type { UUID, UUIDStringType } from '../types/UUID';
import { UUIDKind } from '../types/UUID'; import { UUIDKind } from '../types/UUID';
import type { DirectoryConfigType } from '../types/RendererConfig';
import * as Bytes from '../Bytes'; import * as Bytes from '../Bytes';
import { getRandomValue } from '../Crypto'; import { getRandomValue } from '../Crypto';
import * as linkPreviewFetch from '../linkPreviews/linkPreviewFetch'; import * as linkPreviewFetch from '../linkPreviews/linkPreviewFetch';
import { isBadgeImageFileUrlValid } from '../badges/isBadgeImageFileUrlValid'; import { isBadgeImageFileUrlValid } from '../badges/isBadgeImageFileUrlValid';
import { SocketManager } from './SocketManager'; import { SocketManager } from './SocketManager';
import type { CDSAuthType, CDSResponseType } from './cds/Types.d'; import type {
CDSAuthType,
CDSRequestOptionsType,
CDSResponseType,
} from './cds/Types.d';
import type { CDSBase } from './cds/CDSBase'; import type { CDSBase } from './cds/CDSBase';
import { LegacyCDS } from './cds/LegacyCDS'; import { LegacyCDS } from './cds/LegacyCDS';
import type { LegacyCDSPutAttestationResponseType } from './cds/LegacyCDS'; import type { LegacyCDSPutAttestationResponseType } from './cds/LegacyCDS';
@ -548,40 +553,6 @@ const WEBSOCKET_CALLS = new Set<keyof typeof URL_CALLS>([
'storageToken', 'storageToken',
]); ]);
type DirectoryV1OptionsType = Readonly<{
directoryVersion: 1;
directoryUrl: string;
directoryEnclaveId: string;
directoryTrustAnchor: string;
}>;
type DirectoryV2OptionsType = Readonly<{
directoryVersion: 2;
directoryV2Url: string;
directoryV2PublicKey: string;
directoryV2CodeHashes: ReadonlyArray<string>;
}>;
type DirectoryV3OptionsType = Readonly<{
directoryVersion: 3;
directoryV3Url: string;
directoryV3MRENCLAVE: string;
}>;
type OptionalDirectoryFieldsType = {
directoryUrl?: unknown;
directoryEnclaveId?: unknown;
directoryTrustAnchor?: unknown;
directoryV2Url?: unknown;
directoryV2PublicKey?: unknown;
directoryV2CodeHashes?: unknown;
directoryV3Url?: unknown;
directoryV3MRENCLAVE?: unknown;
};
type DirectoryOptionsType = OptionalDirectoryFieldsType &
(DirectoryV1OptionsType | DirectoryV2OptionsType | DirectoryV3OptionsType);
type InitializeOptionsType = { type InitializeOptionsType = {
url: string; url: string;
storageUrl: string; storageUrl: string;
@ -594,7 +565,7 @@ type InitializeOptionsType = {
contentProxyUrl: string; contentProxyUrl: string;
proxyUrl: string | undefined; proxyUrl: string | undefined;
version: string; version: string;
directoryConfig: DirectoryOptionsType; directoryConfig: DirectoryConfigType;
}; };
export type MessageType = Readonly<{ export type MessageType = Readonly<{
@ -770,6 +741,9 @@ export type CdsLookupOptionsType = Readonly<{
e164s: ReadonlyArray<string>; e164s: ReadonlyArray<string>;
acis?: ReadonlyArray<UUIDStringType>; acis?: ReadonlyArray<UUIDStringType>;
accessKeys?: ReadonlyArray<string>; accessKeys?: ReadonlyArray<string>;
returnAcisWithoutUaks?: boolean;
isLegacy: boolean;
isMirroring: boolean;
}>; }>;
type GetProfileCommonOptionsType = Readonly< type GetProfileCommonOptionsType = Readonly<
@ -1105,12 +1079,17 @@ export function initialize({
socketManager.authenticate({ username, password }); socketManager.authenticate({ username, password });
} }
let cds: CDSBase; const {
if (directoryConfig.directoryVersion === 1) { directoryType,
const { directoryUrl, directoryEnclaveId, directoryTrustAnchor } = directoryUrl,
directoryConfig; directoryEnclaveId,
directoryTrustAnchor,
} = directoryConfig;
cds = new LegacyCDS({ let legacyCDS: LegacyCDS | undefined;
let cds: CDSBase;
if (directoryType === 'legacy' || directoryType === 'mirrored-cdsi') {
legacyCDS = new LegacyCDS({
logger: log, logger: log,
directoryEnclaveId, directoryEnclaveId,
directoryTrustAnchor, directoryTrustAnchor,
@ -1183,17 +1162,20 @@ export function initialize({
})) as CDSAuthType; })) as CDSAuthType;
}, },
}); });
} else if (directoryConfig.directoryVersion === 2) {
const { directoryV2Url, directoryV2PublicKey, directoryV2CodeHashes } =
directoryConfig;
cds = new CDSH({ if (directoryType === 'legacy') {
cds = legacyCDS;
}
}
if (directoryType === 'cdsi' || directoryType === 'mirrored-cdsi') {
const { directoryCDSIUrl, directoryCDSIMRENCLAVE } = directoryConfig;
cds = new CDSI({
logger: log, logger: log,
proxyUrl, proxyUrl,
url: directoryV2Url, url: directoryCDSIUrl,
publicKey: directoryV2PublicKey, mrenclave: directoryCDSIMRENCLAVE,
codeHashes: directoryV2CodeHashes,
certificateAuthority, certificateAuthority,
version, version,
@ -1205,15 +1187,21 @@ export function initialize({
})) as CDSAuthType; })) as CDSAuthType;
}, },
}); });
} else if (directoryConfig.directoryVersion === 3) { }
const { directoryV3Url, directoryV3MRENCLAVE } = directoryConfig; if (directoryType === 'cdsh') {
const {
directoryCDSHUrl,
directoryCDSHPublicKey,
directoryCDSHCodeHashes,
} = directoryConfig;
cds = new CDSI({ cds = new CDSH({
logger: log, logger: log,
proxyUrl, proxyUrl,
url: directoryV3Url, url: directoryCDSHUrl,
mrenclave: directoryV3MRENCLAVE, publicKey: directoryCDSHPublicKey,
codeHashes: directoryCDSHCodeHashes,
certificateAuthority, certificateAuthority,
version, version,
@ -2851,16 +2839,64 @@ export function initialize({
return socketManager.getProvisioningResource(handler); return socketManager.getProvisioningResource(handler);
} }
async function mirroredCdsLookup(
requestOptions: CDSRequestOptionsType,
expectedMapPromise: Promise<CDSResponseType>
): Promise<void> {
try {
log.info('cdsLookup: sending mirrored request');
const actualMap = await cds.request(requestOptions);
const expectedMap = await expectedMapPromise;
let matched = 0;
for (const [e164, { aci }] of actualMap) {
if (!aci) {
continue;
}
const expectedACI = expectedMap.get(e164)?.aci;
if (expectedACI === aci) {
matched += 1;
} else {
log.warn(
`cdsLookup: mirrored request has aci=${aci} for ${e164}, while ` +
`expected aci=${expectedACI}`
);
}
}
log.info(`cdsLookup: mirrored request success, matched=${matched}`);
} catch (error) {
log.error('cdsLookup: mirrored request error', toLogFormat(error));
}
}
async function cdsLookup({ async function cdsLookup({
e164s, e164s,
acis = [], acis = [],
accessKeys = [], accessKeys = [],
returnAcisWithoutUaks,
isLegacy,
isMirroring,
}: CdsLookupOptionsType): Promise<CDSResponseType> { }: CdsLookupOptionsType): Promise<CDSResponseType> {
return cds.request({ const requestOptions = {
e164s, e164s,
acis, acis,
accessKeys, accessKeys,
}); returnAcisWithoutUaks,
};
if (!isLegacy || !legacyCDS) {
return cds.request(requestOptions);
}
const legacyRequest = legacyCDS.request(requestOptions);
if (legacyCDS !== cds && isMirroring) {
// Intentionally not awaiting
mirroredCdsLookup(requestOptions, legacyRequest);
}
return legacyRequest;
} }
} }
} }

View File

@ -70,6 +70,7 @@ export abstract class CDSSocketBase<
e164s, e164s,
acis, acis,
accessKeys, accessKeys,
returnAcisWithoutUaks = false,
}: CDSRequestOptionsType): Promise<CDSSocketResponseType> { }: CDSRequestOptionsType): Promise<CDSSocketResponseType> {
const log = this.logger; const log = this.logger;
@ -109,6 +110,7 @@ export abstract class CDSSocketBase<
}) })
), ),
aciUakPairs: Buffer.concat(aciUakPairs), aciUakPairs: Buffer.concat(aciUakPairs),
returnAcisWithoutUaks,
}).finish(); }).finish();
log.info(`CDSSocket.request(): sending version=${version} request`); log.info(`CDSSocket.request(): sending version=${version} request`);

View File

@ -170,8 +170,8 @@ export class LegacyCDS extends CDSBase<LegacyCDSOptionsType> {
for (const [i, e164] of e164s.entries()) { for (const [i, e164] of e164s.entries()) {
const uuid = uuids[i]; const uuid = uuids[i];
result.set(e164, { result.set(e164, {
aci: undefined, aci: uuid ? UUID.cast(uuid) : undefined,
pni: uuid ? UUID.cast(uuid) : undefined, pni: undefined,
}); });
} }

View File

@ -19,5 +19,6 @@ export type CDSRequestOptionsType = Readonly<{
e164s: ReadonlyArray<string>; e164s: ReadonlyArray<string>;
acis: ReadonlyArray<UUIDStringType>; acis: ReadonlyArray<UUIDStringType>;
accessKeys: ReadonlyArray<string>; accessKeys: ReadonlyArray<string>;
returnAcisWithoutUaks?: boolean;
timeout?: number; timeout?: number;
}>; }>;

View File

@ -18,24 +18,35 @@ export type configOptionalStringType = z.infer<
typeof configOptionalStringSchema typeof configOptionalStringSchema
>; >;
const directoryV1ConfigSchema = z.object({ const directoryLegacyConfigSchema = z.object({
directoryVersion: z.literal(1), directoryType: z.literal('legacy'),
directoryEnclaveId: configRequiredStringSchema, directoryEnclaveId: configRequiredStringSchema,
directoryTrustAnchor: configRequiredStringSchema, directoryTrustAnchor: configRequiredStringSchema,
directoryUrl: configRequiredStringSchema, directoryUrl: configRequiredStringSchema,
}); });
const directoryV2ConfigSchema = z.object({ const directoryCDSIConfigSchema = z.object({
directoryVersion: z.literal(2), directoryType: z.literal('cdsi'),
directoryV2CodeHashes: z.array(z.string().nonempty()), directoryCDSIUrl: configRequiredStringSchema,
directoryV2PublicKey: configRequiredStringSchema, directoryCDSIMRENCLAVE: configRequiredStringSchema,
directoryV2Url: configRequiredStringSchema,
}); });
const directoryV3ConfigSchema = z.object({ const directoryMirroredCDSIConfigSchema = z.object({
directoryVersion: z.literal(3), directoryType: z.literal('mirrored-cdsi'),
directoryV3Url: configRequiredStringSchema,
directoryV3MRENCLAVE: configRequiredStringSchema, directoryEnclaveId: configRequiredStringSchema,
directoryTrustAnchor: configRequiredStringSchema,
directoryUrl: configRequiredStringSchema,
directoryCDSIUrl: configRequiredStringSchema,
directoryCDSIMRENCLAVE: configRequiredStringSchema,
});
const directoryCDSHConfigSchema = z.object({
directoryType: z.literal('cdsh'),
directoryCDSHCodeHashes: z.array(z.string().nonempty()),
directoryCDSHPublicKey: configRequiredStringSchema,
directoryCDSHUrl: configRequiredStringSchema,
}); });
export const directoryConfigSchema = z export const directoryConfigSchema = z
@ -44,16 +55,19 @@ export const directoryConfigSchema = z
directoryEnclaveId: configOptionalUnknownSchema, directoryEnclaveId: configOptionalUnknownSchema,
directoryTrustAnchor: configOptionalUnknownSchema, directoryTrustAnchor: configOptionalUnknownSchema,
directoryUrl: configOptionalUnknownSchema, directoryUrl: configOptionalUnknownSchema,
directoryV2CodeHashes: configOptionalUnknownSchema,
directoryV2PublicKey: configOptionalUnknownSchema, directoryCDSIUrl: configOptionalUnknownSchema,
directoryV2Url: configOptionalUnknownSchema, directoryCDSIMRENCLAVE: configOptionalUnknownSchema,
directoryV3Url: configOptionalUnknownSchema,
directoryV3MRENCLAVE: configOptionalUnknownSchema, directoryCDSHCodeHashes: configOptionalUnknownSchema,
directoryCDSHPublicKey: configOptionalUnknownSchema,
directoryCDSHUrl: configOptionalUnknownSchema,
}) })
.and( .and(
directoryV1ConfigSchema directoryLegacyConfigSchema
.or(directoryV2ConfigSchema) .or(directoryMirroredCDSIConfigSchema)
.or(directoryV3ConfigSchema) .or(directoryCDSIConfigSchema)
.or(directoryCDSHConfigSchema)
); );
export type DirectoryConfigType = z.infer<typeof directoryConfigSchema>; export type DirectoryConfigType = z.infer<typeof directoryConfigSchema>;

View File

@ -5,6 +5,7 @@ import type { CDSResponseType } from '../textsecure/cds/Types.d';
import type { WebAPIType } from '../textsecure/WebAPI'; import type { WebAPIType } from '../textsecure/WebAPI';
import type { UUIDStringType } from '../types/UUID'; import type { UUIDStringType } from '../types/UUID';
import * as log from '../logging/log'; import * as log from '../logging/log';
import { isEnabled } from '../RemoteConfig';
import { isDirectConversation, isMe } from './whatTypeOfConversation'; import { isDirectConversation, isMe } from './whatTypeOfConversation';
export async function getUuidsForE164s( export async function getUuidsForE164s(
@ -37,9 +38,20 @@ export async function getUuidsForE164s(
accessKeys.push(accessKey); accessKeys.push(accessKey);
} }
const returnAcisWithoutUaks = isEnabled('desktop.cdsi.returnAcisWithoutUaks');
const isCDSI = isEnabled('desktop.cdsi');
const isMirroring = isEnabled('desktop.cdsi.mirroring');
log.info( log.info(
`getUuidsForE164s(${e164s}): acis=${acis.length} ` + `getUuidsForE164s(${e164s}): acis=${acis.length} ` +
`accessKeys=${accessKeys.length}` `accessKeys=${accessKeys.length}`
); );
return server.cdsLookup({ e164s, acis, accessKeys }); return server.cdsLookup({
e164s,
acis,
accessKeys,
returnAcisWithoutUaks,
isLegacy: !isCDSI,
isMirroring,
});
} }