87 lines
3.3 KiB
JavaScript
87 lines
3.3 KiB
JavaScript
const sandbox = require('sinon/lib/sinon/sandbox');
|
|
const { use: chaiUse, expect } = require('chai');
|
|
chaiUse(require('chai-as-promised'));
|
|
|
|
const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../..');
|
|
const crypto = require('../../src/crypto');
|
|
const util = require('../../src/util');
|
|
|
|
|
|
module.exports = () => describe('Symmetric AES-GCM (experimental)', function() {
|
|
let sinonSandbox;
|
|
let getWebCryptoStub;
|
|
let getNodeCryptoStub;
|
|
|
|
beforeEach(function () {
|
|
sinonSandbox = sandbox.create();
|
|
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 = webCrypto ? sinonSandbox.spy(webCrypto, 'encrypt') : sinonSandbox.spy(nodeCrypto, 'createCipheriv');
|
|
const nativeDecryptSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'decrypt') : sinonSandbox.spy(nodeCrypto, 'createDecipheriv');
|
|
|
|
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 (asm.js fallback)', function() {
|
|
testAESGCM('12345678901234567890123456789012345678901234567890', false, false);
|
|
});
|
|
|
|
describe('Symmetric AES-GCM (native encrypt, asm.js decrypt)', function() {
|
|
testAESGCM('12345678901234567890123456789012345678901234567890', true, false);
|
|
});
|
|
});
|