Skip to content

Latest commit

 

History

History
742 lines (602 loc) · 18 KB

File metadata and controls

742 lines (602 loc) · 18 KB

SteveMail Trust System Design

Overview

A three-level trust system for server-to-server email authentication using PKI and web-of-trust principles. This allows mail servers to establish cryptographic trust relationships without requiring centralized certificate authorities.

Problem Statement

Current email authentication (SPF, DKIM, DMARC) is domain-centric and doesn't establish server-to-server trust relationships. This design creates a peer-to-peer trust network where servers can:

  • Verify each other's identities cryptographically
  • Build trust networks through peer endorsements
  • Optionally use a public registry for discovery
  • Reject untrusted connections at the SMTP level

Three-Level Trust Model

Level 1: Direct Trust (Manual Key Exchange)

Description: Strongest trust level based on manual administrator configuration.

Process:

  1. Admin of mail.alice.com and mail.bob.com meet/communicate
  2. Exchange public keys out-of-band (email, phone, in-person)
  3. Each admin adds the other's key to their trusted peers list
  4. Servers can now authenticate each other cryptographically

Trust Level: Highest Setup: Manual Use Case: Known partners, frequent communication, high-value relationships

Example Configuration:

Trusted Peers for mail.alice.com:
  - mail.bob.com: <Bob's Public Key>
  - mail.carol.com: <Carol's Public Key>

Level 2: Transitive Trust (Web of Trust)

Description: Discover new trusted servers through existing Level 1 relationships.

Process:

  1. Alice's server receives connection from unknown mail.dave.com
  2. Alice queries her Level 1 peers: "Do you trust dave?"
  3. Bob responds: "Yes, here's Dave's public key and my signature"
  4. Alice caches Dave's key with reduced trust level
  5. Future connections from Dave are verified against cached key

Trust Level: Medium Setup: Automatic via peer queries Use Case: Extended network, partners of partners

Example:

Alice trusts Bob (Level 1)
Bob trusts Dave (Level 1)
→ Alice trusts Dave (Level 2, via Bob)

Query Protocol:

Alice → Bob: "ESRV QUERY-TRUST mail.dave.com"
Bob → Alice: "ESRV RESPONSE-TRUST LEVEL1 <dave-public-key> <bob-signature>"

Level 3: Registry Trust (Public Directory)

Description: Lookup unknown servers in a public registry with reputation scores.

Process:

  1. Server receives connection from unknown domain
  2. No Level 1 or Level 2 trust exists
  3. Query public registry for domain's public key and reputation
  4. Verify signature against registry key
  5. Check trust score and flags
  6. Accept/reject based on policy thresholds

Trust Level: Lowest Setup: Automatic via registry API Use Case: First contact, cold outreach, general public

Registry Entry Example:

{
  "domain": "mail.example.com",
  "public_key": "-----BEGIN PUBLIC KEY-----...",
  "key_fingerprint": "SHA256:abc123...",
  "ip_addresses": ["203.0.113.5", "203.0.113.6"],
  "registered_date": "2024-01-15T10:00:00Z",
  "trust_score": 95,
  "flags": [],
  "endorsements": [
    {
      "endorsed_by": "mail.trusted.com",
      "date": "2024-01-20T12:00:00Z",
      "signature": "..."
    }
  ],
  "last_seen": "2024-01-25T08:30:00Z"
}

SMTP Protocol Extension (ESRV)

Extension Name: ESRV (Extended Server Trust)

EHLO Response:

S: 250-mail.alice.com
S: 250-ESRV TRUST-LEVELS=1,2,3
S: 250-ESRV KEY-FINGERPRINT=SHA256:abc123...
S: 250 STARTTLS

Authentication Commands:

Identify Server:

C: ESRV IDENTIFY mail.bob.com SHA256:def456...
S: 250 IDENTIFIED

Authenticate with Signature:

C: ESRV AUTH LEVEL1
C: SIGNATURE: <base64-signature-of-session-id>
S: 250 AUTH VERIFIED LEVEL1

Query Trust (Level 2):

C: ESRV QUERY-TRUST mail.dave.com
S: 250 TRUST-INFO LEVEL1 <public-key> <signature>

Verify Signature:

C: ESRV VERIFY <signature-data>
S: 250 SIGNATURE VALID

Session Flow:

1. EHLO with ESRV support announcement
2. ESRV IDENTIFY (optional, for tracking)
3. ESRV AUTH (required for trusted delivery)
4. Standard SMTP commands (MAIL FROM, RCPT TO, DATA)

Database Schema

Trusted Peers (Level 1)

CREATE TABLE trusted_peers (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    domain TEXT NOT NULL UNIQUE,
    public_key TEXT NOT NULL,
    key_fingerprint TEXT NOT NULL,
    private_note TEXT,
    added_by TEXT,
    added_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    last_verified TIMESTAMP,
    connection_count INTEGER DEFAULT 0
);

CREATE INDEX idx_trusted_peers_domain ON trusted_peers(domain);
CREATE INDEX idx_trusted_peers_fingerprint ON trusted_peers(key_fingerprint);

Transitive Trust Cache (Level 2)

CREATE TABLE transitive_trust (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    domain TEXT NOT NULL UNIQUE,
    public_key TEXT NOT NULL,
    key_fingerprint TEXT NOT NULL,
    trusted_via TEXT NOT NULL, -- which Level 1 peer vouched
    trust_level INTEGER DEFAULT 2,
    voucher_signature TEXT NOT NULL,
    cached_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    expires_date TIMESTAMP NOT NULL,
    last_used TIMESTAMP,
    use_count INTEGER DEFAULT 0
);

CREATE INDEX idx_transitive_trust_domain ON transitive_trust(domain);
CREATE INDEX idx_transitive_trust_expires ON transitive_trust(expires_date);

Registry Cache (Level 3)

CREATE TABLE registry_cache (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    domain TEXT NOT NULL UNIQUE,
    public_key TEXT NOT NULL,
    key_fingerprint TEXT NOT NULL,
    ip_addresses TEXT, -- JSON array
    trust_score INTEGER,
    flags TEXT, -- JSON array
    endorsements TEXT, -- JSON array
    cached_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    cache_expires TIMESTAMP NOT NULL,
    last_verified TIMESTAMP
);

CREATE INDEX idx_registry_cache_domain ON registry_cache(domain);
CREATE INDEX idx_registry_cache_score ON registry_cache(trust_score);

Connection Log

CREATE TABLE trust_connections (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    remote_domain TEXT NOT NULL,
    remote_ip TEXT NOT NULL,
    trust_level INTEGER, -- 1, 2, 3, or NULL (untrusted)
    authenticated BOOLEAN DEFAULT 0,
    signature_valid BOOLEAN,
    connection_result TEXT, -- accepted, rejected, relayed
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    email_count INTEGER DEFAULT 0
);

CREATE INDEX idx_trust_connections_domain ON trust_connections(remote_domain);
CREATE INDEX idx_trust_connections_timestamp ON trust_connections(timestamp DESC);
CREATE INDEX idx_trust_connections_result ON trust_connections(connection_result);

Server Identity

CREATE TABLE server_identity (
    id INTEGER PRIMARY KEY CHECK (id = 1), -- Single row table
    domain TEXT NOT NULL,
    private_key_path TEXT NOT NULL,
    public_key TEXT NOT NULL,
    key_fingerprint TEXT NOT NULL,
    key_generated_date TIMESTAMP NOT NULL,
    key_algorithm TEXT DEFAULT 'RSA-4096'
);

Configuration

Environment Variables (.env)

# Trust System
ENABLE_TRUST_SYSTEM=true
TRUST_REQUIRE_AUTH_PORT25=false  # Allow unauthenticated on port 25?
TRUST_REQUIRE_AUTH_PORT587=true  # Always require auth on 587

# Trust Levels Enabled
TRUST_ALLOW_LEVEL1=true
TRUST_ALLOW_LEVEL2=true
TRUST_ALLOW_LEVEL3=false  # Registry optional

# Level 2 Settings
TRUST_L2_CACHE_DURATION_HOURS=168  # 1 week
TRUST_L2_MAX_HOPS=2  # How many levels of transitive trust

# Level 3 Registry
TRUST_REGISTRY_URL=https://mailreg.example.org
TRUST_REGISTRY_MIN_SCORE=70  # Minimum trust score to accept
TRUST_REGISTRY_CACHE_HOURS=24

# Server Identity
SERVER_DOMAIN=mail.example.com
SERVER_PRIVATE_KEY=./keys/server.key
SERVER_PUBLIC_KEY=./keys/server.pub

# Fallback Behavior
TRUST_REJECT_UNTRUSTED=true  # Reject if no trust established
TRUST_FALLBACK_TO_SPF=false  # Use SPF/DKIM if ESRV not supported

Trust Policy Configuration

# trust-policy.yaml
trust_policy:
  # Port 25 (incoming from other servers)
  port_25:
    level_1: accept
    level_2: accept
    level_3: accept_if_score_above_80
    untrusted: reject

  # Port 587 (submission from clients)
  port_587:
    require_authentication: true
    allow_relay: level_1_and_2_only

  # Rate limits by trust level
  rate_limits:
    level_1:
      emails_per_hour: unlimited
      recipients_per_email: 100
    level_2:
      emails_per_hour: 100
      recipients_per_email: 50
    level_3:
      emails_per_hour: 10
      recipients_per_email: 10
    untrusted:
      emails_per_hour: 0

Public Registry API Design

Base URL

https://mailreg.example.org/api/v1

Endpoints

Register Server:

POST /servers
Content-Type: application/json

{
  "domain": "mail.example.com",
  "public_key": "-----BEGIN PUBLIC KEY-----...",
  "admin_email": "admin@example.com",
  "ip_addresses": ["203.0.113.5"],
  "proof_of_domain": "<DNS-TXT-record-value>"
}

Response: 201 Created
{
  "server_id": "uuid",
  "verification_status": "pending",
  "verification_method": "dns_txt"
}

Lookup Server:

GET /servers/mail.example.com

Response: 200 OK
{
  "domain": "mail.example.com",
  "public_key": "-----BEGIN PUBLIC KEY-----...",
  "key_fingerprint": "SHA256:abc123...",
  "ip_addresses": ["203.0.113.5"],
  "registered_date": "2024-01-15T10:00:00Z",
  "verified": true,
  "trust_score": 95,
  "flags": [],
  "endorsements_count": 5,
  "last_seen": "2024-01-25T08:30:00Z"
}

Endorse Server:

POST /servers/mail.example.com/endorse
Content-Type: application/json

{
  "endorser_domain": "mail.alice.com",
  "signature": "<signature-of-endorsed-domain-by-endorser>"
}

Response: 201 Created

Report Server:

POST /servers/mail.example.com/report
Content-Type: application/json

{
  "reporter_domain": "mail.alice.com",
  "reason": "spam",
  "evidence": "...",
  "signature": "<signature>"
}

Response: 201 Created

Search Servers:

GET /servers?min_score=80&verified=true&limit=100

Response: 200 OK
{
  "servers": [...],
  "total": 1523,
  "page": 1
}

Implementation Phases

Phase 1: Level 1 Trust (Manual Key Exchange)

Goal: Basic PKI authentication between manually configured peers.

Features:

  • Generate server key pair
  • CLI tool to manage trusted peers
  • ESRV IDENTIFY and AUTH commands
  • Signature verification
  • Reject untrusted connections (optional)

Deliverables:

  1. Key generation tool: mailctl keygen
  2. Peer management: mailctl peer:add, mailctl peer:list
  3. Modified SMTP handler with ESRV support
  4. Database migrations for trusted_peers table
  5. Configuration options

Testing:

  • Setup 2 SteveMail instances
  • Exchange public keys
  • Send authenticated email
  • Verify rejection of untrusted server

Phase 2: Level 2 Trust (Web of Trust)

Goal: Discover trusted servers through peer recommendations.

Features:

  • ESRV QUERY-TRUST command
  • Peer query protocol
  • Trust cache with expiration
  • Transitive trust verification
  • Configurable trust depth (max hops)

Deliverables:

  1. Trust query handler
  2. Cache management
  3. Signature chain verification
  4. CLI: mailctl trust:query <domain>
  5. Database migrations for transitive_trust

Testing:

  • 3 server chain: A trusts B, B trusts C
  • A queries B about C
  • Verify cache expiration
  • Test trust depth limits

Phase 3: Public Registry (Mock Implementation)

Goal: Simple HTTP registry for testing Level 3 trust.

Features:

  • Basic HTTP API server
  • SQLite backend
  • Server registration
  • Lookup by domain
  • Simple trust scoring
  • No authentication (MVP)

Deliverables:

  1. Registry HTTP server
  2. Registration API
  3. Lookup API
  4. Basic web UI
  5. Integration with SteveMail

Testing:

  • Register multiple servers
  • Lookup servers
  • Query from SteveMail
  • Verify trust score filtering

Phase 4: Production Features

Goal: Security, scalability, and reliability.

Features:

  • Key rotation protocol
  • Revocation lists
  • Rate limiting by trust level
  • Prometheus metrics
  • TLS for registry API
  • Registry replication
  • DNSSEC integration
  • Reputation scoring algorithm

Security Considerations

Key Management

  • Private keys stored encrypted at rest
  • Key rotation every 1-2 years
  • Revocation mechanism for compromised keys
  • Separate keys for different purposes (signing vs encryption)

Attack Vectors

1. Man-in-the-Middle:

  • Mitigated by: Signature verification, key fingerprint verification

2. Key Theft:

  • Mitigated by: Encrypted storage, file permissions, HSM support

3. Replay Attacks:

  • Mitigated by: Session-specific signatures, timestamps, nonces

4. Trust Poisoning:

  • Mitigated by: Limited transitive trust depth, cache expiration, manual Level 1

5. Registry Compromise:

  • Mitigated by: Registry is lowest trust level, manual overrides, multiple registries

6. Sybil Attack:

  • Mitigated by: Domain ownership verification, IP reputation, endorsements

Privacy Considerations

  • Connection logs retention policy
  • Registry should not log queries
  • Optional anonymous queries to registry
  • Local caching to minimize registry dependencies

Benefits Over Existing Systems

vs SPF/DKIM/DMARC:

  • Server identity vs domain identity
  • Cryptographic proof vs DNS records
  • Peer-to-peer trust vs centralized DNS
  • Reject at connection vs after content analysis

vs Certificate Authorities:

  • No cost for basic trust (Level 1 & 2)
  • Decentralized trust network
  • Purpose-built for email
  • Web of trust model vs hierarchical CA

vs IP Whitelisting:

  • Cryptographic authentication vs IP address
  • Works across IP changes
  • Portable trust (key follows server)
  • Granular trust levels

Open Questions

  1. Key Algorithm: RSA 4096? Ed25519? Support multiple?
  2. Signature Format: JWS? OpenPGP? Custom?
  3. Trust Decay: Should Level 2 trust degrade over time?
  4. Registry Federation: Multiple registries? Consensus mechanism?
  5. Backward Compatibility: How to handle non-ESRV servers?
  6. Performance: Signature verification on every connection?
  7. Key Discovery: Alternative to registry for Level 3?
  8. Standards: Propose as IETF RFC?

Future Enhancements

  • End-to-end email encryption using server keys
  • Reputation scoring based on connection success
  • Machine learning for trust scoring
  • Blockchain-based registry (for immutability)
  • Federation protocol between registries
  • Integration with existing PKI (DANE/TLSA)
  • Message-level signatures (not just connection)
  • Trust visualization tools
  • Automated key rotation
  • Hardware security module (HSM) support

References

Existing Standards:

  • RFC 5321: SMTP
  • RFC 7208: SPF
  • RFC 6376: DKIM
  • RFC 7489: DMARC
  • RFC 6698: DANE
  • RFC 4880: OpenPGP

Similar Concepts:

  • PGP Web of Trust
  • SSL/TLS with client certificates
  • DNSSEC
  • Certificate Transparency

CLI Tool Reference (mailctl)

Key Management:

# Generate server key pair
mailctl keygen --domain mail.example.com

# Export public key
mailctl key:export > server.pub

# Show key fingerprint
mailctl key:fingerprint

# Rotate keys
mailctl key:rotate --backup

Peer Management (Level 1):

# Add trusted peer
mailctl peer:add mail.bob.com --key ./bob.pub --note "Bob's mail server"

# List trusted peers
mailctl peer:list

# Remove peer
mailctl peer:remove mail.bob.com

# Show peer details
mailctl peer:show mail.bob.com

# Verify peer signature
mailctl peer:verify mail.bob.com --signature <sig>

Trust Queries (Level 2):

# Query trust for domain
mailctl trust:query mail.dave.com

# Show trust cache
mailctl trust:cache

# Clear trust cache
mailctl trust:clear-cache

# Test trust path
mailctl trust:path mail.target.com

Registry Operations (Level 3):

# Register with public registry
mailctl registry:register

# Lookup domain in registry
mailctl registry:lookup mail.example.com

# Endorse another server
mailctl registry:endorse mail.friend.com

# Update registry info
mailctl registry:update --ips 203.0.113.5,203.0.113.6

Monitoring:

# Show connection log
mailctl connections --filter level=1 --limit 100

# Trust statistics
mailctl stats:trust

# Show untrusted connection attempts
mailctl connections --untrusted

Testing Scenarios

Scenario 1: Direct Trust

Setup:
- Server A (mail.alice.com)
- Server B (mail.bob.com)

Steps:
1. A and B exchange keys out-of-band
2. Each adds other to trusted_peers
3. B connects to A
4. B authenticates via ESRV
5. B sends email
6. A delivers to local mailbox

Verify:
- Connection logged with trust_level=1
- Email delivered successfully
- No warnings or rejections

Scenario 2: Transitive Trust

Setup:
- Server A trusts B (Level 1)
- Server B trusts C (Level 1)
- C is unknown to A

Steps:
1. C connects to A
2. A has no Level 1 trust for C
3. A queries B: "Do you trust C?"
4. B responds with C's key + signature
5. A caches C with Level 2 trust
6. C authenticates and sends email
7. Future connections use cache

Verify:
- First connection: query to B
- Cache entry created
- Subsequent connections: no query
- trust_level=2 logged

Scenario 3: Registry Lookup

Setup:
- Server A with registry enabled
- Server D (unknown to A)
- D registered in registry

Steps:
1. D connects to A
2. No Level 1 or 2 trust
3. A queries registry for D
4. Registry returns D's key + trust_score
5. If score > threshold, accept
6. Cache registry data

Verify:
- Registry query logged
- Trust score evaluated
- Accept/reject based on policy
- trust_level=3 if accepted

Scenario 4: Untrusted Rejection

Setup:
- Server A with TRUST_REJECT_UNTRUSTED=true
- Server E (unknown, not in registry)

Steps:
1. E connects to A
2. E does not support ESRV
3. No trust levels match
4. A rejects connection

Verify:
- Connection rejected at SMTP level
- No email accepted
- Rejection logged with trust_level=NULL
- Proper SMTP error code returned

Conclusion

This trust system provides a flexible, cryptographically secure method for mail servers to establish trust relationships. The three-level model allows for strong manual trust, scalable web-of-trust, and optional public discovery. Implementation can be phased, with each phase providing incremental value.

The system is designed to be backward-compatible with existing SMTP while providing significant security improvements for participating servers.