summaryrefslogtreecommitdiff
path: root/extensions/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/crypto')
-rw-r--r--extensions/crypto/01_crypto.js50
-rw-r--r--extensions/crypto/Cargo.toml19
-rw-r--r--extensions/crypto/README.md5
-rw-r--r--extensions/crypto/lib.deno_crypto.d.ts26
-rw-r--r--extensions/crypto/lib.rs56
5 files changed, 156 insertions, 0 deletions
diff --git a/extensions/crypto/01_crypto.js b/extensions/crypto/01_crypto.js
new file mode 100644
index 000000000..dba6b0091
--- /dev/null
+++ b/extensions/crypto/01_crypto.js
@@ -0,0 +1,50 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+"use strict";
+
+((window) => {
+ const core = window.Deno.core;
+
+ function getRandomValues(arrayBufferView) {
+ if (!ArrayBuffer.isView(arrayBufferView)) {
+ throw new TypeError(
+ "Argument 1 does not implement interface ArrayBufferView",
+ );
+ }
+ if (
+ !(
+ arrayBufferView instanceof Int8Array ||
+ arrayBufferView instanceof Uint8Array ||
+ arrayBufferView instanceof Int16Array ||
+ arrayBufferView instanceof Uint16Array ||
+ arrayBufferView instanceof Int32Array ||
+ arrayBufferView instanceof Uint32Array ||
+ arrayBufferView instanceof Uint8ClampedArray
+ )
+ ) {
+ throw new DOMException(
+ "The provided ArrayBufferView is not an integer array type",
+ "TypeMismatchError",
+ );
+ }
+ if (arrayBufferView.byteLength > 65536) {
+ throw new DOMException(
+ `The ArrayBufferView's byte length (${arrayBufferView.byteLength}) exceeds the number of bytes of entropy available via this API (65536)`,
+ "QuotaExceededError",
+ );
+ }
+ const ui8 = new Uint8Array(
+ arrayBufferView.buffer,
+ arrayBufferView.byteOffset,
+ arrayBufferView.byteLength,
+ );
+ core.opSync("op_crypto_get_random_values", null, ui8);
+ return arrayBufferView;
+ }
+
+ window.crypto = {
+ getRandomValues,
+ };
+ window.__bootstrap.crypto = {
+ getRandomValues,
+ };
+})(this);
diff --git a/extensions/crypto/Cargo.toml b/extensions/crypto/Cargo.toml
new file mode 100644
index 000000000..91f60aa9c
--- /dev/null
+++ b/extensions/crypto/Cargo.toml
@@ -0,0 +1,19 @@
+# Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+[package]
+name = "deno_crypto"
+version = "0.19.0"
+edition = "2018"
+description = "Web Cryptography API implementation for Deno"
+authors = ["the Deno authors"]
+license = "MIT"
+readme = "README.md"
+repository = "https://github.com/denoland/deno"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+deno_core = { version = "0.86.0", path = "../../core" }
+rand = "0.8.3"
+
diff --git a/extensions/crypto/README.md b/extensions/crypto/README.md
new file mode 100644
index 000000000..be0724458
--- /dev/null
+++ b/extensions/crypto/README.md
@@ -0,0 +1,5 @@
+# deno_crypto
+
+This crate implements the Web Cryptography API.
+
+Spec: https://www.w3.org/TR/WebCryptoAPI/
diff --git a/extensions/crypto/lib.deno_crypto.d.ts b/extensions/crypto/lib.deno_crypto.d.ts
new file mode 100644
index 000000000..a00757e71
--- /dev/null
+++ b/extensions/crypto/lib.deno_crypto.d.ts
@@ -0,0 +1,26 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+/// <reference no-default-lib="true" />
+/// <reference lib="esnext" />
+
+declare var crypto: Crypto;
+
+declare interface Crypto {
+ readonly subtle: null;
+ getRandomValues<
+ T extends
+ | Int8Array
+ | Int16Array
+ | Int32Array
+ | Uint8Array
+ | Uint16Array
+ | Uint32Array
+ | Uint8ClampedArray
+ | Float32Array
+ | Float64Array
+ | DataView
+ | null,
+ >(
+ array: T,
+ ): T;
+}
diff --git a/extensions/crypto/lib.rs b/extensions/crypto/lib.rs
new file mode 100644
index 000000000..45473f4d5
--- /dev/null
+++ b/extensions/crypto/lib.rs
@@ -0,0 +1,56 @@
+// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
+
+use deno_core::error::null_opbuf;
+use deno_core::error::AnyError;
+use deno_core::include_js_files;
+use deno_core::op_sync;
+use deno_core::Extension;
+use deno_core::OpState;
+use deno_core::ZeroCopyBuf;
+use rand::rngs::StdRng;
+use rand::thread_rng;
+use rand::Rng;
+use rand::SeedableRng;
+use std::path::PathBuf;
+
+pub use rand; // Re-export rand
+
+pub fn init(maybe_seed: Option<u64>) -> Extension {
+ Extension::builder()
+ .js(include_js_files!(
+ prefix "deno:extensions/crypto",
+ "01_crypto.js",
+ ))
+ .ops(vec![(
+ "op_crypto_get_random_values",
+ op_sync(op_crypto_get_random_values),
+ )])
+ .state(move |state| {
+ if let Some(seed) = maybe_seed {
+ state.put(StdRng::seed_from_u64(seed));
+ }
+ Ok(())
+ })
+ .build()
+}
+
+pub fn op_crypto_get_random_values(
+ state: &mut OpState,
+ _args: (),
+ zero_copy: Option<ZeroCopyBuf>,
+) -> Result<(), AnyError> {
+ let mut zero_copy = zero_copy.ok_or_else(null_opbuf)?;
+ let maybe_seeded_rng = state.try_borrow_mut::<StdRng>();
+ if let Some(seeded_rng) = maybe_seeded_rng {
+ seeded_rng.fill(&mut *zero_copy);
+ } else {
+ let mut rng = thread_rng();
+ rng.fill(&mut *zero_copy);
+ }
+
+ Ok(())
+}
+
+pub fn get_declaration() -> PathBuf {
+ PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_crypto.d.ts")
+}