From 5019eff1e361148a50106e2dd9afd7179f5c0718 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 9 Jan 2020 20:49:37 +0000 Subject: [PATCH 1/5] Don't allow upgrade from untrusted key backup. If we trust the key backup at upgrade time then we can sign it so key backup will work automatically when cross-signing is trusted. If we don't sign it at this point we'll end up with cross-signing and key backup set up but key backup untrusted by the cross-signing key which is a bit of a broken situation. With https://github.com/matrix-org/matrix-js-sdk/pull/1144 fixes https://github.com/vector-im/riot-web/issues/11747 --- .../CreateSecretStorageDialog.js | 50 +++++++++++++++---- src/i18n/strings/en_EN.json | 4 +- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js index 25bc8cdfda4..60d1f4c1a0e 100644 --- a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js +++ b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js @@ -24,14 +24,15 @@ import { _t } from '../../../../languageHandler'; import Modal from '../../../../Modal'; const PHASE_LOADING = 0; -const PHASE_MIGRATE = 1; -const PHASE_PASSPHRASE = 2; -const PHASE_PASSPHRASE_CONFIRM = 3; -const PHASE_SHOWKEY = 4; -const PHASE_KEEPITSAFE = 5; -const PHASE_STORING = 6; -const PHASE_DONE = 7; -const PHASE_OPTOUT_CONFIRM = 8; +const PHASE_RESTORE_KEY_BACKUP = 1; +const PHASE_MIGRATE = 2; +const PHASE_PASSPHRASE = 3; +const PHASE_PASSPHRASE_CONFIRM = 4; +const PHASE_SHOWKEY = 5; +const PHASE_KEEPITSAFE = 6; +const PHASE_STORING = 7; +const PHASE_DONE = 8; +const PHASE_OPTOUT_CONFIRM = 9; const PASSWORD_MIN_SCORE = 4; // So secure, many characters, much complex, wow, etc, etc. const PASSPHRASE_FEEDBACK_DELAY = 500; // How long after keystroke to offer passphrase feedback, ms. @@ -67,6 +68,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent { downloaded: false, zxcvbnResult: null, setPassPhrase: false, + backupInfo: null, + backupSigStatus: null, }; this._fetchBackupInfo(); @@ -80,10 +83,16 @@ export default class CreateSecretStorageDialog extends React.PureComponent { async _fetchBackupInfo() { const backupInfo = await MatrixClientPeg.get().getKeyBackupVersion(); + const backupSigStatus = await MatrixClientPeg.get().isKeyBackupTrusted(backupInfo); + + const phase = backupInfo ? + (backupSigStatus.usable ? PHASE_MIGRATE : PHASE_RESTORE_KEY_BACKUP) : + PHASE_PASSPHRASE; this.setState({ - phase: backupInfo ? PHASE_MIGRATE: PHASE_PASSPHRASE, + phase, backupInfo, + backupSigStatus, }); } @@ -268,6 +277,22 @@ export default class CreateSecretStorageDialog extends React.PureComponent { return this.state.zxcvbnResult && this.state.zxcvbnResult.score >= PASSWORD_MIN_SCORE; } + _renderPhaseRestoreKeyBackup() { + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); + return
+

{_t( + "Key Backup is enabled on your account but has not been set " + + "up from this sign-in. To set up secret storage, " + + "restore your key backup.", + )}

+ + +
; + } + _renderPhaseMigrate() { // TODO: This is a temporary screen so people who have the labs flag turned on and // click the button are aware they're making a change to their account. @@ -277,7 +302,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent { const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); return

{_t( - "Secret Storage will be set up using your existing key backup details." + + "Secret Storage will be set up using your existing key backup details. " + "Your secret storage passphrase and recovery key will be the same as " + " they were for your key backup", )}

@@ -527,6 +552,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent { _titleForPhase(phase) { switch (phase) { + case PHASE_RESTORE_KEY_BACKUP: + return _t('Restore Your Key Backup'); case PHASE_MIGRATE: return _t('Migrate from Key Backup'); case PHASE_PASSPHRASE: @@ -569,6 +596,9 @@ export default class CreateSecretStorageDialog extends React.PureComponent { case PHASE_LOADING: content = this._renderBusyPhase(); break; + case PHASE_RESTORE_KEY_BACKUP: + content = this._renderPhaseRestoreKeyBackup(); + break; case PHASE_MIGRATE: content = this._renderPhaseMigrate(); break; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index b34b7378919..3624a7c7432 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1933,7 +1933,8 @@ "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.", "File to import": "File to import", "Import": "Import", - "Secret Storage will be set up using your existing key backup details.Your secret storage passphrase and recovery key will be the same as they were for your key backup": "Secret Storage will be set up using your existing key backup details.Your secret storage passphrase and recovery key will be the same as they were for your key backup", + "Key Backup is enabled on your account but has not been set up from this sign-in. To set up secret storage, restore your key backup.": "Key Backup is enabled on your account but has not been set up from this sign-in. To set up secret storage, restore your key backup.", + "Secret Storage will be set up using your existing key backup details. Your secret storage passphrase and recovery key will be the same as they were for your key backup": "Secret Storage will be set up using your existing key backup details. Your secret storage passphrase and recovery key will be the same as they were for your key backup", "Great! This passphrase looks strong enough.": "Great! This passphrase looks strong enough.", "Warning: You should only set up secret storage from a trusted computer.": "Warning: You should only set up secret storage from a trusted computer.", "We'll use secret storage to optionally store an encrypted copy of your cross-signing identity for verifying other devices and message keys on our server. Protect your access to encrypted messages with a passphrase to keep it secure.": "We'll use secret storage to optionally store an encrypted copy of your cross-signing identity for verifying other devices and message keys on our server. Protect your access to encrypted messages with a passphrase to keep it secure.", @@ -1960,6 +1961,7 @@ "Your access to encrypted messages is now protected.": "Your access to encrypted messages is now protected.", "Without setting up secret storage, you won't be able to restore your access to encrypted messages or your cross-signing identity for verifying other devices if you log out or use another device.": "Without setting up secret storage, you won't be able to restore your access to encrypted messages or your cross-signing identity for verifying other devices if you log out or use another device.", "Set up secret storage": "Set up secret storage", + "Restore Your Key Backup": "Restore Your Key Backup", "Migrate from Key Backup": "Migrate from Key Backup", "Secure your encrypted messages with a passphrase": "Secure your encrypted messages with a passphrase", "Confirm your passphrase": "Confirm your passphrase", From 44ca35296a8d62860f11b94c4f1bf550822c7d41 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Jan 2020 11:31:00 +0000 Subject: [PATCH 2/5] Consistent capitalisation Co-Authored-By: J. Ryan Stinnett --- .../views/dialogs/secretstorage/CreateSecretStorageDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js index 60d1f4c1a0e..414a51bb312 100644 --- a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js +++ b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js @@ -553,7 +553,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent { _titleForPhase(phase) { switch (phase) { case PHASE_RESTORE_KEY_BACKUP: - return _t('Restore Your Key Backup'); + return _t('Restore your Key Backup'); case PHASE_MIGRATE: return _t('Migrate from Key Backup'); case PHASE_PASSPHRASE: From 94e4d5bf1f212b8334543e8bb0e3cec2822f79de Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Jan 2020 11:32:30 +0000 Subject: [PATCH 3/5] s/sign-in/session/ --- .../views/dialogs/secretstorage/CreateSecretStorageDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js index 414a51bb312..608fc964ab9 100644 --- a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js +++ b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js @@ -282,7 +282,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent { return

{_t( "Key Backup is enabled on your account but has not been set " + - "up from this sign-in. To set up secret storage, " + + "up from this session. To set up secret storage, " + "restore your key backup.", )}

Date: Tue, 14 Jan 2020 11:33:16 +0000 Subject: [PATCH 4/5] i18n --- src/i18n/strings/en_EN.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 3624a7c7432..b71f22f1364 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1933,7 +1933,7 @@ "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.", "File to import": "File to import", "Import": "Import", - "Key Backup is enabled on your account but has not been set up from this sign-in. To set up secret storage, restore your key backup.": "Key Backup is enabled on your account but has not been set up from this sign-in. To set up secret storage, restore your key backup.", + "Key Backup is enabled on your account but has not been set up from this session. To set up secret storage, restore your key backup.": "Key Backup is enabled on your account but has not been set up from this session. To set up secret storage, restore your key backup.", "Secret Storage will be set up using your existing key backup details. Your secret storage passphrase and recovery key will be the same as they were for your key backup": "Secret Storage will be set up using your existing key backup details. Your secret storage passphrase and recovery key will be the same as they were for your key backup", "Great! This passphrase looks strong enough.": "Great! This passphrase looks strong enough.", "Warning: You should only set up secret storage from a trusted computer.": "Warning: You should only set up secret storage from a trusted computer.", @@ -1961,7 +1961,7 @@ "Your access to encrypted messages is now protected.": "Your access to encrypted messages is now protected.", "Without setting up secret storage, you won't be able to restore your access to encrypted messages or your cross-signing identity for verifying other devices if you log out or use another device.": "Without setting up secret storage, you won't be able to restore your access to encrypted messages or your cross-signing identity for verifying other devices if you log out or use another device.", "Set up secret storage": "Set up secret storage", - "Restore Your Key Backup": "Restore Your Key Backup", + "Restore your Key Backup": "Restore your Key Backup", "Migrate from Key Backup": "Migrate from Key Backup", "Secure your encrypted messages with a passphrase": "Secure your encrypted messages with a passphrase", "Confirm your passphrase": "Confirm your passphrase", From 24552f567ece2a9bc1873e8cf913c5acbeb23735 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Jan 2020 11:52:00 +0000 Subject: [PATCH 5/5] Add primary button to trigger restore flow --- .../secretstorage/CreateSecretStorageDialog.js | 15 ++++++++++++--- src/i18n/strings/en_EN.json | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js index 608fc964ab9..b6d314aab1f 100644 --- a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js +++ b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js @@ -170,6 +170,14 @@ export default class CreateSecretStorageDialog extends React.PureComponent { this.props.onFinished(true); } + _onRestoreKeyBackupClick = () => { + const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog'); + Modal.createTrackedDialog( + 'Restore Backup', '', RestoreKeyBackupDialog, null, null, + /* priority = */ false, /* static = */ true, + ); + } + _onOptOutClick = () => { this.setState({phase: PHASE_OPTOUT_CONFIRM}); } @@ -285,9 +293,10 @@ export default class CreateSecretStorageDialog extends React.PureComponent { "up from this session. To set up secret storage, " + "restore your key backup.", )}

-
; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index b71f22f1364..19c31d540ad 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1934,6 +1934,7 @@ "File to import": "File to import", "Import": "Import", "Key Backup is enabled on your account but has not been set up from this session. To set up secret storage, restore your key backup.": "Key Backup is enabled on your account but has not been set up from this session. To set up secret storage, restore your key backup.", + "Restore": "Restore", "Secret Storage will be set up using your existing key backup details. Your secret storage passphrase and recovery key will be the same as they were for your key backup": "Secret Storage will be set up using your existing key backup details. Your secret storage passphrase and recovery key will be the same as they were for your key backup", "Great! This passphrase looks strong enough.": "Great! This passphrase looks strong enough.", "Warning: You should only set up secret storage from a trusted computer.": "Warning: You should only set up secret storage from a trusted computer.",