summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorchiefbiiko <noah.anabiik.schwarz@gmail.com>2019-05-17 20:03:01 +0200
committerRyan Dahl <ry@tinyclouds.org>2019-05-17 14:03:01 -0400
commit00f6fa46b34b78e926a907ee24faec78a65eafc1 (patch)
tree856ba74eb30c595f98683d0aa3161c73caa13e5e /js
parent7f6549532c22e5e58deb37334fca06c949902e5f (diff)
Add crypto.getRandomValues() (#2327)
Diffstat (limited to 'js')
-rw-r--r--js/get_random_values.ts35
-rw-r--r--js/get_random_values_test.ts51
-rw-r--r--js/globals.ts21
-rw-r--r--js/test_util.ts4
-rw-r--r--js/unit_tests.ts1
5 files changed, 111 insertions, 1 deletions
diff --git a/js/get_random_values.ts b/js/get_random_values.ts
new file mode 100644
index 000000000..eb46ed009
--- /dev/null
+++ b/js/get_random_values.ts
@@ -0,0 +1,35 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+import * as msg from "gen/cli/msg_generated";
+import * as flatbuffers from "./flatbuffers";
+import * as dispatch from "./dispatch";
+import { assert } from "./util";
+
+function req(
+ typedArray: ArrayBufferView
+): [flatbuffers.Builder, msg.Any, flatbuffers.Offset, ArrayBufferView] {
+ const builder = flatbuffers.createBuilder();
+ const inner = msg.GetRandomValues.createGetRandomValues(builder);
+ return [builder, msg.Any.GetRandomValues, inner, typedArray];
+}
+
+/** Synchronously collects cryptographically secure random values. The
+ * underlying CSPRNG in use is Rust's `rand::rngs::ThreadRng`.
+ *
+ * const arr = new Uint8Array(32);
+ * crypto.getRandomValues(arr);
+ */
+export function getRandomValues<
+ T extends
+ | Int8Array
+ | Uint8Array
+ | Uint8ClampedArray
+ | Int16Array
+ | Uint16Array
+ | Int32Array
+ | Uint32Array
+>(typedArray: T): T {
+ assert(typedArray !== null, "Input must not be null");
+ assert(typedArray.length <= 65536, "Input must not be longer than 65536");
+ dispatch.sendSync(...req(typedArray as ArrayBufferView));
+ return typedArray;
+}
diff --git a/js/get_random_values_test.ts b/js/get_random_values_test.ts
new file mode 100644
index 000000000..68c13d597
--- /dev/null
+++ b/js/get_random_values_test.ts
@@ -0,0 +1,51 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+import { test, assertNotEquals, assertStrictEq } from "./test_util.ts";
+
+test(function getRandomValuesInt8Array(): void {
+ const arr = new Int8Array(32);
+ crypto.getRandomValues(arr);
+ assertNotEquals(arr, new Int8Array(32));
+});
+
+test(function getRandomValuesUint8Array(): void {
+ const arr = new Uint8Array(32);
+ crypto.getRandomValues(arr);
+ assertNotEquals(arr, new Uint8Array(32));
+});
+
+test(function getRandomValuesUint8ClampedArray(): void {
+ const arr = new Uint8ClampedArray(32);
+ crypto.getRandomValues(arr);
+ assertNotEquals(arr, new Uint8ClampedArray(32));
+});
+
+test(function getRandomValuesInt16Array(): void {
+ const arr = new Int16Array(4);
+ crypto.getRandomValues(arr);
+ assertNotEquals(arr, new Int16Array(4));
+});
+
+test(function getRandomValuesUint16Array(): void {
+ const arr = new Uint16Array(4);
+ crypto.getRandomValues(arr);
+ assertNotEquals(arr, new Uint16Array(4));
+});
+
+test(function getRandomValuesInt32Array(): void {
+ const arr = new Int32Array(8);
+ crypto.getRandomValues(arr);
+ assertNotEquals(arr, new Int32Array(8));
+});
+
+test(function getRandomValuesUint32Array(): void {
+ const arr = new Uint32Array(8);
+ crypto.getRandomValues(arr);
+ assertNotEquals(arr, new Uint32Array(8));
+});
+
+test(function getRandomValuesReturnValue(): void {
+ const arr = new Uint32Array(8);
+ const rtn = crypto.getRandomValues(arr);
+ assertNotEquals(arr, new Uint32Array(8));
+ assertStrictEq(rtn, arr);
+});
diff --git a/js/globals.ts b/js/globals.ts
index 765215661..c8289d305 100644
--- a/js/globals.ts
+++ b/js/globals.ts
@@ -10,6 +10,7 @@
import { window } from "./window";
import * as blob from "./blob";
import * as consoleTypes from "./console";
+import * as csprng from "./get_random_values";
import * as customEvent from "./custom_event";
import * as deno from "./deno";
import * as domTypes from "./dom_types";
@@ -69,6 +70,10 @@ window.console = console;
window.setTimeout = timers.setTimeout;
window.setInterval = timers.setInterval;
window.location = (undefined as unknown) as domTypes.Location;
+// The following Crypto interface implementation is not up to par with the
+// standard https://www.w3.org/TR/WebCryptoAPI/#crypto-interface as it does not
+// yet incorporate the SubtleCrypto interface as its "subtle" property.
+window.crypto = (csprng as unknown) as Crypto;
// When creating the runtime type library, we use modifications to `window` to
// determine what is in the global namespace. When we put a class in the
@@ -135,3 +140,19 @@ export interface ImportMeta {
url: string;
main: boolean;
}
+
+export interface Crypto {
+ readonly subtle: null;
+ getRandomValues: <
+ T extends
+ | Int8Array
+ | Uint8Array
+ | Uint8ClampedArray
+ | Int16Array
+ | Uint16Array
+ | Int32Array
+ | Uint32Array
+ >(
+ typedArray: T
+ ) => T;
+}
diff --git a/js/test_util.ts b/js/test_util.ts
index 9d13af634..af5dbd2b5 100644
--- a/js/test_util.ts
+++ b/js/test_util.ts
@@ -14,7 +14,9 @@ import {
} from "./deps/https/deno.land/std/testing/asserts.ts";
export {
assert,
- assertEquals
+ assertEquals,
+ assertNotEquals,
+ assertStrictEq
} from "./deps/https/deno.land/std/testing/asserts.ts";
interface TestPermissions {
diff --git a/js/unit_tests.ts b/js/unit_tests.ts
index b0c6a12f9..eb6f62bdb 100644
--- a/js/unit_tests.ts
+++ b/js/unit_tests.ts
@@ -19,6 +19,7 @@ import "./fetch_test.ts";
import "./file_test.ts";
import "./files_test.ts";
import "./form_data_test.ts";
+import "./get_random_values_test.ts";
import "./globals_test.ts";
import "./headers_test.ts";
import "./link_test.ts";