Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: clarify Key.clone() behaviour #1589

Merged
merged 1 commit into from
Feb 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/key/key.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,13 @@ class Key {
}

/**
* Clones the key object
* @param {Boolean} [deep=false] Whether to return a deep clone
* Clones the key object. The copy is shallow, as it references the same packet objects as the original. However, if the top-level API is used, the two key instances are effectively independent.
* @param {Boolean} [clonePrivateParams=false] Only relevant for private keys: whether the secret key paramenters should be deeply copied. This is needed if e.g. `encrypt()` is to be called either on the clone or the original key.
* @returns {Promise<Key>} Clone of the key.
*/
clone(deep = false) {
clone(clonePrivateParams = false) {
const key = new this.constructor(this.toPacketList());
if (deep) {
if (clonePrivateParams) {
key.getKeys().forEach(k => {
// shallow clone the key packets
k.keyPacket = Object.create(
Expand Down
20 changes: 20 additions & 0 deletions test/general/key.js
Original file line number Diff line number Diff line change
Expand Up @@ -3236,6 +3236,26 @@ module.exports = () => describe('Key', function() {
});
});

it('clone() - removing users or their signatures does not affect the original key', async function() {
const key = await openpgp.readKey({ armoredKey: priv_key_rsa });
const keyClone = key.clone();
expect(key.users[0].selfCertifications.length > 0).to.be.true;
expect(keyClone.users[0].selfCertifications.length > 0).to.be.true;
keyClone.users[0].selfCertifications = [];
expect(key.users[0].selfCertifications.length > 0).to.be.true;
expect(keyClone.users[0].selfCertifications.length > 0).to.be.false;
});

it('clone() - removing subkeys or their signatures does not affect the original key', async function() {
const key = await openpgp.readKey({ armoredKey: priv_key_rsa });
const keyClone = key.clone(true);
expect(key.subkeys[0].bindingSignatures.length > 0).to.be.true;
expect(keyClone.subkeys[0].bindingSignatures.length > 0).to.be.true;
keyClone.subkeys[0].bindingSignatures = [];
expect(key.subkeys[0].bindingSignatures.length > 0).to.be.true;
expect(keyClone.subkeys[0].bindingSignatures.length > 0).to.be.false;
});

it('revoke() - primary key', async function() {
const privKey = await openpgp.decryptKey({
privateKey: await openpgp.readKey({ armoredKey: priv_key_arm2 }),
Expand Down