Generate TLSA Records for DANE (closes #397)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2951,6 +2951,7 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
"tungstenite",
|
"tungstenite",
|
||||||
"utils",
|
"utils",
|
||||||
|
"x509-parser 0.16.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -167,6 +167,9 @@ impl Default for QueueConfig {
|
|||||||
),
|
),
|
||||||
invalid_certs: IfBlock::new::<()>(
|
invalid_certs: IfBlock::new::<()>(
|
||||||
"queue.outbound.tls.allow-invalid-certs",
|
"queue.outbound.tls.allow-invalid-certs",
|
||||||
|
#[cfg(not(feature = "test_mode"))]
|
||||||
|
[("retry_num > 0 && last_error == 'tls'", "true")],
|
||||||
|
#[cfg(feature = "test_mode")]
|
||||||
[],
|
[],
|
||||||
"false",
|
"false",
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -365,6 +365,11 @@ impl TokenMap {
|
|||||||
V_PRIORITY,
|
V_PRIORITY,
|
||||||
V_PROTOCOL,
|
V_PROTOCOL,
|
||||||
V_TLS,
|
V_TLS,
|
||||||
|
V_QUEUE_RETRY_NUM,
|
||||||
|
V_QUEUE_NOTIFY_NUM,
|
||||||
|
V_QUEUE_EXPIRES_IN,
|
||||||
|
V_QUEUE_LAST_STATUS,
|
||||||
|
V_QUEUE_LAST_ERROR,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ rsa = "0.9.2"
|
|||||||
async-trait = "0.1.68"
|
async-trait = "0.1.68"
|
||||||
lz4_flex = { version = "0.11", default-features = false }
|
lz4_flex = { version = "0.11", default-features = false }
|
||||||
rev_lines = "0.3.0"
|
rev_lines = "0.3.0"
|
||||||
|
x509-parser = "0.16.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ece = "2.2"
|
ece = "2.2"
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ use hyper::Method;
|
|||||||
use jmap_proto::error::request::RequestError;
|
use jmap_proto::error::request::RequestError;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
use sha1::Digest;
|
||||||
use store::ahash::AHashMap;
|
use store::ahash::AHashMap;
|
||||||
use utils::url_params::UrlParams;
|
use utils::url_params::UrlParams;
|
||||||
|
use x509_parser::parse_x509_certificate;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::{
|
api::{
|
||||||
@@ -229,6 +231,48 @@ impl JMAP {
|
|||||||
content: format!("v=DMARC1; p=reject; rua=mailto:postmaster@{domain_name}; ruf=mailto:postmaster@{domain_name}",),
|
content: format!("v=DMARC1; p=reject; rua=mailto:postmaster@{domain_name}; ruf=mailto:postmaster@{domain_name}",),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add TLSA records
|
||||||
|
for (name, key) in self.core.tls.certificates.load().iter() {
|
||||||
|
if !name.ends_with(domain_name) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let cert = if let Some(cert) = key.cert.first().map(|cert| cert.as_ref()) {
|
||||||
|
cert
|
||||||
|
} else {
|
||||||
|
tracing::debug!("No certificate found for domain: {}", domain_name);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let parsed_cert = match parse_x509_certificate(cert) {
|
||||||
|
Ok((_, parsed_cert)) => parsed_cert,
|
||||||
|
Err(err) => {
|
||||||
|
tracing::debug!("Failed to parse certificate: {}", err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let name = if !name.starts_with('.') {
|
||||||
|
format!("_25._tcp.{name}.")
|
||||||
|
} else {
|
||||||
|
format!("_25._tcp.mail.{name}.")
|
||||||
|
};
|
||||||
|
|
||||||
|
for (s, cert) in [cert, parsed_cert.subject_pki.raw].into_iter().enumerate() {
|
||||||
|
for (m, hash) in [
|
||||||
|
format!("{:x}", sha2::Sha256::digest(cert)),
|
||||||
|
format!("{:x}", sha2::Sha512::digest(cert)),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
records.push(DnsRecord {
|
||||||
|
typ: "TLSA".to_string(),
|
||||||
|
name: name.clone(),
|
||||||
|
content: format!("3 {} {} {}", s, m + 1, hash),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(records)
|
Ok(records)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user