1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

Revert "chore: upgrade to reqwest 0.12.4 and rustls 0.22 (#24056)" (#24262)

This reverts commit fb31eaa9ca.

Reverting because users reported spurious errors when downloading
dependencies - https://github.com/denoland/deno/issues/24260.

Closes https://github.com/denoland/deno/issues/24260
This commit is contained in:
Bartek Iwańczuk 2024-06-19 15:09:17 +01:00 committed by GitHub
parent f4eead61eb
commit b94707af7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 656 additions and 396 deletions

167
Cargo.lock generated
View file

@ -705,7 +705,7 @@ dependencies = [
"flaky_test", "flaky_test",
"http 1.1.0", "http 1.1.0",
"http-body-util", "http-body-util",
"hyper 1.3.1", "hyper 1.1.0",
"hyper-util", "hyper-util",
"nix 0.26.2", "nix 0.26.2",
"once_cell", "once_cell",
@ -1434,7 +1434,7 @@ dependencies = [
"deno_permissions", "deno_permissions",
"deno_tls", "deno_tls",
"dyn-clone", "dyn-clone",
"http 1.1.0", "http 0.2.12",
"reqwest", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
@ -1527,7 +1527,7 @@ dependencies = [
"http-body-util", "http-body-util",
"httparse", "httparse",
"hyper 0.14.28", "hyper 0.14.28",
"hyper 1.3.1", "hyper 1.1.0",
"hyper-util", "hyper-util",
"itertools", "itertools",
"memmem", "memmem",
@ -1570,7 +1570,6 @@ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
"base64 0.21.7", "base64 0.21.7",
"bytes",
"chrono", "chrono",
"deno_core", "deno_core",
"deno_fetch", "deno_fetch",
@ -1581,7 +1580,6 @@ dependencies = [
"denokv_remote", "denokv_remote",
"denokv_sqlite", "denokv_sqlite",
"faster-hex", "faster-hex",
"http 1.1.0",
"log", "log",
"num-bigint", "num-bigint",
"prost", "prost",
@ -1642,9 +1640,9 @@ dependencies = [
[[package]] [[package]]
name = "deno_native_certs" name = "deno_native_certs"
version = "0.3.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c867603d2a5dfea31f55cecebb572554caa395437786d058faa9a2814c8d6eb9" checksum = "f4785d0bdc13819b665b71e4fb7e119d859568471e4c245ec5610857e70c9345"
dependencies = [ dependencies = [
"dlopen2", "dlopen2",
"dlopen2_derive", "dlopen2_derive",
@ -1694,10 +1692,10 @@ dependencies = [
"elliptic-curve", "elliptic-curve",
"errno 0.2.8", "errno 0.2.8",
"faster-hex", "faster-hex",
"h2 0.4.4", "h2 0.3.26",
"hkdf", "hkdf",
"home", "home",
"http 1.1.0", "http 0.2.12",
"idna 0.3.0", "idna 0.3.0",
"indexmap", "indexmap",
"ipnetwork", "ipnetwork",
@ -1826,7 +1824,7 @@ dependencies = [
"http 1.1.0", "http 1.1.0",
"http-body-util", "http-body-util",
"hyper 0.14.28", "hyper 0.14.28",
"hyper 1.3.1", "hyper 1.1.0",
"hyper-util", "hyper-util",
"libc", "libc",
"log", "log",
@ -1980,7 +1978,7 @@ dependencies = [
"h2 0.4.4", "h2 0.4.4",
"http 1.1.0", "http 1.1.0",
"http-body-util", "http-body-util",
"hyper 1.3.1", "hyper 1.1.0",
"hyper-util", "hyper-util",
"once_cell", "once_cell",
"rustls-tokio-stream", "rustls-tokio-stream",
@ -2009,9 +2007,9 @@ dependencies = [
[[package]] [[package]]
name = "denokv_proto" name = "denokv_proto"
version = "0.8.1" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "114538d2cacd2b219f05faa753d80950f95416e47c77904c7452d5f41e157059" checksum = "bd644ad038e7b6e8453463e96c278ba378e8bdc9f557959d511ac830ea0ec969"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -2019,15 +2017,16 @@ dependencies = [
"futures", "futures",
"num-bigint", "num-bigint",
"prost", "prost",
"prost-build",
"serde", "serde",
"uuid", "uuid",
] ]
[[package]] [[package]]
name = "denokv_remote" name = "denokv_remote"
version = "0.8.1" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d57717b5123e8d1ec5f52973a67f98e3621274d362d18b245038967b402082df" checksum = "23cfa4786f9c609711aab89ce173232ceda0617167881e58fd5e0b78868a6932"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@ -2036,10 +2035,10 @@ dependencies = [
"chrono", "chrono",
"denokv_proto", "denokv_proto",
"futures", "futures",
"http 1.1.0",
"log", "log",
"prost", "prost",
"rand", "rand",
"reqwest",
"serde", "serde",
"serde_json", "serde_json",
"tokio", "tokio",
@ -2050,9 +2049,9 @@ dependencies = [
[[package]] [[package]]
name = "denokv_sqlite" name = "denokv_sqlite"
version = "0.8.1" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "188b792af19082cbfc7b666e71979775300482877d8b80601f4a5a86a80098a3" checksum = "f36c1c54cda2de93d0f4ded0392d0b6917bcd9b1d13c056dd7c309668aa43e17"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@ -2621,7 +2620,7 @@ checksum = "f63dd7b57f9b33b1741fa631c9522eb35d43e96dcca4a6a91d5e4ca7c93acdc1"
dependencies = [ dependencies = [
"base64 0.21.7", "base64 0.21.7",
"http-body-util", "http-body-util",
"hyper 1.3.1", "hyper 1.1.0",
"hyper-util", "hyper-util",
"pin-project", "pin-project",
"rand", "rand",
@ -3371,9 +3370,9 @@ dependencies = [
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "1.3.1" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
@ -3385,45 +3384,39 @@ dependencies = [
"httpdate", "httpdate",
"itoa", "itoa",
"pin-project-lite", "pin-project-lite",
"smallvec",
"tokio", "tokio",
"want", "want",
] ]
[[package]] [[package]]
name = "hyper-rustls" name = "hyper-rustls"
version = "0.26.0" version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
dependencies = [ dependencies = [
"futures-util", "futures-util",
"http 1.1.0", "http 0.2.12",
"hyper 1.3.1", "hyper 0.14.28",
"hyper-util",
"rustls", "rustls",
"rustls-pki-types",
"tokio", "tokio",
"tokio-rustls", "tokio-rustls",
"tower-service",
] ]
[[package]] [[package]]
name = "hyper-util" name = "hyper-util"
version = "0.1.5" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" checksum = "bdea9aac0dbe5a9240d68cfd9501e2db94222c6dc06843e06640b9e07f0fdc67"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
"futures-util", "futures-util",
"http 1.1.0", "http 1.1.0",
"http-body 1.0.0", "http-body 1.0.0",
"hyper 1.3.1", "hyper 1.1.0",
"pin-project-lite", "pin-project-lite",
"socket2", "socket2",
"tokio", "tokio",
"tower",
"tower-service",
"tracing", "tracing",
] ]
@ -3562,7 +3555,7 @@ dependencies = [
"socket2", "socket2",
"widestring", "widestring",
"windows-sys 0.48.0", "windows-sys 0.48.0",
"winreg 0.50.0", "winreg",
] ]
[[package]] [[package]]
@ -5247,22 +5240,21 @@ checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc"
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.12.4" version = "0.11.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
dependencies = [ dependencies = [
"async-compression", "async-compression",
"base64 0.22.1", "base64 0.21.7",
"bytes", "bytes",
"encoding_rs",
"futures-core", "futures-core",
"futures-util", "futures-util",
"h2 0.4.4", "h2 0.3.26",
"http 1.1.0", "http 0.2.12",
"http-body 1.0.0", "http-body 0.4.6",
"http-body-util", "hyper 0.14.28",
"hyper 1.3.1",
"hyper-rustls", "hyper-rustls",
"hyper-util",
"ipnet", "ipnet",
"js-sys", "js-sys",
"log", "log",
@ -5272,11 +5264,9 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
"rustls", "rustls",
"rustls-pemfile", "rustls-pemfile",
"rustls-pki-types",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"sync_wrapper",
"tokio", "tokio",
"tokio-rustls", "tokio-rustls",
"tokio-socks", "tokio-socks",
@ -5288,7 +5278,7 @@ dependencies = [
"wasm-streams", "wasm-streams",
"web-sys", "web-sys",
"webpki-roots", "webpki-roots",
"winreg 0.52.0", "winreg",
] ]
[[package]] [[package]]
@ -5458,52 +5448,42 @@ dependencies = [
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.22.4" version = "0.21.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4"
dependencies = [ dependencies = [
"log", "log",
"ring", "ring",
"rustls-pki-types",
"rustls-webpki", "rustls-webpki",
"subtle", "sct",
"zeroize",
] ]
[[package]] [[package]]
name = "rustls-native-certs" name = "rustls-native-certs"
version = "0.7.0" version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
dependencies = [ dependencies = [
"openssl-probe", "openssl-probe",
"rustls-pemfile", "rustls-pemfile",
"rustls-pki-types",
"schannel", "schannel",
"security-framework", "security-framework",
] ]
[[package]] [[package]]
name = "rustls-pemfile" name = "rustls-pemfile"
version = "2.1.2" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.21.7",
"rustls-pki-types",
] ]
[[package]]
name = "rustls-pki-types"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
[[package]] [[package]]
name = "rustls-tokio-stream" name = "rustls-tokio-stream"
version = "0.2.23" version = "0.2.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c478c030dfd68498e6c59168d9eec4f8bead33152a5f3095ad4bdbdcea09d466" checksum = "fd707225bb670bcd2876886bb571753d1ce03a9cedfa2e629a79984ca9a93cfb"
dependencies = [ dependencies = [
"futures", "futures",
"rustls", "rustls",
@ -5513,12 +5493,11 @@ dependencies = [
[[package]] [[package]]
name = "rustls-webpki" name = "rustls-webpki"
version = "0.102.4" version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [ dependencies = [
"ring", "ring",
"rustls-pki-types",
"untrusted", "untrusted",
] ]
@ -5634,6 +5613,16 @@ dependencies = [
"sha2", "sha2",
] ]
[[package]]
name = "sct"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring",
"untrusted",
]
[[package]] [[package]]
name = "sec1" name = "sec1"
version = "0.7.3" version = "0.7.3"
@ -6577,12 +6566,6 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]] [[package]]
name = "synstructure" name = "synstructure"
version = "0.12.6" version = "0.12.6"
@ -6699,7 +6682,7 @@ dependencies = [
"h2 0.4.4", "h2 0.4.4",
"http 1.1.0", "http 1.1.0",
"http-body-util", "http-body-util",
"hyper 1.3.1", "hyper 1.1.0",
"hyper-util", "hyper-util",
"jsonc-parser", "jsonc-parser",
"lazy-regex", "lazy-regex",
@ -6865,12 +6848,11 @@ dependencies = [
[[package]] [[package]]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.25.0" version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [ dependencies = [
"rustls", "rustls",
"rustls-pki-types",
"tokio", "tokio",
] ]
@ -6907,10 +6889,7 @@ dependencies = [
"futures-core", "futures-core",
"futures-io", "futures-io",
"futures-sink", "futures-sink",
"futures-util",
"hashbrown",
"pin-project-lite", "pin-project-lite",
"slab",
"tokio", "tokio",
"tracing", "tracing",
] ]
@ -6968,7 +6947,6 @@ dependencies = [
"futures-util", "futures-util",
"pin-project", "pin-project",
"pin-project-lite", "pin-project-lite",
"tokio",
"tower-layer", "tower-layer",
"tower-service", "tower-service",
] ]
@ -7542,9 +7520,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]] [[package]]
name = "wasm-streams" name = "wasm-streams"
version = "0.4.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7"
dependencies = [ dependencies = [
"futures-util", "futures-util",
"js-sys", "js-sys",
@ -7565,12 +7543,9 @@ dependencies = [
[[package]] [[package]]
name = "webpki-roots" name = "webpki-roots"
version = "0.26.1" version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
dependencies = [
"rustls-pki-types",
]
[[package]] [[package]]
name = "wgpu-core" name = "wgpu-core"
@ -7907,16 +7882,6 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "winreg"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "winres" name = "winres"
version = "0.1.12" version = "0.1.12"

View file

@ -55,10 +55,10 @@ deno_terminal = "0.1.1"
napi_sym = { version = "0.87.0", path = "./cli/napi/sym" } napi_sym = { version = "0.87.0", path = "./cli/napi/sym" }
test_util = { package = "test_server", path = "./tests/util/server" } test_util = { package = "test_server", path = "./tests/util/server" }
denokv_proto = "0.8.1" denokv_proto = "0.7.0"
denokv_remote = "0.8.1" denokv_remote = "0.7.0"
# denokv_sqlite brings in bundled sqlite if we don't disable the default features # denokv_sqlite brings in bundled sqlite if we don't disable the default features
denokv_sqlite = { default-features = false, version = "0.8.1" } denokv_sqlite = { default-features = false, version = "0.7.0" }
# exts # exts
deno_broadcast_channel = { version = "0.151.0", path = "./ext/broadcast_channel" } deno_broadcast_channel = { version = "0.151.0", path = "./ext/broadcast_channel" }
@ -117,8 +117,8 @@ http = "1.0"
http-body-util = "0.1" http-body-util = "0.1"
http_v02 = { package = "http", version = "0.2.9" } http_v02 = { package = "http", version = "0.2.9" }
httparse = "1.8.0" httparse = "1.8.0"
hyper = { version = "=1.3.1", features = ["full"] } hyper = { version = "=1.1.0", features = ["full"] }
hyper-util = { version = "=0.1.5", features = ["tokio", "server", "server-auto"] } hyper-util = { version = "=0.1.2", features = ["tokio", "server", "server-auto"] }
hyper_v014 = { package = "hyper", version = "0.14.26", features = ["runtime", "http1"] } hyper_v014 = { package = "hyper", version = "0.14.26", features = ["runtime", "http1"] }
indexmap = { version = "2", features = ["serde"] } indexmap = { version = "2", features = ["serde"] }
jsonc-parser = { version = "=0.23.0", features = ["serde"] } jsonc-parser = { version = "=0.23.0", features = ["serde"] }
@ -145,13 +145,14 @@ prost = "0.11"
prost-build = "0.11" prost-build = "0.11"
rand = "=0.8.5" rand = "=0.8.5"
regex = "^1.7.0" regex = "^1.7.0"
reqwest = { version = "=0.12.4", default-features = false, features = ["rustls-tls", "stream", "gzip", "brotli", "socks", "json", "http2"] } # pinned because of https://github.com/seanmonstar/reqwest/pull/1955 reqwest = { version = "=0.11.20", default-features = false, features = ["rustls-tls", "stream", "gzip", "brotli", "socks", "json"] } # pinned because of https://github.com/seanmonstar/reqwest/pull/1955
ring = "^0.17.0" ring = "^0.17.0"
rusqlite = { version = "=0.29.0", features = ["unlock_notify", "bundled"] } rusqlite = { version = "=0.29.0", features = ["unlock_notify", "bundled"] }
rustls = "0.22.4" # pinned because it was causing issues on cargo publish
rustls-pemfile = "2" rustls = "=0.21.11"
rustls-tokio-stream = "=0.2.23" rustls-pemfile = "1.0.0"
rustls-webpki = "0.102" rustls-tokio-stream = "=0.2.24"
rustls-webpki = "0.101.4"
rustyline = "=13.0.0" rustyline = "=13.0.0"
saffron = "=0.1.0" saffron = "=0.1.0"
scopeguard = "1.2.0" scopeguard = "1.2.0"
@ -177,7 +178,7 @@ twox-hash = "=1.6.3"
# Upgrading past 2.4.1 may cause WPT failures # Upgrading past 2.4.1 may cause WPT failures
url = { version = "< 2.5.0", features = ["serde", "expose_internals"] } url = { version = "< 2.5.0", features = ["serde", "expose_internals"] }
uuid = { version = "1.3.0", features = ["v4"] } uuid = { version = "1.3.0", features = ["v4"] }
webpki-roots = "0.26" webpki-roots = "0.25.2"
zeromq = { version = "=0.3.4", default-features = false, features = ["tcp-transport", "tokio-runtime"] } zeromq = { version = "=0.3.4", default-features = false, features = ["tcp-transport", "tokio-runtime"] }
zstd = "=0.12.4" zstd = "=0.12.4"

View file

@ -696,13 +696,21 @@ pub fn get_root_cert_store(
for store in ca_stores.iter() { for store in ca_stores.iter() {
match store.as_str() { match store.as_str() {
"mozilla" => { "mozilla" => {
root_cert_store.extend(webpki_roots::TLS_SERVER_ROOTS.to_vec()); root_cert_store.add_trust_anchors(
webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| {
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
)
}),
);
} }
"system" => { "system" => {
let roots = load_native_certs().expect("could not load platform certs"); let roots = load_native_certs().expect("could not load platform certs");
for root in roots { for root in roots {
root_cert_store root_cert_store
.add(rustls::pki_types::CertificateDer::from(root.0)) .add(&rustls::Certificate(root.0))
.expect("Failed to add platform cert to root cert store"); .expect("Failed to add platform cert to root cert store");
} }
} }
@ -726,17 +734,17 @@ pub fn get_root_cert_store(
RootCertStoreLoadError::CaFileOpenError(err.to_string()) RootCertStoreLoadError::CaFileOpenError(err.to_string())
})?; })?;
let mut reader = BufReader::new(certfile); let mut reader = BufReader::new(certfile);
rustls_pemfile::certs(&mut reader).collect::<Result<Vec<_>, _>>() rustls_pemfile::certs(&mut reader)
} }
CaData::Bytes(data) => { CaData::Bytes(data) => {
let mut reader = BufReader::new(Cursor::new(data)); let mut reader = BufReader::new(Cursor::new(data));
rustls_pemfile::certs(&mut reader).collect::<Result<Vec<_>, _>>() rustls_pemfile::certs(&mut reader)
} }
}; };
match result { match result {
Ok(certs) => { Ok(certs) => {
root_cert_store.add_parsable_certificates(certs); root_cert_store.add_parsable_certificates(&certs);
} }
Err(e) => { Err(e) => {
return Err(RootCertStoreLoadError::FailedAddPemFile(e.to_string())); return Err(RootCertStoreLoadError::FailedAddPemFile(e.to_string()));

View file

@ -587,7 +587,7 @@ mod test {
use std::collections::HashSet; use std::collections::HashSet;
use std::hash::RandomState; use std::hash::RandomState;
use deno_runtime::deno_tls::rustls::RootCertStore; use deno_runtime::deno_tls::RootCertStore;
use crate::version; use crate::version;

View file

@ -20,7 +20,7 @@ deno_core.workspace = true
deno_permissions.workspace = true deno_permissions.workspace = true
deno_tls.workspace = true deno_tls.workspace = true
dyn-clone = "1" dyn-clone = "1"
http.workspace = true http_v02.workspace = true
reqwest.workspace = true reqwest.workspace = true
serde.workspace = true serde.workspace = true
serde_json.workspace = true serde_json.workspace = true

View file

@ -31,7 +31,7 @@ impl FetchHandler for FsFetchHandler {
let file = tokio::fs::File::open(path).map_err(|_| ()).await?; let file = tokio::fs::File::open(path).map_err(|_| ()).await?;
let stream = ReaderStream::new(file); let stream = ReaderStream::new(file);
let body = reqwest::Body::wrap_stream(stream); let body = reqwest::Body::wrap_stream(stream);
let response = http::Response::builder() let response = http_v02::Response::builder()
.status(StatusCode::OK) .status(StatusCode::OK)
.body(body) .body(body)
.map_err(|_| ())? .map_err(|_| ())?

View file

@ -47,8 +47,8 @@ use data_url::DataUrl;
use deno_tls::TlsKey; use deno_tls::TlsKey;
use deno_tls::TlsKeys; use deno_tls::TlsKeys;
use deno_tls::TlsKeysHolder; use deno_tls::TlsKeysHolder;
use http::header::CONTENT_LENGTH; use http_v02::header::CONTENT_LENGTH;
use http::Uri; use http_v02::Uri;
use reqwest::header::HeaderMap; use reqwest::header::HeaderMap;
use reqwest::header::HeaderName; use reqwest::header::HeaderName;
use reqwest::header::HeaderValue; use reqwest::header::HeaderValue;
@ -449,9 +449,12 @@ where
.decode_to_vec() .decode_to_vec()
.map_err(|e| type_error(format!("{e:?}")))?; .map_err(|e| type_error(format!("{e:?}")))?;
let response = http::Response::builder() let response = http_v02::Response::builder()
.status(http::StatusCode::OK) .status(http_v02::StatusCode::OK)
.header(http::header::CONTENT_TYPE, data_url.mime_type().to_string()) .header(
http_v02::header::CONTENT_TYPE,
data_url.mime_type().to_string(),
)
.body(reqwest::Body::from(body))?; .body(reqwest::Body::from(body))?;
let fut = async move { Ok(Ok(Response::from(response))) }; let fut = async move { Ok(Ok(Response::from(response))) };

View file

@ -17,7 +17,6 @@ path = "lib.rs"
anyhow.workspace = true anyhow.workspace = true
async-trait.workspace = true async-trait.workspace = true
base64.workspace = true base64.workspace = true
bytes.workspace = true
chrono = { workspace = true, features = ["now"] } chrono = { workspace = true, features = ["now"] }
deno_core.workspace = true deno_core.workspace = true
deno_fetch.workspace = true deno_fetch.workspace = true
@ -28,7 +27,6 @@ denokv_proto.workspace = true
denokv_remote.workspace = true denokv_remote.workspace = true
denokv_sqlite.workspace = true denokv_sqlite.workspace = true
faster-hex.workspace = true faster-hex.workspace = true
http.workspace = true
log.workspace = true log.workspace = true
num-bigint.workspace = true num-bigint.workspace = true
prost.workspace = true prost.workspace = true

View file

@ -8,14 +8,10 @@ use std::sync::Arc;
use crate::DatabaseHandler; use crate::DatabaseHandler;
use anyhow::Context; use anyhow::Context;
use async_trait::async_trait; use async_trait::async_trait;
use bytes::Bytes;
use deno_core::error::type_error; use deno_core::error::type_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::futures::Stream;
use deno_core::futures::TryStreamExt as _;
use deno_core::OpState; use deno_core::OpState;
use deno_fetch::create_http_client; use deno_fetch::create_http_client;
use deno_fetch::reqwest;
use deno_fetch::CreateHttpClientOptions; use deno_fetch::CreateHttpClientOptions;
use deno_tls::rustls::RootCertStore; use deno_tls::rustls::RootCertStore;
use deno_tls::Proxy; use deno_tls::Proxy;
@ -23,8 +19,6 @@ use deno_tls::RootCertStoreProvider;
use deno_tls::TlsKeys; use deno_tls::TlsKeys;
use denokv_remote::MetadataEndpoint; use denokv_remote::MetadataEndpoint;
use denokv_remote::Remote; use denokv_remote::Remote;
use denokv_remote::RemoteResponse;
use denokv_remote::RemoteTransport;
use url::Url; use url::Url;
#[derive(Clone)] #[derive(Clone)]
@ -108,44 +102,11 @@ impl<P: RemoteDbHandlerPermissions + 'static> denokv_remote::RemotePermissions
} }
} }
#[derive(Clone)]
pub struct ReqwestClient(reqwest::Client);
pub struct ReqwestResponse(reqwest::Response);
impl RemoteTransport for ReqwestClient {
type Response = ReqwestResponse;
async fn post(
&self,
url: Url,
headers: http::HeaderMap,
body: Bytes,
) -> Result<(Url, http::StatusCode, Self::Response), anyhow::Error> {
let res = self.0.post(url).headers(headers).body(body).send().await?;
let url = res.url().clone();
let status = res.status();
Ok((url, status, ReqwestResponse(res)))
}
}
impl RemoteResponse for ReqwestResponse {
async fn bytes(self) -> Result<Bytes, anyhow::Error> {
Ok(self.0.bytes().await?)
}
fn stream(
self,
) -> impl Stream<Item = Result<Bytes, anyhow::Error>> + Send + Sync {
self.0.bytes_stream().map_err(|e| e.into())
}
async fn text(self) -> Result<String, anyhow::Error> {
Ok(self.0.text().await?)
}
}
#[async_trait(?Send)] #[async_trait(?Send)]
impl<P: RemoteDbHandlerPermissions + 'static> DatabaseHandler impl<P: RemoteDbHandlerPermissions + 'static> DatabaseHandler
for RemoteDbHandler<P> for RemoteDbHandler<P>
{ {
type DB = Remote<PermissionChecker<P>, ReqwestClient>; type DB = Remote<PermissionChecker<P>>;
async fn open( async fn open(
&self, &self,
@ -201,14 +162,13 @@ impl<P: RemoteDbHandlerPermissions + 'static> DatabaseHandler
http2: true, http2: true,
}, },
)?; )?;
let reqwest_client = ReqwestClient(client);
let permissions = PermissionChecker { let permissions = PermissionChecker {
state: state.clone(), state: state.clone(),
_permissions: PhantomData, _permissions: PhantomData,
}; };
let remote = Remote::new(reqwest_client, permissions, metadata_endpoint); let remote = Remote::new(client, permissions, metadata_endpoint);
Ok(remote) Ok(remote)
} }

View file

@ -31,11 +31,11 @@ use deno_tls::create_client_config;
use deno_tls::load_certs; use deno_tls::load_certs;
use deno_tls::load_private_keys; use deno_tls::load_private_keys;
use deno_tls::new_resolver; use deno_tls::new_resolver;
use deno_tls::rustls::pki_types::ServerName; use deno_tls::rustls::Certificate;
use deno_tls::rustls::ClientConnection; use deno_tls::rustls::ClientConnection;
use deno_tls::rustls::PrivateKey;
use deno_tls::rustls::ServerConfig; use deno_tls::rustls::ServerConfig;
use deno_tls::webpki::types::CertificateDer; use deno_tls::rustls::ServerName;
use deno_tls::webpki::types::PrivateKeyDer;
use deno_tls::ServerConfigProvider; use deno_tls::ServerConfigProvider;
use deno_tls::SocketUse; use deno_tls::SocketUse;
use deno_tls::TlsKey; use deno_tls::TlsKey;
@ -48,6 +48,7 @@ use serde::Deserialize;
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::RefCell; use std::cell::RefCell;
use std::convert::From; use std::convert::From;
use std::convert::TryFrom;
use std::fs::File; use std::fs::File;
use std::io::BufReader; use std::io::BufReader;
use std::io::ErrorKind; use std::io::ErrorKind;
@ -303,14 +304,14 @@ where
{ {
let rid = args.rid; let rid = args.rid;
let hostname = match &*args.hostname { let hostname = match &*args.hostname {
"" => "localhost".to_string(), "" => "localhost",
n => n.to_string(), n => n,
}; };
{ {
let mut s = state.borrow_mut(); let mut s = state.borrow_mut();
let permissions = s.borrow_mut::<NP>(); let permissions = s.borrow_mut::<NP>();
permissions.check_net(&(&hostname, Some(0)), "Deno.startTls()")?; permissions.check_net(&(hostname, Some(0)), "Deno.startTls()")?;
} }
let ca_certs = args let ca_certs = args
@ -319,8 +320,8 @@ where
.map(|s| s.into_bytes()) .map(|s| s.into_bytes())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let hostname_dns = ServerName::try_from(hostname.to_string()) let hostname_dns =
.map_err(|_| invalid_hostname(&hostname))?; ServerName::try_from(hostname).map_err(|_| invalid_hostname(hostname))?;
let unsafely_ignore_certificate_errors = state let unsafely_ignore_certificate_errors = state
.borrow() .borrow()
@ -421,9 +422,9 @@ where
.borrow::<DefaultTlsOptions>() .borrow::<DefaultTlsOptions>()
.root_cert_store()?; .root_cert_store()?;
let hostname_dns = if let Some(server_name) = args.server_name { let hostname_dns = if let Some(server_name) = args.server_name {
ServerName::try_from(server_name) ServerName::try_from(server_name.as_str())
} else { } else {
ServerName::try_from(addr.hostname.clone()) ServerName::try_from(&*addr.hostname)
} }
.map_err(|_| invalid_hostname(&addr.hostname))?; .map_err(|_| invalid_hostname(&addr.hostname))?;
let connect_addr = resolve_addr(&addr.hostname, addr.port) let connect_addr = resolve_addr(&addr.hostname, addr.port)
@ -465,9 +466,7 @@ where
Ok((rid, IpAddr::from(local_addr), IpAddr::from(remote_addr))) Ok((rid, IpAddr::from(local_addr), IpAddr::from(remote_addr)))
} }
fn load_certs_from_file( fn load_certs_from_file(path: &str) -> Result<Vec<Certificate>, AnyError> {
path: &str,
) -> Result<Vec<CertificateDer<'static>>, AnyError> {
let cert_file = File::open(path)?; let cert_file = File::open(path)?;
let reader = &mut BufReader::new(cert_file); let reader = &mut BufReader::new(cert_file);
load_certs(reader) load_certs(reader)
@ -475,7 +474,7 @@ fn load_certs_from_file(
fn load_private_keys_from_file( fn load_private_keys_from_file(
path: &str, path: &str,
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> { ) -> Result<Vec<PrivateKey>, AnyError> {
let key_bytes = std::fs::read(path)?; let key_bytes = std::fs::read(path)?;
load_private_keys(&key_bytes) load_private_keys(&key_bytes)
} }
@ -524,6 +523,7 @@ where
TlsKeys::Null => Err(anyhow!("Deno.listenTls requires a key")), TlsKeys::Null => Err(anyhow!("Deno.listenTls requires a key")),
TlsKeys::Static(TlsKey(cert, key)) => { TlsKeys::Static(TlsKey(cert, key)) => {
let mut tls_config = ServerConfig::builder() let mut tls_config = ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth() .with_no_client_auth()
.with_single_cert(cert, key) .with_single_cert(cert, key)
.map_err(|e| anyhow!(e))?; .map_err(|e| anyhow!(e))?;

View file

@ -35,10 +35,10 @@ ecb.workspace = true
elliptic-curve.workspace = true elliptic-curve.workspace = true
errno = "0.2.8" errno = "0.2.8"
faster-hex.workspace = true faster-hex.workspace = true
h2.workspace = true h2 = { version = "0.3.26", features = ["unstable"] }
hkdf.workspace = true hkdf.workspace = true
home = "0.5.9" home = "0.5.9"
http.workspace = true http_v02.workspace = true
idna = "0.3.0" idna = "0.3.0"
indexmap.workspace = true indexmap.workspace = true
ipnetwork = "0.20.0" ipnetwork = "0.20.0"

View file

@ -26,11 +26,11 @@ use deno_net::raw::NetworkStream;
use h2; use h2;
use h2::Reason; use h2::Reason;
use h2::RecvStream; use h2::RecvStream;
use http; use http_v02;
use http::request::Parts; use http_v02::request::Parts;
use http::HeaderMap; use http_v02::HeaderMap;
use http::Response; use http_v02::Response;
use http::StatusCode; use http_v02::StatusCode;
use reqwest::header::HeaderName; use reqwest::header::HeaderName;
use reqwest::header::HeaderValue; use reqwest::header::HeaderValue;
use url::Url; use url::Url;
@ -311,7 +311,7 @@ pub async fn op_http2_client_request(
let url = url.join(&pseudo_path)?; let url = url.join(&pseudo_path)?;
let mut req = http::Request::builder() let mut req = http_v02::Request::builder()
.uri(url.as_str()) .uri(url.as_str())
.method(pseudo_method.as_str()); .method(pseudo_method.as_str());
@ -383,7 +383,7 @@ pub async fn op_http2_client_send_trailers(
.get::<Http2ClientStream>(stream_rid)?; .get::<Http2ClientStream>(stream_rid)?;
let mut stream = RcRef::map(&resource, |r| &r.stream).borrow_mut().await; let mut stream = RcRef::map(&resource, |r| &r.stream).borrow_mut().await;
let mut trailers_map = http::HeaderMap::new(); let mut trailers_map = http_v02::HeaderMap::new();
for (name, value) in trailers { for (name, value) in trailers {
trailers_map.insert( trailers_map.insert(
HeaderName::from_bytes(&name).unwrap(), HeaderName::from_bytes(&name).unwrap(),

View file

@ -15,8 +15,8 @@ path = "lib.rs"
[dependencies] [dependencies]
deno_core.workspace = true deno_core.workspace = true
deno_native_certs = "0.3.0" deno_native_certs = "0.2.0"
rustls.workspace = true rustls = { workspace = true, features = ["dangerous_configuration"] }
rustls-pemfile.workspace = true rustls-pemfile.workspace = true
rustls-tokio-stream.workspace = true rustls-tokio-stream.workspace = true
rustls-webpki.workspace = true rustls-webpki.workspace = true

View file

@ -1,9 +1,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
pub use deno_native_certs; pub use deno_native_certs;
pub use rustls; pub use rustls;
use rustls::pki_types::CertificateDer;
use rustls::pki_types::PrivateKeyDer;
use rustls::pki_types::ServerName;
pub use rustls_pemfile; pub use rustls_pemfile;
pub use rustls_tokio_stream::*; pub use rustls_tokio_stream::*;
pub use webpki; pub use webpki;
@ -13,14 +11,14 @@ use deno_core::anyhow::anyhow;
use deno_core::error::custom_error; use deno_core::error::custom_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use rustls::client::danger::HandshakeSignatureValid; use rustls::client::HandshakeSignatureValid;
use rustls::client::danger::ServerCertVerified; use rustls::client::ServerCertVerified;
use rustls::client::danger::ServerCertVerifier; use rustls::client::ServerCertVerifier;
use rustls::client::WebPkiServerVerifier; use rustls::client::WebPkiVerifier;
use rustls::ClientConfig; use rustls::ClientConfig;
use rustls::DigitallySignedStruct; use rustls::DigitallySignedStruct;
use rustls::Error; use rustls::Error;
use rustls::RootCertStore; use rustls::ServerName;
use rustls_pemfile::certs; use rustls_pemfile::certs;
use rustls_pemfile::ec_private_keys; use rustls_pemfile::ec_private_keys;
use rustls_pemfile::pkcs8_private_keys; use rustls_pemfile::pkcs8_private_keys;
@ -29,12 +27,16 @@ use serde::Deserialize;
use std::io::BufRead; use std::io::BufRead;
use std::io::BufReader; use std::io::BufReader;
use std::io::Cursor; use std::io::Cursor;
use std::net::IpAddr;
use std::sync::Arc; use std::sync::Arc;
use std::time::SystemTime;
mod tls_key; mod tls_key;
pub use tls_key::*; pub use tls_key::*;
pub type Certificate = rustls::Certificate;
pub type PrivateKey = rustls::PrivateKey;
pub type RootCertStore = rustls::RootCertStore;
/// Lazily resolves the root cert store. /// Lazily resolves the root cert store.
/// ///
/// This was done because the root cert store is not needed in all cases /// This was done because the root cert store is not needed in all cases
@ -46,59 +48,56 @@ pub trait RootCertStoreProvider: Send + Sync {
// This extension has no runtime apis, it only exports some shared native functions. // This extension has no runtime apis, it only exports some shared native functions.
deno_core::extension!(deno_tls); deno_core::extension!(deno_tls);
#[derive(Debug)] struct DefaultSignatureVerification;
pub struct NoCertificateVerification {
pub ic_allowlist: Vec<String>,
default_verifier: Arc<WebPkiServerVerifier>,
}
impl NoCertificateVerification {
pub fn new(ic_allowlist: Vec<String>) -> Self {
Self {
ic_allowlist,
default_verifier: WebPkiServerVerifier::builder(
create_default_root_cert_store().into(),
)
.build()
.unwrap(),
}
}
}
impl ServerCertVerifier for NoCertificateVerification {
fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
self.default_verifier.supported_verify_schemes()
}
impl ServerCertVerifier for DefaultSignatureVerification {
fn verify_server_cert( fn verify_server_cert(
&self, &self,
end_entity: &rustls::pki_types::CertificateDer<'_>, _end_entity: &Certificate,
intermediates: &[rustls::pki_types::CertificateDer<'_>], _intermediates: &[Certificate],
server_name: &rustls::pki_types::ServerName<'_>, _server_name: &ServerName,
ocsp_response: &[u8], _scts: &mut dyn Iterator<Item = &[u8]>,
now: rustls::pki_types::UnixTime, _ocsp_response: &[u8],
_now: SystemTime,
) -> Result<ServerCertVerified, Error> { ) -> Result<ServerCertVerified, Error> {
if self.ic_allowlist.is_empty() { Err(Error::General("Should not be used".to_string()))
}
}
pub struct NoCertificateVerification(pub Vec<String>);
impl ServerCertVerifier for NoCertificateVerification {
fn verify_server_cert(
&self,
end_entity: &Certificate,
intermediates: &[Certificate],
server_name: &ServerName,
scts: &mut dyn Iterator<Item = &[u8]>,
ocsp_response: &[u8],
now: SystemTime,
) -> Result<ServerCertVerified, Error> {
if self.0.is_empty() {
return Ok(ServerCertVerified::assertion()); return Ok(ServerCertVerified::assertion());
} }
let dns_name_or_ip_address = match server_name { let dns_name_or_ip_address = match server_name {
ServerName::DnsName(dns_name) => dns_name.as_ref().to_owned(), ServerName::DnsName(dns_name) => dns_name.as_ref().to_owned(),
ServerName::IpAddress(ip_address) => { ServerName::IpAddress(ip_address) => ip_address.to_string(),
Into::<IpAddr>::into(*ip_address).to_string()
}
_ => { _ => {
// NOTE(bartlomieju): `ServerName` is a non-exhaustive enum // NOTE(bartlomieju): `ServerName` is a non-exhaustive enum
// so we have this catch all errors here. // so we have this catch all errors here.
return Err(Error::General("Unknown `ServerName` variant".to_string())); return Err(Error::General("Unknown `ServerName` variant".to_string()));
} }
}; };
if self.ic_allowlist.contains(&dns_name_or_ip_address) { if self.0.contains(&dns_name_or_ip_address) {
Ok(ServerCertVerified::assertion()) Ok(ServerCertVerified::assertion())
} else { } else {
self.default_verifier.verify_server_cert( let root_store = create_default_root_cert_store();
let verifier = WebPkiVerifier::new(root_store, None);
verifier.verify_server_cert(
end_entity, end_entity,
intermediates, intermediates,
server_name, server_name,
scts,
ocsp_response, ocsp_response,
now, now,
) )
@ -108,32 +107,28 @@ impl ServerCertVerifier for NoCertificateVerification {
fn verify_tls12_signature( fn verify_tls12_signature(
&self, &self,
message: &[u8], message: &[u8],
cert: &rustls::pki_types::CertificateDer, cert: &rustls::Certificate,
dss: &DigitallySignedStruct, dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> { ) -> Result<HandshakeSignatureValid, Error> {
if self.ic_allowlist.is_empty() { if self.0.is_empty() {
return Ok(HandshakeSignatureValid::assertion()); return Ok(HandshakeSignatureValid::assertion());
} }
filter_invalid_encoding_err( filter_invalid_encoding_err(
self DefaultSignatureVerification.verify_tls12_signature(message, cert, dss),
.default_verifier
.verify_tls12_signature(message, cert, dss),
) )
} }
fn verify_tls13_signature( fn verify_tls13_signature(
&self, &self,
message: &[u8], message: &[u8],
cert: &rustls::pki_types::CertificateDer, cert: &rustls::Certificate,
dss: &DigitallySignedStruct, dss: &DigitallySignedStruct,
) -> Result<HandshakeSignatureValid, Error> { ) -> Result<HandshakeSignatureValid, Error> {
if self.ic_allowlist.is_empty() { if self.0.is_empty() {
return Ok(HandshakeSignatureValid::assertion()); return Ok(HandshakeSignatureValid::assertion());
} }
filter_invalid_encoding_err( filter_invalid_encoding_err(
self DefaultSignatureVerification.verify_tls13_signature(message, cert, dss),
.default_verifier
.verify_tls13_signature(message, cert, dss),
) )
} }
} }
@ -154,10 +149,17 @@ pub struct BasicAuth {
} }
pub fn create_default_root_cert_store() -> RootCertStore { pub fn create_default_root_cert_store() -> RootCertStore {
let root_cert_store = rustls::RootCertStore { let mut root_cert_store = RootCertStore::empty();
roots: webpki_roots::TLS_SERVER_ROOTS.to_vec(), // TODO(@justinmchase): Consider also loading the system keychain here
}; root_cert_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(
debug_assert!(!root_cert_store.is_empty()); |ta| {
rustls::OwnedTrustAnchor::from_subject_spki_name_constraints(
ta.subject,
ta.spki,
ta.name_constraints,
)
},
));
root_cert_store root_cert_store
} }
@ -181,10 +183,10 @@ pub fn create_client_config(
) -> Result<ClientConfig, AnyError> { ) -> Result<ClientConfig, AnyError> {
if let Some(ic_allowlist) = unsafely_ignore_certificate_errors { if let Some(ic_allowlist) = unsafely_ignore_certificate_errors {
let client_config = ClientConfig::builder() let client_config = ClientConfig::builder()
.dangerous() .with_safe_defaults()
.with_custom_certificate_verifier(Arc::new( .with_custom_certificate_verifier(Arc::new(NoCertificateVerification(
NoCertificateVerification::new(ic_allowlist), ic_allowlist,
)); )));
// NOTE(bartlomieju): this if/else is duplicated at the end of the body of this function. // NOTE(bartlomieju): this if/else is duplicated at the end of the body of this function.
// However it's not really feasible to deduplicate it as the `client_config` instances // However it's not really feasible to deduplicate it as the `client_config` instances
@ -192,7 +194,7 @@ pub fn create_client_config(
// or client cert". // or client cert".
let mut client = match maybe_cert_chain_and_key { let mut client = match maybe_cert_chain_and_key {
TlsKeys::Static(TlsKey(cert_chain, private_key)) => client_config TlsKeys::Static(TlsKey(cert_chain, private_key)) => client_config
.with_client_auth_cert(cert_chain, private_key.clone_key()) .with_client_auth_cert(cert_chain, private_key)
.expect("invalid client key or certificate"), .expect("invalid client key or certificate"),
TlsKeys::Null => client_config.with_no_client_auth(), TlsKeys::Null => client_config.with_no_client_auth(),
TlsKeys::Resolver(_) => unimplemented!(), TlsKeys::Resolver(_) => unimplemented!(),
@ -202,16 +204,18 @@ pub fn create_client_config(
return Ok(client); return Ok(client);
} }
let client_config = ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates({
let mut root_cert_store = let mut root_cert_store =
root_cert_store.unwrap_or_else(create_default_root_cert_store); root_cert_store.unwrap_or_else(create_default_root_cert_store);
// If custom certs are specified, add them to the store // If custom certs are specified, add them to the store
for cert in ca_certs { for cert in ca_certs {
let reader = &mut BufReader::new(Cursor::new(cert)); let reader = &mut BufReader::new(Cursor::new(cert));
// This function does not return specific errors, if it fails give a generic message. // This function does not return specific errors, if it fails give a generic message.
for r in rustls_pemfile::certs(reader) { match rustls_pemfile::certs(reader) {
match r { Ok(certs) => {
Ok(cert) => { root_cert_store.add_parsable_certificates(&certs);
root_cert_store.add(cert)?;
} }
Err(e) => { Err(e) => {
return Err(anyhow!( return Err(anyhow!(
@ -221,14 +225,12 @@ pub fn create_client_config(
} }
} }
} }
} root_cert_store
});
let client_config =
ClientConfig::builder().with_root_certificates(root_cert_store);
let mut client = match maybe_cert_chain_and_key { let mut client = match maybe_cert_chain_and_key {
TlsKeys::Static(TlsKey(cert_chain, private_key)) => client_config TlsKeys::Static(TlsKey(cert_chain, private_key)) => client_config
.with_client_auth_cert(cert_chain, private_key.clone_key()) .with_client_auth_cert(cert_chain, private_key)
.expect("invalid client key or certificate"), .expect("invalid client key or certificate"),
TlsKeys::Null => client_config.with_no_client_auth(), TlsKeys::Null => client_config.with_no_client_auth(),
TlsKeys::Resolver(_) => unimplemented!(), TlsKeys::Resolver(_) => unimplemented!(),
@ -255,17 +257,15 @@ fn add_alpn(client: &mut ClientConfig, socket_use: SocketUse) {
pub fn load_certs( pub fn load_certs(
reader: &mut dyn BufRead, reader: &mut dyn BufRead,
) -> Result<Vec<CertificateDer<'static>>, AnyError> { ) -> Result<Vec<Certificate>, AnyError> {
let certs: Result<Vec<_>, _> = certs(reader).collect(); let certs = certs(reader)
let certs = certs
.map_err(|_| custom_error("InvalidData", "Unable to decode certificate"))?; .map_err(|_| custom_error("InvalidData", "Unable to decode certificate"))?;
if certs.is_empty() { if certs.is_empty() {
return Err(cert_not_found_err()); return Err(cert_not_found_err());
} }
Ok(certs) Ok(certs.into_iter().map(rustls::Certificate).collect())
} }
fn key_decode_err() -> AnyError { fn key_decode_err() -> AnyError {
@ -281,32 +281,21 @@ fn cert_not_found_err() -> AnyError {
} }
/// Starts with -----BEGIN RSA PRIVATE KEY----- /// Starts with -----BEGIN RSA PRIVATE KEY-----
fn load_rsa_keys( fn load_rsa_keys(mut bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
mut bytes: &[u8], let keys = rsa_private_keys(&mut bytes).map_err(|_| key_decode_err())?;
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> { Ok(keys.into_iter().map(rustls::PrivateKey).collect())
let keys: Result<Vec<_>, _> = rsa_private_keys(&mut bytes).collect();
let keys = keys.map_err(|_| key_decode_err())?;
Ok(keys.into_iter().map(PrivateKeyDer::Pkcs1).collect())
} }
/// Starts with -----BEGIN EC PRIVATE KEY----- /// Starts with -----BEGIN EC PRIVATE KEY-----
fn load_ec_keys( fn load_ec_keys(mut bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
mut bytes: &[u8], let keys = ec_private_keys(&mut bytes).map_err(|_| key_decode_err())?;
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> { Ok(keys.into_iter().map(rustls::PrivateKey).collect())
let keys: Result<Vec<_>, std::io::Error> =
ec_private_keys(&mut bytes).collect();
let keys2 = keys.map_err(|_| key_decode_err())?;
Ok(keys2.into_iter().map(PrivateKeyDer::Sec1).collect())
} }
/// Starts with -----BEGIN PRIVATE KEY----- /// Starts with -----BEGIN PRIVATE KEY-----
fn load_pkcs8_keys( fn load_pkcs8_keys(mut bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
mut bytes: &[u8], let keys = pkcs8_private_keys(&mut bytes).map_err(|_| key_decode_err())?;
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> { Ok(keys.into_iter().map(rustls::PrivateKey).collect())
let keys: Result<Vec<_>, std::io::Error> =
pkcs8_private_keys(&mut bytes).collect();
let keys2 = keys.map_err(|_| key_decode_err())?;
Ok(keys2.into_iter().map(PrivateKeyDer::Pkcs8).collect())
} }
fn filter_invalid_encoding_err( fn filter_invalid_encoding_err(
@ -320,9 +309,7 @@ fn filter_invalid_encoding_err(
} }
} }
pub fn load_private_keys( pub fn load_private_keys(bytes: &[u8]) -> Result<Vec<PrivateKey>, AnyError> {
bytes: &[u8],
) -> Result<Vec<PrivateKeyDer<'static>>, AnyError> {
let mut keys = load_rsa_keys(bytes)?; let mut keys = load_rsa_keys(bytes)?;
if keys.is_empty() { if keys.is_empty() {

View file

@ -1,4 +0,0 @@
openssl req -x509 -newkey rsa:2048 -nodes -keyout example2_prikey.pem -out example2_cert.der -subj "/C=US/ST=State/L=Locality/O=Organization/CN=example2.com" -outform der
openssl pkey -in example2_prikey.pem -out example2_prikey.der -outform der

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -11,6 +11,8 @@
//! key lookup can handle closing one end of the pair, in which case they will just //! key lookup can handle closing one end of the pair, in which case they will just
//! attempt to clean up the associated resources. //! attempt to clean up the associated resources.
use crate::Certificate;
use crate::PrivateKey;
use deno_core::anyhow::anyhow; use deno_core::anyhow::anyhow;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::futures::future::poll_fn; use deno_core::futures::future::poll_fn;
@ -30,21 +32,12 @@ use std::sync::Arc;
use tokio::sync::broadcast; use tokio::sync::broadcast;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tokio::sync::oneshot; use tokio::sync::oneshot;
use webpki::types::CertificateDer;
use webpki::types::PrivateKeyDer;
type ErrorType = Rc<AnyError>; type ErrorType = Rc<AnyError>;
/// A TLS certificate/private key pair. /// A TLS certificate/private key pair.
/// see https://docs.rs/rustls-pki-types/latest/rustls_pki_types/#cloning-private-keys #[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq)] pub struct TlsKey(pub Vec<Certificate>, pub PrivateKey);
pub struct TlsKey(pub Vec<CertificateDer<'static>>, pub PrivateKeyDer<'static>);
impl Clone for TlsKey {
fn clone(&self) -> Self {
Self(self.0.clone(), self.1.clone_key())
}
}
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub enum TlsKeys { pub enum TlsKeys {
@ -116,8 +109,9 @@ impl TlsKeyResolver {
let key = self.resolve(sni).await?; let key = self.resolve(sni).await?;
let mut tls_config = ServerConfig::builder() let mut tls_config = ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth() .with_no_client_auth()
.with_single_cert(key.0, key.1.clone_key())?; .with_single_cert(key.0, key.1)?;
tls_config.alpn_protocols = alpn; tls_config.alpn_protocols = alpn;
Ok(tls_config.into()) Ok(tls_config.into())
} }
@ -257,18 +251,14 @@ impl TlsKeyLookup {
pub mod tests { pub mod tests {
use super::*; use super::*;
use deno_core::unsync::spawn; use deno_core::unsync::spawn;
use rustls::Certificate;
use rustls::PrivateKey;
fn tls_key_for_test(sni: &str) -> TlsKey { fn tls_key_for_test(sni: &str) -> TlsKey {
let manifest_dir = TlsKey(
std::path::PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); vec![Certificate(format!("{sni}-cert").into_bytes())],
let sni = sni.replace(".com", ""); PrivateKey(format!("{sni}-key").into_bytes()),
let cert_file = manifest_dir.join(format!("testdata/{}_cert.der", sni)); )
let prikey_file = manifest_dir.join(format!("testdata/{}_prikey.der", sni));
let cert = std::fs::read(cert_file).unwrap();
let prikey = std::fs::read(prikey_file).unwrap();
let cert = CertificateDer::from(cert);
let prikey = PrivateKeyDer::try_from(prikey).unwrap();
TlsKey(vec![cert], prikey)
} }
#[tokio::test] #[tokio::test]
@ -280,8 +270,8 @@ pub mod tests {
} }
}); });
let key = resolver.resolve("example1.com".to_owned()).await.unwrap(); let key = resolver.resolve("example.com".to_owned()).await.unwrap();
assert_eq!(tls_key_for_test("example1.com"), key); assert_eq!(tls_key_for_test("example.com"), key);
drop(resolver); drop(resolver);
task.await.unwrap(); task.await.unwrap();
@ -296,13 +286,13 @@ pub mod tests {
} }
}); });
let f1 = resolver.resolve("example1.com".to_owned()); let f1 = resolver.resolve("example.com".to_owned());
let f2 = resolver.resolve("example1.com".to_owned()); let f2 = resolver.resolve("example.com".to_owned());
let key = f1.await.unwrap(); let key = f1.await.unwrap();
assert_eq!(tls_key_for_test("example1.com"), key); assert_eq!(tls_key_for_test("example.com"), key);
let key = f2.await.unwrap(); let key = f2.await.unwrap();
assert_eq!(tls_key_for_test("example1.com"), key); assert_eq!(tls_key_for_test("example.com"), key);
drop(resolver); drop(resolver);
task.await.unwrap(); task.await.unwrap();

View file

@ -36,13 +36,14 @@ use http::Request;
use http::StatusCode; use http::StatusCode;
use http::Uri; use http::Uri;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use rustls_tokio_stream::rustls::pki_types::ServerName;
use rustls_tokio_stream::rustls::RootCertStore; use rustls_tokio_stream::rustls::RootCertStore;
use rustls_tokio_stream::rustls::ServerName;
use rustls_tokio_stream::TlsStream; use rustls_tokio_stream::TlsStream;
use serde::Serialize; use serde::Serialize;
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::Cell; use std::cell::Cell;
use std::cell::RefCell; use std::cell::RefCell;
use std::convert::TryFrom;
use std::fmt; use std::fmt;
use std::future::Future; use std::future::Future;
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
@ -244,8 +245,8 @@ async fn handshake_http1_wss(
) -> Result<(WebSocket<WebSocketStream>, http::HeaderMap), AnyError> { ) -> Result<(WebSocket<WebSocketStream>, http::HeaderMap), AnyError> {
let tcp_socket = TcpStream::connect(addr).await?; let tcp_socket = TcpStream::connect(addr).await?;
let tls_config = create_ws_client_config(state, SocketUse::Http1Only)?; let tls_config = create_ws_client_config(state, SocketUse::Http1Only)?;
let dnsname = ServerName::try_from(domain.to_string()) let dnsname =
.map_err(|_| invalid_hostname(domain))?; ServerName::try_from(domain).map_err(|_| invalid_hostname(domain))?;
let mut tls_connector = TlsStream::new_client_side( let mut tls_connector = TlsStream::new_client_side(
tcp_socket, tcp_socket,
ClientConnection::new(tls_config.into(), dnsname)?, ClientConnection::new(tls_config.into(), dnsname)?,
@ -269,8 +270,8 @@ async fn handshake_http2_wss(
) -> Result<(WebSocket<WebSocketStream>, http::HeaderMap), AnyError> { ) -> Result<(WebSocket<WebSocketStream>, http::HeaderMap), AnyError> {
let tcp_socket = TcpStream::connect(addr).await?; let tcp_socket = TcpStream::connect(addr).await?;
let tls_config = create_ws_client_config(state, SocketUse::Http2Only)?; let tls_config = create_ws_client_config(state, SocketUse::Http2Only)?;
let dnsname = ServerName::try_from(domain.to_string()) let dnsname =
.map_err(|_| invalid_hostname(domain))?; ServerName::try_from(domain).map_err(|_| invalid_hostname(domain))?;
// We need to better expose the underlying errors here // We need to better expose the underlying errors here
let mut tls_connector = TlsStream::new_client_side( let mut tls_connector = TlsStream::new_client_side(
tcp_socket, tcp_socket,

View file

@ -5303,19 +5303,17 @@ async fn listen_tls_alpn() {
let mut reader = &mut BufReader::new(Cursor::new(include_bytes!( let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
"../testdata/tls/RootCA.crt" "../testdata/tls/RootCA.crt"
))); )));
let certs = rustls_pemfile::certs(&mut reader) let certs = rustls_pemfile::certs(&mut reader).unwrap();
.collect::<Result<Vec<_>, _>>()
.unwrap();
let mut root_store = rustls::RootCertStore::empty(); let mut root_store = rustls::RootCertStore::empty();
root_store.add_parsable_certificates(certs); root_store.add_parsable_certificates(&certs);
let mut cfg = rustls::ClientConfig::builder() let mut cfg = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_store) .with_root_certificates(root_store)
.with_no_client_auth(); .with_no_client_auth();
cfg.alpn_protocols.push(b"foobar".to_vec()); cfg.alpn_protocols.push(b"foobar".to_vec());
let cfg = Arc::new(cfg); let cfg = Arc::new(cfg);
let hostname = let hostname = rustls::ServerName::try_from("localhost").unwrap();
rustls::pki_types::ServerName::try_from("localhost".to_string()).unwrap();
let tcp_stream = tokio::net::TcpStream::connect("localhost:4504") let tcp_stream = tokio::net::TcpStream::connect("localhost:4504")
.await .await
@ -5357,18 +5355,17 @@ async fn listen_tls_alpn_fail() {
let mut reader = &mut BufReader::new(Cursor::new(include_bytes!( let mut reader = &mut BufReader::new(Cursor::new(include_bytes!(
"../testdata/tls/RootCA.crt" "../testdata/tls/RootCA.crt"
))); )));
let certs = rustls_pemfile::certs(&mut reader) let certs = rustls_pemfile::certs(&mut reader).unwrap();
.collect::<Result<Vec<_>, _>>()
.unwrap();
let mut root_store = rustls::RootCertStore::empty(); let mut root_store = rustls::RootCertStore::empty();
root_store.add_parsable_certificates(certs); root_store.add_parsable_certificates(&certs);
let mut cfg = rustls::ClientConfig::builder() let mut cfg = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_store) .with_root_certificates(root_store)
.with_no_client_auth(); .with_no_client_auth();
cfg.alpn_protocols.push(b"boofar".to_vec()); cfg.alpn_protocols.push(b"boofar".to_vec());
let cfg = Arc::new(cfg); let cfg = Arc::new(cfg);
let hostname = rustls::pki_types::ServerName::try_from("localhost").unwrap(); let hostname = rustls::ServerName::try_from("localhost").unwrap();
let tcp_stream = tokio::net::TcpStream::connect("localhost:4505") let tcp_stream = tokio::net::TcpStream::connect("localhost:4505")
.await .await

View file

@ -392,8 +392,14 @@
// "test-http-outgoing-message-inheritance.js", // "test-http-outgoing-message-inheritance.js",
"test-http-outgoing-renderHeaders.js", "test-http-outgoing-renderHeaders.js",
"test-http-outgoing-settimeout.js", "test-http-outgoing-settimeout.js",
"test-http-url.parse-auth-with-header-in-request.js",
"test-http-url.parse-auth.js",
"test-http-url.parse-basic.js",
"test-http-url.parse-https.request.js", "test-http-url.parse-https.request.js",
"test-http-url.parse-only-support-http-https-protocol.js", "test-http-url.parse-only-support-http-https-protocol.js",
"test-http-url.parse-path.js",
"test-http-url.parse-post.js",
"test-http-url.parse-search.js",
"test-net-access-byteswritten.js", "test-net-access-byteswritten.js",
"test-net-better-error-messages-listen-path.js", "test-net-better-error-messages-listen-path.js",
"test-net-better-error-messages-path.js", "test-net-better-error-messages-path.js",

View file

@ -1308,12 +1308,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co
- [parallel/test-http-upgrade-reconsume-stream.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-reconsume-stream.js) - [parallel/test-http-upgrade-reconsume-stream.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-reconsume-stream.js)
- [parallel/test-http-upgrade-server.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-server.js) - [parallel/test-http-upgrade-server.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-server.js)
- [parallel/test-http-upgrade-server2.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-server2.js) - [parallel/test-http-upgrade-server2.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-upgrade-server2.js)
- [parallel/test-http-url.parse-auth-with-header-in-request.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-auth-with-header-in-request.js)
- [parallel/test-http-url.parse-auth.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-auth.js)
- [parallel/test-http-url.parse-basic.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-basic.js)
- [parallel/test-http-url.parse-path.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-path.js)
- [parallel/test-http-url.parse-post.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-post.js)
- [parallel/test-http-url.parse-search.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-url.parse-search.js)
- [parallel/test-http-wget.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-wget.js) - [parallel/test-http-wget.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-wget.js)
- [parallel/test-http-writable-true-after-close.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-writable-true-after-close.js) - [parallel/test-http-writable-true-after-close.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-writable-true-after-close.js)
- [parallel/test-http-write-callbacks.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-write-callbacks.js) - [parallel/test-http-write-callbacks.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-http-write-callbacks.js)

View file

@ -0,0 +1,59 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const http = require('http');
const url = require('url');
function check(request) {
// The correct authorization header is be passed
assert.strictEqual(request.headers.authorization, 'NoAuthForYOU');
}
const server = http.createServer(function(request, response) {
// Run the check function
check(request);
response.writeHead(200, {});
response.end('ok');
server.close();
});
server.listen(0, function() {
const testURL =
url.parse(`http://asdf:qwer@localhost:${this.address().port}`);
// The test here is if you set a specific authorization header in the
// request we should not override that with basic auth
testURL.headers = {
Authorization: 'NoAuthForYOU'
};
// make the request
http.request(testURL).end();
});

View file

@ -0,0 +1,55 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const http = require('http');
const url = require('url');
function check(request) {
// The correct authorization header is be passed
assert.strictEqual(request.headers.authorization, 'Basic dXNlcjpwYXNzOg==');
}
const server = http.createServer(function(request, response) {
// Run the check function
check(request);
response.writeHead(200, {});
response.end('ok');
server.close();
});
server.listen(0, function() {
const port = this.address().port;
// username = "user", password = "pass:"
const testURL = url.parse(`http://user:pass%3A@localhost:${port}`);
// make the request
http.request(testURL).end();
});

View file

@ -0,0 +1,65 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const http = require('http');
const url = require('url');
let testURL;
// Make sure the basics work
function check(request) {
// Default method should still be 'GET'
assert.strictEqual(request.method, 'GET');
// There are no URL params, so you should not see any
assert.strictEqual(request.url, '/');
// The host header should use the url.parse.hostname
assert.strictEqual(request.headers.host,
`${testURL.hostname}:${testURL.port}`);
}
const server = http.createServer(function(request, response) {
// Run the check function
check(request);
response.writeHead(200, {});
response.end('ok');
server.close();
});
server.listen(0, function() {
testURL = url.parse(`http://localhost:${this.address().port}`);
// make the request
const clientRequest = http.request(testURL);
// Since there is a little magic with the agent
// make sure that an http request uses the http.Agent
assert.ok(clientRequest.agent instanceof http.Agent);
clientRequest.end();
});

View file

@ -0,0 +1,53 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const http = require('http');
const url = require('url');
function check(request) {
// A path should come over
assert.strictEqual(request.url, '/asdf');
}
const server = http.createServer(function(request, response) {
// Run the check function
check(request);
response.writeHead(200, {});
response.end('ok');
server.close();
});
server.listen(0, function() {
const testURL = url.parse(`http://localhost:${this.address().port}/asdf`);
// make the request
http.request(testURL).end();
});

View file

@ -0,0 +1,61 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const http = require('http');
const url = require('url');
let testURL;
function check(request) {
// url.parse should not mess with the method
assert.strictEqual(request.method, 'POST');
// Everything else should be right
assert.strictEqual(request.url, '/asdf?qwer=zxcv');
// The host header should use the url.parse.hostname
assert.strictEqual(request.headers.host,
`${testURL.hostname}:${testURL.port}`);
}
const server = http.createServer(function(request, response) {
// Run the check function
check(request);
response.writeHead(200, {});
response.end('ok');
server.close();
});
server.listen(0, function() {
testURL = url.parse(`http://localhost:${this.address().port}/asdf?qwer=zxcv`);
testURL.method = 'POST';
// make the request
http.request(testURL).end();
});

View file

@ -0,0 +1,54 @@
// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('../common');
const assert = require('assert');
const http = require('http');
const url = require('url');
function check(request) {
// A path should come over with params
assert.strictEqual(request.url, '/asdf?qwer=zxcv');
}
const server = http.createServer(function(request, response) {
// Run the check function
check(request);
response.writeHead(200, {});
response.end('ok');
server.close();
});
server.listen(0, function() {
const port = this.address().port;
const testURL = url.parse(`http://localhost:${port}/asdf?qwer=zxcv`);
// make the request
http.request(testURL).end();
});

View file

@ -1,3 +1,3 @@
DANGER: TLS certificate validation is disabled for: deno.land DANGER: TLS certificate validation is disabled for: deno.land
error: Import 'https://localhost:5545/subdir/mod2.ts' failed: error sending request for url (https://localhost:5545/subdir/mod2.ts) error: Import 'https://localhost:5545/subdir/mod2.ts' failed: error sending request for url (https://localhost:5545/subdir/mod2.ts): error trying to connect: invalid peer certificate: UnknownIssuer
at file:///[WILDCARD]/cafile_url_imports.ts:[WILDCARD] at file:///[WILDCARD]/cafile_url_imports.ts:[WILDCARD]

View file

@ -67,7 +67,7 @@ Deno.test(
await fetch(`http://localhost:${port}`); await fetch(`http://localhost:${port}`);
}, },
TypeError, TypeError,
"error sending request for url", "error trying to connect",
); );
}, },
); );
@ -80,7 +80,7 @@ Deno.test(
await fetch("http://nil/"); await fetch("http://nil/");
}, },
TypeError, TypeError,
"error sending request for url", "error trying to connect",
); );
}, },
); );
@ -1824,7 +1824,7 @@ Deno.test(
await fetch(`http://${addr}/`); await fetch(`http://${addr}/`);
}, },
TypeError, TypeError,
"error sending request", "invalid content-length parsed",
); );
listener.close(); listener.close();
@ -1880,7 +1880,7 @@ Deno.test(
await response.arrayBuffer(); await response.arrayBuffer();
}, },
Error, Error,
"error decoding response body", "end of file before message length reached",
); );
listener.close(); listener.close();

View file

@ -2574,7 +2574,7 @@ for (const compression of [true, false]) {
assertEquals(result.value, new Uint8Array([65])); assertEquals(result.value, new Uint8Array([65]));
const err = await assertRejects(() => reader.read()); const err = await assertRejects(() => reader.read());
assert(err instanceof TypeError); assert(err instanceof TypeError);
assert(err.message.includes("error decoding response body")); assert(err.message.includes("unexpected EOF"));
const httpConn = await server; const httpConn = await server;
httpConn.close(); httpConn.close();
@ -2610,7 +2610,7 @@ for (const compression of [true, false]) {
assertEquals(result.value, new Uint8Array([65])); assertEquals(result.value, new Uint8Array([65]));
const err = await assertRejects(() => reader.read()); const err = await assertRejects(() => reader.read());
assert(err instanceof TypeError); assert(err instanceof TypeError);
assert(err.message.includes("error decoding response body")); assert(err.message.includes("unexpected internal error encountered"));
const httpConn = await server; const httpConn = await server;
httpConn.close(); httpConn.close();

View file

@ -3522,7 +3522,11 @@ Deno.test(
fail(); fail();
} catch (clientError) { } catch (clientError) {
assert(clientError instanceof TypeError); assert(clientError instanceof TypeError);
assert(clientError.message.includes("error sending request for url")); assert(
clientError.message.endsWith(
"connection closed before message completed",
),
);
} finally { } finally {
ac.abort(); ac.abort();
await server.finished; await server.finished;
@ -3570,7 +3574,11 @@ Deno.test({
fail(); fail();
} catch (clientError) { } catch (clientError) {
assert(clientError instanceof TypeError); assert(clientError instanceof TypeError);
assert(clientError.message.includes("error sending request for url")); assert(
clientError.message.endsWith(
"connection closed before message completed",
),
);
} finally { } finally {
ac.abort(); ac.abort();
await server.finished; await server.finished;

View file

@ -2,9 +2,9 @@
use anyhow::anyhow; use anyhow::anyhow;
use futures::Stream; use futures::Stream;
use futures::StreamExt; use futures::StreamExt;
use rustls::Certificate;
use rustls::PrivateKey;
use rustls_tokio_stream::rustls; use rustls_tokio_stream::rustls;
use rustls_tokio_stream::rustls::pki_types::CertificateDer;
use rustls_tokio_stream::rustls::pki_types::PrivateKeyDer;
use rustls_tokio_stream::TlsStream; use rustls_tokio_stream::TlsStream;
use std::io; use std::io;
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
@ -68,30 +68,30 @@ pub fn get_tls_config(
let key_file = std::fs::File::open(key_path)?; let key_file = std::fs::File::open(key_path)?;
let ca_file = std::fs::File::open(ca_path)?; let ca_file = std::fs::File::open(ca_path)?;
let certs_result: Result<Vec<CertificateDer<'static>>, io::Error> = { let certs: Vec<Certificate> = {
let mut cert_reader = io::BufReader::new(cert_file); let mut cert_reader = io::BufReader::new(cert_file);
rustls_pemfile::certs(&mut cert_reader).collect() rustls_pemfile::certs(&mut cert_reader)
.unwrap()
.into_iter()
.map(Certificate)
.collect()
}; };
let certs = certs_result?;
let mut ca_cert_reader = io::BufReader::new(ca_file); let mut ca_cert_reader = io::BufReader::new(ca_file);
let ca_cert = rustls_pemfile::certs(&mut ca_cert_reader) let ca_cert = rustls_pemfile::certs(&mut ca_cert_reader)
.collect::<Vec<_>>() .expect("Cannot load CA certificate")
.remove(0)?; .remove(0);
let mut key_reader = io::BufReader::new(key_file); let mut key_reader = io::BufReader::new(key_file);
let key = { let key = {
let pkcs8_keys = rustls_pemfile::pkcs8_private_keys(&mut key_reader) let pkcs8_key = rustls_pemfile::pkcs8_private_keys(&mut key_reader)
.collect::<Result<Vec<_>, _>>()?; .expect("Cannot load key file");
let rsa_keys = rustls_pemfile::rsa_private_keys(&mut key_reader) let rsa_key = rustls_pemfile::rsa_private_keys(&mut key_reader)
.collect::<Result<Vec<_>, _>>()?; .expect("Cannot load key file");
if !pkcs8_key.is_empty() {
if !pkcs8_keys.is_empty() { Some(pkcs8_key[0].clone())
let key = pkcs8_keys[0].clone_key(); } else if !rsa_key.is_empty() {
Some(PrivateKeyDer::from(key)) Some(rsa_key[0].clone())
} else if !rsa_keys.is_empty() {
let key = rsa_keys[0].clone_key();
Some(PrivateKeyDer::from(key))
} else { } else {
None None
} }
@ -100,19 +100,18 @@ pub fn get_tls_config(
match key { match key {
Some(key) => { Some(key) => {
let mut root_cert_store = rustls::RootCertStore::empty(); let mut root_cert_store = rustls::RootCertStore::empty();
root_cert_store.add(ca_cert).unwrap(); root_cert_store.add(&rustls::Certificate(ca_cert)).unwrap();
// Allow (but do not require) client authentication. // Allow (but do not require) client authentication.
let client_verifier = rustls::server::WebPkiClientVerifier::builder(
Arc::new(root_cert_store),
)
.allow_unauthenticated()
.build()
.unwrap();
let mut config = rustls::ServerConfig::builder() let mut config = rustls::ServerConfig::builder()
.with_client_cert_verifier(client_verifier) .with_safe_defaults()
.with_single_cert(certs, key) .with_client_cert_verifier(Arc::new(
rustls::server::AllowAnyAnonymousOrAuthenticatedClient::new(
root_cert_store,
),
))
.with_single_cert(certs, PrivateKey(key))
.map_err(|e| anyhow!("Error setting cert: {:?}", e)) .map_err(|e| anyhow!("Error setting cert: {:?}", e))
.unwrap(); .unwrap();