( ctx context.Context, userID string, queryRes *api.QueryKeysResponse, signatures map[string]map[gomatrixserverlib.KeyID]gomatrixserverlib.CrossSigningForKeyOrDevice, )
| 400 | } |
| 401 | |
| 402 | func (a *KeyInternalAPI) processOtherSignatures( |
| 403 | ctx context.Context, userID string, queryRes *api.QueryKeysResponse, |
| 404 | signatures map[string]map[gomatrixserverlib.KeyID]gomatrixserverlib.CrossSigningForKeyOrDevice, |
| 405 | ) error { |
| 406 | // Here we will process: |
| 407 | // * A user signing someone else's master keys using their user-signing keys |
| 408 | |
| 409 | for targetUserID, forTargetUserID := range signatures { |
| 410 | for _, signature := range forTargetUserID { |
| 411 | switch sig := signature.CrossSigningBody.(type) { |
| 412 | case *gomatrixserverlib.CrossSigningKey: |
| 413 | // Find the local copy of the master key. We'll use this to be |
| 414 | // sure that the supplied stanza matches the key that we think it |
| 415 | // should be. |
| 416 | masterKey, ok := queryRes.MasterKeys[targetUserID] |
| 417 | if !ok { |
| 418 | return fmt.Errorf("failed to find master key for user %q", targetUserID) |
| 419 | } |
| 420 | |
| 421 | // For each key ID, write the signatures. Maybe there'll be more |
| 422 | // than one algorithm in the future so it's best not to focus on |
| 423 | // everything being ed25519:. |
| 424 | for targetKeyID, suppliedKeyData := range sig.Keys { |
| 425 | // The master key will be supplied in the request, but we should |
| 426 | // make sure that it matches what we think the master key should |
| 427 | // actually be. |
| 428 | localKeyData, lok := masterKey.Keys[targetKeyID] |
| 429 | if !lok { |
| 430 | return fmt.Errorf("uploaded master key %q for user %q doesn't match local copy", targetKeyID, targetUserID) |
| 431 | } else if !bytes.Equal(suppliedKeyData, localKeyData) { |
| 432 | return fmt.Errorf("uploaded master key %q for user %q doesn't match local copy", targetKeyID, targetUserID) |
| 433 | } |
| 434 | |
| 435 | // We only care about the signatures from the uploading user, so |
| 436 | // we will ignore anything that didn't originate from them. |
| 437 | userSigs, ok := sig.Signatures[userID] |
| 438 | if !ok { |
| 439 | return fmt.Errorf("there are no signatures on master key %q from uploading user %q", targetKeyID, userID) |
| 440 | } |
| 441 | |
| 442 | for originKeyID, originSig := range userSigs { |
| 443 | if err := a.DB.StoreCrossSigningSigsForTarget( |
| 444 | ctx, userID, originKeyID, targetUserID, targetKeyID, originSig, |
| 445 | ); err != nil { |
| 446 | return fmt.Errorf("a.DB.StoreCrossSigningKeysForTarget: %w", err) |
| 447 | } |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | default: |
| 452 | // Users should only be signing another person's master key, |
| 453 | // so if we're here, it's probably because it's actually a |
| 454 | // gomatrixserverlib.DeviceKeys, which doesn't make sense. |
| 455 | } |
| 456 | } |
| 457 | } |
| 458 | |
| 459 | return nil |
no test coverage detected