Merge pull request #635 from openpgpjs/multiple_keys_dec

Allow decryption with multiple keys/passwords
This commit is contained in:
Bart Butler 2018-02-12 10:34:39 -08:00 committed by GitHub
commit 90337debfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 246 additions and 147 deletions

8
npm-shrinkwrap.json generated
View File

@ -1525,7 +1525,7 @@
"browserify-rsa": "4.0.1",
"create-hash": "1.1.3",
"create-hmac": "1.1.6",
"elliptic": "git+https://github.com/openpgpjs/elliptic.git#0bd7555723b84ac2b747e00c8cea1e64e99b4f4f",
"elliptic": "git+https://github.com/openpgpjs/elliptic.git#8b8ee8475b86402b125d4ad3a863a4ccd762e48c",
"inherits": "2.0.3",
"parse-asn1": "5.1.0"
}
@ -1937,7 +1937,7 @@
"dev": true,
"requires": {
"bn.js": "4.11.8",
"elliptic": "git+https://github.com/openpgpjs/elliptic.git#0bd7555723b84ac2b747e00c8cea1e64e99b4f4f"
"elliptic": "git+https://github.com/openpgpjs/elliptic.git#8b8ee8475b86402b125d4ad3a863a4ccd762e48c"
}
},
"create-hash": {
@ -2325,7 +2325,7 @@
"dev": true
},
"elliptic": {
"version": "git+https://github.com/openpgpjs/elliptic.git#0bd7555723b84ac2b747e00c8cea1e64e99b4f4f",
"version": "git+https://github.com/openpgpjs/elliptic.git#8b8ee8475b86402b125d4ad3a863a4ccd762e48c",
"requires": {
"bn.js": "4.11.8",
"brorand": "1.1.0",
@ -5604,7 +5604,7 @@
"integrity": "sha1-1QfOzkAInFJI4J7GgmaiAwqcYyU=",
"requires": {
"asn1.js": "4.9.2",
"elliptic": "git+https://github.com/openpgpjs/elliptic.git#0bd7555723b84ac2b747e00c8cea1e64e99b4f4f",
"elliptic": "git+https://github.com/openpgpjs/elliptic.git#8b8ee8475b86402b125d4ad3a863a4ccd762e48c",
"safe-buffer": "5.1.1"
},
"dependencies": {

View File

@ -208,22 +208,23 @@ Key.prototype.getKeyIds = function() {
};
/**
* Returns first key packet for given array of key IDs
* @param {Array<module:type/keyid>} keyIds
* Returns array containing first key packet for given key ID or all key packets in the case of a wildcard ID
* @param {type/keyid>} keyIds
* @return {(module:packet/public_subkey|module:packet/public_key|
* module:packet/secret_subkey|module:packet/secret_key|null)}
*/
Key.prototype.getKeyPacket = function(keyIds) {
Key.prototype.getKeyPackets = function(packetKeyId) {
var keys = this.getAllKeyPackets();
if (packetKeyId.isWildcard()) {
return keys;
}
for (var i = 0; i < keys.length; i++) {
var keyId = keys[i].getKeyId();
for (var j = 0; j < keyIds.length; j++) {
if (keyId.equals(keyIds[j])) {
return keys[i];
}
if (keyId.equals(packetKeyId)) {
return [keys[i]];
}
}
return null;
return [];
};
/**

View File

@ -35,6 +35,7 @@ import armor from './encoding/armor';
import enums from './enums';
import util from './util';
import packet from './packet';
import type_keyid from './type/keyid';
import { Signature } from './signature';
import { getPreferredHashAlgo, getPreferredSymAlgo } from './key';
@ -91,16 +92,13 @@ Message.prototype.getSigningKeyIds = function() {
/**
* Decrypt the message. Either a private key, a session key, or a password must be specified.
* @param {Key} privateKey (optional) private key with decrypted secret data
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
* @param {String} password (optional) password used to decrypt
* @param {Array<Key>} privateKeys (optional) private keys with decrypted secret data
* @param {Array<String>} passwords (optional) passwords used to decrypt
* @param {Array<Object>} sessionKeys (optional) session keys in the form: { data:Uint8Array, algorithm:String }
* @return {Message} new message with decrypted content
*/
Message.prototype.decrypt = async function(privateKey, sessionKey, password) {
let keyObjs = sessionKey || await this.decryptSessionKeys(privateKey, password);
if (!util.isArray(keyObjs)) {
keyObjs = [keyObjs];
}
Message.prototype.decrypt = async function(privateKeys, passwords, sessionKeys) {
const keyObjs = sessionKeys || await this.decryptSessionKeys(privateKeys, passwords);
const symEncryptedPacketlist = this.packets.filterByTag(
enums.packet.symmetricallyEncrypted,
@ -140,42 +138,49 @@ Message.prototype.decrypt = async function(privateKey, sessionKey, password) {
};
/**
* Decrypt an encrypted session key either with a private key or a password.
* @param {Key} privateKey (optional) private key with decrypted secret data
* @param {String} password (optional) password used to decrypt
* Decrypt encrypted session keys either with private keys or passwords.
* @param {Array<Key>} privateKeys (optional) private keys with decrypted secret data
* @param {Array<String>} passwords (optional) passwords used to decrypt
* @return {Array<{ data:Uint8Array, algorithm:String }>} array of object with potential sessionKey, algorithm pairs
*/
Message.prototype.decryptSessionKeys = function(privateKey, password) {
Message.prototype.decryptSessionKeys = function(privateKeys, passwords) {
var keyPackets = [];
return Promise.resolve().then(async () => {
if (password) {
if (passwords) {
var symESKeyPacketlist = this.packets.filterByTag(enums.packet.symEncryptedSessionKey);
if (!symESKeyPacketlist) {
throw new Error('No symmetrically encrypted session key packet found.');
}
await Promise.all(symESKeyPacketlist.map(async function(packet) {
try {
await packet.decrypt(password);
keyPackets.push(packet);
} catch (err) {}
await Promise.all(passwords.map(async function(password) {
try {
await packet.decrypt(password);
keyPackets.push(packet);
} catch (err) {}
}));
}));
} else if (privateKey) {
} else if (privateKeys) {
var pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
if (!pkESKeyPacketlist) {
throw new Error('No public key encrypted session key packet found.');
}
var privateKeyPacket = privateKey.getKeyPacket(this.getEncryptionKeyIds());
if (!privateKeyPacket.isDecrypted) {
throw new Error('Private key is not decrypted.');
}
await Promise.all(pkESKeyPacketlist.map(async function(packet) {
if (packet.publicKeyId.equals(privateKeyPacket.getKeyId())) {
var privateKeyPackets = privateKeys.reduce(function(acc, privateKey) {
return acc.concat(privateKey.getKeyPackets(packet.publicKeyId));
}, []);
await Promise.all(privateKeyPackets.map(async function(privateKeyPacket) {
if (!privateKeyPacket) {
return;
}
if (!privateKeyPacket.isDecrypted) {
throw new Error('Private key is not decrypted.');
}
try {
await packet.decrypt(privateKeyPacket);
keyPackets.push(packet);
} catch (err) {}
}
}));
}));
} else {
throw new Error('No key or password specified.');
@ -240,9 +245,10 @@ Message.prototype.getText = function() {
* @param {Array<Key>} keys (optional) public key(s) for message encryption
* @param {Array<String>} passwords (optional) password(s) for message encryption
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
* @return {Message} new message with encrypted content
*/
Message.prototype.encrypt = function(keys, passwords, sessionKey) {
Message.prototype.encrypt = function(keys, passwords, sessionKey, wildcard=false) {
let symAlgo, msg, symEncryptedPacket;
return Promise.resolve().then(async () => {
if (sessionKey) {
@ -263,7 +269,7 @@ Message.prototype.encrypt = function(keys, passwords, sessionKey) {
sessionKey = crypto.generateSessionKey(symAlgo);
}
msg = await encryptSessionKey(sessionKey, symAlgo, keys, passwords);
msg = await encryptSessionKey(sessionKey, symAlgo, keys, passwords, wildcard);
if (config.aead_protect) {
symEncryptedPacket = new packet.SymEncryptedAEADProtected();
@ -295,9 +301,10 @@ Message.prototype.encrypt = function(keys, passwords, sessionKey) {
* @param {String} symAlgo session key algorithm
* @param {Array<Key>} publicKeys (optional) public key(s) for message encryption
* @param {Array<String>} passwords (optional) for message encryption
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
* @return {Message} new message with encrypted content
*/
export function encryptSessionKey(sessionKey, symAlgo, publicKeys, passwords) {
export function encryptSessionKey(sessionKey, symAlgo, publicKeys, passwords, wildcard=false) {
var results, packetlist = new packet.List();
return Promise.resolve().then(async () => {
@ -309,7 +316,7 @@ export function encryptSessionKey(sessionKey, symAlgo, publicKeys, passwords) {
throw new Error('Could not find valid key packet for encryption in key ' + key.primaryKey.getKeyId().toHex());
}
var pkESKeyPacket = new packet.PublicKeyEncryptedSessionKey();
pkESKeyPacket.publicKeyId = encryptionKeyPacket.getKeyId();
pkESKeyPacket.publicKeyId = wildcard ? type_keyid.wildcard() : encryptionKeyPacket.getKeyId();
pkESKeyPacket.publicKeyAlgorithm = encryptionKeyPacket.algorithm;
pkESKeyPacket.sessionKey = sessionKey;
pkESKeyPacket.sessionKeyAlgorithm = symAlgo;

View File

@ -196,16 +196,17 @@ export function decryptKey({ privateKey, passphrase }) {
* @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<Object>} 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, armor=true, detached=false, signature=null, returnSessionKey=false}) {
export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey, filename, 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
return asyncProxy.delegate('encrypt', { data, publicKeys, privateKeys, passwords, sessionKey, filename, armor, detached, signature, returnSessionKey });
return asyncProxy.delegate('encrypt', { data, publicKeys, privateKeys, passwords, sessionKey, filename, armor, detached, signature, returnSessionKey, wildcard });
}
var result = {};
return Promise.resolve().then(async function() {
@ -217,16 +218,12 @@ export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey,
if (privateKeys.length || signature) { // sign the message only if private keys or signature is specified
if (detached) {
var detachedSignature = await message.signDetached(privateKeys, signature);
if (armor) {
result.signature = detachedSignature.armor();
} else {
result.signature = detachedSignature;
}
result.signature = armor ? detachedSignature.armor() : detachedSignature;
} else {
message = await message.sign(privateKeys, signature);
}
}
return message.encrypt(publicKeys, passwords, sessionKey);
return message.encrypt(publicKeys, passwords, sessionKey, wildcard);
}).then(encrypted => {
if (armor) {
@ -245,38 +242,33 @@ export function encrypt({ data, publicKeys, privateKeys, passwords, sessionKey,
/**
* Decrypts a message with the user's private key, a session key or a password. Either a private key,
* a session key or a password must be specified.
* @param {Message} message the message object with the encrypted data
* @param {Key} privateKey (optional) private key with decrypted secret key data or session key
* @param {Key|Array<Key>} publicKeys (optional) array of public keys or single key, to verify signatures
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
* @param {String} password (optional) single password to decrypt the message
* @param {String} format (optional) return data format either as 'utf8' or 'binary'
* @param {Signature} signature (optional) detached signature for verification
* @param {Message} message the message object with the encrypted data
* @param {Key|Array<Key>} privateKeys (optional) private keys with decrypted secret key data or session key
* @param {String|Array<String>} passwords (optional) passwords to decrypt the message
* @param {Object|Array<Object>} sessionKeys (optional) session keys in the form: { data:Uint8Array, algorithm:String }
* @param {Key|Array<Key>} publicKeys (optional) array of public keys or single key, to verify signatures
* @param {String} format (optional) return data format either as 'utf8' or 'binary'
* @param {Signature} signature (optional) detached signature for verification
* @return {Promise<Object>} decrypted and verified message in the form:
* { data:Uint8Array|String, filename:String, signatures:[{ keyid:String, valid:Boolean }] }
* @static
*/
export function decrypt({ message, privateKey, publicKeys, sessionKey, password, format='utf8', signature=null }) {
checkMessage(message); publicKeys = toArray(publicKeys);
export function decrypt({ message, privateKeys, passwords, sessionKeys, publicKeys, format='utf8', signature=null }) {
checkMessage(message); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords); sessionKeys = toArray(sessionKeys);
if (!nativeAEAD() && asyncProxy) { // use web worker if web crypto apis are not supported
return asyncProxy.delegate('decrypt', { message, privateKey, publicKeys, sessionKey, password, format, signature });
return asyncProxy.delegate('decrypt', { message, privateKeys, passwords, sessionKeys, publicKeys, format, signature });
}
return message.decrypt(privateKey, sessionKey, password).then(async function(message) {
return message.decrypt(privateKeys, passwords, sessionKeys).then(async function(message) {
const result = parseMessage(message, format);
if (!publicKeys) {
publicKeys = [];
}
if (signature) {
//detached signature
result.signatures = await message.verifyDetached(signature, publicKeys);
} else {
result.signatures = await message.verify(publicKeys);
}
result.signatures = signature ? await message.verifyDetached(signature, publicKeys) : await message.verify(publicKeys);
return result;
}).catch(onError.bind(null, 'Error decrypting message'));
@ -311,21 +303,11 @@ export function sign({ data, privateKeys, armor=true, detached=false}) {
var result = {};
return Promise.resolve().then(async function() {
var message;
if (util.isString(data)) {
message = new CleartextMessage(data);
} else {
message = messageLib.fromBinary(data);
}
var message = util.isString(data) ? new CleartextMessage(data) : messageLib.fromBinary(data);
if (detached) {
var signature = await message.signDetached(privateKeys);
if (armor) {
result.signature = signature.armor();
} else {
result.signature = signature;
}
result.signature = armor ? signature.armor() : signature;
} else {
message = await message.sign(privateKeys);
if (armor) {
@ -359,18 +341,8 @@ export function verify({ message, publicKeys, signature=null }) {
return Promise.resolve().then(async function() {
var result = {};
if (CleartextMessage.prototype.isPrototypeOf(message)) {
result.data = message.getText();
} else {
result.data = message.getLiteralData();
}
if (signature) {
//detached signature
result.signatures = await message.verifyDetached(signature, publicKeys);
} else {
result.signatures = await message.verify(publicKeys);
}
result.data = CleartextMessage.prototype.isPrototypeOf(message) ? message.getText() : message.getLiteralData();
result.signatures = signature ? await message.verifyDetached(signature, publicKeys) : await message.verify(publicKeys);
return result;
}).catch(onError.bind(null, 'Error verifying cleartext signed message'));
@ -391,44 +363,45 @@ export function verify({ message, publicKeys, signature=null }) {
* @param {String} algorithm algorithm of the symmetric session key e.g. 'aes128' or 'aes256'
* @param {Key|Array<Key>} publicKeys (optional) array of public keys or single key, used to encrypt the key
* @param {String|Array<String>} passwords (optional) passwords for the message
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
* @return {Promise<Message>} the encrypted session key packets contained in a message object
* @static
*/
export function encryptSessionKey({ data, algorithm, publicKeys, passwords }) {
export function encryptSessionKey({ data, algorithm, publicKeys, passwords, wildcard=false }) {
checkBinary(data); checkString(algorithm, 'algorithm'); publicKeys = toArray(publicKeys); passwords = toArray(passwords);
if (asyncProxy) { // use web worker if available
return asyncProxy.delegate('encryptSessionKey', { data, algorithm, publicKeys, passwords });
return asyncProxy.delegate('encryptSessionKey', { data, algorithm, publicKeys, passwords, wildcard });
}
return Promise.resolve().then(async function() {
return { message: await messageLib.encryptSessionKey(data, algorithm, publicKeys, passwords) };
return { message: await messageLib.encryptSessionKey(data, algorithm, publicKeys, passwords, wildcard) };
}).catch(onError.bind(null, 'Error encrypting session key'));
}
/**
* Decrypt a symmetric session key with a private key or password. Either a private key or
* Decrypt symmetric session keys with a private key or password. Either a private key or
* a password must be specified.
* @param {Message} message a message object containing the encrypted session key packets
* @param {Key} privateKey (optional) private key with decrypted secret key data
* @param {String} password (optional) a single password to decrypt the session key
* @param {Message} message a message object containing the encrypted session key packets
* @param {Key|Array<Key} privateKeys (optional) private keys with decrypted secret key data
* @param {String|Array<String>} passwords (optional) passwords to decrypt the session key
* @return {Promise<Object|undefined>} Array of decrypted session key, algorithm pairs in form:
* { data:Uint8Array, algorithm:String }
* or 'undefined' if no key packets found
* @static
*/
export function decryptSessionKeys({ message, privateKey, password }) {
checkMessage(message);
export function decryptSessionKeys({ message, privateKeys, passwords }) {
checkMessage(message); privateKeys = toArray(privateKeys); passwords = toArray(passwords);
if (asyncProxy) { // use web worker if available
return asyncProxy.delegate('decryptSessionKeys', { message, privateKey, password });
return asyncProxy.delegate('decryptSessionKeys', { message, privateKeys, passwords });
}
return Promise.resolve().then(async function() {
return message.decryptSessionKeys(privateKey, password);
return message.decryptSessionKeys(privateKeys, passwords);
}).catch(onError.bind(null, 'Error decrypting session keys'));
}

View File

@ -61,6 +61,10 @@ Keyid.prototype.isNull = function() {
return this.bytes === '';
};
Keyid.prototype.isWildcard = function() {
return /^0+$/.test(this.toHex());
};
Keyid.mapToHex = function (keyId) {
return keyId.toHex();
};
@ -76,3 +80,9 @@ Keyid.fromId = function (hex) {
keyid.read(util.str2Uint8Array(util.hex2bin(hex)));
return keyid;
};
Keyid.wildcard = function () {
var keyid = new Keyid();
keyid.read(new Uint8Array(8));
return keyid;
};

View File

@ -186,7 +186,7 @@ describe('Elliptic Curve Cryptography', function () {
var romeo = load_priv_key('romeo');
var msg = openpgp.message.readArmored(data.juliet.message_encrypted);
return openpgp.decrypt(
{privateKey: romeo, publicKeys: [juliet], message: msg}
{privateKeys: romeo, publicKeys: [juliet], message: msg}
).then(function (result) {
expect(result).to.exist;
// trim required because https://github.com/openpgpjs/openpgpjs/issues/311
@ -206,7 +206,7 @@ describe('Elliptic Curve Cryptography', function () {
var romeo = load_pub_key('romeo');
var juliet = load_priv_key('juliet');
return openpgp.decrypt(
{privateKey: juliet, publicKeys: [romeo], message: message}
{privateKeys: juliet, publicKeys: [romeo], message: message}
).then(function (result) {
expect(result).to.exist;
expect(result.data.trim()).to.equal(data.romeo.message);

View File

@ -1004,7 +1004,7 @@ describe('Key', function() {
key = newKey;
return openpgp.message.fromText('hello').encrypt([key.key]);
}).then(function(msg) {
return msg.message.decrypt(key.key);
return msg.message.decrypt([key.key]);
}).catch(function(err) {
expect(err.message).to.equal('Private key is not decrypted.');
});
@ -1258,7 +1258,7 @@ describe('Key', function() {
return openpgp.reformatKey(opt).then(function(newKey) {
newKey = newKey.key;
return openpgp.encrypt({data: 'hello', publicKeys: newKey.toPublic(), privateKeys: newKey, armor: true}).then(function(encrypted) {
return openpgp.decrypt({message: openpgp.message.readArmored(encrypted.data), privateKey: newKey, publicKeys: newKey.toPublic()}).then(function(decrypted) {
return openpgp.decrypt({message: openpgp.message.readArmored(encrypted.data), privateKeys: newKey, publicKeys: newKey.toPublic()}).then(function(decrypted) {
expect(decrypted.data).to.equal('hello');
expect(decrypted.signatures[0].valid).to.be.true;
});

View File

@ -163,6 +163,7 @@ var passphrase = 'hello world';
var plaintext = 'short message\nnext line\n한국어/조선말';
var password1 = 'I am a password';
var password2 = 'I am another password';
var password3 = 'I am a third password';
var twoPasswordGPGFail = ['-----BEGIN PGP MESSAGE-----',
'Version: OpenPGP.js v3.0.0',
@ -494,7 +495,7 @@ describe('OpenPGP.js public api tests', function() {
publicKeys: publicKey.keys,
};
var decOpt = {
privateKey: privateKey.keys[0]
privateKeys: privateKey.keys[0]
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
decOpt.message = openpgp.message.readArmored(encrypted.data);
@ -541,7 +542,7 @@ describe('OpenPGP.js public api tests', function() {
}).then(function(encrypted) {
return openpgp.decryptSessionKeys({
message: encrypted.message,
privateKey: privateKey.keys[0]
privateKeys: privateKey.keys[0]
});
}).then(function(decrypted) {
expect(decrypted[0].data).to.deep.equal(sk);
@ -556,7 +557,7 @@ describe('OpenPGP.js public api tests', function() {
}).then(function(encrypted) {
return openpgp.decryptSessionKeys({
message: encrypted.message,
password: password1
passwords: password1
});
}).then(function(decrypted) {
expect(decrypted[0].data).to.deep.equal(sk);
@ -572,12 +573,12 @@ describe('OpenPGP.js public api tests', function() {
msgAsciiArmored = encrypted.data;
return openpgp.decryptSessionKeys({
message: openpgp.message.readArmored(msgAsciiArmored),
privateKey: privateKey.keys[0]
privateKeys: privateKey.keys[0]
});
}).then(function(decryptedSessionKeys) {
return openpgp.decrypt({
sessionKey: decryptedSessionKeys[0],
sessionKeys: decryptedSessionKeys[0],
message: openpgp.message.readArmored(msgAsciiArmored)
});
@ -595,12 +596,35 @@ describe('OpenPGP.js public api tests', function() {
msgAsciiArmored = encrypted.data;
return openpgp.decryptSessionKeys({
message: openpgp.message.readArmored(msgAsciiArmored),
password: password1
passwords: password1
});
}).then(function(decryptedSessionKeys) {
return openpgp.decrypt({
sessionKey: decryptedSessionKeys[0],
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() {
var 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)
});
@ -616,7 +640,7 @@ describe('OpenPGP.js public api tests', function() {
}).then(function(encrypted) {
return openpgp.decryptSessionKeys({
message: openpgp.message.readArmored(encrypted.data),
password: password1
passwords: password1
});
}).then(function(decryptedSessionKeys) {
expect(decryptedSessionKeys.length).to.equal(1);
@ -648,7 +672,91 @@ describe('OpenPGP.js public api tests', function() {
publicKeys: publicKey.keys,
};
var decOpt = {
privateKey: privateKey.keys[0]
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/);
@ -671,7 +779,7 @@ describe('OpenPGP.js public api tests', function() {
return openpgp.encrypt(encOpt).then(function(encrypted) {
expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/);
var decOpt = {
sessionKey: encrypted.sessionKey,
sessionKeys: encrypted.sessionKey,
message: openpgp.message.readArmored(encrypted.data)
};
return openpgp.decrypt(decOpt);
@ -693,7 +801,7 @@ describe('OpenPGP.js public api tests', function() {
publicKeys: publicKey.keys
};
var decOpt = {
sessionKey: sessionKey
sessionKeys: sessionKey
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/);
@ -711,11 +819,11 @@ describe('OpenPGP.js public api tests', function() {
};
var encOpt = {
data: plaintext,
sessionKey: sessionKey,
sessionKeys: sessionKey,
publicKeys: publicKey.keys
};
var decOpt = {
privateKey: privateKey.keys[0]
privateKeys: privateKey.keys[0]
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
expect(encrypted.data).to.match(/^-----BEGIN PGP MESSAGE/);
@ -733,7 +841,7 @@ describe('OpenPGP.js public api tests', function() {
privateKeys: privateKey.keys
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
publicKeys: publicKey.keys
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
@ -754,7 +862,7 @@ describe('OpenPGP.js public api tests', function() {
privateKeys: privateKey.keys
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
publicKeys: publicKey.keys
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
@ -776,7 +884,7 @@ describe('OpenPGP.js public api tests', function() {
detached: true
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
publicKeys: publicKey.keys
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
@ -805,7 +913,7 @@ describe('OpenPGP.js public api tests', function() {
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
publicKeys: publicKey.keys[0]
};
@ -843,7 +951,7 @@ describe('OpenPGP.js public api tests', function() {
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
publicKeys: [publicKey.keys[0], pubKeyDE]
};
@ -880,7 +988,7 @@ describe('OpenPGP.js public api tests', function() {
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
publicKeys: openpgp.key.readArmored(wrong_pubkey).keys
};
@ -912,7 +1020,7 @@ describe('OpenPGP.js public api tests', function() {
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
publicKeys: openpgp.key.readArmored(wrong_pubkey).keys
};
@ -937,7 +1045,7 @@ describe('OpenPGP.js public api tests', function() {
privateKeys: privateKey.keys
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
publicKeys: openpgp.key.readArmored(wrong_pubkey).keys
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
@ -958,7 +1066,7 @@ describe('OpenPGP.js public api tests', function() {
privateKeys: privateKey.keys
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
publicKeys: openpgp.key.readArmored(wrong_pubkey).keys
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
@ -979,7 +1087,7 @@ describe('OpenPGP.js public api tests', function() {
privateKeys: privateKey.keys
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
decOpt.message = openpgp.message.readArmored(encrypted.data);
@ -1000,7 +1108,7 @@ describe('OpenPGP.js public api tests', function() {
detached: true
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
publicKeys: openpgp.key.readArmored(wrong_pubkey).keys
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
@ -1028,7 +1136,7 @@ describe('OpenPGP.js public api tests', function() {
};
var decOpt = {
privateKey: privateKey.keys[0],
privateKeys: privateKey.keys[0],
publicKeys: [publicKey.keys[0], pubKeyDE]
};
@ -1183,7 +1291,7 @@ describe('OpenPGP.js public api tests', function() {
data: plaintext
}).then(function(encrypted) {
return openpgp.decrypt({
privateKey: privKeyDE,
privateKeys: privKeyDE,
publicKeys: pubKeyDE,
message: openpgp.message.readArmored(encrypted.data)
});
@ -1258,7 +1366,7 @@ describe('OpenPGP.js public api tests', function() {
privKey.decrypt('1234');
message = openpgp.message.readArmored(pgp_msg);
return openpgp.decrypt({ privateKey:privKey, message:message }).then(function(decrypted) {
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);
});
@ -1272,7 +1380,7 @@ describe('OpenPGP.js public api tests', function() {
passwords: password1
};
var decOpt = {
password: password1
passwords: password1
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
decOpt.message = openpgp.message.readArmored(encrypted.data);
@ -1289,7 +1397,7 @@ describe('OpenPGP.js public api tests', function() {
passwords: [password1, password2]
};
var decOpt = {
password: password2
passwords: password2
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
decOpt.message = openpgp.message.readArmored(encrypted.data);
@ -1304,7 +1412,7 @@ describe('OpenPGP.js public api tests', function() {
var decOpt = {
message: openpgp.message.readArmored(twoPasswordGPGFail),
password: password2
passwords: password2
};
return openpgp.decrypt(decOpt).then(function(decrypted) {
expect(decrypted.data).to.equal(plaintext);
@ -1319,7 +1427,7 @@ describe('OpenPGP.js public api tests', function() {
armor: false
};
var decOpt = {
password: password1
passwords: password1
};
return openpgp.encrypt(encOpt).then(function(encrypted) {
decOpt.message = encrypted.message;
@ -1338,7 +1446,7 @@ describe('OpenPGP.js public api tests', function() {
armor: false
};
var decOpt = {
password: password1,
passwords: password1,
format: 'binary'
};
return openpgp.encrypt(encOpt).then(function(encrypted) {

View File

@ -340,7 +340,7 @@ describe("Signature", function() {
var pub_key = openpgp.key.readArmored(pub_key_arm1).keys[0];
var msg = openpgp.message.readArmored(msg_arm1);
priv_key.decrypt("abcd");
return openpgp.decrypt({ privateKey: priv_key, publicKeys:[pub_key], message:msg }).then(function(decrypted) {
return openpgp.decrypt({ privateKeys: priv_key, publicKeys:[pub_key], message:msg }).then(function(decrypted) {
expect(decrypted.data).to.exist;
expect(decrypted.signatures[0].valid).to.be.true;
expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
@ -382,7 +382,7 @@ describe("Signature", function() {
var msg = openpgp.message.readArmored(msg_arm1);
priv_key_gnupg_ext.subKeys[0].subKey.decrypt("abcd");
return msg.decrypt(priv_key_gnupg_ext).then(function(msg) {
return msg.decrypt([priv_key_gnupg_ext]).then(function(msg) {
return msg.verify([pub_key]).then(verified => {
expect(verified).to.exist;
expect(verified).to.have.length(1);
@ -466,7 +466,7 @@ describe("Signature", function() {
var keyids = esMsg.getEncryptionKeyIds();
privKey.decryptKeyPacket(keyids, 'hello world');
return openpgp.decrypt({ privateKey: privKey, publicKeys:[pubKey], message:esMsg }).then(function(decrypted) {
return openpgp.decrypt({ privateKeys: privKey, publicKeys:[pubKey], message:esMsg }).then(function(decrypted) {
expect(decrypted.data).to.exist;
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures).to.have.length(1);
@ -502,7 +502,7 @@ describe("Signature", function() {
var keyids = esMsg.getEncryptionKeyIds();
privKey.decryptKeyPacket(keyids, 'hello world');
return openpgp.decrypt({ privateKey: privKey, publicKeys:[pubKey], message:esMsg }).then(function(decrypted) {
return openpgp.decrypt({ privateKeys: privKey, publicKeys:[pubKey], message:esMsg }).then(function(decrypted) {
expect(decrypted.data).to.exist;
expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures).to.have.length(1);
@ -539,8 +539,8 @@ describe("Signature", function() {
var keyids = sMsg.getSigningKeyIds();
expect(pubKey2.getKeyPacket(keyids)).to.exist;
expect(pubKey3.getKeyPacket(keyids)).to.exist;
expect(pubKey2.getKeyPackets(keyids[1])).to.not.be.empty;
expect(pubKey3.getKeyPackets(keyids[0])).to.not.be.empty;
expect(sMsg.getText()).to.equal(plaintext);
@ -586,8 +586,8 @@ describe("Signature", function() {
var keyids = csMsg.getSigningKeyIds();
expect(pubKey2.getKeyPacket(keyids)).to.exist;
expect(pubKey3.getKeyPacket(keyids)).to.exist;
expect(pubKey2.getKeyPackets(keyids[0])).to.not.be.empty;
expect(pubKey3.getKeyPackets(keyids[1])).to.not.be.empty;
return openpgp.verify({ publicKeys:[pubKey2, pubKey3], message:csMsg }).then(function(cleartextSig) {
expect(cleartextSig).to.exist;

View File

@ -174,7 +174,7 @@ describe('X25519 Cryptography', function () {
expect(night.decrypt(data['night'].pass)).to.be.true;
var msg = openpgp.message.readArmored(data['night'].message_encrypted);
return openpgp.decrypt(
{privateKey: night, publicKeys: [light], message: msg}
{privateKeys: night, publicKeys: [light], message: msg}
).then(function (result) {
expect(result).to.exist;
// trim required because https://github.com/openpgpjs/openpgpjs/issues/311
@ -194,7 +194,7 @@ describe('X25519 Cryptography', function () {
var light = load_pub_key('light');
var night = load_priv_key('night');
return openpgp.decrypt(
{privateKey: night, publicKeys: [light], message: message}
{privateKeys: night, publicKeys: [light], message: message}
).then(function (result) {
expect(result).to.exist;
expect(result.data.trim()).to.equal(data['light'].message);
@ -291,7 +291,7 @@ describe('X25519 Cryptography', function () {
// Decrypting and verifying
return openpgp.decrypt(
{ message: msg,
privateKey: bye,
privateKeys: bye,
publicKeys: [ hi.toPublic() ] }
).then(output => {
expect(output.data).to.equal('Hi, Hi wrote this but only Bye can read it!');