Don't mutate key in openpgp.encryptKey/decryptKey
This commit is contained in:
parent
9394fec1f4
commit
76a8f11780
|
@ -158,6 +158,21 @@ Key.prototype.toPacketlist = function() {
|
|||
return packetlist;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clones the key object
|
||||
* @param {type/keyid} deep Whether to clone each packet, in addition to the list of packets
|
||||
* @returns {Promise<module:key.Key>} cloned key
|
||||
* @async
|
||||
*/
|
||||
Key.prototype.clone = async function(deep = false) {
|
||||
if (deep) {
|
||||
const packetlist = new packet.List();
|
||||
await packetlist.read(this.toPacketlist().write());
|
||||
return new Key(packetlist);
|
||||
}
|
||||
return new Key(this.toPacketlist());
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array containing all public or private subkeys matching keyId;
|
||||
* If keyId is not present, returns all subkeys.
|
||||
|
@ -713,7 +728,7 @@ Key.prototype.revoke = async function({
|
|||
throw new Error('Need private key for revoking');
|
||||
}
|
||||
const dataToSign = { key: this.keyPacket };
|
||||
const key = new Key(this.toPacketlist());
|
||||
const key = await this.clone();
|
||||
key.revocationSignatures.push(await helper.createSignaturePacket(dataToSign, null, this.keyPacket, {
|
||||
signatureType: enums.signature.key_revocation,
|
||||
reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
|
||||
|
@ -764,7 +779,7 @@ Key.prototype.applyRevocationCertificate = async function(revocationCertificate)
|
|||
} catch (e) {
|
||||
throw util.wrapError('Could not verify revocation signature', e);
|
||||
}
|
||||
const key = new Key(this.toPacketlist());
|
||||
const key = await this.clone();
|
||||
key.revocationSignatures.push(revocationSignature);
|
||||
return key;
|
||||
};
|
||||
|
@ -780,7 +795,7 @@ Key.prototype.applyRevocationCertificate = async function(revocationCertificate)
|
|||
Key.prototype.signPrimaryUser = async function(privateKeys, date, userId) {
|
||||
const { index, user } = await this.getPrimaryUser(date, userId);
|
||||
const userSign = await user.sign(this.keyPacket, privateKeys);
|
||||
const key = new Key(this.toPacketlist());
|
||||
const key = await this.clone();
|
||||
key.users[index] = userSign;
|
||||
return key;
|
||||
};
|
||||
|
@ -793,7 +808,7 @@ Key.prototype.signPrimaryUser = async function(privateKeys, date, userId) {
|
|||
*/
|
||||
Key.prototype.signAllUsers = async function(privateKeys) {
|
||||
const that = this;
|
||||
const key = new Key(this.toPacketlist());
|
||||
const key = await this.clone();
|
||||
key.users = await Promise.all(this.users.map(function(user) {
|
||||
return user.sign(that.keyPacket, privateKeys);
|
||||
}));
|
||||
|
|
|
@ -242,15 +242,15 @@ export function revokeKey({
|
|||
* @returns {Promise<Object>} the unlocked key object in the form: { key:Key }
|
||||
* @async
|
||||
*/
|
||||
export function decryptKey({ privateKey, passphrase }) {
|
||||
export function decryptKey({ privateKey, passphrase }, fromWorker = false) {
|
||||
if (asyncProxy) { // use web worker if available
|
||||
return asyncProxy.delegate('decryptKey', { privateKey, passphrase });
|
||||
}
|
||||
|
||||
return Promise.resolve().then(async function() {
|
||||
await privateKey.decrypt(passphrase);
|
||||
|
||||
return privateKey;
|
||||
const key = fromWorker ? privateKey : await privateKey.clone(true);
|
||||
await key.decrypt(passphrase);
|
||||
return key;
|
||||
}).catch(onError.bind(null, 'Error decrypting private key'));
|
||||
}
|
||||
|
||||
|
@ -261,16 +261,16 @@ export function decryptKey({ privateKey, passphrase }) {
|
|||
* @returns {Promise<Object>} the locked key object in the form: { key:Key }
|
||||
* @async
|
||||
*/
|
||||
export function encryptKey({ privateKey, passphrase }) {
|
||||
export function encryptKey({ privateKey, passphrase }, fromWorker = false) {
|
||||
if (asyncProxy) { // use web worker if available
|
||||
return asyncProxy.delegate('encryptKey', { privateKey, passphrase });
|
||||
}
|
||||
|
||||
return Promise.resolve().then(async function() {
|
||||
await privateKey.encrypt(passphrase);
|
||||
|
||||
return privateKey;
|
||||
}).catch(onError.bind(null, 'Error decrypting private key'));
|
||||
const key = fromWorker ? privateKey : await privateKey.clone(true);
|
||||
await key.encrypt(passphrase);
|
||||
return key;
|
||||
}).catch(onError.bind(null, 'Error encrypting private key'));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ function delegate(id, method, options) {
|
|||
if (options.privateKeys) {
|
||||
options.privateKeys = options.privateKeys.map(getCachedKey);
|
||||
}
|
||||
openpgp[method](options).then(function(data) {
|
||||
openpgp[method](options, true).then(function(data) {
|
||||
// clone packets (for web worker structured cloning algorithm)
|
||||
response({ id:id, event:'method-return', data:openpgp.packet.clone.clonePackets(data) });
|
||||
}).catch(function(e) {
|
||||
|
|
|
@ -874,6 +874,7 @@ describe('OpenPGP.js public api tests', function() {
|
|||
}).then(function(unlocked){
|
||||
expect(unlocked.getKeyId().toHex()).to.equal(privateKey.keys[0].getKeyId().toHex());
|
||||
expect(unlocked.isDecrypted()).to.be.true;
|
||||
expect(privateKey.keys[0].isDecrypted()).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user