mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2025-06-09 07:36:42 +00:00

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.
88 lines
3.2 KiB
JavaScript
88 lines
3.2 KiB
JavaScript
import sinon from 'sinon';
|
|
import { use as chaiUse, expect } from 'chai';
|
|
import chaiAsPromised from 'chai-as-promised'; // eslint-disable-line import/newline-after-import
|
|
chaiUse(chaiAsPromised);
|
|
|
|
import openpgp from '../initOpenpgp.js';
|
|
import crypto from '../../src/crypto';
|
|
import util from '../../src/util.js';
|
|
|
|
|
|
export default () => describe('Symmetric AES-GCM (experimental)', function() {
|
|
let sinonSandbox;
|
|
let getWebCryptoStub;
|
|
let getNodeCryptoStub;
|
|
|
|
beforeEach(function () {
|
|
sinonSandbox = sinon.createSandbox();
|
|
enableNative();
|
|
});
|
|
|
|
afterEach(function () {
|
|
sinonSandbox.restore();
|
|
});
|
|
|
|
const disableNative = () => {
|
|
enableNative();
|
|
// stubbed functions return undefined
|
|
getWebCryptoStub = sinonSandbox.stub(util, 'getWebCrypto');
|
|
getNodeCryptoStub = sinonSandbox.stub(util, 'getNodeCrypto');
|
|
};
|
|
const enableNative = () => {
|
|
getWebCryptoStub && getWebCryptoStub.restore();
|
|
getNodeCryptoStub && getNodeCryptoStub.restore();
|
|
};
|
|
|
|
function testAESGCM(plaintext, nativeEncrypt, nativeDecrypt) {
|
|
const aesAlgoNames = Object.keys(openpgp.enums.symmetric).filter(
|
|
algoName => algoName.substr(0,3) === 'aes'
|
|
);
|
|
aesAlgoNames.forEach(function(algoName) {
|
|
it(algoName, async function() {
|
|
const nodeCrypto = util.getNodeCrypto();
|
|
const webCrypto = util.getWebCrypto();
|
|
if (!nodeCrypto && !webCrypto) {
|
|
this.skip(); // eslint-disable-line no-invalid-this
|
|
}
|
|
const algo = openpgp.enums.write(openpgp.enums.symmetric, algoName);
|
|
const key = crypto.generateSessionKey(algo);
|
|
const iv = crypto.random.getRandomBytes(crypto.mode.gcm.ivLength);
|
|
|
|
const nativeEncryptSpy = nodeCrypto ? sinonSandbox.spy(nodeCrypto, 'createCipheriv') : sinonSandbox.spy(webCrypto, 'encrypt');
|
|
const nativeDecryptSpy = nodeCrypto ? sinonSandbox.spy(nodeCrypto, 'createDecipheriv') : sinonSandbox.spy(webCrypto, 'decrypt');
|
|
|
|
nativeEncrypt || disableNative();
|
|
let modeInstance = await crypto.mode.gcm(algo, key);
|
|
const ciphertext = await modeInstance.encrypt(util.stringToUint8Array(plaintext), iv);
|
|
enableNative();
|
|
|
|
nativeDecrypt || disableNative();
|
|
modeInstance = await crypto.mode.gcm(algo, key);
|
|
const decrypted = await modeInstance.decrypt(util.stringToUint8Array(util.uint8ArrayToString(ciphertext)), iv);
|
|
enableNative();
|
|
|
|
const decryptedStr = util.uint8ArrayToString(decrypted);
|
|
expect(decryptedStr).to.equal(plaintext);
|
|
|
|
if (algo !== openpgp.enums.symmetric.aes192) { // not implemented by webcrypto
|
|
// sanity check: native crypto was indeed on/off
|
|
expect(nativeEncryptSpy.called).to.equal(nativeEncrypt);
|
|
expect(nativeDecryptSpy.called).to.equal(nativeDecrypt);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
describe('Symmetric AES-GCM (native)', function() {
|
|
testAESGCM('12345678901234567890123456789012345678901234567890', true, true);
|
|
});
|
|
|
|
describe('Symmetric AES-GCM (non-native)', function() {
|
|
testAESGCM('12345678901234567890123456789012345678901234567890', false, false);
|
|
});
|
|
|
|
describe('Symmetric AES-GCM (native encrypt, non-native decrypt)', function() {
|
|
testAESGCM('12345678901234567890123456789012345678901234567890', true, false);
|
|
});
|
|
});
|