Merge pull request #5149 from matrix-org/jryans/defer-cross-signing-setup
Migrate to new, separate APIs for cross-signing and secret storage
This commit is contained in:
commit
e2acec6059
6 changed files with 56 additions and 30 deletions
|
@ -69,19 +69,19 @@ async function getSecretStorageKey({ keys: keyInfos }, ssssItemName) {
|
||||||
if (keyInfoEntries.length > 1) {
|
if (keyInfoEntries.length > 1) {
|
||||||
throw new Error("Multiple storage key requests not implemented");
|
throw new Error("Multiple storage key requests not implemented");
|
||||||
}
|
}
|
||||||
const [name, info] = keyInfoEntries[0];
|
const [keyId, keyInfo] = keyInfoEntries[0];
|
||||||
|
|
||||||
// Check the in-memory cache
|
// Check the in-memory cache
|
||||||
if (isCachingAllowed() && secretStorageKeys[name]) {
|
if (isCachingAllowed() && secretStorageKeys[keyId]) {
|
||||||
return [name, secretStorageKeys[name]];
|
return [keyId, secretStorageKeys[keyId]];
|
||||||
}
|
}
|
||||||
|
|
||||||
const inputToKey = async ({ passphrase, recoveryKey }) => {
|
const inputToKey = async ({ passphrase, recoveryKey }) => {
|
||||||
if (passphrase) {
|
if (passphrase) {
|
||||||
return deriveKey(
|
return deriveKey(
|
||||||
passphrase,
|
passphrase,
|
||||||
info.passphrase.salt,
|
keyInfo.passphrase.salt,
|
||||||
info.passphrase.iterations,
|
keyInfo.passphrase.iterations,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return decodeRecoveryKey(recoveryKey);
|
return decodeRecoveryKey(recoveryKey);
|
||||||
|
@ -93,10 +93,10 @@ async function getSecretStorageKey({ keys: keyInfos }, ssssItemName) {
|
||||||
AccessSecretStorageDialog,
|
AccessSecretStorageDialog,
|
||||||
/* props= */
|
/* props= */
|
||||||
{
|
{
|
||||||
keyInfo: info,
|
keyInfo,
|
||||||
checkPrivateKey: async (input) => {
|
checkPrivateKey: async (input) => {
|
||||||
const key = await inputToKey(input);
|
const key = await inputToKey(input);
|
||||||
return await MatrixClientPeg.get().checkSecretStorageKey(key, info);
|
return await MatrixClientPeg.get().checkSecretStorageKey(key, keyInfo);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
/* className= */ null,
|
/* className= */ null,
|
||||||
|
@ -118,11 +118,15 @@ async function getSecretStorageKey({ keys: keyInfos }, ssssItemName) {
|
||||||
const key = await inputToKey(input);
|
const key = await inputToKey(input);
|
||||||
|
|
||||||
// Save to cache to avoid future prompts in the current session
|
// Save to cache to avoid future prompts in the current session
|
||||||
if (isCachingAllowed()) {
|
cacheSecretStorageKey(keyId, key);
|
||||||
secretStorageKeys[name] = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [name, key];
|
return [keyId, key];
|
||||||
|
}
|
||||||
|
|
||||||
|
function cacheSecretStorageKey(keyId, key) {
|
||||||
|
if (isCachingAllowed()) {
|
||||||
|
secretStorageKeys[keyId] = key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSecretRequested = async function({
|
const onSecretRequested = async function({
|
||||||
|
@ -170,6 +174,7 @@ const onSecretRequested = async function({
|
||||||
|
|
||||||
export const crossSigningCallbacks = {
|
export const crossSigningCallbacks = {
|
||||||
getSecretStorageKey,
|
getSecretStorageKey,
|
||||||
|
cacheSecretStorageKey,
|
||||||
onSecretRequested,
|
onSecretRequested,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -218,7 +223,7 @@ export async function accessSecretStorage(func = async () => { }, forceReset = f
|
||||||
const { finished } = Modal.createTrackedDialogAsync('Create Secret Storage dialog', '',
|
const { finished } = Modal.createTrackedDialogAsync('Create Secret Storage dialog', '',
|
||||||
import("./async-components/views/dialogs/secretstorage/CreateSecretStorageDialog"),
|
import("./async-components/views/dialogs/secretstorage/CreateSecretStorageDialog"),
|
||||||
{
|
{
|
||||||
force: forceReset,
|
forceReset,
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
/* priority = */ false,
|
/* priority = */ false,
|
||||||
|
@ -239,7 +244,7 @@ export async function accessSecretStorage(func = async () => { }, forceReset = f
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const InteractiveAuthDialog = sdk.getComponent("dialogs.InteractiveAuthDialog");
|
const InteractiveAuthDialog = sdk.getComponent("dialogs.InteractiveAuthDialog");
|
||||||
await cli.bootstrapSecretStorage({
|
await cli.bootstrapCrossSigning({
|
||||||
authUploadDeviceSigningKeys: async (makeRequest) => {
|
authUploadDeviceSigningKeys: async (makeRequest) => {
|
||||||
const { finished } = Modal.createTrackedDialog(
|
const { finished } = Modal.createTrackedDialog(
|
||||||
'Cross-signing keys dialog', '', InteractiveAuthDialog,
|
'Cross-signing keys dialog', '', InteractiveAuthDialog,
|
||||||
|
@ -254,7 +259,9 @@ export async function accessSecretStorage(func = async () => { }, forceReset = f
|
||||||
throw new Error("Cross-signing key upload auth canceled");
|
throw new Error("Cross-signing key upload auth canceled");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getBackupPassphrase: promptForBackupPassphrase,
|
});
|
||||||
|
await cli.bootstrapSecretStorage({
|
||||||
|
getKeyBackupPassphrase: promptForBackupPassphrase,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,9 +207,13 @@ export default class DeviceListener {
|
||||||
// (we add a listener on sync to do once check after the initial sync is done)
|
// (we add a listener on sync to do once check after the initial sync is done)
|
||||||
if (!cli.isInitialSyncComplete()) return;
|
if (!cli.isInitialSyncComplete()) return;
|
||||||
|
|
||||||
|
// JRS: This will change again in the next PR which moves secret storage
|
||||||
|
// later in the process.
|
||||||
const crossSigningReady = await cli.isCrossSigningReady();
|
const crossSigningReady = await cli.isCrossSigningReady();
|
||||||
|
const secretStorageReady = await cli.isSecretStorageReady();
|
||||||
|
const allSystemsReady = crossSigningReady && secretStorageReady;
|
||||||
|
|
||||||
if (this.dismissedThisDeviceToast || crossSigningReady) {
|
if (this.dismissedThisDeviceToast || allSystemsReady) {
|
||||||
hideSetupEncryptionToast();
|
hideSetupEncryptionToast();
|
||||||
} else if (this.shouldShowSetupEncryptionToast()) {
|
} else if (this.shouldShowSetupEncryptionToast()) {
|
||||||
// make sure our keys are finished downloading
|
// make sure our keys are finished downloading
|
||||||
|
|
|
@ -56,12 +56,12 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
hasCancel: PropTypes.bool,
|
hasCancel: PropTypes.bool,
|
||||||
accountPassword: PropTypes.string,
|
accountPassword: PropTypes.string,
|
||||||
force: PropTypes.bool,
|
forceReset: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
hasCancel: true,
|
hasCancel: true,
|
||||||
force: false,
|
forceReset: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -118,8 +118,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
||||||
MatrixClientPeg.get().isCryptoEnabled() && await MatrixClientPeg.get().isKeyBackupTrusted(backupInfo)
|
MatrixClientPeg.get().isCryptoEnabled() && await MatrixClientPeg.get().isKeyBackupTrusted(backupInfo)
|
||||||
);
|
);
|
||||||
|
|
||||||
const { force } = this.props;
|
const { forceReset } = this.props;
|
||||||
const phase = (backupInfo && !force) ? PHASE_MIGRATE : PHASE_CHOOSE_KEY_PASSPHRASE;
|
const phase = (backupInfo && !forceReset) ? PHASE_MIGRATE : PHASE_CHOOSE_KEY_PASSPHRASE;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
phase,
|
phase,
|
||||||
|
@ -277,20 +277,25 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
||||||
|
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
|
|
||||||
const { force } = this.props;
|
const { forceReset } = this.props;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (force) {
|
if (forceReset) {
|
||||||
console.log("Forcing secret storage reset"); // log something so we can debug this later
|
console.log("Forcing cross-signing and secret storage reset");
|
||||||
await cli.bootstrapSecretStorage({
|
await cli.bootstrapSecretStorage({
|
||||||
authUploadDeviceSigningKeys: this._doBootstrapUIAuth,
|
|
||||||
createSecretStorageKey: async () => this._recoveryKey,
|
createSecretStorageKey: async () => this._recoveryKey,
|
||||||
setupNewKeyBackup: true,
|
setupNewKeyBackup: true,
|
||||||
setupNewSecretStorage: true,
|
setupNewSecretStorage: true,
|
||||||
});
|
});
|
||||||
} else {
|
await cli.bootstrapCrossSigning({
|
||||||
await cli.bootstrapSecretStorage({
|
|
||||||
authUploadDeviceSigningKeys: this._doBootstrapUIAuth,
|
authUploadDeviceSigningKeys: this._doBootstrapUIAuth,
|
||||||
|
setupNewCrossSigning: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await cli.bootstrapCrossSigning({
|
||||||
|
authUploadDeviceSigningKeys: this._doBootstrapUIAuth,
|
||||||
|
});
|
||||||
|
await cli.bootstrapSecretStorage({
|
||||||
createSecretStorageKey: async () => this._recoveryKey,
|
createSecretStorageKey: async () => this._recoveryKey,
|
||||||
keyBackupInfo: this.state.backupInfo,
|
keyBackupInfo: this.state.backupInfo,
|
||||||
setupNewKeyBackup: !this.state.backupInfo,
|
setupNewKeyBackup: !this.state.backupInfo,
|
||||||
|
|
|
@ -89,6 +89,7 @@ export default class CrossSigningPanel extends React.PureComponent {
|
||||||
const homeserverSupportsCrossSigning =
|
const homeserverSupportsCrossSigning =
|
||||||
await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing");
|
await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing");
|
||||||
const crossSigningReady = await cli.isCrossSigningReady();
|
const crossSigningReady = await cli.isCrossSigningReady();
|
||||||
|
const secretStorageReady = await cli.isSecretStorageReady();
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
crossSigningPublicKeysOnDevice,
|
crossSigningPublicKeysOnDevice,
|
||||||
|
@ -101,6 +102,7 @@ export default class CrossSigningPanel extends React.PureComponent {
|
||||||
secretStorageKeyInAccount,
|
secretStorageKeyInAccount,
|
||||||
homeserverSupportsCrossSigning,
|
homeserverSupportsCrossSigning,
|
||||||
crossSigningReady,
|
crossSigningReady,
|
||||||
|
secretStorageReady,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,6 +153,7 @@ export default class CrossSigningPanel extends React.PureComponent {
|
||||||
secretStorageKeyInAccount,
|
secretStorageKeyInAccount,
|
||||||
homeserverSupportsCrossSigning,
|
homeserverSupportsCrossSigning,
|
||||||
crossSigningReady,
|
crossSigningReady,
|
||||||
|
secretStorageReady,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
let errorSection;
|
let errorSection;
|
||||||
|
@ -166,14 +169,19 @@ export default class CrossSigningPanel extends React.PureComponent {
|
||||||
summarisedStatus = <p>{_t(
|
summarisedStatus = <p>{_t(
|
||||||
"Your homeserver does not support cross-signing.",
|
"Your homeserver does not support cross-signing.",
|
||||||
)}</p>;
|
)}</p>;
|
||||||
} else if (crossSigningReady) {
|
} else if (crossSigningReady && secretStorageReady) {
|
||||||
summarisedStatus = <p>✅ {_t(
|
summarisedStatus = <p>✅ {_t(
|
||||||
"Cross-signing and secret storage are enabled.",
|
"Cross-signing and secret storage are ready for use.",
|
||||||
|
)}</p>;
|
||||||
|
} else if (crossSigningReady && !secretStorageReady) {
|
||||||
|
summarisedStatus = <p>✅ {_t(
|
||||||
|
"Cross-signing is ready for use, but secret storage is " +
|
||||||
|
"currently not being used to backup your keys.",
|
||||||
)}</p>;
|
)}</p>;
|
||||||
} else if (crossSigningPrivateKeysInStorage) {
|
} else if (crossSigningPrivateKeysInStorage) {
|
||||||
summarisedStatus = <p>{_t(
|
summarisedStatus = <p>{_t(
|
||||||
"Your account has a cross-signing identity in secret storage, but it " +
|
"Your account has a cross-signing identity in secret storage, " +
|
||||||
"is not yet trusted by this session.",
|
"but it is not yet trusted by this session.",
|
||||||
)}</p>;
|
)}</p>;
|
||||||
} else {
|
} else {
|
||||||
summarisedStatus = <p>{_t(
|
summarisedStatus = <p>{_t(
|
||||||
|
|
|
@ -645,7 +645,8 @@
|
||||||
"Confirm password": "Confirm password",
|
"Confirm password": "Confirm password",
|
||||||
"Change Password": "Change Password",
|
"Change Password": "Change Password",
|
||||||
"Your homeserver does not support cross-signing.": "Your homeserver does not support cross-signing.",
|
"Your homeserver does not support cross-signing.": "Your homeserver does not support cross-signing.",
|
||||||
"Cross-signing and secret storage are enabled.": "Cross-signing and secret storage are enabled.",
|
"Cross-signing and secret storage are ready for use.": "Cross-signing and secret storage are ready for use.",
|
||||||
|
"Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.",
|
||||||
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.",
|
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.",
|
||||||
"Cross-signing and secret storage are not yet set up.": "Cross-signing and secret storage are not yet set up.",
|
"Cross-signing and secret storage are not yet set up.": "Cross-signing and secret storage are not yet set up.",
|
||||||
"Reset cross-signing and secret storage": "Reset cross-signing and secret storage",
|
"Reset cross-signing and secret storage": "Reset cross-signing and secret storage",
|
||||||
|
|
|
@ -115,6 +115,7 @@ async function collectBugReport(opts: IOpts = {}, gzipLogs = true) {
|
||||||
body.append("cross_signing_supported_by_hs",
|
body.append("cross_signing_supported_by_hs",
|
||||||
String(await client.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")));
|
String(await client.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")));
|
||||||
body.append("cross_signing_ready", String(await client.isCrossSigningReady()));
|
body.append("cross_signing_ready", String(await client.isCrossSigningReady()));
|
||||||
|
body.append("secret_storage_ready", String(await client.isSecretStorageReady()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue