cert signing tests
This commit is contained in:
parent
020abccf79
commit
33ba674073
|
@ -555,6 +555,7 @@ checksum = "7bd577ba9d4bcab443cac60003d8fd32c638e7024a3ec92c200d7af5d2c397ed"
|
|||
dependencies = [
|
||||
"curve25519-dalek 4.0.0-rc.1",
|
||||
"ed25519",
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"sha2",
|
||||
"zeroize",
|
||||
|
@ -2425,6 +2426,8 @@ dependencies = [
|
|||
"ipnet",
|
||||
"pem",
|
||||
"quick-protobuf",
|
||||
"rand",
|
||||
"rand_core 0.6.4",
|
||||
"sha2",
|
||||
"x25519-dalek",
|
||||
]
|
||||
|
|
|
@ -9,8 +9,10 @@ description = "A rust implementation of the Nebula PKI system"
|
|||
[dependencies]
|
||||
pem = "1.1.1"
|
||||
x25519-dalek = "2.0.0-pre.1"
|
||||
ed25519-dalek = "2.0.0-pre.0"
|
||||
ed25519-dalek = { version = "2.0.0-pre.0", features = ["rand_core", "alloc"] }
|
||||
ipnet = "2.7.1"
|
||||
quick-protobuf = "0.8.1"
|
||||
hex = "0.4.3"
|
||||
sha2 = "0.10.6"
|
||||
sha2 = "0.10.6"
|
||||
rand_core = "0.6.4"
|
||||
rand = "0.8.5"
|
|
@ -3,6 +3,7 @@
|
|||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::time::SystemTime;
|
||||
use ed25519_dalek::VerifyingKey;
|
||||
use crate::cert::{deserialize_nebula_certificate_from_pem, NebulaCertificate};
|
||||
|
||||
|
@ -55,10 +56,25 @@ impl NebulaCAPool {
|
|||
}
|
||||
|
||||
if !cert.check_signature(&VerifyingKey::from_bytes(&cert.details.public_key)?)? {
|
||||
|
||||
return Err(CaPoolError::NotSelfSigned.into())
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
let fingerprint = cert.sha256sum()?;
|
||||
let expired = cert.expired(SystemTime::now());
|
||||
|
||||
self.cas.insert(fingerprint, cert);
|
||||
|
||||
Ok(expired)
|
||||
}
|
||||
|
||||
/// Blocklist the given certificate in the CA pool
|
||||
pub fn blocklist_fingerprint(&mut self, fingerprint: &str) {
|
||||
self.cert_blocklist.push(fingerprint.to_string());
|
||||
}
|
||||
|
||||
/// Clears the list of blocklisted fingerprints
|
||||
pub fn reset_blocklist(&mut self) {
|
||||
self.cert_blocklist = vec![];
|
||||
}
|
||||
|
||||
/// Checks if the given certificate is blocklisted
|
||||
|
@ -77,6 +93,11 @@ impl NebulaCAPool {
|
|||
|
||||
Ok(self.cas.get(&cert.details.issuer))
|
||||
}
|
||||
|
||||
/// Get a list of trusted CA fingerprints
|
||||
pub fn get_fingerprints(&self) -> Vec<&String> {
|
||||
self.cas.keys().collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -7,7 +7,6 @@ use std::net::Ipv4Addr;
|
|||
use std::ops::Add;
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
|
||||
use ed25519_dalek::ed25519::pkcs8::spki::der::Encode;
|
||||
use ipnet::{Ipv4Net};
|
||||
use pem::Pem;
|
||||
use quick_protobuf::{BytesReader, MessageRead, MessageWrite, Writer};
|
||||
|
@ -294,14 +293,9 @@ impl NebulaCertificate {
|
|||
pub fn sign(&mut self, key: &SigningKey) -> Result<(), Box<dyn Error>> {
|
||||
let mut out = Vec::new();
|
||||
let mut writer = Writer::new(&mut out);
|
||||
writer.write_message(&self.get_raw_details())?;
|
||||
self.get_raw_details().write_message(&mut writer)?;
|
||||
|
||||
let sig = key.sign(&out).to_bytes();
|
||||
|
||||
self.signature = match sig.to_vec() {
|
||||
Ok(v) => v,
|
||||
Err(_) => return Err("signature error".into())
|
||||
};
|
||||
self.signature = key.sign(&out).to_vec();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -311,9 +305,11 @@ impl NebulaCertificate {
|
|||
pub fn check_signature(&self, key: &VerifyingKey) -> Result<bool, Box<dyn Error>> {
|
||||
let mut out = Vec::new();
|
||||
let mut writer = Writer::new(&mut out);
|
||||
writer.write_message(&self.get_raw_details())?;
|
||||
self.get_raw_details().write_message(&mut writer)?;
|
||||
|
||||
Ok(key.verify(&out, &Signature::try_from(&*self.signature)?).is_ok())
|
||||
let sig = Signature::from_slice(&self.signature)?;
|
||||
|
||||
Ok(key.verify(&out, &sig).is_ok())
|
||||
}
|
||||
|
||||
/// Returns true if the signature is too young or too old compared to the provided time
|
||||
|
|
|
@ -8,6 +8,8 @@ use std::time::{Duration, SystemTime, SystemTimeError, UNIX_EPOCH};
|
|||
use ipnet::Ipv4Net;
|
||||
use crate::cert::{deserialize_nebula_certificate, NebulaCertificate, NebulaCertificateDetails};
|
||||
use std::str::FromStr;
|
||||
use ed25519_dalek::{SigningKey};
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
/// This is a cert that we (e3team) actually use in production, and it's a known-good certificate.
|
||||
pub const KNOWN_GOOD_CERT: &[u8; 258] = b"-----BEGIN NEBULA CERTIFICATE-----\nCkkKF2UzdGVhbSBJbnRlcm5hbCBOZXR3b3JrKJWev5wGMJWFxKsGOiCvpwoHyKY5\n8Q5+2XxDjtoCf/zlNY/EUdB8bwXQSwEo50ABEkB0Dx76lkMqc3IyH5+ml2dKjTyv\nB4Jiw6x3abf5YZcf8rDuVEgQpvFdJmo3xJyIb3C9vKZ6kXsUxjw6s1JdWgkA\n-----END NEBULA CERTIFICATE-----";
|
||||
|
@ -68,6 +70,43 @@ fn certificate_serialization() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cert_signing() {
|
||||
let before = round_systime_to_secs(SystemTime::now() - Duration::from_secs(60)).unwrap();
|
||||
let after = round_systime_to_secs(SystemTime::now() + Duration::from_secs(60)).unwrap();
|
||||
let pub_key = b"1234567890abcedfghij1234567890ab";
|
||||
|
||||
let mut cert = NebulaCertificate {
|
||||
details: NebulaCertificateDetails {
|
||||
name: "testing".to_string(),
|
||||
ips: vec![
|
||||
netmask!("10.1.1.1", "255.255.255.0"),
|
||||
netmask!("10.1.1.2", "255.255.0.0"),
|
||||
netmask!("10.1.1.3", "255.0.0.0")
|
||||
],
|
||||
subnets: vec![
|
||||
netmask!("9.1.1.1", "255.255.255.128"),
|
||||
netmask!("9.1.1.2", "255.255.255.0"),
|
||||
netmask!("9.1.1.3", "255.255.0.0")
|
||||
],
|
||||
groups: vec!["test-group1".to_string(), "test-group2".to_string(), "test-group3".to_string()],
|
||||
not_before: before,
|
||||
not_after: after,
|
||||
public_key: *pub_key,
|
||||
is_ca: false,
|
||||
issuer: "1234567890abcedfabcd1234567890ab".to_string(),
|
||||
},
|
||||
signature: b"1234567890abcedfghij1234567890ab".to_vec(),
|
||||
};
|
||||
|
||||
let mut csprng = OsRng;
|
||||
let key = SigningKey::generate(&mut csprng);
|
||||
|
||||
assert!(cert.check_signature(&key.verifying_key()).is_err());
|
||||
cert.sign(&key).unwrap();
|
||||
assert!(cert.check_signature(&key.verifying_key()).unwrap());
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! netmask {
|
||||
($ip:expr,$mask:expr) => {
|
||||
|
|
Loading…
Reference in New Issue