diff --git a/src/cleartext.js b/src/cleartext.js index dc50601d..93850a54 100644 --- a/src/cleartext.js +++ b/src/cleartext.js @@ -68,12 +68,12 @@ CleartextMessage.prototype.getSigningKeyIds = function() { * @param {Array} privateKeys private keys with decrypted secret key data for signing * @param {Signature} signature (optional) any existing detached signature * @param {Date} date (optional) The creation time of the signature that should be created - * @param {Object} userId (optional) user ID to sign with, e.g. { name:'Steve Sender', email:'steve@openpgp.org' } + * @param {Array} userIds (optional) user IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] * @returns {Promise} new cleartext message with signed content * @async */ -CleartextMessage.prototype.sign = async function(privateKeys, signature=null, date=new Date(), userId={}) { - return new CleartextMessage(this.text, await this.signDetached(privateKeys, signature, date, userId)); +CleartextMessage.prototype.sign = async function(privateKeys, signature=null, date=new Date(), userIds=[]) { + return new CleartextMessage(this.text, await this.signDetached(privateKeys, signature, date, userIds)); }; /** @@ -81,15 +81,15 @@ CleartextMessage.prototype.sign = async function(privateKeys, signature=null, da * @param {Array} privateKeys private keys with decrypted secret key data for signing * @param {Signature} signature (optional) any existing detached signature * @param {Date} date (optional) The creation time of the signature that should be created - * @param {Object} userId (optional) user ID to sign with, e.g. { name:'Steve Sender', email:'steve@openpgp.org' } + * @param {Array} userIds (optional) user IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] * @returns {Promise} new detached signature of message content * @async */ -CleartextMessage.prototype.signDetached = async function(privateKeys, signature=null, date=new Date(), userId={}) { +CleartextMessage.prototype.signDetached = async function(privateKeys, signature=null, date=new Date(), userIds=[]) { const literalDataPacket = new packet.Literal(); literalDataPacket.setText(this.text); - return new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, date, userId)); + return new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, date, userIds)); }; /** diff --git a/src/key.js b/src/key.js index 5588b18c..d550f3e6 100644 --- a/src/key.js +++ b/src/key.js @@ -290,7 +290,7 @@ async function getLatestValidSignature(signatures, primaryKey, signatureType, da /** * Returns last created key or key by given keyId that is available for signing and verification * @param {module:type/keyid} keyId, optional - * @param {Date} date use the given date for verification instead of the current time + * @param {Date} date (optional) use the given date for verification instead of the current time * @param {Object} userId, optional user ID * @returns {Promise} key or null if no signing key has been found * @async @@ -501,7 +501,7 @@ Key.prototype.verifyPrimaryKey = async function(date=new Date(), userId={}) { * @async */ Key.prototype.getExpirationTime = async function(capabilities, keyId, userId) { - const primaryUser = await this.getPrimaryUser(null); + const primaryUser = await this.getPrimaryUser(null, userId); if (!primaryUser) { throw new Error('Could not find primary user'); } @@ -532,7 +532,7 @@ Key.prototype.getExpirationTime = async function(capabilities, keyId, userId) { * Returns primary user and most significant (latest valid) self signature * - if multiple primary users exist, returns the one with the latest self signature * - otherwise, returns the user with the latest self signature - * @param {Date} date use the given date for verification instead of the current time + * @param {Date} date (optional) use the given date for verification instead of the current time * @param {Object} userId (optional) user ID to get instead of the primary user, if it exists * @returns {Promise<{user: module:key.User, * selfCertification: module:packet.Signature}>} The primary user and the self signature @@ -743,11 +743,13 @@ Key.prototype.applyRevocationCertificate = async function(revocationCertificate) /** * Signs primary user of key * @param {Array} privateKey decrypted private keys for signing + * @param {Date} date (optional) use the given date for verification instead of the current time + * @param {Object} userId (optional) user ID to get instead of the primary user, if it exists * @returns {Promise} new public key with new certificate signature * @async */ -Key.prototype.signPrimaryUser = async function(privateKeys) { - const { index, user } = await this.getPrimaryUser() || {}; +Key.prototype.signPrimaryUser = async function(privateKeys, date, userId) { + const { index, user } = await this.getPrimaryUser(date, userId) || {}; if (!user) { throw new Error('Could not find primary user'); } @@ -777,13 +779,15 @@ Key.prototype.signAllUsers = async function(privateKeys) { * - if no arguments are given, verifies the self certificates; * - otherwise, verifies all certificates signed with given keys. * @param {Array} keys array of keys to verify certificate signatures + * @param {Date} date (optional) use the given date for verification instead of the current time + * @param {Object} userId (optional) user ID to get instead of the primary user, if it exists * @returns {Promise>} List of signer's keyid and validity of signature * @async */ -Key.prototype.verifyPrimaryUser = async function(keys) { +Key.prototype.verifyPrimaryUser = async function(keys, date, userId) { const primaryKey = this.keyPacket; - const { user } = await this.getPrimaryUser() || {}; + const { user } = await this.getPrimaryUser(date, userId) || {}; if (!user) { throw new Error('Could not find primary user'); } @@ -1705,16 +1709,16 @@ export async function getPreferredHashAlgo(key, keyPacket, date=new Date(), user * @param {symmetric|aead} type Type of preference to return * @param {Array} keys Set of keys * @param {Date} date (optional) use the given date for verification instead of the current time - * @param {Object} userId (optional) user ID + * @param {Array} userIds (optional) user IDs * @returns {Promise} Preferred symmetric algorithm * @async */ -export async function getPreferredAlgo(type, keys, date=new Date(), userId={}) { +export async function getPreferredAlgo(type, keys, date=new Date(), userIds=[]) { const prefProperty = type === 'symmetric' ? 'preferredSymmetricAlgorithms' : 'preferredAeadAlgorithms'; const defaultAlgo = type === 'symmetric' ? enums.symmetric.aes128 : enums.aead.eax; const prioMap = {}; - await Promise.all(keys.map(async function(key) { - const primaryUser = await key.getPrimaryUser(date, userId); + await Promise.all(keys.map(async function(key, i) { + const primaryUser = await key.getPrimaryUser(date, userIds[i]); if (!primaryUser || !primaryUser.selfCertification[prefProperty]) { return defaultAlgo; } @@ -1743,14 +1747,15 @@ export async function getPreferredAlgo(type, keys, date=new Date(), userId={}) { * Returns whether aead is supported by all keys in the set * @param {Array} keys Set of keys * @param {Date} date (optional) use the given date for verification instead of the current time + * @param {Array} userIds (optional) user IDs * @returns {Promise} * @async */ -export async function isAeadSupported(keys, date=new Date(), userId={}) { +export async function isAeadSupported(keys, date=new Date(), userIds=[]) { let supported = true; // TODO replace when Promise.some or Promise.any are implemented - await Promise.all(keys.map(async function(key) { - const primaryUser = await key.getPrimaryUser(date, userId); + await Promise.all(keys.map(async function(key, i) { + const primaryUser = await key.getPrimaryUser(date, userIds[i]); if (!primaryUser || !primaryUser.selfCertification.features || !(primaryUser.selfCertification.features[0] & enums.features.aead)) { supported = false; diff --git a/src/message.js b/src/message.js index 1a5f6145..ba51eeba 100644 --- a/src/message.js +++ b/src/message.js @@ -280,12 +280,12 @@ Message.prototype.getText = function() { * @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String, [aeadAlgorithm:String] } * @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs * @param {Date} date (optional) override the creation date of the literal package - * @param {Object} userId (optional) user ID to encrypt for, e.g. { name:'Robert Receiver', email:'robert@openpgp.org' } + * @param {Array} userIds (optional) user IDs to encrypt for, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }] * @param {Boolean} streaming (optional) whether to process data as a stream * @returns {Promise} new message with encrypted content * @async */ -Message.prototype.encrypt = async function(keys, passwords, sessionKey, wildcard=false, date=new Date(), userId={}, streaming) { +Message.prototype.encrypt = async function(keys, passwords, sessionKey, wildcard=false, date=new Date(), userIds=[], streaming) { let symAlgo; let aeadAlgo; let symEncryptedPacket; @@ -298,9 +298,9 @@ Message.prototype.encrypt = async function(keys, passwords, sessionKey, wildcard aeadAlgo = sessionKey.aeadAlgorithm; sessionKey = sessionKey.data; } else if (keys && keys.length) { - symAlgo = enums.read(enums.symmetric, await getPreferredAlgo('symmetric', keys, date, userId)); - if (config.aead_protect && config.aead_protect_version === 4 && await isAeadSupported(keys, date, userId)) { - aeadAlgo = enums.read(enums.aead, await getPreferredAlgo('aead', keys, date, userId)); + symAlgo = enums.read(enums.symmetric, await getPreferredAlgo('symmetric', keys, date, userIds)); + if (config.aead_protect && config.aead_protect_version === 4 && await isAeadSupported(keys, date, userIds)) { + aeadAlgo = enums.read(enums.aead, await getPreferredAlgo('aead', keys, date, userIds)); } } else if (passwords && passwords.length) { symAlgo = enums.read(enums.symmetric, config.encryption_cipher); @@ -313,7 +313,7 @@ Message.prototype.encrypt = async function(keys, passwords, sessionKey, wildcard sessionKey = await crypto.generateSessionKey(symAlgo); } - const msg = await encryptSessionKey(sessionKey, symAlgo, aeadAlgo, keys, passwords, wildcard, date, userId); + const msg = await encryptSessionKey(sessionKey, symAlgo, aeadAlgo, keys, passwords, wildcard, date, userIds); if (config.aead_protect && (config.aead_protect_version !== 4 || aeadAlgo)) { symEncryptedPacket = new packet.SymEncryptedAEADProtected(); @@ -348,16 +348,16 @@ Message.prototype.encrypt = async function(keys, passwords, sessionKey, wildcard * @param {Array} passwords (optional) for message encryption * @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs * @param {Date} date (optional) override the date - * @param {Object} userId (optional) user ID to encrypt for, e.g. { name:'Robert Receiver', email:'robert@openpgp.org' } + * @param {Array} userIds (optional) user IDs to encrypt for, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }] * @returns {Promise} new message with encrypted content * @async */ -export async function encryptSessionKey(sessionKey, symAlgo, aeadAlgo, publicKeys, passwords, wildcard=false, date=new Date(), userId={}) { +export async function encryptSessionKey(sessionKey, symAlgo, aeadAlgo, publicKeys, passwords, wildcard=false, date=new Date(), userIds=[]) { const packetlist = new packet.List(); if (publicKeys) { const results = await Promise.all(publicKeys.map(async function(publicKey) { - const encryptionKey = await publicKey.getEncryptionKey(undefined, date, userId); + const encryptionKey = await publicKey.getEncryptionKey(undefined, date, userIds); if (!encryptionKey) { throw new Error('Could not find valid key packet for encryption in key ' + publicKey.getKeyId().toHex()); @@ -417,11 +417,11 @@ export async function encryptSessionKey(sessionKey, symAlgo, aeadAlgo, publicKey * @param {Array} privateKeys private keys with decrypted secret key data for signing * @param {Signature} signature (optional) any existing detached signature to add to the message * @param {Date} date (optional) override the creation time of the signature - * @param {Object} userId (optional) user ID to sign with, e.g. { name:'Steve Sender', email:'steve@openpgp.org' } + * @param {Array} userIds (optional) user IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] * @returns {Promise} new message with signed content * @async */ -Message.prototype.sign = async function(privateKeys=[], signature=null, date=new Date(), userId={}) { +Message.prototype.sign = async function(privateKeys=[], signature=null, date=new Date(), userIds=[]) { const packetlist = new packet.List(); const literalDataPacket = this.packets.findPacket(enums.packet.literal); @@ -455,14 +455,14 @@ Message.prototype.sign = async function(privateKeys=[], signature=null, date=new if (privateKey.isPublic()) { throw new Error('Need private key for signing'); } - const signingKey = await privateKey.getSigningKey(undefined, date, userId); + const signingKey = await privateKey.getSigningKey(undefined, date, userIds); if (!signingKey) { throw new Error('Could not find valid key packet for signing in key ' + privateKey.getKeyId().toHex()); } const onePassSig = new packet.OnePassSignature(); onePassSig.signatureType = signatureType; - onePassSig.hashAlgorithm = await getPreferredHashAlgo(privateKey, signingKey.keyPacket, date, userId); + onePassSig.hashAlgorithm = await getPreferredHashAlgo(privateKey, signingKey.keyPacket, date, userIds); onePassSig.publicKeyAlgorithm = signingKey.keyPacket.algorithm; onePassSig.issuerKeyId = signingKey.getKeyId(); if (i === privateKeys.length - 1) { @@ -504,16 +504,16 @@ Message.prototype.compress = function(compression) { * @param {Array} privateKeys private keys with decrypted secret key data for signing * @param {Signature} signature (optional) any existing detached signature * @param {Date} date (optional) override the creation time of the signature - * @param {Object} userId (optional) user ID to sign with, e.g. { name:'Steve Sender', email:'steve@openpgp.org' } + * @param {Array} userIds (optional) user IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] * @returns {Promise} new detached signature of message content * @async */ -Message.prototype.signDetached = async function(privateKeys=[], signature=null, date=new Date(), userId={}) { +Message.prototype.signDetached = async function(privateKeys=[], signature=null, date=new Date(), userIds=[]) { const literalDataPacket = this.packets.findPacket(enums.packet.literal); if (!literalDataPacket) { throw new Error('No literal data packet to sign.'); } - return new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, date, userId)); + return new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, date, userIds)); }; /** @@ -522,18 +522,19 @@ Message.prototype.signDetached = async function(privateKeys=[], signature=null, * @param {Array} privateKeys private keys with decrypted secret key data for signing * @param {Signature} signature (optional) any existing detached signature to append * @param {Date} date (optional) override the creationtime of the signature - * @param {Object} userId (optional) user ID to sign with, e.g. { name:'Steve Sender', email:'steve@openpgp.org' } + * @param {Array} userIds (optional) user IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] * @returns {Promise} list of signature packets * @async */ -export async function createSignaturePackets(literalDataPacket, privateKeys, signature=null, date=new Date(), userId={}) { +export async function createSignaturePackets(literalDataPacket, privateKeys, signature=null, date=new Date(), userIds=[]) { const packetlist = new packet.List(); // If data packet was created from Uint8Array, use binary, otherwise use text const signatureType = literalDataPacket.text === null ? enums.signature.binary : enums.signature.text; - await Promise.all(privateKeys.map(async privateKey => { + await Promise.all(privateKeys.map(async (privateKey, i) => { + const userId = userIds[i]; if (privateKey.isPublic()) { throw new Error('Need private key for signing'); } diff --git a/src/openpgp.js b/src/openpgp.js index 96c2f55d..48200d6c 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -288,8 +288,8 @@ export function encryptKey({ privateKey, passphrase }) { * @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 * @param {Date} date (optional) override the creation date of the message signature - * @param {Object} fromUserId (optional) user ID to sign with, e.g. { name:'Steve Sender', email:'steve@openpgp.org' } - * @param {Object} toUserId (optional) user ID to encrypt for, e.g. { name:'Robert Receiver', email:'robert@openpgp.org' } + * @param {Array} fromUserIds (optional) array of user IDs to sign with, one per key in `privateKeys`, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] + * @param {Array} toUserIds (optional) array of user IDs to encrypt for, one per key in `publicKeys`, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }] * @returns {Promise} Object containing encrypted (and optionally signed) message in the form: * * { @@ -302,11 +302,11 @@ export function encryptKey({ privateKey, passphrase }) { * @async * @static */ -export function encrypt({ message, publicKeys, privateKeys, passwords, sessionKey, compression=config.compression, armor=true, streaming=message&&message.fromStream, detached=false, signature=null, returnSessionKey=false, wildcard=false, date=new Date(), fromUserId={}, toUserId={} }) { - checkMessage(message); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords); +export function encrypt({ message, publicKeys, privateKeys, passwords, sessionKey, compression=config.compression, armor=true, streaming=message&&message.fromStream, detached=false, signature=null, returnSessionKey=false, wildcard=false, date=new Date(), fromUserIds=[], toUserIds=[] }) { + checkMessage(message); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords); fromUserIds = toArray(fromUserIds); toUserIds = toArray(toUserIds); if (!nativeAEAD() && asyncProxy) { // use web worker if web crypto apis are not supported - return asyncProxy.delegate('encrypt', { message, publicKeys, privateKeys, passwords, sessionKey, compression, armor, streaming, detached, signature, returnSessionKey, wildcard, date, fromUserId, toUserId }); + return asyncProxy.delegate('encrypt', { message, publicKeys, privateKeys, passwords, sessionKey, compression, armor, streaming, detached, signature, returnSessionKey, wildcard, date, fromUserIds, toUserIds }); } const result = {}; return Promise.resolve().then(async function() { @@ -315,14 +315,14 @@ export function encrypt({ message, publicKeys, privateKeys, passwords, sessionKe } if (privateKeys.length || signature) { // sign the message only if private keys or signature is specified if (detached) { - const detachedSignature = await message.signDetached(privateKeys, signature, date, fromUserId); + const detachedSignature = await message.signDetached(privateKeys, signature, date, fromUserIds); result.signature = armor ? detachedSignature.armor() : detachedSignature; } else { - message = await message.sign(privateKeys, signature, date, fromUserId); + message = await message.sign(privateKeys, signature, date, fromUserIds); } } message = message.compress(compression); - return message.encrypt(publicKeys, passwords, sessionKey, wildcard, date, toUserId, streaming); + return message.encrypt(publicKeys, passwords, sessionKey, wildcard, date, toUserIds, streaming); }).then(async encrypted => { if (armor) { @@ -405,7 +405,7 @@ export function decrypt({ message, privateKeys, passwords, sessionKeys, publicKe * @param {'web'|'node'|false} streaming (optional) whether to return data as a stream. Defaults to the type of stream `message` was created from, if any. * @param {Boolean} detached (optional) if the return value should contain a detached signature * @param {Date} date (optional) override the creation date of the signature - * @param {Object} fromUserId (optional) user ID to sign with, e.g. { name:'Steve Sender', email:'steve@openpgp.org' } + * @param {Array} fromUserIds (optional) array of user IDs to sign with, one per key in `privateKeys`, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] * @returns {Promise} Object containing signed message in the form: * * { @@ -422,23 +422,23 @@ export function decrypt({ message, privateKeys, passwords, sessionKeys, publicKe * @async * @static */ -export function sign({ message, privateKeys, armor=true, streaming=message&&message.fromStream, detached=false, date=new Date(), fromUserId={} }) { +export function sign({ message, privateKeys, armor=true, streaming=message&&message.fromStream, detached=false, date=new Date(), fromUserIds=[] }) { checkCleartextOrMessage(message); - privateKeys = toArray(privateKeys); + privateKeys = toArray(privateKeys); fromUserIds = toArray(fromUserIds); if (asyncProxy) { // use web worker if available return asyncProxy.delegate('sign', { - message, privateKeys, armor, streaming, detached, date, fromUserId + message, privateKeys, armor, streaming, detached, date, fromUserIds }); } const result = {}; return Promise.resolve().then(async function() { if (detached) { - const signature = await message.signDetached(privateKeys, undefined, date, fromUserId); + const signature = await message.signDetached(privateKeys, undefined, date, fromUserIds); result.signature = armor ? signature.armor() : signature; } else { - message = await message.sign(privateKeys, undefined, date, fromUserId); + message = await message.sign(privateKeys, undefined, date, fromUserIds); if (armor) { result.data = message.armor(); } else { @@ -509,21 +509,21 @@ export function verify({ message, publicKeys, streaming=message&&message.fromStr * @param {String|Array} passwords (optional) passwords for the message * @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs * @param {Date} date (optional) override the date - * @param {Object} toUserId (optional) user ID to encrypt for, e.g. { name:'Phil Zimmermann', email:'phil@openpgp.org' } + * @param {Array} toUserIds (optional) array of user IDs to encrypt for, one per key in `publicKeys`, e.g. [{ name:'Phil Zimmermann', email:'phil@openpgp.org' }] * @returns {Promise} the encrypted session key packets contained in a message object * @async * @static */ -export function encryptSessionKey({ data, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard=false, date=new Date(), toUserId={} }) { - checkBinary(data); checkString(algorithm, 'algorithm'); publicKeys = toArray(publicKeys); passwords = toArray(passwords); +export function encryptSessionKey({ data, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard=false, date=new Date(), toUserIds=[] }) { + checkBinary(data); checkString(algorithm, 'algorithm'); publicKeys = toArray(publicKeys); passwords = toArray(passwords); toUserIds = toArray(toUserIds); if (asyncProxy) { // use web worker if available - return asyncProxy.delegate('encryptSessionKey', { data, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard, date, toUserId }); + return asyncProxy.delegate('encryptSessionKey', { data, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard, date, toUserIds }); } return Promise.resolve().then(async function() { - return { message: await messageLib.encryptSessionKey(data, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard, date, toUserId) }; + return { message: await messageLib.encryptSessionKey(data, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard, date, toUserIds) }; }).catch(onError.bind(null, 'Error encrypting session key')); } diff --git a/test/general/key.js b/test/general/key.js index 8e1d8fbf..8210d741 100644 --- a/test/general/key.js +++ b/test/general/key.js @@ -2325,9 +2325,9 @@ VYGdb3eNlV8CfoEC publicKey.users[0].selfCertifications[0].isPrimaryUserID = true; // Set second user to prefer aes128. We will select this user. publicKey.users[1].selfCertifications[0].preferredSymmetricAlgorithms = [openpgp.enums.symmetric.aes128]; - const encrypted = await openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: publicKey, privateKeys: privateKey, toUserId: {name: 'Test User', email: 'b@c.com'}, armor: false}); + const encrypted = await openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: publicKey, privateKeys: privateKey, toUserIds: {name: 'Test User', email: 'b@c.com'}, armor: false}); expect(encrypted.message.packets[0].sessionKeyAlgorithm).to.equal('aes128'); - await expect(openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: publicKey, privateKeys: privateKey, toUserId: {name: 'Test User', email: 'c@c.com'}, armor: false})).to.be.rejectedWith('Could not find user that matches that user ID'); + await expect(openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: publicKey, privateKeys: privateKey, toUserIds: {name: 'Test User', email: 'c@c.com'}, armor: false})).to.be.rejectedWith('Could not find user that matches that user ID'); }); it('Sign - specific user', async function() { @@ -2343,11 +2343,11 @@ VYGdb3eNlV8CfoEC privateKey.users[0].userId.parse('Test User '); // Set second user to prefer aes128. We will select this user. privateKey.users[1].selfCertifications[0].preferredHashAlgorithms = [openpgp.enums.hash.sha512]; - const signed = await openpgp.sign({message: openpgp.cleartext.fromText('hello'), privateKeys: privateKey, fromUserId: {name: 'Test McTestington', email: 'test@example.com'}, armor: false}); + const signed = await openpgp.sign({message: openpgp.cleartext.fromText('hello'), privateKeys: privateKey, fromUserIds: {name: 'Test McTestington', email: 'test@example.com'}, armor: false}); expect(signed.message.signature.packets[0].hashAlgorithm).to.equal(openpgp.enums.hash.sha512); - const encrypted = await openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: publicKey, privateKeys: privateKey, fromUserId: {name: 'Test McTestington', email: 'test@example.com'}, detached: true, armor: false}); + const encrypted = await openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: publicKey, privateKeys: privateKey, fromUserIds: {name: 'Test McTestington', email: 'test@example.com'}, detached: true, armor: false}); expect(encrypted.signature.packets[0].hashAlgorithm).to.equal(openpgp.enums.hash.sha512); - await expect(openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: publicKey, privateKeys: privateKey, fromUserId: {name: 'Not Test McTestington', email: 'test@example.com'}, detached: true, armor: false})).to.be.rejectedWith('Could not find user that matches that user ID'); + await expect(openpgp.encrypt({message: openpgp.message.fromText('hello'), publicKeys: publicKey, privateKeys: privateKey, fromUserIds: {name: 'Not Test McTestington', email: 'test@example.com'}, detached: true, armor: false})).to.be.rejectedWith('Could not find user that matches that user ID'); }); it('Find a valid subkey binding signature among many invalid ones', async function() {