Slightly simplifies key.js; adds key.verifyKeyPackets which should be run before getEncryption/SigningKeyPacket
This commit is contained in:
parent
354b961b67
commit
ec22dabac3
|
@ -53,6 +53,8 @@ export default {
|
||||||
* @property {Boolean} password_collision_check
|
* @property {Boolean} password_collision_check
|
||||||
*/
|
*/
|
||||||
password_collision_check: false,
|
password_collision_check: false,
|
||||||
|
/** @property {Boolean} revocations_expire If true, expired revocation signatures are ignored */
|
||||||
|
revocations_expire: false,
|
||||||
|
|
||||||
/** @property {Boolean} use_native Use native Node.js crypto/zlib and WebCrypto APIs when available */
|
/** @property {Boolean} use_native Use native Node.js crypto/zlib and WebCrypto APIs when available */
|
||||||
use_native: true,
|
use_native: true,
|
||||||
|
|
|
@ -234,13 +234,6 @@ const ECDSASignature = nodeCrypto ?
|
||||||
);
|
);
|
||||||
}) : undefined;
|
}) : undefined;
|
||||||
|
|
||||||
const ECParameters = nodeCrypto ?
|
|
||||||
asn1.define('ECParameters', function() {
|
|
||||||
this.choice({
|
|
||||||
namedCurve: this.objid()
|
|
||||||
});
|
|
||||||
}) : undefined;
|
|
||||||
|
|
||||||
const ECPrivateKey = nodeCrypto ?
|
const ECPrivateKey = nodeCrypto ?
|
||||||
asn1.define('ECPrivateKey', function() {
|
asn1.define('ECPrivateKey', function() {
|
||||||
this.seq().obj(
|
this.seq().obj(
|
||||||
|
|
671
src/key.js
671
src/key.js
File diff suppressed because it is too large
Load Diff
|
@ -148,24 +148,23 @@ Message.prototype.decryptSessionKeys = async function(privateKeys, passwords) {
|
||||||
if (!symESKeyPacketlist) {
|
if (!symESKeyPacketlist) {
|
||||||
throw new Error('No symmetrically encrypted session key packet found.');
|
throw new Error('No symmetrically encrypted session key packet found.');
|
||||||
}
|
}
|
||||||
await Promise.all(symESKeyPacketlist.map(async function(packet) {
|
await Promise.all(symESKeyPacketlist.map(async function(keyPacket) {
|
||||||
await Promise.all(passwords.map(async function(password) {
|
await Promise.all(passwords.map(async function(password) {
|
||||||
try {
|
try {
|
||||||
await packet.decrypt(password);
|
await keyPacket.decrypt(password);
|
||||||
keyPackets.push(packet);
|
keyPackets.push(keyPacket);
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
} else if (privateKeys) {
|
} else if (privateKeys) {
|
||||||
const pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
|
const pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
|
||||||
if (!pkESKeyPacketlist) {
|
if (!pkESKeyPacketlist) {
|
||||||
throw new Error('No public key encrypted session key packet found.');
|
throw new Error('No public key encrypted session key packet found.');
|
||||||
}
|
}
|
||||||
await Promise.all(pkESKeyPacketlist.map(async function(packet) {
|
await Promise.all(pkESKeyPacketlist.map(async function(keyPacket) {
|
||||||
const privateKeyPackets = privateKeys.reduce(function(acc, privateKey) {
|
const privateKeyPackets = privateKeys.reduce(function(acc, privateKey) {
|
||||||
return acc.concat(privateKey.getKeyPackets(packet.publicKeyId));
|
return acc.concat(privateKey.getKeyPackets(keyPacket.publicKeyId));
|
||||||
}, []);
|
}, new packet.List());
|
||||||
await Promise.all(privateKeyPackets.map(async function(privateKeyPacket) {
|
await Promise.all(privateKeyPackets.map(async function(privateKeyPacket) {
|
||||||
if (!privateKeyPacket) {
|
if (!privateKeyPacket) {
|
||||||
return;
|
return;
|
||||||
|
@ -174,8 +173,8 @@ Message.prototype.decryptSessionKeys = async function(privateKeys, passwords) {
|
||||||
throw new Error('Private key is not decrypted.');
|
throw new Error('Private key is not decrypted.');
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await packet.decrypt(privateKeyPacket);
|
await keyPacket.decrypt(privateKeyPacket);
|
||||||
keyPackets.push(packet);
|
keyPackets.push(keyPacket);
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
|
@ -302,7 +301,7 @@ export async function encryptSessionKey(sessionKey, symAlgo, publicKeys, passwor
|
||||||
|
|
||||||
if (publicKeys) {
|
if (publicKeys) {
|
||||||
const results = await Promise.all(publicKeys.map(async function(key) {
|
const results = await Promise.all(publicKeys.map(async function(key) {
|
||||||
await key.verifyPrimaryUser();
|
await key.verifyKeyPackets(undefined, date);
|
||||||
const encryptionKeyPacket = key.getEncryptionKeyPacket(undefined, date);
|
const encryptionKeyPacket = key.getEncryptionKeyPacket(undefined, date);
|
||||||
if (!encryptionKeyPacket) {
|
if (!encryptionKeyPacket) {
|
||||||
throw new Error('Could not find valid key packet for encryption in key ' + key.primaryKey.getKeyId().toHex());
|
throw new Error('Could not find valid key packet for encryption in key ' + key.primaryKey.getKeyId().toHex());
|
||||||
|
@ -318,7 +317,6 @@ export async function encryptSessionKey(sessionKey, symAlgo, publicKeys, passwor
|
||||||
}));
|
}));
|
||||||
packetlist.concat(results);
|
packetlist.concat(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (passwords) {
|
if (passwords) {
|
||||||
const testDecrypt = async function(keyPacket, password) {
|
const testDecrypt = async function(keyPacket, password) {
|
||||||
try {
|
try {
|
||||||
|
@ -396,7 +394,7 @@ Message.prototype.sign = async function(privateKeys=[], signature=null, date=new
|
||||||
if (privateKey.isPublic()) {
|
if (privateKey.isPublic()) {
|
||||||
throw new Error('Need private key for signing');
|
throw new Error('Need private key for signing');
|
||||||
}
|
}
|
||||||
await privateKey.verifyPrimaryUser();
|
await privateKey.verifyKeyPackets(undefined, date);
|
||||||
const signingKeyPacket = privateKey.getSigningKeyPacket(undefined, date);
|
const signingKeyPacket = privateKey.getSigningKeyPacket(undefined, date);
|
||||||
if (!signingKeyPacket) {
|
if (!signingKeyPacket) {
|
||||||
throw new Error('Could not find valid key packet for signing in key ' +
|
throw new Error('Could not find valid key packet for signing in key ' +
|
||||||
|
@ -475,10 +473,11 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
|
||||||
if (privateKey.isPublic()) {
|
if (privateKey.isPublic()) {
|
||||||
throw new Error('Need private key for signing');
|
throw new Error('Need private key for signing');
|
||||||
}
|
}
|
||||||
await privateKey.verifyPrimaryUser();
|
await privateKey.verifyKeyPackets(undefined, date);
|
||||||
const signingKeyPacket = privateKey.getSigningKeyPacket(undefined, date);
|
const signingKeyPacket = privateKey.getSigningKeyPacket(undefined, date);
|
||||||
if (!signingKeyPacket) {
|
if (!signingKeyPacket) {
|
||||||
throw new Error('Could not find valid key packet for signing in key ' + privateKey.primaryKey.getKeyId().toHex());
|
throw new Error('Could not find valid key packet for signing in key ' +
|
||||||
|
privateKey.primaryKey.getKeyId().toHex());
|
||||||
}
|
}
|
||||||
if (!signingKeyPacket.isDecrypted) {
|
if (!signingKeyPacket.isDecrypted) {
|
||||||
throw new Error('Private key is not decrypted.');
|
throw new Error('Private key is not decrypted.');
|
||||||
|
@ -545,15 +544,14 @@ export async function createVerificationObjects(signatureList, literalDataList,
|
||||||
return Promise.all(signatureList.map(async function(signature) {
|
return Promise.all(signatureList.map(async function(signature) {
|
||||||
let keyPacket = null;
|
let keyPacket = null;
|
||||||
await Promise.all(keys.map(async function(key) {
|
await Promise.all(keys.map(async function(key) {
|
||||||
await key.verifyPrimaryUser();
|
|
||||||
// Look for the unique key packet that matches issuerKeyId of signature
|
// Look for the unique key packet that matches issuerKeyId of signature
|
||||||
|
await key.verifyKeyPackets(signature.issuerKeyId, date);
|
||||||
const result = key.getSigningKeyPacket(signature.issuerKeyId, date);
|
const result = key.getSigningKeyPacket(signature.issuerKeyId, date);
|
||||||
if (result) {
|
if (result) {
|
||||||
keyPacket = result;
|
keyPacket = result;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Look for the unique key packet that matches issuerKeyId of signature
|
|
||||||
const verifiedSig = {
|
const verifiedSig = {
|
||||||
keyid: signature.issuerKeyId,
|
keyid: signature.issuerKeyId,
|
||||||
valid: keyPacket ? await signature.verify(keyPacket, literalDataList[0]) : null
|
valid: keyPacket ? await signature.verify(keyPacket, literalDataList[0]) : null
|
||||||
|
|
|
@ -177,6 +177,19 @@ Packetlist.prototype.some = async function (callback) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the callback function once for each element,
|
||||||
|
* returns true if all callbacks returns a truthy value
|
||||||
|
*/
|
||||||
|
Packetlist.prototype.every = function (callback) {
|
||||||
|
for (let i = 0; i < this.length; i++) {
|
||||||
|
if (!callback(this[i], i, this)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traverses packet tree and returns first matching packet
|
* Traverses packet tree and returns first matching packet
|
||||||
* @param {module:enums.packet} type The packet type
|
* @param {module:enums.packet} type The packet type
|
||||||
|
@ -240,6 +253,7 @@ Packetlist.prototype.concat = function (packetlist) {
|
||||||
this.push(packetlist[i]);
|
this.push(packetlist[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -86,6 +86,7 @@ export default function Signature(date=new Date()) {
|
||||||
this.embeddedSignature = null;
|
this.embeddedSignature = null;
|
||||||
|
|
||||||
this.verified = null;
|
this.verified = null;
|
||||||
|
this.revoked = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -53,7 +53,7 @@ Keyid.prototype.toHex = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
Keyid.prototype.equals = function(keyid) {
|
Keyid.prototype.equals = function(keyid) {
|
||||||
return this.bytes === keyid.bytes;
|
return keyid.isWildcard() || this.bytes === keyid.bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
Keyid.prototype.isNull = function() {
|
Keyid.prototype.isNull = function() {
|
||||||
|
|
|
@ -1278,10 +1278,11 @@ describe('Key', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Find a valid subkey binding signature among many invalid ones', function(done) {
|
it('Find a valid subkey binding signature among many invalid ones', function() {
|
||||||
const k = openpgp.key.readArmored(valid_binding_sig_among_many_expired_sigs_pub).keys[0];
|
const k = openpgp.key.readArmored(valid_binding_sig_among_many_expired_sigs_pub).keys[0];
|
||||||
expect(k.getEncryptionKeyPacket()).to.not.be.null;
|
return k.verifyKeyPackets().then(() => {
|
||||||
done();
|
expect(k.getEncryptionKeyPacket()).to.not.be.null;
|
||||||
|
})
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -448,8 +448,7 @@ describe("Signature", function() {
|
||||||
const pubKey = openpgp.key.readArmored(pub_key_arm2).keys[0];
|
const pubKey = openpgp.key.readArmored(pub_key_arm2).keys[0];
|
||||||
const privKey = openpgp.key.readArmored(priv_key_arm2).keys[0];
|
const privKey = openpgp.key.readArmored(priv_key_arm2).keys[0];
|
||||||
|
|
||||||
const keyids = esMsg.getEncryptionKeyIds();
|
esMsg.getEncryptionKeyIds().map(keyId => privKey.decrypt('hello world', keyId));
|
||||||
privKey.decryptKeyPacket(keyids, 'hello world');
|
|
||||||
|
|
||||||
return openpgp.decrypt({ privateKeys: 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.exist;
|
||||||
|
@ -483,8 +482,7 @@ describe("Signature", function() {
|
||||||
const pubKey = openpgp.key.readArmored(pub_key_arm2).keys[0];
|
const pubKey = openpgp.key.readArmored(pub_key_arm2).keys[0];
|
||||||
const privKey = openpgp.key.readArmored(priv_key_arm2).keys[0];
|
const privKey = openpgp.key.readArmored(priv_key_arm2).keys[0];
|
||||||
|
|
||||||
const keyids = esMsg.getEncryptionKeyIds();
|
esMsg.getEncryptionKeyIds().map(keyId => privKey.decrypt('hello world', keyId));
|
||||||
privKey.decryptKeyPacket(keyids, 'hello world');
|
|
||||||
|
|
||||||
return openpgp.decrypt({ privateKeys: 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.exist;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user