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:
larabr 2023-10-12 10:10:28 +02:00 committed by GitHub
parent 96d6e76c05
commit 410dbcf1d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 27 additions and 27 deletions

View File

@ -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 }}

View File

@ -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);

View File

@ -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.');
} }

View File

@ -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 });

View File

@ -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);

View File

@ -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');