Fix Node 20 tests: always use NodeCrypto over WebCrypto (#1692)
This is also to uniform behaviour across Node versions for now.
This commit is contained in:
parent
96d6e76c05
commit
410dbcf1d5
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
|
@ -30,7 +30,7 @@ jobs:
|
||||||
node:
|
node:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [14.x, 16.x, 18.x]
|
node-version: [14.x, 16.x, 18.x, 20.x]
|
||||||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
||||||
|
|
||||||
name: Node ${{ matrix.node-version }}
|
name: Node ${{ matrix.node-version }}
|
||||||
|
|
|
@ -47,6 +47,25 @@ async function GCM(cipher, key) {
|
||||||
throw new Error('GCM mode supports only AES cipher');
|
throw new Error('GCM mode supports only AES cipher');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (util.getNodeCrypto()) { // Node crypto library
|
||||||
|
return {
|
||||||
|
encrypt: async function(pt, iv, adata = new Uint8Array()) {
|
||||||
|
const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
||||||
|
en.setAAD(adata);
|
||||||
|
const ct = Buffer.concat([en.update(pt), en.final(), en.getAuthTag()]); // append auth tag to ciphertext
|
||||||
|
return new Uint8Array(ct);
|
||||||
|
},
|
||||||
|
|
||||||
|
decrypt: async function(ct, iv, adata = new Uint8Array()) {
|
||||||
|
const de = new nodeCrypto.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
||||||
|
de.setAAD(adata);
|
||||||
|
de.setAuthTag(ct.slice(ct.length - tagLength, ct.length)); // read auth tag at end of ciphertext
|
||||||
|
const pt = Buffer.concat([de.update(ct.slice(0, ct.length - tagLength)), de.final()]);
|
||||||
|
return new Uint8Array(pt);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
|
if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
|
||||||
const _key = await webCrypto.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']);
|
const _key = await webCrypto.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']);
|
||||||
|
|
||||||
|
@ -69,25 +88,6 @@ async function GCM(cipher, key) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (util.getNodeCrypto()) { // Node crypto library
|
|
||||||
return {
|
|
||||||
encrypt: async function(pt, iv, adata = new Uint8Array()) {
|
|
||||||
const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
|
||||||
en.setAAD(adata);
|
|
||||||
const ct = Buffer.concat([en.update(pt), en.final(), en.getAuthTag()]); // append auth tag to ciphertext
|
|
||||||
return new Uint8Array(ct);
|
|
||||||
},
|
|
||||||
|
|
||||||
decrypt: async function(ct, iv, adata = new Uint8Array()) {
|
|
||||||
const de = new nodeCrypto.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
|
||||||
de.setAAD(adata);
|
|
||||||
de.setAuthTag(ct.slice(ct.length - tagLength, ct.length)); // read auth tag at end of ciphertext
|
|
||||||
const pt = Buffer.concat([de.update(ct.slice(0, ct.length - tagLength)), de.final()]);
|
|
||||||
return new Uint8Array(pt);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
encrypt: async function(pt, iv, adata) {
|
encrypt: async function(pt, iv, adata) {
|
||||||
return AES_GCM.encrypt(pt, key, iv, adata);
|
return AES_GCM.encrypt(pt, key, iv, adata);
|
||||||
|
|
|
@ -33,11 +33,11 @@ const nodeCrypto = util.getNodeCrypto();
|
||||||
*/
|
*/
|
||||||
export function getRandomBytes(length) {
|
export function getRandomBytes(length) {
|
||||||
const buf = new Uint8Array(length);
|
const buf = new Uint8Array(length);
|
||||||
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
if (nodeCrypto) {
|
||||||
crypto.getRandomValues(buf);
|
|
||||||
} else if (nodeCrypto) {
|
|
||||||
const bytes = nodeCrypto.randomBytes(buf.length);
|
const bytes = nodeCrypto.randomBytes(buf.length);
|
||||||
buf.set(bytes);
|
buf.set(bytes);
|
||||||
|
} else if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
||||||
|
crypto.getRandomValues(buf);
|
||||||
} else {
|
} else {
|
||||||
throw new Error('No secure random number generator available.');
|
throw new Error('No secure random number generator available.');
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,7 +255,7 @@ module.exports = () => describe('API functional testing', function() {
|
||||||
// test using webCrypto
|
// test using webCrypto
|
||||||
const sinonSandbox = sandbox.create();
|
const sinonSandbox = sandbox.create();
|
||||||
const webCrypto = util.getWebCrypto();
|
const webCrypto = util.getWebCrypto();
|
||||||
if (webCrypto) {
|
if (webCrypto && !util.getNodeCrypto()) {
|
||||||
const webCryptoSpy = sinonSandbox.spy(webCrypto, 'encrypt');
|
const webCryptoSpy = sinonSandbox.spy(webCrypto, 'encrypt');
|
||||||
try {
|
try {
|
||||||
await testCFB('12345678901234567890123456789012345678901234567890', { ...openpgp.config, minBytesForWebCrypto: 0 });
|
await testCFB('12345678901234567890123456789012345678901234567890', { ...openpgp.config, minBytesForWebCrypto: 0 });
|
||||||
|
|
|
@ -47,8 +47,8 @@ module.exports = () => describe('Symmetric AES-GCM (experimental)', function() {
|
||||||
const key = crypto.generateSessionKey(algo);
|
const key = crypto.generateSessionKey(algo);
|
||||||
const iv = crypto.random.getRandomBytes(crypto.mode.gcm.ivLength);
|
const iv = crypto.random.getRandomBytes(crypto.mode.gcm.ivLength);
|
||||||
|
|
||||||
const nativeEncryptSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'encrypt') : sinonSandbox.spy(nodeCrypto, 'createCipheriv');
|
const nativeEncryptSpy = nodeCrypto ? sinonSandbox.spy(nodeCrypto, 'createCipheriv') : sinonSandbox.spy(webCrypto, 'encrypt');
|
||||||
const nativeDecryptSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'decrypt') : sinonSandbox.spy(nodeCrypto, 'createDecipheriv');
|
const nativeDecryptSpy = nodeCrypto ? sinonSandbox.spy(nodeCrypto, 'createDecipheriv') : sinonSandbox.spy(webCrypto, 'decrypt');
|
||||||
|
|
||||||
nativeEncrypt || disableNative();
|
nativeEncrypt || disableNative();
|
||||||
let modeInstance = await crypto.mode.gcm(algo, key);
|
let modeInstance = await crypto.mode.gcm(algo, key);
|
||||||
|
|
|
@ -202,7 +202,7 @@ module.exports = () => describe('Packet', function() {
|
||||||
|
|
||||||
it('Sym. encrypted AEAD protected packet is encrypted in parallel (AEAD, GCM)', async function() {
|
it('Sym. encrypted AEAD protected packet is encrypted in parallel (AEAD, GCM)', async function() {
|
||||||
const webCrypto = util.getWebCrypto();
|
const webCrypto = util.getWebCrypto();
|
||||||
if (!webCrypto) return;
|
if (!webCrypto || util.getNodeCrypto()) return;
|
||||||
const encryptStub = cryptStub(webCrypto, 'encrypt');
|
const encryptStub = cryptStub(webCrypto, 'encrypt');
|
||||||
const decryptStub = cryptStub(webCrypto, 'decrypt');
|
const decryptStub = cryptStub(webCrypto, 'decrypt');
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user