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