use base64::Engine;
use sha2::{Digest, Sha256};
pub fn key_authorization(token: &str, thumbprint: &str) -> String {
format!("{token}.{thumbprint}")
}
pub fn dns_txt_value(key_authorization: &str) -> String {
let digest = Sha256::digest(key_authorization.as_bytes());
base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(digest)
}
pub fn challenge_dns_name(identifier: &str) -> String {
format!("_acme-challenge.{identifier}")
}
fn normalize(name: &str) -> String {
name.trim().trim_end_matches('.').to_lowercase()
}
pub fn is_in_zone(identifier: &str, zone: &str) -> bool {
let zone = normalize(zone);
if zone.is_empty() {
return false;
}
let ident = normalize(identifier);
let base = ident.strip_prefix("*.").unwrap_or(&ident);
if base.is_empty() {
return false;
}
if base.contains('*') {
return false;
}
base == zone || base.ends_with(&format!(".{zone}"))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn key_authorization_is_token_dot_thumbprint() {
assert_eq!(key_authorization("tok", "thumb"), "tok.thumb");
}
#[test]
fn dns_txt_value_is_b64url_sha256() {
let v = dns_txt_value("tok.thumb");
assert_eq!(v.len(), 43);
assert_eq!(dns_txt_value("tok.thumb"), v);
assert_ne!(dns_txt_value("other"), v);
}
#[test]
fn challenge_name_is_prefixed() {
assert_eq!(
challenge_dns_name("grafana.lan"),
"_acme-challenge.grafana.lan"
);
}
#[test]
fn in_zone_accepts_subdomains_and_zone_itself() {
assert!(is_in_zone("grafana.lan", "lan"));
assert!(is_in_zone("a.b.lan", "lan"));
assert!(is_in_zone("lan", "lan"));
}
#[test]
fn in_zone_accepts_wildcard_in_zone() {
assert!(is_in_zone("*.lan", "lan"));
assert!(is_in_zone("*.team.lan", "lan"));
}
#[test]
fn out_of_zone_is_rejected() {
assert!(!is_in_zone("evil.com", "lan"));
assert!(!is_in_zone("grafana.example.org", "lan"));
assert!(!is_in_zone("notlan", "lan"));
assert!(!is_in_zone("lan.evil.com", "lan"));
}
#[test]
fn embedded_wildcard_is_rejected() {
assert!(!is_in_zone("a.*.lan", "lan"));
}
#[test]
fn case_and_trailing_dot_insensitive() {
assert!(is_in_zone("Grafana.LAN.", "lan"));
assert!(is_in_zone("grafana.lan", "LAN"));
}
}