No description
  • Go 98.9%
  • Makefile 0.6%
  • Dockerfile 0.5%
Find a file
2026-04-30 09:17:40 +07:00
checker checker: join recorded owner Hdr.Name to parent FQDN 2026-04-30 09:17:33 +07:00
plugin Initial commit 2026-04-26 18:11:28 +07:00
.gitignore Initial commit 2026-04-26 18:11:28 +07:00
Dockerfile docker: add HEALTHCHECK probing /health 2026-04-26 18:11:28 +07:00
go.mod docker: add HEALTHCHECK probing /health 2026-04-26 18:11:28 +07:00
go.sum docker: add HEALTHCHECK probing /health 2026-04-26 18:11:28 +07:00
LICENSE Initial commit 2026-04-26 18:11:28 +07:00
main.go Initial commit 2026-04-26 18:11:28 +07:00
Makefile Initial commit 2026-04-26 18:11:28 +07:00
NOTICE Initial commit 2026-04-26 18:11:28 +07:00
README.md Include rules section 2026-04-30 09:17:40 +07:00

checker-email-keys

DANE-Email posture checker for happyDomain.

Runs a comprehensive testsuite on a domain's DNS-published OpenPGP key (OPENPGPKEY, RFC 7929) or S/MIME certificate (SMIMEA, RFC 8162) and renders an actionable HTML report whose top block nudges the user toward the fix for the most common failure scenarios.

This checker binds to the happyDomain services:

  • abstract.OpenPGP: individual user's PGP key, owner-hashed below ._openpgpkey.<zone>.
  • abstract.SMimeCert: user's S/MIME certificate, owner-hashed below ._smimecert.<zone>.

Security scope

This checker validates DNS publication and the structure/metadata of the keys it finds. It does not cryptographically verify them:

  • OpenPGP signatures (self-signatures, third-party certifications, revocations beyond the presence of a revocation packet) are not verified.
  • S/MIME certificate chains are not built or validated against any trust anchor; revocation (CRL/OCSP) is not checked.
  • Authenticity of the records themselves is delegated to the validating resolver via the DNSSEC AD flag (see dnssec_not_validated). Run the checker against a resolver you trust to perform DNSSEC validation.

Treat a green report as "the record is well-formed and DNSSEC-signed", not as "the key is trustworthy".

Rules

Code Description Severity
dns_query_failed Verifies that the DNS lookup for the OPENPGPKEY/SMIMEA record succeeds. CRITICAL
dns_no_record Verifies that an OPENPGPKEY/SMIMEA record is published at the expected owner name. CRITICAL
dns_record_mismatch Verifies that the record returned by DNS matches the service-declared record. WARNING
dnssec_not_validated Verifies that the record is authenticated by DNSSEC (AD flag set). CRITICAL
owner_hash_mismatch Verifies that the owner-name first label equals hex(sha256(username))[:28]. CRITICAL
pgp_parse_error Verifies that the OPENPGPKEY record decodes as a valid OpenPGP key. CRITICAL
pgp_primary_revoked Verifies that the OpenPGP primary key carries no revocation signature. CRITICAL
pgp_primary_expired Verifies that the OpenPGP primary key has not passed its self-signature expiry. CRITICAL
pgp_primary_expiring_soon Warns when the OpenPGP primary key expires within the configured window. WARNING
pgp_weak_algorithm Verifies that OpenPGP keys do not use legacy algorithms (DSA/ElGamal). WARNING
pgp_weak_key_size Verifies that OpenPGP RSA keys meet the minimum 2048-bit size (3072+ preferred). CRITICAL
pgp_no_encryption_subkey Verifies that at least one active OpenPGP key advertises encryption capability. CRITICAL
pgp_no_identity Verifies that the OpenPGP key carries at least one self-signed User ID. WARNING
pgp_uid_mismatch Checks that at least one OpenPGP UID references <username@...>. INFO
pgp_multiple_entities Verifies that the record carries a single OpenPGP entity (RFC 7929). WARNING
pgp_record_too_large Verifies that the OPENPGPKEY record stays below 4 KiB to fit typical UDP answers. WARNING
smimea_bad_usage Verifies that the SMIMEA usage field is 0, 1, 2, or 3. CRITICAL
smimea_bad_selector Verifies that the SMIMEA selector field is 0 (Cert) or 1 (SPKI). CRITICAL
smimea_bad_match_type Verifies that the SMIMEA matching type is 0 (Full), 1 (SHA-256), or 2 (SHA-512). CRITICAL
smimea_cert_parse_error Verifies that the SMIMEA record decodes as a valid X.509 certificate or SPKI. CRITICAL
smimea_cert_not_yet_valid Verifies that the S/MIME certificate's NotBefore is in the past. CRITICAL
smimea_cert_expired Verifies that the S/MIME certificate's NotAfter is in the future. CRITICAL
smimea_cert_expiring_soon Warns when the S/MIME certificate expires within the configured window. WARNING
smimea_no_email_protection_eku Verifies that the S/MIME certificate advertises the emailProtection EKU. CRITICAL
smimea_missing_key_usage Verifies that the certificate carries digitalSignature and/or keyEncipherment key usage. WARNING
smimea_weak_signature_algorithm Verifies that the certificate is not signed with a deprecated algorithm (MD2/MD5/SHA-1). CRITICAL
smimea_weak_key_size Verifies that SMIMEA RSA keys meet the minimum 2048-bit size (3072+ preferred). CRITICAL
smimea_self_signed Flags self-signed certificates paired with PKIX-EE (usage 1). INFO
smimea_email_mismatch Checks that at least one email SAN on the certificate begins with @. INFO
smimea_hash_only Notes that SMIMEA matching types 1/2 transport only a digest, preventing certificate inspection. INFO

Options

Id Type Default Description
resolver string (system) Validating resolver to query; comma-separated list accepted.
certExpiryWarnDays number 30 Raise an expiring_soon warning within this window.
requireDNSSEC bool true When false, missing AD is a warn instead of crit.
requireEmailProtection bool true When false, missing emailProtection EKU is a warn instead of crit.

Auto-filled by the host: domain_name, subdomain, service, service_type.

Running

# Plugin (loaded by happyDomain at startup)
make plugin

# Standalone HTTP server
make && ./checker-email-keys -listen :8080