From 4802216752289efb0cf6fc0a47c16e9ed11fda18 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 29 Jul 2021 15:29:16 +0100 Subject: [PATCH] Initial signature upload support maybe --- keyserver/internal/cross_signing.go | 66 +++++++++++++++++++++++++++++ keyserver/storage/interface.go | 2 + keyserver/storage/shared/storage.go | 15 +++++++ 3 files changed, 83 insertions(+) diff --git a/keyserver/internal/cross_signing.go b/keyserver/internal/cross_signing.go index b08a6e45..ffdcfb4d 100644 --- a/keyserver/internal/cross_signing.go +++ b/keyserver/internal/cross_signing.go @@ -160,6 +160,72 @@ func (a *KeyInternalAPI) PerformUploadDeviceKeys(ctx context.Context, req *api.P } func (a *KeyInternalAPI) PerformUploadDeviceSignatures(ctx context.Context, req *api.PerformUploadDeviceSignaturesRequest, res *api.PerformUploadDeviceSignaturesResponse) { + for targetUserID, forTarget := range req.CrossSigningSignatures { + for targetID, signable := range forTarget { + switch obj := signable.(type) { + case *gomatrixserverlib.CrossSigningKey: // signing a key + // Check to see if we know about the target user ID and key ID. If we + // don't then we'll just drop the signatures. + keys, err := a.DB.CrossSigningKeysForUser(ctx, targetUserID) + if err != nil { + continue + } + foundMatchingKey := false + for _, key := range keys { + if key.Encode() == targetID { + foundMatchingKey = true + } + } + if !foundMatchingKey { + continue + } + + /* + keyJSON, err := json.Marshal(obj) + if err != nil { + res.Error = &api.KeyError{ + Err: fmt.Sprintf("The JSON of the signable object is invalid: %s", err.Error()), + } + return + } + */ + + for originUserID, forOriginUserID := range obj.Signatures { + for originKeyID, signature := range forOriginUserID { + // TODO: sig checking + /* + if err := gomatrixserverlib.VerifyJSON(originUserID, originKeyID, ed25519.PublicKey(masterKey), keyJSON); err != nil { + res.Error = &api.KeyError{ + Err: fmt.Sprintf("The %q sub-key failed master key signature verification: %s", purpose, err.Error()), + IsInvalidSignature: true, + } + return + } + */ + + err := a.DB.StoreCrossSigningSigsForTarget(ctx, originUserID, originKeyID, targetUserID, gomatrixserverlib.KeyID(targetID), signature) + if err != nil { + res.Error = &api.KeyError{ + Err: "Failed to store cross-signing keys for target: " + err.Error(), + } + return + } + } + } + + case *gomatrixserverlib.CrossSigningSignature: // signing a device + // TODO: signatures for devices + continue + + default: + res.Error = &api.KeyError{ + Err: "Found an unexpected item type", + } + return + } + } + } + res.Error = &api.KeyError{ Err: "Not supported yet", } diff --git a/keyserver/storage/interface.go b/keyserver/storage/interface.go index e0eeefcf..e46afc44 100644 --- a/keyserver/storage/interface.go +++ b/keyserver/storage/interface.go @@ -79,5 +79,7 @@ type Database interface { CrossSigningKeysForUser(ctx context.Context, userID string) (api.CrossSigningKeyMap, error) CrossSigningSigsForTarget(ctx context.Context, targetUserID string, targetKeyID gomatrixserverlib.KeyID) (api.CrossSigningSigMap, error) + StoreCrossSigningKeysForUser(ctx context.Context, userID string, keyMap api.CrossSigningKeyMap, streamID int64) error + StoreCrossSigningSigsForTarget(ctx context.Context, originUserID string, originKeyID gomatrixserverlib.KeyID, targetUserID string, targetKeyID gomatrixserverlib.KeyID, signature gomatrixserverlib.Base64Bytes) error } diff --git a/keyserver/storage/shared/storage.go b/keyserver/storage/shared/storage.go index 6a63f3c2..0ae4f6f5 100644 --- a/keyserver/storage/shared/storage.go +++ b/keyserver/storage/shared/storage.go @@ -179,3 +179,18 @@ func (d *Database) StoreCrossSigningKeysForUser(ctx context.Context, userID stri return nil }) } + +// StoreCrossSigningSigsForTarget stores a signature for a target user ID and key/dvice. +func (d *Database) StoreCrossSigningSigsForTarget( + ctx context.Context, + originUserID string, originKeyID gomatrixserverlib.KeyID, + targetUserID string, targetKeyID gomatrixserverlib.KeyID, + signature gomatrixserverlib.Base64Bytes, +) error { + return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error { + if err := d.CrossSigningSigsTable.InsertCrossSigningSigsForTarget(ctx, nil, originUserID, originKeyID, targetUserID, targetKeyID, signature); err != nil { + return fmt.Errorf("d.CrossSigningSigsTable.InsertCrossSigningSigsForTarget: %w", err) + } + return nil + }) +}