Skip to content

Commit

Permalink
Store cross signing keys and user signing keys
Browse files Browse the repository at this point in the history
  • Loading branch information
florianduros committed Jun 23, 2023
1 parent 86b8d03 commit 09a461b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
22 changes: 15 additions & 7 deletions spec/integ/crypto/crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2235,11 +2235,11 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
* Resolved when the cross signing master key is uploaded
* https://spec.matrix.org/v1.6/client-server-api/#put_matrixclientv3useruseridaccount_datatype
*/
function awaitCrossSigningMasterKeyUpload(): Promise<Record<string, {}>> {
function awaitCrossSigningKeyUpload(key: string): Promise<Record<string, {}>> {
return new Promise((resolve) => {
// Called when the cross signing key master key is uploaded
// Called when the cross signing key is uploaded
fetchMock.put(
"express:/_matrix/client/r0/user/:userId/account_data/m.cross_signing.master",
`express:/_matrix/client/r0/user/:userId/account_data/m.cross_signing.${key}`,
(url: string, options: RequestInit) => {
const content = JSON.parse(options.body as string);
resolve(content.encrypted);
Expand Down Expand Up @@ -2374,11 +2374,13 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
},
);

newBackendOnly("should upload cross signing master key", async () => {
newBackendOnly("should upload cross signing keys", async () => {
mockSetupCrossSigningRequests();

// Before setting up secret-storage, bootstrap cross-signing, so that the client has cross-signing keys.
await aliceClient.getCrypto()?.bootstrapCrossSigning({});

// Now, when we bootstrap secret-storage, the cross-signing keys should be uploaded.
const bootstrapPromise = aliceClient
.getCrypto()!
.bootstrapSecretStorage({ setupNewSecretStorage: true, createSecretStorageKey });
Expand All @@ -2389,14 +2391,20 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
// Return the newly created key in the sync response
sendSyncResponse(secretStorageKey);

// Wait for the cross signing key to be uploaded
const crossSigningKey = await awaitCrossSigningMasterKeyUpload();
// Wait for the cross signing keys to be uploaded
const [masterKey, userSigningKey, selfSigningKey] = await Promise.all([
awaitCrossSigningKeyUpload("master"),
awaitCrossSigningKeyUpload("user_signing"),
awaitCrossSigningKeyUpload("self_signing"),
]);

// Finally, wait for bootstrapSecretStorage to finished
await bootstrapPromise;

// Expect the cross signing master key to be uploaded and to be encrypted with `secretStorageKey`
expect(crossSigningKey[secretStorageKey]).toBeDefined();
expect(masterKey[secretStorageKey]).toBeDefined();
expect(userSigningKey[secretStorageKey]).toBeDefined();
expect(selfSigningKey[secretStorageKey]).toBeDefined();
});
});
});
16 changes: 15 additions & 1 deletion src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,14 @@ export class RustCrypto implements CryptoBackend {
await this.addSecretStorageKeyToSecretStorage(recoveryKey);
}

const crossSigningStatus: RustSdkCryptoJs.CrossSigningStatus = await this.olmMachine.crossSigningStatus();
const hasPrivateKeys =
crossSigningStatus.hasMaster && crossSigningStatus.hasSelfSigning && crossSigningStatus.hasUserSigning;

// If we have cross-signing private keys cached, store them in secret
// storage if they are not there already.
if (
(await this.isCrossSigningReady()) &&
hasPrivateKeys &&
(isNewSecretStorageKeyNeeded || !(await secretStorageContainsCrossSigningKeys(this.secretStorage)))
) {
const crossSigningPrivateKeys: RustSdkCryptoJs.CrossSigningKeyExport =
Expand All @@ -414,7 +418,17 @@ export class RustCrypto implements CryptoBackend {
throw new Error("missing master key in cross signing private keys");
}

if (!crossSigningPrivateKeys.userSigningKey) {
throw new Error("missing user signing key in cross signing private keys");
}

if (!crossSigningPrivateKeys.self_signing_key) {
throw new Error("missing self signing key in cross signing private keys");
}

await this.secretStorage.store("m.cross_signing.master", crossSigningPrivateKeys.masterKey);
await this.secretStorage.store("m.cross_signing.user_signing", crossSigningPrivateKeys.userSigningKey);
await this.secretStorage.store("m.cross_signing.self_signing", crossSigningPrivateKeys.self_signing_key);
}
}

Expand Down

0 comments on commit 09a461b

Please sign in to comment.