- Go 98.9%
- Makefile 0.6%
- Dockerfile 0.5%
The binary doubles as its own healthcheck client via the SDK's -healthcheck flag, so the probe works in the scratch image (no shell, no curl, no wget). |
||
|---|---|---|
| checker | ||
| plugin | ||
| .gitignore | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| main.go | ||
| Makefile | ||
| NOTICE | ||
| README.md | ||
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
ADflag (seednssec_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".
Tests run
All findings are tagged by severity (info / warn / crit) so the
rule engine can fold them into a single CheckState.
DNS (both record types)
| Code | Severity | What it catches |
|---|---|---|
dns_query_failed |
crit | The resolver returned an error or did not answer. |
dns_no_record |
crit | The authoritative answer has no record at the expected owner. |
dnssec_not_validated |
crit / warn | The validating resolver did not set AD. RFC 7929/8162 mandate DNSSEC; the severity is configurable via requireDNSSEC. |
dns_record_mismatch |
warn | The record returned by DNS differs from the one declared in the service (typically a stale zone on the authoritative servers). |
owner_hash_mismatch |
crit | Record owner-name first label is not sha256(localpart)[:28]; mail clients will never find it. |
OpenPGP-specific (RFC 7929)
| Code | Severity | What it catches |
|---|---|---|
pgp_parse_error |
crit | Malformed base64 or OpenPGP packet stream. |
pgp_no_entity |
crit | Record decoded but carries no valid entity. |
pgp_primary_revoked |
crit | Primary key has a revocation signature. |
pgp_primary_expired |
crit | Self-signature expired; clients will refuse to encrypt. |
pgp_primary_expiring_soon |
warn | Expires within the certExpiryWarnDays window (default 30). |
pgp_weak_algorithm |
warn | Uses DSA / ElGamal (phase-out). |
pgp_weak_key_size |
crit / warn | RSA below 2048 bits is critical, 2048-3071 is a warn. |
pgp_no_encryption_subkey |
crit | No active key in the entity advertises encryption capability. |
pgp_no_identity |
warn | No self-signed User ID. |
pgp_uid_mismatch |
info | None of the UIDs reference <username@…>. |
pgp_multiple_entities |
warn | Record carries more than one entity (RFC 7929 recommends one). |
pgp_record_too_large |
warn | Raw key > 4 KiB; forces UDP→TCP fallback on every lookup. |
SMIMEA-specific (RFC 8162)
| Code | Severity | What it catches |
|---|---|---|
smimea_bad_usage / _selector / _match_type |
crit | Field outside the allowed range. |
smimea_cert_parse_error |
crit | Hex-encoded blob is not a valid X.509 certificate / SPKI. |
smimea_cert_expired / _not_yet_valid |
crit | notBefore / notAfter gate the current time out. |
smimea_cert_expiring_soon |
warn | Within the certExpiryWarnDays window. |
smimea_no_email_protection_eku |
crit / warn | Missing emailProtection EKU (RFC 8550/8551 agents will reject). |
smimea_missing_key_usage |
warn | Neither digitalSignature nor keyEncipherment key-usage is set. |
smimea_email_mismatch |
info | No email SAN starts with <username>@. |
smimea_weak_signature_algorithm |
crit | MD5 / SHA-1 based signature. |
smimea_weak_key_size |
crit / warn | RSA < 2048 / 3072 bits. |
smimea_self_signed |
info | Self-signed certificate paired with PKIX-EE usage. |
smimea_hash_only |
info | Matching-type 1/2 only carries a digest; certificate can't be inspected. |
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