From 057f4c5666ff581682dc07231be04f0ba51d9c69 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Fri, 21 Mar 2025 14:35:31 +0100 Subject: [PATCH 1/3] crypto: fix output of privateDecrypt with zero-length data closes #57553 closes #57572 closes #57558 --- deps/ncrypto/ncrypto.cc | 2 +- test/parallel/test-crypto-zero-lengths.mjs | 51 ++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-crypto-zero-lengths.mjs diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index 884a4ab7c609c0..faf9cf00e84f31 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -215,7 +215,7 @@ Buffer DataPointer::release() { DataPointer DataPointer::resize(size_t len) { size_t actual_len = std::min(len_, len); auto buf = release(); - if (actual_len == len_) return DataPointer(buf); + if (actual_len == len_) return DataPointer(buf.data, actual_len); buf.data = OPENSSL_realloc(buf.data, actual_len); buf.len = actual_len; return DataPointer(buf); diff --git a/test/parallel/test-crypto-zero-lengths.mjs b/test/parallel/test-crypto-zero-lengths.mjs new file mode 100644 index 00000000000000..93bd6a5366d6aa --- /dev/null +++ b/test/parallel/test-crypto-zero-lengths.mjs @@ -0,0 +1,51 @@ +import * as common from '../common/index.mjs'; + +if (!common.hasCrypto) + common.skip('missing crypto'); + +import * as fixtures from '../common/fixtures.mjs'; +import assert from 'assert'; +import crypto from 'crypto'; + +const { subtle } = globalThis.crypto; + +{ + const privateKey = crypto.createPrivateKey(fixtures.readKey('rsa_private.pem', 'ascii')); + const publicKey = crypto.createPublicKey(fixtures.readKey('rsa_public.pem', 'ascii')); + + const data = Buffer.alloc(0); + { + + const ciphertext = crypto.publicEncrypt({ + padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, + key: publicKey, + }, data); + + const plaintext = crypto.privateDecrypt({ + padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, + key: privateKey + }, ciphertext); + + assert.deepStrictEqual(plaintext, data); + } + + { + const ciphertext = crypto.publicEncrypt(publicKey, data); + const plaintext = crypto.privateDecrypt(privateKey, ciphertext); + + assert.deepStrictEqual(plaintext, data); + } + + { + const pkcs8 = privateKey.export({ format: 'der', type: 'pkcs8' }); + const spki = publicKey.export({ format: 'der', type: 'spki' }); + const kp = { + privateKey: await subtle.importKey('pkcs8', pkcs8, { name: 'RSA-OAEP', hash: 'SHA-1' }, false, ['decrypt']), + publicKey: await subtle.importKey('spki', spki, { name: 'RSA-OAEP', hash: 'SHA-1' }, false, ['encrypt']), + }; + + const ciphertext = await subtle.encrypt('RSA-OAEP', kp.publicKey, data); + const plaintext = await subtle.decrypt('RSA-OAEP', kp.privateKey, ciphertext); + assert.deepStrictEqual(plaintext, data.buffer); + } +} From 547d3cf8c9346868766ec0d3373d25606634ca9a Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Fri, 21 Mar 2025 16:16:08 +0100 Subject: [PATCH 2/3] fixup! crypto: fix output of privateDecrypt with zero-length data --- ...engths.mjs => test-crypto-zero-lengths.js} | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) rename test/parallel/{test-crypto-zero-lengths.mjs => test-crypto-zero-lengths.js} (50%) diff --git a/test/parallel/test-crypto-zero-lengths.mjs b/test/parallel/test-crypto-zero-lengths.js similarity index 50% rename from test/parallel/test-crypto-zero-lengths.mjs rename to test/parallel/test-crypto-zero-lengths.js index 93bd6a5366d6aa..f43a5b6c6e457a 100644 --- a/test/parallel/test-crypto-zero-lengths.mjs +++ b/test/parallel/test-crypto-zero-lengths.js @@ -1,11 +1,12 @@ -import * as common from '../common/index.mjs'; +'use strict'; +const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -import * as fixtures from '../common/fixtures.mjs'; -import assert from 'assert'; -import crypto from 'crypto'; +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const crypto = require('crypto'); const { subtle } = globalThis.crypto; @@ -37,15 +38,18 @@ const { subtle } = globalThis.crypto; } { - const pkcs8 = privateKey.export({ format: 'der', type: 'pkcs8' }); - const spki = publicKey.export({ format: 'der', type: 'spki' }); - const kp = { - privateKey: await subtle.importKey('pkcs8', pkcs8, { name: 'RSA-OAEP', hash: 'SHA-1' }, false, ['decrypt']), - publicKey: await subtle.importKey('spki', spki, { name: 'RSA-OAEP', hash: 'SHA-1' }, false, ['encrypt']), - }; - - const ciphertext = await subtle.encrypt('RSA-OAEP', kp.publicKey, data); - const plaintext = await subtle.decrypt('RSA-OAEP', kp.privateKey, ciphertext); - assert.deepStrictEqual(plaintext, data.buffer); + (async () => { + const pkcs8 = privateKey.export({ format: 'der', type: 'pkcs8' }); + const spki = publicKey.export({ format: 'der', type: 'spki' }); + + const kp = { + privateKey: await subtle.importKey('pkcs8', pkcs8, { name: 'RSA-OAEP', hash: 'SHA-1' }, false, ['decrypt']), + publicKey: await subtle.importKey('spki', spki, { name: 'RSA-OAEP', hash: 'SHA-1' }, false, ['encrypt']), + }; + + const ciphertext = await subtle.encrypt('RSA-OAEP', kp.publicKey, data); + const plaintext = await subtle.decrypt('RSA-OAEP', kp.privateKey, ciphertext); + assert.deepStrictEqual(plaintext, data.buffer); + })().then(common.mustCall()); } } From 556183ffe6407b0fd84f4db68065ceea7c4a1f65 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Fri, 21 Mar 2025 17:36:27 +0100 Subject: [PATCH 3/3] fixup! crypto: fix output of privateDecrypt with zero-length data --- ...st-crypto-zero-lengths.js => test-crypto-oaep-zero-length.js} | 1 + 1 file changed, 1 insertion(+) rename test/parallel/{test-crypto-zero-lengths.js => test-crypto-oaep-zero-length.js} (96%) diff --git a/test/parallel/test-crypto-zero-lengths.js b/test/parallel/test-crypto-oaep-zero-length.js similarity index 96% rename from test/parallel/test-crypto-zero-lengths.js rename to test/parallel/test-crypto-oaep-zero-length.js index f43a5b6c6e457a..5194ce25454955 100644 --- a/test/parallel/test-crypto-zero-lengths.js +++ b/test/parallel/test-crypto-oaep-zero-length.js @@ -10,6 +10,7 @@ const crypto = require('crypto'); const { subtle } = globalThis.crypto; +// Regression test for https://github.com/nodejs/node/issues/57553. { const privateKey = crypto.createPrivateKey(fixtures.readKey('rsa_private.pem', 'ascii')); const publicKey = crypto.createPublicKey(fixtures.readKey('rsa_public.pem', 'ascii'));