diff --git a/Cargo.lock b/Cargo.lock index 01c99e309..8973b1160 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -377,6 +377,14 @@ dependencies = [ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ct-logs" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ctrlc" version = "3.1.1" @@ -670,17 +678,18 @@ dependencies = [ "grin_util 0.3.0", "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.12.10 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-tls 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tls 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -984,6 +993,24 @@ dependencies = [ "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hyper-rustls" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.10 (registry+https://github.com/rust-lang/crates.io-index)", + "rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki-roots 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "hyper-staticfile" version = "0.3.0" @@ -1810,6 +1837,17 @@ dependencies = [ "uuid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ring" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ripemd160" version = "0.7.0" @@ -1838,6 +1876,19 @@ dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustls" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ryu" version = "0.2.6" @@ -1875,6 +1926,15 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "sct" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "secp256k1zkp" version = "0.7.1" @@ -2279,6 +2339,16 @@ dependencies = [ "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-rustls" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-service" version = "0.1.0" @@ -2325,16 +2395,6 @@ dependencies = [ "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tokio-tls" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tokio-udp" version = "0.1.2" @@ -2440,6 +2500,11 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "untrusted" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "url" version = "1.7.1" @@ -2513,6 +2578,24 @@ dependencies = [ "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "webpki" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "webpki-roots" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "which" version = "1.0.5" @@ -2647,6 +2730,7 @@ dependencies = [ "checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" "checksum crypto-mac 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7afa06d05a046c7a47c3a849907ec303504608c927f4e85f7bfff22b7180d971" "checksum csv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ef22b37c7a51c564a365892c012dc0271221fdcc64c69b19ba4d6fa8bd96d9c" +"checksum ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95a4bf5107667e12bf6ce31a3a5066d67acc88942b6742117a41198734aaccaa" "checksum ctrlc 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "630391922b1b893692c6334369ff528dcc3a9d8061ccf4c803aa8f83cb13db5e" "checksum cursive 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c75a59f5b54834c5853b1e8d0d4a256252d4ca1da02f0be3e245b48daa754233" "checksum daemonize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4093d27eb267d617f03c2ee25d4c3ca525b89a76154001954a11984508ffbde5" @@ -2684,6 +2768,7 @@ dependencies = [ "checksum httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7b6288d7db100340ca12873fd4d08ad1b8f206a9457798dfb17c018a33fee540" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" "checksum hyper 0.12.10 (registry+https://github.com/rust-lang/crates.io-index)" = "529d00e4c998cced1a15ffd53bbe203917b39ed6071281c16184ab0014ca6ff3" +"checksum hyper-rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68f2aa6b1681795bf4da8063f718cd23145aa0c9a5143d9787b345aa60d38ee4" "checksum hyper-staticfile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4080cb44b9c1e4c6dfd6f7ee85a9c3439777ec9c59df32f944836d3de58ac35e" "checksum hyper-tls 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "caaee4dea92794a9e697038bd401e264307d1f22c883dbcb6f6618ba0d3b3bd3" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" @@ -2776,16 +2861,19 @@ dependencies = [ "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum reqwest 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c4265be4dad32ffa4be2cea9c8ecb5e096feca6b4ff024482bfc0f64b6019b2f" +"checksum ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe642b9dd1ba0038d78c4a3999d1ee56178b4d415c1e1fbaba83b06dce012f0" "checksum ripemd160 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "482aa56cc68aaeccdaaff1cc5a72c247da8bbad3beb174ca5741f274c22883fb" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +"checksum rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "942b71057b31981152970d57399c25f72e27a6ee0d207a669d8304cabf44705b" "checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c" "checksum schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1fabf2a7b6483a141426e1afd09ad543520a77ac49bd03c286e7696ccfd77f" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb8f61f9e6eadd062a71c380043d28036304a4706b3c4dd001ff3387ed00745a" "checksum secp256k1zkp 0.7.1 (git+https://github.com/mimblewimble/rust-secp256k1-zkp?tag=grin_integration_23a)" = "" "checksum security-framework 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "697d3f3c23a618272ead9e1fb259c1411102b31c6af8b93f1d64cca9c3b0e8e0" "checksum security-framework-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab01dfbe5756785b5b4d46e0289e5a18071dfa9a7c2b24213ea00b9ef9b665bf" @@ -2829,11 +2917,11 @@ dependencies = [ "checksum tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6cc2de7725863c86ac71b0b9068476fec50834f055a243558ef1655bbd34cb" "checksum tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4bfbaf9f260635649ec26b6fb4aded03887295ffcd999f6e43fd2c4758f758ea" "checksum tokio-retry 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f05746ae87dca83a2016b4f5dba5b237b897dd12fd324f60afe282112f16969a" +"checksum tokio-rustls 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "208d62fa3e015426e3c64039d9d20adf054a3c9b4d9445560f1c41c75bef3eab" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "checksum tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4c329b47f071eb8a746040465fa751bd95e4716e98daef6a9b4e434c17d565" "checksum tokio-threadpool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a5758cecb6e0633cea5d563ac07c975e04961690b946b04fd84e7d6445a8f6af" "checksum tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d03fa701f9578a01b7014f106b47f0a363b4727a7f3f75d666e312ab7acbbf1c" -"checksum tokio-tls 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e53fdbf3156f588be1676022fe794232b24922d426e8c14f4e46891c1e31c440" "checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c" "checksum tokio-uds 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "424c1ed15a0132251813ccea50640b224c809d6ceafb88154c1a8775873a0e89" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" @@ -2848,6 +2936,7 @@ dependencies = [ "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" "checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" "checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" @@ -2858,6 +2947,8 @@ dependencies = [ "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "af464bc7be7b785c7ac72e266a6b67c4c9070155606f51655a650a6686204e35" "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" +"checksum webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "17d7967316d8411ca3b01821ee6c332bde138ba4363becdb492f12e514daa17f" +"checksum webpki-roots 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85d1f408918fd590908a70d36b7ac388db2edc221470333e4d6e5b598e44cabf" "checksum which 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e84a603e7e0b1ce1aa1ee2b109c7be00155ce52df5081590d1ffb93f4f515cb2" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" diff --git a/api/Cargo.toml b/api/Cargo.toml index bd243e00b..d4ac82a2b 100644 --- a/api/Cargo.toml +++ b/api/Cargo.toml @@ -17,11 +17,12 @@ serde_json = "1" slog = { version = "~2.3", features = ["max_level_trace", "release_max_level_trace"] } tokio = "0.1.7" tokio-core = "0.1.17" -tokio-tls = "0.2" -native-tls = "0.2" +tokio-tcp = "0.1" +tokio-rustls = "0.7" http = "0.1.5" -hyper-tls = "0.3" +hyper-rustls = "0.14" futures = "0.1.21" +rustls = "0.13" url = "1.7.0" grin_core = { path = "../core" } diff --git a/api/src/client.rs b/api/src/client.rs index 42d0a34af..b6bac3b33 100644 --- a/api/src/client.rs +++ b/api/src/client.rs @@ -19,11 +19,11 @@ use http::uri::{InvalidUri, Uri}; use hyper::header::{ACCEPT, AUTHORIZATION, USER_AGENT}; use hyper::rt::{Future, Stream}; use hyper::{Body, Client, Request}; -use hyper_tls; use serde::{Deserialize, Serialize}; use serde_json; use futures::future::{err, ok, Either}; +use hyper_rustls; use tokio::runtime::Runtime; use rest::{Error, ErrorKind}; @@ -186,7 +186,7 @@ where } fn send_request_async(req: Request) -> Box + Send> { - let https = hyper_tls::HttpsConnector::new(1).unwrap(); + let https = hyper_rustls::HttpsConnector::new(1); let client = Client::builder().build::<_, Body>(https); Box::new( client diff --git a/api/src/lib.rs b/api/src/lib.rs index 41be1cf71..9430c65de 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -24,7 +24,6 @@ extern crate failure; #[macro_use] extern crate failure_derive; extern crate hyper; -extern crate hyper_tls; #[macro_use] extern crate lazy_static; extern crate regex; @@ -36,10 +35,12 @@ extern crate serde_json; extern crate slog; extern crate futures; extern crate http; -extern crate native_tls; +extern crate hyper_rustls; +extern crate rustls; extern crate tokio; extern crate tokio_core; -extern crate tokio_tls; +extern crate tokio_rustls; +extern crate tokio_tcp; pub mod auth; pub mod client; diff --git a/api/src/rest.rs b/api/src/rest.rs index 9d440a4ef..f7738d0a5 100644 --- a/api/src/rest.rs +++ b/api/src/rest.rs @@ -22,17 +22,17 @@ use failure::{Backtrace, Context, Fail, ResultExt}; use futures::sync::oneshot; use futures::Stream; use hyper::rt::Future; -use hyper::server::conn::Http; use hyper::{rt, Body, Request, Server}; -use native_tls::{Identity, TlsAcceptor}; use router::{Handler, HandlerObj, ResponseFuture, Router}; +use rustls; +use rustls::internal::pemfile; use std::fmt::{self, Display}; use std::fs::File; -use std::io::Read; use std::net::SocketAddr; +use std::sync::Arc; use std::{io, thread}; -use tokio::net::TcpListener; -use tokio_tls; +use tokio_rustls::ServerConfigExt; +use tokio_tcp; use util::LOGGER; /// Errors that can be returned by an ApiEndpoint implementation. @@ -93,23 +93,55 @@ impl From> for Error { /// TLS config pub struct TLSConfig { - pub pkcs_bytes: Vec, - pub pass: String, + certificate: String, + private_key: String, } impl TLSConfig { - pub fn new(pass: String, file: String) -> Result { - let mut f = File::open(&file).context(ErrorKind::Internal(format!( - "can't open TLS certifiacte file {}", - file + pub fn new(certificate: String, private_key: String) -> TLSConfig { + TLSConfig { + certificate, + private_key, + } + } + + fn load_certs(&self) -> Result, Error> { + let certfile = File::open(&self.certificate).context(ErrorKind::Internal(format!( + "failed to open file {}", + self.certificate )))?; - let mut pkcs_bytes = Vec::new(); - f.read_to_end(&mut pkcs_bytes) - .context(ErrorKind::Internal(format!( - "can't read TLS certifiacte file {}", - file - )))?; - Ok(TLSConfig { pkcs_bytes, pass }) + let mut reader = io::BufReader::new(certfile); + + pemfile::certs(&mut reader) + .map_err(|_| ErrorKind::Internal("failed to load certificate".to_string()).into()) + } + + fn load_private_key(&self) -> Result { + let keyfile = File::open(&self.private_key).context(ErrorKind::Internal(format!( + "failed to open file {}", + self.private_key + )))?; + let mut reader = io::BufReader::new(keyfile); + + let keys = pemfile::pkcs8_private_keys(&mut reader) + .map_err(|_| ErrorKind::Internal("failed to load private key".to_string()))?; + if keys.len() != 1 { + return Err(ErrorKind::Internal( + "expected a single private key".to_string(), + ))?; + } + Ok(keys[0].clone()) + } + + pub fn build_server_config(&self) -> Result, Error> { + let certs = self.load_certs()?; + let key = self.load_private_key()?; + let mut cfg = rustls::ServerConfig::new(rustls::NoClientAuth::new()); + cfg.set_single_cert(certs, key) + .context(ErrorKind::Internal( + "set single certificate failed".to_string(), + ))?; + Ok(Arc::new(cfg)) } } @@ -180,37 +212,26 @@ impl ApiServer { "Can't start HTTPS API server, it's running already".to_string(), ))?; } + + let tls_conf = conf.build_server_config()?; + thread::Builder::new() .name("apis".to_string()) .spawn(move || { - let cert = Identity::from_pkcs12(conf.pkcs_bytes.as_slice(), &conf.pass).unwrap(); - let tls_cx = TlsAcceptor::builder(cert).build().unwrap(); - let tls_cx = tokio_tls::TlsAcceptor::from(tls_cx); - let srv = TcpListener::bind(&addr).expect("Error binding local port"); - // Use lower lever hyper API to be able to intercept client connection - let server = Http::new() - .serve_incoming( - srv.incoming().and_then(move |socket| { - tls_cx - .accept(socket) - .map_err(|e| io::Error::new(io::ErrorKind::Other, e)) - }), - router, - ).then(|res| match res { - Ok(conn) => Ok(Some(conn)), + let listener = tokio_tcp::TcpListener::bind(&addr).expect("failed to bind"); + let tls = listener + .incoming() + .and_then(move |s| tls_conf.accept_async(s)) + .then(|r| match r { + Ok(x) => Ok::<_, io::Error>(Some(x)), Err(e) => { - eprintln!("Error: {}", e); - Ok(None) + eprintln!("accept_async failed"); + Err(e) } - }).for_each(|conn_opt| { - if let Some(conn) = conn_opt { - rt::spawn( - conn.and_then(|c| c.map_err(|e| panic!("Hyper error {}", e))) - .map_err(|e| eprintln!("Connection error {}", e)), - ); - } - Ok(()) - }); + }).filter_map(|x| x); + let server = Server::builder(tls) + .serve(router) + .map_err(|e| eprintln!("HTTP API server error: {}", e)); rt::run(server); }).map_err(|_| ErrorKind::Internal("failed to spawn API thread".to_string()).into()) diff --git a/api/tests/rest.rs b/api/tests/rest.rs index c17495198..f522c5539 100644 --- a/api/tests/rest.rs +++ b/api/tests/rest.rs @@ -86,17 +86,16 @@ fn test_start_api() { #[test] fn test_start_api_tls() { util::init_test_logger(); - let tls_conf = TLSConfig { - pkcs_bytes: include_bytes!("localhost+1.p12").to_vec(), - pass: "changeit".to_string(), - }; + let tls_conf = TLSConfig::new( + "tests/fullchain.pem".to_string(), + "tests/privkey.pem".to_string(), + ); let mut server = ApiServer::new(); let router = build_router(); - let server_addr = "127.0.0.1:14444"; + let server_addr = "0.0.0.0:14444"; let addr: SocketAddr = server_addr.parse().expect("unable to parse server address"); assert!(server.start(addr, router, Some(tls_conf)).is_ok()); - let url = format!("https://{}/v1/", server_addr); - let index = api::client::get::>(url.as_str(), None).unwrap(); + let index = api::client::get::>("https://yourdomain.com:14444/v1/", None).unwrap(); assert_eq!(index.len(), 2); assert!(!server.stop()); } diff --git a/config/src/comments.rs b/config/src/comments.rs index a5f31cbaf..056eb4efb 100644 --- a/config/src/comments.rs +++ b/config/src/comments.rs @@ -311,12 +311,10 @@ fn comments() -> HashMap { " #port for wallet listener -#path of TLS certificate file (PKCS#12 format is supported) -#self-signed certificates are not supported, use https://github.com/FiloSottile/mkcert -#to test on localhost +#path of TLS certificate file, self-signed certificates are not supported #tls_certificate_file = \"\" -#password of TLS certificate file (PKCS#12 format is supported) -#tls_certificate_pass = \"\" +#private key for the TLS certificate +#tls_certificate_key = \"\" ".to_string(), ); diff --git a/src/bin/cmd/wallet.rs b/src/bin/cmd/wallet.rs index ac34ad327..fb62ac7c1 100644 --- a/src/bin/cmd/wallet.rs +++ b/src/bin/cmd/wallet.rs @@ -137,15 +137,13 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) { let tls_conf = match wallet_config.tls_certificate_file.clone() { None => None, - Some(file) => Some( - TLSConfig::new( - wallet_config - .tls_certificate_pass - .clone() - .expect("tls_certificate_pass must be set"), - file, - ).expect("failed to configure TLS"), - ), + Some(file) => Some(TLSConfig::new( + file, + wallet_config + .tls_certificate_key + .clone() + .expect("Private key for certificate is not set"), + )), }; match wallet_args.subcommand() { ("listen", Some(listen_args)) => { @@ -161,7 +159,8 @@ pub fn wallet_command(wallet_args: &ArgMatches, config: GlobalWalletConfig) { }); } ("owner_api", Some(_api_args)) => { - controller::owner_listener(wallet, "127.0.0.1:13420", api_secret, tls_conf) + // TLS is disabled because we bind to localhost + controller::owner_listener(wallet, "127.0.0.1:13420", api_secret, None) .unwrap_or_else(|e| { panic!( "Error creating wallet api listener: {:?} Config: {:?}", diff --git a/wallet/src/types.rs b/wallet/src/types.rs index 8bbc97119..97792e164 100644 --- a/wallet/src/types.rs +++ b/wallet/src/types.rs @@ -50,8 +50,8 @@ pub struct WalletConfig { pub data_file_dir: String, /// TLS ceritificate file pub tls_certificate_file: Option, - /// TLS ceritificate password - pub tls_certificate_pass: Option, + /// TLS ceritificate private key file + pub tls_certificate_key: Option, } impl Default for WalletConfig { @@ -65,7 +65,7 @@ impl Default for WalletConfig { check_node_api_http_addr: "http://127.0.0.1:13413".to_string(), data_file_dir: ".".to_string(), tls_certificate_file: None, - tls_certificate_pass: None, + tls_certificate_key: None, } } }