Deduplicate getPreferredSymAlgo / getPreferredAEADAlgo
This commit is contained in:
parent
4568d080d5
commit
0376f49e01
57
src/key.js
57
src/key.js
|
@ -1436,31 +1436,34 @@ export async function getPreferredHashAlgo(key, date) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred symmetric algorithm for a set of keys
|
||||
* Returns the preferred symmetric/aead algorithm for a set of keys
|
||||
* @param {symmetric|aead} type Type of preference to return
|
||||
* @param {Array<module:key.Key>} keys Set of keys
|
||||
* @param {Date} date (optional) use the given date for verification instead of the current time
|
||||
* @returns {Promise<module:enums.symmetric>} Preferred symmetric algorithm
|
||||
* @async
|
||||
*/
|
||||
export async function getPreferredSymAlgo(keys, date) {
|
||||
export async function getPreferredAlgo(type, keys, date) {
|
||||
const prefProperty = type === 'symmetric' ? 'preferredSymmetricAlgorithms' : 'preferredAeadAlgorithms';
|
||||
const defaultAlgo = type === 'symmetric' ? config.encryption_cipher : config.aead_mode;
|
||||
const prioMap = {};
|
||||
await Promise.all(keys.map(async function(key) {
|
||||
const primaryUser = await key.getPrimaryUser(date);
|
||||
if (!primaryUser || !primaryUser.selfCertification.preferredSymmetricAlgorithms) {
|
||||
return config.encryption_cipher;
|
||||
if (!primaryUser || !primaryUser.selfCertification[prefProperty]) {
|
||||
return defaultAlgo;
|
||||
}
|
||||
primaryUser.selfCertification.preferredSymmetricAlgorithms.forEach(function(algo, index) {
|
||||
primaryUser.selfCertification[prefProperty].forEach(function(algo, index) {
|
||||
const entry = prioMap[algo] || (prioMap[algo] = { prio: 0, count: 0, algo: algo });
|
||||
entry.prio += 64 >> index;
|
||||
entry.count++;
|
||||
});
|
||||
}));
|
||||
let prefAlgo = { prio: 0, algo: config.encryption_cipher };
|
||||
let prefAlgo = { prio: 0, algo: defaultAlgo };
|
||||
for (const algo in prioMap) {
|
||||
try {
|
||||
if (algo !== enums.symmetric.plaintext &&
|
||||
algo !== enums.symmetric.idea && // not implemented
|
||||
enums.read(enums.symmetric, algo) && // known algorithm
|
||||
if (algo !== enums[type].plaintext &&
|
||||
algo !== enums[type].idea && // not implemented
|
||||
enums.read(enums[type], algo) && // known algorithm
|
||||
prioMap[algo].count === keys.length && // available for all keys
|
||||
prioMap[algo].prio > prefAlgo.prio) {
|
||||
prefAlgo = prioMap[algo];
|
||||
|
@ -1471,43 +1474,21 @@ export async function getPreferredSymAlgo(keys, date) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred aead algorithm for a set of keys
|
||||
* Returns whether aead is supported by all keys in the set
|
||||
* @param {Array<module:key.Key>} keys Set of keys
|
||||
* @param {Date} date (optional) use the given date for verification instead of the current time
|
||||
* @returns {Promise<module:enums.aead>} Preferred aead algorithm, or null if the public keys do not support aead
|
||||
* @returns {Promise<Boolean>}
|
||||
* @async
|
||||
*/
|
||||
export async function getPreferredAeadAlgo(keys, date) {
|
||||
let supports_aead = true;
|
||||
const prioMap = {};
|
||||
export async function isAeadSupported(keys, date) {
|
||||
let supported = true;
|
||||
// TODO replace when Promise.some or Promise.any are implemented
|
||||
await Promise.all(keys.map(async function(key) {
|
||||
const primaryUser = await key.getPrimaryUser(date);
|
||||
if (!primaryUser || !primaryUser.selfCertification.features ||
|
||||
!(primaryUser.selfCertification.features[0] & enums.features.aead)) {
|
||||
supports_aead = false;
|
||||
return;
|
||||
supported = false;
|
||||
}
|
||||
if (!primaryUser || !primaryUser.selfCertification.preferredAeadAlgorithms) {
|
||||
return config.aead_mode;
|
||||
}
|
||||
primaryUser.selfCertification.preferredAeadAlgorithms.forEach(function(algo, index) {
|
||||
const entry = prioMap[algo] || (prioMap[algo] = { prio: 0, count: 0, algo: algo });
|
||||
entry.prio += 64 >> index;
|
||||
entry.count++;
|
||||
});
|
||||
}));
|
||||
if (!supports_aead) {
|
||||
return null;
|
||||
}
|
||||
let prefAlgo = { prio: 0, algo: config.aead_mode };
|
||||
for (const algo in prioMap) {
|
||||
try {
|
||||
if (enums.read(enums.aead, algo) && // known algorithm
|
||||
prioMap[algo].count === keys.length && // available for all keys
|
||||
prioMap[algo].prio > prefAlgo.prio) {
|
||||
prefAlgo = prioMap[algo];
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
return prefAlgo.algo;
|
||||
return supported;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ import enums from './enums';
|
|||
import util from './util';
|
||||
import packet from './packet';
|
||||
import { Signature } from './signature';
|
||||
import { getPreferredHashAlgo, getPreferredSymAlgo, getPreferredAeadAlgo } from './key';
|
||||
import { getPreferredHashAlgo, getPreferredAlgo, isAeadSupported } from './key';
|
||||
|
||||
|
||||
/**
|
||||
|
@ -263,10 +263,9 @@ Message.prototype.encrypt = async function(keys, passwords, sessionKey, wildcard
|
|||
aeadAlgo = sessionKey.aeadAlgorithm;
|
||||
sessionKey = sessionKey.data;
|
||||
} else if (keys && keys.length) {
|
||||
symAlgo = enums.read(enums.symmetric, await getPreferredSymAlgo(keys, date));
|
||||
aeadAlgo = await getPreferredAeadAlgo(keys, date);
|
||||
if (aeadAlgo) {
|
||||
aeadAlgo = enums.read(enums.aead, aeadAlgo);
|
||||
symAlgo = enums.read(enums.symmetric, await getPreferredAlgo('symmetric', keys, date));
|
||||
if (config.aead_protect && config.aead_protect_version === 4 && await isAeadSupported(keys, date)) {
|
||||
aeadAlgo = enums.read(enums.aead, await getPreferredAlgo('aead', keys, date));
|
||||
}
|
||||
} else if (passwords && passwords.length) {
|
||||
symAlgo = enums.read(enums.symmetric, config.encryption_cipher);
|
||||
|
|
|
@ -1170,42 +1170,44 @@ p92yZgB3r2+f6/GIe2+7
|
|||
});
|
||||
});
|
||||
|
||||
it('getPreferredSymAlgo() - one key - AES256', async function() {
|
||||
it("getPreferredAlgo('symmetric') - one key - AES256", async function() {
|
||||
const key1 = openpgp.key.readArmored(twoKeys).keys[0];
|
||||
const prefAlgo = await openpgp.key.getPreferredSymAlgo([key1]);
|
||||
const prefAlgo = await openpgp.key.getPreferredAlgo('symmetric', [key1]);
|
||||
expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes256);
|
||||
});
|
||||
|
||||
it('getPreferredSymAlgo() - two key - AES128', async function() {
|
||||
it("getPreferredAlgo('symmetric') - two key - AES128", async function() {
|
||||
const keys = openpgp.key.readArmored(twoKeys).keys;
|
||||
const key1 = keys[0];
|
||||
const key2 = keys[1];
|
||||
const primaryUser = await key2.getPrimaryUser();
|
||||
primaryUser.selfCertification.preferredSymmetricAlgorithms = [6,7,3];
|
||||
const prefAlgo = await openpgp.key.getPreferredSymAlgo([key1, key2]);
|
||||
const prefAlgo = await openpgp.key.getPreferredAlgo('symmetric', [key1, key2]);
|
||||
expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes128);
|
||||
});
|
||||
|
||||
it('getPreferredSymAlgo() - two key - one without pref', async function() {
|
||||
it("getPreferredAlgo('symmetric') - two key - one without pref", async function() {
|
||||
const keys = openpgp.key.readArmored(twoKeys).keys;
|
||||
const key1 = keys[0];
|
||||
const key2 = keys[1];
|
||||
const primaryUser = await key2.getPrimaryUser();
|
||||
primaryUser.selfCertification.preferredSymmetricAlgorithms = null;
|
||||
const prefAlgo = await openpgp.key.getPreferredSymAlgo([key1, key2]);
|
||||
const prefAlgo = await openpgp.key.getPreferredAlgo('symmetric', [key1, key2]);
|
||||
expect(prefAlgo).to.equal(openpgp.config.encryption_cipher);
|
||||
});
|
||||
|
||||
it('getPreferredAeadAlgo() - one key - OCB', async function() {
|
||||
it("getPreferredAlgo('aead') - one key - OCB", async function() {
|
||||
const key1 = openpgp.key.readArmored(twoKeys).keys[0];
|
||||
const primaryUser = await key1.getPrimaryUser();
|
||||
primaryUser.selfCertification.features = [7]; // Monkey-patch AEAD feature flag
|
||||
primaryUser.selfCertification.preferredAeadAlgorithms = [2,1];
|
||||
const prefAlgo = await openpgp.key.getPreferredAeadAlgo([key1]);
|
||||
const prefAlgo = await openpgp.key.getPreferredAlgo('aead', [key1]);
|
||||
expect(prefAlgo).to.equal(openpgp.enums.aead.ocb);
|
||||
const supported = await openpgp.key.isAeadSupported([key1]);
|
||||
expect(supported).to.be.true;
|
||||
});
|
||||
|
||||
it('getPreferredAeadAlgo() - two key - one without pref', async function() {
|
||||
it("getPreferredAlgo('aead') - two key - one without pref", async function() {
|
||||
const keys = openpgp.key.readArmored(twoKeys).keys;
|
||||
const key1 = keys[0];
|
||||
const key2 = keys[1];
|
||||
|
@ -1214,19 +1216,23 @@ p92yZgB3r2+f6/GIe2+7
|
|||
primaryUser.selfCertification.preferredAeadAlgorithms = [2,1];
|
||||
const primaryUser2 = await key2.getPrimaryUser();
|
||||
primaryUser2.selfCertification.features = [7]; // Monkey-patch AEAD feature flag
|
||||
const prefAlgo = await openpgp.key.getPreferredAeadAlgo([key1, key2]);
|
||||
const prefAlgo = await openpgp.key.getPreferredAlgo('aead', [key1, key2]);
|
||||
expect(prefAlgo).to.equal(openpgp.config.aead_mode);
|
||||
const supported = await openpgp.key.isAeadSupported([key1, key2]);
|
||||
expect(supported).to.be.true;
|
||||
});
|
||||
|
||||
it('getPreferredAeadAlgo() - two key - one with no support', async function() {
|
||||
it("getPreferredAlgo('aead') - two key - one with no support", async function() {
|
||||
const keys = openpgp.key.readArmored(twoKeys).keys;
|
||||
const key1 = keys[0];
|
||||
const key2 = keys[1];
|
||||
const primaryUser = await key1.getPrimaryUser();
|
||||
primaryUser.selfCertification.features = [7]; // Monkey-patch AEAD feature flag
|
||||
primaryUser.selfCertification.preferredAeadAlgorithms = [2,1];
|
||||
const prefAlgo = await openpgp.key.getPreferredAeadAlgo([key1, key2]);
|
||||
expect(prefAlgo).to.be.null;
|
||||
const prefAlgo = await openpgp.key.getPreferredAlgo('aead', [key1, key2]);
|
||||
expect(prefAlgo).to.equal(openpgp.config.aead_mode);
|
||||
const supported = await openpgp.key.isAeadSupported([key1, key2]);
|
||||
expect(supported).to.be.false;
|
||||
});
|
||||
|
||||
it('Preferences of generated key', function() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user