// 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 /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 /. 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) }