diff --git a/__network/fetch-rs/Cargo.lock b/__network/fetch-rs/Cargo.lock index 818a449..f9f7a04 100644 --- a/__network/fetch-rs/Cargo.lock +++ b/__network/fetch-rs/Cargo.lock @@ -315,6 +315,19 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" +dependencies = [ + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -600,6 +613,7 @@ dependencies = [ "http", "http-body", "hyper", + "hyper-rustls", "hyper-tls", "ipnet", "js-sys", @@ -609,19 +623,38 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "tokio", "tokio-native-tls", + "tokio-rustls", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots", "winreg", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + [[package]] name = "rust_util" version = "0.6.41" @@ -648,6 +681,37 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rustls" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.100.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.12" @@ -669,6 +733,16 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "security-framework" version = "2.9.1" @@ -740,6 +814,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "syn" version = "2.0.18" @@ -846,6 +926,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.8" @@ -913,6 +1003,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "url" version = "2.3.1" @@ -1022,6 +1118,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/__network/fetch-rs/Cargo.toml b/__network/fetch-rs/Cargo.toml index 3375801..64507d9 100644 --- a/__network/fetch-rs/Cargo.toml +++ b/__network/fetch-rs/Cargo.toml @@ -6,5 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -reqwest = { version = "0.11.18", features = ["blocking"] } +reqwest = { version = "0.11.18", features = ["blocking", "rustls-tls"] } rust_util = "0.6.41" diff --git a/__network/fetch-rs/src/main.rs b/__network/fetch-rs/src/main.rs index f0a3803..1ab1a5a 100644 --- a/__network/fetch-rs/src/main.rs +++ b/__network/fetch-rs/src/main.rs @@ -1,12 +1,46 @@ use std::str::FromStr; use std::time::Duration; -use reqwest::{Method, Proxy, Url}; +use reqwest::{Certificate, Method, Proxy, Url}; use reqwest::blocking::{Body, Client, Request}; use reqwest::header::{HeaderName, HeaderValue}; use rust_util::{simple_error, XResult}; +const TEST_CERT: &str = r#"-----BEGIN CERTIFICATE----- +MIIDeTCCAmGgAwIBAgIJAKL5ZETgtiFQMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNV +BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp +c2NvMQ8wDQYDVQQKDAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTAeFw0y +MzA0MjQwMDAxNDVaFw0yNTA0MjMwMDAxNDVaMGIxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQK +DAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMIE7PiM7gTCs9hQ1XBYzJMY61yoaEmwIrX5lZ6xKyx2 +PmzAS2BMTOqytMAPgLaw+XLJhgL5XEFdEyt/ccRLvOmULlA3pmccYYz2QULFRtMW +hyefdOsKnRFSJiFzbIRMeVXk0WvoBj1IFVKtsyjbqv9u/2CVSndrOfEk0TG23U3A +xPxTuW1CrbV8/q71FdIzSOciccfCFHpsKOo3St/qbLVytH5aohbcabFXRNsKEqve +ww9HdFxBIuGa+RuT5q0iBikusbpJHAwnnqP7i/dAcgCskgjZjFeEU4EFy+b+a1SY +QCeFxxC7c3DvaRhBB0VVfPlkPz0sw6l865MaTIbRyoUCAwEAAaMyMDAwCQYDVR0T +BAIwADAjBgNVHREEHDAaggwqLmJhZHNzbC5jb22CCmJhZHNzbC5jb20wDQYJKoZI +hvcNAQELBQADggEBAJqRSkgOf5GHCJzljWQg9D+1LEuByYyQfNzGJb+TZkPpxNEw +6gbt3vbQfWBx9WQ6995XjdjM6N6l5DO8p0Sp70OHHQ9Lt2N7PC7I5YhJFObkMyza +sRuLWTzlYShLvSRGQFC/Ky4hTbpzlZA5TADG1weajSlIBLo6UGkQaGk4xG4zhIKA +PhvsFZsayLexJ1DCql0XAiNnknTfX8FRMI9Ezsj0XeZ8ZD8ouLGYwbTezcYnE/uI +0Y/ayROwdd+Ny4N6McsEE+KOxS8Xe+LU4X3MEHSXcmT8ht/xTyxQ2JjzHtS6eHjO +lJON+7kLWv6kgtYf9jHJDsNMPLis6RbUYdkeP5A= +-----END CERTIFICATE-----"#; + fn main() -> XResult<()> { + let _ = print_response(&fetch( + "https://self-signed.badssl.com/", + &FetchOptions { + trust_all_certificates: false, + certificates: vec![TEST_CERT.into()], + ..Default::default() + }, + )?); + Ok(()) +} + +fn main2() -> XResult<()> { println!("TEST1: GET"); let response = fetch( "https://hatter.ink/util/print_request.action", @@ -90,6 +124,8 @@ pub struct FetchOptions { pub proxy: Option, // TODO hsts supports // TODO follow redirects? + pub certificates: Vec, + pub trust_all_certificates: bool, } impl FetchOptions {} @@ -124,7 +160,18 @@ pub fn fetch(url: &str, option: &FetchOptions) -> XResult { if let Some(proxy) = &option.proxy { client_builder = client_builder.proxy(Proxy::all(proxy.as_str())?); } - // TODO client_builder.add_root_certificate() + if option.trust_all_certificates { + client_builder = client_builder.danger_accept_invalid_certs(true); + } + if !option.certificates.is_empty() { + client_builder = client_builder.use_rustls_tls(); + for cert in &option.certificates { + match Certificate::from_pem(cert.as_bytes()) { + Ok(cert) => client_builder = client_builder.add_root_certificate(cert), + Err(e) => return simple_error!("Parse certificate failed: {}", e), + } + } + } let client = client_builder.build()?; let method = match option.method { FetchMethod::Get => Method::GET,