From eeedfdf48e4c05af058fa83c51400097b8bdb627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 22 Nov 2022 14:53:41 +0100 Subject: [PATCH 1/2] [wasm] Use "node:crypto" to polyfill crypto.getRandomValues on older node versions. --- src/mono/wasm/runtime/polyfills.ts | 17 +++++++++++++++++ src/mono/wasm/test-main.js | 12 ------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/mono/wasm/runtime/polyfills.ts b/src/mono/wasm/runtime/polyfills.ts index b330f45b8f18e6..b93eb1c3f211d0 100644 --- a/src/mono/wasm/runtime/polyfills.ts +++ b/src/mono/wasm/runtime/polyfills.ts @@ -7,6 +7,7 @@ import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, ENVIRONM import { afterUpdateGlobalBufferAndViews } from "./memory"; import { replaceEmscriptenPThreadLibrary } from "./pthreads/shared/emscripten-replacements"; import { DotnetModuleConfigImports, EarlyReplacements } from "./types"; +import { TypedArray } from "./types/emscripten"; let node_fs: any | undefined = undefined; let node_url: any | undefined = undefined; @@ -195,6 +196,22 @@ export async function init_polyfills_async(): Promise { const { performance } = INTERNAL.require("perf_hooks"); globalThis.performance = performance; } + + if (!globalThis.crypto) { + globalThis.crypto = {}; + } + if (!globalThis.crypto.getRandomValues) { + const nodeCrypto = INTERNAL.require("node:crypto"); + if (nodeCrypto.webcrypto) { + globalThis.crypto = nodeCrypto.webcrypto; + } else if (nodeCrypto.randomBytes) { + globalThis.crypto.getRandomValues = (buffer: TypedArray) => { + if (buffer) { + buffer.set(nodeCrypto.randomBytes(buffer.length)); + } + }; + } + } } } diff --git a/src/mono/wasm/test-main.js b/src/mono/wasm/test-main.js index bac3f856160c57..58f4512e6f0298 100644 --- a/src/mono/wasm/test-main.js +++ b/src/mono/wasm/test-main.js @@ -23,18 +23,6 @@ if (is_node && process.versions.node.split(".")[0] < 14) { throw new Error(`NodeJS at '${process.execPath}' has too low version '${process.versions.node}'`); } -if (typeof globalThis.crypto === 'undefined') { - // **NOTE** this is a simple insecure polyfill for testing purposes only - // /dev/random doesn't work on js shells, so define our own - // See library_fs.js:createDefaultDevices () - globalThis.crypto = { - getRandomValues: function (buffer) { - for (let i = 0; i < buffer.length; i++) - buffer[i] = (Math.random() * 256) | 0; - } - } -} - let v8args; if (typeof arguments !== "undefined") { // this must be captured in top level scope in V8 From 4ebb4a9c24930ef251918aa6d28563840495f9ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Wed, 23 Nov 2022 10:24:40 +0100 Subject: [PATCH 2/2] Revert getRandomValues using Math for tests on V8. --- src/mono/wasm/test-main.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mono/wasm/test-main.js b/src/mono/wasm/test-main.js index 58f4512e6f0298..24f5817ef19bad 100644 --- a/src/mono/wasm/test-main.js +++ b/src/mono/wasm/test-main.js @@ -23,6 +23,18 @@ if (is_node && process.versions.node.split(".")[0] < 14) { throw new Error(`NodeJS at '${process.execPath}' has too low version '${process.versions.node}'`); } +if (!is_node && !is_browser && typeof globalThis.crypto === 'undefined') { + // **NOTE** this is a simple insecure polyfill for testing purposes only + // /dev/random doesn't work on js shells, so define our own + // See library_fs.js:createDefaultDevices () + globalThis.crypto = { + getRandomValues: function (buffer) { + for (let i = 0; i < buffer.length; i++) + buffer[i] = (Math.random() * 256) | 0; + } + } +} + let v8args; if (typeof arguments !== "undefined") { // this must be captured in top level scope in V8