diff options
Diffstat (limited to 'comm/mail/extensions/openpgp/test/unit/rnp')
12 files changed, 1683 insertions, 0 deletions
diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/data/bluebird50.jpg b/comm/mail/extensions/openpgp/test/unit/rnp/data/bluebird50.jpg Binary files differnew file mode 100644 index 0000000000..6bc9b4f3af --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/data/bluebird50.jpg diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/data/bluebird50.jpg.asc b/comm/mail/extensions/openpgp/test/unit/rnp/data/bluebird50.jpg.asc new file mode 100644 index 0000000000..c67d0dd057 --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/data/bluebird50.jpg.asc @@ -0,0 +1,200 @@ +-----BEGIN PGP MESSAGE----- + +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 +OqSc9tGDcmANF3LQEj1htma9yReOKmZdQTDY +=s6vG +-----END PGP MESSAGE----- diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/data/bluebird50.jpg.gpg b/comm/mail/extensions/openpgp/test/unit/rnp/data/bluebird50.jpg.gpg Binary files differnew file mode 100644 index 0000000000..1feb515938 --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/data/bluebird50.jpg.gpg diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/data/plaintext-with-key-and-windows-1252-encoded-eml-attachment.eml b/comm/mail/extensions/openpgp/test/unit/rnp/data/plaintext-with-key-and-windows-1252-encoded-eml-attachment.eml new file mode 100644 index 0000000000..599d5f64f4 --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/data/plaintext-with-key-and-windows-1252-encoded-eml-attachment.eml @@ -0,0 +1,109 @@ +Content-Type: multipart/mixed; boundary=\"xy23ZrTYskosBXu9d5LEB0IV1ZMMCLTf7\"; + protected-headers=\"v1\" +Subject: Key And Windows 1252 Encoded Attachment +From: Bob Babbage <bob@openpgp.example> +To: alice@openpgp.example +Message-ID: <ce639032-0823-5c4d-30a3-76a874950908@openpgp.example> + +--xy23ZrTYskosBXu9d5LEB0IV1ZMMCLTf7 +Content-Type: multipart/mixed; boundary=\"------------azSRG4BClDM2kDHcC4FYbiRW\" + +--------------azSRG4BClDM2kDHcC4FYbiRW +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: quoted-printable + +Please see attached. + +--------------azSRG4BClDM2kDHcC4FYbiRW +Content-Type: message/rfc822; name=\"win1252.eml\" +Content-Disposition: attachment; filename=\"win1252.eml\" +Content-Transfer-Encoding: 8bit + +To: bob@openpgp.example +From: carol@openpgp.example +Subject: Windows 1252 +Date: Wed, 4 Nov 2020 16:32:02 -0400 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 + Thunderbird/78.4.0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=windows-1252; format=flowed +Content-Transfer-Encoding: 8bit +Content-Language: en-US + +This message has 6 ü ü ü ü ü ü. + +--------------azSRG4BClDM2kDHcC4FYbiRW +Content-Type: application/pgp-keys; name=\"OpenPGP_0xFBFCC82A015E7330.asc\" +Content-Disposition: attachment; filename=\"OpenPGP_0xFBFCC82A015E7330.asc\" +Content-Transfer-Encoding: quoted-printable + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +xsDNBF2lnPIBDAC5cL9PQoQLTMuhjbYvb4Ncuuo0bfmgPRFywX53jPhoFf4Zg6mv/seOXpgec= +TdO +cVttfzC8ycIKrt3aQTiwOG/ctaR4Bk/t6ayNFfdUNxHWk4WCKzdz/56fW2O0F23qIRd8UUJp5= +IIl +N4RDdRCtdhVQIAuzvp2oVy/LaS2kxQoKvph/5pQ/5whqsyroEWDJoSV0yOb25B/iwk/pLUFoy= +hDG +9bj0kIzDxrEqW+7Ba8nocQlecMF3X5KMN5kp2zraLv9dlBBpWW43XktjcCZgMy20SouraVma8= +Je/ +ECwUWYUiAZxLIlMv9CurEOtxUw6N3RdOtLmYZS9uEnn5y1UkF88o8Nku890uk6BrewFzJyLAx= +5wR +Z4F0qV/yq36UWQ0JB/AUGhHVPdFf6pl6eaxBwT5GXvbBUibtf8YI2og5RsgTWtXfU7ebSGXrl= +5ZM +pbA6mbfhd0R8aPxWfmDWiIOhBufhMCvUHh1sApMKVZnvIff9/0Dca3wbvLIwa3T4CyshfT0AE= +QEA +Ac0hQm9iIEJhYmJhZ2UgPGJvYkBvcGVucGdwLmV4YW1wbGU+wsEOBBMBCgA4AhsDBQsJCAcCB= +hUK +CQgLAgQWAgMBAh4BAheAFiEE0aZuGiOxgsmYD3iM+/zIKgFeczAFAl2lnvoACgkQ+/zIKgFec= +zBv +bAv/VNk90a6hG8Od9xTzXxH5YRFUSGfIA1yjPIVOnKqhMwps2U+sWE3urL+MvjyQRlyRV8oY9= +IOh +Q5Esm6DOZYrTnE7qVETm1ajIAP2OFChEc55uH88x/anpPOXOJY7S8jbn3naC9qad75BrZ+3g9= +EBU +Wiy5p8TykP05WSnSxNRt7vFKLfEB4nGkehpwHXOVF0CRNwYle42bg8lpmdXFDcCZCi+qEbafm= +TQz +kAqyzS3nCh3IAqq6Y0kBuaKLm2tSNUOlZbD+OHYQNZ5Jix7cZUzs6Xh4+I55NRWl5smrLq66y= +OQo +FPy9jot/Qxikx/wP3MsAzeGaZSEPc0fHp5G16rlGbxQ3vl8/usUV7W+TMEMljgwd5x8POR6HC= +8Ea +CDfVnUBCPi/Gv+egLjsIbPJZZEroiE40e6/UoCiQtlpQB5exPJYSd1Q1txCwueih99PHepsDh= +mUQ +KiACszNU+RRozAYau2VdHqnRJ7QYdxHDiH49jPK4NTMyb/tJh2TiIwcmsIpGzsDNBF2lnPIBD= +ADW +ML9cbGMrp12CtF9b2P6z9TTT74S8iyBOzaSvdGDQY/sUtZXRg21HWamXnn9sSXvIDEINOQ6A9= +Qxd +xoqWdCHrOuW3ofneYXoG+zeKc4dC86wa1TR2q9vW+RMXSO4uImA+Uzula/6k1DogDf28qhCxM= +wG/ +i/m9g1c/0aApuDyKdQ1PXsHHNlgd/Dn6rrd5y2AObaifV7wIhEJnvqgFXDN2RXGjLeCOHV4Q2= +WTY +Pg/S4k1nMXVDwZXrvIsA0YwIMgIT86Rafp1qKlgPNbiIlC1g9RY/iFaGN2b4Ir6GDohBQSfZW= +2+L +XoPZuVE/wGlQ01rh827KVZW4lXvqsge+wtnWlszcselGATyzqOK9LdHPdZGzROZYI2e8c+paL= +NDd +VPL6vdRBUnkCaEkOtl1mr2JpQi5nTU+gTX4IeInC7E+1a9UDF/Y85ybUz8XV8rUnR76UqVC7K= +idN +epdHbZjjXCt8/Zo+Tec9JNbYNQB/e9ExmDntmlHEsSEQzFwzj8sxH48AEQEAAcLA9gQYAQoAI= +BYh +BNGmbhojsYLJmA94jPv8yCoBXnMwBQJdpZzyAhsMAAoJEPv8yCoBXnMw6f8L/26C34dkjBffT= +zMj +5Bdzm8MtF67OYneJ4TQMw7+41IL4rVcSKhIhk/3Ud5knaRtP2ef1+5F66h9/RPQOJ5+tvBwhB= +AcU +WSupKnUrdVaZQanYmtSxcVV2PL9+QEiNN3tzluhaWO//rACxJ+K/ZXQlIzwQVTpNhfGzAaMVV= +9zp +f3u0k14itcv6alKY8+rLZvO1wIIeRZLmU0tZDD5HtWDvUV7rIFI1WuoLb+KZgbYn3OWjCPHVd= +Trd +Z2CqnZbG3SXw6awH9bzRLV9EXkbhIMez0deCVdeo+wFFklh8/5VK2b0vk/+wqMJxfpa1lHvJL= +obz +OP9fvrswsr92MA2+k901WeISR7qEzcI0Fdg8AyFAExaEK6VyjP7SXGLwvfisw34OxuZr3qmx1= +Suf +u4toH3XrB7QJN8XyqqbsGxUCBqWif9RSK4xjzRTe56iPeiSJJOIciMP9i2ldI+KgLycyeDvGo= +Bj0 +HCLO3gVaBe4ubVrj5KjhX2PVNEJd3XZRzaXZE2aAMQ=3D=3D +=3DF9yX +-----END PGP PUBLIC KEY BLOCK----- +--------------azSRG4BClDM2kDHcC4FYbiRW-- + + +--xy23ZrTYskosBXu9d5LEB0IV1ZMMCLTf7-- + diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/data/plaintext-with-windows-1252-encoded-eml-attachment.eml b/comm/mail/extensions/openpgp/test/unit/rnp/data/plaintext-with-windows-1252-encoded-eml-attachment.eml new file mode 100644 index 0000000000..b43d9883bf --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/data/plaintext-with-windows-1252-encoded-eml-attachment.eml @@ -0,0 +1,39 @@ +Content-Type: multipart/mixed; boundary=\"mzik1s6PCI8wO850i5PykshHnKiAGShJ0\"; + protected-headers=\"v1\" +Subject: Key And Windows 1252 Encoded Attachment +From: Bob Babbage <bob@openpgp.example> +To: alice@openpgp.example +Message-ID: <26826c45-bac5-f173-9d60-dab5c907156d@openpgp.example> + +--mzik1s6PCI8wO850i5PykshHnKiAGShJ0 +Content-Type: multipart/mixed; boundary=\"------------voUvzEdWKr8OR9mQliQ0aHDW\" + +--------------voUvzEdWKr8OR9mQliQ0aHDW +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: quoted-printable + +Please see attached. + +--------------voUvzEdWKr8OR9mQliQ0aHDW +Content-Type: message/rfc822; name=\"win1252.eml\" +Content-Disposition: attachment; filename=\"win1252.eml\" +Content-Transfer-Encoding: 8bit + +To: bob@openpgp.example +From: carol@openpgp.example +Subject: Windows 1252 +Date: Wed, 4 Nov 2020 16:32:02 -0400 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 + Thunderbird/78.4.0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=windows-1252; format=flowed +Content-Transfer-Encoding: 8bit +Content-Language: en-US + +This message has 6 ü ü ü ü ü ü. + +--------------voUvzEdWKr8OR9mQliQ0aHDW-- + + +--mzik1s6PCI8wO850i5PykshHnKiAGShJ0-- + diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/test_alias.js b/comm/mail/extensions/openpgp/test/unit/rnp/test_alias.js new file mode 100644 index 0000000000..cc30b52a8a --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/test_alias.js @@ -0,0 +1,321 @@ +/* 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 OpenPGP encryption alias rules. + */ + +"use strict"; + +const { RNP } = ChromeUtils.import("chrome://openpgp/content/modules/RNP.jsm"); +const { EnigmailConstants } = ChromeUtils.import( + "chrome://openpgp/content/modules/constants.jsm" +); +const { EnigmailKeyRing } = ChromeUtils.import( + "chrome://openpgp/content/modules/keyRing.jsm" +); +const { EnigmailEncryption } = ChromeUtils.import( + "chrome://openpgp/content/modules/encryption.jsm" +); +const { OpenPGPAlias } = ChromeUtils.import( + "chrome://openpgp/content/modules/OpenPGPAlias.jsm" +); + +const { OpenPGPTestUtils } = ChromeUtils.import( + "resource://testing-common/mozmill/OpenPGPTestUtils.jsm" +); + +const keyDir = "../../../../../test/browser/openpgp/data/keys"; +const mailNewsDir = "../../../../../../mailnews/test/data"; + +// Alice's key: EB85BB5FA33A75E15E944E63F231550C4F47E38E +// Bob's key: D1A66E1A23B182C9980F788CFBFCC82A015E7330 +// Carol's key: B8F2F6F4BD3AD3F82DC446833099FF1238852B9F + +const tests = [ + { + info: "Should find Alice's key directly", + filename: undefined, + to: "alice@openpgp.example", + expectedMissing: false, + expectedAliasKeys: null, + }, + { + info: "Key absent, no alias defined for address", + filename: `${mailNewsDir}/alias-1.json`, + to: "nobody@openpgp.example", + expectedMissing: true, + expectedAliasKeys: null, + }, + { + info: "File maps Alice's address to Bob's (id) and Carol's (fingerprint) keys", + filename: `${mailNewsDir}/alias-1.json`, + to: "alice@openpgp.example", + expectedMissing: false, + expectedAliasKeys: [ + "D1A66E1A23B182C9980F788CFBFCC82A015E7330", + "B8F2F6F4BD3AD3F82DC446833099FF1238852B9F", + ], + }, + { + info: "File maps Alice's address to an absent key", + filename: `${mailNewsDir}/alias-2.json`, + to: "alice@openpgp.example", + expectedMissing: true, + expectedAliasKeys: null, + }, + { + info: "File maps Alice's address to Alice's key (unnecessary alias)", + filename: `${mailNewsDir}/alias-3.json`, + to: "alice@openpgp.example", + expectedMissing: false, + expectedAliasKeys: ["EB85BB5FA33A75E15E944E63F231550C4F47E38E"], + }, + { + info: "File maps an address to several keys, all available", + filename: `${mailNewsDir}/alias-4.json`, + to: "nobody@example.com", + expectedMissing: false, + expectedAliasKeys: [ + "EB85BB5FA33A75E15E944E63F231550C4F47E38E", + "D1A66E1A23B182C9980F788CFBFCC82A015E7330", + "B8F2F6F4BD3AD3F82DC446833099FF1238852B9F", + ], + }, + { + info: "File maps an address to several keys, one not available", + filename: `${mailNewsDir}/alias-5.json`, + to: "nobody@example.com", + expectedMissing: true, + expectedAliasKeys: null, + }, + { + info: "File maps the domain to Carol's key", + filename: `${mailNewsDir}/alias-6.json`, + to: "someone@example.com", + expectedMissing: false, + expectedAliasKeys: ["B8F2F6F4BD3AD3F82DC446833099FF1238852B9F"], + }, + { + info: "Multiple rules, should match domain1 rule", + filename: `${mailNewsDir}/alias-7.json`, + to: "someone@domain1.example.com", + expectedMissing: false, + expectedAliasKeys: ["EB85BB5FA33A75E15E944E63F231550C4F47E38E"], + }, + { + info: "Multiple rules, should match domain2 rule", + filename: `${mailNewsDir}/alias-7.json`, + to: "contact@domain2.example.com", + expectedMissing: false, + expectedAliasKeys: ["D1A66E1A23B182C9980F788CFBFCC82A015E7330"], + }, + { + info: "Multiple rules, should match email contact@domain1 rule", + filename: `${mailNewsDir}/alias-7.json`, + to: "contact@domain1.example.com", + expectedMissing: false, + expectedAliasKeys: [ + "D1A66E1A23B182C9980F788CFBFCC82A015E7330", + "EB85BB5FA33A75E15E944E63F231550C4F47E38E", + ], + }, + { + info: "Multiple rules, shouldn't match", + filename: `${mailNewsDir}/alias-7.json`, + to: "contact@domain2.example", + expectedMissing: true, + expectedAliasKeys: null, + }, + { + info: "Mixed case test a", + filename: `${mailNewsDir}/alias-8.json`, + to: "a@UPPERDOM.EXAMPLE", + expectedMissing: false, + expectedAliasKeys: ["EB85BB5FA33A75E15E944E63F231550C4F47E38E"], + }, + { + info: "Mixed case test b", + filename: `${mailNewsDir}/alias-8.json`, + to: "b@lowerdom.example", + expectedMissing: false, + expectedAliasKeys: ["D1A66E1A23B182C9980F788CFBFCC82A015E7330"], + }, + { + info: "Mixed case test c", + filename: `${mailNewsDir}/alias-8.json`, + to: "C@MIXed.EXample", + expectedMissing: false, + expectedAliasKeys: ["B8F2F6F4BD3AD3F82DC446833099FF1238852B9F"], + }, + { + info: "Mixed case test d", + filename: `${mailNewsDir}/alias-13.json`, + to: "NAME@DOMAIN.NET", + expectedMissing: false, + expectedAliasKeys: ["D1A66E1A23B182C9980F788CFBFCC82A015E7330"], + }, + { + info: "Mixed case test e", + filename: `${mailNewsDir}/alias-14.json`, + to: "name@domain.net", + expectedMissing: false, + expectedAliasKeys: ["D1A66E1A23B182C9980F788CFBFCC82A015E7330"], + }, + { + info: "Mixed case test f", + filename: `${mailNewsDir}/alias-15.json`, + to: "name@domain.net", + expectedMissing: false, + expectedAliasKeys: ["D1A66E1A23B182C9980F788CFBFCC82A015E7330"], + }, + { + info: "JSON with bad syntax, should find Alice's key directly", + filename: `${mailNewsDir}/alias-9.json`, + to: "alice@openpgp.example", + expectedMissing: false, + expectedAliasKeys: null, + expectException: true, + }, + { + info: "JSON with missing keys entry, should find Alice's key directly", + filename: `${mailNewsDir}/alias-10.json`, + to: "alice@openpgp.example", + expectedMissing: false, + expectedAliasKeys: null, + }, + { + info: "JSON with empty keys entry, should find Alice's key directly", + filename: `${mailNewsDir}/alias-11.json`, + to: "alice@openpgp.example", + expectedMissing: false, + expectedAliasKeys: null, + }, + { + info: "JSON with bad type keys entry, should find Alice's key directly", + filename: `${mailNewsDir}/alias-12.json`, + to: "alice@openpgp.example", + expectedMissing: false, + expectedAliasKeys: null, + }, +]; + +/** + * Initialize OpenPGP add testing keys. + */ +add_setup(async function () { + do_get_profile(); + + await OpenPGPTestUtils.initOpenPGP(); + + await OpenPGPTestUtils.importPublicKey( + null, + do_get_file(`${keyDir}/alice@openpgp.example-0xf231550c4f47e38e-pub.asc`) + ); + + await OpenPGPTestUtils.importPublicKey( + null, + do_get_file(`${keyDir}/bob@openpgp.example-0xfbfcc82a015e7330-pub.asc`) + ); + + await OpenPGPTestUtils.importPublicKey( + null, + do_get_file(`${keyDir}/carol@example.com-0x3099ff1238852b9f-pub.asc`) + ); +}); + +add_task(async function testAlias() { + let aliasFilename = "openpgp-alias-rules.json"; + let profileDir = Services.dirsvc.get("ProfD", Ci.nsIFile); + + for (let test of tests) { + if (test.filename) { + info(`Running alias test with rules from: ${test.filename}`); + + // Copy test file to profile directory (which is a relative path), + // because load function only works with simple filenames + // or absolute file URLs. + + let inFile = do_get_file(test.filename); + inFile.copyTo(profileDir, aliasFilename); + + try { + await OpenPGPAlias._loadFromFile(aliasFilename); + Assert.ok( + !("expectException" in test) || !test.expectException, + "expected no load exception" + ); + } catch (ex) { + console.log( + "exception when loading alias file " + aliasFilename + " : " + ex + ); + Assert.ok( + "expectException" in test && test.expectException, + "expected load exception" + ); + } + } else { + info(`Running alias test without rules`); + OpenPGPAlias._clear(); + } + info(test.info); + + let addresses = [test.to]; + let resultDetails = {}; + + let isMissing = await EnigmailKeyRing.getValidKeysForAllRecipients( + addresses, + resultDetails + ); + + Assert.ok( + (isMissing && test.expectedMissing) || + (!isMissing && !test.expectedMissing), + "Should have the expected result from getValidKeysForAllRecipients" + ); + + if (isMissing || test.expectedMissing) { + continue; + } + + let errorMsgObj = { value: "" }; + let logFileObj = {}; + let encryptArgs = EnigmailEncryption.getCryptParams( + "", + test.to, + "", + "SHA256", + EnigmailConstants.SEND_ENCRYPTED, + 0, + errorMsgObj, + logFileObj + ); + + let foundAliasKeys = encryptArgs.aliasKeys.get(test.to.toLowerCase()); + + if (!test.expectedAliasKeys) { + Assert.ok(!foundAliasKeys, "foundAliasKeys should be empty"); + } else { + Assert.equal(foundAliasKeys.length, test.expectedAliasKeys.length); + + test.expectedAliasKeys.forEach((val, i) => { + Assert.ok(foundAliasKeys.includes(val)); + }); + + let encryptResult = {}; + let encrypted = await RNP.encryptAndOrSign( + "plaintext", + encryptArgs, + encryptResult + ); + + Assert.ok( + !encryptResult.exitCode, + "RNP.encryptAndOrSign() should exit ok" + ); + + Assert.ok(encrypted.includes("END PGP MESSAGE")); + } + } +}); diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/test_badKeys.js b/comm/mail/extensions/openpgp/test/unit/rnp/test_badKeys.js new file mode 100644 index 0000000000..3ca7709dc6 --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/test_badKeys.js @@ -0,0 +1,69 @@ +/* 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 bad OpenPGP keys. + */ + +"use strict"; + +const { RNP } = ChromeUtils.import("chrome://openpgp/content/modules/RNP.jsm"); +const { EnigmailConstants } = ChromeUtils.import( + "chrome://openpgp/content/modules/constants.jsm" +); +const { EnigmailKeyRing } = ChromeUtils.import( + "chrome://openpgp/content/modules/keyRing.jsm" +); +const { EnigmailEncryption } = ChromeUtils.import( + "chrome://openpgp/content/modules/encryption.jsm" +); +const { OpenPGPAlias } = ChromeUtils.import( + "chrome://openpgp/content/modules/OpenPGPAlias.jsm" +); +const { OpenPGPTestUtils } = ChromeUtils.import( + "resource://testing-common/mozmill/OpenPGPTestUtils.jsm" +); + +const KEY_DIR = "../../../../../test/browser/openpgp/data/keys"; + +add_setup(async function () { + do_get_profile(); + + await OpenPGPTestUtils.initOpenPGP(); +}); + +// Attempt to import a key with a single user ID, which is invalid, +// because it doesn't have a valid signature. +// Our code should reject the attempt to import the key. +add_task(async function testFailToImport() { + let ids = await OpenPGPTestUtils.importKey( + null, + do_get_file(`${KEY_DIR}/invalid-pubkey-nosigs.pgp`), + true + ); + Assert.ok(!ids.length, "importKey should return empty list of imported keys"); +}); + +// Import a key with two encryption subkeys. One is good, the other one +// has an invalid signature. When attempting to encrypt, our code should +// skip the bad subkey, and should use the expected good subkey. +add_task(async function testAvoidBadSubkey() { + let ids = await OpenPGPTestUtils.importKey( + null, + do_get_file(`${KEY_DIR}/encryption-subkey-bad.pgp`), + true + ); + await OpenPGPTestUtils.updateKeyIdAcceptance( + ids, + OpenPGPTestUtils.ACCEPTANCE_VERIFIED + ); + + let primaryKey = await RNP.findKeyByEmail( + "<encryption-subkey@example.org>", + true + ); + let encSubKey = RNP.getSuitableSubkey(primaryKey, "encrypt"); + let keyId = RNP.getKeyIDFromHandle(encSubKey); + Assert.ok(keyId == "BC63472A109D5859", "should obtain key ID of good subkey"); +}); diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/test_encryptAndOrSign.js b/comm/mail/extensions/openpgp/test/unit/rnp/test_encryptAndOrSign.js new file mode 100644 index 0000000000..a52911d288 --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/test_encryptAndOrSign.js @@ -0,0 +1,278 @@ +/* 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 RNP.encryptAndOrSign(). + */ + +"use strict"; + +const { RNP } = ChromeUtils.import("chrome://openpgp/content/modules/RNP.jsm"); +const { EnigmailConstants } = ChromeUtils.import( + "chrome://openpgp/content/modules/constants.jsm" +); + +const { OpenPGPTestUtils } = ChromeUtils.import( + "resource://testing-common/mozmill/OpenPGPTestUtils.jsm" +); + +const keyDir = "../../../../../test/browser/openpgp/data/keys"; +const mailNewsDir = "../../../../../../mailnews/test/data"; + +const tests = [ + // Base64 encoded bodies. + { + filename: `${mailNewsDir}/01-plaintext.eml`, + }, + { + filename: `${mailNewsDir}/02-plaintext+attachment.eml`, + }, + { + filename: `${mailNewsDir}/03-HTML.eml`, + }, + { + filename: `${mailNewsDir}/04-HTML+attachment.eml`, + }, + { + filename: `${mailNewsDir}/05-HTML+embedded-image.eml`, + }, + { + filename: `${mailNewsDir}/06-plaintext+HMTL.eml`, + }, + { + filename: `${mailNewsDir}/07-plaintext+(HTML+embedded-image).eml`, + }, + { + filename: `${mailNewsDir}/08-plaintext+HTML+attachment.eml`, + }, + { + filename: `${mailNewsDir}/09-(HTML+embedded-image)+attachment.eml`, + }, + { + filename: `${mailNewsDir}/10-plaintext+(HTML+embedded-image)+attachment.eml`, + }, + + // Bodies with non-ASCII characters in UTF-8 and other charsets. + { + filename: `${mailNewsDir}/11-plaintext.eml`, + skip: true, + }, + // using ISO-8859-7 (Greek) + { + filename: `${mailNewsDir}/12-plaintext+attachment.eml`, + encoding: "iso-8859-7", + skip: true, + }, + { + filename: `${mailNewsDir}/13-HTML.eml`, + skip: true, + }, + { + filename: `${mailNewsDir}/14-HTML+attachment.eml`, + skip: true, + }, + { + filename: `${mailNewsDir}/15-HTML+embedded-image.eml`, + skip: true, + }, + // text part is base64 encoded + { + filename: `${mailNewsDir}/16-plaintext+HMTL.eml`, + skip: true, + }, + // HTML part is base64 encoded + { + filename: `${mailNewsDir}/17-plaintext+(HTML+embedded-image).eml`, + skip: true, + }, + { + filename: `${mailNewsDir}/18-plaintext+HTML+attachment.eml`, + skip: true, + }, + { + filename: `${mailNewsDir}/19-(HTML+embedded-image)+attachment.eml`, + skip: true, + }, + // using windows-1252 + { + filename: `${mailNewsDir}/20-plaintext+(HTML+embedded-image)+attachment.eml`, + encoding: "windows-1252", + skip: true, + }, + + // Bodies with non-ASCII characters in UTF-8 and other charsets, all encoded + // with quoted printable. + { + filename: `${mailNewsDir}/21-plaintext.eml`, + }, + // using ISO-8859-7 (Greek) + { + filename: `${mailNewsDir}/22-plaintext+attachment.eml`, + encoding: "iso-8859-7", + }, + { + filename: `${mailNewsDir}/23-HTML.eml`, + }, + { + filename: `${mailNewsDir}/24-HTML+attachment.eml`, + }, + { + filename: `${mailNewsDir}/25-HTML+embedded-image.eml`, + }, + // text part is base64 encoded + { + filename: `${mailNewsDir}/26-plaintext+HMTL.eml`, + }, + // HTML part is base64 encoded + { + filename: `${mailNewsDir}/27-plaintext+(HTML+embedded-image).eml`, + }, + { + filename: `${mailNewsDir}/28-plaintext+HTML+attachment.eml`, + }, + { + filename: `${mailNewsDir}/29-(HTML+embedded-image)+attachment.eml`, + }, + // using windows-1252 + { + filename: `${mailNewsDir}/30-plaintext+(HTML+embedded-image)+attachment.eml`, + encoding: "windows-1252", + }, + + // Bug 1669107 + { + filename: + "data/plaintext-with-key-and-windows-1252-encoded-eml-attachment.eml", + encoding: "windows-1252", + skip: true, + }, + { + filename: "data/plaintext-with-windows-1252-encoded-eml-attachment.eml", + encoding: "windows-1252", + skip: true, + }, +]; + +/** + * Initialize OpenPGP add testing keys. + */ +add_setup(async function () { + do_get_profile(); + + await OpenPGPTestUtils.initOpenPGP(); + + await OpenPGPTestUtils.importPrivateKey( + null, + do_get_file(`${keyDir}/bob@openpgp.example-0xfbfcc82a015e7330-secret.asc`) + ); + + await OpenPGPTestUtils.importPublicKey( + null, + do_get_file(`${keyDir}/alice@openpgp.example-0xf231550c4f47e38e-pub.asc`) + ); +}); + +/** + * Test the decrypted output of RNP.encryptOrSign() against its source text + * with various inputs. + */ +add_task(async function testEncryptAndOrSignResults() { + for (let test of tests) { + let chunks = test.filename.split("/"); + let filename = chunks[chunks.length - 1]; + if (test.skip) { + info(`Skipped input from: ${filename}`); + continue; + } + + info(`Running test with input from: ${filename}`); + + let buffer = await IOUtils.read(do_get_file(test.filename).path); + const textDecoder = new TextDecoder(test.encoding || "utf-8"); + + let sourceText = textDecoder.decode(buffer); + let encryptResult = {}; + + let encryptArgs = { + aliasKeys: new Map(), + armor: true, + bcc: [], + encrypt: true, + encryptToSender: true, + sender: "0xFBFCC82A015E7330", + senderKeyIsExternal: false, + sigTypeClear: false, + sigTypeDetached: false, + sign: false, + signatureHash: "SHA256", + to: ["<alice@openpgp.example>"], + }; + + let encrypted = await RNP.encryptAndOrSign( + sourceText, + encryptArgs, + encryptResult + ); + + Assert.ok( + !encryptResult.exitCode, + `${filename}: RNP.encryptAndOrSign() exited ok` + ); + + let decryptOptions = { + fromAddr: "bob@openpgp.example", + maxOutputLength: encrypted.length * 100, + noOutput: false, + uiFlags: EnigmailConstants.UI_PGP_MIME, + verifyOnly: false, + msgDate: null, + }; + + let { exitCode, decryptedData } = await RNP.decrypt( + encrypted, + decryptOptions + ); + + Assert.ok(!exitCode, `${filename}: RNP.decrypt() exited ok`); + + Assert.equal( + sourceText, + decryptedData, + `${filename}: source text and decrypted text should be the same` + ); + } +}); + +/** + * Test that we correctly produce binary files when decrypting, + * for both binary OpenPGP input and ASCII armored OpenPGP input. + * + * Image source: openclipart.org (public domain) + * https://openclipart.org/detail/191741/blue-bird + */ +add_task(async function testDecryptAttachment() { + let expected = String.fromCharCode( + ...(await IOUtils.read(do_get_file("data/bluebird50.jpg").path)) + ); + + for (let filename of ["data/bluebird50.jpg.asc", "data/bluebird50.jpg.gpg"]) { + let encrypted = String.fromCharCode( + ...(await IOUtils.read(do_get_file(filename).path)) + ); + let options = {}; + options.fromAddr = ""; + options.msgDate = null; + let result = await RNP.decrypt(encrypted, options); + + Assert.ok(!result.exitCode, `${filename}: RNP.decrypt() exited ok`); + + // Don't use Assert.equal to avoid logging the raw binary data + let isEqual = expected === result.decryptedData; + + Assert.ok( + isEqual, + `${filename}: decrypted data should match the expected binary file` + ); + } +}); diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/test_secretKeys.js b/comm/mail/extensions/openpgp/test/unit/rnp/test_secretKeys.js new file mode 100644 index 0000000000..772c5caae4 --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/test_secretKeys.js @@ -0,0 +1,384 @@ +/* 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 secret keys. + */ + +"use strict"; + +const { RNP, RnpPrivateKeyUnlockTracker } = ChromeUtils.import( + "chrome://openpgp/content/modules/RNP.jsm" +); +const { OpenPGPMasterpass } = ChromeUtils.import( + "chrome://openpgp/content/modules/masterpass.jsm" +); +const { EnigmailConstants } = ChromeUtils.import( + "chrome://openpgp/content/modules/constants.jsm" +); +const { EnigmailKeyRing } = ChromeUtils.import( + "chrome://openpgp/content/modules/keyRing.jsm" +); +const { FileUtils } = ChromeUtils.importESModule( + "resource://gre/modules/FileUtils.sys.mjs" +); +const { OpenPGPTestUtils } = ChromeUtils.import( + "resource://testing-common/mozmill/OpenPGPTestUtils.jsm" +); + +const keyDir = "../../../../../test/browser/openpgp/data/keys"; + +/** + * Initialize OpenPGP add testing keys. + */ +add_setup(async function () { + do_get_profile(); + + await OpenPGPTestUtils.initOpenPGP(); +}); + +add_task(async function testSecretKeys() { + let pass = await OpenPGPMasterpass.retrieveOpenPGPPassword(); + let newKeyId = await RNP.genKey( + "Erin <erin@example.com>", + "ECC", + 0, + 30, + pass + ); + + Assert.ok( + newKeyId != null && typeof newKeyId == "string", + "RNP.genKey() should return a non null string with a key ID" + ); + + let keyObj = EnigmailKeyRing.getKeyById(newKeyId); + Assert.ok( + keyObj && keyObj.secretAvailable, + "EnigmailKeyRing.getKeyById should return an object with a secret key" + ); + + let fpr = keyObj.fpr; + + Assert.ok( + keyObj.iSimpleOneSubkeySameExpiry(), + "check iSimpleOneSubkeySameExpiry should succeed" + ); + + let allFingerprints = [fpr, keyObj.subKeys[0].fpr]; + + let keyTrackers = []; + for (let fp of allFingerprints) { + let tracker = RnpPrivateKeyUnlockTracker.constructFromFingerprint(fp); + await tracker.unlock(); + keyTrackers.push(tracker); + } + + let expiryChanged = await RNP.changeExpirationDate( + allFingerprints, + 100 * 24 * 60 * 60 + ); + Assert.ok(expiryChanged, "changeExpirationDate should return success"); + + for (let t of keyTrackers) { + t.release(); + } + + let backupPassword = "new-password-1234"; + + let backupKeyBlock = await RNP.backupSecretKeys([fpr], backupPassword); + + let expectedString = "END PGP PRIVATE KEY BLOCK"; + + Assert.ok( + backupKeyBlock.includes(expectedString), + "backup of secret key should contain the string: " + expectedString + ); + + await RNP.deleteKey(fpr, true); + + EnigmailKeyRing.clearCache(); + + keyObj = EnigmailKeyRing.getKeyById(newKeyId); + Assert.ok( + !keyObj, + "after deleting the key we should be unable to find it in the keyring" + ); + + let alreadyProvidedWrongPassword = false; + + let getWrongPassword = function (win, keyId, resultFlags) { + if (alreadyProvidedWrongPassword) { + resultFlags.canceled = true; + return ""; + } + + alreadyProvidedWrongPassword = true; + return "wrong-password"; + }; + + let importResult = await RNP.importSecKeyBlockImpl( + null, + getWrongPassword, + false, + backupKeyBlock + ); + + Assert.ok(importResult.exitCode != 0, "import should have failed"); + + let getGoodPassword = function (win, keyId, resultFlags) { + return backupPassword; + }; + + importResult = await RNP.importSecKeyBlockImpl( + null, + getGoodPassword, + false, + backupKeyBlock + ); + + Assert.ok(importResult.exitCode == 0, "import result code should be 0"); + + keyObj = EnigmailKeyRing.getKeyById(newKeyId); + + Assert.ok( + keyObj && keyObj.secretAvailable, + "after import, EnigmailKeyRing.getKeyById should return an object with a secret key" + ); +}); + +add_task(async function testImportSecretKeyIsProtected() { + let carolFile = do_get_file( + `${keyDir}/carol@example.com-0x3099ff1238852b9f-secret.asc` + ); + let carolSec = await IOUtils.readUTF8(carolFile.path); + + // Carol's secret key is protected with password "x". + let getCarolPassword = function (win, keyId, resultFlags) { + return "x"; + }; + + let importResult = await RNP.importSecKeyBlockImpl( + null, + getCarolPassword, + false, + carolSec + ); + + Assert.equal( + importResult.exitCode, + 0, + "Should be able to import Carol's secret key" + ); + + let aliceFile = do_get_file( + `${keyDir}/alice@openpgp.example-0xf231550c4f47e38e-secret.asc` + ); + let aliceSec = await IOUtils.readUTF8(aliceFile.path); + + // Alice's secret key is unprotected. + importResult = await RNP.importSecKeyBlockImpl(null, null, false, aliceSec); + + Assert.equal( + importResult.exitCode, + 0, + "Should be able to import Alice's secret key" + ); + + let [prot, unprot] = OpenPGPTestUtils.getProtectedKeysCount(); + Assert.notEqual(prot, 0, "Should have protected secret keys"); + Assert.equal(unprot, 0, "Should not have any unprotected secret keys"); +}); + +add_task(async function testImportOfflinePrimaryKey() { + let importResult = await OpenPGPTestUtils.importPrivateKey( + null, + do_get_file(`${keyDir}/ofelia-secret-subkeys.asc`) + ); + + Assert.equal( + importResult[0], + "0x97DCDA5E56EBB822", + "expected key id should have been reported" + ); + + let primaryKey = await RNP.findKeyByEmail("<ofelia@openpgp.example>", false); + + let encSubKey = RNP.getSuitableSubkey(primaryKey, "encrypt"); + let keyId = RNP.getKeyIDFromHandle(encSubKey); + Assert.equal( + keyId, + "31C31DF1DFB67601", + "should obtain key ID of encryption subkey" + ); + + let sigSubKey = RNP.getSuitableSubkey(primaryKey, "sign"); + let keyIdSig = RNP.getKeyIDFromHandle(sigSubKey); + Assert.equal( + keyIdSig, + "1BC8F5764D348FE1", + "should obtain key ID of signing subkey" + ); + + // Test that we can sign with a signing subkey + // (this ensures that our code can unlock the secret subkey). + // Ofelia's key has no secret key for the primary key available, + // which further ensures that signing used the subkey. + + let sourceText = "we-sign-this-text"; + let signResult = {}; + + let signArgs = { + aliasKeys: new Map(), + armor: true, + bcc: [], + encrypt: false, + encryptToSender: false, + sender: "0x97DCDA5E56EBB822", + senderKeyIsExternal: false, + sigTypeClear: true, + sigTypeDetached: false, + sign: true, + signatureHash: "SHA256", + to: ["<alice@openpgp.example>"], + }; + + await RNP.encryptAndOrSign(sourceText, signArgs, signResult); + + Assert.ok(!signResult.exitCode, "signing with subkey should work"); +}); + +add_task(async function testSecretForPreferredSignSubkeyIsMissing() { + let secBlock = await IOUtils.readUTF8( + do_get_file( + `${keyDir}/secret-for-preferred-sign-subkey-is-missing--a-without-second-sub--sec.asc` + ).path + ); + + let cancelPassword = function (win, keyId, resultFlags) { + resultFlags.canceled = true; + return ""; + }; + + let importResult = await RNP.importSecKeyBlockImpl( + null, + cancelPassword, + false, + secBlock + ); + + Assert.ok(importResult.exitCode == 0); + + let pubBlock = await IOUtils.readUTF8( + do_get_file( + `${keyDir}/secret-for-preferred-sign-subkey-is-missing--b-with-second-sub--pub.asc` + ).path + ); + + importResult = await RNP.importPubkeyBlockAutoAcceptImpl( + null, + pubBlock, + null // acceptance + ); + + Assert.ok(importResult.exitCode == 0); + + let primaryKey = await RNP.findKeyByEmail( + "<secret-for-preferred-sign-subkey-is-missing@example.com>", + false + ); + + let signSubKey = RNP.getSuitableSubkey(primaryKey, "sign"); + let keyId = RNP.getKeyIDFromHandle(signSubKey); + Assert.equal( + keyId, + "625D4819F02EE727", + "should obtain key ID of older, non-preferred subkey that has the secret key available" + ); +}); + +// If we an existing public key, with multiple subkeys, and then we +// import the secret key, but one of the existing public subkeys is +// missing, test that we don't fail to import (bug 1795698). +add_task(async function testNoSecretForExistingPublicSubkey() { + let pubBlock = await IOUtils.readUTF8( + do_get_file(`${keyDir}/two-enc-subkeys-still-both.pub.asc`).path + ); + + let importResult = await RNP.importPubkeyBlockAutoAcceptImpl( + null, + pubBlock, + null // acceptance + ); + + Assert.ok(importResult.exitCode == 0); + + let secBlock = await IOUtils.readUTF8( + do_get_file(`${keyDir}/two-enc-subkeys-one-deleted.sec.asc`).path + ); + + let cancelPassword = function (win, keyId, resultFlags) { + resultFlags.canceled = true; + return ""; + }; + + importResult = await RNP.importSecKeyBlockImpl( + null, + cancelPassword, + false, + secBlock + ); + + Assert.ok(importResult.exitCode == 0); +}); + +add_task(async function testImportAndBackupUntweakedECCKey() { + const untweakedFile = do_get_file(`${keyDir}/untweaked-secret.asc`); + const untweakedSecKey = await IOUtils.readUTF8(untweakedFile.path); + + const getGoodPasswordForTweaked = function (win, keyId, resultFlags) { + return "pass112233"; + }; + + const importResult = await RNP.importSecKeyBlockImpl( + null, + getGoodPasswordForTweaked, + false, + untweakedSecKey + ); + + Assert.ok(importResult.exitCode == 0); + const fpr = "492965A6F56DAD2423B3506E849F29B0020707F7"; + + const backupPassword = "new-password-1234"; + const backupKeyBlock = await RNP.backupSecretKeys([fpr], backupPassword); + const expectedString = "END PGP PRIVATE KEY BLOCK"; + + Assert.ok( + backupKeyBlock.includes(expectedString), + "backup of secret key should contain the string: " + expectedString + ); + + await RNP.deleteKey(fpr, true); + + EnigmailKeyRing.clearCache(); +}); + +// Sanity check for bug 1790610 and bug 1792450, test that our passphrase +// reading code, which can run through repair code for corrupted profiles, +// will not replace our existing and good data. +// Ideally this test should restart the application, but is is difficult. +// We simulate a restart by erasing the cache and forcing it to read +// data again from disk (which will run the consistency checks and +// could potentially execute the repair code). +add_task(async function testRereadingPassphrase() { + let pass1 = await OpenPGPMasterpass.retrieveOpenPGPPassword(); + OpenPGPMasterpass.cachedPassword = null; + let pass2 = await OpenPGPMasterpass.retrieveOpenPGPPassword(); + Assert.equal( + pass1, + pass2, + "openpgp passphrase should remain the same after cache invalidation" + ); +}); diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/test_strip.js b/comm/mail/extensions/openpgp/test/unit/rnp/test_strip.js new file mode 100644 index 0000000000..4260921ef2 --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/test_strip.js @@ -0,0 +1,137 @@ +/* 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 stripping keys. + */ + +"use strict"; + +const { RNP } = ChromeUtils.import("chrome://openpgp/content/modules/RNP.jsm"); +const { EnigmailKeyRing } = ChromeUtils.import( + "chrome://openpgp/content/modules/keyRing.jsm" +); +const { OpenPGPTestUtils } = ChromeUtils.import( + "resource://testing-common/mozmill/OpenPGPTestUtils.jsm" +); +const { MailStringUtils } = ChromeUtils.import( + "resource:///modules/MailStringUtils.jsm" +); + +const keyDir = "../../../../../test/browser/openpgp/data/keys"; + +/** + * Initialize OpenPGP add testing keys. + */ +add_setup(async function () { + do_get_profile(); + + await OpenPGPTestUtils.initOpenPGP(); +}); + +add_task(async function testStripSignatures() { + await OpenPGPTestUtils.importPublicKey( + null, + do_get_file(`${keyDir}/heisenberg-signed-by-pinkman.asc`) + ); + + let heisenbergFpr = "8E3D32E652A254F05BEA9F66CF3EB4AFCAC29340"; + let foundKeys = await RNP.getKeys(["0x" + heisenbergFpr]); + + Assert.equal(foundKeys.length, 1); + + let sigs = RNP.getKeyObjSignatures(foundKeys[0]); + + // Signatures for one user ID + Assert.equal(sigs.length, 1); + + // The key in the file has two signatures: one self signature, + // plus one foreign certification signature. + Assert.equal(sigs[0].sigList.length, 2); + + let reducedKey = RNP.getMultiplePublicKeys([], ["0x" + heisenbergFpr], []); + + // Delete the key we have previously imported + await RNP.deleteKey(heisenbergFpr); + foundKeys = await RNP.getKeys(["0x" + heisenbergFpr]); + Assert.equal(foundKeys.length, 0); + + // Import the reduced key + let errorObj = {}; + let fingerPrintObj = {}; + let result = await EnigmailKeyRing.importKeyAsync( + null, + false, + reducedKey, + false, + null, + errorObj, + fingerPrintObj, + false, + [], + false + ); + Assert.equal(result, 0); + + foundKeys = await RNP.getKeys(["0x" + heisenbergFpr]); + Assert.equal(foundKeys.length, 1); + + sigs = RNP.getKeyObjSignatures(foundKeys[0]); + + // The imported stripped key should have only the self signature. + Assert.equal(sigs[0].sigList.length, 1); +}); + +add_task(async function testKeyWithUnicodeComment() { + let keyFile = do_get_file(`${keyDir}/key-with-utf8-comment.asc`); + let keyBlock = await IOUtils.readUTF8(keyFile.path); + + let errorObj = {}; + let fingerPrintObj = {}; + let result = await EnigmailKeyRing.importKeyAsync( + null, + false, + keyBlock, + false, + null, + errorObj, + fingerPrintObj, + false, + [], + false + ); + Assert.equal(result, 0); + + let fpr = "72514F43D0060FC588E80238852C55E6D2AFD7EF"; + let foundKeys = await RNP.getKeys(["0x" + fpr]); + + Assert.equal(foundKeys.length, 1); +}); + +add_task(async function testBinaryKey() { + let keyFile = do_get_file(`${keyDir}/key-binary.gpg`); + let keyData = await IOUtils.read(keyFile.path); + let keyBlock = MailStringUtils.uint8ArrayToByteString(keyData); + + let errorObj = {}; + let fingerPrintObj = {}; + let result = await EnigmailKeyRing.importKeyAsync( + null, + false, + keyBlock, + true, + null, + errorObj, + fingerPrintObj, + false, + [], + false + ); + Assert.equal(result, 0); + + let fpr = "683F775BA2E5F0ADEBB29697A2D1B914F722004E"; + let foundKeys = await RNP.getKeys(["0x" + fpr]); + + Assert.equal(foundKeys.length, 1); +}); diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/test_uid.js b/comm/mail/extensions/openpgp/test/unit/rnp/test_uid.js new file mode 100644 index 0000000000..b87e068e0d --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/test_uid.js @@ -0,0 +1,132 @@ +/* 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 OpenPGP encryption alias rules. + */ + +"use strict"; + +const { OpenPGPTestUtils } = ChromeUtils.import( + "resource://testing-common/mozmill/OpenPGPTestUtils.jsm" +); +const { EnigmailFuncs } = ChromeUtils.import( + "chrome://openpgp/content/modules/funcs.jsm" +); + +const tests = [ + { + input: "Cherry Blossom (桜の花) (description) <email@example.com>", + email: "email@example.com", + }, + { + input: + "Cherry Blossom (桜の花) (description) (more information) <email@example.com>", + email: "email@example.com", + }, + { + input: "First Last <email@example.com>", + email: "email@example.com", + }, + { + input: "Last, First <email@example.com>", + email: "email@example.com", + }, + { + input: "email@example.com", + email: "email@example.com", + }, + { + input: "<email@example.com>", + email: "email@example.com", + }, + { + input: "First Last email@example.com>", + email: "", + }, + { + input: "First Last (comment) <email@example.com>", + email: "email@example.com", + }, + { + input: "First Last (a) (b) (c) (comment) <email@example.com>", + email: "email@example.com", + }, + { + input: "First Last (comment <email@example.com>", + email: "email@example.com", + }, + { + input: "First Last )comment) <email@example.com>", + email: "email@example.com", + }, + { + input: "", + email: "", + }, + { + input: "First Last () <>", + email: "", + }, + { + input: "First Last () <> <> <>", + email: "", + }, + { + input: "First Last () <> <email1@example.com>", + email: "", + }, + { + input: "First <Last> (comment) <email1@example.com>", + email: "", + }, + { + input: "First Last <email@example.com> (bad comment)", + email: "email@example.com", + }, + { + input: "First Last <email@example.com> extra text", + email: "email@example.com", + }, + { + input: "First Last <not-an-email> extra text", + email: "", + }, + { + input: "First Last (comment (nested)) <email@example.com>", + email: "email@example.com", + }, + { + input: + "First Last (comment (no second closing bracket) <email@example.com>", + email: "email@example.com", + }, + { + input: "<a@example.org b@example.org>", + email: "", + }, + { + input: "<a@@example.org>", + email: "", + }, +]; + +/** + * Initialize OpenPGP add testing keys. + */ +add_setup(async function () { + do_get_profile(); + + await OpenPGPTestUtils.initOpenPGP(); +}); + +add_task(async function testAlias() { + for (let test of tests) { + console.debug("testing input: " + test.input); + + let email = EnigmailFuncs.getEmailFromUserID(test.input); + + Assert.equal(test.email, email); + } +}); diff --git a/comm/mail/extensions/openpgp/test/unit/rnp/xpcshell.ini b/comm/mail/extensions/openpgp/test/unit/rnp/xpcshell.ini new file mode 100644 index 0000000000..f0601aefae --- /dev/null +++ b/comm/mail/extensions/openpgp/test/unit/rnp/xpcshell.ini @@ -0,0 +1,14 @@ +[DEFAULT] +head = +tail = +support-files = + ../../../../../test/browser/openpgp/data/keys/* + ../../../../../../mailnews/test/data/* + data/* + +[test_encryptAndOrSign.js] +[test_secretKeys.js] +[test_alias.js] +[test_badKeys.js] +[test_uid.js] +[test_strip.js] |