Check for changes in PerformUploadDeviceKeys (#2233)

* Don't generate key change notifs if nothing changed on cross-signing upload

* Check both directions of changes
This commit is contained in:
Neil Alexander 2022-03-01 11:00:54 +00:00 committed by GitHub
parent a23fda6626
commit 58bf91a585
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -166,8 +166,10 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
} }
// We can't have a self-signing or user-signing key without a master // We can't have a self-signing or user-signing key without a master
// key, so make sure we have one of those. // key, so make sure we have one of those. We will also only actually do
if !hasMasterKey { // something if any of the specified keys in the request are different
// to what we've got in the database, to avoid generating key change
// notifications unnecessarily.
existingKeys, err := a.DB.CrossSigningKeysDataForUser(ctx, req.UserID) existingKeys, err := a.DB.CrossSigningKeysDataForUser(ctx, req.UserID)
if err != nil { if err != nil {
res.Error = &api.KeyError{ res.Error = &api.KeyError{
@ -176,18 +178,43 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P
return return
} }
_, hasMasterKey = existingKeys[gomatrixserverlib.CrossSigningKeyPurposeMaster]
}
// If we still can't find a master key for the user then stop the upload. // If we still can't find a master key for the user then stop the upload.
// This satisfies the "Fails to upload self-signing key without master key" test. // This satisfies the "Fails to upload self-signing key without master key" test.
if !hasMasterKey { if !hasMasterKey {
if _, hasMasterKey = existingKeys[gomatrixserverlib.CrossSigningKeyPurposeMaster]; !hasMasterKey {
res.Error = &api.KeyError{ res.Error = &api.KeyError{
Err: "No master key was found", Err: "No master key was found",
IsMissingParam: true, IsMissingParam: true,
} }
return return
} }
}
// Check if anything actually changed compared to what we have in the database.
changed := false
for _, purpose := range []gomatrixserverlib.CrossSigningKeyPurpose{
gomatrixserverlib.CrossSigningKeyPurposeMaster,
gomatrixserverlib.CrossSigningKeyPurposeSelfSigning,
gomatrixserverlib.CrossSigningKeyPurposeUserSigning,
} {
old, gotOld := existingKeys[purpose]
new, gotNew := toStore[purpose]
if gotOld != gotNew {
// A new key purpose has been specified that we didn't know before,
// or one has been removed.
changed = true
break
}
if !bytes.Equal(old, new) {
// One of the existing keys for a purpose we already knew about has
// changed.
changed = true
break
}
}
if !changed {
return
}
// Store the keys. // Store the keys.
if err := a.DB.StoreCrossSigningKeysForUser(ctx, req.UserID, toStore); err != nil { if err := a.DB.StoreCrossSigningKeysForUser(ctx, req.UserID, toStore); err != nil {