diff --git a/keyserver/api/api.go b/keyserver/api/api.go index 3933961c1..a13697dd2 100644 --- a/keyserver/api/api.go +++ b/keyserver/api/api.go @@ -15,8 +15,10 @@ package api import ( + "bytes" "context" "encoding/json" + "fmt" "strings" "time" @@ -73,6 +75,22 @@ type DeviceMessage struct { DeviceChangeID int64 } +func (m1 *DeviceMessage) DeviceKeysEqual(m2 *DeviceMessage) (bool, error) { + if m1.DeviceKeys == nil || m2.DeviceKeys == nil { + return false, fmt.Errorf("not device keys") + } + if m1.UserID != m2.UserID || m1.DeviceID != m2.DeviceID { + return false, fmt.Errorf("different user ID or device ID") + } + if len(m1.KeyJSON) == 0 || len(m2.KeyJSON) == 0 { + return false, nil + } + if m1.DisplayName != m2.DisplayName { + return false, nil + } + return bytes.Equal(m1.KeyJSON, m2.KeyJSON), nil +} + // DeviceKeys represents a set of device keys for a single device // https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-keys-upload type DeviceKeys struct { diff --git a/keyserver/internal/internal.go b/keyserver/internal/internal.go index 0c264b718..7eeae5b20 100644 --- a/keyserver/internal/internal.go +++ b/keyserver/internal/internal.go @@ -718,7 +718,10 @@ func emitDeviceKeyChanges(producer KeyChangeProducer, existing, new []api.Device for _, existingKey := range existing { // Do not treat the absence of keys as equal, or else we will not emit key changes // when users delete devices which never had a key to begin with as both KeyJSONs are nil. - if bytes.Equal(existingKey.KeyJSON, newKey.KeyJSON) && len(existingKey.KeyJSON) > 0 { + // if bytes.Equal(existingKey.KeyJSON, newKey.KeyJSON) && len(existingKey.KeyJSON) > 0 { + if equal, err := existingKey.DeviceKeysEqual(&newKey); err != nil { + continue + } else if equal { exists = true break }