package omemo import ( "fmt" "dev.narayana.im/narayana/telegabber/e2ee/omemo/libsignal" ) // Version identifies which OMEMO wire-format generation a message, device // list, or bundle uses - the full namespace+XML dialect, not just the // underlying crypto-engine version (see libsignal.ProtocolVersionV3/V4, // which is a strictly coarser, two-way distinction shared by two of the // three versions below). type Version int const ( // Omemo0 is the original "siacs" OMEMO (eu.siacs.conversations.axolotl, // XEP-0384 <= 0.3.0): libsignal.ProtocolVersionV3, AES-128-GCM directly // on the plaintext body, key||tag distributed per-device, element // present. Still the most widely deployed version as of this writing, // and the current implementation priority. Omemo0 Version = iota // Omemo1 is urn:xmpp:omemo:1 (XEP-0384 0.4.0-0.7.x, introduced // 2020-03-08): libsignal.ProtocolVersionV4, AES-256-CBC+HMAC-SHA256 // (via HKDF) over an SCE envelope using the OLD (pre-0.4.0) XEP-0420 // dialect: root element , inner // wrapper . Confirmed by reading the archived XEP-0420 0.3.2 // spec directly (https://xmpp.org/extensions/attic/xep-0420-0.3.2.html), // not assumed - see sceEncodeV0/sceDecodeV0. Omemo1 // Omemo2 is urn:xmpp:omemo:2 (XEP-0384 0.8.0+, current spec): // libsignal.ProtocolVersionV4, the same AES-256-CBC+HMAC-SHA256 scheme // as Omemo1, but over the NEW (XEP-0420 0.4.0+) dialect: root element // , inner wrapper . Omemo2 ) func (v Version) String() string { switch v { case Omemo0: return "omemo0" case Omemo1: return "omemo1" case Omemo2: return "omemo2" default: return "omemo?" } } // ParseVersion maps an e2ee.Variant string (omemo0/omemo1/omemo2 - see // Version.String()) back to a Version, at every point the generic // e2ee.Backend interface hands one in (DeviceListNode, BundleNode, // PublishedIdentity, PublishedBundle). func ParseVersion(s string) (Version, error) { switch s { case "omemo0": return Omemo0, nil case "omemo1": return Omemo1, nil case "omemo2": return Omemo2, nil default: return 0, fmt.Errorf("omemo: unknown version %q (want omemo0, omemo1, or omemo2)", s) } } // libsignalVersion returns the underlying Signal-protocol wire version // this OMEMO version uses. Omemo1 and Omemo2 share the same crypto-engine // version - libomemo-c itself only branches on "message_version >= 4", not // on which OMEMO namespace is in play (confirmed by reading protocol.c) - // they differ only in the outer XML/SCE dialect (see envelope.go). func (v Version) libsignalVersion() int { if v == Omemo0 { return libsignal.ProtocolVersionV3 } return libsignal.ProtocolVersionV4 }