From 060f2cf54f19beba7160fcf69b133c09c0e9078b Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 6 Aug 2020 15:10:47 +0100 Subject: [PATCH 1/4] Enable sharing of master cross-signing key We've realised it's beneficial to support sharing the master cross-singing key so that new devices can fully manage cross-signing on your account. Part of https://github.com/vector-im/element-web/issues/13896 --- src/CrossSigningManager.js | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js index a584a69d35..fe07a821c6 100644 --- a/src/CrossSigningManager.js +++ b/src/CrossSigningManager.js @@ -132,24 +132,14 @@ const onSecretRequested = async function({ if (name.startsWith("m.cross_signing")) { const callbacks = client.getCrossSigningCacheCallbacks(); if (!callbacks.getCrossSigningKeyCache) return; - /* Explicit enumeration here is deliberate – never share the master key! */ - if (name === "m.cross_signing.self_signing") { - const key = await callbacks.getCrossSigningKeyCache("self_signing"); - if (!key) { - console.log( - `self_signing requested by ${deviceId}, but not found in cache`, - ); - } - return key && encodeBase64(key); - } else if (name === "m.cross_signing.user_signing") { - const key = await callbacks.getCrossSigningKeyCache("user_signing"); - if (!key) { - console.log( - `user_signing requested by ${deviceId}, but not found in cache`, - ); - } - return key && encodeBase64(key); + const keyId = name.replace("m.cross_signing.", ""); + const key = await callbacks.getCrossSigningKeyCache(keyId); + if (!key) { + console.log( + `${keyId} requested by ${deviceId}, but not found in cache`, + ); } + return key && encodeBase64(key); } else if (name === "m.megolm_backup.v1") { const key = await client._crypto.getSessionBackupPrivateKey(); if (!key) { From 4c1956a3c21a2acf53c8924d9affd1e4f25f9712 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 6 Aug 2020 15:25:33 +0100 Subject: [PATCH 2/4] Show master key cache status in Settings --- src/components/views/settings/CrossSigningPanel.js | 8 ++++++++ src/i18n/strings/en_EN.json | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/components/views/settings/CrossSigningPanel.js b/src/components/views/settings/CrossSigningPanel.js index aa512d4365..1c6baee9af 100644 --- a/src/components/views/settings/CrossSigningPanel.js +++ b/src/components/views/settings/CrossSigningPanel.js @@ -32,6 +32,7 @@ export default class CrossSigningPanel extends React.PureComponent { error: null, crossSigningPublicKeysOnDevice: false, crossSigningPrivateKeysInStorage: false, + masterPrivateKeyCached: false, selfSigningPrivateKeyCached: false, userSigningPrivateKeyCached: false, sessionBackupKeyCached: false, @@ -78,6 +79,7 @@ export default class CrossSigningPanel extends React.PureComponent { const secretStorage = cli._crypto._secretStorage; const crossSigningPublicKeysOnDevice = crossSigning.getId(); const crossSigningPrivateKeysInStorage = await crossSigning.isStoredInSecretStorage(secretStorage); + const masterPrivateKeyCached = !!(pkCache && await pkCache.getCrossSigningKeyCache("master")); const selfSigningPrivateKeyCached = !!(pkCache && await pkCache.getCrossSigningKeyCache("self_signing")); const userSigningPrivateKeyCached = !!(pkCache && await pkCache.getCrossSigningKeyCache("user_signing")); const sessionBackupKeyFromCache = await cli._crypto.getSessionBackupPrivateKey(); @@ -91,6 +93,7 @@ export default class CrossSigningPanel extends React.PureComponent { this.setState({ crossSigningPublicKeysOnDevice, crossSigningPrivateKeysInStorage, + masterPrivateKeyCached, selfSigningPrivateKeyCached, userSigningPrivateKeyCached, sessionBackupKeyCached, @@ -140,6 +143,7 @@ export default class CrossSigningPanel extends React.PureComponent { error, crossSigningPublicKeysOnDevice, crossSigningPrivateKeysInStorage, + masterPrivateKeyCached, selfSigningPrivateKeyCached, userSigningPrivateKeyCached, sessionBackupKeyCached, @@ -235,6 +239,10 @@ export default class CrossSigningPanel extends React.PureComponent { {_t("Cross-signing private keys:")} {crossSigningPrivateKeysInStorage ? _t("in secret storage") : _t("not found")} + + {_t("Master private key:")} + {masterPrivateKeyCached ? _t("cached locally") : _t("not found locally")} + {_t("Self signing private key:")} {selfSigningPrivateKeyCached ? _t("cached locally") : _t("not found locally")} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 82a8f960ab..d25e136747 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -653,9 +653,10 @@ "not found": "not found", "Cross-signing private keys:": "Cross-signing private keys:", "in secret storage": "in secret storage", - "Self signing private key:": "Self signing private key:", + "Master private key:": "Master private key:", "cached locally": "cached locally", "not found locally": "not found locally", + "Self signing private key:": "Self signing private key:", "User signing private key:": "User signing private key:", "Session backup key:": "Session backup key:", "Secret storage public key:": "Secret storage public key:", From 810f07a84693170cf28d41382212e39a5cd5fe40 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 6 Aug 2020 15:26:47 +0100 Subject: [PATCH 3/4] Report master key cache status in rageshakes --- src/rageshake/submit-rageshake.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rageshake/submit-rageshake.ts b/src/rageshake/submit-rageshake.ts index 350602aa5d..b562141338 100644 --- a/src/rageshake/submit-rageshake.ts +++ b/src/rageshake/submit-rageshake.ts @@ -122,6 +122,8 @@ export default async function sendBugReport(bugReportEndpoint: string, opts: IOp body.append("ssss_key_in_account", String(!!(await secretStorage.hasKey()))); const pkCache = client.getCrossSigningCacheCallbacks(); + body.append("master_pk_cached", + String(!!(pkCache && await pkCache.getCrossSigningKeyCache("master")))); body.append("self_signing_pk_cached", String(!!(pkCache && await pkCache.getCrossSigningKeyCache("self_signing")))); body.append("user_signing_pk_cached", From 9e40e079ffd0444348fc39eb4b2786faa4b63013 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Fri, 7 Aug 2020 15:54:05 +0100 Subject: [PATCH 4/4] Use an explicit list of keys to share --- src/CrossSigningManager.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js index fe07a821c6..676c41d7d7 100644 --- a/src/CrossSigningManager.js +++ b/src/CrossSigningManager.js @@ -129,7 +129,11 @@ const onSecretRequested = async function({ console.log(`CrossSigningManager: Ignoring request from untrusted device ${deviceId}`); return; } - if (name.startsWith("m.cross_signing")) { + if ( + name === "m.cross_signing.master" || + name === "m.cross_signing.self_signing" || + name === "m.cross_signing.user_signing" + ) { const callbacks = client.getCrossSigningCacheCallbacks(); if (!callbacks.getCrossSigningKeyCache) return; const keyId = name.replace("m.cross_signing.", "");