code cleanup
This commit is contained in:
parent
130aabad38
commit
4f9563755a
|
@ -1,8 +1,8 @@
|
|||
use std::collections::HashMap;
|
||||
use crate::pki::{EPFCertificate, EpfPublicKey};
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct EpfCaPool {
|
||||
pub ca_lookup_table: HashMap<EpfPublicKey, EPFCertificate>
|
||||
pub ca_lookup_table: HashMap<EpfPublicKey, EPFCertificate>,
|
||||
}
|
||||
|
||||
pub trait EpfCaPoolOps {
|
||||
|
@ -14,7 +14,7 @@ pub trait EpfCaPoolOps {
|
|||
impl EpfCaPoolOps for EpfCaPool {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
ca_lookup_table: HashMap::new()
|
||||
ca_lookup_table: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ impl EpfCaPoolOps for EpfCaPool {
|
|||
}
|
||||
|
||||
fn insert(&mut self, cert: &EPFCertificate) {
|
||||
self.ca_lookup_table.insert(cert.details.public_key, cert.clone());
|
||||
self.ca_lookup_table
|
||||
.insert(cert.details.public_key, cert.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
pub mod ca_pool;
|
||||
pub mod pki;
|
||||
pub mod util;
|
||||
pub mod ca_pool;
|
|
@ -1,18 +1,19 @@
|
|||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::time::{SystemTime};
|
||||
use crate::ca_pool::{EpfCaPool, EpfCaPoolOps};
|
||||
use crate::util::{pretty_print_date, u64_to_st};
|
||||
use ed25519_dalek::{Signature, SignatureError, Signer, SigningKey, Verifier, VerifyingKey};
|
||||
use pem::Pem;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use crate::ca_pool::{EpfCaPool, EpfCaPoolOps};
|
||||
use crate::util::{pretty_print_date, u64_to_st};
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::time::SystemTime;
|
||||
|
||||
pub const EPFPKI_PUBLIC_KEY_LENGTH: usize = 32;
|
||||
pub const EPFPKI_SIGNATURE_LENGTH: usize = 64;
|
||||
|
||||
pub const EPFPKI_SELF_SIGNED_CERTIFICATE: &str = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
pub const EPFPKI_SELF_SIGNED_CERTIFICATE: &str =
|
||||
"0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
pub type EpfPublicKey = [u8; 32];
|
||||
pub type EpfPrivateKey = [u8; 64];
|
||||
|
@ -22,7 +23,7 @@ pub struct EPFCertificate {
|
|||
pub details: EPFCertificateDetails,
|
||||
pub fingerprint: String,
|
||||
#[serde(with = "serde_arrays")]
|
||||
pub signature: [u8; EPFPKI_SIGNATURE_LENGTH]
|
||||
pub signature: [u8; EPFPKI_SIGNATURE_LENGTH],
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Eq, Clone)]
|
||||
|
@ -36,17 +37,21 @@ pub struct EPFCertificateDetails {
|
|||
|
||||
pub issuer_public_key: [u8; EPFPKI_PUBLIC_KEY_LENGTH],
|
||||
|
||||
pub claims: HashMap<String, String>
|
||||
pub claims: HashMap<String, String>,
|
||||
}
|
||||
|
||||
pub trait EpfPkiSerializable {
|
||||
const PEM_BANNER: &'static str;
|
||||
|
||||
fn as_bytes(&self) -> Result<Vec<u8>, rmp_serde::encode::Error>;
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self, rmp_serde::decode::Error> where Self: Sized;
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self, rmp_serde::decode::Error>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
fn as_pem(&self) -> Result<Vec<u8>, Box<dyn Error>>;
|
||||
fn from_pem(bytes: &[u8]) -> Result<Self, Box<dyn Error>> where Self: Sized;
|
||||
fn from_pem(bytes: &[u8]) -> Result<Self, Box<dyn Error>>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
pub fn fingerprint(cert: &EPFCertificateDetails) -> Result<String, rmp_serde::encode::Error> {
|
||||
|
@ -69,20 +74,41 @@ pub enum EpfPkiCertificateValidationError {
|
|||
FingerprintDoesNotMatch { expected: String, got: String },
|
||||
InvalidSignature { e: SignatureError },
|
||||
ExpiresAfterSigner,
|
||||
ValidAfterSigner
|
||||
ValidAfterSigner,
|
||||
}
|
||||
|
||||
impl Display for EpfPkiCertificateValidationError {
|
||||
#[cfg_attr(tarpaulin, ignore)]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
EpfPkiCertificateValidationError::NoLongerValid { expired_at } => write!(f, "Certificate no longer valid (expired at {})", pretty_print_date(expired_at)),
|
||||
EpfPkiCertificateValidationError::NotValidYet { valid_at } => write!(f, "Certificate not valid yet (valid at {})", pretty_print_date(valid_at)),
|
||||
EpfPkiCertificateValidationError::InvalidCertificateData { e } => write!(f, "Unable to serialize cert data: {}", e),
|
||||
EpfPkiCertificateValidationError::FingerprintDoesNotMatch { expected, got } => write!(f, "Fingerprint mismatch (expected {}, got {})", expected, got),
|
||||
EpfPkiCertificateValidationError::InvalidSignature { e } => write!(f, "Certificate validation error: {}", e),
|
||||
EpfPkiCertificateValidationError::ExpiresAfterSigner => write!(f, "Certificate expires after it's signing certificate"),
|
||||
EpfPkiCertificateValidationError::ValidAfterSigner => write!(f, "Certificate is valid longer than it's signing certificate")
|
||||
EpfPkiCertificateValidationError::NoLongerValid { expired_at } => write!(
|
||||
f,
|
||||
"Certificate no longer valid (expired at {})",
|
||||
pretty_print_date(expired_at)
|
||||
),
|
||||
EpfPkiCertificateValidationError::NotValidYet { valid_at } => write!(
|
||||
f,
|
||||
"Certificate not valid yet (valid at {})",
|
||||
pretty_print_date(valid_at)
|
||||
),
|
||||
EpfPkiCertificateValidationError::InvalidCertificateData { e } => {
|
||||
write!(f, "Unable to serialize cert data: {}", e)
|
||||
}
|
||||
EpfPkiCertificateValidationError::FingerprintDoesNotMatch { expected, got } => write!(
|
||||
f,
|
||||
"Fingerprint mismatch (expected {}, got {})",
|
||||
expected, got
|
||||
),
|
||||
EpfPkiCertificateValidationError::InvalidSignature { e } => {
|
||||
write!(f, "Certificate validation error: {}", e)
|
||||
}
|
||||
EpfPkiCertificateValidationError::ExpiresAfterSigner => {
|
||||
write!(f, "Certificate expires after it's signing certificate")
|
||||
}
|
||||
EpfPkiCertificateValidationError::ValidAfterSigner => write!(
|
||||
f,
|
||||
"Certificate is valid longer than it's signing certificate"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +116,11 @@ impl Display for EpfPkiCertificateValidationError {
|
|||
pub trait EpfPkiCertificateOps {
|
||||
fn recalculate_fingerprint(&mut self) -> Result<(), rmp_serde::encode::Error>;
|
||||
fn sign(&mut self, private_key: &EpfPrivateKey) -> Result<(), Box<dyn Error>>;
|
||||
fn verify_with_time(&self, time: SystemTime, ca_pool: &EpfCaPool) -> Result<bool, EpfPkiCertificateValidationError>;
|
||||
fn verify_with_time(
|
||||
&self,
|
||||
time: SystemTime,
|
||||
ca_pool: &EpfCaPool,
|
||||
) -> Result<bool, EpfPkiCertificateValidationError>;
|
||||
fn verify(&self, ca_pool: &EpfCaPool) -> Result<bool, EpfPkiCertificateValidationError>;
|
||||
}
|
||||
impl EpfPkiCertificateOps for EPFCertificate {
|
||||
|
@ -116,43 +146,64 @@ impl EpfPkiCertificateOps for EPFCertificate {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn verify_with_time(&self, time: SystemTime, ca_pool: &EpfCaPool) -> Result<bool, EpfPkiCertificateValidationError> {
|
||||
fn verify_with_time(
|
||||
&self,
|
||||
time: SystemTime,
|
||||
ca_pool: &EpfCaPool,
|
||||
) -> Result<bool, EpfPkiCertificateValidationError> {
|
||||
// Is it expired
|
||||
if u64_to_st(self.details.not_after) < time {
|
||||
return Err(EpfPkiCertificateValidationError::NoLongerValid {expired_at: u64_to_st(self.details.not_after)})
|
||||
return Err(EpfPkiCertificateValidationError::NoLongerValid {
|
||||
expired_at: u64_to_st(self.details.not_after),
|
||||
});
|
||||
}
|
||||
|
||||
// Is it valid yet
|
||||
if u64_to_st(self.details.not_before) > time {
|
||||
return Err(EpfPkiCertificateValidationError::NotValidYet {valid_at: u64_to_st(self.details.not_before)})
|
||||
return Err(EpfPkiCertificateValidationError::NotValidYet {
|
||||
valid_at: u64_to_st(self.details.not_before),
|
||||
});
|
||||
}
|
||||
|
||||
let fingerprint_on_cert = fingerprint(&self.details).map_err(|e| EpfPkiCertificateValidationError::InvalidCertificateData { e })?;
|
||||
let fingerprint_on_cert = fingerprint(&self.details)
|
||||
.map_err(|e| EpfPkiCertificateValidationError::InvalidCertificateData { e })?;
|
||||
|
||||
// Does the fingerprint match
|
||||
if fingerprint_on_cert != self.fingerprint {
|
||||
return Err(EpfPkiCertificateValidationError::FingerprintDoesNotMatch { expected: self.fingerprint.clone(), got: fingerprint_on_cert})
|
||||
return Err(EpfPkiCertificateValidationError::FingerprintDoesNotMatch {
|
||||
expected: self.fingerprint.clone(),
|
||||
got: fingerprint_on_cert,
|
||||
});
|
||||
}
|
||||
|
||||
// Does the signature match
|
||||
let signature = Signature::from_slice(&self.signature).map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })?;
|
||||
let signature = Signature::from_slice(&self.signature)
|
||||
.map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })?;
|
||||
|
||||
let is_self_signed;
|
||||
|
||||
println!("{}: {:?} {:?}", self.details.name, self.details.issuer_public_key, self.details.public_key);
|
||||
println!(
|
||||
"{}: {:?} {:?}",
|
||||
self.details.name, self.details.issuer_public_key, self.details.public_key
|
||||
);
|
||||
|
||||
let verifying_key = if self.details.issuer_public_key == self.details.public_key {
|
||||
// self-signed certificate
|
||||
is_self_signed = true;
|
||||
VerifyingKey::from_bytes(&self.details.public_key).map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })?
|
||||
VerifyingKey::from_bytes(&self.details.public_key)
|
||||
.map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })?
|
||||
} else {
|
||||
is_self_signed = false;
|
||||
VerifyingKey::from_bytes(&self.details.issuer_public_key).map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })?
|
||||
VerifyingKey::from_bytes(&self.details.issuer_public_key)
|
||||
.map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })?
|
||||
};
|
||||
|
||||
let cert_data_bytes = rmp_serde::to_vec(&self.details).map_err(|e| EpfPkiCertificateValidationError::InvalidCertificateData { e })?;
|
||||
let cert_data_bytes = rmp_serde::to_vec(&self.details)
|
||||
.map_err(|e| EpfPkiCertificateValidationError::InvalidCertificateData { e })?;
|
||||
|
||||
verifying_key.verify(&cert_data_bytes, &signature).map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })?;
|
||||
verifying_key
|
||||
.verify(&cert_data_bytes, &signature)
|
||||
.map_err(|e| EpfPkiCertificateValidationError::InvalidSignature { e })?;
|
||||
|
||||
// Signature OK
|
||||
|
||||
|
@ -164,7 +215,7 @@ impl EpfPkiCertificateOps for EPFCertificate {
|
|||
return Ok(false);
|
||||
}
|
||||
} else if let Some(cert) = ca_pool.get_ca(&self.details.issuer_public_key) {
|
||||
cert
|
||||
cert
|
||||
} else {
|
||||
return Ok(false);
|
||||
};
|
||||
|
@ -175,7 +226,7 @@ impl EpfPkiCertificateOps for EPFCertificate {
|
|||
}
|
||||
// Make sure this cert isnt valid after the root
|
||||
if ca_cert.details.not_before > self.details.not_before {
|
||||
return Err(EpfPkiCertificateValidationError::ValidAfterSigner)
|
||||
return Err(EpfPkiCertificateValidationError::ValidAfterSigner);
|
||||
}
|
||||
|
||||
// Cert OK
|
||||
|
@ -194,10 +245,26 @@ impl Display for EPFCertificate {
|
|||
writeln!(f, "EPFCertificate {{")?;
|
||||
writeln!(f, "\tDetails: {{")?;
|
||||
writeln!(f, "\t\tName: {}", self.details.name)?;
|
||||
writeln!(f, "\t\tNot Before: {}", pretty_print_date(&u64_to_st(self.details.not_before)))?;
|
||||
writeln!(f, "\t\tNot After: {}", pretty_print_date(&u64_to_st(self.details.not_after)))?;
|
||||
writeln!(f, "\t\tPublic Key: {}", hex::encode(self.details.public_key))?;
|
||||
writeln!(f, "\t\tIssuer Fingerprint: {}", hex::encode(self.details.issuer_public_key))?;
|
||||
writeln!(
|
||||
f,
|
||||
"\t\tNot Before: {}",
|
||||
pretty_print_date(&u64_to_st(self.details.not_before))
|
||||
)?;
|
||||
writeln!(
|
||||
f,
|
||||
"\t\tNot After: {}",
|
||||
pretty_print_date(&u64_to_st(self.details.not_after))
|
||||
)?;
|
||||
writeln!(
|
||||
f,
|
||||
"\t\tPublic Key: {}",
|
||||
hex::encode(self.details.public_key)
|
||||
)?;
|
||||
writeln!(
|
||||
f,
|
||||
"\t\tIssuer Fingerprint: {}",
|
||||
hex::encode(self.details.issuer_public_key)
|
||||
)?;
|
||||
writeln!(f, "\t}}")?;
|
||||
writeln!(f, "\tFingerprint: {}", self.fingerprint)?;
|
||||
writeln!(f, "\tSignature: {}", hex::encode(self.signature))?;
|
||||
|
@ -217,13 +284,18 @@ impl EpfPkiSerializable for EPFCertificate {
|
|||
}
|
||||
|
||||
fn as_pem(&self) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||
Ok(pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes()?)).as_bytes().to_vec())
|
||||
Ok(pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes()?))
|
||||
.as_bytes()
|
||||
.to_vec())
|
||||
}
|
||||
|
||||
fn from_pem(bytes: &[u8]) -> Result<Self, Box<dyn Error>> where Self: Sized {
|
||||
fn from_pem(bytes: &[u8]) -> Result<Self, Box<dyn Error>>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let pem = pem::parse(bytes)?;
|
||||
if pem.tag() != Self::PEM_BANNER {
|
||||
return Err("Not a certificate".into())
|
||||
return Err("Not a certificate".into());
|
||||
}
|
||||
Ok(Self::from_bytes(pem.contents())?)
|
||||
}
|
||||
|
@ -237,17 +309,24 @@ impl EpfPkiSerializable for EpfPublicKey {
|
|||
}
|
||||
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self, rmp_serde::decode::Error> {
|
||||
bytes.try_into().map_err(|_| rmp_serde::decode::Error::LengthMismatch(bytes.len() as u32))
|
||||
bytes
|
||||
.try_into()
|
||||
.map_err(|_| rmp_serde::decode::Error::LengthMismatch(bytes.len() as u32))
|
||||
}
|
||||
|
||||
fn as_pem(&self) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||
Ok(pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes()?)).as_bytes().to_vec())
|
||||
Ok(pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes()?))
|
||||
.as_bytes()
|
||||
.to_vec())
|
||||
}
|
||||
|
||||
fn from_pem(bytes: &[u8]) -> Result<Self, Box<dyn Error>> where Self: Sized {
|
||||
fn from_pem(bytes: &[u8]) -> Result<Self, Box<dyn Error>>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let pem = pem::parse(bytes)?;
|
||||
if pem.tag() != Self::PEM_BANNER {
|
||||
return Err("Not a public key".into())
|
||||
return Err("Not a public key".into());
|
||||
}
|
||||
Ok(Self::from_bytes(pem.contents())?)
|
||||
}
|
||||
|
@ -261,17 +340,24 @@ impl EpfPkiSerializable for EpfPrivateKey {
|
|||
}
|
||||
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self, rmp_serde::decode::Error> {
|
||||
bytes.try_into().map_err(|_| rmp_serde::decode::Error::LengthMismatch(bytes.len() as u32))
|
||||
bytes
|
||||
.try_into()
|
||||
.map_err(|_| rmp_serde::decode::Error::LengthMismatch(bytes.len() as u32))
|
||||
}
|
||||
|
||||
fn as_pem(&self) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||
Ok(pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes()?)).as_bytes().to_vec())
|
||||
Ok(pem::encode(&Pem::new(Self::PEM_BANNER, self.as_bytes()?))
|
||||
.as_bytes()
|
||||
.to_vec())
|
||||
}
|
||||
|
||||
fn from_pem(bytes: &[u8]) -> Result<Self, Box<dyn Error>> where Self: Sized {
|
||||
fn from_pem(bytes: &[u8]) -> Result<Self, Box<dyn Error>>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let pem = pem::parse(bytes)?;
|
||||
if pem.tag() != Self::PEM_BANNER {
|
||||
return Err("Incorrect PEM tag".into())
|
||||
return Err("Incorrect PEM tag".into());
|
||||
}
|
||||
Ok(Self::from_bytes(pem.contents())?)
|
||||
}
|
||||
|
@ -279,12 +365,16 @@ impl EpfPkiSerializable for EpfPrivateKey {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::HashMap;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use crate::ca_pool::{EpfCaPool, EpfCaPoolOps};
|
||||
use crate::pki::{
|
||||
EPFCertificate, EPFCertificateDetails, EpfPkiCertificateOps,
|
||||
EpfPkiCertificateValidationError, EpfPkiSerializable, EpfPrivateKey, EpfPublicKey,
|
||||
EPFPKI_PUBLIC_KEY_LENGTH, EPFPKI_SIGNATURE_LENGTH,
|
||||
};
|
||||
use ed25519_dalek::{SignatureError, SigningKey};
|
||||
use rand::rngs::OsRng;
|
||||
use crate::ca_pool::{EpfCaPool, EpfCaPoolOps};
|
||||
use crate::pki::{EPFCertificate, EPFCertificateDetails, EPFPKI_PUBLIC_KEY_LENGTH, EPFPKI_SIGNATURE_LENGTH, EpfPkiCertificateOps, EpfPkiCertificateValidationError, EpfPkiSerializable, EpfPrivateKey, EpfPublicKey};
|
||||
use std::collections::HashMap;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
#[test]
|
||||
pub fn certificate_serialization() {
|
||||
|
@ -329,7 +419,10 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
pub fn pubkey_deserialization_pem() {
|
||||
assert_eq!(EpfPublicKey::from_pem(&null_public_key_pem()).unwrap(), [0u8; 32])
|
||||
assert_eq!(
|
||||
EpfPublicKey::from_pem(&null_public_key_pem()).unwrap(),
|
||||
[0u8; 32]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -355,13 +448,19 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
pub fn privkey_deserialization_pem() {
|
||||
assert_eq!(EpfPrivateKey::from_pem(&null_private_key_pem()).unwrap(), [0u8; 64])
|
||||
assert_eq!(
|
||||
EpfPrivateKey::from_pem(&null_private_key_pem()).unwrap(),
|
||||
[0u8; 64]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
pub fn privkey_deserialization_pem_wrong_tag() {
|
||||
assert_eq!(EpfPrivateKey::from_pem(&null_public_key_pem()).unwrap(), [0u8; 64])
|
||||
assert_eq!(
|
||||
EpfPrivateKey::from_pem(&null_public_key_pem()).unwrap(),
|
||||
[0u8; 64]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -373,7 +472,10 @@ mod tests {
|
|||
pub fn cert_fingerprinting() {
|
||||
let mut cert = cert();
|
||||
cert.recalculate_fingerprint().unwrap();
|
||||
assert_eq!(cert.fingerprint, "922c5cb83633b214d19d9aebf387314fcde67210ff92bd9691fbd059141d6adf");
|
||||
assert_eq!(
|
||||
cert.fingerprint,
|
||||
"922c5cb83633b214d19d9aebf387314fcde67210ff92bd9691fbd059141d6adf"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -389,8 +491,16 @@ mod tests {
|
|||
let mut ca_cert = EPFCertificate {
|
||||
details: EPFCertificateDetails {
|
||||
name: "Testing CA".to_string(),
|
||||
not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 10,
|
||||
not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 60,
|
||||
not_before: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
- 10,
|
||||
not_after: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
+ 60,
|
||||
public_key: *public_key.as_bytes(),
|
||||
issuer_public_key: [0u8; 32],
|
||||
claims: Default::default(),
|
||||
|
@ -416,8 +526,16 @@ mod tests {
|
|||
let mut not_ca_cert = EPFCertificate {
|
||||
details: EPFCertificateDetails {
|
||||
name: "Testing Certificate".to_string(),
|
||||
not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 10,
|
||||
not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 60,
|
||||
not_before: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
- 10,
|
||||
not_after: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
+ 60,
|
||||
public_key: *public_key2.as_bytes(),
|
||||
issuer_public_key: [0u8; 32],
|
||||
claims: Default::default(),
|
||||
|
@ -436,8 +554,15 @@ mod tests {
|
|||
let expired_cert = EPFCertificate {
|
||||
details: EPFCertificateDetails {
|
||||
name: "Testing Certificate - Expired".to_string(),
|
||||
not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
|
||||
not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() -20,
|
||||
not_before: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs(),
|
||||
not_after: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
- 20,
|
||||
public_key: [0u8; 32],
|
||||
issuer_public_key: [0u8; 32],
|
||||
claims: Default::default(),
|
||||
|
@ -448,7 +573,10 @@ mod tests {
|
|||
|
||||
let ca_pool = EpfCaPool::new();
|
||||
|
||||
assert!(matches!(expired_cert.verify(&ca_pool).unwrap_err(), EpfPkiCertificateValidationError::NoLongerValid { .. }))
|
||||
assert!(matches!(
|
||||
expired_cert.verify(&ca_pool).unwrap_err(),
|
||||
EpfPkiCertificateValidationError::NoLongerValid { .. }
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -456,8 +584,16 @@ mod tests {
|
|||
let not_yet_valid_cert = EPFCertificate {
|
||||
details: EPFCertificateDetails {
|
||||
name: "Testing Certificate - Not Yet Valid".to_string(),
|
||||
not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 20,
|
||||
not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 30,
|
||||
not_before: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
+ 20,
|
||||
not_after: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
+ 30,
|
||||
public_key: [0u8; 32],
|
||||
issuer_public_key: [0u8; 32],
|
||||
claims: Default::default(),
|
||||
|
@ -468,7 +604,10 @@ mod tests {
|
|||
|
||||
let ca_pool = EpfCaPool::new();
|
||||
|
||||
assert!(matches!(not_yet_valid_cert.verify(&ca_pool).unwrap_err(), EpfPkiCertificateValidationError::NotValidYet { .. }))
|
||||
assert!(matches!(
|
||||
not_yet_valid_cert.verify(&ca_pool).unwrap_err(),
|
||||
EpfPkiCertificateValidationError::NotValidYet { .. }
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -479,8 +618,16 @@ mod tests {
|
|||
let mut not_trusted_cert = EPFCertificate {
|
||||
details: EPFCertificateDetails {
|
||||
name: "Testing Certificate - Not Trusted".to_string(),
|
||||
not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 20,
|
||||
not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 30,
|
||||
not_before: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
- 20,
|
||||
not_after: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
+ 30,
|
||||
public_key: [0u8; 32],
|
||||
issuer_public_key: *public_key.as_bytes(),
|
||||
claims: Default::default(),
|
||||
|
@ -488,7 +635,9 @@ mod tests {
|
|||
fingerprint: "".to_string(),
|
||||
signature: [0u8; EPFPKI_SIGNATURE_LENGTH],
|
||||
};
|
||||
not_trusted_cert.sign(&private_key.to_keypair_bytes()).unwrap();
|
||||
not_trusted_cert
|
||||
.sign(&private_key.to_keypair_bytes())
|
||||
.unwrap();
|
||||
|
||||
let ca_pool = EpfCaPool::new();
|
||||
|
||||
|
@ -508,8 +657,16 @@ mod tests {
|
|||
let mut ca_cert = EPFCertificate {
|
||||
details: EPFCertificateDetails {
|
||||
name: "Testing CA".to_string(),
|
||||
not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 10,
|
||||
not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 60,
|
||||
not_before: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
- 10,
|
||||
not_after: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
+ 60,
|
||||
public_key: *public_key.as_bytes(),
|
||||
issuer_public_key: [0u8; 32],
|
||||
claims: Default::default(),
|
||||
|
@ -524,8 +681,16 @@ mod tests {
|
|||
let mut not_ca_cert = EPFCertificate {
|
||||
details: EPFCertificateDetails {
|
||||
name: "Testing Certificate - Valid After Signer".to_string(),
|
||||
not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 10,
|
||||
not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 120,
|
||||
not_before: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
- 10,
|
||||
not_after: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
+ 120,
|
||||
public_key: *public_key2.as_bytes(),
|
||||
issuer_public_key: [0u8; 32],
|
||||
claims: Default::default(),
|
||||
|
@ -536,7 +701,10 @@ mod tests {
|
|||
|
||||
assert!(not_ca_cert.verify(&ca_pool).is_err());
|
||||
not_ca_cert.sign(&private_key.to_keypair_bytes()).unwrap();
|
||||
assert!(matches!(not_ca_cert.verify(&ca_pool).unwrap_err(), EpfPkiCertificateValidationError::ExpiresAfterSigner));
|
||||
assert!(matches!(
|
||||
not_ca_cert.verify(&ca_pool).unwrap_err(),
|
||||
EpfPkiCertificateValidationError::ExpiresAfterSigner
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -552,8 +720,16 @@ mod tests {
|
|||
let mut ca_cert = EPFCertificate {
|
||||
details: EPFCertificateDetails {
|
||||
name: "Testing CA".to_string(),
|
||||
not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 10,
|
||||
not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 60,
|
||||
not_before: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
- 10,
|
||||
not_after: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
+ 60,
|
||||
public_key: *public_key.as_bytes(),
|
||||
issuer_public_key: [0u8; 32],
|
||||
claims: Default::default(),
|
||||
|
@ -568,8 +744,16 @@ mod tests {
|
|||
let mut not_ca_cert = EPFCertificate {
|
||||
details: EPFCertificateDetails {
|
||||
name: "Testing Certificate - Valid After Signer".to_string(),
|
||||
not_before: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - 200,
|
||||
not_after: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() + 10,
|
||||
not_before: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
- 200,
|
||||
not_after: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
+ 10,
|
||||
public_key: *public_key2.as_bytes(),
|
||||
issuer_public_key: [0u8; 32],
|
||||
claims: Default::default(),
|
||||
|
@ -580,16 +764,45 @@ mod tests {
|
|||
|
||||
assert!(not_ca_cert.verify(&ca_pool).is_err());
|
||||
not_ca_cert.sign(&private_key.to_keypair_bytes()).unwrap();
|
||||
assert!(matches!(not_ca_cert.verify(&ca_pool).unwrap_err(), EpfPkiCertificateValidationError::ValidAfterSigner));
|
||||
assert!(matches!(
|
||||
not_ca_cert.verify(&ca_pool).unwrap_err(),
|
||||
EpfPkiCertificateValidationError::ValidAfterSigner
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn verifying_error_display() {
|
||||
println!("{}", EpfPkiCertificateValidationError::NoLongerValid { expired_at: SystemTime::now() });
|
||||
println!("{}", EpfPkiCertificateValidationError::NotValidYet { valid_at: SystemTime::now() });
|
||||
println!("{}", EpfPkiCertificateValidationError::InvalidCertificateData { e: rmp_serde::encode::Error::UnknownLength});
|
||||
println!("{}", EpfPkiCertificateValidationError::FingerprintDoesNotMatch { expected: "".to_string(), got: "".to_string() });
|
||||
println!("{}", EpfPkiCertificateValidationError::InvalidSignature { e: SignatureError::new() });
|
||||
println!(
|
||||
"{}",
|
||||
EpfPkiCertificateValidationError::NoLongerValid {
|
||||
expired_at: SystemTime::now()
|
||||
}
|
||||
);
|
||||
println!(
|
||||
"{}",
|
||||
EpfPkiCertificateValidationError::NotValidYet {
|
||||
valid_at: SystemTime::now()
|
||||
}
|
||||
);
|
||||
println!(
|
||||
"{}",
|
||||
EpfPkiCertificateValidationError::InvalidCertificateData {
|
||||
e: rmp_serde::encode::Error::UnknownLength
|
||||
}
|
||||
);
|
||||
println!(
|
||||
"{}",
|
||||
EpfPkiCertificateValidationError::FingerprintDoesNotMatch {
|
||||
expected: "".to_string(),
|
||||
got: "".to_string()
|
||||
}
|
||||
);
|
||||
println!(
|
||||
"{}",
|
||||
EpfPkiCertificateValidationError::InvalidSignature {
|
||||
e: SignatureError::new()
|
||||
}
|
||||
);
|
||||
println!("{}", EpfPkiCertificateValidationError::ExpiresAfterSigner);
|
||||
println!("{}", EpfPkiCertificateValidationError::ValidAfterSigner);
|
||||
}
|
||||
|
@ -602,22 +815,69 @@ mod tests {
|
|||
not_after: 0,
|
||||
public_key: [0u8; EPFPKI_PUBLIC_KEY_LENGTH],
|
||||
issuer_public_key: [0u8; EPFPKI_PUBLIC_KEY_LENGTH],
|
||||
claims: HashMap::new()
|
||||
claims: HashMap::new(),
|
||||
},
|
||||
fingerprint: "0000000000000000000000000000000000000000000000000000000000000000".to_string(),
|
||||
fingerprint: "0000000000000000000000000000000000000000000000000000000000000000"
|
||||
.to_string(),
|
||||
signature: [0u8; EPFPKI_SIGNATURE_LENGTH],
|
||||
}
|
||||
}
|
||||
fn cert_bytes() -> Vec<u8> {
|
||||
vec![147, 150, 187, 73, 110, 118, 97, 108, 105, 100, 32, 84, 101, 115, 116, 105, 110, 103, 32, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 0, 0, 220, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 217, 64, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 220, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
vec![
|
||||
147, 150, 187, 73, 110, 118, 97, 108, 105, 100, 32, 84, 101, 115, 116, 105, 110, 103,
|
||||
32, 67, 101, 114, 116, 105, 102, 105, 99, 97, 116, 101, 0, 0, 220, 0, 32, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
220, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 128, 217, 64, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 220, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
]
|
||||
}
|
||||
fn cert_pem() -> Vec<u8> {
|
||||
vec![45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 69, 80, 70, 32, 67, 69, 82, 84, 73, 70, 73, 67, 65, 84, 69, 45, 45, 45, 45, 45, 13, 10, 107, 53, 97, 55, 83, 87, 53, 50, 89, 87, 120, 112, 90, 67, 66, 85, 90, 88, 78, 48, 97, 87, 53, 110, 73, 69, 78, 108, 99, 110, 82, 112, 90, 109, 108, 106, 89, 88, 82, 108, 65, 65, 68, 99, 65, 67, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 78, 119, 65, 73, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 103, 78, 108, 65, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 13, 10, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 78, 119, 65, 81, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 61, 13, 10, 45, 45, 45, 45, 45, 69, 78, 68, 32, 69, 80, 70, 32, 67, 69, 82, 84, 73, 70, 73, 67, 65, 84, 69, 45, 45, 45, 45, 45, 13, 10]
|
||||
vec![
|
||||
45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 69, 80, 70, 32, 67, 69, 82, 84, 73, 70, 73,
|
||||
67, 65, 84, 69, 45, 45, 45, 45, 45, 13, 10, 107, 53, 97, 55, 83, 87, 53, 50, 89, 87,
|
||||
120, 112, 90, 67, 66, 85, 90, 88, 78, 48, 97, 87, 53, 110, 73, 69, 78, 108, 99, 110,
|
||||
82, 112, 90, 109, 108, 106, 89, 88, 82, 108, 65, 65, 68, 99, 65, 67, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 78, 119,
|
||||
65, 73, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 103, 78, 108, 65, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77,
|
||||
68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77,
|
||||
68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 13,
|
||||
10, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65,
|
||||
119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 68, 65, 119, 77, 78, 119, 65, 81, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 61, 13,
|
||||
10, 45, 45, 45, 45, 45, 69, 78, 68, 32, 69, 80, 70, 32, 67, 69, 82, 84, 73, 70, 73, 67,
|
||||
65, 84, 69, 45, 45, 45, 45, 45, 13, 10,
|
||||
]
|
||||
}
|
||||
fn null_public_key_pem() -> Vec<u8> {
|
||||
vec![45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 69, 80, 70, 32, 80, 85, 66, 76, 73, 67, 32, 75, 69, 89, 45, 45, 45, 45, 45, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 61, 13, 10, 45, 45, 45, 45, 45, 69, 78, 68, 32, 69, 80, 70, 32, 80, 85, 66, 76, 73, 67, 32, 75, 69, 89, 45, 45, 45, 45, 45, 13, 10]
|
||||
vec![
|
||||
45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 69, 80, 70, 32, 80, 85, 66, 76, 73, 67, 32,
|
||||
75, 69, 89, 45, 45, 45, 45, 45, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 61, 13, 10, 45, 45, 45, 45, 45, 69, 78, 68, 32, 69,
|
||||
80, 70, 32, 80, 85, 66, 76, 73, 67, 32, 75, 69, 89, 45, 45, 45, 45, 45, 13, 10,
|
||||
]
|
||||
}
|
||||
fn null_private_key_pem() -> Vec<u8> {
|
||||
vec![45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 69, 80, 70, 32, 80, 82, 73, 86, 65, 84, 69, 32, 75, 69, 89, 45, 45, 45, 45, 45, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 61, 61, 13, 10, 45, 45, 45, 45, 45, 69, 78, 68, 32, 69, 80, 70, 32, 80, 82, 73, 86, 65, 84, 69, 32, 75, 69, 89, 45, 45, 45, 45, 45, 13, 10]
|
||||
vec![
|
||||
45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 69, 80, 70, 32, 80, 82, 73, 86, 65, 84, 69,
|
||||
32, 75, 69, 89, 45, 45, 45, 45, 45, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 13, 10, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 61, 61, 13, 10, 45, 45, 45, 45, 45, 69, 78,
|
||||
68, 32, 69, 80, 70, 32, 80, 82, 73, 86, 65, 84, 69, 32, 75, 69, 89, 45, 45, 45, 45, 45,
|
||||
13, 10,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use chrono::{DateTime, Utc};
|
||||
use std::ops::Add;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
pub fn pretty_print_date(date: &SystemTime) -> String {
|
||||
let datetime: DateTime<Utc> = (*date).into();
|
||||
|
@ -9,4 +9,4 @@ pub fn pretty_print_date(date: &SystemTime) -> String {
|
|||
|
||||
pub fn u64_to_st(unix: u64) -> SystemTime {
|
||||
SystemTime::UNIX_EPOCH.add(Duration::from_secs(unix))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue