Skip to content

Commit

Permalink
test: add CryptoKey transferring tests
Browse files Browse the repository at this point in the history
PR-URL: #45811
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: James M Snell <[email protected]>
  • Loading branch information
panva authored and targos committed Jan 1, 2023
1 parent e229f06 commit 53f02cf
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 43 deletions.
92 changes: 52 additions & 40 deletions test/parallel/test-crypto-key-objects-messageport.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ if (!common.hasCrypto)
common.skip('missing crypto');

const assert = require('assert');
const { createSecretKey, generateKeyPairSync, randomBytes } = require('crypto');
const {
generateKeySync,
generateKeyPairSync,
KeyObject,
} = require('crypto');
const { subtle } = globalThis.crypto;
const { createContext } = require('vm');
const {
MessageChannel,
Expand All @@ -15,6 +20,9 @@ const {

function keyToString(key) {
let ret;
if (key instanceof CryptoKey) {
key = KeyObject.from(key);
}
if (key.type === 'secret') {
ret = key.export().toString('hex');
} else {
Expand All @@ -33,55 +41,59 @@ if (process.env.HAS_STARTED_WORKER) {
// Don't use isMainThread to allow running this test inside a worker.
process.env.HAS_STARTED_WORKER = 1;

// The main thread generates keys and passes them to worker threads.
const secretKey = createSecretKey(randomBytes(32));
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
modulusLength: 1024
});
(async () => {
// The main thread generates keys and passes them to worker threads.
const secretKey = generateKeySync('aes', { length: 128 });
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
modulusLength: 1024
});
const cryptoKey = await subtle.generateKey(
{ name: 'AES-CBC', length: 128 }, false, ['encrypt']);

// Get immutable representations of all keys.
const keys = [secretKey, publicKey, privateKey]
// Get immutable representations of all keys.
const keys = [secretKey, publicKey, privateKey, cryptoKey]
.map((key) => [key, keyToString(key)]);

for (const [key, repr] of keys) {
{
for (const [key, repr] of keys) {
{
// Test 1: No context change.
const { port1, port2 } = new MessageChannel();

port1.postMessage({ key });
assert.strictEqual(keyToString(key), repr);
const { port1, port2 } = new MessageChannel();

port2.once('message', common.mustCall(({ key }) => {
port1.postMessage({ key });
assert.strictEqual(keyToString(key), repr);
}));
}

{
port2.once('message', common.mustCall(({ key }) => {
assert.strictEqual(keyToString(key), repr);
}));
}

{
// Test 2: Across threads.
const worker = new Worker(__filename);
worker.once('message', common.mustCall((receivedRepresentation) => {
assert.strictEqual(receivedRepresentation, repr);
}));
worker.on('disconnect', () => console.log('disconnect'));
worker.postMessage({ key });
}
const worker = new Worker(__filename);
worker.once('message', common.mustCall((receivedRepresentation) => {
assert.strictEqual(receivedRepresentation, repr);
}));
worker.on('disconnect', () => console.log('disconnect'));
worker.postMessage({ key });
}

{
{
// Test 3: Across contexts (should not work).
const { port1, port2 } = new MessageChannel();
const context = createContext();
const port2moved = moveMessagePortToContext(port2, context);
assert(!(port2moved instanceof Object));
const { port1, port2 } = new MessageChannel();
const context = createContext();
const port2moved = moveMessagePortToContext(port2, context);
assert(!(port2moved instanceof Object));

// TODO(addaleax): Switch this to a 'messageerror' event once MessagePort
// implements EventTarget fully and in a cross-context manner.
port2moved.onmessageerror = common.mustCall((event) => {
assert.strictEqual(event.data.code,
'ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE');
});
// TODO(addaleax): Switch this to a 'messageerror' event once MessagePort
// implements EventTarget fully and in a cross-context manner.
port2moved.onmessageerror = common.mustCall((event) => {
assert.strictEqual(event.data.code,
'ERR_MESSAGE_TARGET_CONTEXT_UNAVAILABLE');
});

port2moved.start();
port1.postMessage({ key });
port1.close();
port2moved.start();
port1.postMessage({ key });
port1.close();
}
}
}
})().then(common.mustCall());
23 changes: 20 additions & 3 deletions test/parallel/test-crypto-worker-thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,30 @@ if (!common.hasCrypto)

// Issue https://github.com/nodejs/node/issues/35263
// Description: Test that passing keyobject to worker thread does not crash.
const { createSecretKey } = require('crypto');
const {
generateKeySync,
generateKeyPairSync,
} = require('crypto');
const { subtle } = globalThis.crypto;

const assert = require('assert');

const { Worker, isMainThread, workerData } = require('worker_threads');

if (isMainThread) {
const key = createSecretKey(Buffer.from('hello'));
new Worker(__filename, { workerData: key });
(async () => {
const secretKey = generateKeySync('aes', { length: 128 });
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
modulusLength: 1024
});
const cryptoKey = await subtle.generateKey(
{ name: 'AES-CBC', length: 128 }, false, ['encrypt']);

for (const key of [secretKey, publicKey, privateKey, cryptoKey]) {
new Worker(__filename, { workerData: key });
}
})().then(common.mustCall());
} else {
console.log(workerData);
assert.notDeepStrictEqual(workerData, {});
}

0 comments on commit 53f02cf

Please sign in to comment.