hightower-node 0.1.0

Hightower node service
Documentation
use hightower_wireguard::crypto::{PrivateKey, PublicKey25519, dh_generate};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct NodeCertificate {
    #[serde(with = "serde_bytes")]
    private_key: PrivateKey,
    #[serde(with = "serde_bytes")]
    public_key: PublicKey25519,
}

impl NodeCertificate {
    pub fn from_keys(private_key: PrivateKey, public_key: PublicKey25519) -> Self {
        Self {
            private_key,
            public_key,
        }
    }

    #[cfg_attr(not(test), allow(dead_code))]
    pub fn private_key(&self) -> &PrivateKey {
        &self.private_key
    }

    #[cfg_attr(not(test), allow(dead_code))]
    pub fn public_key(&self) -> &PublicKey25519 {
        &self.public_key
    }

    pub fn private_key_hex(&self) -> String {
        hex::encode(self.private_key)
    }

    pub fn public_key_hex(&self) -> String {
        hex::encode(self.public_key)
    }
}

pub fn generate() -> NodeCertificate {
    let (private_key, public_key) = dh_generate();
    NodeCertificate::from_keys(private_key, public_key)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn from_keys_stores_values() {
        let private_key = [1u8; 32];
        let public_key = [2u8; 32];

        let cert = NodeCertificate::from_keys(private_key, public_key);

        assert_eq!(cert.private_key(), &private_key);
        assert_eq!(cert.public_key(), &public_key);
    }

    #[test]
    fn private_key_hex_encodes_key() {
        let private_key = [0xAAu8; 32];
        let public_key = [0u8; 32];
        let cert = NodeCertificate::from_keys(private_key, public_key);

        assert_eq!(
            cert.private_key_hex(),
            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        );
    }

    #[test]
    fn public_key_hex_encodes_key() {
        let private_key = [0u8; 32];
        let public_key = [0xBBu8; 32];
        let cert = NodeCertificate::from_keys(private_key, public_key);

        assert_eq!(
            cert.public_key_hex(),
            "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
        );
    }

    #[test]
    fn generate_returns_random_keys() {
        let cert = generate();

        assert_eq!(cert.private_key().len(), 32);
        assert_eq!(cert.public_key().len(), 32);
        assert_eq!(cert.private_key_hex().len(), 64);
        assert_eq!(cert.public_key_hex().len(), 64);
    }

    #[test]
    fn serde_round_trip_preserves_data() {
        let cert = NodeCertificate::from_keys([3u8; 32], [4u8; 32]);
        let bytes = serde_json::to_vec(&cert).expect("serialize");
        let decoded: NodeCertificate = serde_json::from_slice(&bytes).expect("deserialize");
        assert_eq!(decoded, cert);
    }
}