Technical Details
Zero-Trust Implementation
This page covers the technical implementation details of Honse Farm's zero-trust architecture. If you're looking for the conceptual overview, see Zero-Trust Architecture.
Key Management
Server Keys
Location: {WebHostEnvironment}/Certificates/
Generation (KeyManagementService):
- Generate a BIP39 mnemonic (recovery phrase)
- Derive Ed25519 keypair from mnemonic
- Store:
{serverId}.key(private key, base64){serverId}.pub(public key, base64){serverId}.recovery(mnemonic, encrypted)
Usage:
- Private key used to sign outgoing federation requests
- Public key shared with other servers during discovery
Client Keys
Location: {PluginConfigDirectory}/cryptography/
Generation (CryptographyService):
- Similar Ed25519 keypair generation
- Keys stored per Lodestone ID
- Private key never leaves the client machine
Usage:
- Private key signs all user actions
- Public key uploaded to the user's home server during registration
Signature Verification Flow
Client Signature (SignatureAuthenticationHandler.AuthenticateClientRequestAsync)
1. Extract ClientSignatureRequest from HTTP body
2. Get userId from request
3. Fetch user's public key from database
4. Reconstruct payload JSON (Payload + Timestamp + Nonce)
5. Verify Ed25519 signature:
- Convert signature from base64
- Convert public key from base64
- Verify using NSec.Cryptography
6. Check timestamp (reject if > 5 minutes old)
7. Check nonce against recent nonce cache
8. Create authenticated ClaimsPrincipal with userId
Server Signature (HttpSignatureValidationMiddleware + HttpSignatureService)
1. Middleware intercepts federation routes
2. Extract Signature header
3. Parse keyId (serverId) and signature value
4. Fetch server's public key:
- Check request body (for discovery)
- Query DataService federation database
5. Rebuild signature string from request headers/body
6. Verify Ed25519 signature
7. Validate Date header (reject if > 5 minutes old)
8. Store verified serverId in HttpContext.Items
9. Authentication handler creates ClaimsPrincipal
Replay Attack Prevention
Timestamp Validation
- Both client and server requests include timestamps
- Requests outside the acceptable time window (typically 5 minutes) are rejected
- Prevents attackers from reusing old signed requests
Unique request Tracking
- Each client request includes a unique request ID (nonce)
- Server maintains a cache of recently seen nonces
- Duplicate nonces within the time window are rejected
- Cache expiration matches timestamp window
Public Key Distribution
Server Keys
- Exchanged during federation discovery (
POST /api/federation/announce) - Cached in
FederationDbContext(DataService) - Updated when servers re-announce themselves
Client Keys
- Uploaded during user registration
- Stored in user's home server database
- Shared with remote servers only when needed (e.g., pairing operations)
- Never exposed in public APIs
Code Structure
Key Classes
| Class | Responsibility |
|---|---|
| CryptographyService (Client) | Client keypair management, signing requests |
| KeyManagementService (Server) | Server keypair management, signing federation requests |
| HttpSignatureService (Server) | Create/verify HTTP signatures for federation |
| SignatureAuthenticationHandler (Server) | ASP.NET authentication for both client and server requests |
| HttpSignatureValidationMiddleware (Server) | Early validation of federation HTTP signatures |