Skip to content

Commit

Permalink
OP-01-007 Algorithm Preferences ignored upon Encryption (Low)
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Oberndörfer committed Mar 18, 2014
1 parent 9f23c6a commit 22e4540
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 7 deletions.
34 changes: 34 additions & 0 deletions src/key.js
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,40 @@ function generate(keyType, numBits, userId, passphrase) {
return new Key(packetlist);
}

/**
* Returns the preferred symmetric algorithm for a set of keys
* @param {Array<module:key~Key>} keys Set of keys
* @return {enums.symmetric} Preferred symmetric algorithm
*/
function getPreferredSymAlgo(keys) {
var prioMap = {};
for (var i = 0; i < keys.length; i++) {
var primaryUser = keys[i].getPrimaryUser();
if (!primaryUser || !primaryUser.selfCertificate.preferredSymmetricAlgorithms) {
return config.encryption_cipher;
}
primaryUser.selfCertificate.preferredSymmetricAlgorithms.forEach(function(algo, index) {
var entry = prioMap[algo] || (prioMap[algo] = {prio: 0, count: 0, algo: algo});
entry.prio += 64 >> index;
entry.count++;
});
}
var prefAlgo = {prio: 0, algo: config.encryption_cipher};
for (var algo in prioMap) {
try {
if (algo !== enums.symmetric.plaintext &&
algo !== enums.symmetric.idea && // not implemented
enums.read(enums.symmetric, 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;
}

exports.Key = Key;
exports.readArmored = readArmored;
exports.generate = generate;
exports.getPreferredSymAlgo = getPreferredSymAlgo;
13 changes: 6 additions & 7 deletions src/message.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ var packet = require('./packet'),
enums = require('./enums.js'),
armor = require('./encoding/armor.js'),
config = require('./config'),
crypto = require('./crypto');
crypto = require('./crypto'),
keyModule = require('./key.js');

/**
* @class
Expand Down Expand Up @@ -144,17 +145,16 @@ Message.prototype.getText = function() {
*/
Message.prototype.encrypt = function(keys) {
var packetlist = new packet.List();
//TODO get preferred algo from signature
var sessionKey = crypto.generateSessionKey(enums.read(enums.symmetric, config.encryption_cipher));
var symAlgo = keyModule.getPreferredSymAlgo(keys);
var sessionKey = crypto.generateSessionKey(enums.read(enums.symmetric, symAlgo));
keys.forEach(function(key) {
var encryptionKeyPacket = key.getEncryptionKeyPacket();
if (encryptionKeyPacket) {
var pkESKeyPacket = new packet.PublicKeyEncryptedSessionKey();
pkESKeyPacket.publicKeyId = encryptionKeyPacket.getKeyId();
pkESKeyPacket.publicKeyAlgorithm = encryptionKeyPacket.algorithm;
pkESKeyPacket.sessionKey = sessionKey;
//TODO get preferred algo from signature
pkESKeyPacket.sessionKeyAlgorithm = enums.read(enums.symmetric, config.encryption_cipher);
pkESKeyPacket.sessionKeyAlgorithm = enums.read(enums.symmetric, symAlgo);
pkESKeyPacket.encrypt(encryptionKeyPacket);
packetlist.push(pkESKeyPacket);
} else {
Expand All @@ -168,8 +168,7 @@ Message.prototype.encrypt = function(keys) {
symEncryptedPacket = new packet.SymmetricallyEncrypted();
}
symEncryptedPacket.packets = this.packets;
//TODO get preferred algo from signature
symEncryptedPacket.encrypt(enums.read(enums.symmetric, config.encryption_cipher), sessionKey);
symEncryptedPacket.encrypt(enums.read(enums.symmetric, symAlgo), sessionKey);
packetlist.push(symEncryptedPacket);
// remove packets after encryption
symEncryptedPacket.packets = new packet.List();
Expand Down
24 changes: 24 additions & 0 deletions test/general/key.js
Original file line number Diff line number Diff line change
Expand Up @@ -454,5 +454,29 @@ describe('Key', function() {
expect(dest.update.bind(dest, source)).to.throw('Cannot update public key with private key if subkey mismatch');
});

it('getPreferredSymAlgo() - one key - AES256', function() {
var key1 = openpgp.key.readArmored(twoKeys).keys[0];
var prefAlgo = openpgp.key.getPreferredSymAlgo([key1]);
expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes256);
});

it('getPreferredSymAlgo() - two key - AES192', function() {
var keys = openpgp.key.readArmored(twoKeys).keys;
var key1 = keys[0];
var key2 = keys[1];
key2.getPrimaryUser().selfCertificate.preferredSymmetricAlgorithms = [6,8,3];
var prefAlgo = openpgp.key.getPreferredSymAlgo([key1, key2]);
expect(prefAlgo).to.equal(openpgp.enums.symmetric.aes192);
});

it('getPreferredSymAlgo() - two key - one without pref', function() {
var keys = openpgp.key.readArmored(twoKeys).keys;
var key1 = keys[0];
var key2 = keys[1];
key2.getPrimaryUser().selfCertificate.preferredSymmetricAlgorithms = null;
var prefAlgo = openpgp.key.getPreferredSymAlgo([key1, key2]);
expect(prefAlgo).to.equal(openpgp.config.encryption_cipher);
});

});

0 comments on commit 22e4540

Please sign in to comment.