From d8d5c421c33b1cc5416ff87f6a7c3837e5176d4d Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Tue, 28 Aug 2018 13:49:19 -0400 Subject: [PATCH] Support https imports. Adds hyper-rustls to the build. Use ring for sha1 instead of "ssh1" crate. Fixes #528. --- BUILD.gn | 3 +- Cargo.toml | 4 +- build_extra/rust/BUILD.gn | 234 +++++++++++++++++++++++++++++++++++++- src/deno_dir.rs | 22 ++-- src/main.rs | 3 +- src/net.rs | 6 +- tests/https_import.ts | 5 + tests/https_import.ts.out | 2 + third_party | 2 +- 9 files changed, 262 insertions(+), 19 deletions(-) create mode 100644 tests/https_import.ts create mode 100644 tests/https_import.ts.out diff --git a/BUILD.gn b/BUILD.gn index 74597ff1d0..0cae2087f7 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -38,10 +38,11 @@ config("deno_config") { main_extern = [ "$rust_build:hyper", + "$rust_build:hyper_rustls", "$rust_build:futures", "$rust_build:libc", "$rust_build:log", - "$rust_build:sha1", + "$rust_build:ring", "$rust_build:tempfile", "$rust_build:rand", "$rust_build:tokio", diff --git a/Cargo.toml b/Cargo.toml index 0803b7f45c..1407831c1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,8 @@ version = "0.0.0" url = "1.7.1" libc = "0.2.42" log = "0.4.3" -rand = "0.5.4" -sha1 = "0.6.0" +rand = "0.4.2" tempfile = "3" tokio = "0.1" hyper = "0.12.8" +hyper-rustls = "0.14.0" diff --git a/build_extra/rust/BUILD.gn b/build_extra/rust/BUILD.gn index 5e8439ecb2..382f9a90b2 100644 --- a/build_extra/rust/BUILD.gn +++ b/build_extra/rust/BUILD.gn @@ -67,11 +67,6 @@ rust_crate("cfg_if") { source_root = "$registry_github/cfg-if-0.1.4/src/lib.rs" } -rust_crate("sha1") { - source_root = "$registry_github/sha1-0.6.0/src/lib.rs" - args = [ "-Aunused_parens" ] # https://github.com/mitsuhiko/rust-sha1/issues/36 -} - rust_crate("tempfile") { source_root = "$registry_github/tempfile-3.0.2/src/lib.rs" extern = [ @@ -401,6 +396,7 @@ rust_crate("tokio_core") { ":log", ":iovec", ":bytes", + ":scoped_tls", ] } @@ -584,3 +580,231 @@ rust_crate("tokio_threadpool") { ":tokio_executor", ] } + +rust_crate("hyper_rustls") { + source_root = "$registry_github/hyper-rustls-0.14.0/src/lib.rs" + extern = [ + ":ct_logs", + ":futures", + ":http", + ":hyper", + ":rustls", + ":tokio_core", + ":tokio_io", + ":tokio_rustls", + ":tokio_tcp", + ":webpki", + ":webpki_roots", + ] +} + +ring_root = "$registry_github/ring-0.13.2/" + +component("ring_primitives") { + sources = [ + "$ring_root/crypto/constant_time_test.c", + "$ring_root/crypto/cpu-aarch64-linux.c", + "$ring_root/crypto/cpu-arm-linux.c", + "$ring_root/crypto/cpu-arm.c", + "$ring_root/crypto/cpu-intel.c", + "$ring_root/crypto/crypto.c", + "$ring_root/crypto/fipsmodule/aes/aes.c", + "$ring_root/crypto/fipsmodule/aes/internal.h", + "$ring_root/crypto/fipsmodule/bn/exponentiation.c", + "$ring_root/crypto/fipsmodule/bn/generic.c", + "$ring_root/crypto/fipsmodule/bn/internal.h", + "$ring_root/crypto/fipsmodule/bn/montgomery.c", + "$ring_root/crypto/fipsmodule/bn/montgomery_inv.c", + "$ring_root/crypto/fipsmodule/bn/shift.c", + "$ring_root/crypto/fipsmodule/cipher/e_aes.c", + "$ring_root/crypto/fipsmodule/cipher/internal.h", + "$ring_root/crypto/fipsmodule/ec", + "$ring_root/crypto/fipsmodule/ec/ecp_nistz.c", + "$ring_root/crypto/fipsmodule/ec/ecp_nistz.h", + "$ring_root/crypto/fipsmodule/ec/ecp_nistz256.c", + "$ring_root/crypto/fipsmodule/ec/ecp_nistz256.h", + "$ring_root/crypto/fipsmodule/ec/ecp_nistz384.h", + "$ring_root/crypto/fipsmodule/ec/gfp_p256.c", + "$ring_root/crypto/fipsmodule/ec/gfp_p384.c", + "$ring_root/crypto/fipsmodule/modes/gcm.c", + "$ring_root/crypto/fipsmodule/modes/internal.h", + "$ring_root/crypto/internal.h", + "$ring_root/crypto/limbs/limbs.c", + "$ring_root/crypto/limbs/limbs.h", + "$ring_root/crypto/mem.c", + "$ring_root/include/GFp/aes.h", + "$ring_root/include/GFp/arm_arch.h", + "$ring_root/include/GFp/base.h", + "$ring_root/include/GFp/cpu.h", + "$ring_root/include/GFp/mem.h", + "$ring_root/include/GFp/type_check.h", + "$ring_root/third_party/fiat/curve25519.c", + "$ring_root/third_party/fiat/curve25519_tables.h", + "$ring_root/third_party/fiat/internal.h", + + #"$ring_root/crypto/fipsmodule/modes/polyval.c", + ] + if (is_mac) { + sources += [ + "$ring_root/pregenerated/aes-586-macosx.S", + "$ring_root/pregenerated/aes-x86_64-macosx.S", + "$ring_root/pregenerated/aesni-gcm-x86_64-macosx.S", + "$ring_root/pregenerated/aesni-x86-macosx.S", + "$ring_root/pregenerated/aesni-x86_64-macosx.S", + "$ring_root/pregenerated/chacha-x86-macosx.S", + "$ring_root/pregenerated/chacha-x86_64-macosx.S", + "$ring_root/pregenerated/ecp_nistz256-x86-macosx.S", + "$ring_root/pregenerated/ghash-x86-macosx.S", + "$ring_root/pregenerated/ghash-x86_64-macosx.S", + "$ring_root/pregenerated/p256-x86_64-asm-macosx.S", + "$ring_root/pregenerated/poly1305-x86-macosx.S", + "$ring_root/pregenerated/poly1305-x86_64-macosx.S", + "$ring_root/pregenerated/sha256-586-macosx.S", + "$ring_root/pregenerated/sha256-x86_64-macosx.S", + "$ring_root/pregenerated/sha512-586-macosx.S", + "$ring_root/pregenerated/sha512-x86_64-macosx.S", + "$ring_root/pregenerated/vpaes-x86-macosx.S", + "$ring_root/pregenerated/vpaes-x86_64-macosx.S", + "$ring_root/pregenerated/x86-mont-macosx.S", + "$ring_root/pregenerated/x86_64-mont-macosx.S", + "$ring_root/pregenerated/x86_64-mont5-macosx.S", + ] + } + if (is_linux) { + sources += [ + "$ring_root/pregenerated/aes-x86_64-elf.S", + "$ring_root/pregenerated/aesni-gcm-x86_64-elf.S", + "$ring_root/pregenerated/aesni-x86_64-elf.S", + "$ring_root/pregenerated/aesv8-armx-linux64.S", + "$ring_root/pregenerated/chacha-x86_64-elf.S", + "$ring_root/pregenerated/ghash-x86_64-elf.S", + "$ring_root/pregenerated/ghashv8-armx-linux64.S", + "$ring_root/pregenerated/p256-x86_64-asm-elf.S", + "$ring_root/pregenerated/poly1305-x86_64-elf.S", + "$ring_root/pregenerated/sha256-x86_64-elf.S", + "$ring_root/pregenerated/sha512-x86_64-elf.S", + "$ring_root/pregenerated/vpaes-x86_64-elf.S", + "$ring_root/pregenerated/x86_64-mont-elf.S", + "$ring_root/pregenerated/x86_64-mont5-elf.S", + ] + } + if (is_win) { + libs = [ + "$ring_root/pregenerated/aes-x86_64-nasm.obj", + "$ring_root/pregenerated/aesni-gcm-x86_64-nasm.obj", + "$ring_root/pregenerated/aesni-x86_64-nasm.obj", + "$ring_root/pregenerated/chacha-x86_64-nasm.obj", + "$ring_root/pregenerated/ghash-x86_64-nasm.obj", + "$ring_root/pregenerated/p256-x86_64-asm-nasm.obj", + "$ring_root/pregenerated/poly1305-x86_64-nasm.obj", + "$ring_root/pregenerated/sha256-x86_64-nasm.obj", + "$ring_root/pregenerated/sha512-x86_64-nasm.obj", + "$ring_root/pregenerated/vpaes-x86_64-nasm.obj", + "$ring_root/pregenerated/x86_64-mont-nasm.obj", + "$ring_root/pregenerated/x86_64-mont5-nasm.obj", + ] + } + include_dirs = [ "$ring_root/include/" ] +} + +rust_crate("ring") { + source_root = "$ring_root/src/lib.rs" + features = [ + "use_heap", + "rsa_signing", + ] + extern = [ + ":libc", + ":untrusted", + ":lazy_static", + ] + deps = [ + ":ring_primitives", + ] +} + +rust_crate("rustls") { + source_root = "$registry_github/rustls-0.13.1/src/lib.rs" + extern = [ + ":untrusted", + ":base64", + ":log", + ":ring", + ":webpki", + ":sct", + ] + args = [ "-Aunused_variables" ] # TODO Remove. +} + +rust_crate("ct_logs") { + source_root = "$registry_github/ct-logs-0.4.0/src/lib.rs" + extern = [ ":sct" ] +} + +rust_crate("tokio_rustls") { + source_root = "$registry_github/tokio-rustls-0.7.2/src/lib.rs" + extern = [ + ":rustls", + ":webpki", + ":tokio", + ] + features = [ + "default", + "tokio", + "tokio-support", + ] + args = [ "-Adead_code" ] # TODO Remove. +} + +rust_crate("untrusted") { + source_root = "$registry_github/untrusted-0.6.2/src/untrusted.rs" + extern = [] +} + +rust_crate("webpki") { + source_root = "$registry_github/webpki-0.18.1/src/webpki.rs" + features = [ + "std", + "trust_anchor_util", + ] + extern = [ + ":ring", + ":untrusted", + ] +} + +rust_crate("webpki_roots") { + source_root = "$registry_github/webpki-roots-0.15.0/src/lib.rs" + extern = [ + ":webpki", + ":untrusted", + ] +} + +rust_crate("sct") { + source_root = "$registry_github/sct-0.4.0/src/lib.rs" + extern = [ + ":ring", + ":untrusted", + ] +} + +rust_crate("base64") { + source_root = "$registry_github/base64-0.9.2/src/lib.rs" + extern = [ + ":byteorder", + ":safemem", + ] +} + +rust_crate("safemem") { + source_root = "$registry_github/safemem-0.2.0/src/lib.rs" +} + +rust_crate("scoped_tls") { + source_root = "$registry_github/scoped-tls-0.1.2/src/lib.rs" + extern = [ + ":ring", + ":untrusted", + ] +} diff --git a/src/deno_dir.rs b/src/deno_dir.rs index 45ce7db28e..0a3557d5b3 100644 --- a/src/deno_dir.rs +++ b/src/deno_dir.rs @@ -3,17 +3,17 @@ use errors::DenoError; use errors::DenoResult; use fs as deno_fs; use net; -use sha1; +use ring; use std; +use std::fmt::Write; use std::fs; use std::path::Path; use std::path::PathBuf; use std::result::Result; -use url; -use url::Url; - #[cfg(test)] use tempfile::TempDir; +use url; +use url::Url; pub struct DenoDir { // Example: /Users/rld/.deno/ @@ -331,10 +331,16 @@ fn test_code_cache() { // https://github.com/denoland/deno/blob/golang/deno_dir.go#L25-L30 fn source_code_hash(filename: &str, source_code: &str) -> String { - let mut m = sha1::Sha1::new(); - m.update(filename.as_bytes()); - m.update(source_code.as_bytes()); - m.digest().to_string() + let mut ctx = ring::digest::Context::new(&ring::digest::SHA1); + ctx.update(filename.as_bytes()); + ctx.update(source_code.as_bytes()); + let digest = ctx.finish(); + let mut out = String::new(); + // TODO There must be a better way to do this... + for byte in digest.as_ref() { + write!(&mut out, "{:02x}", byte).unwrap(); + } + out } #[test] diff --git a/src/main.rs b/src/main.rs index a43f62642c..e4a7566548 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,12 +4,13 @@ extern crate hyper; extern crate libc; extern crate msg_rs as msg_generated; extern crate rand; -extern crate sha1; extern crate tempfile; extern crate tokio; extern crate url; #[macro_use] extern crate log; +extern crate hyper_rustls; +extern crate ring; mod binding; mod deno_dir; diff --git a/src/net.rs b/src/net.rs index fc0df3fa28..7e0700bb68 100644 --- a/src/net.rs +++ b/src/net.rs @@ -1,13 +1,17 @@ use errors::DenoResult; +use hyper; use hyper::rt::{Future, Stream}; use hyper::{Client, Uri}; +use hyper_rustls; use tokio::runtime::current_thread::Runtime; // The CodeFetch message is used to load HTTP javascript resources and expects a // synchronous response, this utility method supports that. pub fn fetch_sync_string(module_name: &str) -> DenoResult { let url = module_name.parse::().unwrap(); - let client = Client::new(); + + let https = hyper_rustls::HttpsConnector::new(4); + let client: Client<_, hyper::Body> = Client::builder().build(https); // TODO Use Deno's RT let mut rt = Runtime::new().unwrap(); diff --git a/tests/https_import.ts b/tests/https_import.ts new file mode 100644 index 0000000000..faaf2175f1 --- /dev/null +++ b/tests/https_import.ts @@ -0,0 +1,5 @@ +// TODO Use https://localhost:4555/ but we need more infrastructure to +// support verifying self-signed certificates. +import { printHello } from "https://gist.githubusercontent.com/ry/f12b2aa3409e6b52645bc346a9e22929/raw/79318f239f51d764384a8bded8d7c6a833610dde/print_hello.ts"; + +printHello(); diff --git a/tests/https_import.ts.out b/tests/https_import.ts.out new file mode 100644 index 0000000000..efc3fd5433 --- /dev/null +++ b/tests/https_import.ts.out @@ -0,0 +1,2 @@ +Downloading https://gist.githubusercontent.com/ry/f12b2aa3409e6b52645bc346a9e22929/raw/79318f239f51d764384a8bded8d7c6a833610dde/print_hello.ts +Hello diff --git a/third_party b/third_party index 0398b18406..8c1d351df3 160000 --- a/third_party +++ b/third_party @@ -1 +1 @@ -Subproject commit 0398b184060eb0f4e8e1b9ab20b1e21a4f37755c +Subproject commit 8c1d351df3139d82a939b2f5052e0fd96c577d65