telegabber/e2ee/types.go
2026-07-28 20:32:56 -04:00

97 lines
4.4 KiB
Go

// Package e2ee is a backend-agnostic end-to-end encryption abstraction for
// telegabber's XMPP side. It knows nothing about stanza XML shape - a
// Backend deals only in opaque byte envelopes; wrapping/unwrapping those
// into <encrypted>/PEP XML is the caller's job (see e2ee/omemo for the
// first, and so far only, implementation, and its envelope.go for the
// XEP-0384 wire format specifically).
package e2ee
// PeerID identifies one bridging endpoint's cryptographic identity scope.
// For telegabber this is always a bare XMPP JID: either a bridged chat's
// pseudo-JID (whose keys the gateway owns and generates) or a real remote
// user's bare JID (whose keys the gateway only ever fetches).
type PeerID string
// DeviceID is an opaque per-backend device identifier, serialized as its
// natural string form (OMEMO: decimal uint32; a hypothetical single-key
// backend could always use "0" or the empty string).
type DeviceID string
// Envelope is an opaque, backend-defined encrypted payload, plus enough
// metadata for the xmpp layer to build the wire XML generically.
type Envelope struct {
Backend string // e.g. "omemo" - which backend produced Raw, so the xmpp layer picks the right XML shape
Raw []byte // backend-specific serialized envelope
}
// Namespaces is what a Backend wants advertised/served for a given peer.
type Namespaces struct {
Disco []string // disco#info features to advertise (e.g. "...+notify" hints)
EME string // urn:xmpp:eme:0 encryption-namespace hint for non-supporting clients
}
// DeviceListDoc is an opaque, backend-defined serialization of a peer's
// PEP device-list document (fetched from them, or published for a chat
// pseudo-JID we own).
type DeviceListDoc struct{ Raw []byte }
// BundleDoc is an opaque, backend-defined serialization of one device's
// PEP bundle document.
type BundleDoc struct{ Raw []byte }
// DeviceInfo describes one known device of a peer, for trust-listing
// ad-hoc commands.
type DeviceInfo struct {
ID DeviceID
Trusted bool
Fingerprint string
}
// Backend is the minimal contract a pluggable E2EE scheme must implement.
type Backend interface {
// Name identifies the backend for config/logging (e.g. "omemo").
Name() string
// Namespaces lists what this backend wants advertised/served.
Namespaces() Namespaces
// EnsureIdentity creates (idempotently) a local cryptographic identity
// for a PeerID this gateway owns (a bridged chat pseudo-JID - built via
// OwnedPeer, since a chat pseudo-JID alone isn't globally unique across
// telegabber's multiple bridged Telegram logins), generating and
// persisting whatever key material the backend needs.
EnsureIdentity(peer PeerID) error
// PublishedIdentity returns the material this gateway must SERVE to
// pubsub GET requests for its own PeerID (an OwnedPeer - see
// EnsureIdentity) device list, pre-marshaled to opaque bytes the xmpp
// layer wraps in <items>/<item>.
PublishedIdentity(peer PeerID) (DeviceListDoc, error)
// PublishedBundle is the same, for one specific device's bundle node.
PublishedBundle(peer PeerID, device DeviceID) (BundleDoc, error)
// IngestRemoteDeviceList / IngestRemoteBundle feed the results of an
// outbound PEP fetch (device-list, then per-device bundle) for a real
// remote peer (owner is an OwnedPeer identifying which of this
// gateway's identities is doing the fetching; peer is the remote's
// plain bare JID, no scoping needed) into the backend's store,
// establishing/refreshing sessions as needed (trust decisions happen
// inside here).
IngestRemoteDeviceList(owner PeerID, peer PeerID, doc DeviceListDoc) error
IngestRemoteBundle(owner PeerID, peer PeerID, device DeviceID, doc BundleDoc) error
// Encrypt produces an opaque envelope addressed to every known device
// of every given recipient, ready to be embedded in a stanza by the
// xmpp layer. from is the identity doing the encrypting (an OwnedPeer -
// see EnsureIdentity); to are the real remote peers' plain bare JIDs.
Encrypt(from PeerID, to []PeerID, plaintext []byte) (Envelope, error)
// Decrypt consumes an inbound envelope addressed to "to" (an
// OwnedPeer - see EnsureIdentity) from "from" (the real remote peer's
// plain bare JID) and returns plaintext.
Decrypt(from PeerID, to PeerID, env Envelope) ([]byte, error)
// Devices lists peer's known devices, as seen from owner's (an
// OwnedPeer) point of view - for trust-listing ad-hoc commands.
Devices(owner PeerID, peer PeerID) ([]DeviceInfo, error)
}