mirror of
https://dev.narayana.im/narayana/telegabber.git
synced 2026-08-05 12:17:06 +00:00
83 lines
2.6 KiB
Go
83 lines
2.6 KiB
Go
package omemo
|
|
|
|
import "encoding/xml"
|
|
|
|
// Device-list document parsing/encoding for all three OMEMO versions.
|
|
// Omemo1 and Omemo2 share an identical element shape (only the namespace
|
|
// differs - the XEP-0384 0.8.0 changelog only calls out SCE-related and
|
|
// namespace renames, nothing about the device-list/bundle schema itself,
|
|
// and 0.4.0/Omemo1's own changelog entry that introduced this schema
|
|
// doesn't mention it changing again later), so one xepDeviceList struct
|
|
// serves both: its XMLName tag omits the namespace, which makes Go's
|
|
// encoding/xml match on local name only during Unmarshal (so it accepts
|
|
// either namespace), while Marshal gets the right namespace by having the
|
|
// caller set XMLName explicitly before encoding.
|
|
|
|
// Namespace strings shared by both the device-list and bundle documents
|
|
// (see bundle.go) - both document kinds are just different local element
|
|
// names within the same OMEMO namespace.
|
|
const (
|
|
omemo0NS = "eu.siacs.conversations.axolotl"
|
|
omemo1NS = "urn:xmpp:omemo:1"
|
|
omemo2NS = "urn:xmpp:omemo:2"
|
|
)
|
|
|
|
type omemo0DeviceList struct {
|
|
XMLName xml.Name `xml:"eu.siacs.conversations.axolotl list"`
|
|
Devices []omemo0Device `xml:"device"`
|
|
}
|
|
|
|
type omemo0Device struct {
|
|
ID uint32 `xml:"id,attr"`
|
|
}
|
|
|
|
type xepDeviceList struct {
|
|
XMLName xml.Name `xml:"devices"`
|
|
Devices []xepDevice `xml:"device"`
|
|
}
|
|
|
|
type xepDevice struct {
|
|
ID uint32 `xml:"id,attr"`
|
|
Label string `xml:"label,attr,omitempty"`
|
|
LabelSig string `xml:"labelsig,attr,omitempty"`
|
|
}
|
|
|
|
// parseDeviceList extracts device ids from a device-list document, in
|
|
// whichever of the three known namespaces it's in.
|
|
func parseDeviceList(raw []byte) ([]uint32, error) {
|
|
var omemo0 omemo0DeviceList
|
|
if err := xml.Unmarshal(raw, &omemo0); err == nil {
|
|
ids := make([]uint32, len(omemo0.Devices))
|
|
for i, d := range omemo0.Devices {
|
|
ids[i] = d.ID
|
|
}
|
|
return ids, nil
|
|
}
|
|
|
|
var xep xepDeviceList
|
|
if err := xml.Unmarshal(raw, &xep); err != nil {
|
|
return nil, err
|
|
}
|
|
ids := make([]uint32, len(xep.Devices))
|
|
for i, d := range xep.Devices {
|
|
ids[i] = d.ID
|
|
}
|
|
return ids, nil
|
|
}
|
|
|
|
// encodeDeviceList produces a device-list document for this gateway's own
|
|
// published identity, in the namespace matching version.
|
|
func encodeDeviceList(version Version, deviceID uint32) ([]byte, error) {
|
|
if version == Omemo0 {
|
|
return xml.Marshal(omemo0DeviceList{Devices: []omemo0Device{{ID: deviceID}}})
|
|
}
|
|
ns := omemo1NS
|
|
if version == Omemo2 {
|
|
ns = omemo2NS
|
|
}
|
|
list := xepDeviceList{
|
|
XMLName: xml.Name{Space: ns, Local: "devices"},
|
|
Devices: []xepDevice{{ID: deviceID}},
|
|
}
|
|
return xml.Marshal(list)
|
|
}
|