diff --git a/Cargo.lock b/Cargo.lock index 652bc4c..c703f11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2427,6 +2427,7 @@ dependencies = [ "dirs 5.0.0", "flate2", "hex", + "ipnet", "log", "reqwest", "serde", @@ -2748,7 +2749,7 @@ dependencies = [ [[package]] name = "trifid-pki" -version = "0.1.5" +version = "0.1.6" dependencies = [ "ed25519-dalek", "hex", @@ -2757,6 +2758,7 @@ dependencies = [ "quick-protobuf", "rand", "rand_core 0.6.4", + "serde", "sha2", "x25519-dalek", ] diff --git a/tfclient/Cargo.toml b/tfclient/Cargo.toml index 0639ee2..9c21ab1 100644 --- a/tfclient/Cargo.toml +++ b/tfclient/Cargo.toml @@ -8,7 +8,7 @@ description = "An open-source reimplementation of a Defined Networking-compatibl [dependencies] clap = { version = "4.1.10", features = ["derive"] } -trifid-pki = { version = "0.1.5", path = "../trifid-pki" } +trifid-pki = { version = "0.1.6", path = "../trifid-pki", features = ["serde_derive"] } dirs = "5.0.0" log = "0.4.17" simple_logger = "4.1.0" @@ -22,6 +22,8 @@ ctrlc = "3.2.5" reqwest = { version = "0.11.16", features = ["blocking"] } base64 = "0.21.0" chrono = "0.4.24" +ipnet = "2.7.1" + [build-dependencies] serde = { version = "1.0.157", features = ["derive"] } diff --git a/tfclient/src/apiworker.rs b/tfclient/src/apiworker.rs index b749fdf..3eacefe 100644 --- a/tfclient/src/apiworker.rs +++ b/tfclient/src/apiworker.rs @@ -3,6 +3,7 @@ use base64::Engine; use chrono::Local; use log::{error, info, warn}; use url::Url; +use trifid_pki::ca::NebulaCAPool; use trifid_pki::cert::{serialize_ed25519_public, serialize_x25519_public}; use trifid_pki::ed25519_dalek::{SecretKey, SigningKey}; use trifid_pki::rand_core::OsRng; @@ -106,15 +107,34 @@ pub fn apiworker_main(config: TFClientConfig, instance: String, url: String, _tr }; info!("Enrolled with server. Host-ID {} config count {}", resp.data.host_id, resp.data.counter); - info!("NebulaCAPool {}, org {} {}", resp.data.trusted_keys, resp.data.organization.name, resp.data.organization.id); + info!("KeyPool {}, org {} {}", resp.data.trusted_keys, resp.data.organization.name, resp.data.organization.id); info!("Config: {}", resp.data.config); + // Decode the CAPool and config + let key_pool_pem = match base64::engine::general_purpose::STANDARD.decode(resp.data.trusted_keys) { + Ok(p) => p, + Err(e) => { + error!("error with enrollment: {}", e); + continue; + } + }; + + let config = match base64::engine::general_purpose::STANDARD.decode(resp.data.config) { + Ok(p) => p, + Err(e) => { + error!("error with enrollment: {}", e); + continue; + } + }; + let config_str = String::from_utf8(config).unwrap(); + + cdata.host_id = Some(resp.data.host_id); cdata.counter = resp.data.counter as i32; - cdata.ca_pool = Some(resp.data.trusted_keys); + cdata.key_pool = Some(String::from_utf8(key_pool_pem).unwrap()); cdata.org_name = Some(resp.data.organization.name); cdata.org_id = Some(resp.data.organization.id); - cdata.config = Some(resp.data.config); + cdata.config = Some(config_str); // Save vardata match save_cdata(&instance, cdata) { diff --git a/tfclient/src/config.rs b/tfclient/src/config.rs index 1eb41fc..f65831e 100644 --- a/tfclient/src/config.rs +++ b/tfclient/src/config.rs @@ -1,7 +1,11 @@ +use std::collections::HashMap; use std::error::Error; use std::fs; +use std::net::{Ipv4Addr, SocketAddrV4}; +use ipnet::Ipv4Net; use log::{debug, info}; use serde::{Deserialize, Serialize}; +use trifid_pki::ca::NebulaCAPool; use crate::dirs::{get_cdata_dir, get_cdata_file, get_config_dir, get_config_file, get_data_dir}; pub const DEFAULT_PORT: u16 = 8157; @@ -19,7 +23,7 @@ pub struct TFClientData { pub ed_privkey: Option<[u8; 32]>, pub dh_privkey: Option<[u8; 32]>, pub counter: i32, - pub ca_pool: Option, + pub key_pool: Option, pub org_id: Option, pub org_name: Option, pub config: Option @@ -57,7 +61,7 @@ pub fn create_cdata(instance: &str) -> Result<(), Box> { info!("Creating data directory..."); fs::create_dir_all(get_cdata_dir(instance).ok_or("Unable to load data dir")?)?; info!("Copying default data file to config directory..."); - let config = TFClientData { host_id: None, ed_privkey: None, dh_privkey: None, counter: 0, ca_pool: None, org_id: None, org_name: None, config: None }; + let config = TFClientData { host_id: None, ed_privkey: None, dh_privkey: None, counter: 0, key_pool: None, org_id: None, org_name: None, config: None }; let config_str = toml::to_string(&config)?; fs::write(get_cdata_file(instance).ok_or("Unable to load data dir")?, config_str)?; Ok(()) diff --git a/trifid-pki/Cargo.toml b/trifid-pki/Cargo.toml index a6fdb94..4c50a20 100644 --- a/trifid-pki/Cargo.toml +++ b/trifid-pki/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "trifid-pki" -version = "0.1.5" +version = "0.1.6" edition = "2021" description = "A rust implementation of the Nebula PKI system" license = "AGPL-3.0-or-later" @@ -19,4 +19,9 @@ quick-protobuf = "0.8.1" hex = "0.4.3" sha2 = "0.10.6" rand_core = "0.6.4" -rand = "0.8.5" \ No newline at end of file +rand = "0.8.5" +serde = { version = "1", features = ["derive"], optional = true } + +[features] +default = [] +serde_derive = ["serde", "ipnet/serde"] \ No newline at end of file diff --git a/trifid-pki/src/ca.rs b/trifid-pki/src/ca.rs index 66dc20a..d5b3aaf 100644 --- a/trifid-pki/src/ca.rs +++ b/trifid-pki/src/ca.rs @@ -7,9 +7,13 @@ use std::time::SystemTime; use ed25519_dalek::VerifyingKey; use crate::cert::{deserialize_nebula_certificate_from_pem, NebulaCertificate}; +#[cfg(feature = "serde_derive")] +use serde::{Serialize, Deserialize}; + /// A pool of trusted CA certificates, and certificates that should be blocked. /// This is equivalent to the `pki` section in a typical Nebula config.yml. -#[derive(Default)] +#[derive(Default, Clone)] +#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] pub struct NebulaCAPool { /// The list of CA root certificates that should be trusted. pub cas: HashMap, @@ -102,8 +106,9 @@ impl NebulaCAPool { } } -#[derive(Debug)] /// A list of errors that can happen when working with a CA Pool +#[derive(Debug)] +#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] pub enum CaPoolError { /// Tried to add a non-CA cert to the CA pool NotACA, diff --git a/trifid-pki/src/cert.rs b/trifid-pki/src/cert.rs index e328307..c5495e6 100644 --- a/trifid-pki/src/cert.rs +++ b/trifid-pki/src/cert.rs @@ -15,6 +15,9 @@ use crate::ca::NebulaCAPool; use crate::cert_codec::{RawNebulaCertificate, RawNebulaCertificateDetails}; use sha2::Digest; +#[cfg(feature = "serde_derive")] +use serde::{Serialize, Deserialize}; + /// The length, in bytes, of public keys pub const PUBLIC_KEY_LENGTH: i32 = 32; @@ -31,6 +34,7 @@ pub const ED25519_PUBLIC_KEY_BANNER: &str = "NEBULA ED25519 PUBLIC KEY"; /// A Nebula PKI certificate #[derive(Debug, Clone)] +#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] pub struct NebulaCertificate { /// The signed data of this certificate pub details: NebulaCertificateDetails, @@ -40,6 +44,7 @@ pub struct NebulaCertificate { /// The signed details contained in a Nebula PKI certificate #[derive(Debug, Clone)] +#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] pub struct NebulaCertificateDetails { /// The name of the identity this certificate was issued for pub name: String, @@ -63,6 +68,7 @@ pub struct NebulaCertificateDetails { /// A list of errors that can occur parsing certificates #[derive(Debug)] +#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] pub enum CertificateError { /// Attempted to deserialize a certificate from an empty byte array EmptyByteArray, @@ -186,6 +192,7 @@ pub fn deserialize_nebula_certificate(bytes: &[u8]) -> Result