Skip to content

Commit

Permalink
feat: replace refreshActiveCertificate with hasActiveCertificate and …
Browse files Browse the repository at this point in the history
…initialise MLSService with e2eServiceExternal (#5815)

* refactor: remove refreshCertificate flag and use hasActiveCertificate from CC

* feat: initialise MLS Service with e2eServiceExternal

* fix: change constructor param order

* test: update test
  • Loading branch information
arjita-mitra authored Dec 21, 2023
1 parent 0008113 commit dc24b45
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 23 deletions.
10 changes: 4 additions & 6 deletions packages/core/src/Account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,11 @@ export class Account extends TypedEventEmitter<Events> {
displayName,
handle,
discoveryUrl,
refreshActiveCertificate = false,
oAuthIdToken,
}: {
displayName: string;
handle: string;
discoveryUrl: string;
refreshActiveCertificate?: boolean;
oAuthIdToken?: string;
}): Promise<AcmeChallenge | boolean> {
const context = this.apiClient.context;
Expand Down Expand Up @@ -272,7 +270,6 @@ export class Account extends TypedEventEmitter<Events> {
user,
this.currentClient,
this.nbPrekeys,
refreshActiveCertificate,
oAuthIdToken,
);
}
Expand Down Expand Up @@ -454,7 +451,7 @@ export class Account extends TypedEventEmitter<Events> {
const [clientType, cryptoClient] = await this.buildCryptoClient(context, this.storeEngine);

let mlsService: MLSService | undefined;
let e2eIdentityService: E2EIServiceExternal | undefined;
let e2eServiceExternal: E2EIServiceExternal | undefined;

const proteusService = new ProteusService(this.apiClient, cryptoClient, {
onNewClient: payload => this.emit(EVENTS.NEW_SESSION, payload),
Expand All @@ -464,12 +461,13 @@ export class Account extends TypedEventEmitter<Events> {
const clientService = new ClientService(this.apiClient, proteusService, this.storeEngine);

if (clientType === CryptoClientType.CORE_CRYPTO && (await this.isMlsEnabled())) {
e2eIdentityService = new E2EIServiceExternal(cryptoClient.getNativeClient(), clientService);
e2eServiceExternal = new E2EIServiceExternal(cryptoClient.getNativeClient(), clientService);
mlsService = new MLSService(
this.apiClient,
cryptoClient.getNativeClient(),
this.db,
this.recurringTaskScheduler,
e2eServiceExternal,
{
...this.coreCryptoConfig?.mls,
},
Expand All @@ -496,7 +494,7 @@ export class Account extends TypedEventEmitter<Events> {
const userService = new UserService(this.apiClient);

this.service = {
e2eIdentity: e2eIdentityService,
e2eIdentity: e2eServiceExternal,
mls: mlsService,
proteus: proteusService,
account: accountService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ class E2EIServiceInternal {
return E2EIServiceInternal.instance;
}

public async startCertificateProcess(refreshActiveCertificate: boolean) {
public async startCertificateProcess() {
// Step 0: Check if we have a handle in local storage
// If we don't have a handle, we need to start a new OAuth flow
try {
// Initialize the identity
await this.initIdentity(refreshActiveCertificate);
await this.initIdentity();
return this.startNewOAuthFlow();
} catch (error) {
return this.exitWithError('Error while trying to start OAuth flow with error:', error);
Expand All @@ -119,20 +119,25 @@ class E2EIServiceInternal {

// ############ Internal Functions ############

private async initIdentity(refreshActiveCertificate: boolean) {
private async initIdentity() {
const {clientId, user} = E2EIStorage.get.initialData();
const e2eiClientId = getE2EIClientId(clientId, user.id, user.domain).asString;
const expiryDays = 2;
const ciphersuite = Ciphersuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519;

if (refreshActiveCertificate) {
this.identity = await this.coreCryptoClient.e2eiNewRotateEnrollment(
e2eiClientId,
expiryDays,
ciphersuite,
user.displayName,
user.handle,
);
if (this.e2eServiceExternal.hasActiveCertificate()) {
try {
this.identity = await this.coreCryptoClient.e2eiNewRotateEnrollment(
e2eiClientId,
expiryDays,
ciphersuite,
user.displayName,
user.handle,
);
} catch (error) {
this.logger.error('Error while trying to initIdentity e2eiNewRotateEnrollment', error);
throw error;
}
} else {
this.identity = await this.coreCryptoClient.e2eiNewActivationEnrollment(
e2eiClientId,
Expand Down Expand Up @@ -321,7 +326,12 @@ class E2EIServiceInternal {
E2EIStorage.store.certificate(certificate);

// Step 10: Initialize MLS with the certificate
return await this.coreCryptoClient.e2eiRotateAll(this.identity, certificate, this.keyPackagesAmount);
try {
return await this.coreCryptoClient.e2eiRotateAll(this.identity, certificate, this.keyPackagesAmount);
} catch (error) {
this.logger.error('Error while e2eiRotateAll', error);
throw error;
}
}

/**
Expand Down Expand Up @@ -394,7 +404,7 @@ class E2EIServiceInternal {
}

// We need to initialize the identity
await this.initIdentity(true);
await this.initIdentity();

await this.getAndStoreInitialEnrollmentData();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,26 @@ import {CoreCrypto, DecryptedMessage} from '@wireapp/core-crypto';
import {CoreCryptoMLSError} from './CoreCryptoMLSError';
import {MLSService} from './MLSService';

import {ClientService} from '../../../client';
import {openDB} from '../../../storage/CoreDB';
import {RecurringTaskScheduler} from '../../../util/RecurringTaskScheduler';
import {TaskScheduler} from '../../../util/TaskScheduler';
import {E2EIServiceExternal} from '../E2EIdentityService';

jest.createMockFromModule('@wireapp/api-client');

function createUserId() {
return {id: randomUUID(), domain: ''};
}

const coreCrypto = {
getUserIdentities: jest.fn(),
} as unknown as jest.Mocked<CoreCrypto>;

const clientService = {} as jest.Mocked<ClientService>;
const createMLSService = async () => {
const apiClient = new APIClient();
const e2eServiceExternal = new E2EIServiceExternal(coreCrypto, clientService);
const mockCoreCrypto = {
createConversation: jest.fn(),
conversationExists: jest.fn(),
Expand All @@ -70,7 +78,14 @@ const createMLSService = async () => {
},
});

const mlsService = new MLSService(apiClient, mockCoreCrypto, mockedDb, recurringTaskScheduler, {});
const mlsService = new MLSService(
apiClient,
mockCoreCrypto,
mockedDb,
recurringTaskScheduler,
e2eServiceExternal,
{},
);

return [mlsService, {apiClient, coreCrypto: mockCoreCrypto, recurringTaskScheduler}] as const;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export class MLSService extends TypedEventEmitter<Events> {
private readonly coreCryptoClient: CoreCrypto,
private readonly coreDatabase: CoreDatabase,
private readonly recurringTaskScheduler: RecurringTaskScheduler,
private readonly e2eServiceExternal: E2EIServiceExternal,
{
keyingMaterialUpdateThreshold = defaultConfig.keyingMaterialUpdateThreshold,
nbKeyPackages = defaultConfig.nbKeyPackages,
Expand Down Expand Up @@ -768,7 +769,6 @@ export class MLSService extends TypedEventEmitter<Events> {
user: User,
client: RegisteredClient,
nbPrekeys: number,
refreshActiveCertificate: boolean,
oAuthIdToken?: string,
): Promise<AcmeChallenge | boolean> {
try {
Expand All @@ -783,7 +783,7 @@ export class MLSService extends TypedEventEmitter<Events> {
});
// If we don't have an OAuth id token, we need to start the certificate process with Oauth
if (!oAuthIdToken) {
const challengeData = await instance.startCertificateProcess(refreshActiveCertificate);
const challengeData = await instance.startCertificateProcess();
if (challengeData) {
return challengeData;
}
Expand All @@ -792,7 +792,7 @@ export class MLSService extends TypedEventEmitter<Events> {
let rotateBundle;

// If we are not refreshing the active certificate, we need to continue the certificate process with Oauth
if (!refreshActiveCertificate) {
if (!this.e2eServiceExternal.hasActiveCertificate()) {
rotateBundle = await instance.continueCertificateProcess(oAuthIdToken);
// If we are refreshing the active certificate, can start the refresh process
} else {
Expand Down

0 comments on commit dc24b45

Please sign in to comment.