Sign and upload master keys of other users

Signed-off-by: Nikos Filippakis <me@nfil.dev>
This commit is contained in:
Nikos Filippakis 2020-08-25 20:46:39 +02:00
commit f5e1f1e414
4 changed files with 76 additions and 7 deletions

View file

@ -1105,6 +1105,12 @@ func (cli *Client) UploadCrossSigningKeys(keys *UploadCrossSigningKeysReq, uiAut
return err
}
func (cli *Client) UploadSignatures(req *ReqUploadSignatures) (resp *RespUploadSignatures, err error) {
urlPath := cli.BuildBaseURL("_matrix", "client", "unstable", "keys", "signatures", "upload")
_, err = cli.MakeRequest("POST", urlPath, req, &resp)
return
}
// GetPushRules returns the push notification rules for the global scope.
func (cli *Client) GetPushRules() (*pushrules.PushRuleset, error) {
return cli.GetScopedPushRules("global")

View file

@ -7,6 +7,7 @@
package crypto
import (
"github.com/pkg/errors"
"maunium.net/go/mautrix"
"maunium.net/go/mautrix/crypto/olm"
"maunium.net/go/mautrix/id"
@ -200,3 +201,65 @@ func (mach *OlmMachine) uploadCrossSigningKeysToServer(keys *CrossSigningKeysCac
}
})
}
// SignUserAndUpload creates a cross-signing signature for a user, stores it and uploads it to the server.
func (mach *OlmMachine) SignUserAndUpload(userID id.UserID) error {
if mach.crossSigningKeys == nil {
return errors.New("No cross-signing keys found")
}
if userID == mach.Client.UserID {
return nil
}
keys, err := mach.CryptoStore.GetCrossSigningKeys(userID)
if err != nil {
return err
}
masterKey, ok := keys[id.XSUsageMaster]
if !ok {
return errors.Errorf("No master key found for user %v", userID)
}
userSigningKey := mach.crossSigningKeys.UserSigningKey
masterKeyObj := mautrix.ReqKeysSignatures{
UserID: userID,
Usage: []id.CrossSigningUsage{id.XSUsageMaster},
Keys: map[id.KeyID]id.Ed25519{
id.NewKeyID(id.KeyAlgorithmEd25519, masterKey.String()): masterKey,
},
}
signature, err := userSigningKey.SignJSON(masterKeyObj)
if err != nil {
return err
}
masterKeyObj.Signatures = mautrix.Signatures{
mach.Client.UserID: map[id.KeyID]string{
id.NewKeyID(id.KeyAlgorithmEd25519, userSigningKey.PublicKey.String()): signature,
},
}
mach.Log.Trace("Signed master key for user %v: `%v`", userID, signature)
resp, err := mach.Client.UploadSignatures(&mautrix.ReqUploadSignatures{
userID: map[string]mautrix.ReqKeysSignatures{
masterKey.String(): masterKeyObj,
},
})
if err != nil {
return err
}
if len(resp.Failures) > 0 {
return errors.Errorf("Key uploading failures: %v", resp.Failures)
}
if err := mach.CryptoStore.PutSignature(userID, masterKey, mach.Client.UserID, userSigningKey.PublicKey, signature); err != nil {
return err
}
return nil
}
// SignDeviceAndUpload creates a cross-signing signature for a device, stores it and uploads it to the server.
func (mach *OlmMachine) SignDeviceAndUpload(device *DeviceIdentity) error {
return nil
}

View file

@ -211,7 +211,7 @@ var Upgrades = [...]upgradeFunc{
if _, err := tx.Exec(
`CREATE TABLE IF NOT EXISTS crypto_cross_signing_keys (
user_id VARCHAR(255) NOT NULL,
usage CHAR(20) NOT NULL,
usage VARCHAR(20) NOT NULL,
key CHAR(43) NOT NULL,
PRIMARY KEY (user_id, usage)
)`,

View file

@ -181,12 +181,12 @@ type ReqUploadKeys struct {
}
type ReqKeysSignatures struct {
UserID id.UserID `json:"user_id"`
DeviceID id.DeviceID `json:"device_id,omitempty"`
Algorithms []id.Algorithm `json:"algorithms,omitempty"`
Usage []id.CrossSigningUsage `json:"usage,omitempty"`
Keys KeyMap `json:"keys"`
Signatures Signatures `json:"signatures"`
UserID id.UserID `json:"user_id"`
DeviceID id.DeviceID `json:"device_id,omitempty"`
Algorithms []id.Algorithm `json:"algorithms,omitempty"`
Usage []id.CrossSigningUsage `json:"usage,omitempty"`
Keys map[id.KeyID]id.Ed25519 `json:"keys"`
Signatures Signatures `json:"signatures"`
}
type ReqUploadSignatures map[id.UserID]map[string]ReqKeysSignatures