/* globals tryTests: true */ const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../../dist/openpgp'); const sinon = require('sinon'); const chai = require('chai'); chai.use(require('chai-as-promised')); const expect = chai.expect; const pub_key = ['-----BEGIN PGP PUBLIC KEY BLOCK-----', 'Version: GnuPG v2.0.19 (GNU/Linux)', '', 'mI0EUmEvTgEEANyWtQQMOybQ9JltDqmaX0WnNPJeLILIM36sw6zL0nfTQ5zXSS3+', 'fIF6P29lJFxpblWk02PSID5zX/DYU9/zjM2xPO8Oa4xo0cVTOTLj++Ri5mtr//f5', 'GLsIXxFrBJhD/ghFsL3Op0GXOeLJ9A5bsOn8th7x6JucNKuaRB6bQbSPABEBAAG0', 'JFRlc3QgTWNUZXN0aW5ndG9uIDx0ZXN0QGV4YW1wbGUuY29tPoi5BBMBAgAjBQJS', 'YS9OAhsvBwsJCAcDAgEGFQgCCQoLBBYCAwECHgECF4AACgkQSmNhOk1uQJQwDAP6', 'AgrTyqkRlJVqz2pb46TfbDM2TDF7o9CBnBzIGoxBhlRwpqALz7z2kxBDmwpQa+ki', 'Bq3jZN/UosY9y8bhwMAlnrDY9jP1gdCo+H0sD48CdXybblNwaYpwqC8VSpDdTndf', '9j2wE/weihGp/DAdy/2kyBCaiOY1sjhUfJ1GogF49rC4jQRSYS9OAQQA6R/PtBFa', 'JaT4jq10yqASk4sqwVMsc6HcifM5lSdxzExFP74naUMMyEsKHP53QxTF0Grqusag', 'Qg/ZtgT0CN1HUM152y7ACOdp1giKjpMzOTQClqCoclyvWOFB+L/SwGEIJf7LSCEr', 'woBuJifJc8xAVr0XX0JthoW+uP91eTQ3XpsAEQEAAYkBPQQYAQIACQUCUmEvTgIb', 'LgCoCRBKY2E6TW5AlJ0gBBkBAgAGBQJSYS9OAAoJEOCE90RsICyXuqIEANmmiRCA', 'SF7YK7PvFkieJNwzeK0V3F2lGX+uu6Y3Q/Zxdtwc4xR+me/CSBmsURyXTO29OWhP', 'GLszPH9zSJU9BdDi6v0yNprmFPX/1Ng0Abn/sCkwetvjxC1YIvTLFwtUL/7v6NS2', 'bZpsUxRTg9+cSrMWWSNjiY9qUKajm1tuzPDZXAUEAMNmAN3xXN/Kjyvj2OK2ck0X', 'W748sl/tc3qiKPMJ+0AkMF7Pjhmh9nxqE9+QCEl7qinFqqBLjuzgUhBU4QlwX1GD', 'AtNTq6ihLMD5v1d82ZC7tNatdlDMGWnIdvEMCv2GZcuIqDQ9rXWs49e7tq1NncLY', 'hz3tYjKhoFTKEIq3y3Pp', '=h/aX', '-----END PGP PUBLIC KEY BLOCK-----'].join('\n'); const priv_key = ['-----BEGIN PGP PRIVATE KEY BLOCK-----', 'Version: GnuPG v2.0.19 (GNU/Linux)', '', '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', '=lw5e', '-----END PGP PRIVATE KEY BLOCK-----'].join('\n'); const pub_key_de = ['-----BEGIN PGP PUBLIC KEY BLOCK-----', 'Version: GnuPG v2.0.22 (GNU/Linux)', '', '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', 'og2umGfGng==', '=v3+L', '-----END PGP PUBLIC KEY BLOCK-----'].join('\n'); const priv_key_de = ['-----BEGIN PGP PRIVATE KEY BLOCK-----', 'Version: GnuPG v2.0.22 (GNU/Linux)', '', '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', 'DHTORVqAOdoOcu5Qh7AQg1GdSmfFAsx2', '=kyeP', '-----END PGP PRIVATE KEY BLOCK-----'].join('\n'); const priv_key_2000_2008 = `-----BEGIN PGP PRIVATE KEY BLOCK----- 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 t/ia1kMpSEiOVLlX5dfHZzhR3WNtBqU= =C0fJ -----END PGP PRIVATE KEY BLOCK-----`; const pub_key_2000_2008 = `-----BEGIN PGP PUBLIC KEY BLOCK----- xo0EOKg3aAEEALLlUS7z92VAc53Xa/y01jYCJz4L6TrLIp7t4dF/U+rB3R050yT7 QS8yLVn6LTH9xCPz217zUXtMKZV36qshZHqspz/pZDOD0VDSHVZArENiLMQjKJrR k0S5h3sXUfrJzHfna3KZ6kC2HTmLq3UvEjmMTEUOr53zPwvl7Or7/oFlABEBAAHN E3Rlc3QgPHRlc3RAZXhhbXBsZT7CrQQTAQoAFwUCOKg3aAIbLwMLCQcDFQoIAh4B AheAAAoJEFzwINOIu4R09q8EAIqd3AAl3W0oacbyhLELNKATdR+TwMdQQBl2p8Po 8QxVJKw5NQzkq2RZzGqIbqCa2MqBP0ZC89OtYPLRXPyhE5p8iQHFy/zz4nN7Twgr NXKYVQLAIxC7GMDy+FEKRZ0VNnvqYYM1/TPxu/ML6ojhnDPytEmU58kb2GgBx7ix RNsZzo0EOKg3aAEEALOt5AUdDf7fz0DwOkIokGj4zeiFuphsTPwpRAS6c1o9xAzS /C8hLFShhTKL4Z9znYkdaMHuFIs7AJ3P5tKlvG0/cZAl3u286lz0aTtQluHMCKNy UyhuZ0K1VgZOj+HcDKo8jQ+aejcwjHDg02yPvfzrXHBjWAJMjglV4W+YPFYjABEB AAHCwIMEGAEKAA8FAjioN2gFCQ8JnAACGy4AqAkQXPAg04i7hHSdIAQZAQoABgUC OKg3aAAKCRDh8+Pj74TEoHURA/4+mbmGa/ZzTjzfrAxceOMIhfV+wGEk1J5Y1mWP E85w+BvSQB3aFjVL9Wf1kOiB5iYMFRD8kePjYR11rYhhrH/vh0DBRNXYqcOx0FPx Nv2WMedjcYzsmoQqL+7T27tl/Crdq5EMfxFb+FEdDTnx1+RKiiuk3mIJR/Ngl6Yz hmYDs08LA/4+xDre4g+YMHj0zaxDBXUawFz5gH5oPeGCCxG/tQeHiC+vYYJy6RGU cOL+k4Q79lNqjJK6febtvYziffVsSPWWSdkG0xkujS5bDDpikBATAUVeFVwA5hCo 5vYp8XWskYHrDXS2ald01abkk8A27pGppcjOS4xxFSqVhw0t/PpJQc6NBDioN2gB BAC30PxDScc8m4HSi0AYRfETd8W9VfA4mBbX4A5G6Gr44kg+z1RAzTtvOnC6Hv7g JBPg4JtqBBZmfyCUoV/gS9SZB63jSrlk1tBs9I5KmGxOOCrLMucsAl3NCLVuMqzL Wm1zyOc6l83j3fRcKe2TrfEDf41Pk1HxlDMBL9rQyqv/uwARAQABwsCDBBgBCgAP BQI4qDdoBQkPCZwAAhsuAKgJEFzwINOIu4R0nSAEGQEKAAYFAjioN2gACgkQJVG+ vfNJQKhK6gP+LB5qXTJKCduuqZm7VhFvPeOu4W0pyORo29zZI0owKZnD2ZKZrZhK XZC/1+xKXi8aX4V2ygRth2P1tGFLJRqRiA3C20NVewdI4tQtEqWWSlfNFDz4EsbN spyodQ4jPsKPk2R8pFjAwmpXLizPg2UyPKUJ/2GnNWjleP0UNyUXgD1MkgP+IkxX TYgDF5/LrOlrq7ThWqFqQ/prQCBy7xxNLjpVKLDxGYbXVER6p0pkD6DXlaOgSB3i 32dQJnU96l44TlUyaUK/dJP7JPbVUOFq/awSxJiCxFxF6Oarc10qQ+OG5ESdJAjp CMHGCzlbt/ia1kMpSEiOVLlX5dfHZzhR3WNtBqU= =kwK1 -----END PGP PUBLIC KEY BLOCK-----`; const priv_key_2038_2045 = `-----BEGIN PGP PRIVATE KEY BLOCK----- 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 0uyeibPdgJTjARMuQzDFA8bdbM540vBf5Q== =WLIN -----END PGP PRIVATE KEY BLOCK-----`; const pub_key_2038_2045 = `-----BEGIN PGP PUBLIC KEY BLOCK----- xo0Ef+gZTwEEAKKWRh6fq/GvUsCGpZzQdpL7MySN40P8/0Q14+g1FWjcGrwotpyr WlAWK0lVxRrPoPmWTTC2KNJZv+5RKHohbqV1Vi+yMd1OkZiofe8smylhfMHNPqxe qG35x5A+Lmkikv9fnbjRZ5pBC0PRqt5xUC2a2Cs3nAn/dKjyWWqZ/yrRABEBAAHN FmV4YW1wbGUgPHRlc3RAZXhhbXBsZT7CrQQTAQoAFwUCf+gZTwIbLwMLCQcDFQoI Ah4BAheAAAoJEHSimBgePDrrKzoD/2e/hfwT+K59Ag8j4F5l74/hAGBdm0VhW8Vh j7PCjrmvV77gDtVyUAguzIMfw/Lf+y3y2J+JE8xGyhU/92bTc5e+D5f0JQ2aqHZk /IBREg3dNS7C+fZiNDvc8O4D+0WZH7Yhb3jhr0+DrP0rzs3aVxhlgH8rR7aMZsQ6 uuoM7mVDzo0Ef+gZTwEEAK0pLhDM5pDxWVfuVFssIdbWhClxlN9ZGhjGM27vf5QE 0YAluhlv5BTtLU3pYtQYScJksNAFYmENtufWU+c4fv4HHSTGXsW5baw8Ix1vFasr Aa9atZWBZklQVt3Bsxu9+jOYxGJDjkzyhpLOZgJSYFK36l8dATPF5t1eGy405i0n ABEBAAHCwIMEGAEKAA8FAn/oGU8FCQ8JnAACGy4AqAkQdKKYGB48OuudIAQZAQoA BgUCf+gZTwAKCRDuSkIwkyAjaKEqA/9XS9AgN4nV9on6GsuK1ZpQpqcKAf4SZaF3 rDXqpYfM+LDpqaIl8LZKzK7EyW2pVNV9PwnYtMXwQ7A3KAu2audWxSawHNyvgez1 Ujl0J7TfKwJyVBrCDjZCJrr+joPU0To95jJivSrnCYC3l1ngoMIZycfaU6FhYwHd 2XJe2kbzc8JPA/9aCPIahfTEDEH/giKdtzlLbkri2UYGCJqcoNl0Maz6LVUI3NCo 3O77zi2v7gLtu+9hgfWa8dTxCOszDbNTknb8XXCK74FxwIBgr4gHlvK+xh38RI+8 eC2y0qONraQ/qACJ+UGh1/4smKasSlBi7hZOvNmOxqm4iQ5hve4uWsSlIs6NBH/o GU8BBADDinuE+B31B2hCxsRcNiruHEF9Q65vWUC0w32a9ScsyiiESqhwIgs0L/Ey ejnn4jAQVlmgfJJLUIggGjLXGBGF7Q7v4uzxH97JeC+OCFV2b0RIyUf37Sn3i/+B /BLp250RbLfN5jOJAtVpnbBJSLDjpWzzC6YBXiUXMRrSdEEwWwARAQABwsCDBBgB CgAPBQJ/6BlPBQkPCZwAAhsuAKgJEHSimBgePDrrnSAEGQEKAAYFAn/oGU8ACgkQ KMGvjkoZ3acysgP9FoulZYO+rmQwjyYE7hZ97v/gdzWb6ScO+m8Jm30Q0J9uKNTK wOlTOh6Nrb0q0t1U2apJ//SQV0zxmQmWf1a5pNR0KdhiD3J02+3hwLl5dSoYzkNz A9Xzgg1cCbSDF/dgLH+x1ieMBOH91OTZ0flurq2p2lwNoIVclLJNJSbZzONNJwP+ OYAKvRAWVEi/g1nWGfv0YF6cOP+6cA26vxuJPuGFp/7bwlJ8ALAk6NsQ+qjfonGO VsAU6YXQP9Dt1PvLo7pOtZZ/W9NbuPRaFW7sB6EtYFcko9kckYJXZcIOpffTCPHm Jrh3+G2j19Lsnomz3YCU4wETLkMwxQPG3WzOeNLwX+U= =yV+n -----END PGP PUBLIC KEY BLOCK-----`; const passphrase = 'hello world'; const plaintext = 'short message\nnext line\n한국어/조선말'; const password1 = 'I am a password'; const password2 = 'I am another password'; const password3 = 'I am a third password'; const twoPasswordGPGFail = ['-----BEGIN PGP MESSAGE-----', 'Version: OpenPGP.js v3.0.0', 'Comment: https://openpgpjs.org', '', 'wy4ECQMIWjj3WEfWxGpgrfb3vXu0TS9L8UNTBvNZFIjltGjMVkLFD+/afgs5', 'aXt0wy4ECQMIrFo3TFN5xqtgtB+AaAjBcWJrA4bvIPBpJ38PbMWeF0JQgrqg', 'j3uehxXy0mUB5i7B61g0ho+YplyFGM0s9XayJCnu40tWmr5LqqsRxuwrhJKR', 'migslOF/l6Y9F0F9xGIZWGhxp3ugQPjVKjj8fOH7ap14mLm60C8q8AOxiSmL', 'ubsd/hL7FPZatUYAAZVA0a6hmQ==', '=cHCV', '-----END PGP MESSAGE-----'].join('\n'); function withCompression(tests) { const compressionTypes = Object.keys(openpgp.enums.compression).map(k => openpgp.enums.compression[k]); compressionTypes.forEach(function (compression) { const compressionName = openpgp.enums.read(openpgp.enums.compression, compression); const group = `compression - ${compressionName}`; describe(group, function() { let compressSpy; let decompressSpy; beforeEach(function () { compressSpy = sinon.spy(openpgp.packet.Compressed.prototype, 'compress'); decompressSpy = sinon.spy(openpgp.packet.Compressed.prototype, 'decompress'); }); afterEach(function () { compressSpy.restore(); decompressSpy.restore(); }); tests( function(options) { options.compression = compression; return options; }, function() { // Disable the call expectations when using the web worker because it's not possible to spy on what functions get called. if (openpgp.getWorker()) { return; } if (compression === openpgp.enums.compression.uncompressed) { expect(compressSpy.called).to.be.false; expect(decompressSpy.called).to.be.false; return; } expect(compressSpy.called).to.be.true; expect(compressSpy.thisValues[0].algorithm).to.equal(compressionName); expect(decompressSpy.called).to.be.true; expect(decompressSpy.thisValues[0].algorithm).to.equal(compressionName); } ); }); }); } describe('OpenPGP.js public api tests', function() { describe('initWorker, getWorker, destroyWorker - unit tests', function() { afterEach(function() { openpgp.destroyWorker(); // cleanup worker in case of failure }); it('should work', function() { const workerStub = { postMessage: function() {} }; openpgp.initWorker({ worker: workerStub }); expect(openpgp.getWorker()).to.exist; openpgp.destroyWorker(); expect(openpgp.getWorker()).to.not.exist; }); }); describe('generateKey - unit tests', function() { let keyGenStub; let keyObjStub; let getWebCryptoAllStub; beforeEach(function() { keyObjStub = { armor: function() { return 'priv_key'; }, toPublic: function() { return { armor: function() { return 'pub_key'; } }; } }; keyGenStub = sinon.stub(openpgp.key, 'generate'); keyGenStub.returns(resolves(keyObjStub)); getWebCryptoAllStub = sinon.stub(openpgp.util, 'getWebCryptoAll'); }); afterEach(function() { keyGenStub.restore(); openpgp.destroyWorker(); getWebCryptoAllStub.restore(); }); it('should fail for invalid user name', function() { const opt = { userIds: [{ name: {}, email: 'text@example.com' }] }; const test = openpgp.generateKey.bind(null, opt); expect(test).to.throw(/Invalid user id format/); }); it('should fail for invalid user email address', function() { const opt = { userIds: [{ name: 'Test User', email: 'textexample.com' }] }; const test = openpgp.generateKey.bind(null, opt); expect(test).to.throw(/Invalid user id format/); }); it('should fail for invalid user email address', function() { const opt = { userIds: [{ name: 'Test User', email: 'text@examplecom' }] }; const test = openpgp.generateKey.bind(null, opt); expect(test).to.throw(/Invalid user id format/); }); it('should fail for invalid string user id', function() { const opt = { userIds: ['Test User text@example.com>'] }; const test = openpgp.generateKey.bind(null, opt); expect(test).to.throw(/Invalid user id format/); }); it('should fail for invalid single string user id', function() { const opt = { userIds: 'Test User text@example.com>' }; const test = openpgp.generateKey.bind(null, opt); expect(test).to.throw(/Invalid user id format/); }); it('should work for valid single string user id', function() { const opt = { userIds: 'Test User ' }; return openpgp.generateKey(opt); }); it('should work for valid string user id', function() { const opt = { userIds: ['Test User '] }; return openpgp.generateKey(opt); }); it('should work for valid single user id hash', function() { const opt = { userIds: { name: 'Test User', email: 'text@example.com' } }; return openpgp.generateKey(opt); }); it('should work for valid single user id hash', function() { const opt = { userIds: [{ name: 'Test User', email: 'text@example.com' }] }; return openpgp.generateKey(opt); }); it('should work for an empty name', function() { const opt = { userIds: { email: 'text@example.com' } }; return openpgp.generateKey(opt); }); it('should work for an empty email address', function() { const opt = { userIds: { name: 'Test User' } }; return openpgp.generateKey(opt); }); it('should have default params set', function() { const opt = { userIds: { name: 'Test User', email: 'text@example.com' }, passphrase: 'secret', unlocked: true }; return openpgp.generateKey(opt).then(function(newKey) { expect(keyGenStub.withArgs({ userIds: ['Test User '], passphrase: 'secret', numBits: 2048, unlocked: true, keyExpirationTime: 0, curve: "" }).calledOnce).to.be.true; expect(newKey.key).to.exist; expect(newKey.privateKeyArmored).to.exist; expect(newKey.publicKeyArmored).to.exist; }); }); it('should work for no params', function() { return openpgp.generateKey().then(function(newKey) { expect(keyGenStub.withArgs({ userIds: [], passphrase: undefined, numBits: 2048, unlocked: false, keyExpirationTime: 0, curve: "" }).calledOnce).to.be.true; expect(newKey.key).to.exist; }); }); it('should delegate to async proxy', function() { const workerStub = { postMessage: function() {} }; openpgp.initWorker({ worker: workerStub }); const proxyGenStub = sinon.stub(openpgp.getWorker(), 'delegate'); getWebCryptoAllStub.returns(); openpgp.generateKey(); expect(proxyGenStub.calledOnce).to.be.true; expect(keyGenStub.calledOnce).to.be.false; }); }); describe('generateKey - integration tests', function() { let use_nativeVal; beforeEach(function() { use_nativeVal = openpgp.config.use_native; }); afterEach(function() { openpgp.config.use_native = use_nativeVal; openpgp.destroyWorker(); }); it('should work in JS (without worker)', function() { openpgp.config.use_native = false; openpgp.destroyWorker(); const opt = { userIds: [{ name: 'Test User', email: 'text@example.com' }], numBits: 512 }; return openpgp.generateKey(opt).then(function(newKey) { expect(newKey.key.getUserIds()[0]).to.equal('Test User '); expect(newKey.publicKeyArmored).to.match(/^-----BEGIN PGP PUBLIC/); expect(newKey.privateKeyArmored).to.match(/^-----BEGIN PGP PRIVATE/); }); }); it('should work in JS (with worker)', function() { openpgp.config.use_native = false; openpgp.initWorker({ path:'../dist/openpgp.worker.js' }); const opt = { userIds: [{ name: 'Test User', email: 'text@example.com' }], numBits: 512 }; return openpgp.generateKey(opt).then(function(newKey) { expect(newKey.key.getUserIds()[0]).to.equal('Test User '); expect(newKey.publicKeyArmored).to.match(/^-----BEGIN PGP PUBLIC/); expect(newKey.privateKeyArmored).to.match(/^-----BEGIN PGP PRIVATE/); }); }); it('should work in with native crypto', function() { openpgp.config.use_native = true; const opt = { userIds: [{ name: 'Test User', email: 'text@example.com' }], numBits: 512 }; if (openpgp.util.getWebCryptoAll()) { opt.numBits = 2048; } // webkit webcrypto accepts minimum 2048 bit keys return openpgp.generateKey(opt).then(function(newKey) { expect(newKey.key.getUserIds()[0]).to.equal('Test User '); expect(newKey.publicKeyArmored).to.match(/^-----BEGIN PGP PUBLIC/); expect(newKey.privateKeyArmored).to.match(/^-----BEGIN PGP PRIVATE/); }); }); }); describe('encrypt, decrypt, sign, verify - integration tests', function() { let privateKey_2000_2008; let publicKey_2000_2008; let privateKey_2038_2045; let publicKey_2038_2045; let privateKey; let publicKey; let zero_copyVal; let use_nativeVal; let aead_protectVal; beforeEach(function(done) { publicKey = openpgp.key.readArmored(pub_key); expect(publicKey.keys).to.have.length(1); expect(publicKey.err).to.not.exist; privateKey = openpgp.key.readArmored(priv_key); expect(privateKey.keys).to.have.length(1); expect(privateKey.err).to.not.exist; publicKey_2000_2008 = openpgp.key.readArmored(pub_key_2000_2008); expect(publicKey_2000_2008.keys).to.have.length(1); expect(publicKey_2000_2008.err).to.not.exist; privateKey_2000_2008 = openpgp.key.readArmored(priv_key_2000_2008); expect(privateKey_2000_2008.keys).to.have.length(1); expect(privateKey_2000_2008.err).to.not.exist; publicKey_2038_2045 = openpgp.key.readArmored(pub_key_2038_2045); expect(publicKey_2038_2045.keys).to.have.length(1); expect(publicKey_2038_2045.err).to.not.exist; privateKey_2038_2045 = openpgp.key.readArmored(priv_key_2038_2045); expect(privateKey_2038_2045.keys).to.have.length(1); expect(privateKey_2038_2045.err).to.not.exist; zero_copyVal = openpgp.config.zero_copy; use_nativeVal = openpgp.config.use_native; aead_protectVal = openpgp.config.aead_protect; privateKey.keys[0].verifyPrimaryUser().then(() => done()); }); afterEach(function() { openpgp.config.zero_copy = zero_copyVal; openpgp.config.use_native = use_nativeVal; openpgp.config.aead_protect = aead_protectVal; }); it('Decrypting key with wrong passphrase returns false', function () { expect(privateKey.keys[0].decrypt('wrong passphrase')).to.be.false; }); it('Decrypting key with correct passphrase returns true', function () { expect(privateKey.keys[0].decrypt(passphrase)).to.be.true; }); tryTests('CFB mode (asm.js)', tests, { if: true, beforeEach: function() { openpgp.config.use_native = true; openpgp.config.aead_protect = false; } }); tryTests('CFB mode (asm.js, worker)', tests, { if: typeof window !== 'undefined' && window.Worker, before: function() { openpgp.initWorker({ path:'../dist/openpgp.worker.js' }); }, beforeEach: function() { openpgp.config.use_native = true; openpgp.config.aead_protect = false; }, after: function() { openpgp.destroyWorker(); } }); tryTests('GCM mode (native)', tests, { if: openpgp.util.getWebCrypto() || openpgp.util.getNodeCrypto(), beforeEach: function() { openpgp.config.use_native = true; openpgp.config.aead_protect = true; } }); function tests() { it('Configuration', function() { openpgp.config.show_version = false; openpgp.config.commentstring = 'different'; if (openpgp.getWorker()) { // init again to trigger config event openpgp.initWorker({ path:'../dist/openpgp.worker.js' }); } return openpgp.encrypt({ publicKeys:publicKey.keys, data:plaintext }).then(function(encrypted) { expect(encrypted.data).to.exist; expect(encrypted.data).not.to.match(/^Version:/); expect(encrypted.data).to.match(/Comment: different/); }); }); it('Calling decrypt with not decrypted key leads to exception', function() { const encOpt = { data: plaintext, publicKeys: publicKey.keys }; const decOpt = { privateKeys: privateKey.keys[0] }; return openpgp.encrypt(encOpt).then(function(encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).catch(function(error) { expect(error.message).to.match(/not decrypted/); }); }); describe('decryptKey', function() { it('should work for correct passphrase', function() { return openpgp.decryptKey({ privateKey: privateKey.keys[0], passphrase: passphrase }).then(function(unlocked){ expect(unlocked.key.primaryKey.getKeyId().toHex()).to.equal(privateKey.keys[0].primaryKey.getKeyId().toHex()); expect(unlocked.key.primaryKey.isDecrypted).to.be.true; }); }); it('should fail for incorrect passphrase', function() { return openpgp.decryptKey({ privateKey: privateKey.keys[0], passphrase: 'incorrect' }).catch(function(error){ expect(error.message).to.match(/Invalid passphrase/); }); }); }); describe('encryptSessionKey, decryptSessionKeys', function() { const sk = new Uint8Array([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]); beforeEach(function(done) { expect(privateKey.keys[0].decrypt(passphrase)).to.be.true; privateKey.keys[0].verifyPrimaryUser().then(() => done()); }); it('should encrypt with public key', function() { return openpgp.encryptSessionKey({ data: sk, algorithm: 'aes128', publicKeys: publicKey.keys }).then(function(encrypted) { return openpgp.decryptSessionKeys({ message: encrypted.message, privateKeys: privateKey.keys[0] }); }).then(function(decrypted) { expect(decrypted[0].data).to.deep.equal(sk); }); }); it('should encrypt with password', function() { return openpgp.encryptSessionKey({ data: sk, algorithm: 'aes128', passwords: password1 }).then(function(encrypted) { return openpgp.decryptSessionKeys({ message: encrypted.message, passwords: password1 }); }).then(function(decrypted) { expect(decrypted[0].data).to.deep.equal(sk); }); }); it('roundtrip workflow: encrypt, decryptSessionKeys, decrypt with pgp key pair', function () { let msgAsciiArmored; return openpgp.encrypt({ data: plaintext, publicKeys: publicKey.keys }).then(function (encrypted) { msgAsciiArmored = encrypted.data; return openpgp.decryptSessionKeys({ message: openpgp.message.readArmored(msgAsciiArmored), privateKeys: privateKey.keys[0] }); }).then(function (decryptedSessionKeys) { const message = openpgp.message.readArmored(msgAsciiArmored); return openpgp.decrypt({ sessionKeys: decryptedSessionKeys[0], message }); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); }); }); it('roundtrip workflow: encrypt, decryptSessionKeys, decrypt with password', function () { let msgAsciiArmored; return openpgp.encrypt({ data: plaintext, passwords: password1 }).then(function (encrypted) { msgAsciiArmored = encrypted.data; return openpgp.decryptSessionKeys({ message: openpgp.message.readArmored(msgAsciiArmored), passwords: password1 }); }).then(function (decryptedSessionKeys) { return openpgp.decrypt({ sessionKeys: decryptedSessionKeys[0], message: openpgp.message.readArmored(msgAsciiArmored) }); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); }); }); it('roundtrip workflow: encrypt with multiple passwords, decryptSessionKeys, decrypt with multiple passwords', function () { let msgAsciiArmored; return openpgp.encrypt({ data: plaintext, passwords: [password1, password2] }).then(function (encrypted) { msgAsciiArmored = encrypted.data; return openpgp.decryptSessionKeys({ message: openpgp.message.readArmored(msgAsciiArmored), passwords: [password1, password2] }); }).then(function (decryptedSessionKeys) { return openpgp.decrypt({ sessionKeys: decryptedSessionKeys, message: openpgp.message.readArmored(msgAsciiArmored) }); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); }); }); it('roundtrip workflow: encrypt twice with one password, decryptSessionKeys, only one session key', function () { let msgAsciiArmored; return openpgp.encrypt({ data: plaintext, passwords: [password1, password1] }).then(function (encrypted) { msgAsciiArmored = encrypted.data; return openpgp.decryptSessionKeys({ message: openpgp.message.readArmored(msgAsciiArmored), passwords: password1 }); }).then(function (decryptedSessionKeys) { expect(decryptedSessionKeys.length).to.equal(1); return openpgp.decrypt({ sessionKeys: decryptedSessionKeys, message: openpgp.message.readArmored(msgAsciiArmored) }); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); }); }); }); describe('AES / RSA encrypt, decrypt, sign, verify', function() { const wrong_pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n' + 'Version: OpenPGP.js v0.9.0\r\n' + 'Comment: Hoodiecrow - https://hoodiecrow.com\r\n' + '\r\n' + 'xk0EUlhMvAEB/2MZtCUOAYvyLFjDp3OBMGn3Ev8FwjzyPbIF0JUw+L7y2XR5\r\n' + 'RVGvbK88unV3cU/1tOYdNsXI6pSp/Ztjyv7vbBUAEQEAAc0pV2hpdGVvdXQg\r\n' + 'VXNlciA8d2hpdGVvdXQudGVzdEB0LW9ubGluZS5kZT7CXAQQAQgAEAUCUlhM\r\n' + 'vQkQ9vYOm0LN/0wAAAW4Af9C+kYW1AvNWmivdtr0M0iYCUjM9DNOQH1fcvXq\r\n' + 'IiN602mWrkd8jcEzLsW5IUNzVPLhrFIuKyBDTpLnC07Loce1\r\n' + '=6XMW\r\n' + '-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n'; beforeEach(function (done) { expect(privateKey.keys[0].decrypt(passphrase)).to.be.true; privateKey.keys[0].verifyPrimaryUser().then(() => done()); }); it('should encrypt then decrypt', function () { const encOpt = { data: plaintext, publicKeys: publicKey.keys }; const decOpt = { privateKeys: privateKey.keys }; return openpgp.encrypt(encOpt).then(function (encrypted) { expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/); decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures).to.exist; expect(decrypted.signatures.length).to.equal(0); }); }); it('should encrypt then decrypt', function () { const encOpt = { data: plaintext, publicKeys: publicKey.keys }; const decOpt = { privateKeys: privateKey.keys }; return openpgp.encrypt(encOpt).then(function (encrypted) { expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/); decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures).to.exist; expect(decrypted.signatures.length).to.equal(0); }); }); it('should encrypt then decrypt with multiple private keys', function () { const privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; privKeyDE.decrypt(passphrase); const encOpt = { data: plaintext, publicKeys: publicKey.keys }; const decOpt = { privateKeys: [privKeyDE, privateKey.keys[0]] }; return openpgp.encrypt(encOpt).then(function (encrypted) { expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/); decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures).to.exist; expect(decrypted.signatures.length).to.equal(0); }); }); it('should encrypt then decrypt with wildcard', function () { const encOpt = { data: plaintext, publicKeys: publicKey.keys, wildcard: true }; const decOpt = { privateKeys: privateKey.keys }; return openpgp.encrypt(encOpt).then(function (encrypted) { expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/); decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures).to.exist; expect(decrypted.signatures.length).to.equal(0); }); }); it('should encrypt then decrypt with wildcard with multiple private keys', function () { const privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; privKeyDE.decrypt(passphrase); const encOpt = { data: plaintext, publicKeys: publicKey.keys, wildcard: true }; const decOpt = { privateKeys: [privKeyDE, privateKey.keys[0]] }; return openpgp.encrypt(encOpt).then(function (encrypted) { expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/); decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures).to.exist; expect(decrypted.signatures.length).to.equal(0); }); }); it('should encrypt then decrypt using returned session key', function () { const encOpt = { data: plaintext, publicKeys: publicKey.keys, returnSessionKey: true }; return openpgp.encrypt(encOpt).then(function (encrypted) { expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/); const decOpt = { sessionKeys: encrypted.sessionKey, message: openpgp.message.readArmored(encrypted.data) }; return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures).to.exist; expect(decrypted.signatures.length).to.equal(0); }); }); it('should encrypt using custom session key and decrypt using session key', function () { const sessionKey = { data: openpgp.crypto.generateSessionKey('aes256'), algorithm: 'aes256' }; const encOpt = { data: plaintext, sessionKey: sessionKey, publicKeys: publicKey.keys }; const decOpt = { sessionKeys: sessionKey }; return openpgp.encrypt(encOpt).then(function (encrypted) { expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/); decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); }); }); it('should encrypt using custom session key and decrypt using private key', function () { const sessionKey = { data: openpgp.crypto.generateSessionKey('aes128'), algorithm: 'aes128' }; const encOpt = { data: plaintext, sessionKeys: sessionKey, publicKeys: publicKey.keys }; const decOpt = { privateKeys: privateKey.keys[0] }; return openpgp.encrypt(encOpt).then(function (encrypted) { expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/); decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); }); }); it('should encrypt/sign and decrypt/verify', function () { const encOpt = { data: plaintext, publicKeys: publicKey.keys, privateKeys: privateKey.keys }; const decOpt = { privateKeys: privateKey.keys[0], publicKeys: publicKey.keys }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); it('should encrypt/sign and decrypt/verify with null string input', function () { const encOpt = { data: '', publicKeys: publicKey.keys, privateKeys: privateKey.keys }; const decOpt = { privateKeys: privateKey.keys[0], publicKeys: publicKey.keys }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(''); expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); it('should encrypt/sign and decrypt/verify with detached signatures', function () { const encOpt = { data: plaintext, publicKeys: publicKey.keys, privateKeys: privateKey.keys, detached: true }; const decOpt = { privateKeys: privateKey.keys[0], publicKeys: publicKey.keys }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); decOpt.signature = openpgp.signature.readArmored(encrypted.signature); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); it('should encrypt and decrypt/verify with detached signature input and detached flag set for encryption', function () { const signOpt = { data: plaintext, privateKeys: privateKey.keys[0], detached: true }; const encOpt = { data: plaintext, publicKeys: publicKey.keys, detached: true }; const decOpt = { privateKeys: privateKey.keys[0], publicKeys: publicKey.keys[0] }; return openpgp.sign(signOpt).then(function (signed) { encOpt.signature = openpgp.signature.readArmored(signed.signature); return openpgp.encrypt(encOpt); }).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); decOpt.signature = openpgp.signature.readArmored(encrypted.signature); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); it('should encrypt and decrypt/verify with detached signature as input and detached flag not set for encryption', function () { const privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; privKeyDE.decrypt(passphrase); const pubKeyDE = openpgp.key.readArmored(pub_key_de).keys[0]; const signOpt = { data: plaintext, privateKeys: privKeyDE, detached: true }; const encOpt = { data: plaintext, publicKeys: publicKey.keys, privateKeys: privateKey.keys[0] }; const decOpt = { privateKeys: privateKey.keys[0], publicKeys: [publicKey.keys[0], pubKeyDE] }; return openpgp.sign(signOpt).then(function (signed) { encOpt.signature = openpgp.signature.readArmored(signed.signature); return openpgp.encrypt(encOpt); }).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[1].valid).to.be.true; return privKeyDE.verifyPrimaryUser().then(() => { expect(decrypted.signatures[1].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[1].signature.packets.length).to.equal(1); }); }); }); it('should fail to encrypt and decrypt/verify with detached signature input and detached flag set for encryption with wrong public key', function () { const signOpt = { data: plaintext, privateKeys: privateKey.keys, detached: true }; const encOpt = { data: plaintext, publicKeys: publicKey.keys, detached: true }; const decOpt = { privateKeys: privateKey.keys[0], publicKeys: openpgp.key.readArmored(wrong_pubkey).keys }; return openpgp.sign(signOpt).then(function (signed) { encOpt.signature = openpgp.signature.readArmored(signed.signature); return openpgp.encrypt(encOpt); }).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); decOpt.signature = openpgp.signature.readArmored(encrypted.signature); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.null; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); it('should fail to encrypt and decrypt/verify with detached signature as input and detached flag not set for encryption with wrong public key', function () { const signOpt = { data: plaintext, privateKeys: privateKey.keys, detached: true }; const encOpt = { data: plaintext, publicKeys: publicKey.keys }; const decOpt = { privateKeys: privateKey.keys[0], publicKeys: openpgp.key.readArmored(wrong_pubkey).keys }; return openpgp.sign(signOpt).then(function (signed) { encOpt.signature = openpgp.signature.readArmored(signed.signature); return openpgp.encrypt(encOpt); }).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.null; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); it('should fail to verify decrypted data with wrong public pgp key', function () { const encOpt = { data: plaintext, publicKeys: publicKey.keys, privateKeys: privateKey.keys }; const decOpt = { privateKeys: privateKey.keys[0], publicKeys: openpgp.key.readArmored(wrong_pubkey).keys }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.null; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); it('should fail to verify decrypted null string with wrong public pgp key', function () { const encOpt = { data: '', publicKeys: publicKey.keys, privateKeys: privateKey.keys }; const decOpt = { privateKeys: privateKey.keys[0], publicKeys: openpgp.key.readArmored(wrong_pubkey).keys }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(''); expect(decrypted.signatures[0].valid).to.be.null; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); it('should successfully decrypt signed message without public keys to verify', function () { const encOpt = { data: plaintext, publicKeys: publicKey.keys, privateKeys: privateKey.keys }; const decOpt = { privateKeys: privateKey.keys[0] }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.null; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); it('should fail to verify decrypted data with wrong public pgp key with detached signatures', function () { const encOpt = { data: plaintext, publicKeys: publicKey.keys, privateKeys: privateKey.keys, detached: true }; const decOpt = { privateKeys: privateKey.keys[0], publicKeys: openpgp.key.readArmored(wrong_pubkey).keys }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); decOpt.signature = openpgp.signature.readArmored(encrypted.signature); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.null; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); it('should encrypt and decrypt/verify both signatures when signed with two private keys', function () { const privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; privKeyDE.decrypt(passphrase); const pubKeyDE = openpgp.key.readArmored(pub_key_de).keys[0]; const encOpt = { data: plaintext, publicKeys: publicKey.keys, privateKeys: [privateKey.keys[0], privKeyDE] }; const decOpt = { privateKeys: privateKey.keys[0], publicKeys: [publicKey.keys[0], pubKeyDE] }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[1].valid).to.be.true; return privKeyDE.verifyPrimaryUser().then(() => { expect(decrypted.signatures[1].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[1].signature.packets.length).to.equal(1); }); }); }); it('should sign and verify cleartext data', function () { const signOpt = { data: plaintext, privateKeys: privateKey.keys }; const verifyOpt = { publicKeys: publicKey.keys }; return openpgp.sign(signOpt).then(function (signed) { expect(signed.data).to.match(/-----BEGIN PGP SIGNED MESSAGE-----/); verifyOpt.message = openpgp.cleartext.readArmored(signed.data); return openpgp.verify(verifyOpt); }).then(function (verified) { expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); it('should sign and verify cleartext data with multiple private keys', function () { const privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; privKeyDE.decrypt(passphrase); const signOpt = { data: plaintext, privateKeys: [privateKey.keys[0], privKeyDE] }; const verifyOpt = { publicKeys: [publicKey.keys[0], privKeyDE.toPublic()] }; return openpgp.sign(signOpt).then(function (signed) { expect(signed.data).to.match(/-----BEGIN PGP SIGNED MESSAGE-----/); verifyOpt.message = openpgp.cleartext.readArmored(signed.data); return openpgp.verify(verifyOpt); }).then(function (verified) { expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); expect(verified.signatures[1].valid).to.be.true; return privKeyDE.verifyPrimaryUser().then(() => { expect(verified.signatures[1].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); expect(verified.signatures[1].signature.packets.length).to.equal(1); }); }); }); it('should sign and verify cleartext data with detached signatures', function () { const signOpt = { data: plaintext, privateKeys: privateKey.keys, detached: true }; const verifyOpt = { publicKeys: publicKey.keys }; return openpgp.sign(signOpt).then(function (signed) { verifyOpt.message = new openpgp.cleartext.CleartextMessage(plaintext); verifyOpt.signature = openpgp.signature.readArmored(signed.signature); return openpgp.verify(verifyOpt); }).then(function (verified) { expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); it('should sign and fail to verify cleartext data with wrong public pgp key', function () { const signOpt = { data: plaintext, privateKeys: privateKey.keys }; const verifyOpt = { publicKeys: openpgp.key.readArmored(wrong_pubkey).keys }; return openpgp.sign(signOpt).then(function (signed) { verifyOpt.message = openpgp.cleartext.readArmored(signed.data); return openpgp.verify(verifyOpt); }).then(function (verified) { expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.null; expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); it('should sign and fail to verify cleartext data with wrong public pgp key with detached signature', function () { const signOpt = { data: plaintext, privateKeys: privateKey.keys, detached: true }; const verifyOpt = { publicKeys: openpgp.key.readArmored(wrong_pubkey).keys }; return openpgp.sign(signOpt).then(function (signed) { verifyOpt.message = new openpgp.cleartext.CleartextMessage(plaintext); verifyOpt.signature = openpgp.signature.readArmored(signed.signature); return openpgp.verify(verifyOpt); }).then(function (verified) { expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.null; expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); it('should sign and verify cleartext data and not armor', function () { const signOpt = { data: plaintext, privateKeys: privateKey.keys, armor: false }; const verifyOpt = { publicKeys: publicKey.keys }; return openpgp.sign(signOpt).then(function (signed) { verifyOpt.message = signed.message; return openpgp.verify(verifyOpt); }).then(function (verified) { expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); it('should sign and verify cleartext data and not armor with detached signatures', function () { const start = Date.now(); const signOpt = { data: plaintext, privateKeys: privateKey.keys, detached: true, armor: false }; const verifyOpt = { publicKeys: publicKey.keys }; return openpgp.sign(signOpt).then(function (signed) { verifyOpt.message = new openpgp.cleartext.CleartextMessage(plaintext); verifyOpt.signature = signed.signature; return openpgp.verify(verifyOpt); }).then(function (verified) { expect(verified.data).to.equal(plaintext); expect(+verified.signatures[0].signature.packets[0].created).to.be.lte(Date.now()); expect(+verified.signatures[0].signature.packets[0].created).to.be.gte(start); expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].keyid.toHex()).to.equal(privateKey.keys[0].getSigningKeyPacket().getKeyId().toHex()); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); it('should sign and verify cleartext data with a date in the past', function () { const past = new Date(2005, 5, 5, 5, 5, 5, 0); const signOpt = { data: plaintext, privateKeys: privateKey_2000_2008.keys, detached: true, creationDate: past, armor: false }; const verifyOpt = { publicKeys: publicKey_2000_2008.keys }; return openpgp.sign(signOpt).then(function (signed) { verifyOpt.message = new openpgp.cleartext.CleartextMessage(plaintext); verifyOpt.signature = signed.signature; return openpgp.verify(verifyOpt); }).then(function (verified) { expect(+verified.signatures[0].signature.packets[0].created).to.equal(+past); expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.true; expect(signOpt.privateKeys[0].getSigningKeyPacket(verified.signatures[0].keyid, past)) .to.be.not.a('null'); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); it('should sign and verify binary data with a date in the future', function () { const future = new Date(2040, 5, 5, 5, 5, 5, 0); const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]); const signOpt = { data, privateKeys: privateKey_2038_2045.keys, detached: true, creationDate: future, armor: false }; const verifyOpt = { publicKeys: publicKey_2038_2045.keys }; return openpgp.sign(signOpt).then(function (signed) { verifyOpt.message = openpgp.message.fromBinary(data); verifyOpt.signature = signed.signature; return openpgp.verify(verifyOpt); }).then(function (verified) { expect(+verified.signatures[0].signature.packets[0].created).to.equal(+future); expect(verified.data).to.equal(data); expect(verified.signatures[0].valid).to.be.true; expect(signOpt.privateKeys[0].getSigningKeyPacket(verified.signatures[0].keyid, future)) .to.be.not.a('null'); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); it('should encrypt and decrypt cleartext data with a date in the future', function () { const future = new Date(2040, 5, 5, 5, 5, 5, 0); const encryptOpt = { data: plaintext, publicKeys: publicKey_2038_2045.keys, creationDate: future, armor: false }; const decryptOpt = { privateKeys: privateKey_2038_2045.keys }; return openpgp.encrypt(encryptOpt).then(function (encrypted) { decryptOpt.message = encrypted.message; return encrypted.message.decrypt(decryptOpt.privateKeys); }).then(function (packets) { const literals = packets.packets.filterByTag(openpgp.enums.packet.literal); expect(literals.length).to.equal(1); expect(+literals[0].date).to.equal(+future); expect(packets.getText()).to.equal(plaintext); }); }); it('should encrypt and decrypt binary data with a date in the past', function () { const past = new Date(2005, 5, 5, 5, 5, 5, 0); const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]); const encryptOpt = { data, publicKeys: publicKey_2000_2008.keys, creationDate: past, armor: false }; const decryptOpt = { privateKeys: privateKey_2000_2008.keys }; return openpgp.encrypt(encryptOpt).then(function (encrypted) { decryptOpt.message = encrypted.message; return encrypted.message.decrypt(decryptOpt.privateKeys); }).then(function (packets) { const literals = packets.packets.filterByTag(openpgp.enums.packet.literal); expect(literals.length).to.equal(1); expect(+literals[0].date).to.equal(+past); expect(packets.getLiteralData()).to.deep.equal(data); }); }); it('should sign, encrypt and decrypt, verify cleartext data with a date in the past', function () { const past = new Date(2005, 5, 5, 5, 5, 5, 0); const encryptOpt = { data: plaintext, publicKeys: publicKey_2000_2008.keys, privateKeys: privateKey_2000_2008.keys, creationDate: past, armor: false }; return openpgp.encrypt(encryptOpt).then(function (encrypted) { return encrypted.message.decrypt(encryptOpt.privateKeys); }).then(function (packets) { const literals = packets.packets.filterByTag(openpgp.enums.packet.literal); expect(literals.length).to.equal(1); expect(+literals[0].date).to.equal(+past); expect(packets.getText()).to.equal(plaintext); return packets.verify(encryptOpt.publicKeys); }).then(function (signatures) { expect(+signatures[0].signature.packets[0].created).to.equal(+past); expect(signatures[0].valid).to.be.true; expect(encryptOpt.privateKeys[0].getSigningKeyPacket(signatures[0].keyid, past)) .to.be.not.a('null'); expect(signatures[0].signature.packets.length).to.equal(1); }); }); it('should sign, encrypt and decrypt, verify binary data with a date in the future', function () { const future = new Date(2040, 5, 5, 5, 5, 5, 0); const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]); const encryptOpt = { data, publicKeys: publicKey_2038_2045.keys, privateKeys: privateKey_2038_2045.keys, creationDate: future, armor: false }; return openpgp.encrypt(encryptOpt).then(function (encrypted) { return encrypted.message.decrypt(encryptOpt.privateKeys); }).then(function (packets) { const literals = packets.packets.filterByTag(openpgp.enums.packet.literal); expect(literals.length).to.equal(1); expect(+literals[0].date).to.equal(+future); expect(packets.getLiteralData()).to.deep.equal(data); return packets.verify(encryptOpt.publicKeys); }).then(function (signatures) { expect(+signatures[0].signature.packets[0].created).to.equal(+future); expect(signatures[0].valid).to.be.true; expect(encryptOpt.privateKeys[0].getSigningKeyPacket(signatures[0].keyid, future)) .to.be.not.a('null'); expect(signatures[0].signature.packets.length).to.equal(1); }); }); it('should sign and verify cleartext data with a date in the past', function () { const past = new Date(2005, 5, 5, 5, 5, 5, 0); const signOpt = { data: plaintext, privateKeys: privateKey_2000_2008.keys, detached: true, creationDate: past, armor: false }; const verifyOpt = { publicKeys: publicKey_2000_2008.keys }; return openpgp.sign(signOpt).then(function (signed) { verifyOpt.message = new openpgp.cleartext.CleartextMessage(plaintext); verifyOpt.signature = signed.signature; return openpgp.verify(verifyOpt); }).then(function (verified) { expect(+verified.signatures[0].signature.packets[0].created).to.equal(+past); expect(verified.data).to.equal(plaintext); expect(verified.signatures[0].valid).to.be.true; expect(signOpt.privateKeys[0].getSigningKeyPacket(verified.signatures[0].keyid, past)) .to.be.not.a('null'); expect(verified.signatures[0].signature.packets.length).to.equal(1); }); }); it('should encrypt and decrypt cleartext data with a date in the future', function () { const future = new Date(2040, 5, 5, 5, 5, 5, 0); const encryptOpt = { data: plaintext, publicKeys: publicKey_2038_2045.keys, creationDate: future, armor: false }; const decryptOpt = { privateKeys: privateKey_2038_2045.keys }; return openpgp.encrypt(encryptOpt).then(function (encrypted) { decryptOpt.message = encrypted.message; return encrypted.message.decrypt(decryptOpt.privateKeys); }).then(function (packets) { const literals = packets.packets.filterByTag(openpgp.enums.packet.literal); expect(literals.length).to.equal(1); expect(+literals[0].date).to.equal(+future); expect(packets.getText()).to.equal(plaintext); }); }); it('should encrypt and decrypt binary data with a date in the past', function () { const past = new Date(2005, 5, 5, 5, 5, 5, 0); const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]); const encryptOpt = { data, publicKeys: publicKey_2000_2008.keys, creationDate: past, armor: false }; const decryptOpt = { privateKeys: privateKey_2000_2008.keys }; return openpgp.encrypt(encryptOpt).then(function (encrypted) { decryptOpt.message = encrypted.message; return encrypted.message.decrypt(decryptOpt.privateKeys); }).then(function (packets) { const literals = packets.packets.filterByTag(openpgp.enums.packet.literal); expect(literals.length).to.equal(1); expect(+literals[0].date).to.equal(+past); expect(packets.getLiteralData()).to.deep.equal(data); }); }); it('should sign, encrypt and decrypt, verify cleartext data with a date in the past', function () { const past = new Date(2005, 5, 5, 5, 5, 5, 0); const encryptOpt = { data: plaintext, publicKeys: publicKey_2000_2008.keys, privateKeys: privateKey_2000_2008.keys, creationDate: past, armor: false }; return openpgp.encrypt(encryptOpt).then(function (encrypted) { return encrypted.message.decrypt(encryptOpt.privateKeys); }).then(function (packets) { const literals = packets.packets.filterByTag(openpgp.enums.packet.literal); expect(literals.length).to.equal(1); expect(+literals[0].date).to.equal(+past); expect(packets.getText()).to.equal(plaintext); return packets.verify(encryptOpt.publicKeys); }).then(function (signatures) { expect(+signatures[0].signature.packets[0].created).to.equal(+past); expect(signatures[0].valid).to.be.true; expect(encryptOpt.privateKeys[0].getSigningKeyPacket(signatures[0].keyid, past)) .to.be.not.a('null'); expect(signatures[0].signature.packets.length).to.equal(1); }); }); it('should sign, encrypt and decrypt, verify binary data with a date in the future', function () { const future = new Date(2040, 5, 5, 5, 5, 5, 0); const data = new Uint8Array([3, 14, 15, 92, 65, 35, 59]); const encryptOpt = { data, publicKeys: publicKey_2038_2045.keys, privateKeys: privateKey_2038_2045.keys, creationDate: future, armor: false }; return openpgp.encrypt(encryptOpt).then(function (encrypted) { return encrypted.message.decrypt(encryptOpt.privateKeys); }).then(function (packets) { const literals = packets.packets.filterByTag(openpgp.enums.packet.literal); expect(literals.length).to.equal(1); expect(+literals[0].date).to.equal(+future); expect(packets.getLiteralData()).to.deep.equal(data); return packets.verify(encryptOpt.publicKeys); }).then(function (signatures) { expect(+signatures[0].signature.packets[0].created).to.equal(+future); expect(signatures[0].valid).to.be.true; expect(encryptOpt.privateKeys[0].getSigningKeyPacket(signatures[0].keyid, future)) .to.be.not.a('null'); expect(signatures[0].signature.packets.length).to.equal(1); }); }); }); describe('ELG / DSA encrypt, decrypt, sign, verify', function() { it('round trip test', function () { const pubKeyDE = openpgp.key.readArmored(pub_key_de).keys[0]; const privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; privKeyDE.decrypt(passphrase); return openpgp.encrypt({ publicKeys: pubKeyDE, privateKeys: privKeyDE, data: plaintext }).then(function (encrypted) { return openpgp.decrypt({ privateKeys: privKeyDE, publicKeys: pubKeyDE, message: openpgp.message.readArmored(encrypted.data) }); }).then(function (decrypted) { expect(decrypted.data).to.exist; expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures[0].valid).to.be.true; return privKeyDE.verifyPrimaryUser().then(() => { expect(decrypted.signatures[0].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); }); }); describe("3DES decrypt", function() { const pgp_msg = ['-----BEGIN PGP MESSAGE-----', 'Version: GnuPG/MacGPG2 v2.0.19 (Darwin)', 'Comment: GPGTools - https://gpgtools.org', '', 'hIwDBU4Dycfvp2EBA/9tuhQgOrcATcm2PRmIOcs6q947YhlsBTZZdVJDfVjkKlyM', 'M0yE+lnNplWb041Cpfkkl6IvorKQd2iPbAkOL0IXwmVN41l+PvVgMcuFvvzetehG', 'Ca0/VEYOaTZRNqyr9FIzcnVy1I/PaWT3iqVAYa+G8TEA5Dh9RLfsx8ZA9UNIaNI+', 'ASm9aZ3H6FerNhm8RezDY5vRn6xw3o/wH5YEBvV2BEmmFKZ2BlqFQxqChr8UNwd1', 'Ieebnq0HtBPE8YU/L0U=', '=JyIa', '-----END PGP MESSAGE-----'].join('\n'); const priv_key = ['-----BEGIN PGP PRIVATE KEY BLOCK-----', 'Version: GnuPG/MacGPG2 v2.0.19 (Darwin)', 'Comment: GPGTools - https://gpgtools.org', '', 'lQH+BFLqLegBBAC/rN3g30Jrcpx5lTb7Kxe+ZfS7ppOIoBjjN+qcOh81cJJVS5dT', 'UGcDsm2tCLVS3P2dGaYhfU9fsoSq/wK/tXsdoWXvXdjHbbueyi1kTZqlnyT190UE', 'vmDxH0yqquvUaf7+CNXC0T6l9gGS9p0x7xNydWRb7zeK1wIsYI+dRGQmzQARAQAB', '/gMDArgQHMknurQXy0Pho3Nsdu6zCUNXuplvaSXruefKsQn6eexGPnecNTT2iy5N', '70EK371D7GcNhhLsn8roUcj1Hi3kR14wXW7lcQBy9RRbbglIJXIqKJ8ywBEO8BaQ', 'b0plL+w5A9EvX0BQc4d53MTqySh6POsEDOxPzH4D/JWbaozfmc4LfGDqH1gl7ebY', 'iu81vnBuuskjpz8rxRI81MldJEIObrTE2x46DF7AmS6L6u/Qz3AAmZd89p5INCdx', 'DemxzuMKpC3wSgdgSSKHHTKiNOMxiRd5mFH5v1KVcEG/TyXFlmah7RwA4rA4fjeo', 'OpnbVWp6ciUniRvgLaCMMbmolAoho9zaLbPzCQVQ8F7gkrjnnPm4MKA+AUXmjt7t', 'VrrYkyTp1pxLZyUWX9+aKoxEO9OIDz7p9Mh02BZ/tznQ7U+IV2bcNhwrL6LPk4Mb', 'J4YF/cLVxFVVma88GSFikSjPf30AUty5nBQFtbFGqnPctCF0aHJvd2F3YXkgPHRo', 'cm93YXdheUBleGFtcGxlLmNvbT6IuAQTAQIAIgUCUuot6AIbAwYLCQgHAwIGFQgC', 'CQoLBBYCAwECHgECF4AACgkQkk2hoj5duD/HZQP/ZXJ8PSlA1oj1NW97ccT0LiNH', 'WzxPPoH9a/qGQYg61jp+aTa0C5hlYY/GgeFpiZlpwVUtlkZYfslXJqbCcp3os4xt', 'kiukDbPnq2Y41wNVxXrDw6KbOjohbhzeRUh8txbkiXGiwHtHBSJsPMntN6cB3vn3', '08eE69vOiHPQfowa2CmdAf4EUuot6AEEAOQpNjkcTUo14JQ2o+mrpxj5yXbGtZKh', 'D8Ll+aZZrIDIa44p9KlQ3aFzPxdmFBiBX57m1nQukr58FQ5Y/FuQ1dKYc3M8QdZL', 'vCKDC8D9ZJf13iwUjYkfn/e/bDqCS2piyd63zI0xDJo+s2bXCIJxgrhbOqFDeFd6', '4W8PfBOvUuRjABEBAAH+AwMCuBAcySe6tBfLV0P5MbBesR3Ifu/ppjzLoXKhwkqm', 'PXf09taLcRfUHeMbPjboj2P2m2UOnSrbXK9qsDQ8XOMtdsEWGLWpmiqnMlkiOchv', 'MsNRYpZ67iX3JVdxNuhs5+g5bdP1PNVbKiTzx73u1h0SS93IJp1jFj50/kyGl1Eq', 'tkr0TWe5uXCh6cSZDPwhto0a12GeDHehdTw6Yq4KoZHccneHhN9ySFy0DZOeULIi', 'Y61qtR0io52T7w69fBe9Q5/d5SwpwWKMpCTOqvvzdHX7JmeFtV+2vRVilIif7AfP', 'AD+OjQ/OhMu3jYO+XNhm3raPT2tIBsBdl2UiHOnj4AUNuLuUJeVghtz4Qt6dvjyz', 'PlBvSF+ESqALjM8IqnG15FX4LmEDFrFcfNCsnmeyZ2nr1h2mV5jOON0EmBtCyhCt', 'D/Ivi4/SZk+tBVhsBI+7ZECZYDJzZQnyPDsUv31MU4OwdWi7FhzHvDj/0bhYY7+I', 'nwQYAQIACQUCUuot6AIbDAAKCRCSTaGiPl24PwYAA/sGIHvCKWP5+4ZlBHuOdbP9', '9v3PXFCm61qFEL0DTSq7NgBcuf0ASRElRI3wIKlfkwaiSzVPfNLiMTexdc7XaiTz', 'CHaOn1Xl2gmYTq2KiJkgtLuwptYU1iSj7vvSHKy0+nYIckOZB4pRCOjknT08O4ZJ', '22q10ausyQXoOxXfDWVwKA==', '=IkKW', '-----END PGP PRIVATE KEY BLOCK-----'].join('\n'); it('Decrypt message', function() { const privKey = openpgp.key.readArmored(priv_key).keys[0]; privKey.decrypt('1234'); const message = openpgp.message.readArmored(pgp_msg); return openpgp.decrypt({ privateKeys:privKey, message:message }).then(function(decrypted) { expect(decrypted.data).to.equal('hello 3des\n'); expect(decrypted.signatures.length).to.equal(0); }); }); }); describe('AES encrypt, decrypt', function() { it('should encrypt and decrypt with one password', function () { const encOpt = { data: plaintext, passwords: password1 }; const decOpt = { passwords: password1 }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures.length).to.equal(0); }); }); it('should encrypt and decrypt with two passwords', function () { const encOpt = { data: plaintext, passwords: [password1, password2] }; const decOpt = { passwords: password2 }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures.length).to.equal(0); }); }); it('should decrypt with two passwords message which GPG fails on', function () { const decOpt = { message: openpgp.message.readArmored(twoPasswordGPGFail), passwords: password2 }; return openpgp.decrypt(decOpt).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures.length).to.equal(0); }); }); it('should encrypt and decrypt with password and not ascii armor', function () { const encOpt = { data: plaintext, passwords: password1, armor: false }; const decOpt = { passwords: password1 }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = encrypted.message; return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures.length).to.equal(0); }); }); it('should encrypt and decrypt with binary data and transferable objects', function () { openpgp.config.zero_copy = true; // activate transferable objects const encOpt = { data: new Uint8Array([0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01]), passwords: password1, armor: false }; const decOpt = { passwords: password1, format: 'binary' }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = encrypted.message; return openpgp.decrypt(decOpt); }).then(function (decrypted) { if (openpgp.getWorker()) { expect(encOpt.data.byteLength).to.equal(0); // transferred buffer should be empty } expect(decrypted.data).to.deep.equal(new Uint8Array([0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01])); expect(decrypted.signatures.length).to.equal(0); }); }); }); describe('Encrypt, decrypt with compression', function() { withCompression(function (modifyCompressionEncryptOptions, verifyCompressionDecrypted) { it('should encrypt and decrypt with one password', function () { const encOpt = modifyCompressionEncryptOptions({ data: plaintext, passwords: password1 }); const decOpt = { passwords: password1 }; return openpgp.encrypt(encOpt).then(function (encrypted) { decOpt.message = openpgp.message.readArmored(encrypted.data); return openpgp.decrypt(decOpt); }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); expect(decrypted.signatures.length).to.equal(0); verifyCompressionDecrypted(decrypted); }); }); }); }); describe('Errors', function() { it('Error message should contain the original error message', function() { return openpgp.encrypt({ data: new Uint8Array([0x01, 0x01, 0x01]), passwords: null }) .then(function() { throw new Error('Error expected.'); }) .catch(function(error) { expect(error.message).to.match(/No keys, passwords, or session key provided/); }); }); }); } }); });