From 1c221f2b887ddb156c59b125647afcd26422f2fd Mon Sep 17 00:00:00 2001 From: Kit Sczudlo Date: Sun, 14 May 2017 15:16:47 -0700 Subject: [PATCH 1/8] Add in a "verify" slash command to confirm signing keys Allows users to send a text string via an alternative channel (like email or SMS) which Riot can leverage to confirm that the signing keys match. Effectively removes the tedium of checking keys until a better mechanism is completed. Signed-off-by: Kit Sczudlo --- src/SlashCommands.js | 62 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index 1ddcf4832d6..ac12893e6a6 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -282,7 +282,67 @@ var commands = { } } return reject(this.getUsage()); - }) + }), + + // Verify a user, device, and pubkey tuple + verify: new Command("verify", " ", function(room_id, args) { + if (args) { + var matches = args.match(/^(\S+) +(\S+) +(\S+)$/); + if (matches) { + var userId = matches[1]; + var deviceId = matches[2]; + var device = MatrixClientPeg.get().getStoredDevice(userId, deviceId); + if (!device) { + return reject(`Unknown (user, device) pair: (${userId}, ${deviceId})`); + } + + var fingerprint = matches[3]; + + if (device.getFingerprint() === fingerprint) { + + var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + Modal.createDialog(QuestionDialog, { + title: "Approve validated device", + description: ( +
+

+ The signing key in your slash command matches the signing key you + received for this user and device! +

+
+
    +
  • { userId }
  • +
  • { device.getDisplayName() }
  • +
  • { device.deviceId}
  • +
  • { device.getFingerprint() }
  • +
  • { device.getIdentityKey() }
  • +
+
+

+ If you would like to accept this device as validated, press accept! +

+
+ ), + button: "Accept this validated key", + onFinished: confirm => { + if (confirm) { + MatrixClientPeg.get().setDeviceVerified( + userId, deviceId, true + ); + } + }, + }); + + return success(); + } else { + return reject(`WARNING: KEY VALIDATION FAILED! The signing key for ${userId} and device + ${deviceId} is \"${device.getFingerprint()}\" which does not match the provided key + \"${fingerprint}\" This could mean your communications are being intercepted!`); + } + } + } + return reject(this.getUsage()); + }), }; // helpful aliases From 92ca3c2e3b78ab25fa2dc2915210343c0e0d697a Mon Sep 17 00:00:00 2001 From: Kit Sczudlo Date: Sun, 21 May 2017 01:33:54 -0700 Subject: [PATCH 2/8] Make wording more consistent, notify user of edgecases Replace all instaces of "Validated" with "Verified", and error out when the user's device is already verified. Signed-off-by: Kit Sczudlo --- src/SlashCommands.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index ac12893e6a6..2546fb52683 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -298,11 +298,17 @@ var commands = { var fingerprint = matches[3]; + if (device.isVerified() && device.getFingerprint() === fingerprint) { + return reject(`Device already verified!`); + } else if (device.isVerified() && device.getFingerprint() !== fingerprint) { + return reject(`WARNING: Device already verified, but keys do NOT MATCH!`); + } + if (device.getFingerprint() === fingerprint) { var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); Modal.createDialog(QuestionDialog, { - title: "Approve validated device", + title: "Approve verified device", description: (

@@ -323,7 +329,7 @@ var commands = {

), - button: "Accept this validated key", + button: "Accept this verified key", onFinished: confirm => { if (confirm) { MatrixClientPeg.get().setDeviceVerified( @@ -335,7 +341,7 @@ var commands = { return success(); } else { - return reject(`WARNING: KEY VALIDATION FAILED! The signing key for ${userId} and device + return reject(`WARNING: KEY VERIFICATION FAILED! The signing key for ${userId} and device ${deviceId} is \"${device.getFingerprint()}\" which does not match the provided key \"${fingerprint}\" This could mean your communications are being intercepted!`); } From 6897c600f8f93f750c1772531047afea6cbc9258 Mon Sep 17 00:00:00 2001 From: Kit Sczudlo Date: Sun, 21 May 2017 01:39:54 -0700 Subject: [PATCH 3/8] Fix nit to make if conditional more straightforward Signed-off-by: Kit Sczudlo --- src/SlashCommands.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index 2546fb52683..9e85ff2ae28 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -298,10 +298,12 @@ var commands = { var fingerprint = matches[3]; - if (device.isVerified() && device.getFingerprint() === fingerprint) { - return reject(`Device already verified!`); - } else if (device.isVerified() && device.getFingerprint() !== fingerprint) { - return reject(`WARNING: Device already verified, but keys do NOT MATCH!`); + if (device.isVerified()) { + if (device.getFingerprint() === fingerprint) { + return reject(`Device already verified!`); + } else { + return reject(`WARNING: Device already verified, but keys do NOT MATCH!`); + } } if (device.getFingerprint() === fingerprint) { From 4be5d8835023574ffc74be5e4345ba8dfe47eb06 Mon Sep 17 00:00:00 2001 From: Kit Sczudlo Date: Sun, 21 May 2017 01:47:32 -0700 Subject: [PATCH 4/8] Prefer const over var, replace validated with verified Also remove a few unnecessary escape characters in front or double quotes Signed-off-by: Kit Sczudlo --- src/SlashCommands.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index 9e85ff2ae28..a090ec7bade 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -289,15 +289,15 @@ var commands = { if (args) { var matches = args.match(/^(\S+) +(\S+) +(\S+)$/); if (matches) { - var userId = matches[1]; - var deviceId = matches[2]; - var device = MatrixClientPeg.get().getStoredDevice(userId, deviceId); + const userId = matches[1]; + const deviceId = matches[2]; + const fingerprint = matches[3]; + + const device = MatrixClientPeg.get().getStoredDevice(userId, deviceId); if (!device) { return reject(`Unknown (user, device) pair: (${userId}, ${deviceId})`); } - var fingerprint = matches[3]; - if (device.isVerified()) { if (device.getFingerprint() === fingerprint) { return reject(`Device already verified!`); @@ -307,8 +307,7 @@ var commands = { } if (device.getFingerprint() === fingerprint) { - - var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); Modal.createDialog(QuestionDialog, { title: "Approve verified device", description: ( @@ -327,7 +326,7 @@ var commands = {

- If you would like to accept this device as validated, press accept! + If you would like to accept this device as verified, press accept!

), @@ -344,8 +343,8 @@ var commands = { return success(); } else { return reject(`WARNING: KEY VERIFICATION FAILED! The signing key for ${userId} and device - ${deviceId} is \"${device.getFingerprint()}\" which does not match the provided key - \"${fingerprint}\" This could mean your communications are being intercepted!`); + ${deviceId} is "${device.getFingerprint()}" which does not match the provided key + "${fingerprint}" This could mean your communications are being intercepted!`); } } } From 352f81b8aad238631f0fdc807d0191bdb018d3a7 Mon Sep 17 00:00:00 2001 From: Kit Sczudlo Date: Mon, 22 May 2017 23:26:17 -0700 Subject: [PATCH 5/8] Streamline "accept" dialog and fix missing period Signed-off-by: Kit Sczudlo --- src/SlashCommands.js | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index a090ec7bade..4e6d001d2c0 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -309,28 +309,16 @@ var commands = { if (device.getFingerprint() === fingerprint) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); Modal.createDialog(QuestionDialog, { - title: "Approve verified device", + title: "Verified key", description: (

- The signing key in your slash command matches the signing key you - received for this user and device! -

-
-
    -
  • { userId }
  • -
  • { device.getDisplayName() }
  • -
  • { device.deviceId}
  • -
  • { device.getFingerprint() }
  • -
  • { device.getIdentityKey() }
  • -
-
-

- If you would like to accept this device as verified, press accept! + The signing key you provided matches the signing key you received from + { userId }'s device { deviceId }

), - button: "Accept this verified key", + button: "Accept verification", onFinished: confirm => { if (confirm) { MatrixClientPeg.get().setDeviceVerified( @@ -344,7 +332,7 @@ var commands = { } else { return reject(`WARNING: KEY VERIFICATION FAILED! The signing key for ${userId} and device ${deviceId} is "${device.getFingerprint()}" which does not match the provided key - "${fingerprint}" This could mean your communications are being intercepted!`); + "${fingerprint}". This could mean your communications are being intercepted!`); } } } From 68df4a88f1b976c7ccd37d173cea1fb9fa970a80 Mon Sep 17 00:00:00 2001 From: Kit Sczudlo Date: Mon, 22 May 2017 23:43:05 -0700 Subject: [PATCH 6/8] Fix missing space before username in verify dialog Signed-off-by: Kit Sczudlo --- src/SlashCommands.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index 4e6d001d2c0..c1a93881240 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -313,8 +313,8 @@ var commands = { description: (

- The signing key you provided matches the signing key you received from - { userId }'s device { deviceId } + The signing key you provided matches the signing key you received + from { userId }'s device { deviceId }

), From fbfbcc1a8e8d7404dab014cf4b58e526711a8e8e Mon Sep 17 00:00:00 2001 From: Kit Sczudlo Date: Tue, 23 May 2017 01:03:47 -0700 Subject: [PATCH 7/8] Change acceptance dialog to confirmation dialog Signed-off-by: Kit Sczudlo --- src/SlashCommands.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index c1a93881240..11e148cc5f2 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -314,11 +314,12 @@ var commands = {

The signing key you provided matches the signing key you received - from { userId }'s device { deviceId } + from { userId }'s device { deviceId }. Device marked as verified.

), - button: "Accept verification", + button: "Ok", + hasCancelButton: false, onFinished: confirm => { if (confirm) { MatrixClientPeg.get().setDeviceVerified( From 97c98b1883988758b7d5d4db2516911c261c62dd Mon Sep 17 00:00:00 2001 From: Kit Sczudlo Date: Tue, 23 May 2017 01:11:30 -0700 Subject: [PATCH 8/8] Make the confirmation dialog after verification Signed-off-by: Kit Sczudlo --- src/SlashCommands.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index 11e148cc5f2..4b6fb8cfcb8 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -307,6 +307,11 @@ var commands = { } if (device.getFingerprint() === fingerprint) { + MatrixClientPeg.get().setDeviceVerified( + userId, deviceId, true + ); + + // Tell the user we verified everything! const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); Modal.createDialog(QuestionDialog, { title: "Verified key", @@ -320,13 +325,6 @@ var commands = { ), button: "Ok", hasCancelButton: false, - onFinished: confirm => { - if (confirm) { - MatrixClientPeg.get().setDeviceVerified( - userId, deviceId, true - ); - } - }, }); return success();