mirror of
https://github.com/nukesor/pueue
synced 2024-10-01 13:34:07 +00:00
Certificate generation
This commit is contained in:
parent
9c292dbe5f
commit
dd44788fc7
49
Cargo.lock
generated
49
Cargo.lock
generated
|
@ -284,12 +284,6 @@ version = "1.3.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0dcbc35f504eb6fc275a6d20e4ebcda18cf50d40ba6fabff8c711fa16cb3b16"
|
||||
|
||||
[[package]]
|
||||
name = "cache-padded"
|
||||
version = "1.1.1"
|
||||
|
@ -988,6 +982,17 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pem"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c220d01f863d13d96ca82359d1e81e64a7c6bf0637bcde7b2349630addf0c6"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"once_cell",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
|
@ -1170,7 +1175,6 @@ dependencies = [
|
|||
"async-trait",
|
||||
"bincode",
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"chrono-english",
|
||||
"clap",
|
||||
|
@ -1187,6 +1191,7 @@ dependencies = [
|
|||
"proptest",
|
||||
"psutil",
|
||||
"rand",
|
||||
"rcgen",
|
||||
"rustls",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
|
@ -1272,6 +1277,18 @@ dependencies = [
|
|||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rcgen"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cb7a2dc0e5307189b6933a61290ff06b65b35bdcaae2b2c50a0c3e355cb118e"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"pem",
|
||||
"ring",
|
||||
"yasna",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
|
@ -1289,6 +1306,15 @@ dependencies = [
|
|||
"rust-argon2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.21"
|
||||
|
@ -1852,3 +1878,12 @@ checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d"
|
|||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yasna"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0de7bff972b4f2a06c85f6d8454b09df153af7e3a4ec2aac81db1b105b684ddb"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
]
|
||||
|
|
14
Cargo.toml
14
Cargo.toml
|
@ -28,10 +28,6 @@ path = "shared/lib.rs"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
async-std = { version = "1", features = ["attributes", "std"] }
|
||||
async-tls = "0.11"
|
||||
async-trait = "0.1"
|
||||
rustls = "0.19"
|
||||
dirs = "3"
|
||||
chrono = { version = "^0.4", features = ["serde"] }
|
||||
chrono-english = "^0.1.0"
|
||||
|
@ -39,9 +35,14 @@ ctrlc = { version = "3", features = ["termination"] }
|
|||
rand = "^0.7"
|
||||
strum = "^0.20"
|
||||
strum_macros = "^0.20"
|
||||
tempfile = "^3"
|
||||
handlebars = "3"
|
||||
|
||||
bytes = "^0.6"
|
||||
async-std = { version = "1", features = ["attributes", "std"] }
|
||||
async-tls = "0.11"
|
||||
async-trait = "0.1"
|
||||
rustls = "0.19"
|
||||
rcgen = "0.8"
|
||||
byteorder = "^1"
|
||||
snap = "1"
|
||||
serde = "^1.0"
|
||||
|
@ -50,14 +51,13 @@ serde_json = "^1.0"
|
|||
serde_yaml = "^0.8"
|
||||
serde_derive = "^1.0"
|
||||
|
||||
log = "0.4"
|
||||
config = { version = "^0.10", default-features = false, features = ["yaml"] }
|
||||
log = "0.4"
|
||||
simplelog = { version = "0.8", default-features = false }
|
||||
clap = "3.0.0-beta.2"
|
||||
clap_generate = "3.0.0-beta.2"
|
||||
crossterm = "^0.18"
|
||||
comfy-table= "^1"
|
||||
tempfile = "^3"
|
||||
|
||||
[target.'cfg(not(windows))'.dependencies]
|
||||
users = "^0.11"
|
||||
|
|
|
@ -8,6 +8,7 @@ use anyhow::Result;
|
|||
use clap::Clap;
|
||||
use simplelog::{Config, LevelFilter, SimpleLogger};
|
||||
|
||||
use pueue::network::certificate::create_certificates;
|
||||
use pueue::network::message::Message;
|
||||
use pueue::network::secret::init_shared_secret;
|
||||
use pueue::settings::Settings;
|
||||
|
@ -60,6 +61,9 @@ async fn main() -> Result<()> {
|
|||
};
|
||||
|
||||
init_directories(&settings.shared.pueue_directory);
|
||||
if !settings.shared.daemon_key.exists() && !settings.shared.daemon_cert.exists() {
|
||||
create_certificates(&settings)?;
|
||||
}
|
||||
init_shared_secret(&settings.shared.shared_secret_path)?;
|
||||
|
||||
let state = State::new(&settings, opt.config.clone());
|
||||
|
@ -127,6 +131,17 @@ fn init_directories(pueue_dir: &PathBuf) {
|
|||
}
|
||||
}
|
||||
|
||||
// Task certs dir
|
||||
let certs_dir = pueue_dir.join("certs");
|
||||
if !certs_dir.exists() {
|
||||
if let Err(error) = create_dir_all(&certs_dir) {
|
||||
panic!(
|
||||
"Failed to create certificate directory at {:?} error: {:?}",
|
||||
certs_dir, error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Task log dir
|
||||
let logs_dir = pueue_dir.join("task_logs");
|
||||
if !logs_dir.exists() {
|
||||
|
|
52
shared/network/certificate.rs
Normal file
52
shared/network/certificate.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use std::{fs::File, io::Write, path::PathBuf};
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use log::info;
|
||||
use rcgen::generate_simple_self_signed;
|
||||
|
||||
use crate::settings::Settings;
|
||||
|
||||
/// This the default certificates at the default `pueue_dir/certs` location.
|
||||
pub fn create_certificates(settings: &Settings) -> Result<()> {
|
||||
let certs_dir = settings.shared.pueue_directory.join("certs");
|
||||
|
||||
let daemon_cert_path = certs_dir.join("daemon.cert");
|
||||
let daemon_key_path = certs_dir.join("daemon.key");
|
||||
|
||||
if daemon_key_path.exists() || daemon_cert_path.exists() {
|
||||
if !(daemon_key_path.exists() && daemon_cert_path.exists()) {
|
||||
bail!(
|
||||
"Not all default certificates exist, some are missing. \
|
||||
Please fix your cert/key paths.\n \
|
||||
You can also remove the `$pueue_directory/certs` directory \
|
||||
and restart the daemon to create new certificates/keys."
|
||||
);
|
||||
}
|
||||
info!("All default keys do exist.");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let subject_alt_names = vec!["pueue.local".to_string(), "localhost".to_string()];
|
||||
|
||||
let cert = generate_simple_self_signed(subject_alt_names).unwrap();
|
||||
// The certificate is now valid for localhost and the domain "hello.world.example"
|
||||
let ca_cert = cert
|
||||
.serialize_pem()
|
||||
.context("Failed to serialize daemon certificate.")?;
|
||||
write_file(ca_cert, "daemon cert", &daemon_cert_path)?;
|
||||
|
||||
let ca_key = cert.serialize_private_key_pem();
|
||||
write_file(ca_key, "daemon key", &daemon_key_path)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_file(blob: String, name: &str, path: &PathBuf) -> Result<()> {
|
||||
info!("Generate {}.", name);
|
||||
let error_message = format!("Cannot write default {}: {:?}", name, path);
|
||||
let mut file = File::create(path).context(error_message.clone())?;
|
||||
|
||||
file.write_all(&blob.into_bytes()).context(error_message)?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
pub mod certificate;
|
||||
pub mod message;
|
||||
pub mod protocol;
|
||||
pub mod secret;
|
||||
|
|
|
@ -3,10 +3,10 @@ use std::io::{BufReader, Cursor};
|
|||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{anyhow, Context, Error, Result};
|
||||
use anyhow::{anyhow, bail, Context, Error, Result};
|
||||
use async_tls::{TlsAcceptor, TlsConnector};
|
||||
use rustls::{
|
||||
internal::pemfile::{certs, rsa_private_keys},
|
||||
internal::pemfile::{certs, pkcs8_private_keys, rsa_private_keys},
|
||||
NoClientAuth,
|
||||
};
|
||||
use rustls::{Certificate, ClientConfig, PrivateKey, ServerConfig};
|
||||
|
@ -20,7 +20,7 @@ pub async fn get_tls_connector(settings: &Settings) -> Result<TlsConnector> {
|
|||
let mut config = ClientConfig::new();
|
||||
|
||||
// Trust server-certificates signed with our own CA.
|
||||
let mut ca = load_ca(&settings.shared.ca_cert)?;
|
||||
let mut ca = load_ca(&settings.shared.daemon_cert)?;
|
||||
config
|
||||
.root_store
|
||||
.add_pem_file(&mut ca)
|
||||
|
@ -40,6 +40,13 @@ pub fn get_tls_listener(settings: &Settings) -> Result<TlsAcceptor> {
|
|||
// Set the server-side key and certificate that should be used for any communication
|
||||
let certs = load_certs(&settings.shared.daemon_cert)?;
|
||||
let mut keys = load_keys(&settings.shared.daemon_key)?;
|
||||
if keys.is_empty() {
|
||||
bail!(
|
||||
"Couldn't extract private key from keyfile {:?}",
|
||||
&settings.shared.daemon_key
|
||||
);
|
||||
}
|
||||
|
||||
config
|
||||
// set this server to use one cert together with the loaded private key
|
||||
.set_single_cert(certs, keys.remove(0))
|
||||
|
@ -58,6 +65,15 @@ fn load_certs(path: &Path) -> Result<Vec<Certificate>> {
|
|||
/// Load the passed keys file
|
||||
fn load_keys(path: &Path) -> Result<Vec<PrivateKey>> {
|
||||
let file = File::open(path).context(format!("Cannot open key {:?}", path))?;
|
||||
// Try to read pkcs8 format first
|
||||
let keys = pkcs8_private_keys(&mut BufReader::new(&file))
|
||||
.map_err(|_| anyhow!("Failed to parse daemon key."))?;
|
||||
|
||||
if !keys.is_empty() {
|
||||
return Ok(keys);
|
||||
}
|
||||
|
||||
// Try the normal rsa format afterwards.
|
||||
rsa_private_keys(&mut BufReader::new(file)).map_err(|_| anyhow!("Failed to parse daemon key."))
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ pub struct Shared {
|
|||
pub unix_socket_path: PathBuf,
|
||||
|
||||
pub port: String,
|
||||
pub ca_cert: PathBuf,
|
||||
pub daemon_cert: PathBuf,
|
||||
pub daemon_key: PathBuf,
|
||||
pub shared_secret_path: PathBuf,
|
||||
|
@ -66,7 +65,6 @@ impl Settings {
|
|||
|
||||
config.set_default("shared.port", "6924")?;
|
||||
config.set_default("shared.tls_enabled", true)?;
|
||||
config.set_default("shared.ca_cert", pueue_path.clone() + "/certs/ca.cert")?;
|
||||
config.set_default(
|
||||
"shared.daemon_key",
|
||||
pueue_path.clone() + "/certs/daemon.key",
|
||||
|
|
Loading…
Reference in a new issue