mirror of
https://mau.dev/mautrix/go.git
synced 2026-03-14 14:25:53 +01:00
Move DeviceIdentity and Fingerprint to id package
This commit is contained in:
parent
bac6e0e3b2
commit
d1d7f999f7
18 changed files with 119 additions and 111 deletions
|
|
@ -93,7 +93,7 @@ func (helper *CryptoHelper) Init() error {
|
|||
return helper.mach.Load()
|
||||
}
|
||||
|
||||
func (helper *CryptoHelper) allowKeyShare(device *crypto.DeviceIdentity, info event.RequestedKeyInfo) *crypto.KeyShareRejection {
|
||||
func (helper *CryptoHelper) allowKeyShare(device *id.Device, info event.RequestedKeyInfo) *crypto.KeyShareRejection {
|
||||
cfg := helper.bridge.Config.Bridge.GetEncryptionConfig()
|
||||
if !cfg.AllowKeySharing {
|
||||
return &crypto.KeyShareRejectNoResponse
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ var (
|
|||
ErrMismatchingMasterKeyMAC = errors.New("mismatching cross-signing master key MAC")
|
||||
)
|
||||
|
||||
func (mach *OlmMachine) fetchMasterKey(device *DeviceIdentity, content *event.VerificationMacEventContent, verState *verificationState, transactionID string) (id.Ed25519, error) {
|
||||
func (mach *OlmMachine) fetchMasterKey(device *id.Device, content *event.VerificationMacEventContent, verState *verificationState, transactionID string) (id.Ed25519, error) {
|
||||
crossSignKeys, err := mach.CryptoStore.GetCrossSigningKeys(device.UserID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to fetch cross-signing keys: %w", err)
|
||||
|
|
@ -138,7 +138,7 @@ func (mach *OlmMachine) SignOwnMasterKey() error {
|
|||
}
|
||||
|
||||
// SignOwnDevice creates a cross-signing signature for a device belonging to the current user and uploads it to the server.
|
||||
func (mach *OlmMachine) SignOwnDevice(device *DeviceIdentity) error {
|
||||
func (mach *OlmMachine) SignOwnDevice(device *id.Device) error {
|
||||
if device.UserID != mach.Client.UserID {
|
||||
return ErrCantSignOtherDevice
|
||||
} else if mach.CrossSigningKeys == nil || mach.CrossSigningKeys.SelfSigningKey == nil {
|
||||
|
|
@ -176,7 +176,7 @@ func (mach *OlmMachine) SignOwnDevice(device *DeviceIdentity) error {
|
|||
|
||||
// getFullDeviceKeys gets the full device keys object for the given device.
|
||||
// This is used because we don't cache some of the details like list of algorithms and unsupported key types.
|
||||
func (mach *OlmMachine) getFullDeviceKeys(device *DeviceIdentity) (*mautrix.DeviceKeys, error) {
|
||||
func (mach *OlmMachine) getFullDeviceKeys(device *id.Device) (*mautrix.DeviceKeys, error) {
|
||||
devicesKeys, err := mach.Client.QueryKeys(&mautrix.ReqQueryKeys{
|
||||
DeviceKeys: mautrix.DeviceKeysRequest{
|
||||
device.UserID: mautrix.DeviceIDList{device.DeviceID},
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func getOlmMachine(t *testing.T) *OlmMachine {
|
|||
|
||||
func TestTrustOwnDevice(t *testing.T) {
|
||||
m := getOlmMachine(t)
|
||||
ownDevice := &DeviceIdentity{
|
||||
ownDevice := &id.Device{
|
||||
UserID: m.Client.UserID,
|
||||
DeviceID: "device",
|
||||
SigningKey: id.Ed25519("deviceKey"),
|
||||
|
|
@ -109,7 +109,7 @@ func TestTrustOtherUser(t *testing.T) {
|
|||
func TestTrustOtherDevice(t *testing.T) {
|
||||
m := getOlmMachine(t)
|
||||
otherUser := id.UserID("@user")
|
||||
theirDevice := &DeviceIdentity{
|
||||
theirDevice := &id.Device{
|
||||
UserID: otherUser,
|
||||
DeviceID: "theirDevice",
|
||||
SigningKey: id.Ed25519("theirDeviceKey"),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
// ResolveTrust resolves the trust state of the device from cross-signing.
|
||||
func (mach *OlmMachine) ResolveTrust(device *DeviceIdentity) id.TrustState {
|
||||
func (mach *OlmMachine) ResolveTrust(device *id.Device) id.TrustState {
|
||||
if device.Trust == id.TrustStateVerified || device.Trust == id.TrustStateBlacklisted {
|
||||
return device.Trust
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ func (mach *OlmMachine) ResolveTrust(device *DeviceIdentity) id.TrustState {
|
|||
}
|
||||
|
||||
// IsDeviceTrusted returns whether a device has been determined to be trusted either through verification or cross-signing.
|
||||
func (mach *OlmMachine) IsDeviceTrusted(device *DeviceIdentity) bool {
|
||||
func (mach *OlmMachine) IsDeviceTrusted(device *id.Device) bool {
|
||||
switch mach.ResolveTrust(device) {
|
||||
case id.TrustStateVerified, id.TrustStateCrossSignedTOFU, id.TrustStateCrossSignedVerified:
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func (mach *OlmMachine) DecryptMegolmEvent(evt *event.Event) (*event.Event, erro
|
|||
|
||||
var trustLevel id.TrustState
|
||||
var forwardedKeys bool
|
||||
var device *DeviceIdentity
|
||||
var device *id.Device
|
||||
ownSigningKey, ownIdentityKey := mach.account.Keys()
|
||||
if sess.SigningKey == ownSigningKey && sess.SenderKey == ownIdentityKey && len(sess.ForwardingChains) == 0 {
|
||||
trustLevel = id.TrustStateVerified
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ var (
|
|||
InvalidKeySignature = errors.New("invalid signature on device keys")
|
||||
)
|
||||
|
||||
func (mach *OlmMachine) LoadDevices(user id.UserID) map[id.DeviceID]*DeviceIdentity {
|
||||
func (mach *OlmMachine) LoadDevices(user id.UserID) map[id.DeviceID]*id.Device {
|
||||
return mach.fetchKeys([]id.UserID{user}, "", true)[user]
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ func (mach *OlmMachine) storeDeviceSelfSignatures(userID id.UserID, deviceID id.
|
|||
}
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) fetchKeys(users []id.UserID, sinceToken string, includeUntracked bool) (data map[id.UserID]map[id.DeviceID]*DeviceIdentity) {
|
||||
func (mach *OlmMachine) fetchKeys(users []id.UserID, sinceToken string, includeUntracked bool) (data map[id.UserID]map[id.DeviceID]*id.Device) {
|
||||
req := &mautrix.ReqQueryKeys{
|
||||
DeviceKeys: mautrix.DeviceKeysRequest{},
|
||||
Timeout: 10 * 1000,
|
||||
|
|
@ -90,15 +90,15 @@ func (mach *OlmMachine) fetchKeys(users []id.UserID, sinceToken string, includeU
|
|||
mach.Log.Warn("Query keys failure for %s: %v", server, err)
|
||||
}
|
||||
mach.Log.Trace("Query key result received with %d users", len(resp.DeviceKeys))
|
||||
data = make(map[id.UserID]map[id.DeviceID]*DeviceIdentity)
|
||||
data = make(map[id.UserID]map[id.DeviceID]*id.Device)
|
||||
for userID, devices := range resp.DeviceKeys {
|
||||
delete(req.DeviceKeys, userID)
|
||||
|
||||
newDevices := make(map[id.DeviceID]*DeviceIdentity)
|
||||
newDevices := make(map[id.DeviceID]*id.Device)
|
||||
existingDevices, err := mach.CryptoStore.GetDevices(userID)
|
||||
if err != nil {
|
||||
mach.Log.Warn("Failed to get existing devices for %s: %v", userID, err)
|
||||
existingDevices = make(map[id.DeviceID]*DeviceIdentity)
|
||||
existingDevices = make(map[id.DeviceID]*id.Device)
|
||||
}
|
||||
mach.Log.Trace("Updating devices for %s, got %d devices, have %d in store", userID, len(devices), len(existingDevices))
|
||||
changed := false
|
||||
|
|
@ -154,7 +154,7 @@ func (mach *OlmMachine) OnDevicesChanged(userID id.UserID) {
|
|||
}
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) validateDevice(userID id.UserID, deviceID id.DeviceID, deviceKeys mautrix.DeviceKeys, existing *DeviceIdentity) (*DeviceIdentity, error) {
|
||||
func (mach *OlmMachine) validateDevice(userID id.UserID, deviceID id.DeviceID, deviceKeys mautrix.DeviceKeys, existing *id.Device) (*id.Device, error) {
|
||||
if deviceID != deviceKeys.DeviceID {
|
||||
return nil, MismatchingDeviceID
|
||||
} else if userID != deviceKeys.UserID {
|
||||
|
|
@ -185,7 +185,7 @@ func (mach *OlmMachine) validateDevice(userID id.UserID, deviceID id.DeviceID, d
|
|||
name = string(deviceID)
|
||||
}
|
||||
|
||||
return &DeviceIdentity{
|
||||
return &id.Device{
|
||||
UserID: userID,
|
||||
DeviceID: deviceID,
|
||||
IdentityKey: identityKey,
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ func (mach *OlmMachine) newOutboundGroupSession(roomID id.RoomID) *OutboundGroup
|
|||
|
||||
type deviceSessionWrapper struct {
|
||||
session *OlmSession
|
||||
identity *DeviceIdentity
|
||||
identity *id.Device
|
||||
}
|
||||
|
||||
// ShareGroupSession shares a group session for a specific room with all the devices of the given user list.
|
||||
|
|
@ -115,8 +115,8 @@ func (mach *OlmMachine) ShareGroupSession(roomID id.RoomID, users []id.UserID) e
|
|||
withheldCount := 0
|
||||
toDeviceWithheld := &mautrix.ReqSendToDevice{Messages: make(map[id.UserID]map[id.DeviceID]*event.Content)}
|
||||
olmSessions := make(map[id.UserID]map[id.DeviceID]deviceSessionWrapper)
|
||||
missingSessions := make(map[id.UserID]map[id.DeviceID]*DeviceIdentity)
|
||||
missingUserSessions := make(map[id.DeviceID]*DeviceIdentity)
|
||||
missingSessions := make(map[id.UserID]map[id.DeviceID]*id.Device)
|
||||
missingUserSessions := make(map[id.DeviceID]*id.Device)
|
||||
var fetchKeys []id.UserID
|
||||
|
||||
for _, userID := range users {
|
||||
|
|
@ -137,7 +137,7 @@ func (mach *OlmMachine) ShareGroupSession(roomID id.RoomID, users []id.UserID) e
|
|||
withheldCount += len(toDeviceWithheld.Messages[userID])
|
||||
if len(missingUserSessions) > 0 {
|
||||
missingSessions[userID] = missingUserSessions
|
||||
missingUserSessions = make(map[id.DeviceID]*DeviceIdentity)
|
||||
missingUserSessions = make(map[id.DeviceID]*id.Device)
|
||||
}
|
||||
if len(toDeviceWithheld.Messages[userID]) == 0 {
|
||||
delete(toDeviceWithheld.Messages, userID)
|
||||
|
|
@ -234,7 +234,7 @@ func (mach *OlmMachine) encryptAndSendGroupSession(session *OutboundGroupSession
|
|||
return err
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) findOlmSessionsForUser(session *OutboundGroupSession, userID id.UserID, devices map[id.DeviceID]*DeviceIdentity, output map[id.DeviceID]deviceSessionWrapper, withheld map[id.DeviceID]*event.Content, missingOutput map[id.DeviceID]*DeviceIdentity) {
|
||||
func (mach *OlmMachine) findOlmSessionsForUser(session *OutboundGroupSession, userID id.UserID, devices map[id.DeviceID]*id.Device, output map[id.DeviceID]deviceSessionWrapper, withheld map[id.DeviceID]*event.Content, missingOutput map[id.DeviceID]*id.Device) {
|
||||
for deviceID, device := range devices {
|
||||
userKey := UserDevice{UserID: userID, DeviceID: deviceID}
|
||||
if state := session.Users[userKey]; state != OGSNotShared {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import (
|
|||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
func (mach *OlmMachine) encryptOlmEvent(session *OlmSession, recipient *DeviceIdentity, evtType event.Type, content event.Content) *event.EncryptedEventContent {
|
||||
func (mach *OlmMachine) encryptOlmEvent(session *OlmSession, recipient *id.Device, evtType event.Type, content event.Content) *event.EncryptedEventContent {
|
||||
evt := &DecryptedOlmEvent{
|
||||
Sender: mach.Client.UserID,
|
||||
SenderDevice: mach.Client.DeviceID,
|
||||
|
|
@ -61,7 +61,7 @@ func (mach *OlmMachine) shouldCreateNewSession(identityKey id.IdentityKey) bool
|
|||
return shouldUnwedge
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) createOutboundSessions(input map[id.UserID]map[id.DeviceID]*DeviceIdentity) error {
|
||||
func (mach *OlmMachine) createOutboundSessions(input map[id.UserID]map[id.DeviceID]*id.Device) error {
|
||||
request := make(mautrix.OneTimeKeysRequest)
|
||||
for userID, devices := range input {
|
||||
request[userID] = make(map[id.DeviceID]id.KeyAlgorithm)
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ func (mach *OlmMachine) importForwardedRoomKey(evt *DecryptedOlmEvent, content *
|
|||
return true
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) rejectKeyRequest(rejection KeyShareRejection, device *DeviceIdentity, request event.RequestedKeyInfo) {
|
||||
func (mach *OlmMachine) rejectKeyRequest(rejection KeyShareRejection, device *id.Device, request event.RequestedKeyInfo) {
|
||||
if rejection.Code == "" {
|
||||
// If the rejection code is empty, it means don't share keys, but also don't tell the requester.
|
||||
return
|
||||
|
|
@ -183,7 +183,7 @@ func (mach *OlmMachine) rejectKeyRequest(rejection KeyShareRejection, device *De
|
|||
}
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) defaultAllowKeyShare(device *DeviceIdentity, _ event.RequestedKeyInfo) *KeyShareRejection {
|
||||
func (mach *OlmMachine) defaultAllowKeyShare(device *id.Device, _ event.RequestedKeyInfo) *KeyShareRejection {
|
||||
if mach.Client.UserID != device.UserID {
|
||||
mach.Log.Debug("Ignoring key request from a different user (%s)", device.UserID)
|
||||
return &KeyShareRejectOtherUser
|
||||
|
|
|
|||
|
|
@ -41,11 +41,11 @@ type OlmMachine struct {
|
|||
SendKeysMinTrust id.TrustState
|
||||
ShareKeysMinTrust id.TrustState
|
||||
|
||||
AllowKeyShare func(*DeviceIdentity, event.RequestedKeyInfo) *KeyShareRejection
|
||||
AllowKeyShare func(*id.Device, event.RequestedKeyInfo) *KeyShareRejection
|
||||
|
||||
DefaultSASTimeout time.Duration
|
||||
// AcceptVerificationFrom determines whether the machine will accept verification requests from this device.
|
||||
AcceptVerificationFrom func(string, *DeviceIdentity, id.RoomID) (VerificationRequestResponse, VerificationHooks)
|
||||
AcceptVerificationFrom func(string, *id.Device, id.RoomID) (VerificationRequestResponse, VerificationHooks)
|
||||
|
||||
account *OlmAccount
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ func NewOlmMachine(client *mautrix.Client, log Logger, cryptoStore Store, stateS
|
|||
ShareKeysMinTrust: id.TrustStateCrossSignedTOFU,
|
||||
|
||||
DefaultSASTimeout: 10 * time.Minute,
|
||||
AcceptVerificationFrom: func(string, *DeviceIdentity, id.RoomID) (VerificationRequestResponse, VerificationHooks) {
|
||||
AcceptVerificationFrom: func(string, *id.Device, id.RoomID) (VerificationRequestResponse, VerificationHooks) {
|
||||
// Reject requests by default. Users need to override this to return appropriate verification hooks.
|
||||
return RejectRequest, nil
|
||||
},
|
||||
|
|
@ -143,28 +143,19 @@ func (mach *OlmMachine) timeTrace(thing, trace string, expectedDuration time.Dur
|
|||
}
|
||||
}
|
||||
|
||||
func Fingerprint(signingKey id.SigningKey) string {
|
||||
spacedSigningKey := make([]byte, len(signingKey)+(len(signingKey)-1)/4)
|
||||
var ptr = 0
|
||||
for i, chr := range signingKey {
|
||||
spacedSigningKey[ptr] = byte(chr)
|
||||
ptr++
|
||||
if i%4 == 3 {
|
||||
spacedSigningKey[ptr] = ' '
|
||||
ptr++
|
||||
}
|
||||
}
|
||||
return string(spacedSigningKey)
|
||||
// Deprecated: moved to SigningKey.Fingerprint
|
||||
func Fingerprint(key id.SigningKey) string {
|
||||
return key.Fingerprint()
|
||||
}
|
||||
|
||||
// Fingerprint returns the fingerprint of the Olm account that can be used for non-interactive verification.
|
||||
func (mach *OlmMachine) Fingerprint() string {
|
||||
return Fingerprint(mach.account.SigningKey())
|
||||
return mach.account.SigningKey().Fingerprint()
|
||||
}
|
||||
|
||||
// OwnIdentity returns this device's DeviceIdentity struct
|
||||
func (mach *OlmMachine) OwnIdentity() *DeviceIdentity {
|
||||
return &DeviceIdentity{
|
||||
func (mach *OlmMachine) OwnIdentity() *id.Device {
|
||||
return &id.Device{
|
||||
UserID: mach.Client.UserID,
|
||||
DeviceID: mach.Client.DeviceID,
|
||||
IdentityKey: mach.account.IdentityKey(),
|
||||
|
|
@ -343,7 +334,7 @@ func (mach *OlmMachine) HandleToDeviceEvent(evt *event.Event) {
|
|||
|
||||
// GetOrFetchDevice attempts to retrieve the device identity for the given device from the store
|
||||
// and if it's not found it asks the server for it.
|
||||
func (mach *OlmMachine) GetOrFetchDevice(userID id.UserID, deviceID id.DeviceID) (*DeviceIdentity, error) {
|
||||
func (mach *OlmMachine) GetOrFetchDevice(userID id.UserID, deviceID id.DeviceID) (*id.Device, error) {
|
||||
// get device identity
|
||||
device, err := mach.CryptoStore.GetDevice(userID, deviceID)
|
||||
if err != nil {
|
||||
|
|
@ -365,7 +356,7 @@ func (mach *OlmMachine) GetOrFetchDevice(userID id.UserID, deviceID id.DeviceID)
|
|||
// GetOrFetchDeviceByKey attempts to retrieve the device identity for the device with the given identity key from the
|
||||
// store and if it's not found it asks the server for it. This returns nil if the server doesn't return a device with
|
||||
// the given identity key.
|
||||
func (mach *OlmMachine) GetOrFetchDeviceByKey(userID id.UserID, identityKey id.IdentityKey) (*DeviceIdentity, error) {
|
||||
func (mach *OlmMachine) GetOrFetchDeviceByKey(userID id.UserID, identityKey id.IdentityKey) (*id.Device, error) {
|
||||
deviceIdentity, err := mach.CryptoStore.FindDeviceByKey(userID, identityKey)
|
||||
if err != nil || deviceIdentity != nil {
|
||||
return deviceIdentity, err
|
||||
|
|
@ -381,8 +372,8 @@ func (mach *OlmMachine) GetOrFetchDeviceByKey(userID id.UserID, identityKey id.I
|
|||
}
|
||||
|
||||
// SendEncryptedToDevice sends an Olm-encrypted event to the given user device.
|
||||
func (mach *OlmMachine) SendEncryptedToDevice(device *DeviceIdentity, evtType event.Type, content event.Content) error {
|
||||
if err := mach.createOutboundSessions(map[id.UserID]map[id.DeviceID]*DeviceIdentity{
|
||||
func (mach *OlmMachine) SendEncryptedToDevice(device *id.Device, evtType event.Type, content event.Content) error {
|
||||
if err := mach.createOutboundSessions(map[id.UserID]map[id.DeviceID]*id.Device{
|
||||
device.UserID: {
|
||||
device.DeviceID: device,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ func TestOlmMachineOlmMegolmSessions(t *testing.T) {
|
|||
}
|
||||
|
||||
// store sender device identity in receiving machine store
|
||||
machineIn.CryptoStore.PutDevices("user1", map[id.DeviceID]*DeviceIdentity{
|
||||
machineIn.CryptoStore.PutDevices("user1", map[id.DeviceID]*id.Device{
|
||||
"device1": {
|
||||
UserID: "user1",
|
||||
DeviceID: "device1",
|
||||
|
|
@ -98,7 +98,7 @@ func TestOlmMachineOlmMegolmSessions(t *testing.T) {
|
|||
machineOut.CryptoStore.AddOutboundGroupSession(megolmOutSession)
|
||||
|
||||
// encrypt m.room_key event with olm session
|
||||
deviceIdentity := &DeviceIdentity{
|
||||
deviceIdentity := &id.Device{
|
||||
UserID: "user2",
|
||||
DeviceID: "device2",
|
||||
IdentityKey: machineIn.account.IdentityKey(),
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ func (store *SQLCryptoStore) ValidateMessageIndex(senderKey id.SenderKey, sessio
|
|||
}
|
||||
|
||||
// GetDevices returns a map of device IDs to device identities, including the identity and signing keys, for a given user ID.
|
||||
func (store *SQLCryptoStore) GetDevices(userID id.UserID) (map[id.DeviceID]*DeviceIdentity, error) {
|
||||
func (store *SQLCryptoStore) GetDevices(userID id.UserID) (map[id.DeviceID]*id.Device, error) {
|
||||
var ignore id.UserID
|
||||
err := store.DB.QueryRow("SELECT user_id FROM crypto_tracked_user WHERE user_id=$1", userID).Scan(&ignore)
|
||||
if err == sql.ErrNoRows {
|
||||
|
|
@ -458,9 +458,9 @@ func (store *SQLCryptoStore) GetDevices(userID id.UserID) (map[id.DeviceID]*Devi
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := make(map[id.DeviceID]*DeviceIdentity)
|
||||
data := make(map[id.DeviceID]*id.Device)
|
||||
for rows.Next() {
|
||||
var identity DeviceIdentity
|
||||
var identity id.Device
|
||||
err := rows.Scan(&identity.DeviceID, &identity.IdentityKey, &identity.SigningKey, &identity.Trust, &identity.Deleted, &identity.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -472,8 +472,8 @@ func (store *SQLCryptoStore) GetDevices(userID id.UserID) (map[id.DeviceID]*Devi
|
|||
}
|
||||
|
||||
// GetDevice returns the device dentity for a given user and device ID.
|
||||
func (store *SQLCryptoStore) GetDevice(userID id.UserID, deviceID id.DeviceID) (*DeviceIdentity, error) {
|
||||
var identity DeviceIdentity
|
||||
func (store *SQLCryptoStore) GetDevice(userID id.UserID, deviceID id.DeviceID) (*id.Device, error) {
|
||||
var identity id.Device
|
||||
err := store.DB.QueryRow(`
|
||||
SELECT identity_key, signing_key, trust, deleted, name
|
||||
FROM crypto_device WHERE user_id=$1 AND device_id=$2`,
|
||||
|
|
@ -491,8 +491,8 @@ func (store *SQLCryptoStore) GetDevice(userID id.UserID, deviceID id.DeviceID) (
|
|||
}
|
||||
|
||||
// FindDeviceByKey finds a specific device by its sender key.
|
||||
func (store *SQLCryptoStore) FindDeviceByKey(userID id.UserID, identityKey id.IdentityKey) (*DeviceIdentity, error) {
|
||||
var identity DeviceIdentity
|
||||
func (store *SQLCryptoStore) FindDeviceByKey(userID id.UserID, identityKey id.IdentityKey) (*id.Device, error) {
|
||||
var identity id.Device
|
||||
err := store.DB.QueryRow(`
|
||||
SELECT device_id, signing_key, trust, deleted, name
|
||||
FROM crypto_device WHERE user_id=$1 AND identity_key=$2`,
|
||||
|
|
@ -519,14 +519,14 @@ ON CONFLICT (user_id, device_id) DO UPDATE
|
|||
var deviceMassInsertTemplate = strings.ReplaceAll(deviceInsertQuery, "($1, $2, $3, $4, $5, $6, $7)", "%s")
|
||||
|
||||
// PutDevice stores a single device for a user, replacing it if it exists already.
|
||||
func (store *SQLCryptoStore) PutDevice(userID id.UserID, device *DeviceIdentity) error {
|
||||
func (store *SQLCryptoStore) PutDevice(userID id.UserID, device *id.Device) error {
|
||||
_, err := store.DB.Exec(deviceInsertQuery,
|
||||
userID, device.DeviceID, device.IdentityKey, device.SigningKey, device.Trust, device.Deleted, device.Name)
|
||||
return err
|
||||
}
|
||||
|
||||
// PutDevices stores the device identity information for the given user ID.
|
||||
func (store *SQLCryptoStore) PutDevices(userID id.UserID, devices map[id.DeviceID]*DeviceIdentity) error {
|
||||
func (store *SQLCryptoStore) PutDevices(userID id.UserID, devices map[id.DeviceID]*id.Device) error {
|
||||
tx, err := store.DB.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -630,12 +630,12 @@ func (store *SQLCryptoStore) PutCrossSigningKey(userID id.UserID, usage id.Cross
|
|||
}
|
||||
|
||||
// GetCrossSigningKeys retrieves a user's stored cross-signing keys.
|
||||
func (store *SQLCryptoStore) GetCrossSigningKeys(userID id.UserID) (map[id.CrossSigningUsage]CrossSigningKey, error) {
|
||||
func (store *SQLCryptoStore) GetCrossSigningKeys(userID id.UserID) (map[id.CrossSigningUsage]id.CrossSigningKey, error) {
|
||||
rows, err := store.DB.Query("SELECT usage, key, first_seen_key FROM crypto_cross_signing_keys WHERE user_id=$1", userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := make(map[id.CrossSigningUsage]CrossSigningKey)
|
||||
data := make(map[id.CrossSigningUsage]id.CrossSigningKey)
|
||||
for rows.Next() {
|
||||
var usage id.CrossSigningUsage
|
||||
var key, first id.Ed25519
|
||||
|
|
@ -643,7 +643,7 @@ func (store *SQLCryptoStore) GetCrossSigningKeys(userID id.UserID) (map[id.Cross
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data[usage] = CrossSigningKey{key, first}
|
||||
data[usage] = id.CrossSigningKey{key, first}
|
||||
}
|
||||
|
||||
return data, nil
|
||||
|
|
|
|||
|
|
@ -18,26 +18,8 @@ import (
|
|||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
// DeviceIdentity contains the identity details of a device and some additional info.
|
||||
type DeviceIdentity struct {
|
||||
UserID id.UserID
|
||||
DeviceID id.DeviceID
|
||||
IdentityKey id.Curve25519
|
||||
SigningKey id.Ed25519
|
||||
|
||||
Trust id.TrustState
|
||||
Deleted bool
|
||||
Name string
|
||||
}
|
||||
|
||||
func (device *DeviceIdentity) Fingerprint() string {
|
||||
return Fingerprint(device.SigningKey)
|
||||
}
|
||||
|
||||
type CrossSigningKey struct {
|
||||
Key id.Ed25519
|
||||
First id.Ed25519
|
||||
}
|
||||
// Deprecated: moved to id.Device
|
||||
type DeviceIdentity = id.Device
|
||||
|
||||
var ErrGroupSessionWithheld = errors.New("group session has been withheld")
|
||||
|
||||
|
|
@ -111,15 +93,15 @@ type Store interface {
|
|||
ValidateMessageIndex(senderKey id.SenderKey, sessionID id.SessionID, eventID id.EventID, index uint, timestamp int64) bool
|
||||
|
||||
// GetDevices returns a map from device ID to DeviceIdentity containing all devices of a given user.
|
||||
GetDevices(id.UserID) (map[id.DeviceID]*DeviceIdentity, error)
|
||||
GetDevices(id.UserID) (map[id.DeviceID]*id.Device, error)
|
||||
// GetDevice returns a specific device of a given user.
|
||||
GetDevice(id.UserID, id.DeviceID) (*DeviceIdentity, error)
|
||||
GetDevice(id.UserID, id.DeviceID) (*id.Device, error)
|
||||
// PutDevice stores a single device for a user, replacing it if it exists already.
|
||||
PutDevice(id.UserID, *DeviceIdentity) error
|
||||
PutDevice(id.UserID, *id.Device) error
|
||||
// PutDevices overrides the stored device list for the given user with the given list.
|
||||
PutDevices(id.UserID, map[id.DeviceID]*DeviceIdentity) error
|
||||
PutDevices(id.UserID, map[id.DeviceID]*id.Device) error
|
||||
// FindDeviceByKey finds a specific device by its identity key.
|
||||
FindDeviceByKey(id.UserID, id.IdentityKey) (*DeviceIdentity, error)
|
||||
FindDeviceByKey(id.UserID, id.IdentityKey) (*id.Device, error)
|
||||
// FilterTrackedUsers returns a filtered version of the given list that only includes user IDs whose device lists
|
||||
// have been stored with PutDevices. A user is considered tracked even if the PutDevices list was empty.
|
||||
FilterTrackedUsers([]id.UserID) []id.UserID
|
||||
|
|
@ -127,7 +109,7 @@ type Store interface {
|
|||
// PutCrossSigningKey stores a cross-signing key of some user along with its usage.
|
||||
PutCrossSigningKey(id.UserID, id.CrossSigningUsage, id.Ed25519) error
|
||||
// GetCrossSigningKeys retrieves a user's stored cross-signing keys.
|
||||
GetCrossSigningKeys(id.UserID) (map[id.CrossSigningUsage]CrossSigningKey, error)
|
||||
GetCrossSigningKeys(id.UserID) (map[id.CrossSigningUsage]id.CrossSigningKey, error)
|
||||
// PutSignature stores a signature of a cross-signing or device key along with the signer's user ID and key.
|
||||
PutSignature(signedUser id.UserID, signedKey id.Ed25519, signerUser id.UserID, signerKey id.Ed25519, signature string) error
|
||||
// IsKeySignedBy returns whether a cross-signing or device key is signed by the given signer.
|
||||
|
|
@ -160,8 +142,8 @@ type GobStore struct {
|
|||
WithheldGroupSessions map[id.RoomID]map[id.SenderKey]map[id.SessionID]*event.RoomKeyWithheldEventContent
|
||||
OutGroupSessions map[id.RoomID]*OutboundGroupSession
|
||||
MessageIndices map[messageIndexKey]messageIndexValue
|
||||
Devices map[id.UserID]map[id.DeviceID]*DeviceIdentity
|
||||
CrossSigningKeys map[id.UserID]map[id.CrossSigningUsage]CrossSigningKey
|
||||
Devices map[id.UserID]map[id.DeviceID]*id.Device
|
||||
CrossSigningKeys map[id.UserID]map[id.CrossSigningUsage]id.CrossSigningKey
|
||||
KeySignatures map[id.UserID]map[id.Ed25519]map[id.UserID]map[id.Ed25519]string
|
||||
}
|
||||
|
||||
|
|
@ -178,8 +160,8 @@ func NewGobStore(path string) (*GobStore, error) {
|
|||
WithheldGroupSessions: make(map[id.RoomID]map[id.SenderKey]map[id.SessionID]*event.RoomKeyWithheldEventContent),
|
||||
OutGroupSessions: make(map[id.RoomID]*OutboundGroupSession),
|
||||
MessageIndices: make(map[messageIndexKey]messageIndexValue),
|
||||
Devices: make(map[id.UserID]map[id.DeviceID]*DeviceIdentity),
|
||||
CrossSigningKeys: make(map[id.UserID]map[id.CrossSigningUsage]CrossSigningKey),
|
||||
Devices: make(map[id.UserID]map[id.DeviceID]*id.Device),
|
||||
CrossSigningKeys: make(map[id.UserID]map[id.CrossSigningUsage]id.CrossSigningKey),
|
||||
KeySignatures: make(map[id.UserID]map[id.Ed25519]map[id.UserID]map[id.Ed25519]string),
|
||||
}
|
||||
return gs, gs.load()
|
||||
|
|
@ -427,7 +409,7 @@ func (gs *GobStore) ValidateMessageIndex(senderKey id.SenderKey, sessionID id.Se
|
|||
return true
|
||||
}
|
||||
|
||||
func (gs *GobStore) GetDevices(userID id.UserID) (map[id.DeviceID]*DeviceIdentity, error) {
|
||||
func (gs *GobStore) GetDevices(userID id.UserID) (map[id.DeviceID]*id.Device, error) {
|
||||
gs.lock.RLock()
|
||||
devices, ok := gs.Devices[userID]
|
||||
if !ok {
|
||||
|
|
@ -437,7 +419,7 @@ func (gs *GobStore) GetDevices(userID id.UserID) (map[id.DeviceID]*DeviceIdentit
|
|||
return devices, nil
|
||||
}
|
||||
|
||||
func (gs *GobStore) GetDevice(userID id.UserID, deviceID id.DeviceID) (*DeviceIdentity, error) {
|
||||
func (gs *GobStore) GetDevice(userID id.UserID, deviceID id.DeviceID) (*id.Device, error) {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
devices, ok := gs.Devices[userID]
|
||||
|
|
@ -451,7 +433,7 @@ func (gs *GobStore) GetDevice(userID id.UserID, deviceID id.DeviceID) (*DeviceId
|
|||
return device, nil
|
||||
}
|
||||
|
||||
func (gs *GobStore) FindDeviceByKey(userID id.UserID, identityKey id.IdentityKey) (*DeviceIdentity, error) {
|
||||
func (gs *GobStore) FindDeviceByKey(userID id.UserID, identityKey id.IdentityKey) (*id.Device, error) {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
devices, ok := gs.Devices[userID]
|
||||
|
|
@ -466,11 +448,11 @@ func (gs *GobStore) FindDeviceByKey(userID id.UserID, identityKey id.IdentityKey
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (gs *GobStore) PutDevice(userID id.UserID, device *DeviceIdentity) error {
|
||||
func (gs *GobStore) PutDevice(userID id.UserID, device *id.Device) error {
|
||||
gs.lock.Lock()
|
||||
devices, ok := gs.Devices[userID]
|
||||
if !ok {
|
||||
devices = make(map[id.DeviceID]*DeviceIdentity)
|
||||
devices = make(map[id.DeviceID]*id.Device)
|
||||
gs.Devices[userID] = devices
|
||||
}
|
||||
devices[device.DeviceID] = device
|
||||
|
|
@ -479,7 +461,7 @@ func (gs *GobStore) PutDevice(userID id.UserID, device *DeviceIdentity) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (gs *GobStore) PutDevices(userID id.UserID, devices map[id.DeviceID]*DeviceIdentity) error {
|
||||
func (gs *GobStore) PutDevices(userID id.UserID, devices map[id.DeviceID]*id.Device) error {
|
||||
gs.lock.Lock()
|
||||
gs.Devices[userID] = devices
|
||||
err := gs.save()
|
||||
|
|
@ -505,7 +487,7 @@ func (gs *GobStore) PutCrossSigningKey(userID id.UserID, usage id.CrossSigningUs
|
|||
gs.lock.RLock()
|
||||
userKeys, ok := gs.CrossSigningKeys[userID]
|
||||
if !ok {
|
||||
userKeys = make(map[id.CrossSigningUsage]CrossSigningKey)
|
||||
userKeys = make(map[id.CrossSigningUsage]id.CrossSigningKey)
|
||||
gs.CrossSigningKeys[userID] = userKeys
|
||||
}
|
||||
existing, ok := userKeys[usage]
|
||||
|
|
@ -513,7 +495,7 @@ func (gs *GobStore) PutCrossSigningKey(userID id.UserID, usage id.CrossSigningUs
|
|||
existing.Key = key
|
||||
userKeys[usage] = existing
|
||||
} else {
|
||||
userKeys[usage] = CrossSigningKey{
|
||||
userKeys[usage] = id.CrossSigningKey{
|
||||
Key: key,
|
||||
First: key,
|
||||
}
|
||||
|
|
@ -523,12 +505,12 @@ func (gs *GobStore) PutCrossSigningKey(userID id.UserID, usage id.CrossSigningUs
|
|||
return err
|
||||
}
|
||||
|
||||
func (gs *GobStore) GetCrossSigningKeys(userID id.UserID) (map[id.CrossSigningUsage]CrossSigningKey, error) {
|
||||
func (gs *GobStore) GetCrossSigningKeys(userID id.UserID) (map[id.CrossSigningUsage]id.CrossSigningKey, error) {
|
||||
gs.lock.RLock()
|
||||
defer gs.lock.RUnlock()
|
||||
keys, ok := gs.CrossSigningKeys[userID]
|
||||
if !ok {
|
||||
return map[id.CrossSigningUsage]CrossSigningKey{}, nil
|
||||
return map[id.CrossSigningUsage]id.CrossSigningKey{}, nil
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,11 +231,11 @@ func TestStoreDevices(t *testing.T) {
|
|||
defer cleanup()
|
||||
for storeName, store := range stores {
|
||||
t.Run(storeName, func(t *testing.T) {
|
||||
deviceMap := make(map[id.DeviceID]*DeviceIdentity)
|
||||
deviceMap := make(map[id.DeviceID]*id.Device)
|
||||
for i := 0; i < 17; i++ {
|
||||
iStr := strconv.Itoa(i)
|
||||
acc := NewOlmAccount()
|
||||
deviceMap[id.DeviceID("dev"+iStr)] = &DeviceIdentity{
|
||||
deviceMap[id.DeviceID("dev"+iStr)] = &id.Device{
|
||||
UserID: "user1",
|
||||
DeviceID: id.DeviceID("dev" + iStr),
|
||||
IdentityKey: acc.IdentityKey(),
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ var (
|
|||
type VerificationHooks interface {
|
||||
// VerifySASMatch receives the generated SAS and its method, as well as the device that is being verified.
|
||||
// It returns whether the given SAS match with the SAS displayed on other device.
|
||||
VerifySASMatch(otherDevice *DeviceIdentity, sas SASData) bool
|
||||
VerifySASMatch(otherDevice *id.Device, sas SASData) bool
|
||||
// VerificationMethods returns the list of supported verification methods in order of preference.
|
||||
// It must contain at least the decimal method.
|
||||
VerificationMethods() []VerificationMethod
|
||||
|
|
@ -106,7 +106,7 @@ func (mach *OlmMachine) getPKAndKeysMAC(sas *olm.SAS, sendingUser id.UserID, sen
|
|||
// verificationState holds all the information needed for the state of a SAS verification with another device.
|
||||
type verificationState struct {
|
||||
sas *olm.SAS
|
||||
otherDevice *DeviceIdentity
|
||||
otherDevice *id.Device
|
||||
initiatedByUs bool
|
||||
verificationStarted bool
|
||||
keyReceived bool
|
||||
|
|
@ -175,7 +175,7 @@ func (mach *OlmMachine) handleVerificationStart(userID id.UserID, content *event
|
|||
}
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) actuallyStartVerification(userID id.UserID, content *event.VerificationStartEventContent, otherDevice *DeviceIdentity, transactionID string, timeout time.Duration, inRoomID id.RoomID) {
|
||||
func (mach *OlmMachine) actuallyStartVerification(userID id.UserID, content *event.VerificationStartEventContent, otherDevice *id.Device, transactionID string, timeout time.Duration, inRoomID id.RoomID) {
|
||||
if inRoomID != "" && transactionID != "" {
|
||||
verState, err := mach.getTransactionState(transactionID, userID)
|
||||
if err != nil {
|
||||
|
|
@ -609,14 +609,14 @@ func (mach *OlmMachine) handleVerificationRequest(userID id.UserID, content *eve
|
|||
|
||||
// NewSimpleSASVerificationWith starts the SAS verification process with another device with a default timeout,
|
||||
// a generated transaction ID and support for both emoji and decimal SAS methods.
|
||||
func (mach *OlmMachine) NewSimpleSASVerificationWith(device *DeviceIdentity, hooks VerificationHooks) (string, error) {
|
||||
func (mach *OlmMachine) NewSimpleSASVerificationWith(device *id.Device, hooks VerificationHooks) (string, error) {
|
||||
return mach.NewSASVerificationWith(device, hooks, "", mach.DefaultSASTimeout)
|
||||
}
|
||||
|
||||
// NewSASVerificationWith starts the SAS verification process with another device.
|
||||
// If the other device accepts the verification transaction, the methods in `hooks` will be used to verify the SAS match and to complete the transaction..
|
||||
// If the transaction ID is empty, a new one is generated.
|
||||
func (mach *OlmMachine) NewSASVerificationWith(device *DeviceIdentity, hooks VerificationHooks, transactionID string, timeout time.Duration) (string, error) {
|
||||
func (mach *OlmMachine) NewSASVerificationWith(device *id.Device, hooks VerificationHooks, transactionID string, timeout time.Duration) (string, error) {
|
||||
if transactionID == "" {
|
||||
transactionID = strconv.Itoa(rand.Int())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,10 +255,10 @@ func (mach *OlmMachine) SendInRoomSASVerificationMAC(roomID id.RoomID, userID id
|
|||
// NewInRoomSASVerificationWith starts the in-room SAS verification process with another user in the given room.
|
||||
// It returns the generated transaction ID.
|
||||
func (mach *OlmMachine) NewInRoomSASVerificationWith(inRoomID id.RoomID, userID id.UserID, hooks VerificationHooks, timeout time.Duration) (string, error) {
|
||||
return mach.newInRoomSASVerificationWithInner(inRoomID, &DeviceIdentity{UserID: userID}, hooks, "", timeout)
|
||||
return mach.newInRoomSASVerificationWithInner(inRoomID, &id.Device{UserID: userID}, hooks, "", timeout)
|
||||
}
|
||||
|
||||
func (mach *OlmMachine) newInRoomSASVerificationWithInner(inRoomID id.RoomID, device *DeviceIdentity, hooks VerificationHooks, transactionID string, timeout time.Duration) (string, error) {
|
||||
func (mach *OlmMachine) newInRoomSASVerificationWithInner(inRoomID id.RoomID, device *id.Device, hooks VerificationHooks, transactionID string, timeout time.Duration) (string, error) {
|
||||
mach.Log.Debug("Starting new in-room verification transaction user %v", device.UserID)
|
||||
|
||||
request := transactionID == ""
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ type MautrixInfo struct {
|
|||
TrustState id.TrustState
|
||||
ForwardedKeys bool
|
||||
WasEncrypted bool
|
||||
TrustSource interface{}
|
||||
TrustSource *id.Device
|
||||
|
||||
CheckpointSent bool
|
||||
}
|
||||
|
|
|
|||
35
id/crypto.go
35
id/crypto.go
|
|
@ -59,6 +59,20 @@ func (ed25519 Ed25519) String() string {
|
|||
return string(ed25519)
|
||||
}
|
||||
|
||||
func (ed25519 Ed25519) Fingerprint() string {
|
||||
spacedSigningKey := make([]byte, len(ed25519)+(len(ed25519)-1)/4)
|
||||
var ptr = 0
|
||||
for i, chr := range ed25519 {
|
||||
spacedSigningKey[ptr] = byte(chr)
|
||||
ptr++
|
||||
if i%4 == 3 {
|
||||
spacedSigningKey[ptr] = ' '
|
||||
ptr++
|
||||
}
|
||||
}
|
||||
return string(spacedSigningKey)
|
||||
}
|
||||
|
||||
// Curve25519 is the base64 representation of an Curve25519 public key
|
||||
type Curve25519 string
|
||||
type SenderKey = Curve25519
|
||||
|
|
@ -112,3 +126,24 @@ func (keyID KeyID) Parse() (KeyAlgorithm, string) {
|
|||
}
|
||||
return KeyAlgorithm(keyID[:index]), string(keyID[index+1:])
|
||||
}
|
||||
|
||||
// Device contains the identity details of a device and some additional info.
|
||||
type Device struct {
|
||||
UserID UserID
|
||||
DeviceID DeviceID
|
||||
IdentityKey Curve25519
|
||||
SigningKey Ed25519
|
||||
|
||||
Trust TrustState
|
||||
Deleted bool
|
||||
Name string
|
||||
}
|
||||
|
||||
func (device *Device) Fingerprint() string {
|
||||
return device.SigningKey.Fingerprint()
|
||||
}
|
||||
|
||||
type CrossSigningKey struct {
|
||||
Key Ed25519
|
||||
First Ed25519
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue