Skip to content

Commit

Permalink
feat: grpc over tls (#5990)
Browse files Browse the repository at this point in the history
Description
---
Add configuration and support for operating grpc over tls to enhance the
overall security of communicating nodes, wallets, and miners.

This includes a self-signed certificate generation function for using
locally, although it's highly recommended to generate valid, and
verifiable certificates if you plan on opening any service up to the
internet.

~TODO (before merge, eta: 1day)~: Complete
- ~Expand to the merge miner~
- ~Expand to the wallet~
- ~Display a warning about security when generating self signed
certificates~

Motivation and Context
---
Mo' security mo' better.

Closes: #5808 

How Has This Been Tested?
---
Locally

What process can a PR reviewer use to test or verify this change?
---
Mostly read about how to set it up, and see if that makes sense.

Breaking Changes
---

- [x] None
- [ ] Requires data directory on base node to be deleted
- [ ] Requires hard fork
- [ ] Other - Please specify
  • Loading branch information
brianp committed Nov 30, 2023
1 parent 49f2053 commit b80f7e3
Show file tree
Hide file tree
Showing 27 changed files with 567 additions and 40 deletions.
113 changes: 102 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion applications/minotari_app_grpc/Cargo.toml
Expand Up @@ -23,10 +23,12 @@ log = "0.4"
prost = "0.9"
prost-types = "0.9"
rand = "0.8"
rcgen = "0.11.3"
subtle = { version = "2.5.0", features = ["core_hint_black_box"] }
thiserror = "1"
tokio = "1.23"
tonic = "0.6.2"
zeroize = "1"
subtle = { version = "2.5.0", features = ["core_hint_black_box"] }

[build-dependencies]
tonic-build = "0.6.2"
Expand Down
2 changes: 2 additions & 0 deletions applications/minotari_app_grpc/src/lib.rs
Expand Up @@ -23,6 +23,8 @@ pub mod authentication;

pub mod conversions;

pub mod tls;

pub mod tari_rpc {
tonic::include_proto!("tari.rpc");
}
78 changes: 78 additions & 0 deletions applications/minotari_app_grpc/src/tls/certs.rs
@@ -0,0 +1,78 @@
// Copyright 2023. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::{
fs::File,
io::Write,
path::{Path, PathBuf},
};

use rcgen::{generate_simple_self_signed, Certificate, CertificateParams, DnType, IsCa::Ca};

use crate::tls::error::GrpcTlsError;

pub fn generate_self_signed_certs() -> Result<(String, String, String), GrpcTlsError> {
let subject_alt_names = vec!["localhost".to_string(), "127.0.0.1".to_string(), "0.0.0.0".to_string()];
let mut params = CertificateParams::new(subject_alt_names.clone());
params.distinguished_name.push(DnType::CommonName, "127.0.0.1");
params.is_ca = Ca(rcgen::BasicConstraints::Unconstrained);
let ca = Certificate::from_params(params).unwrap();
let cacert = ca.serialize_pem().unwrap();

let server_cert = generate_simple_self_signed(subject_alt_names).unwrap();

Ok((
cacert,
server_cert.serialize_pem_with_signer(&ca).unwrap(),
server_cert.serialize_private_key_pem(),
))
}

pub fn write_cert_to_disk(dir: PathBuf, filename: &str, data: &String) -> Result<(), GrpcTlsError> {
let path = dir.join(Path::new(filename));
let mut file = File::create(&path)?;
file.write_all(data.as_ref())?;

println!("{:?} written to disk.", path);

Ok(())
}
pub fn print_warning() {
println!(
"⚠️WARNING: The use of self-signed TLS certificates poses a significant security risk. These certificates are \
not issued or verified by a trusted Certificate Authority (CA), making them susceptible to man-in-the-middle \
attacks. When employing self-signed certificates, the encryption provided is compromised, and your data may \
be intercepted or manipulated without detection."
);
println!();
println!(
"It is strongly advised to use certificates issued by reputable CAs to ensure the authenticity and security \
of your connections. Self-signed certificates are suitable for testing purposes only and should never be \
used in a production environment where data integrity and confidentiality are paramount."
);
println!();
println!(
"Please exercise extreme caution and prioritize the use of valid, properly authenticated TLS certificates to \
safeguard your applications and data against potential security threats."
);
println!();
}
35 changes: 35 additions & 0 deletions applications/minotari_app_grpc/src/tls/error.rs
@@ -0,0 +1,35 @@
// Copyright 2023. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::io;

use rcgen::RcgenError;

#[derive(Debug, thiserror::Error)]
pub enum GrpcTlsError {
#[error("Couldn't read file: {0}")]
FileReadError(String),
#[error("Error generating the certificate: {0}")]
CertGenerationError(#[from] RcgenError),
#[error("Error opening or writing the file: {0}")]
IoError(#[from] io::Error),
}

0 comments on commit b80f7e3

Please sign in to comment.