mirror of
https://mau.dev/mautrix/go.git
synced 2026-03-14 14:25:53 +01:00
Checking of trust for devices and users based on cross-signing
signatures Signed-off-by: Nikos Filippakis <me@nfil.dev>
This commit is contained in:
parent
6159b22f94
commit
50bb209da7
11 changed files with 292 additions and 34 deletions
|
|
@ -64,7 +64,7 @@ func (account *OlmAccount) getInitialKeys(userID id.UserID, deviceID id.DeviceID
|
|||
|
||||
deviceKeys.Signatures = mautrix.Signatures{
|
||||
userID: {
|
||||
id.NewDeviceKeyID(id.KeyAlgorithmEd25519, deviceID): signature,
|
||||
id.NewKeyID(id.KeyAlgorithmEd25519, deviceID.String()): signature,
|
||||
},
|
||||
}
|
||||
return deviceKeys
|
||||
|
|
@ -83,7 +83,7 @@ func (account *OlmAccount) getOneTimeKeys(userID id.UserID, deviceID id.DeviceID
|
|||
signature, _ := account.Internal.SignJSON(key)
|
||||
key.Signatures = mautrix.Signatures{
|
||||
userID: {
|
||||
id.NewDeviceKeyID(id.KeyAlgorithmEd25519, deviceID): signature,
|
||||
id.NewKeyID(id.KeyAlgorithmEd25519, deviceID.String()): signature,
|
||||
},
|
||||
}
|
||||
key.IsSigned = true
|
||||
|
|
|
|||
|
|
@ -54,12 +54,81 @@ func (mach *OlmMachine) storeCrossSigningKeys(crossSigningKeys map[id.UserID]mau
|
|||
|
||||
// IsDeviceTrusted returns whether a device has been determined to be trusted either through verification or cross-signing.
|
||||
func (mach *OlmMachine) IsDeviceTrusted(device *DeviceIdentity) bool {
|
||||
// TODO if not verified / blacklisted then check via cross-signing to determine trust
|
||||
return device.Trust == TrustStateVerified
|
||||
userID := device.UserID
|
||||
if device.Trust == TrustStateVerified {
|
||||
return true
|
||||
} else if device.Trust == TrustStateBlacklisted {
|
||||
return false
|
||||
}
|
||||
if !mach.IsUserTrusted(userID) {
|
||||
return false
|
||||
}
|
||||
|
||||
theirKeys, err := mach.CryptoStore.GetCrossSigningKeys(userID)
|
||||
if err != nil {
|
||||
mach.Log.Error("Error retrieving cross-singing key of user %v from database: %v", userID, err)
|
||||
return false
|
||||
}
|
||||
theirMSK, ok := theirKeys[id.XSUsageMaster]
|
||||
if !ok {
|
||||
mach.Log.Error("Master key of user %v not found", userID)
|
||||
return false
|
||||
}
|
||||
theirSSK, ok := theirKeys[id.XSUsageSelfSigning]
|
||||
if !ok {
|
||||
mach.Log.Error("Self-signing key of user %v not found", userID)
|
||||
return false
|
||||
}
|
||||
sskSigExists, err := mach.CryptoStore.IsKeySignedBy(userID, theirSSK, userID, theirMSK)
|
||||
if err != nil {
|
||||
mach.Log.Error("Error retrieving cross-singing signatures for master key of user %v from database: %v", userID, err)
|
||||
return false
|
||||
}
|
||||
if !sskSigExists {
|
||||
mach.Log.Warn("Self-signing key of user %v is not signed by their master key", userID)
|
||||
return false
|
||||
}
|
||||
deviceSigExists, err := mach.CryptoStore.IsKeySignedBy(userID, device.SigningKey, userID, theirSSK)
|
||||
if err != nil {
|
||||
mach.Log.Error("Error retrieving cross-singing signatures for master key of user %v from database: %v", userID, err)
|
||||
return false
|
||||
}
|
||||
return deviceSigExists
|
||||
}
|
||||
|
||||
// IsUserTrusted returns whether a user has been determined to be trusted by our user-signing key having signed their master key.
|
||||
func (mach *OlmMachine) IsUserTrusted(device *DeviceIdentity) bool {
|
||||
// TODO implement
|
||||
return false
|
||||
// In the case the user ID is our own and we have successfully retrieved our cross-signing keys, we trust our own user.
|
||||
func (mach *OlmMachine) IsUserTrusted(userID id.UserID) bool {
|
||||
if mach.crossSigningKeys == nil {
|
||||
return false
|
||||
}
|
||||
if userID == mach.Client.UserID {
|
||||
return true
|
||||
}
|
||||
// first we verify our user-signing key
|
||||
sskSigs, err := mach.CryptoStore.GetSignaturesForKeyBy(mach.Client.UserID, mach.crossSigningKeys.UserSigningKey.PublicKey, mach.Client.UserID)
|
||||
if err != nil {
|
||||
mach.Log.Error("Error retrieving our self-singing key signatures: %v", err)
|
||||
return false
|
||||
}
|
||||
if _, ok := sskSigs[mach.crossSigningKeys.MasterKey.PublicKey]; !ok {
|
||||
// our user-signing key was not signed by our master key
|
||||
return false
|
||||
}
|
||||
theirKeys, err := mach.CryptoStore.GetCrossSigningKeys(userID)
|
||||
if err != nil {
|
||||
mach.Log.Error("Error retrieving cross-singing key of user %v from database: %v", userID, err)
|
||||
return false
|
||||
}
|
||||
theirMskKey, ok := theirKeys[id.XSUsageMaster]
|
||||
if !ok {
|
||||
mach.Log.Error("Master key of user %v not found", userID)
|
||||
return false
|
||||
}
|
||||
sigExists, err := mach.CryptoStore.IsKeySignedBy(userID, theirMskKey, mach.Client.UserID, mach.crossSigningKeys.UserSigningKey.PublicKey)
|
||||
if err != nil {
|
||||
mach.Log.Error("Error retrieving cross-singing signatures for master key of user %v from database: %v", userID, err)
|
||||
return false
|
||||
}
|
||||
return sigExists
|
||||
}
|
||||
|
|
|
|||
145
crypto/cross_sign_test.go
Normal file
145
crypto/cross_sign_test.go
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
// Copyright (c) 2020 Nikos Filippakis
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/crypto/olm"
|
||||
sqlUpgrade "maunium.net/go/mautrix/crypto/sql_store_upgrade"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
func getOlmMachine(t *testing.T) *OlmMachine {
|
||||
db, err := sql.Open("sqlite3", ":memory:?_busy_timeout=5000")
|
||||
if err != nil {
|
||||
t.Fatalf("Error opening db: %v", err)
|
||||
}
|
||||
sqlUpgrade.Upgrade(db, "sqlite3")
|
||||
sqlStore := NewSQLCryptoStore(db, "sqlite3", "accid", id.DeviceID("dev"), []byte("test"), emptyLogger{})
|
||||
|
||||
userID := id.UserID("@mautrix")
|
||||
mk, _ := olm.NewPkSigning()
|
||||
ssk, _ := olm.NewPkSigning()
|
||||
usk, _ := olm.NewPkSigning()
|
||||
|
||||
sqlStore.PutCrossSigningKey(userID, id.XSUsageMaster, mk.PublicKey)
|
||||
sqlStore.PutCrossSigningKey(userID, id.XSUsageSelfSigning, ssk.PublicKey)
|
||||
sqlStore.PutCrossSigningKey(userID, id.XSUsageUserSigning, usk.PublicKey)
|
||||
|
||||
return &OlmMachine{
|
||||
CryptoStore: sqlStore,
|
||||
crossSigningKeys: &CrossSigningKeysCache{
|
||||
MasterKey: mk,
|
||||
SelfSigningKey: ssk,
|
||||
UserSigningKey: usk,
|
||||
},
|
||||
Client: &mautrix.Client{
|
||||
UserID: userID,
|
||||
},
|
||||
Log: emptyLogger{},
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrustOwnDevice(t *testing.T) {
|
||||
m := getOlmMachine(t)
|
||||
ownDevice := &DeviceIdentity{
|
||||
UserID: m.Client.UserID,
|
||||
DeviceID: "device",
|
||||
SigningKey: id.Ed25519("deviceKey"),
|
||||
}
|
||||
if m.IsDeviceTrusted(ownDevice) {
|
||||
t.Error("Own device trusted while it shouldn't be")
|
||||
}
|
||||
|
||||
m.CryptoStore.PutSignature(ownDevice.UserID, m.crossSigningKeys.SelfSigningKey.PublicKey,
|
||||
ownDevice.UserID, m.crossSigningKeys.MasterKey.PublicKey, "sig1")
|
||||
m.CryptoStore.PutSignature(ownDevice.UserID, ownDevice.SigningKey,
|
||||
ownDevice.UserID, m.crossSigningKeys.SelfSigningKey.PublicKey, "sig2")
|
||||
|
||||
if !m.IsUserTrusted(ownDevice.UserID) {
|
||||
t.Error("Own user not trusted while they should be")
|
||||
}
|
||||
if !m.IsDeviceTrusted(ownDevice) {
|
||||
t.Error("Own device not trusted while it should be")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrustOtherUser(t *testing.T) {
|
||||
m := getOlmMachine(t)
|
||||
otherUser := id.UserID("@user")
|
||||
if m.IsUserTrusted(otherUser) {
|
||||
t.Error("Other user trusted while they shouldn't be")
|
||||
}
|
||||
|
||||
theirMasterKey, _ := olm.NewPkSigning()
|
||||
m.CryptoStore.PutCrossSigningKey(otherUser, id.XSUsageMaster, theirMasterKey.PublicKey)
|
||||
|
||||
m.CryptoStore.PutSignature(m.Client.UserID, m.crossSigningKeys.UserSigningKey.PublicKey,
|
||||
m.Client.UserID, m.crossSigningKeys.MasterKey.PublicKey, "sig1")
|
||||
|
||||
// sign them with self-signing instead of user-signing key
|
||||
m.CryptoStore.PutSignature(otherUser, theirMasterKey.PublicKey,
|
||||
m.Client.UserID, m.crossSigningKeys.SelfSigningKey.PublicKey, "invalid_sig")
|
||||
|
||||
if m.IsUserTrusted(otherUser) {
|
||||
t.Error("Other user trusted before their master key has been signed with our user-signing key")
|
||||
}
|
||||
|
||||
m.CryptoStore.PutSignature(otherUser, theirMasterKey.PublicKey,
|
||||
m.Client.UserID, m.crossSigningKeys.UserSigningKey.PublicKey, "sig2")
|
||||
|
||||
if !m.IsUserTrusted(otherUser) {
|
||||
t.Error("Other user not trusted while they should be")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrustOtherDevice(t *testing.T) {
|
||||
m := getOlmMachine(t)
|
||||
otherUser := id.UserID("@user")
|
||||
theirDevice := &DeviceIdentity{
|
||||
UserID: otherUser,
|
||||
DeviceID: "theirDevice",
|
||||
SigningKey: id.Ed25519("theirDeviceKey"),
|
||||
}
|
||||
if m.IsUserTrusted(otherUser) {
|
||||
t.Error("Other user trusted while they shouldn't be")
|
||||
}
|
||||
if m.IsDeviceTrusted(theirDevice) {
|
||||
t.Error("Other device trusted while it shouldn't be")
|
||||
}
|
||||
|
||||
theirMasterKey, _ := olm.NewPkSigning()
|
||||
m.CryptoStore.PutCrossSigningKey(otherUser, id.XSUsageMaster, theirMasterKey.PublicKey)
|
||||
theirSSK, _ := olm.NewPkSigning()
|
||||
m.CryptoStore.PutCrossSigningKey(otherUser, id.XSUsageSelfSigning, theirSSK.PublicKey)
|
||||
|
||||
m.CryptoStore.PutSignature(m.Client.UserID, m.crossSigningKeys.UserSigningKey.PublicKey,
|
||||
m.Client.UserID, m.crossSigningKeys.MasterKey.PublicKey, "sig1")
|
||||
m.CryptoStore.PutSignature(otherUser, theirMasterKey.PublicKey,
|
||||
m.Client.UserID, m.crossSigningKeys.UserSigningKey.PublicKey, "sig2")
|
||||
|
||||
if !m.IsUserTrusted(otherUser) {
|
||||
t.Error("Other user not trusted while they should be")
|
||||
}
|
||||
|
||||
m.CryptoStore.PutSignature(otherUser, theirSSK.PublicKey,
|
||||
otherUser, theirMasterKey.PublicKey, "sig3")
|
||||
|
||||
if m.IsDeviceTrusted(theirDevice) {
|
||||
t.Error("Other device trusted before it has been signed with user's SSK")
|
||||
}
|
||||
|
||||
m.CryptoStore.PutSignature(otherUser, theirDevice.SigningKey,
|
||||
otherUser, theirSSK.PublicKey, "sig4")
|
||||
|
||||
if !m.IsDeviceTrusted(theirDevice) {
|
||||
t.Error("Other device not trusted while it should be")
|
||||
}
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ func (mach *OlmMachine) DecryptMegolmEvent(evt *event.Event) (*event.Event, erro
|
|||
// We don't want to throw these errors as the message can still be decrypted.
|
||||
mach.Log.Debug("Failed to get device %s/%s to verify session %s: %v", evt.Sender, content.DeviceID, sess.ID(), err)
|
||||
// TODO maybe store the info that the device is deleted?
|
||||
} else if device.Trust == TrustStateVerified && len(sess.ForwardingChains) == 0 { // For some reason, matrix-nio had a comment saying not to events decrypted using a forwarded key as verified.
|
||||
} else if mach.IsDeviceTrusted(device) && len(sess.ForwardingChains) == 0 { // For some reason, matrix-nio had a comment saying not to events decrypted using a forwarded key as verified.
|
||||
if device.SigningKey != sess.SigningKey || device.IdentityKey != content.SenderKey {
|
||||
return nil, DeviceKeyMismatch
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,22 @@ func (mach *OlmMachine) fetchKeys(users []id.UserID, sinceToken string, includeU
|
|||
newDevices[deviceID] = newDevice
|
||||
for signerUserID, signerKeys := range deviceKeys.Signatures {
|
||||
for signerKey, signature := range signerKeys {
|
||||
if signKey, ok := deviceKeys.Keys[signerKey]; ok {
|
||||
// verify and save self-signing key signature for each device
|
||||
if selfSignKeys, ok := resp.SelfSigningKeys[signerUserID]; ok {
|
||||
for _, pubKey := range selfSignKeys.Keys {
|
||||
if verified, err := olm.VerifySignatureJSON(deviceKeys, signerUserID, pubKey.String(), pubKey); verified {
|
||||
if signKey, ok := deviceKeys.Keys[id.DeviceKeyID(signerKey)]; ok {
|
||||
signature := deviceKeys.Signatures[signerUserID][id.NewKeyID(id.KeyAlgorithmEd25519, pubKey.String())]
|
||||
mach.Log.Trace("Verified self-signing signature for device %v: `%v`", deviceID, signature)
|
||||
mach.CryptoStore.PutSignature(userID, id.Ed25519(signKey), signerUserID, pubKey, signature)
|
||||
}
|
||||
} else {
|
||||
mach.Log.Warn("Error verifying device self-signing signature: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// save signature of device made by its own device signing key
|
||||
if signKey, ok := deviceKeys.Keys[id.DeviceKeyID(signerKey)]; ok {
|
||||
mach.CryptoStore.PutSignature(userID, id.Ed25519(signKey), signerUserID, id.Ed25519(signKey), signature)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ func (mach *OlmMachine) encryptGroupSessionForUser(session *OutboundGroupSession
|
|||
Reason: "Device is blacklisted",
|
||||
}}
|
||||
session.Users[userKey] = OGSIgnored
|
||||
} else if !mach.AllowUnverifiedDevices && device.Trust == TrustStateUnset {
|
||||
} else if !mach.AllowUnverifiedDevices && !mach.IsDeviceTrusted(device) {
|
||||
mach.Log.Debug("Not encrypting group session %s for %s of %s: device is not verified", session.ID(), deviceID, userID)
|
||||
withheld[deviceID] = &event.Content{Parsed: &event.RoomKeyWithheldEventContent{
|
||||
RoomID: session.RoomID,
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ func (mach *OlmMachine) defaultAllowKeyShare(device *DeviceIdentity, _ event.Req
|
|||
} else if device.Trust == TrustStateBlacklisted {
|
||||
mach.Log.Debug("Ignoring key request from blacklisted device %s", device.DeviceID)
|
||||
return &KeyShareRejectBlacklisted
|
||||
} else if device.Trust == TrustStateVerified {
|
||||
} else if mach.IsDeviceTrusted(device) {
|
||||
mach.Log.Debug("Accepting key request from verified device %s", device.DeviceID)
|
||||
return nil
|
||||
} else if mach.ShareKeysToUnverifiedDevices {
|
||||
|
|
|
|||
|
|
@ -8,12 +8,14 @@ import "C"
|
|||
import (
|
||||
"crypto/rand"
|
||||
"unsafe"
|
||||
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
// PkSigning stores a key pair for signing messages.
|
||||
type PkSigning struct {
|
||||
int *C.OlmPkSigning
|
||||
PublicKey string
|
||||
PublicKey id.Ed25519
|
||||
Seed []byte
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +57,7 @@ func NewPkSigningFromSeed(seed []byte) (*PkSigning, error) {
|
|||
unsafe.Pointer(&seed[0]), C.size_t(len(seed))) == errorVal() {
|
||||
return nil, p.lastError()
|
||||
}
|
||||
p.PublicKey = string(pubKey)
|
||||
p.PublicKey = id.Ed25519(pubKey)
|
||||
p.Seed = seed
|
||||
return p, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -588,7 +588,7 @@ func (store *SQLCryptoStore) PutCrossSigningKey(userID id.UserID, usage id.Cross
|
|||
err = fmt.Errorf("unsupported dialect %s", store.Dialect)
|
||||
}
|
||||
if err != nil {
|
||||
store.Log.Warn("Failed to store device: %v", err)
|
||||
store.Log.Warn("Failed to store cross-signing key: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -630,33 +630,37 @@ func (store *SQLCryptoStore) PutSignature(signedUserID id.UserID, signedKey id.E
|
|||
err = fmt.Errorf("unsupported dialect %s", store.Dialect)
|
||||
}
|
||||
if err != nil {
|
||||
store.Log.Warn("Failed to store device: %v", err)
|
||||
store.Log.Warn("Failed to store signature: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignaturesForKey retrieves the stored signatures for a given cross-signing or device key.
|
||||
func (store *SQLCryptoStore) GetSignaturesForKey(userID id.UserID, key id.Ed25519) (map[id.UserID]map[id.Ed25519]string, error) {
|
||||
rows, err := store.DB.Query("SELECT signer_user_id, signer_key, signature FROM crypto_cross_signing_signatures WHERE signed_user_id=$1 AND signed_key=$2", userID, key)
|
||||
// GetSignaturesForKeyBy retrieves the stored signatures for a given cross-signing or device key, by the given signer.
|
||||
func (store *SQLCryptoStore) GetSignaturesForKeyBy(userID id.UserID, key id.Ed25519, signerID id.UserID) (map[id.Ed25519]string, error) {
|
||||
rows, err := store.DB.Query("SELECT signer_key, signature FROM crypto_cross_signing_signatures WHERE signed_user_id=$1 AND signed_key=$2 AND signer_user_id=$3", userID, key, signerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := make(map[id.UserID]map[id.Ed25519]string)
|
||||
data := make(map[id.Ed25519]string)
|
||||
for rows.Next() {
|
||||
var signerUserID id.UserID
|
||||
var signerKey id.Ed25519
|
||||
var signature string
|
||||
err := rows.Scan(&signerUserID, &signerKey, &signature)
|
||||
err := rows.Scan(&signerKey, &signature)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
signerKeys, ok := data[signerUserID]
|
||||
if !ok {
|
||||
signerKeys = make(map[id.Ed25519]string)
|
||||
data[signerUserID] = signerKeys
|
||||
}
|
||||
signerKeys[signerKey] = signature
|
||||
data[signerKey] = signature
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// IsKeySignedBy returns whether a cross-signing or device key is signed by the given signer.
|
||||
func (store *SQLCryptoStore) IsKeySignedBy(userID id.UserID, key id.Ed25519, signerID id.UserID, signerKey id.Ed25519) (bool, error) {
|
||||
sigs, err := store.GetSignaturesForKeyBy(userID, key, signerID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
_, ok := sigs[signerKey]
|
||||
return ok, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,8 +147,10 @@ type Store interface {
|
|||
GetCrossSigningKeys(id.UserID) (map[id.CrossSigningUsage]id.Ed25519, error)
|
||||
// PutSignature stores a signature of a cross-signing or device key along with the signer's user ID and key.
|
||||
PutSignature(id.UserID, id.Ed25519, id.UserID, id.Ed25519, string) error
|
||||
// GetSignatures retrieves the stored signatures for a given cross-signing or device key.
|
||||
GetSignaturesForKey(id.UserID, id.Ed25519) (map[id.UserID]map[id.Ed25519]string, error)
|
||||
// GetSignaturesForKeyBy returns the signatures for a cross-signing or device key by the given signer.
|
||||
GetSignaturesForKeyBy(id.UserID, id.Ed25519, id.UserID) (map[id.Ed25519]string, error)
|
||||
// IsKeySignedBy returns whether a cross-signing or device key is signed by the given signer.
|
||||
IsKeySignedBy(id.UserID, id.Ed25519, id.UserID, id.Ed25519) (bool, error)
|
||||
}
|
||||
|
||||
type messageIndexKey struct {
|
||||
|
|
@ -511,7 +513,11 @@ func (gs *GobStore) PutCrossSigningKey(userID id.UserID, usage id.CrossSigningUs
|
|||
func (gs *GobStore) GetCrossSigningKeys(userID id.UserID) (map[id.CrossSigningUsage]id.Ed25519, error) {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
return gs.CrossSigningKeys[userID], nil
|
||||
keys, ok := gs.CrossSigningKeys[userID]
|
||||
if !ok {
|
||||
return map[id.CrossSigningUsage]id.Ed25519{}, nil
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
func (gs *GobStore) PutSignature(signedUserID id.UserID, signedKey id.Ed25519, signerUserID id.UserID, signerKey id.Ed25519, signature string) error {
|
||||
|
|
@ -537,12 +543,29 @@ func (gs *GobStore) PutSignature(signedUserID id.UserID, signedKey id.Ed25519, s
|
|||
return err
|
||||
}
|
||||
|
||||
func (gs *GobStore) GetSignaturesForKey(userID id.UserID, key id.Ed25519) (map[id.UserID]map[id.Ed25519]string, error) {
|
||||
func (gs *GobStore) GetSignaturesForKeyBy(userID id.UserID, key id.Ed25519, signerID id.UserID) (map[id.Ed25519]string, error) {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
userKeys, ok := gs.KeySignatures[userID]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
return map[id.Ed25519]string{}, nil
|
||||
}
|
||||
return userKeys[key], nil
|
||||
sigsForKey, ok := userKeys[key]
|
||||
if !ok {
|
||||
return map[id.Ed25519]string{}, nil
|
||||
}
|
||||
sigsBySigner, ok := sigsForKey[signerID]
|
||||
if !ok {
|
||||
return map[id.Ed25519]string{}, nil
|
||||
}
|
||||
return sigsBySigner, nil
|
||||
}
|
||||
|
||||
func (gs *GobStore) IsKeySignedBy(userID id.UserID, key id.Ed25519, signerID id.UserID, signerKey id.Ed25519) (bool, error) {
|
||||
sigs, err := gs.GetSignaturesForKeyBy(userID, key, signerID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
_, ok := sigs[signerKey]
|
||||
return ok, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ func (km KeyMap) GetCurve25519(deviceID id.DeviceID) id.Curve25519 {
|
|||
return id.Curve25519(val)
|
||||
}
|
||||
|
||||
type Signatures map[id.UserID]map[id.DeviceKeyID]string
|
||||
type Signatures map[id.UserID]map[id.KeyID]string
|
||||
|
||||
type ReqQueryKeys struct {
|
||||
DeviceKeys DeviceKeysRequest `json:"device_keys"`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue