use validator::ValidationError;
use validator::Validator;
use validator::Validatable;
use revoker::RevokeError;
use revoker::Revoker;
use revoker::Revokable;
#[derive(Clone,Debug,PartialEq)]
pub struct TrustValidator<R: Revoker> {
revoker: R,
trusted_certificates: Vec<Vec<u8>>,
}
impl<R: Revoker> TrustValidator<R> {
pub fn new(revoker: R) -> TrustValidator<R> {
TrustValidator {
revoker: revoker,
trusted_certificates: Vec::new(),
}
}
pub fn with_trusted_certificates<T>(trusted_certificates: T, revoker: R) -> TrustValidator<R>
where T: Into<Vec<Vec<u8>>>
{
TrustValidator {
revoker: revoker,
trusted_certificates: trusted_certificates.into(),
}
}
pub fn add_trusted_certificates<T>(&mut self, trusted_certificates: T)
where T: IntoIterator<Item = Vec<u8>>
{
self.trusted_certificates.extend(trusted_certificates);
}
pub fn is_revoked<V: Revokable>(&self, cert: &V) -> Result<(), RevokeError> {
self.revoker.is_revoked(cert)
}
}
impl<R: Revoker> Validator for TrustValidator<R> {
fn is_valid<V: Validatable + Revokable>(&self, cert: &V) -> Result<(), ValidationError> {
if self.trusted_certificates.contains(&cert.fingerprint()) {
return Ok(());
}
try!(cert.self_validate(self));
try!(self.revoker.is_revoked(cert));
Ok(())
}
fn is_signature_valid(&self, _: &[u8], _: &[u8]) -> bool {
false
}
}
#[test]
fn test_trusted_certificates() {
use fingerprint::Fingerprint;
use meta::Meta;
use certificate::Certificate;
use revoker::NoRevoker;
use chrono::datetime::DateTime;
use chrono::UTC;
let mut meta = Meta::new_empty();
meta.set("use-for", r#"["edcert.sign"]"#);
let cert: Certificate =
Certificate::generate_random(meta,
DateTime::parse_from_rfc3339("2020-01-01T00:00:00+00:00")
.unwrap()
.with_timezone(&UTC));
let mut child: Certificate =
Certificate::generate_random(Meta::new_empty(),
DateTime::parse_from_rfc3339("2020-01-01T00:00:00+00:00")
.unwrap()
.with_timezone(&UTC));
cert.sign_certificate(&mut child).unwrap();
let trusted = vec![cert.fingerprint()];
let cv = TrustValidator::with_trusted_certificates(trusted, NoRevoker);
match cv.is_valid(&child) {
Err(x) => {
println!("{:?}", x);
panic!();
}
_ => {}
};
assert_eq!(cv.is_valid(&child).is_ok(), true);
}
#[test]
fn test_add_trusted_certificates() {
use fingerprint::Fingerprint;
use meta::Meta;
use certificate::Certificate;
use revoker::NoRevoker;
use chrono::datetime::DateTime;
use chrono::UTC;
let meta = Meta::new_empty();
let cert: Certificate =
Certificate::generate_random(meta,
DateTime::parse_from_rfc3339("2020-01-01T00:00:00+00:00")
.unwrap()
.with_timezone(&UTC));
let mut cv = TrustValidator::new(NoRevoker);
assert_eq!(cv.is_valid(&cert).is_ok(), false);
cv.add_trusted_certificates(vec![cert.fingerprint()]);
assert_eq!(cv.is_valid(&cert).is_ok(), true);
}
#[test]
fn test_trusted_certificates_fail() {
use fingerprint::Fingerprint;
use meta::Meta;
use certificate::Certificate;
use revoker::NoRevoker;
use chrono::datetime::DateTime;
use chrono::UTC;
let mut meta = Meta::new_empty();
meta.set("use-for", r#"["edcert.sign"]"#);
let cert: Certificate =
Certificate::generate_random(meta,
DateTime::parse_from_rfc3339("2020-01-01T00:00:00+00:00")
.unwrap()
.with_timezone(&UTC));
let child: Certificate =
Certificate::generate_random(Meta::new_empty(),
DateTime::parse_from_rfc3339("2020-01-01T00:00:00+00:00")
.unwrap()
.with_timezone(&UTC));
let trusted = vec![cert.fingerprint()];
let cv = TrustValidator::with_trusted_certificates(trusted, NoRevoker);
assert_eq!(cv.is_valid(&child).is_ok(), false);
}