diff options
Diffstat (limited to 'comm/mail/test/browser/openpgp/browser_collectKeys.js')
-rw-r--r-- | comm/mail/test/browser/openpgp/browser_collectKeys.js | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/comm/mail/test/browser/openpgp/browser_collectKeys.js b/comm/mail/test/browser/openpgp/browser_collectKeys.js new file mode 100644 index 0000000000..d87df03ba3 --- /dev/null +++ b/comm/mail/test/browser/openpgp/browser_collectKeys.js @@ -0,0 +1,318 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Tests for the collecting keys from messages. + */ + +"use strict"; + +const { get_about_message, open_message_from_file } = ChromeUtils.import( + "resource://testing-common/mozmill/FolderDisplayHelpers.jsm" +); +const { close_window } = ChromeUtils.import( + "resource://testing-common/mozmill/WindowHelpers.jsm" +); +const { waitForCondition } = ChromeUtils.import( + "resource://testing-common/mozmill/utils.jsm" +); +const { + assert_notification_displayed, + get_notification_button, + wait_for_notification_to_show, + wait_for_notification_to_stop, +} = ChromeUtils.import( + "resource://testing-common/mozmill/NotificationBoxHelpers.jsm" +); +const { OpenPGPTestUtils } = ChromeUtils.import( + "resource://testing-common/mozmill/OpenPGPTestUtils.jsm" +); + +const { MailServices } = ChromeUtils.import( + "resource:///modules/MailServices.jsm" +); +const { CollectedKeysDB } = ChromeUtils.import( + "chrome://openpgp/content/modules/CollectedKeysDB.jsm" +); + +var aliceAcct; + +/** + * When testing a scenario that should automatically process the OpenPGP + * contents (it's not suppressed e.g. because of a partial content), + * then we need to wait for the automatic processing to complete. + */ +async function openpgpProcessed() { + let [subject] = await TestUtils.topicObserved( + "document-element-inserted", + document => { + return document.ownerGlobal?.location == "about:message"; + } + ); + + return BrowserTestUtils.waitForEvent(subject, "openpgpprocessed"); +} + +/** + * Set up the base account, identity and keys needed for the tests. + */ +add_setup(async function () { + aliceAcct = MailServices.accounts.createAccount(); + aliceAcct.incomingServer = MailServices.accounts.createIncomingServer( + "alice", + "openpgp.example", + "pop3" + ); + let aliceIdentity = MailServices.accounts.createIdentity(); + aliceIdentity.email = "alice@openpgp.example"; + aliceAcct.addIdentity(aliceIdentity); + + // Set up the alice's private key. + // We need one key set up for use. Otherwise we do not process OpenPGP data. + let [id] = await OpenPGPTestUtils.importPrivateKey( + window, + new FileUtils.File( + getTestFilePath( + "data/keys/alice@openpgp.example-0xf231550c4f47e38e-secret.asc" + ) + ) + ); + aliceIdentity.setUnicharAttribute("openpgp_key_id", id); +}); + +/** + * Test that an attached key is collected. + */ +add_task(async function testCollectKeyAttachment() { + let keycollected = BrowserTestUtils.waitForEvent(window, "keycollected"); + let opengpgprocessed = openpgpProcessed(); + let mc = await open_message_from_file( + new FileUtils.File( + getTestFilePath( + "data/eml/unsigned-unencrypted-key-0x1f10171bfb881b1c-attached.eml" + ) + ) + ); + await opengpgprocessed; + let aboutMessage = get_about_message(mc.window); + + Assert.ok( + OpenPGPTestUtils.hasNoSignedIconState(aboutMessage.document), + "signed icon is not displayed" + ); + Assert.ok( + !OpenPGPTestUtils.hasEncryptedIconState(aboutMessage.document, "ok"), + "encrypted icon is not displayed" + ); + await keycollected; + + let db = await CollectedKeysDB.getInstance(); + let keys = await db.findKeysForEmail("jdoe@invalid"); + Assert.equal(keys.length, 1, "should find one key"); + + let sources = keys[0].sources; + Assert.equal(sources.length, 1, "should have one source"); + let source = sources[0]; + + Assert.equal(source.type, "attachment"); + Assert.equal(source.uri, "mid:4a735c72-dc19-48ff-4fa5-2c1f65513b27@invalid"); + Assert.equal(source.description, "OpenPGP_0x1F10171BFB881B1C.asc"); + + close_window(mc); +}); + +/** + * Test that an Autocrypt header key is collected. + */ +add_task(async function testCollectAutocrypt() { + let keycollected = BrowserTestUtils.waitForEvent(window, "keycollected"); + let opengpgprocessed = openpgpProcessed(); + let mc = await open_message_from_file( + new FileUtils.File( + getTestFilePath( + "data/eml/unsigned-unencrypted-0x3099ff1238852b9f-autocrypt.eml" + ) + ) + ); + await opengpgprocessed; + let aboutMessage = get_about_message(mc.window); + + Assert.ok( + OpenPGPTestUtils.hasNoSignedIconState(aboutMessage.document), + "signed icon is not displayed" + ); + Assert.ok( + !OpenPGPTestUtils.hasEncryptedIconState(aboutMessage.document, "ok"), + "encrypted icon is not displayed" + ); + await keycollected; + + const carolEmail = "carol@example.com"; + + let db = await CollectedKeysDB.getInstance(); + let keys = await db.findKeysForEmail(carolEmail); + Assert.equal(keys.length, 1, "should find one key"); + + let sources = keys[0].sources; + Assert.equal(sources.length, 1, "should have one source"); + let source = sources[0]; + + Assert.equal(source.type, "autocrypt"); + Assert.equal( + source.uri, + "mid:b3609461-36e8-0371-1b9d-7ce6864ec66d@example.com" + ); + Assert.equal(source.description, undefined); + + // Clean up to ensure other tests will not find this key + db.deleteKeysForEmail(carolEmail); + keys = await db.findKeysForEmail(carolEmail); + Assert.equal(keys.length, 0, "should find zero keys after cleanup"); + + close_window(mc); +}); + +/** + * Test that an Autocrypt-Gossip header key is collected. + */ +add_task(async function testCollectAutocryptGossip() { + let keycollected = BrowserTestUtils.waitForEvent(window, "keycollected"); + let keycollected2 = BrowserTestUtils.waitForEvent(window, "keycollected"); + let keycollected3 = BrowserTestUtils.waitForEvent(window, "keycollected"); + let opengpgprocessed = openpgpProcessed(); + let msgc = await open_message_from_file( + new FileUtils.File( + getTestFilePath("data/eml/signed-encrypted-autocrypt-gossip.eml") + ) + ); + await opengpgprocessed; + let aboutMessage = get_about_message(msgc.window); + + Assert.ok( + OpenPGPTestUtils.hasSignedIconState(aboutMessage.document, "unknown"), + "signed icon is displayed" + ); + Assert.ok( + OpenPGPTestUtils.hasEncryptedIconState(aboutMessage.document, "ok"), + "encrypted icon is displayed" + ); + + await keycollected; + await keycollected2; + await keycollected3; + + const carolEmail = "carol@example.com"; + + let db = await CollectedKeysDB.getInstance(); + let keys = await db.findKeysForEmail(carolEmail); + Assert.equal(keys.length, 1, "should find one key"); + + let sources = keys[0].sources; + Assert.equal(sources.length, 1, "should have one source"); + let source = sources[0]; + + Assert.equal(source.type, "autocrypt"); + Assert.equal( + source.uri, + "mid:e8690528-d187-4d99-b505-9f3d6a2704ca@openpgp.example" + ); + Assert.equal(source.description, undefined); + + // Clean up to ensure other tests will not find this key + db.deleteKeysForEmail(carolEmail); + keys = await db.findKeysForEmail(carolEmail); + Assert.equal(keys.length, 0, "should find zero keys after cleanup"); + + close_window(msgc); +}); + +/** + * Test that we don't collect keys that refer to an email address that + * isn't one of the message participants, and that we don't collect keys + * if we already have a personal key for an email address. + */ +add_task(async function testSkipFakeOrUnrelatedKeys() { + let opengpgprocessed = openpgpProcessed(); + let mc = await open_message_from_file( + new FileUtils.File( + getTestFilePath("data/eml/unrelated-and-fake-keys-attached.eml") + ) + ); + await opengpgprocessed; + let aboutMessage = get_about_message(mc.window); + + Assert.ok( + OpenPGPTestUtils.hasNoSignedIconState(aboutMessage.document), + "signed icon is not displayed" + ); + Assert.ok( + !OpenPGPTestUtils.hasEncryptedIconState(aboutMessage.document, "ok"), + "encrypted icon is not displayed" + ); + + let db = await CollectedKeysDB.getInstance(); + + let keys = await db.findKeysForEmail("alice@openpgp.example"); + Assert.equal( + keys.length, + 0, + "the attached key for alice should have been ignored because we have a personal key for that address" + ); + + keys = await db.findKeysForEmail("stranger@example.com"); + Assert.equal( + keys.length, + 0, + "the attached key for stranger should have been ignored because stranger isn't a participant of this message" + ); + + let bobEmail = "bob@openpgp.example"; + keys = await db.findKeysForEmail(bobEmail); + Assert.equal(keys.length, 1, "bob's key should have been collected"); + + db.deleteKeysForEmail(bobEmail); + keys = await db.findKeysForEmail(bobEmail); + Assert.equal(keys.length, 0, "should find zero keys after cleanup"); + + close_window(mc); +}); + +/** + * If an email contains two different keys for the same email address, + * don't import any keys for that email address. + */ +add_task(async function testSkipDuplicateKeys() { + let opengpgprocessed = openpgpProcessed(); + let mc = await open_message_from_file( + new FileUtils.File(getTestFilePath("data/eml/eve-duplicate.eml")) + ); + await opengpgprocessed; + let aboutMessage = get_about_message(mc.window); + + Assert.ok( + OpenPGPTestUtils.hasNoSignedIconState(aboutMessage.document), + "signed icon is not displayed" + ); + Assert.ok( + !OpenPGPTestUtils.hasEncryptedIconState(aboutMessage.document, "ok"), + "encrypted icon is not displayed" + ); + + let db = await CollectedKeysDB.getInstance(); + + let keys = await db.findKeysForEmail("eve@example.com"); + Assert.equal( + keys.length, + 0, + "the attached keys for eve should have been ignored" + ); + + close_window(mc); +}); + +registerCleanupFunction(async function tearDown() { + MailServices.accounts.removeAccount(aliceAcct, true); + await OpenPGPTestUtils.removeKeyById("0xf231550c4f47e38e", true); + await CollectedKeysDB.deleteDb(); +}); |