Skip to content

Commit b702d91

Browse files
committed
Support HTTPS
Signed-off-by: Miroslav Kovar <[email protected]>
1 parent d77e1df commit b702d91

File tree

3 files changed

+92
-2
lines changed

3 files changed

+92
-2
lines changed

indy-vdr-proxy/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ license = "Apache-2.0"
1010
[features]
1111
fetch = ["hyper-tls", "hyper/client"]
1212
zmq_vendored = ["indy-vdr/zmq_vendored"]
13+
tls = ["rustls-pemfile", "tokio-rustls", "hyper/stream"]
1314
default = ["fetch", "zmq_vendored"]
1415

1516
[dependencies]
@@ -27,6 +28,8 @@ regex = "1.5.4"
2728
serde_json = "1.0"
2829
tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "signal"] }
2930
url = "2.2.2"
31+
rustls-pemfile = { version = "1.0.3", optional = true }
32+
tokio-rustls = { version = "0.24.1", optional = true }
3033

3134
[target.'cfg(unix)'.dependencies]
3235
hyper-unix-connector = "0.2"

indy-vdr-proxy/src/app.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ pub struct Config {
1111
pub init_refresh: bool,
1212
pub interval_refresh: u32,
1313
pub is_multiple: bool,
14+
pub tls_cert_path: Option<String>,
15+
pub tls_key_path: Option<String>,
1416
}
1517

1618
pub fn load_config() -> Result<Config, String> {
@@ -66,6 +68,20 @@ pub fn load_config() -> Result<Config, String> {
6668
.takes_value(true)
6769
.value_name("INTERVAL")
6870
.help("Set the interval in minutes between validator node refresh attempts (0 to disable refresh, default 120)"),
71+
)
72+
.arg(
73+
Arg::new("tls-cert")
74+
.long("tls-cert")
75+
.takes_value(true)
76+
.value_name("CERT")
77+
.help("Path to the TLS certificate file")
78+
)
79+
.arg(
80+
Arg::new("tls-key")
81+
.long("tls-key")
82+
.takes_value(true)
83+
.value_name("KEY")
84+
.help("Path to the TLS private key file")
6985
);
7086

7187
#[cfg(unix)]
@@ -112,6 +128,9 @@ pub fn load_config() -> Result<Config, String> {
112128
.transpose()?
113129
.unwrap_or(120);
114130

131+
let tls_cert_path = matches.value_of("tls-cert").map(str::to_owned);
132+
let tls_key_path = matches.value_of("tls-key").map(str::to_owned);
133+
115134
Ok(Config {
116135
genesis,
117136
namespace,
@@ -122,5 +141,7 @@ pub fn load_config() -> Result<Config, String> {
122141
init_refresh,
123142
interval_refresh,
124143
is_multiple,
144+
tls_cert_path,
145+
tls_key_path,
125146
})
126147
}

indy-vdr-proxy/src/main.rs

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ use std::path::PathBuf;
1616
use std::process::exit;
1717
use std::rc::Rc;
1818
use std::time::{Duration, SystemTime};
19+
#[cfg(feature = "tls")]
20+
use std::{fs::File, io::BufReader, sync::Arc};
1921

2022
use futures_util::future::FutureExt;
23+
#[cfg(feature = "tls")]
24+
use futures_util::stream;
2125
use git2::Repository;
2226

2327
#[cfg(feature = "fetch")]
@@ -32,9 +36,18 @@ use hyper_tls::HttpsConnector;
3236
#[cfg(unix)]
3337
use hyper_unix_connector::UnixConnector;
3438

39+
#[cfg(feature = "tls")]
40+
use rustls_pemfile::{certs, pkcs8_private_keys};
41+
#[cfg(feature = "tls")]
42+
use tokio::net::TcpListener;
3543
use tokio::select;
3644
#[cfg(unix)]
3745
use tokio::signal::unix::SignalKind;
46+
#[cfg(feature = "tls")]
47+
use tokio_rustls::{
48+
rustls::{Certificate, PrivateKey, ServerConfig},
49+
TlsAcceptor,
50+
};
3851

3952
use indy_vdr::common::error::prelude::*;
4053
use indy_vdr::pool::{helpers::perform_refresh, LocalPool, PoolBuilder, PoolTransactions};
@@ -352,11 +365,64 @@ async fn init_server(config: app::Config) -> Result<(), String> {
352365
.parse::<IpAddr>()
353366
.map_err(|_| "Error parsing host IP")?;
354367
let addr = (ip, config.port.unwrap()).into();
355-
let builder =
356-
Server::try_bind(&addr).map_err(|err| format!("Error binding TCP socket: {}", err))?;
368+
369+
#[cfg(feature = "tls")]
370+
if let (Some(tls_cert_path), Some(tls_key_path)) = (&config.tls_cert_path, &config.tls_key_path)
371+
{
372+
let tls_cfg = build_tls_config(&tls_cert_path, &tls_key_path)?;
373+
let tls_acceptor = TlsAcceptor::from(Arc::new(tls_cfg));
374+
let tcp_listener = TcpListener::bind(&addr)
375+
.await
376+
.map_err(|err| format!("Error binding TCP socket: {}", err))?;
377+
378+
let incoming_tls_stream = stream::try_unfold(tcp_listener, move |tcp_listener| {
379+
let tls_acceptor = tls_acceptor.clone();
380+
async move {
381+
match tcp_listener.accept().await {
382+
Ok((socket, _)) => Ok(Some((
383+
tls_acceptor.clone().accept(socket).await?,
384+
tcp_listener,
385+
))),
386+
Err(err) => Err(err),
387+
}
388+
}
389+
});
390+
let builder = Server::builder(hyper::server::accept::from_stream(incoming_tls_stream));
391+
return run_server(builder, state, format!("https://{}", addr), config).await;
392+
}
393+
394+
let builder = Server::try_bind(&addr)
395+
.map_err(|err| format!("Error binding TCP socket: {}", err.to_string()))?;
357396
run_server(builder, state, format!("http://{}", addr), config).await
358397
}
359398

399+
#[cfg(feature = "tls")]
400+
fn build_tls_config(cert_path: &str, key_path: &str) -> Result<ServerConfig, String> {
401+
let certs = certs(&mut BufReader::new(
402+
File::open(cert_path)
403+
.map_err(|err| format!("Error opening TLS certificate file: {}", err))?,
404+
))
405+
.map_err(|err| format!("Error parsing TLS certificate file: {}", err))?;
406+
let keys = pkcs8_private_keys(&mut BufReader::new(
407+
File::open(key_path).map_err(|err| format!("Error opening TLS key file: {}", err))?,
408+
))
409+
.map_err(|err| format!("Error parsing TLS key file: {}", err))?;
410+
ServerConfig::builder()
411+
.with_safe_defaults()
412+
.with_no_client_auth()
413+
.with_single_cert(
414+
vec![Certificate(certs.into_iter().next().ok_or_else(|| {
415+
"Error parsing TLS certificate file: no certificates found".to_string()
416+
})?)],
417+
PrivateKey(
418+
keys.into_iter()
419+
.next()
420+
.ok_or_else(|| "Error parsing TLS key file: no keys found".to_string())?,
421+
),
422+
)
423+
.map_err(|err| format!("Error building TLS config: {}", err.to_string()))
424+
}
425+
360426
async fn run_server<I>(
361427
builder: hyper::server::Builder<I>,
362428
state: Rc<RefCell<AppState>>,

0 commit comments

Comments
 (0)