mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
Add crypto.getRandomValues() (#2327)
This commit is contained in:
parent
7f6549532c
commit
00f6fa46b3
9 changed files with 128 additions and 1 deletions
|
@ -88,6 +88,7 @@ ts_sources = [
|
||||||
"../js/files.ts",
|
"../js/files.ts",
|
||||||
"../js/flatbuffers.ts",
|
"../js/flatbuffers.ts",
|
||||||
"../js/form_data.ts",
|
"../js/form_data.ts",
|
||||||
|
"../js/get_random_values.ts",
|
||||||
"../js/globals.ts",
|
"../js/globals.ts",
|
||||||
"../js/headers.ts",
|
"../js/headers.ts",
|
||||||
"../js/io.ts",
|
"../js/io.ts",
|
||||||
|
|
|
@ -11,6 +11,7 @@ extern crate clap;
|
||||||
extern crate deno;
|
extern crate deno;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
extern crate nix;
|
extern crate nix;
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
mod ansi;
|
mod ansi;
|
||||||
pub mod compiler;
|
pub mod compiler;
|
||||||
|
|
|
@ -19,6 +19,7 @@ union Any {
|
||||||
FetchRes,
|
FetchRes,
|
||||||
FormatError,
|
FormatError,
|
||||||
FormatErrorRes,
|
FormatErrorRes,
|
||||||
|
GetRandomValues,
|
||||||
GlobalTimer,
|
GlobalTimer,
|
||||||
GlobalTimerRes,
|
GlobalTimerRes,
|
||||||
GlobalTimerStop,
|
GlobalTimerStop,
|
||||||
|
@ -578,4 +579,6 @@ table Seek {
|
||||||
whence: uint;
|
whence: uint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table GetRandomValues {}
|
||||||
|
|
||||||
root_type Base;
|
root_type Base;
|
||||||
|
|
12
cli/ops.rs
12
cli/ops.rs
|
@ -13,6 +13,7 @@ use crate::js_errors::apply_source_map;
|
||||||
use crate::js_errors::JSErrorColor;
|
use crate::js_errors::JSErrorColor;
|
||||||
use crate::msg;
|
use crate::msg;
|
||||||
use crate::msg_util;
|
use crate::msg_util;
|
||||||
|
use crate::rand;
|
||||||
use crate::repl;
|
use crate::repl;
|
||||||
use crate::resolve_addr::resolve_addr;
|
use crate::resolve_addr::resolve_addr;
|
||||||
use crate::resources;
|
use crate::resources;
|
||||||
|
@ -39,6 +40,7 @@ use futures::Sink;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use hyper;
|
use hyper;
|
||||||
use hyper::rt::Future;
|
use hyper::rt::Future;
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
use remove_dir_all::remove_dir_all;
|
use remove_dir_all::remove_dir_all;
|
||||||
use std;
|
use std;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
@ -195,6 +197,7 @@ pub fn op_selector_std(inner_type: msg::Any) -> Option<OpCreator> {
|
||||||
msg::Any::Exit => Some(op_exit),
|
msg::Any::Exit => Some(op_exit),
|
||||||
msg::Any::Fetch => Some(op_fetch),
|
msg::Any::Fetch => Some(op_fetch),
|
||||||
msg::Any::FormatError => Some(op_format_error),
|
msg::Any::FormatError => Some(op_format_error),
|
||||||
|
msg::Any::GetRandomValues => Some(op_get_random_values),
|
||||||
msg::Any::GlobalTimer => Some(op_global_timer),
|
msg::Any::GlobalTimer => Some(op_global_timer),
|
||||||
msg::Any::GlobalTimerStop => Some(op_global_timer_stop),
|
msg::Any::GlobalTimerStop => Some(op_global_timer_stop),
|
||||||
msg::Any::IsTTY => Some(op_is_tty),
|
msg::Any::IsTTY => Some(op_is_tty),
|
||||||
|
@ -2168,3 +2171,12 @@ fn op_host_post_message(
|
||||||
});
|
});
|
||||||
Box::new(op)
|
Box::new(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn op_get_random_values(
|
||||||
|
_state: &ThreadSafeState,
|
||||||
|
_base: &msg::Base<'_>,
|
||||||
|
data: Option<PinnedBuf>,
|
||||||
|
) -> Box<OpWithError> {
|
||||||
|
thread_rng().fill(&mut data.unwrap()[..]);
|
||||||
|
Box::new(ok_future(empty_buf()))
|
||||||
|
}
|
||||||
|
|
35
js/get_random_values.ts
Normal file
35
js/get_random_values.ts
Normal file
|
@ -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;
|
||||||
|
}
|
51
js/get_random_values_test.ts
Normal file
51
js/get_random_values_test.ts
Normal file
|
@ -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);
|
||||||
|
});
|
|
@ -10,6 +10,7 @@
|
||||||
import { window } from "./window";
|
import { window } from "./window";
|
||||||
import * as blob from "./blob";
|
import * as blob from "./blob";
|
||||||
import * as consoleTypes from "./console";
|
import * as consoleTypes from "./console";
|
||||||
|
import * as csprng from "./get_random_values";
|
||||||
import * as customEvent from "./custom_event";
|
import * as customEvent from "./custom_event";
|
||||||
import * as deno from "./deno";
|
import * as deno from "./deno";
|
||||||
import * as domTypes from "./dom_types";
|
import * as domTypes from "./dom_types";
|
||||||
|
@ -69,6 +70,10 @@ window.console = console;
|
||||||
window.setTimeout = timers.setTimeout;
|
window.setTimeout = timers.setTimeout;
|
||||||
window.setInterval = timers.setInterval;
|
window.setInterval = timers.setInterval;
|
||||||
window.location = (undefined as unknown) as domTypes.Location;
|
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
|
// 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
|
// determine what is in the global namespace. When we put a class in the
|
||||||
|
@ -135,3 +140,19 @@ export interface ImportMeta {
|
||||||
url: string;
|
url: string;
|
||||||
main: boolean;
|
main: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Crypto {
|
||||||
|
readonly subtle: null;
|
||||||
|
getRandomValues: <
|
||||||
|
T extends
|
||||||
|
| Int8Array
|
||||||
|
| Uint8Array
|
||||||
|
| Uint8ClampedArray
|
||||||
|
| Int16Array
|
||||||
|
| Uint16Array
|
||||||
|
| Int32Array
|
||||||
|
| Uint32Array
|
||||||
|
>(
|
||||||
|
typedArray: T
|
||||||
|
) => T;
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@ import {
|
||||||
} from "./deps/https/deno.land/std/testing/asserts.ts";
|
} from "./deps/https/deno.land/std/testing/asserts.ts";
|
||||||
export {
|
export {
|
||||||
assert,
|
assert,
|
||||||
assertEquals
|
assertEquals,
|
||||||
|
assertNotEquals,
|
||||||
|
assertStrictEq
|
||||||
} from "./deps/https/deno.land/std/testing/asserts.ts";
|
} from "./deps/https/deno.land/std/testing/asserts.ts";
|
||||||
|
|
||||||
interface TestPermissions {
|
interface TestPermissions {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import "./fetch_test.ts";
|
||||||
import "./file_test.ts";
|
import "./file_test.ts";
|
||||||
import "./files_test.ts";
|
import "./files_test.ts";
|
||||||
import "./form_data_test.ts";
|
import "./form_data_test.ts";
|
||||||
|
import "./get_random_values_test.ts";
|
||||||
import "./globals_test.ts";
|
import "./globals_test.ts";
|
||||||
import "./headers_test.ts";
|
import "./headers_test.ts";
|
||||||
import "./link_test.ts";
|
import "./link_test.ts";
|
||||||
|
|
Loading…
Reference in a new issue