Slightly simplifies key.js; adds key.verifyKeyPackets which should be run before getEncryption/SigningKeyPacket

This commit is contained in:
Mahrud Sayrafi 2018-03-04 07:00:44 -08:00 committed by Sanjana Rajan
parent 354b961b67
commit ec22dabac3
9 changed files with 373 additions and 367 deletions

View File

@ -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,

View File

@ -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(

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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;
}; };
/** /**

View File

@ -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;
} }
/** /**

View File

@ -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() {

View File

@ -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;
})
}); });
}); });

View File

@ -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;