Skip to content

Instantly share code, notes, and snippets.

@kaworu
Last active April 11, 2020 17:06
Show Gist options
  • Save kaworu/c53df552f4461e245b115144c12111e4 to your computer and use it in GitHub Desktop.
Save kaworu/c53df552f4461e245b115144c12111e4 to your computer and use it in GitHub Desktop.
/**
* Returns an array containing all the given Key's subkeys sorted in prefered
* order for encryption.
*
* The prefered order is as follow:
* - First all the one-time keys sorted by their expiration time (closest to
* expiration first).
* - Then all the non one-time keys sorted by their creation time (more
* recently created first).
*
* @param {key/key} the OpenPGP key.
* @returns {Array<module:key/SubKey>}
*/
export async function subKeysOrderedByEncryptionPriority(key, date = new Date()) {
const toComparable = async subKey => ({
isOneTimeKey: await subKey.isOneTimeKey(key.keyPacket, date),
expire: await subKey.getExpirationTime(key.keyPacket, date),
created: subKey.keyPacket.created,
key: subKey
});
const fromComparable = obj => obj.key;
const comparableSubKeys = await Promise.all(key.getSubkeys().map(toComparable));
comparableSubKeys.sort((a, b) => {
if (!a.isOneTimeKey && !b.isOneTimeKey) {
/* last created key first */
return b.created - a.created;
} else if (a.isOneTimeKey && !b.isOneTimeKey) {
/* a first as it is a one-time key */
return -1;
} else if (b.isOneTimeKey && !a.isOneTimeKey) {
/* b first as it is a one-time key */
return 1;
} else if (a.expire && b.expire) {
/* both a and b are one-time key, we put first the one closest to its
expiration according to draft-brown-pgp-pfs-03 §2.1 */
return a.expire - b.expire;
} else { // one of the key has expired or is invalid.
/* last created key first */
return b.created - a.created;
}
});
return comparableSubKeys.map(fromComparable);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment