Skip to content

Commit

Permalink
New CryptoApi.getUserVerificationStatus API
Browse files Browse the repository at this point in the history
  • Loading branch information
richvdh committed Sep 1, 2023
1 parent 5ddd453 commit f2bfe79
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 53 deletions.
2 changes: 2 additions & 0 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2643,6 +2643,8 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* The cross-signing API is currently UNSTABLE and may change without notice.
*
* @param userId - The ID of the user to check.
*
* @deprecated Use {@link Crypto.CryptoApi.getUsererificationStatus | `CryptoApi.getUserVerificationStatus`}
*/
public checkUserTrust(userId: string): UserTrustLevel {
if (!this.cryptoBackend) {
Expand Down
4 changes: 2 additions & 2 deletions src/common-crypto/CryptoBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ export interface CryptoBackend extends SyncCryptoCallbacks, CryptoApi {
/**
* Get the verification level for a given user
*
* TODO: define this better
*
* @param userId - user to be checked
*
* @deprecated Superceded by {@link CryptoApi#getUserVerificationStatus}.
*/
checkUserTrust(userId: string): UserTrustLevel;

Expand Down
48 changes: 48 additions & 0 deletions src/crypto-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ export interface CryptoApi {
*/
getTrustCrossSignedDevices(): boolean;

/**
* Get the verification status of a given user.
*
* @param userId - The ID of the user to check.
*
*/
getUserVerificationStatus(userId: string): Promise<UserVerificationStatus>;

/**
* Get the verification status of a given device.
*
Expand Down Expand Up @@ -398,6 +406,46 @@ export interface BootstrapCrossSigningOpts {
authUploadDeviceSigningKeys?: UIAuthCallback<void>;
}

/**
* Represents the ways in which we trust a user
*/
export class UserVerificationStatus {
public constructor(
private readonly crossSigningVerified: boolean,
private readonly crossSigningVerifiedBefore: boolean,
private readonly tofu: boolean,
) {}

/**
* @returns true if this user is verified via any means
*/
public isVerified(): boolean {
return this.isCrossSigningVerified();
}

/**
* @returns true if this user is verified via cross signing
*/
public isCrossSigningVerified(): boolean {
return this.crossSigningVerified;
}

/**
* @returns true if we ever verified this user before (at least for
* the history of verifications observed by this device).
*/
public wasCrossSigningVerified(): boolean {
return this.crossSigningVerifiedBefore;
}

/**
* @returns true if this user's key is trusted on first use
*/
public isTofu(): boolean {
return this.tofu;
}
}

export class DeviceVerificationStatus {
/**
* True if this device has been signed by its owner (and that signature verified).
Expand Down
45 changes: 4 additions & 41 deletions src/crypto/CrossSigning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ import { ICryptoCallbacks } from ".";
import { ISignatures } from "../@types/signed";
import { CryptoStore, SecretStorePrivateKeys } from "./store/base";
import { ServerSideSecretStorage, SecretStorageKeyDescription } from "../secret-storage";
import { DeviceVerificationStatus } from "../crypto-api";
import { DeviceVerificationStatus, UserVerificationStatus as UserTrustLevel } from "../crypto-api";

// backwards-compatibility re-exports
export { UserTrustLevel };

const KEY_REQUEST_TIMEOUT_MS = 1000 * 60;

Expand Down Expand Up @@ -587,46 +590,6 @@ export enum CrossSigningLevel {
SELF_SIGNING = 1,
}

/**
* Represents the ways in which we trust a user
*/
export class UserTrustLevel {
public constructor(
private readonly crossSigningVerified: boolean,
private readonly crossSigningVerifiedBefore: boolean,
private readonly tofu: boolean,
) {}

/**
* @returns true if this user is verified via any means
*/
public isVerified(): boolean {
return this.isCrossSigningVerified();
}

/**
* @returns true if this user is verified via cross signing
*/
public isCrossSigningVerified(): boolean {
return this.crossSigningVerified;
}

/**
* @returns true if we ever verified this user before (at least for
* the history of verifications observed by this device).
*/
public wasCrossSigningVerified(): boolean {
return this.crossSigningVerifiedBefore;
}

/**
* @returns true if this user's key is trusted on first use
*/
public isTofu(): boolean {
return this.tofu;
}
}

/**
* Represents the ways in which we trust a device.
*
Expand Down
7 changes: 7 additions & 0 deletions src/crypto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1524,6 +1524,13 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
return this.crossSigningInfo.checkUserTrust(userCrossSigning);
}

/**
* Implementation of {@link CryptoApi.getUserVerificationStatus}.
*/
public async getUserVerificationStatus(userId: string): Promise<UserTrustLevel> {
return this.checkUserTrust(userId);
}

/**
* Check whether a given device is trusted.
*
Expand Down
4 changes: 2 additions & 2 deletions src/rust-crypto/CrossSigningIdentity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class CrossSigningIdentity {
private readonly outgoingRequestProcessor: OutgoingRequestProcessor,
private readonly secretStorage: ServerSideSecretStorage,
/** Called if the cross signing keys are imported from the secret storage */
private readonly onCrossSigningKeysImport: () => void,
private readonly onCrossSigningKeysImport: () => Promise<void>,
) {}

/**
Expand Down Expand Up @@ -96,7 +96,7 @@ export class CrossSigningIdentity {
const request: RustSdkCryptoJs.SignatureUploadRequest = await device.verify();
await this.outgoingRequestProcessor.makeOutgoingRequest(request);

this.onCrossSigningKeysImport();
await this.onCrossSigningKeysImport();
}

// TODO: we might previously have bootstrapped cross-signing but not completed uploading the keys to the
Expand Down
33 changes: 25 additions & 8 deletions src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import { RoomMember } from "../models/room-member";
import { CryptoBackend, OnSyncCompletedData } from "../common-crypto/CryptoBackend";
import { logger } from "../logger";
import { IHttpOpts, MatrixHttpApi, Method } from "../http-api";
import { UserTrustLevel } from "../crypto/CrossSigning";
import { RoomEncryptor } from "./RoomEncryptor";
import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProcessor";
import { KeyClaimManager } from "./KeyClaimManager";
Expand All @@ -44,6 +43,7 @@ import {
ImportRoomKeysOpts,
KeyBackupCheck,
KeyBackupInfo,
UserVerificationStatus,
VerificationRequest,
} from "../crypto-api";
import { deviceKeysToDeviceMap, rustDeviceToJsDevice } from "./device-converter";
Expand Down Expand Up @@ -128,8 +128,9 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
]);

// Fire if the cross signing keys are imported from the secret storage
const onCrossSigningKeysImport = (): void => {
this.emit(CryptoEvent.UserTrustStatusChanged, this.userId, this.checkUserTrust(this.userId));
const onCrossSigningKeysImport = async (): Promise<void> => {
const newVerification = await this.getUserVerificationStatus(this.userId);
this.emit(CryptoEvent.UserTrustStatusChanged, this.userId, newVerification);
};
this.crossSigningIdentity = new CrossSigningIdentity(
olmMachine,
Expand Down Expand Up @@ -218,9 +219,14 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
return ret as IEncryptedEventInfo;
}

public checkUserTrust(userId: string): UserTrustLevel {
// TODO
return new UserTrustLevel(false, false, false);
/**
* Implementation of {@link CryptoBackend#checkUserTrust}.
*
* Stub for backwards compatibility.
*
*/
public checkUserTrust(userId: string): UserVerificationStatus {
return new UserVerificationStatus(false, false, false);
}

/**
Expand All @@ -244,7 +250,6 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
* The function is stub to keep the compatibility with the old crypto.
* More information: https://github.com/vector-im/element-web/issues/25648
*
*
* Implementation of {@link CryptoBackend#checkOwnCrossSigningTrust}
*/
public async checkOwnCrossSigningTrust(): Promise<void> {
Expand Down Expand Up @@ -475,6 +480,18 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
});
}

/**
* Implementation of {@link CryptoApi#getUserVerificationStatus}.
*/
public async getUserVerificationStatus(userId: string): Promise<UserVerificationStatus> {
const userIdentity: RustSdkCryptoJs.UserIdentity | RustSdkCryptoJs.OwnUserIdentity | undefined =
await this.olmMachine.getIdentity(new RustSdkCryptoJs.UserId(userId));
if (userIdentity === undefined) {
return new UserVerificationStatus(false, false, false);
}
return new UserVerificationStatus(userIdentity.isVerified(), false, false);
}

/**
* Implementation of {@link CryptoApi#isCrossSigningReady}
*/
Expand Down Expand Up @@ -1364,5 +1381,5 @@ type RustCryptoEventMap = {
/**
* Fires when the cross signing keys are imported during {@link CryptoApi#bootstrapCrossSigning}
*/
[CryptoEvent.UserTrustStatusChanged]: (userId: string, userTrustLevel: UserTrustLevel) => void;
[CryptoEvent.UserTrustStatusChanged]: (userId: string, userTrustLevel: UserVerificationStatus) => void;
} & RustBackupCryptoEventMap;

0 comments on commit f2bfe79

Please sign in to comment.