Skip to content

Commit

Permalink
fix removal of certificate with identical fingerprint
Browse files Browse the repository at this point in the history
  • Loading branch information
Keksoj committed Feb 13, 2024
1 parent a732674 commit ec21bad
Showing 1 changed file with 73 additions and 4 deletions.
77 changes: 73 additions & 4 deletions lib/src/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,12 @@ impl TryFrom<&AddCertificate> for CertifiedKeyWrapper {
parse_pem(cert.certificate.as_bytes()).map_err(CertificateResolverError::ParsePem)?;

let x509 = parse_x509(&pem.contents).map_err(CertificateResolverError::ParseX509)?;
let overriding_names = get_cn_and_san_attributes(&x509);

let overriding_names = if add.certificate.names.is_empty() {
get_cn_and_san_attributes(&x509)
} else {
add.certificate.names.clone()
};

let expiration = add
.expired_at
Expand Down Expand Up @@ -176,9 +181,6 @@ impl CertificateResolver {
return Ok(cert_to_add.fingerprint);
}

self.certificates
.insert(cert_to_add.fingerprint.to_owned(), cert_to_add.clone());

for new_name in &cert_to_add.names {
self.domains.remove(&new_name.to_owned().into_bytes());

Expand All @@ -205,6 +207,9 @@ impl CertificateResolver {
self.certificates.remove(outdated);
}

self.certificates
.insert(cert_to_add.fingerprint.to_owned(), cert_to_add.clone());

Ok(cert_to_add.fingerprint.to_owned())
}

Expand Down Expand Up @@ -495,6 +500,70 @@ mod tests {
Ok(())
}

#[test]
fn properly_replace_outdated_cert() -> Result<(), Box<dyn Error + Send + Sync>> {
let address = SocketAddress::new_v4(127, 0, 0, 1, 8080);
let mut resolver = CertificateResolver::default();

let first_certificate = CertificateAndKey {
certificate: String::from(include_str!("../assets/tests/certificate-1y.pem")),
key: String::from(include_str!("../assets/tests/key.pem")),
names: vec!["localhost".into()],
..Default::default()
};
let first = resolver.add_certificate(&AddCertificate {
address: address.clone(),
certificate: first_certificate,
expired_at: None,
})?;
if resolver.get_certificate(&first).is_none() {
return Err("failed to retrieve first certificate".into());
}
println!("{:#?}", resolver);
match resolver.domain_lookup("localhost".as_bytes(), true) {
Some((_, fingerprint)) if fingerprint == &first => {}
Some((domain, fingerprint)) => {
return Err(format!(
"failed to lookup first inserted certificate. domain: {:?}, fingerprint: {}",
domain, fingerprint
)
.into())
}
_ => return Err("failed to lookup first inserted certificate".into()),
}

let second_certificate = CertificateAndKey {
certificate: String::from(include_str!("../assets/tests/certificate-2y.pem")),
key: String::from(include_str!("../assets/tests/key.pem")),
names: vec!["localhost".into(), "lolcatho.st".into()],
..Default::default()
};
let second = resolver.add_certificate(&AddCertificate {
address,
certificate: second_certificate,
expired_at: None,
})?;
println!("\n{:#?}\n", resolver);

if resolver.get_certificate(&second).is_none() {
return Err("failed to retrieve second certificate".into());
}

match resolver.domain_lookup("localhost".as_bytes(), true) {
Some((_, fingerprint)) if fingerprint == &second => {}
Some((domain, fingerprint)) => {
return Err(format!(
"failed to lookup second inserted certificate. domain: {:?}, fingerprint: {}",
domain, fingerprint
)
.into())
}
_ => return Err("the former certificate has not been overriden by the new one".into()),
}

Ok(())
}

#[test]
fn replacement() -> Result<(), Box<dyn Error + Send + Sync>> {
let address = SocketAddress::new_v4(127, 0, 0, 1, 8080);
Expand Down

0 comments on commit ec21bad

Please sign in to comment.