aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rwxr-xr-xgenkeys.sh35
-rw-r--r--src/rpc_client.rs3
-rw-r--r--src/tls_util.rs58
4 files changed, 37 insertions, 61 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 2e98c45a..c339f7a6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,7 +31,7 @@ reduce = "0.1.2"
serde_json = "1.0"
rustls = "0.17"
-tokio-rustls = { version = "0.13", features = ["dangerous_configuration"] }
+tokio-rustls = "0.13"
hyper-rustls = { version = "0.20", default-features = false }
webpki = "0.21"
diff --git a/genkeys.sh b/genkeys.sh
index ae493248..92d86ab8 100755
--- a/genkeys.sh
+++ b/genkeys.sh
@@ -7,6 +7,8 @@ cd $(dirname $0)
mkdir -p pki
cd pki
+# Create a certificate authority that both the client side and the server side of
+# the RPC protocol will use to authenticate the other side.
if [ ! -f garage-ca.key ]; then
echo "Generating Garage CA keys..."
openssl genrsa -out garage-ca.key 4096
@@ -14,6 +16,9 @@ if [ ! -f garage-ca.key ]; then
fi
+# Generate a certificate that can be used either as a server certificate
+# or a client certificate. This is what the RPC client and server will use
+# to prove that they are authenticated by the CA.
if [ ! -f garage.crt ]; then
echo "Generating Garage agent keys..."
if [ ! -f garage.key ]; then
@@ -46,3 +51,33 @@ EOF
-CA garage-ca.crt -CAkey garage-ca.key -CAcreateserial \
-out garage.crt -days 365
fi
+
+# Client-only certificate used for the CLI
+if [ ! -f garage-client.crt ]; then
+ echo "Generating Garage client keys..."
+ if [ ! -f garage-client.key ]; then
+ openssl genrsa -out garage-client.key 4096
+ fi
+ openssl req -new -sha256 -key garage-client.key -subj "/C=FR/O=Garage" \
+ -out garage-client.csr
+ openssl req -in garage-client.csr -noout -text
+ openssl x509 -req -in garage-client.csr \
+ -extensions v3_req \
+ -extfile <(cat <<EOF
+[req]
+distinguished_name = req_distinguished_name
+req_extensions = v3_req
+prompt = no
+
+[req_distinguished_name]
+C = FR
+O = Garage
+
+[v3_req]
+keyUsage = keyEncipherment, dataEncipherment
+extendedKeyUsage = clientAuth
+EOF
+) \
+ -CA garage-ca.crt -CAkey garage-ca.key -CAcreateserial \
+ -out garage-client.crt -days 365
+fi
diff --git a/src/rpc_client.rs b/src/rpc_client.rs
index 255eb958..6f897a90 100644
--- a/src/rpc_client.rs
+++ b/src/rpc_client.rs
@@ -109,7 +109,6 @@ impl RpcClient {
}
config.set_single_client_cert([&node_certs[..], &ca_certs[..]].concat(), node_key)?;
- // config.dangerous().set_certificate_verifier(Arc::new(tls_util::NoHostnameCertVerifier));
let connector =
tls_util::HttpsConnectorFixedDnsname::<HttpConnector>::new(config, "garage");
@@ -143,7 +142,7 @@ impl RpcClient {
let resp = tokio::time::timeout(timeout, resp_fut)
.await?
.map_err(|e| {
- eprintln!("RPC client error: {}", e);
+ eprintln!("RPC HTTP client error when connecting to {}: {}", to_addr, e);
e
})?;
diff --git a/src/tls_util.rs b/src/tls_util.rs
index 5a17d380..dfc4e716 100644
--- a/src/tls_util.rs
+++ b/src/tls_util.rs
@@ -7,7 +7,6 @@ use core::future::Future;
use futures_util::future::*;
use tokio::io::{AsyncRead, AsyncWrite};
use rustls::internal::pemfile;
-use rustls::*;
use hyper::client::HttpConnector;
use hyper::client::connect::Connection;
use hyper::service::Service;
@@ -60,63 +59,6 @@ pub fn load_private_key(filename: &str) -> Result<rustls::PrivateKey, Error> {
}
-// ---- AWFUL COPYPASTA FROM rustls/verifier.rs
-// ---- USED TO ALLOW TO VERIFY SERVER CERTIFICATE VALIDITY IN CHAIN
-// ---- BUT DISREGARD HOSTNAME PARAMETER
-
-pub struct NoHostnameCertVerifier;
-
-type SignatureAlgorithms = &'static [&'static webpki::SignatureAlgorithm];
-static SUPPORTED_SIG_ALGS: SignatureAlgorithms = &[
- &webpki::ECDSA_P256_SHA256,
- &webpki::ECDSA_P256_SHA384,
- &webpki::ECDSA_P384_SHA256,
- &webpki::ECDSA_P384_SHA384,
- &webpki::RSA_PSS_2048_8192_SHA256_LEGACY_KEY,
- &webpki::RSA_PSS_2048_8192_SHA384_LEGACY_KEY,
- &webpki::RSA_PSS_2048_8192_SHA512_LEGACY_KEY,
- &webpki::RSA_PKCS1_2048_8192_SHA256,
- &webpki::RSA_PKCS1_2048_8192_SHA384,
- &webpki::RSA_PKCS1_2048_8192_SHA512,
- &webpki::RSA_PKCS1_3072_8192_SHA384
-];
-
-impl rustls::ServerCertVerifier for NoHostnameCertVerifier {
- fn verify_server_cert(&self,
- roots: &RootCertStore,
- presented_certs: &[Certificate],
- _dns_name: webpki::DNSNameRef,
- _ocsp_response: &[u8]) -> Result<rustls::ServerCertVerified, TLSError> {
-
- if presented_certs.is_empty() {
- return Err(TLSError::NoCertificatesPresented);
- }
-
- let cert = webpki::EndEntityCert::from(&presented_certs[0].0)
- .map_err(TLSError::WebPKIError)?;
-
- let chain = presented_certs.iter()
- .skip(1)
- .map(|cert| cert.0.as_ref())
- .collect::<Vec<_>>();
-
- let trustroots: Vec<webpki::TrustAnchor> = roots.roots
- .iter()
- .map(|x| x.to_trust_anchor())
- .collect();
-
- let now = webpki::Time::try_from(std::time::SystemTime::now())
- .map_err( |_ | TLSError::FailedToGetCurrentTime)?;
-
- cert.verify_is_valid_tls_server_cert(SUPPORTED_SIG_ALGS,
- &webpki::TLSServerTrustAnchors(&trustroots), &chain, now)
- .map_err(TLSError::WebPKIError)?;
-
- Ok(rustls::ServerCertVerified::assertion())
- }
-}
-
-
// ---- AWFUL COPYPASTA FROM HYPER-RUSTLS connector.rs
// ---- ALWAYS USE `garage` AS HOSTNAME FOR TLS VERIFICATION