Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Erhardt <eric.erhardt@microsoft.com>2022-06-22 00:27:16 +0300
committerGitHub <noreply@github.com>2022-06-22 00:27:16 +0300
commiteed18afa59b00f780461e0f9bd871fbd4b843b7c (patch)
tree7476e5cbe55aa7507d7ad010c407d551241da4c7 /src/mono/wasm/runtime
parent89dc073529aadfa3f36bcf7ed029c0a3b59d357e (diff)
Use crypto.subtle for HMAC on Browser WASM (#70745)
* Use crypto.subtle for HMAC on Browser WASM Implement the browser "native" portion for HMAC on Browser WASM. I also made a few refactoring / simplifications where necessary. Contributes to #40074
Diffstat (limited to 'src/mono/wasm/runtime')
-rw-r--r--src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js3
-rw-r--r--src/mono/wasm/runtime/crypto-worker.ts23
-rw-r--r--src/mono/wasm/runtime/es6/dotnet.es6.lib.js3
-rw-r--r--src/mono/wasm/runtime/exports.ts9
-rw-r--r--src/mono/wasm/runtime/workers/dotnet-crypto-worker.js44
5 files changed, 66 insertions, 16 deletions
diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js
index ceeb9d37d75..d8492ff8ced 100644
--- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js
+++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js
@@ -70,8 +70,9 @@ const linked_functions = [
"mono_wasm_get_icudt_name",
// pal_crypto_webworker.c
+ "dotnet_browser_can_use_subtle_crypto_impl",
"dotnet_browser_simple_digest_hash",
- "dotnet_browser_can_use_simple_digest_hash",
+ "dotnet_browser_sign",
];
// -- this javascript file is evaluated by emcc during compilation! --
diff --git a/src/mono/wasm/runtime/crypto-worker.ts b/src/mono/wasm/runtime/crypto-worker.ts
index f17a455892d..92171e76562 100644
--- a/src/mono/wasm/runtime/crypto-worker.ts
+++ b/src/mono/wasm/runtime/crypto-worker.ts
@@ -9,7 +9,7 @@ let mono_wasm_crypto: {
worker: Worker
} | null = null;
-export function dotnet_browser_can_use_simple_digest_hash(): number {
+export function dotnet_browser_can_use_subtle_crypto_impl(): number {
return mono_wasm_crypto === null ? 0 : 1;
}
@@ -33,6 +33,27 @@ export function dotnet_browser_simple_digest_hash(ver: number, input_buffer: num
return 1;
}
+export function dotnet_browser_sign(hashAlgorithm: number, key_buffer: number, key_len: number, input_buffer: number, input_len: number, output_buffer: number, output_len: number): number {
+ mono_assert(!!mono_wasm_crypto, "subtle crypto not initialized");
+
+ const msg = {
+ func: "sign",
+ type: hashAlgorithm,
+ key: Array.from(Module.HEAPU8.subarray(key_buffer, key_buffer + key_len)),
+ data: Array.from(Module.HEAPU8.subarray(input_buffer, input_buffer + input_len))
+ };
+
+ const response = mono_wasm_crypto.channel.send_msg(JSON.stringify(msg));
+ const signResult = JSON.parse(response);
+ if (signResult.length > output_len) {
+ console.info("dotnet_browser_sign: about to throw!");
+ throw "SIGN HASH: Sign length exceeds output length: " + signResult.length + " > " + output_len;
+ }
+
+ Module.HEAPU8.set(signResult, output_buffer);
+ return 1;
+}
+
export function init_crypto(): void {
if (typeof globalThis.crypto !== "undefined" && typeof globalThis.crypto.subtle !== "undefined"
&& typeof SharedArrayBuffer !== "undefined"
diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js
index 5866ffed265..3cabbf8833e 100644
--- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js
+++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js
@@ -107,8 +107,9 @@ const linked_functions = [
"mono_wasm_get_icudt_name",
// pal_crypto_webworker.c
+ "dotnet_browser_can_use_subtle_crypto_impl",
"dotnet_browser_simple_digest_hash",
- "dotnet_browser_can_use_simple_digest_hash",
+ "dotnet_browser_sign",
];
// -- this javascript file is evaluated by emcc during compilation! --
diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts
index 439665bcc94..16b7e88054a 100644
--- a/src/mono/wasm/runtime/exports.ts
+++ b/src/mono/wasm/runtime/exports.ts
@@ -69,7 +69,11 @@ import { fetch_like, readAsync_like } from "./polyfills";
import { EmscriptenModule } from "./types/emscripten";
import { mono_run_main, mono_run_main_and_exit } from "./run";
import { diagnostics } from "./diagnostics";
-import { dotnet_browser_can_use_simple_digest_hash, dotnet_browser_simple_digest_hash } from "./crypto-worker";
+import {
+ dotnet_browser_can_use_subtle_crypto_impl,
+ dotnet_browser_simple_digest_hash,
+ dotnet_browser_sign
+} from "./crypto-worker";
const MONO = {
// current "public" MONO API
@@ -370,8 +374,9 @@ export const __linker_exports: any = {
mono_wasm_get_icudt_name,
// pal_crypto_webworker.c
+ dotnet_browser_can_use_subtle_crypto_impl,
dotnet_browser_simple_digest_hash,
- dotnet_browser_can_use_simple_digest_hash,
+ dotnet_browser_sign
};
const INTERNAL: any = {
diff --git a/src/mono/wasm/runtime/workers/dotnet-crypto-worker.js b/src/mono/wasm/runtime/workers/dotnet-crypto-worker.js
index 329e6a48a76..5e27dd59b5f 100644
--- a/src/mono/wasm/runtime/workers/dotnet-crypto-worker.js
+++ b/src/mono/wasm/runtime/workers/dotnet-crypto-worker.js
@@ -163,29 +163,51 @@ var ChannelWorker = {
};
async function call_digest(type, data) {
- var digest_type = "";
- switch(type) {
- case 0: digest_type = "SHA-1"; break;
- case 1: digest_type = "SHA-256"; break;
- case 2: digest_type = "SHA-384"; break;
- case 3: digest_type = "SHA-512"; break;
- default:
- throw "CRYPTO: Unknown digest: " + type;
- }
+ const digest_type = get_hash_name(type);
// The 'crypto' API is not available in non-browser
// environments (for example, v8 server).
- var digest = await crypto.subtle.digest(digest_type, data);
+ const digest = await crypto.subtle.digest(digest_type, data);
return Array.from(new Uint8Array(digest));
}
+async function sign(type, key, data) {
+ const hash_name = get_hash_name(type);
+
+ if (key.length === 0) {
+ // crypto.subtle.importKey will raise an error for an empty key.
+ // To prevent an error, reset it to a key with just a `0x00` byte. This is equivalent
+ // since HMAC keys get zero-extended up to the block size of the algorithm.
+ key = new Uint8Array([0]);
+ }
+
+ const cryptoKey = await crypto.subtle.importKey("raw", key, {name: "HMAC", hash: hash_name}, false /* extractable */, ["sign"]);
+ const signResult = await crypto.subtle.sign("HMAC", cryptoKey, data);
+ return Array.from(new Uint8Array(signResult));
+}
+
+function get_hash_name(type) {
+ switch(type) {
+ case 0: return "SHA-1";
+ case 1: return "SHA-256";
+ case 2: return "SHA-384";
+ case 3: return "SHA-512";
+ default:
+ throw "CRYPTO: Unknown digest: " + type;
+ }
+}
+
// Operation to perform.
async function async_call(msg) {
const req = JSON.parse(msg);
if (req.func === "digest") {
- var digestArr = await call_digest(req.type, new Uint8Array(req.data));
+ const digestArr = await call_digest(req.type, new Uint8Array(req.data));
return JSON.stringify(digestArr);
+ }
+ else if (req.func === "sign") {
+ const signResult = await sign(req.type, new Uint8Array(req.key), new Uint8Array(req.data));
+ return JSON.stringify(signResult);
} else {
throw "CRYPTO: Unknown request: " + req.func;
}