[wasm] Use "node:crypto" to polyfill getRandomValues on older node (#78696)
authorMarek Fišera <mara@neptuo.com>
Wed, 23 Nov 2022 13:09:36 +0000 (14:09 +0100)
committerGitHub <noreply@github.com>
Wed, 23 Nov 2022 13:09:36 +0000 (14:09 +0100)
src/mono/wasm/runtime/polyfills.ts
src/mono/wasm/test-main.js

index b330f45..b93eb1c 100644 (file)
@@ -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<void> {
             const { performance } = INTERNAL.require("perf_hooks");
             globalThis.performance = performance;
         }
+
+        if (!globalThis.crypto) {
+            globalThis.crypto = <any>{};
+        }
+        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));
+                    }
+                };
+            }
+        }
     }
 }
 
index 09eeece..8f37acc 100644 (file)
@@ -23,7 +23,7 @@ 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') {
+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 ()