diff options
author | chiefbiiko <noah.anabiik.schwarz@gmail.com> | 2019-05-17 20:03:01 +0200 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2019-05-17 14:03:01 -0400 |
commit | 00f6fa46b34b78e926a907ee24faec78a65eafc1 (patch) | |
tree | 856ba74eb30c595f98683d0aa3161c73caa13e5e /js | |
parent | 7f6549532c22e5e58deb37334fca06c949902e5f (diff) |
Add crypto.getRandomValues() (#2327)
Diffstat (limited to 'js')
-rw-r--r-- | js/get_random_values.ts | 35 | ||||
-rw-r--r-- | js/get_random_values_test.ts | 51 | ||||
-rw-r--r-- | js/globals.ts | 21 | ||||
-rw-r--r-- | js/test_util.ts | 4 | ||||
-rw-r--r-- | js/unit_tests.ts | 1 |
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"; |