package apps import ( "crypto/ed25519" "crypto/x509" "encoding/pem" "errors" "fmt" "os" ) // LoadPubKey reads a PEM-encoded SubjectPublicKeyInfo (the format // `openssl pkey -pubout` emits) from path and returns the underlying // Ed25519 public key. // // Operators distribute and configure this key explicitly — same posture // as the TLS certificate: zddc-server bakes nothing in. Customers // running against zddc.varasys.io's release channel download the // canonical key from zddc.varasys.io/pubkey.pem and pass the local // path via --apps-pubkey or ZDDC_APPS_PUBKEY. Customers running their // own signing infrastructure pass their own public key instead. // // Returns a descriptive error for missing files, malformed PEM, wrong // PEM type, or non-Ed25519 keys. Callers (cmd/zddc-server's startup // path) treat any error as fatal — refusing to start with a misconfigured // apps-pubkey is the right posture. func LoadPubKey(path string) (ed25519.PublicKey, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("read apps-pubkey from %s: %w", path, err) } return ParsePubKeyPEM(data) } // ParsePubKeyPEM is LoadPubKey's content-only variant. Useful when the // PEM bytes come from somewhere other than disk (test fixtures, etc.). func ParsePubKeyPEM(pemBytes []byte) (ed25519.PublicKey, error) { block, _ := pem.Decode(pemBytes) if block == nil { return nil, errors.New("no PEM block found") } if block.Type != "PUBLIC KEY" { return nil, fmt.Errorf("unexpected PEM type %q (want PUBLIC KEY)", block.Type) } pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, fmt.Errorf("parse PKIX: %w", err) } edPub, ok := pub.(ed25519.PublicKey) if !ok { return nil, fmt.Errorf("public key is not Ed25519 (got %T)", pub) } return edPub, nil } // VerifyEd25519 checks that sig is a valid Ed25519 signature of body // produced with the private key matching pub. Returns nil on success // or a descriptive error otherwise. // // sig must be exactly 64 bytes (the raw Ed25519 signature format // produced by `openssl pkeyutl -sign -rawin`). func VerifyEd25519(pub ed25519.PublicKey, body, sig []byte) error { if pub == nil { return errors.New("no public key configured") } if len(sig) != ed25519.SignatureSize { return fmt.Errorf("signature has wrong length: %d (want %d)", len(sig), ed25519.SignatureSize) } if !ed25519.Verify(pub, body, sig) { return errors.New("signature does not verify against trusted public key") } return nil }