fix(SECURITY): return error on failed DANE verification
and add raw cert caching in DANE verificator
This commit is contained in:
parent
c3b50e4ecc
commit
32b888b3c1
2 changed files with 18 additions and 10 deletions
|
@ -149,8 +149,7 @@ impl SelfsignedCertVerifier for CertVerifier {
|
|||
CertFingerprint::new_sha256(cert)
|
||||
}
|
||||
Err(e) => {
|
||||
// some other problem (e.g. DNS server rejected the request),
|
||||
// we shouldn't continue
|
||||
// cert not matched, DNS server rejected request, etc.
|
||||
eprintln!("DANE verification failed: {:?}", e);
|
||||
return Err(e);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ use crate::{
|
|||
LibError,
|
||||
};
|
||||
|
||||
use tokio_rustls::rustls;
|
||||
|
||||
pub async fn dane(
|
||||
dns: &DnsClient,
|
||||
cert: &CertificateDer<'_>,
|
||||
|
@ -12,8 +14,11 @@ pub async fn dane(
|
|||
) -> Result<CertFingerprint, LibError> {
|
||||
let mut dns = dns.clone();
|
||||
|
||||
// TODO: maybe kinda Iterator or HashMap?
|
||||
// what if we needed one more algorithm to add?
|
||||
let mut sha256: Option<CertFingerprint> = None;
|
||||
let mut sha512: Option<CertFingerprint> = None;
|
||||
let mut raw: Option<CertFingerprint> = None;
|
||||
|
||||
for tlsa_fp in dns.query_tlsa(host, port).await? {
|
||||
match tlsa_fp {
|
||||
|
@ -36,19 +41,23 @@ pub async fn dane(
|
|||
}
|
||||
}
|
||||
CertFingerprint::Raw(_) => {
|
||||
let this_fp = CertFingerprint::new_raw(cert);
|
||||
if this_fp == tlsa_fp {
|
||||
return Ok(CertFingerprint::new_sha256(cert));
|
||||
if raw.is_none() {
|
||||
raw = Some(CertFingerprint::new_raw(cert));
|
||||
}
|
||||
let this_fp = raw.as_ref().unwrap();
|
||||
if this_fp == &tlsa_fp {
|
||||
return Ok(sha256.unwrap_or_else(|| CertFingerprint::new_sha256(cert)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(sha256) = sha256 {
|
||||
Ok(sha256)
|
||||
} else if let Some(sha512) = sha512 {
|
||||
Ok(sha512)
|
||||
if sha256.is_some() || sha512.is_some() || raw.is_some() {
|
||||
// we have a hash => we tried to match a cert at least once,
|
||||
// i.e. query_tlsa did not return an empty iterator
|
||||
Err(rustls::CertificateError::ApplicationVerificationFailure.into())
|
||||
} else {
|
||||
Ok(CertFingerprint::new_sha256(cert))
|
||||
// iterator was empty, we can't do any verification
|
||||
Err(LibError::HostLookupError)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue