From f0a662c348102931a09880c828b591da4f4799d3 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Fri, 25 Sep 2020 11:59:32 +0200 Subject: [PATCH 01/15] [wasm][crypto] RandomNumberGenerator mapped to Web Crypto getRandomValues - Uses Web Crypto API [`getRandomValues`](https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues) if available. - Falls back to `/dev/urandom` as default if the crypto library is missing. --- .../Native/Unix/System.Native/pal_random.c | 16 ++++++++++++++++ src/mono/wasm/runtime/driver.c | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/libraries/Native/Unix/System.Native/pal_random.c b/src/libraries/Native/Unix/System.Native/pal_random.c index 8f5e8927834a6..f3a4762ff9256 100644 --- a/src/libraries/Native/Unix/System.Native/pal_random.c +++ b/src/libraries/Native/Unix/System.Native/pal_random.c @@ -55,6 +55,10 @@ void SystemNative_GetNonCryptographicallySecureRandomBytes(uint8_t* buffer, int3 #endif // HAVE_ARC4RANDOM_BUF } +#ifdef __EMSCRIPTEN__ +int32_t mono_wasm_browser_crypto_getRandomValues(uint8_t* buffer, int32_t bufferLength); +#endif + /* Generate cryptographically strong random bytes. @@ -68,6 +72,18 @@ int32_t SystemNative_GetCryptographicallySecureRandomBytes(uint8_t* buffer, int3 assert(buffer != NULL); +#ifdef __EMSCRIPTEN__ + static bool sMissingBrowserCrypto; + if (!sMissingBrowserCrypto) + { + int32_t bff = mono_wasm_browser_crypto_getRandomValues(buffer, bufferLength); + if (bff == -1) + sMissingBrowserCrypto = true; + else + return 0; + } +#endif + if (!sMissingDevURandom) { if (rand_des == -1) diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 3f17256b0431f..00fc09747ee43 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -940,3 +940,15 @@ mono_timezone_get_local_name (MonoString **result) *result = mono_string_from_utf16 (tzd_local_name); free (tzd_local_name); } + +EM_JS(int32_t, mono_wasm_browser_crypto_getRandomValues, (uint8_t* buffer, int32_t bufferLength), +{ + // check that we have crypto available + if (!(typeof crypto !== 'undefined' && crypto.subtle && typeof crypto.getRandomValues === 'function')) { + return -1; + } + // map the work array to the memory buffer passed with the length + var wrkArray = new Uint8Array(Module.HEAPU8.buffer, buffer, bufferLength); + crypto.getRandomValues(wrkArray); + return 0; +}); From eb46e2fe649aa0684d97a88e07c8e8f0c42fe46a Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Mon, 28 Sep 2020 09:10:05 +0200 Subject: [PATCH 02/15] Remove the emscripten interface code from the driver.c. --- src/mono/wasm/runtime/driver.c | 12 ------------ src/mono/wasm/runtime/library_mono.js | 22 +++++++++++++++++----- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 00fc09747ee43..3f17256b0431f 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -940,15 +940,3 @@ mono_timezone_get_local_name (MonoString **result) *result = mono_string_from_utf16 (tzd_local_name); free (tzd_local_name); } - -EM_JS(int32_t, mono_wasm_browser_crypto_getRandomValues, (uint8_t* buffer, int32_t bufferLength), -{ - // check that we have crypto available - if (!(typeof crypto !== 'undefined' && crypto.subtle && typeof crypto.getRandomValues === 'function')) { - return -1; - } - // map the work array to the memory buffer passed with the length - var wrkArray = new Uint8Array(Module.HEAPU8.buffer, buffer, bufferLength); - crypto.getRandomValues(wrkArray); - return 0; -}); diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 4ae04e16048d4..b3d29274515f8 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -85,6 +85,7 @@ var MonoSupportLib = { module ["mono_wasm_new_root"] = MONO.mono_wasm_new_root; module ["mono_wasm_new_roots"] = MONO.mono_wasm_new_roots; module ["mono_wasm_release_roots"] = MONO.mono_wasm_release_roots; + //module ["mono_wasm_browser_crypto_getRandomValues"] = MONO.mono_wasm_browser_crypto_getRandomValues; }, _base64Converter: { @@ -211,7 +212,7 @@ var MonoSupportLib = { }, /** @returns {ManagedPointer} */ get: function (index) { - this._check_in_range (index); + this._check_in_range (index); return Module.HEAP32[this.get_address_32 (index)]; }, set: function (index, value) { @@ -317,7 +318,7 @@ var MonoSupportLib = { throw new Error ("capacity >= 1"); capacity = capacity | 0; - + var capacityBytes = capacity * 4; var offset = Module._malloc (capacityBytes); if ((offset % 4) !== 0) @@ -328,7 +329,7 @@ var MonoSupportLib = { var result = Object.create (this._mono_wasm_root_buffer_prototype); result.__offset = offset; result.__offset32 = (offset / 4) | 0; - result.__count = capacity; + result.__count = capacity; result.length = capacity; result.__handle = this.mono_wasm_register_root (offset, capacityBytes, msg || 0); @@ -347,7 +348,7 @@ var MonoSupportLib = { mono_wasm_new_root: function (value) { var index = this._mono_wasm_claim_scratch_index (); var buffer = this._scratch_root_buffer; - + var result = Object.create (this._mono_wasm_root_prototype); result.__buffer = buffer; result.__index = index; @@ -395,7 +396,7 @@ var MonoSupportLib = { * Multiple objects may be passed on the argument list. * 'undefined' may be passed as an argument so it is safe to call this method from finally blocks * even if you are not sure all of your roots have been created yet. - * @param {... WasmRoot} roots + * @param {... WasmRoot} roots */ mono_wasm_release_roots: function () { for (var i = 0; i < arguments.length; i++) { @@ -2389,6 +2390,17 @@ var MonoSupportLib = { pdb_b64 }); }, + + mono_wasm_browser_crypto_getRandomValues : function (buffer, bufferLength) { + // check that we have crypto available + if (!(typeof crypto !== 'undefined' && crypto.subtle && typeof crypto.getRandomValues === 'function')) { + return -1; + } + // map the work array to the memory buffer passed with the length + var wrkArray = new Uint8Array(Module.HEAPU8.buffer, buffer, bufferLength); + crypto.getRandomValues(wrkArray); + return 0; + }, }; autoAddDeps(MonoSupportLib, '$MONO') From 878cfcf13b116de946984d0124745b2757f78e65 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Mon, 28 Sep 2020 10:57:24 +0200 Subject: [PATCH 03/15] remove extraneous code comment --- src/mono/wasm/runtime/library_mono.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index b3d29274515f8..4547d68a0fa12 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -85,7 +85,6 @@ var MonoSupportLib = { module ["mono_wasm_new_root"] = MONO.mono_wasm_new_root; module ["mono_wasm_new_roots"] = MONO.mono_wasm_new_roots; module ["mono_wasm_release_roots"] = MONO.mono_wasm_release_roots; - //module ["mono_wasm_browser_crypto_getRandomValues"] = MONO.mono_wasm_browser_crypto_getRandomValues; }, _base64Converter: { From 289efeff57beab92bd290bb12c53a9f67175ca41 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Mon, 28 Sep 2020 10:59:42 +0200 Subject: [PATCH 04/15] Move emscripten definition around. --- src/libraries/Native/Unix/System.Native/pal_random.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/Native/Unix/System.Native/pal_random.c b/src/libraries/Native/Unix/System.Native/pal_random.c index f3a4762ff9256..4f75010ed6f70 100644 --- a/src/libraries/Native/Unix/System.Native/pal_random.c +++ b/src/libraries/Native/Unix/System.Native/pal_random.c @@ -55,10 +55,6 @@ void SystemNative_GetNonCryptographicallySecureRandomBytes(uint8_t* buffer, int3 #endif // HAVE_ARC4RANDOM_BUF } -#ifdef __EMSCRIPTEN__ -int32_t mono_wasm_browser_crypto_getRandomValues(uint8_t* buffer, int32_t bufferLength); -#endif - /* Generate cryptographically strong random bytes. @@ -73,6 +69,10 @@ int32_t SystemNative_GetCryptographicallySecureRandomBytes(uint8_t* buffer, int3 assert(buffer != NULL); #ifdef __EMSCRIPTEN__ + #include + EMSCRIPTEN_KEEPALIVE int32_t + mono_wasm_browser_crypto_getRandomValues(uint8_t* buffer, int32_t bufferLength); + static bool sMissingBrowserCrypto; if (!sMissingBrowserCrypto) { From b5d372be59609461308b34e1fdda629b52fbac63 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Mon, 28 Sep 2020 11:07:36 +0200 Subject: [PATCH 05/15] Address review comment --- src/libraries/Native/Unix/System.Native/pal_random.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libraries/Native/Unix/System.Native/pal_random.c b/src/libraries/Native/Unix/System.Native/pal_random.c index 4f75010ed6f70..b8a31ddcbdd94 100644 --- a/src/libraries/Native/Unix/System.Native/pal_random.c +++ b/src/libraries/Native/Unix/System.Native/pal_random.c @@ -63,9 +63,6 @@ Return 0 on success, -1 on failure. */ int32_t SystemNative_GetCryptographicallySecureRandomBytes(uint8_t* buffer, int32_t bufferLength) { - static volatile int rand_des = -1; - static bool sMissingDevURandom; - assert(buffer != NULL); #ifdef __EMSCRIPTEN__ @@ -82,7 +79,10 @@ int32_t SystemNative_GetCryptographicallySecureRandomBytes(uint8_t* buffer, int3 else return 0; } -#endif +#else + + static volatile int rand_des = -1; + static bool sMissingDevURandom; if (!sMissingDevURandom) { @@ -137,6 +137,6 @@ int32_t SystemNative_GetCryptographicallySecureRandomBytes(uint8_t* buffer, int3 return 0; } } - +#endif return -1; } From cf74a12cb84b65fed75144a293c967bd0b5de35d Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 29 Sep 2020 09:37:48 +0200 Subject: [PATCH 06/15] Add javascript bridge implementation library to Native source tree. - Javascript checks for crypto interface and uses `crypto.getRandomValues` - Add api bridge call when building for emscripten browser. - separate out into browser subdirectory - If we couldn't find a proper implementation, as Math.random() is not suitable we will abort. ``` ABORT: no cryptographic support found getRandomValues. Consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } }; ``` --- .../browser/pal_entropy_bridge.js | 23 +++++++++++++++++++ .../browser/pal_random_browser.h | 9 ++++++++ .../Native/Unix/System.Native/pal_random.c | 9 ++++---- 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 src/libraries/Native/Unix/System.Native/browser/pal_entropy_bridge.js create mode 100644 src/libraries/Native/Unix/System.Native/browser/pal_random_browser.h diff --git a/src/libraries/Native/Unix/System.Native/browser/pal_entropy_bridge.js b/src/libraries/Native/Unix/System.Native/browser/pal_entropy_bridge.js new file mode 100644 index 0000000000000..fb536560ccf62 --- /dev/null +++ b/src/libraries/Native/Unix/System.Native/browser/pal_entropy_bridge.js @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +var DotNetEntropyLib = { + $DOTNETENTROPY: { + }, + dotnet_browser_entropy : function (buffer, bufferLength) { + // check that we have crypto available + if (typeof crypto === 'object' && typeof crypto['getRandomValues'] === 'function') { + // for modern web browsers + // map the work array to the memory buffer passed with the length + var wrkArray = new Uint8Array(Module.HEAPU8.buffer, buffer, bufferLength); + crypto.getRandomValues(wrkArray); + return 0; + } else { + // we couldn't find a proper implementation, as Math.random() is not suitable + abort("no cryptographic support found for getRandomValues. Consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };"); + } + }, +}; + +autoAddDeps(DotNetEntropyLib, '$DOTNETENTROPY') +mergeInto(LibraryManager.library, DotNetEntropyLib) diff --git a/src/libraries/Native/Unix/System.Native/browser/pal_random_browser.h b/src/libraries/Native/Unix/System.Native/browser/pal_random_browser.h new file mode 100644 index 0000000000000..8226de64a2796 --- /dev/null +++ b/src/libraries/Native/Unix/System.Native/browser/pal_random_browser.h @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#pragma once + +#include "pal_compiler.h" +#include "pal_types.h" + +PALEXPORT int32_t dotnet_browser_entropy(uint8_t* buffer, int32_t bufferLength); diff --git a/src/libraries/Native/Unix/System.Native/pal_random.c b/src/libraries/Native/Unix/System.Native/pal_random.c index b8a31ddcbdd94..fb3d9b53d7eed 100644 --- a/src/libraries/Native/Unix/System.Native/pal_random.c +++ b/src/libraries/Native/Unix/System.Native/pal_random.c @@ -14,6 +14,9 @@ #include "pal_config.h" #include "pal_random.h" +#ifdef __EMSCRIPTEN__ +#include "browser/pal_random_browser.h" +#endif /* Generate random bytes. The generated bytes are not cryptographically strong. @@ -66,14 +69,10 @@ int32_t SystemNative_GetCryptographicallySecureRandomBytes(uint8_t* buffer, int3 assert(buffer != NULL); #ifdef __EMSCRIPTEN__ - #include - EMSCRIPTEN_KEEPALIVE int32_t - mono_wasm_browser_crypto_getRandomValues(uint8_t* buffer, int32_t bufferLength); - static bool sMissingBrowserCrypto; if (!sMissingBrowserCrypto) { - int32_t bff = mono_wasm_browser_crypto_getRandomValues(buffer, bufferLength); + int32_t bff = dotnet_browser_entropy(buffer, bufferLength); if (bff == -1) sMissingBrowserCrypto = true; else From 88fa846ac5644957a476a8a1093d145f703d947d Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 29 Sep 2020 09:39:15 +0200 Subject: [PATCH 07/15] Change tests to set random values of the buffer instead of return a single value. --- src/mono/wasm/runtime-test.js | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index b3fbf5dc3fbca..be3ed08bd4f9d 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -40,12 +40,13 @@ if (typeof console !== "undefined") { console.error = console.log; } -if (typeof crypto == 'undefined') { +if (typeof crypto === 'undefined') { // /dev/random doesn't work on js shells, so define our own // See library_fs.js:createDefaultDevices () var crypto = { getRandomValues: function (buffer) { - buffer[0] = (Math.random()*256)|0; + for (var i = 0; i < buffer.length; i++) + buffer[i] = (Math.random()*256)|0; } } } @@ -120,7 +121,9 @@ runtime_args = []; enable_gc = true; enable_zoneinfo = false; working_dir='/'; +extra_scripts=[]; while (args !== undefined && args.length > 0) { + console.log("processign arg: " + args [0]); if (args [0].startsWith ("--profile=")) { var arg = args [0].substring ("--profile=".length); @@ -144,6 +147,10 @@ while (args !== undefined && args.length > 0) { } else if (args [0].startsWith ("--working-dir=")) { var arg = args [0].substring ("--working-dir=".length); working_dir = arg; + args = args.slice (1); + } else if (args [0].startsWith ("--extra-scripts=")) { + var extras = args [0].substring ("--extra-scripts=".length); + extra_scripts = extras.split(','); args = args.slice (1); } else { break; @@ -171,6 +178,19 @@ function loadScript (url) loadScript ("mono-config.js"); +// Load the extra script files which may contain poly fills to be loaded +extra_scripts.forEach(scriptToLoad => { + try { + loadScript (scriptToLoad); + } catch (error) { + console.log(error + ": " + scriptToLoad); + } +}); + +// check if crypto polyfill is loaded +if (typeof msrCrypto !== 'undefined') + var crypto = msrCrypto; /*polyfill*/ + var Module = { mainScriptUrlOrBlob: "dotnet.js", From 2b8987dbf44f026665418eac0991db97d6a75229 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 29 Sep 2020 09:39:52 +0200 Subject: [PATCH 08/15] Remove old test code --- src/mono/wasm/runtime/library_mono.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 4547d68a0fa12..dafc3e2068d8a 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -2389,17 +2389,6 @@ var MonoSupportLib = { pdb_b64 }); }, - - mono_wasm_browser_crypto_getRandomValues : function (buffer, bufferLength) { - // check that we have crypto available - if (!(typeof crypto !== 'undefined' && crypto.subtle && typeof crypto.getRandomValues === 'function')) { - return -1; - } - // map the work array to the memory buffer passed with the length - var wrkArray = new Uint8Array(Module.HEAPU8.buffer, buffer, bufferLength); - crypto.getRandomValues(wrkArray); - return 0; - }, }; autoAddDeps(MonoSupportLib, '$MONO') From 61f1c192703589ac2be99bee6448daa211814682 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 29 Sep 2020 09:41:54 +0200 Subject: [PATCH 09/15] Remove testing code --- src/mono/wasm/runtime-test.js | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index be3ed08bd4f9d..4b7e55769c03d 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -121,9 +121,7 @@ runtime_args = []; enable_gc = true; enable_zoneinfo = false; working_dir='/'; -extra_scripts=[]; while (args !== undefined && args.length > 0) { - console.log("processign arg: " + args [0]); if (args [0].startsWith ("--profile=")) { var arg = args [0].substring ("--profile=".length); @@ -148,10 +146,6 @@ while (args !== undefined && args.length > 0) { var arg = args [0].substring ("--working-dir=".length); working_dir = arg; args = args.slice (1); - } else if (args [0].startsWith ("--extra-scripts=")) { - var extras = args [0].substring ("--extra-scripts=".length); - extra_scripts = extras.split(','); - args = args.slice (1); } else { break; } @@ -178,19 +172,6 @@ function loadScript (url) loadScript ("mono-config.js"); -// Load the extra script files which may contain poly fills to be loaded -extra_scripts.forEach(scriptToLoad => { - try { - loadScript (scriptToLoad); - } catch (error) { - console.log(error + ": " + scriptToLoad); - } -}); - -// check if crypto polyfill is loaded -if (typeof msrCrypto !== 'undefined') - var crypto = msrCrypto; /*polyfill*/ - var Module = { mainScriptUrlOrBlob: "dotnet.js", From ce13ad1ff03c0740875fd69caf515606e5dc073b Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 29 Sep 2020 10:36:43 +0200 Subject: [PATCH 10/15] Incorporate the PAL bridge layer into the `--js-library` build process --- src/mono/wasm/Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index 4fc42d4f7ad0d..6354eb5260afd 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -15,6 +15,7 @@ PINVOKE_TABLE?=$(TOP)/artifacts/obj/wasm/pinvoke-table.h MONO_BIN_DIR?=$(BINDIR)/mono/Browser.wasm.$(CONFIG) NATIVE_BIN_DIR?=$(BINDIR)/native/net5.0-Browser-$(CONFIG)-wasm ICU_LIBDIR?= +SYSTEM_NATIVE_LIBDIR?=$(TOP)/src/libraries/Native/Unix/System.Native/browser ENABLE_ES6?=false all: build-native icu-data @@ -81,8 +82,8 @@ $(NATIVE_BIN_DIR): $(BUILDS_OBJ_DIR): mkdir -p $$@ -$(NATIVE_BIN_DIR)/dotnet.js: $(BUILDS_OBJ_DIR)/driver.o $(BUILDS_OBJ_DIR)/pinvoke.o $(BUILDS_OBJ_DIR)/corebindings.o runtime/library_mono.js runtime/binding_support.js runtime/dotnet_support.js $(2) | $(NATIVE_BIN_DIR) - $(EMCC) $(EMCC_FLAGS) $(1) --js-library runtime/library_mono.js --js-library runtime/binding_support.js --js-library runtime/dotnet_support.js $(BUILDS_OBJ_DIR)/driver.o $(BUILDS_OBJ_DIR)/pinvoke.o $(BUILDS_OBJ_DIR)/corebindings.o $(2) -o $(NATIVE_BIN_DIR)/dotnet.js +$(NATIVE_BIN_DIR)/dotnet.js: $(BUILDS_OBJ_DIR)/driver.o $(BUILDS_OBJ_DIR)/pinvoke.o $(BUILDS_OBJ_DIR)/corebindings.o runtime/library_mono.js runtime/binding_support.js runtime/dotnet_support.js $(SYSTEM_NATIVE_LIBDIR)/pal_entropy_bridge.js $(2) | $(NATIVE_BIN_DIR) + $(EMCC) $(EMCC_FLAGS) $(1) --js-library runtime/library_mono.js --js-library runtime/binding_support.js --js-library runtime/dotnet_support.js --js-library $(SYSTEM_NATIVE_LIBDIR)/pal_entropy_bridge.js $(BUILDS_OBJ_DIR)/driver.o $(BUILDS_OBJ_DIR)/pinvoke.o $(BUILDS_OBJ_DIR)/corebindings.o $(2) -o $(NATIVE_BIN_DIR)/dotnet.js $(BUILDS_OBJ_DIR)/pinvoke-table.h: $(PINVOKE_TABLE) | $(BUILDS_OBJ_DIR) if cmp -s $(PINVOKE_TABLE) $$@ ; then : ; else cp $(PINVOKE_TABLE) $$@ ; fi From 5e593bb525e1f7c1b57bfaa0f32be4c6a27be2b0 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Wed, 30 Sep 2020 08:46:21 +0200 Subject: [PATCH 11/15] Address review comments about directory structure and naming --- .../Unix/System.Native/browser/pal_random_browser.h | 9 --------- src/libraries/Native/Unix/System.Native/pal_random.c | 4 +--- .../{browser/pal_entropy_bridge.js => pal_random.js} | 0 src/mono/wasm/Makefile | 6 +++--- 4 files changed, 4 insertions(+), 15 deletions(-) delete mode 100644 src/libraries/Native/Unix/System.Native/browser/pal_random_browser.h rename src/libraries/Native/Unix/System.Native/{browser/pal_entropy_bridge.js => pal_random.js} (100%) diff --git a/src/libraries/Native/Unix/System.Native/browser/pal_random_browser.h b/src/libraries/Native/Unix/System.Native/browser/pal_random_browser.h deleted file mode 100644 index 8226de64a2796..0000000000000 --- a/src/libraries/Native/Unix/System.Native/browser/pal_random_browser.h +++ /dev/null @@ -1,9 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#pragma once - -#include "pal_compiler.h" -#include "pal_types.h" - -PALEXPORT int32_t dotnet_browser_entropy(uint8_t* buffer, int32_t bufferLength); diff --git a/src/libraries/Native/Unix/System.Native/pal_random.c b/src/libraries/Native/Unix/System.Native/pal_random.c index fb3d9b53d7eed..b824b2968f95c 100644 --- a/src/libraries/Native/Unix/System.Native/pal_random.c +++ b/src/libraries/Native/Unix/System.Native/pal_random.c @@ -14,9 +14,6 @@ #include "pal_config.h" #include "pal_random.h" -#ifdef __EMSCRIPTEN__ -#include "browser/pal_random_browser.h" -#endif /* Generate random bytes. The generated bytes are not cryptographically strong. @@ -69,6 +66,7 @@ int32_t SystemNative_GetCryptographicallySecureRandomBytes(uint8_t* buffer, int3 assert(buffer != NULL); #ifdef __EMSCRIPTEN__ + extern int32_t dotnet_browser_entropy(uint8_t* buffer, int32_t bufferLength); static bool sMissingBrowserCrypto; if (!sMissingBrowserCrypto) { diff --git a/src/libraries/Native/Unix/System.Native/browser/pal_entropy_bridge.js b/src/libraries/Native/Unix/System.Native/pal_random.js similarity index 100% rename from src/libraries/Native/Unix/System.Native/browser/pal_entropy_bridge.js rename to src/libraries/Native/Unix/System.Native/pal_random.js diff --git a/src/mono/wasm/Makefile b/src/mono/wasm/Makefile index 6354eb5260afd..12f1962920fd9 100644 --- a/src/mono/wasm/Makefile +++ b/src/mono/wasm/Makefile @@ -15,7 +15,7 @@ PINVOKE_TABLE?=$(TOP)/artifacts/obj/wasm/pinvoke-table.h MONO_BIN_DIR?=$(BINDIR)/mono/Browser.wasm.$(CONFIG) NATIVE_BIN_DIR?=$(BINDIR)/native/net5.0-Browser-$(CONFIG)-wasm ICU_LIBDIR?= -SYSTEM_NATIVE_LIBDIR?=$(TOP)/src/libraries/Native/Unix/System.Native/browser +SYSTEM_NATIVE_LIBDIR?=$(TOP)/src/libraries/Native/Unix/System.Native ENABLE_ES6?=false all: build-native icu-data @@ -82,8 +82,8 @@ $(NATIVE_BIN_DIR): $(BUILDS_OBJ_DIR): mkdir -p $$@ -$(NATIVE_BIN_DIR)/dotnet.js: $(BUILDS_OBJ_DIR)/driver.o $(BUILDS_OBJ_DIR)/pinvoke.o $(BUILDS_OBJ_DIR)/corebindings.o runtime/library_mono.js runtime/binding_support.js runtime/dotnet_support.js $(SYSTEM_NATIVE_LIBDIR)/pal_entropy_bridge.js $(2) | $(NATIVE_BIN_DIR) - $(EMCC) $(EMCC_FLAGS) $(1) --js-library runtime/library_mono.js --js-library runtime/binding_support.js --js-library runtime/dotnet_support.js --js-library $(SYSTEM_NATIVE_LIBDIR)/pal_entropy_bridge.js $(BUILDS_OBJ_DIR)/driver.o $(BUILDS_OBJ_DIR)/pinvoke.o $(BUILDS_OBJ_DIR)/corebindings.o $(2) -o $(NATIVE_BIN_DIR)/dotnet.js +$(NATIVE_BIN_DIR)/dotnet.js: $(BUILDS_OBJ_DIR)/driver.o $(BUILDS_OBJ_DIR)/pinvoke.o $(BUILDS_OBJ_DIR)/corebindings.o runtime/library_mono.js runtime/binding_support.js runtime/dotnet_support.js $(SYSTEM_NATIVE_LIBDIR)/pal_random.js $(2) | $(NATIVE_BIN_DIR) + $(EMCC) $(EMCC_FLAGS) $(1) --js-library runtime/library_mono.js --js-library runtime/binding_support.js --js-library runtime/dotnet_support.js --js-library $(SYSTEM_NATIVE_LIBDIR)/pal_random.js $(BUILDS_OBJ_DIR)/driver.o $(BUILDS_OBJ_DIR)/pinvoke.o $(BUILDS_OBJ_DIR)/corebindings.o $(2) -o $(NATIVE_BIN_DIR)/dotnet.js $(BUILDS_OBJ_DIR)/pinvoke-table.h: $(PINVOKE_TABLE) | $(BUILDS_OBJ_DIR) if cmp -s $(PINVOKE_TABLE) $$@ ; then : ; else cp $(PINVOKE_TABLE) $$@ ; fi From 76de399c75193a5571f54cdf3593230ee60e7da4 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Thu, 1 Oct 2020 05:48:00 +0200 Subject: [PATCH 12/15] Update src/mono/wasm/runtime-test.js Co-authored-by: Ryan Lucia --- src/mono/wasm/runtime-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 4964c73e6ac1b..ca080a26f60ee 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -68,7 +68,7 @@ if (typeof crypto === 'undefined') { var crypto = { getRandomValues: function (buffer) { for (var i = 0; i < buffer.length; i++) - buffer[i] = (Math.random()*256)|0; + buffer [i] = (Math.random () * 256) | 0; } } } From 8077f7cf801618831d10f2fc1de0c2bbdfa26134 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Thu, 1 Oct 2020 06:21:18 +0200 Subject: [PATCH 13/15] Add note about insecure code for testing purposes --- src/mono/wasm/runtime-test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index ca080a26f60ee..992236692eedd 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -63,6 +63,7 @@ if (typeof console !== "undefined") { } if (typeof 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 () var crypto = { From ec16f1a182470a4787e13ab3f89487eb8054edcd Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Thu, 1 Oct 2020 06:23:17 +0200 Subject: [PATCH 14/15] Formatting --- src/mono/wasm/runtime-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index 992236692eedd..1d217aae5dade 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -168,7 +168,7 @@ while (args !== undefined && args.length > 0) { } else if (args [0].startsWith ("--working-dir=")) { var arg = args [0].substring ("--working-dir=".length); working_dir = arg; - args = args.slice (1); + args = args.slice (1); } else { break; } From 7b7e9d28132f177641bf66e18a118622a122744e Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Thu, 1 Oct 2020 06:58:30 +0200 Subject: [PATCH 15/15] Return -1 if crypto does not exist instead of aborting from js. This allows the managed code exception flow to continue as normal. --- src/libraries/Native/Unix/System.Native/pal_random.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/Native/Unix/System.Native/pal_random.js b/src/libraries/Native/Unix/System.Native/pal_random.js index fb536560ccf62..231eda0b8ca86 100644 --- a/src/libraries/Native/Unix/System.Native/pal_random.js +++ b/src/libraries/Native/Unix/System.Native/pal_random.js @@ -14,7 +14,8 @@ var DotNetEntropyLib = { return 0; } else { // we couldn't find a proper implementation, as Math.random() is not suitable - abort("no cryptographic support found for getRandomValues. Consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };"); + // instead of aborting here we will return and let managed code handle the message + return -1; } }, };