From 9f7466ef458cbb93889ef6d2cde07b911399a4e0 Mon Sep 17 00:00:00 2001 From: mmso Date: Tue, 13 Feb 2018 15:08:41 +0100 Subject: [PATCH 1/5] Add compression support for the encrypt function --- src/config/config.js | 2 +- src/message.js | 20 + src/openpgp.js | 4 +- src/packet/compressed.js | 2 +- test/general/openpgp.js | 1519 ++++++++++++++++++++------------------ 5 files changed, 832 insertions(+), 715 deletions(-) diff --git a/src/config/config.js b/src/config/config.js index a7ae24b0..b2645463 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -31,7 +31,7 @@ export default { /** @property {Integer} encryption_cipher Default encryption cipher {@link module:enums.symmetric} */ encryption_cipher: enums.symmetric.aes256, /** @property {Integer} compression Default compression algorithm {@link module:enums.compression} */ - compression: enums.compression.zip, + compression: enums.compression.uncompressed, /** * Use Authenticated Encryption with Additional Data (AEAD) protection for symmetric encryption. diff --git a/src/message.js b/src/message.js index 2d9adf48..c392fddd 100644 --- a/src/message.js +++ b/src/message.js @@ -451,6 +451,26 @@ Message.prototype.sign = async function(privateKeys=[], signature=null) { return new Message(packetlist); }; +/** + * Compresses the message (the literal and -if signed- signature data packets of the message) + * @param {module:enums.compression} compression compression algorithm to be used + * @return {module:message~Message} new message with signed content + */ +Message.prototype.compress = function(compression) { + if (compression === enums.compression.uncompressed) { + return this; + } + + const compressed = new packet.Compressed(); + compressed.packets = this.packets; + compressed.algorithm = enums.read(enums.compression, compression); + + const packetList = new packet.List(); + packetList.push(compressed); + + return new Message(packetList); +}; + /** * Create a detached signature for the message (the literal data packet of the message) * @param {Array} privateKey private keys with decrypted secret key data for signing diff --git a/src/openpgp.js b/src/openpgp.js index e2476a15..99d368aa 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -192,6 +192,7 @@ export function decryptKey({ privateKey, passphrase }) { * @param {String|Array} passwords (optional) array of passwords or a single password to encrypt the message * @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String } * @param {String} filename (optional) a filename for the literal data packet + * @param {Boolean} compression (optional) which compression algorithm to compress the message with, defaults to what is specified in config * @param {Boolean} armor (optional) if the return values should be ascii armored or the message/signature objects * @param {Boolean} detached (optional) if the signature should be detached (if true, signature will be added to returned object) * @param {Signature} signature (optional) a detached signature to add to the encrypted message @@ -202,7 +203,7 @@ export function decryptKey({ privateKey, passphrase }) { * message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true} * @static */ -export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey, filename, armor=true, detached=false, signature=null, returnSessionKey=false, wildcard=false}) { +export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey, filename, compression=config.compression, armor=true, detached=false, signature=null, returnSessionKey=false, wildcard=false}) { checkData(data); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords); if (!nativeAEAD() && asyncProxy) { // use web worker if web crypto apis are not supported @@ -223,6 +224,7 @@ export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey, message = await message.sign(privateKeys, signature); } } + message = message.compress(compression); return message.encrypt(publicKeys, passwords, sessionKey, wildcard); }).then(encrypted => { diff --git a/src/packet/compressed.js b/src/packet/compressed.js index 88695aaf..b63ef6a7 100644 --- a/src/packet/compressed.js +++ b/src/packet/compressed.js @@ -88,7 +88,7 @@ Compressed.prototype.write = function () { this.compress(); } - return util.concatUint8Array(new Uint8Array([enums.write(enums.compression, this.algorithm)]), this.compressed); + return util.concatUint8Array([new Uint8Array([enums.write(enums.compression, this.algorithm)]), this.compressed]); }; diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 5bd11f81..9c502fc6 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -177,6 +177,55 @@ var twoPasswordGPGFail = ['-----BEGIN PGP MESSAGE-----', '=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}`; + + // Compression bzip2 [BZ2] is yet to be implemented. + if (compression === openpgp.enums.compression.bzip2) { + describe.skip(`${group} (not implemented --> skipping tests)`, tests); + return; + } + + 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() { + 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() { @@ -564,86 +613,101 @@ describe('OpenPGP.js public api tests', function() { }); }); - it('roundtrip workflow: encrypt, decryptSessionKeys, decrypt with pgp key pair', function() { - var 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] - }); + withCompression(function (modifyCompressionEncryptOptions, verifyCompressionDecrypted) { + it('roundtrip workflow: encrypt, decryptSessionKeys, decrypt with pgp key pair', function () { + var msgAsciiArmored; + return openpgp.encrypt(modifyCompressionEncryptOptions({ + 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) { - return openpgp.decrypt({ - sessionKeys: decryptedSessionKeys[0], - message: openpgp.message.readArmored(msgAsciiArmored) - }); + }).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); + }).then(function (decrypted) { + expect(decrypted.data).to.equal(plaintext); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('roundtrip workflow: encrypt, decryptSessionKeys, decrypt with password', function() { - var msgAsciiArmored; - return openpgp.encrypt({ - data: plaintext, - passwords: password1 - }).then(function(encrypted) { - msgAsciiArmored = encrypted.data; - return openpgp.decryptSessionKeys({ - message: openpgp.message.readArmored(msgAsciiArmored), + it('roundtrip workflow: encrypt, decryptSessionKeys, decrypt with password', function () { + var msgAsciiArmored; + return openpgp.encrypt(modifyCompressionEncryptOptions({ + 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 (decryptedSessionKeys) { + return openpgp.decrypt({ + sessionKeys: decryptedSessionKeys[0], + message: openpgp.message.readArmored(msgAsciiArmored) + }); - }).then(function(decrypted) { - expect(decrypted.data).to.equal(plaintext); + }).then(function (decrypted) { + expect(decrypted.data).to.equal(plaintext); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('roundtrip workflow: encrypt with multiple passwords, decryptSessionKeys, decrypt with multiple passwords', function() { - var msgAsciiArmored; - return openpgp.encrypt({ - data: plaintext, - passwords: [password1, password2] - }).then(function(encrypted) { - msgAsciiArmored = encrypted.data; - return openpgp.decryptSessionKeys({ - message: openpgp.message.readArmored(msgAsciiArmored), + it('roundtrip workflow: encrypt with multiple passwords, decryptSessionKeys, decrypt with multiple passwords', function () { + var msgAsciiArmored; + return openpgp.encrypt(modifyCompressionEncryptOptions({ + 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 (decryptedSessionKeys) { + return openpgp.decrypt({ + sessionKeys: decryptedSessionKeys, + message: openpgp.message.readArmored(msgAsciiArmored) + }); - }).then(function(decrypted) { - expect(decrypted.data).to.equal(plaintext); + }).then(function (decrypted) { + expect(decrypted.data).to.equal(plaintext); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('roundtrip workflow: encrypt twice with one password, decryptSessionKeys, only one session key', function() { - return openpgp.encrypt({ - data: plaintext, - passwords: [password1, password1] - }).then(function(encrypted) { - return openpgp.decryptSessionKeys({ - message: openpgp.message.readArmored(encrypted.data), - passwords: password1 + it('roundtrip workflow: encrypt twice with one password, decryptSessionKeys, only one session key', function () { + var msgAsciiArmored; + return openpgp.encrypt(modifyCompressionEncryptOptions({ + 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); + verifyCompressionDecrypted(decrypted); }); - }).then(function(decryptedSessionKeys) { - expect(decryptedSessionKeys.length).to.equal(1); }); }); }); @@ -661,647 +725,672 @@ describe('OpenPGP.js public api tests', function() { '=6XMW\r\n' + '-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n'; - beforeEach(function(done) { + beforeEach(function (done) { expect(privateKey.keys[0].decrypt(passphrase)).to.be.true; privateKey.keys[0].verifyPrimaryUser().then(() => done()); }); - it('should encrypt then decrypt', function() { - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - }; - var 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() { - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - }; - var 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() { - var privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; - privKeyDE.decrypt(passphrase); - - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - }; - var 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() { - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - wildcard: true - }; - var 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() { - var privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; - privKeyDE.decrypt(passphrase); - - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - wildcard: true - }; - var 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() { - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - returnSessionKey: true - }; - - return openpgp.encrypt(encOpt).then(function(encrypted) { - expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/); + withCompression(function (modifyCompressionEncryptOptions, verifyCompressionDecrypted) { + it('should encrypt then decrypt', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + }); var decOpt = { - sessionKeys: encrypted.sessionKey, - message: openpgp.message.readArmored(encrypted.data) + privateKeys: privateKey.keys }; - 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); + 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should encrypt using custom session key and decrypt using session key', function() { - var sessionKey = { - data: openpgp.crypto.generateSessionKey('aes256'), - algorithm: 'aes256' - }; - var encOpt = { - data: plaintext, - sessionKey: sessionKey, - publicKeys: publicKey.keys - }; - var 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 then decrypt', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should encrypt using custom session key and decrypt using private key', function() { - var sessionKey = { - data: openpgp.crypto.generateSessionKey('aes128'), - algorithm: 'aes128' - }; - var encOpt = { - data: plaintext, - sessionKeys: sessionKey, - publicKeys: publicKey.keys - }; - var 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 then decrypt with multiple private keys', function () { + var privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; + privKeyDE.decrypt(passphrase); + + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should encrypt/sign and decrypt/verify', function() { - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - privateKeys: privateKey.keys - }; - var 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 then decrypt with wildcard', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + wildcard: true + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should encrypt/sign and decrypt/verify with null string input', function() { - var encOpt = { - data: '', - publicKeys: publicKey.keys, - privateKeys: privateKey.keys - }; - var 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 then decrypt with wildcard with multiple private keys', function () { + var privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; + privKeyDE.decrypt(passphrase); + + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + wildcard: true + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should encrypt/sign and decrypt/verify with detached signatures', function() { - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - privateKeys: privateKey.keys, - detached: true - }; - var 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 then decrypt using returned session key', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + returnSessionKey: true + }); + + return openpgp.encrypt(encOpt).then(function (encrypted) { + expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should encrypt and decrypt/verify with detached signature input and detached flag set for encryption', function() { - var signOpt = { - data: plaintext, - privateKeys: privateKey.keys[0], - detached: true - }; - - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - detached: true - }; - - var 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 using custom session key and decrypt using session key', function () { + var sessionKey = { + data: openpgp.crypto.generateSessionKey('aes256'), + algorithm: 'aes256' + }; + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + sessionKey: sessionKey, + publicKeys: publicKey.keys + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should encrypt and decrypt/verify with detached signature as input and detached flag not set for encryption', function() { - var privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; - privKeyDE.decrypt(passphrase); + it('should encrypt using custom session key and decrypt using private key', function () { + var sessionKey = { + data: openpgp.crypto.generateSessionKey('aes128'), + algorithm: 'aes128' + }; + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + sessionKeys: sessionKey, + publicKeys: publicKey.keys + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); + }); - var pubKeyDE = openpgp.key.readArmored(pub_key_de).keys[0]; + it('should encrypt/sign and decrypt/verify', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + privateKeys: privateKey.keys + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); + }); - var signOpt = { - data: plaintext, - privateKeys: privKeyDE, - detached: true - }; + it('should encrypt/sign and decrypt/verify with null string input', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: '', + publicKeys: publicKey.keys, + privateKeys: privateKey.keys + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); + }); - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - privateKeys: privateKey.keys[0] - }; + it('should encrypt/sign and decrypt/verify with detached signatures', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + privateKeys: privateKey.keys, + detached: true + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); + }); - var decOpt = { - privateKeys: privateKey.keys[0], - publicKeys: [publicKey.keys[0], pubKeyDE] - }; + it('should encrypt and decrypt/verify with detached signature input and detached flag set for encryption', function () { + var signOpt = { + data: plaintext, + privateKeys: privateKey.keys[0], + detached: true + }; - 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); + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + detached: true + }); + + var 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); + verifyCompressionDecrypted(decrypted); + }); + }); + + it('should encrypt and decrypt/verify with detached signature as input and detached flag not set for encryption', function () { + var privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; + privKeyDE.decrypt(passphrase); + + var pubKeyDE = openpgp.key.readArmored(pub_key_de).keys[0]; + + var signOpt = { + data: plaintext, + privateKeys: privKeyDE, + detached: true + }; + + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + privateKeys: privateKey.keys[0] + }); + + var 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; + verifyCompressionDecrypted(decrypted); + 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() { - var signOpt = { - data: plaintext, - privateKeys: privateKey.keys, - detached: true - }; + it('should fail to encrypt and decrypt/verify with detached signature input and detached flag set for encryption with wrong public key', function () { + var signOpt = { + data: plaintext, + privateKeys: privateKey.keys, + detached: true + }; - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - detached: true - }; + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + detached: true + }); - var decOpt = { - privateKeys: privateKey.keys[0], - publicKeys: openpgp.key.readArmored(wrong_pubkey).keys - }; + var 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); + 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - 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() { - var signOpt = { - data: plaintext, - privateKeys: privateKey.keys, - detached: true - }; + 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 () { + var signOpt = { + data: plaintext, + privateKeys: privateKey.keys, + detached: true + }; - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys - }; + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys + }); - var decOpt = { - privateKeys: privateKey.keys[0], - publicKeys: openpgp.key.readArmored(wrong_pubkey).keys - }; + var 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); + 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should fail to verify decrypted data with wrong public pgp key', function() { - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - privateKeys: privateKey.keys - }; - var 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 data with wrong public pgp key', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + privateKeys: privateKey.keys + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should fail to verify decrypted null string with wrong public pgp key', function() { - var encOpt = { - data: '', - publicKeys: publicKey.keys, - privateKeys: privateKey.keys - }; - var 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 fail to verify decrypted null string with wrong public pgp key', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: '', + publicKeys: publicKey.keys, + privateKeys: privateKey.keys + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should successfully decrypt signed message without public keys to verify', function() { - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - privateKeys: privateKey.keys - }; - var 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 successfully decrypt signed message without public keys to verify', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + privateKeys: privateKey.keys + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should fail to verify decrypted data with wrong public pgp key with detached signatures', function() { - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - privateKeys: privateKey.keys, - detached: true - }; - var 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 fail to verify decrypted data with wrong public pgp key with detached signatures', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + privateKeys: privateKey.keys, + detached: true + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should encrypt and decrypt/verify both signatures when signed with two private keys', function() { - var privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; - privKeyDE.decrypt(passphrase); + it('should encrypt and decrypt/verify both signatures when signed with two private keys', function () { + var privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; + privKeyDE.decrypt(passphrase); - var pubKeyDE = openpgp.key.readArmored(pub_key_de).keys[0]; + var pubKeyDE = openpgp.key.readArmored(pub_key_de).keys[0]; - var encOpt = { - data: plaintext, - publicKeys: publicKey.keys, - privateKeys: [privateKey.keys[0], privKeyDE] - }; + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + publicKeys: publicKey.keys, + privateKeys: [privateKey.keys[0], privKeyDE] + }); - var decOpt = { - privateKeys: privateKey.keys[0], - publicKeys: [publicKey.keys[0], pubKeyDE] - }; + var 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); + 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; + verifyCompressionDecrypted(decrypted); + 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() { - var signOpt = { - data: plaintext, - privateKeys: privateKey.keys - }; - var 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', function () { + var signOpt = { + data: plaintext, + privateKeys: privateKey.keys + }; + var 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 detached signatures', function() { - var signOpt = { - data: plaintext, - privateKeys: privateKey.keys, - detached: true - }; - var 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 verify cleartext data with detached signatures', function () { + var signOpt = { + data: plaintext, + privateKeys: privateKey.keys, + detached: true + }; + var 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() { - var signOpt = { - data: plaintext, - privateKeys: privateKey.keys - }; - var 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', function () { + var signOpt = { + data: plaintext, + privateKeys: privateKey.keys + }; + var 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() { - var signOpt = { - data: plaintext, - privateKeys: privateKey.keys, - detached: true - }; - var 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 fail to verify cleartext data with wrong public pgp key with detached signature', function () { + var signOpt = { + data: plaintext, + privateKeys: privateKey.keys, + detached: true + }; + var 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() { - var signOpt = { - data: plaintext, - privateKeys: privateKey.keys, - armor: false - }; - var 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', function () { + var signOpt = { + data: plaintext, + privateKeys: privateKey.keys, + armor: false + }; + var 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() { - var signOpt = { - data: plaintext, - privateKeys: privateKey.keys, - detached: true, - armor: false - }; - var 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].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 () { + var signOpt = { + data: plaintext, + privateKeys: privateKey.keys, + detached: true, + armor: false + }; + var 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].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); + }); }); }); }); describe('ELG / DSA encrypt, decrypt, sign, verify', function() { - it('round trip test', function() { - var pubKeyDE = openpgp.key.readArmored(pub_key_de).keys[0]; - var 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, + withCompression(function (modifyCompressionEncryptOptions, verifyCompressionDecrypted) { + it('round trip test', function () { + var pubKeyDE = openpgp.key.readArmored(pub_key_de).keys[0]; + var privKeyDE = openpgp.key.readArmored(priv_key_de).keys[0]; + privKeyDE.decrypt(passphrase); + return openpgp.encrypt(modifyCompressionEncryptOptions({ publicKeys: pubKeyDE, - message: openpgp.message.readArmored(encrypted.data) - }); - }).then(function(encrypted) { - expect(encrypted.data).to.exist; - expect(encrypted.data).to.equal(plaintext); - expect(encrypted.signatures[0].valid).to.be.true; - return privKeyDE.verifyPrimaryUser().then(() => { - expect(encrypted.signatures[0].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); - expect(encrypted.signatures[0].signature.packets.length).to.equal(1); + privateKeys: privKeyDE, + data: plaintext + })).then(function (encrypted) { + return openpgp.decrypt({ + privateKeys: privKeyDE, + publicKeys: pubKeyDE, + message: openpgp.message.readArmored(encrypted.data) + }); + }).then(function (encrypted) { + expect(encrypted.data).to.exist; + expect(encrypted.data).to.equal(plaintext); + expect(encrypted.signatures[0].valid).to.be.true; + verifyCompressionDecrypted(encrypted); + return privKeyDE.verifyPrimaryUser().then(() => { + expect(encrypted.signatures[0].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); + expect(encrypted.signatures[0].signature.packets.length).to.equal(1); + }); }); }); }); @@ -1374,90 +1463,96 @@ describe('OpenPGP.js public api tests', function() { }); describe('AES encrypt, decrypt', function() { - it('should encrypt and decrypt with one password', function() { - var encOpt = { - data: plaintext, - passwords: password1 - }; - var 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); + withCompression(function (modifyCompressionEncryptOptions, verifyCompressionDecrypted) { + it('should encrypt and decrypt with one password', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + passwords: password1 + }); + var 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); + }); }); - }); - it('should encrypt and decrypt with two passwords', function() { - var encOpt = { - data: plaintext, - passwords: [password1, password2] - }; - var 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 encrypt and decrypt with two passwords', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + passwords: [password1, password2] + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should decrypt with two passwords message which GPG fails on', function() { + it('should decrypt with two passwords message which GPG fails on', function () { - var 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); + var 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() { - var encOpt = { - data: plaintext, - passwords: password1, - armor: false - }; - var 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 password and not ascii armor', function () { + var encOpt = modifyCompressionEncryptOptions({ + data: plaintext, + passwords: password1, + armor: false + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); - }); - it('should encrypt and decrypt with binary data and transferable objects', function() { - openpgp.config.zero_copy = true; // activate transferable objects - var encOpt = { - data: new Uint8Array([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]), - passwords: password1, - armor: false - }; - var 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); + it('should encrypt and decrypt with binary data and transferable objects', function () { + openpgp.config.zero_copy = true; // activate transferable objects + var encOpt = modifyCompressionEncryptOptions({ + data: new Uint8Array([0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01]), + passwords: password1, + armor: false + }); + var 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); + verifyCompressionDecrypted(decrypted); + }); }); }); }); From 7a2c3578bfaf746cb6738fe45cae82d31ab46dc7 Mon Sep 17 00:00:00 2001 From: mmso Date: Tue, 13 Feb 2018 15:25:20 +0100 Subject: [PATCH 2/5] Update README --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 9128752d..3f9ef162 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,35 @@ openpgp.decrypt(options).then(function(plaintext) { }); ``` +#### Encrypt with compression + +By default, `encrypt` will not use any compression. It's possible to override that behavior in two ways: + +Either set the `compression` parameter in the options object when calling `encrypt`. + +```js +var options, encrypted; + +options = { + data: new Uint8Array([0x01, 0x02, 0x03]), // input as Uint8Array (or String) + passwords: ['secret stuff'], // multiple passwords possible + compression: openpgp.enums.compression.zip // compress the data with zip +}; + +openpgp.encrypt(options).then(function(ciphertext) { + // use ciphertext +}); +``` + +Or, override the config to enable compression: + +```js +openpgp.config.compression = openpgp.enums.compression.zip +``` + +Where `compression` can take the value of `openpgp.enums.compression.zlib` or `openpgp.enums.compression.zip`. + + #### Generate new key pair RSA keys: From 2a504e4e1aa63f0240634a6b8bb872bcb59c8ef9 Mon Sep 17 00:00:00 2001 From: mmso Date: Tue, 13 Feb 2018 17:21:20 +0100 Subject: [PATCH 3/5] Disable spy call expecations on the web worker --- test/general/openpgp.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/test/general/openpgp.js b/test/general/openpgp.js index 9c502fc6..0990f3b3 100644 --- a/test/general/openpgp.js +++ b/test/general/openpgp.js @@ -210,6 +210,11 @@ function withCompression(tests) { 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; @@ -632,7 +637,6 @@ describe('OpenPGP.js public api tests', function() { sessionKeys: decryptedSessionKeys[0], message }); - }).then(function (decrypted) { expect(decrypted.data).to.equal(plaintext); verifyCompressionDecrypted(decrypted); @@ -1382,14 +1386,13 @@ describe('OpenPGP.js public api tests', function() { publicKeys: pubKeyDE, message: openpgp.message.readArmored(encrypted.data) }); - }).then(function (encrypted) { - expect(encrypted.data).to.exist; - expect(encrypted.data).to.equal(plaintext); - expect(encrypted.signatures[0].valid).to.be.true; - verifyCompressionDecrypted(encrypted); + }).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(encrypted.signatures[0].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); - expect(encrypted.signatures[0].signature.packets.length).to.equal(1); + expect(decrypted.signatures[0].keyid.toHex()).to.equal(privKeyDE.getSigningKeyPacket().getKeyId().toHex()); + expect(decrypted.signatures[0].signature.packets.length).to.equal(1); }); }); }); From c855fd4e4e5583d5735c73235afebb22e36b9b1d Mon Sep 17 00:00:00 2001 From: Bart Butler Date: Tue, 13 Feb 2018 10:58:55 -0800 Subject: [PATCH 4/5] Update message.js doc fix --- src/message.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/message.js b/src/message.js index c392fddd..dfd60da3 100644 --- a/src/message.js +++ b/src/message.js @@ -454,7 +454,7 @@ Message.prototype.sign = async function(privateKeys=[], signature=null) { /** * Compresses the message (the literal and -if signed- signature data packets of the message) * @param {module:enums.compression} compression compression algorithm to be used - * @return {module:message~Message} new message with signed content + * @return {module:message~Message} new message with compressed content */ Message.prototype.compress = function(compression) { if (compression === enums.compression.uncompressed) { From 8873ed0ff1b8310398fdc79dcb4403fb14cd9785 Mon Sep 17 00:00:00 2001 From: Bart Butler Date: Tue, 13 Feb 2018 11:01:09 -0800 Subject: [PATCH 5/5] Update openpgp.js doc fix --- src/openpgp.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/openpgp.js b/src/openpgp.js index 99d368aa..8181351e 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -186,21 +186,21 @@ export function decryptKey({ privateKey, passphrase }) { /** * Encrypts message text/data with public keys, passwords or both at once. At least either public keys or passwords * must be specified. If private keys are specified, those will be used to sign the message. - * @param {String|Uint8Array} data text/data to be encrypted as JavaScript binary string or Uint8Array - * @param {Key|Array} publicKeys (optional) array of keys or single key, used to encrypt the message - * @param {Key|Array} privateKeys (optional) private keys for signing. If omitted message will not be signed - * @param {String|Array} passwords (optional) array of passwords or a single password to encrypt the message - * @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String } - * @param {String} filename (optional) a filename for the literal data packet - * @param {Boolean} compression (optional) which compression algorithm to compress the message with, defaults to what is specified in config - * @param {Boolean} armor (optional) if the return values should be ascii armored or the message/signature objects - * @param {Boolean} detached (optional) if the signature should be detached (if true, signature will be added to returned object) - * @param {Signature} signature (optional) a detached signature to add to the encrypted message - * @param {Boolean} returnSessionKey (optional) if the unencrypted session key should be added to returned object - * @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs - * @return {Promise} encrypted (and optionally signed message) in the form: - * {data: ASCII armored message if 'armor' is true, - * message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true} + * @param {String|Uint8Array} data text/data to be encrypted as JavaScript binary string or Uint8Array + * @param {Key|Array} publicKeys (optional) array of keys or single key, used to encrypt the message + * @param {Key|Array} privateKeys (optional) private keys for signing. If omitted message will not be signed + * @param {String|Array} passwords (optional) array of passwords or a single password to encrypt the message + * @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String } + * @param {String} filename (optional) a filename for the literal data packet + * @param {module:enums.compression} compression (optional) which compression algorithm to compress the message with, defaults to what is specified in config + * @param {Boolean} armor (optional) if the return values should be ascii armored or the message/signature objects + * @param {Boolean} detached (optional) if the signature should be detached (if true, signature will be added to returned object) + * @param {Signature} signature (optional) a detached signature to add to the encrypted message + * @param {Boolean} returnSessionKey (optional) if the unencrypted session key should be added to returned object + * @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs + * @return {Promise} encrypted (and optionally signed message) in the form: + * {data: ASCII armored message if 'armor' is true, + * message: full Message object if 'armor' is false, signature: detached signature if 'detached' is true} * @static */ export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey, filename, compression=config.compression, armor=true, detached=false, signature=null, returnSessionKey=false, wildcard=false}) {