Check session key size on v3 SKESK and PKESK packet decryption

For v3 SKESK and PKESK packets, the session key algorithm is part of the payload,
so we can check the session key size on packet decryption.
This is helpful to catch errors early, when using e.g. `decryptSessionKeys`.

In v6 packets, the session key size check can only be done on SEIPDv2 decryption.
This commit is contained in:
larabr 2024-10-17 17:29:04 +02:00
parent e58c02d5ee
commit 3cdaab7894
5 changed files with 18 additions and 11 deletions

View File

@ -208,11 +208,14 @@ class PublicKeyEncryptedSessionKeyPacket {
const { sessionKey, sessionKeyAlgorithm } = decodeSessionKey(this.version, this.publicKeyAlgorithm, decryptedData, randomSessionKey);
// v3 Montgomery curves have cleartext cipher algo
if (this.version === 3 && (
this.publicKeyAlgorithm !== enums.publicKey.x25519 && this.publicKeyAlgorithm !== enums.publicKey.x448)
) {
this.sessionKeyAlgorithm = sessionKeyAlgorithm;
if (this.version === 3) {
// v3 Montgomery curves have cleartext cipher algo
const hasEncryptedAlgo = this.publicKeyAlgorithm !== enums.publicKey.x25519 && this.publicKeyAlgorithm !== enums.publicKey.x448;
this.sessionKeyAlgorithm = hasEncryptedAlgo ? sessionKeyAlgorithm : this.sessionKeyAlgorithm;
if (sessionKey.length !== crypto.getCipherParams(this.sessionKeyAlgorithm).keySize) {
throw new Error('Unexpected session key size');
}
}
this.sessionKey = sessionKey;
}

View File

@ -56,7 +56,7 @@ class SymEncryptedSessionKeyPacket {
* Algorithm to encrypt the message with
* @type {enums.symmetric}
*/
this.sessionKeyAlgorithm = enums.symmetric.aes256;
this.sessionKeyAlgorithm = null;
/**
* AEAD mode to encrypt the session key with (if AEAD protection is enabled)
* @type {enums.aead}
@ -177,7 +177,11 @@ class SymEncryptedSessionKeyPacket {
this.sessionKeyAlgorithm = enums.write(enums.symmetric, decrypted[0]);
this.sessionKey = decrypted.subarray(1, decrypted.length);
if (this.sessionKey.length !== crypto.getCipherParams(this.sessionKeyAlgorithm).keySize) {
throw new Error('Unexpected session key size');
}
} else {
// session key size is checked as part of SEIPDv2 decryption, where we know the expected symmetric algo
this.sessionKey = key;
}
}

View File

@ -159,7 +159,7 @@ export default () => describe('Symmetric AES-EAX', function() {
testAESEAX();
});
describe('Symmetric AES-EAX (asm.js fallback)', function() {
describe('Symmetric AES-EAX (non-native fallback)', function() {
beforeEach(function () {
sinonSandbox = sinon.createSandbox();
disableNative();

View File

@ -77,11 +77,11 @@ export default () => describe('Symmetric AES-GCM (experimental)', function() {
testAESGCM('12345678901234567890123456789012345678901234567890', true, true);
});
describe('Symmetric AES-GCM (asm.js fallback)', function() {
describe('Symmetric AES-GCM (non-native)', function() {
testAESGCM('12345678901234567890123456789012345678901234567890', false, false);
});
describe('Symmetric AES-GCM (native encrypt, asm.js decrypt)', function() {
describe('Symmetric AES-GCM (native encrypt, non-native decrypt)', function() {
testAESGCM('12345678901234567890123456789012345678901234567890', true, false);
});
});

View File

@ -2532,7 +2532,7 @@ XfA3pqV4mTzF
}
});
tryTests('CFB mode (asm.js)', tests, {
tryTests('CFB mode', tests, {
if: true,
beforeEach: function() {
openpgp.config.aeadProtect = false;
@ -2582,7 +2582,7 @@ XfA3pqV4mTzF
function tests() {
describe('encryptSessionKey, decryptSessionKeys', function() {
const sk = new Uint8Array([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]);
const sk = new Uint8Array([0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01]);
let decryptedPrivateKey; // to avoid decrypting key before each test
beforeEach(async function() {