diff --git a/desktop/go.mod b/desktop/go.mod index 4f60534..52a8af4 100644 --- a/desktop/go.mod +++ b/desktop/go.mod @@ -73,7 +73,7 @@ require ( gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - maunium.net/go/mautrix v0.22.1-0.20241205122504-933daead3b34 // indirect + maunium.net/go/mautrix v0.22.1-0.20241207130433-421bd5c4c837 // indirect mvdan.cc/xurls/v2 v2.5.0 // indirect ) diff --git a/desktop/go.sum b/desktop/go.sum index 151c356..9d1f340 100644 --- a/desktop/go.sum +++ b/desktop/go.sum @@ -250,7 +250,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -maunium.net/go/mautrix v0.22.1-0.20241205122504-933daead3b34 h1:oDfWbC8MwcMwrqtIhQ3uQBP23C/B9YqAUfKkDxToFm0= -maunium.net/go/mautrix v0.22.1-0.20241205122504-933daead3b34/go.mod h1:oqwf9WYC/brqucM+heYk4gX11O59nP+ljvyxVhndFIM= +maunium.net/go/mautrix v0.22.1-0.20241207130433-421bd5c4c837 h1:v3cRnMfhKxpnKjhikZ5HY72MKIsgYzldL2s3cqbkNbY= +maunium.net/go/mautrix v0.22.1-0.20241207130433-421bd5c4c837/go.mod h1:oqwf9WYC/brqucM+heYk4gX11O59nP+ljvyxVhndFIM= mvdan.cc/xurls/v2 v2.5.0 h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8= mvdan.cc/xurls/v2 v2.5.0/go.mod h1:yQgaGQ1rFtJUzkmKiHYSSfuQxqfYmd//X6PxvholpeE= diff --git a/go.mod b/go.mod index 9a78a46..de86e44 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( golang.org/x/text v0.20.0 gopkg.in/yaml.v3 v3.0.1 maunium.net/go/mauflag v1.0.0 - maunium.net/go/mautrix v0.22.1-0.20241205122504-933daead3b34 + maunium.net/go/mautrix v0.22.1-0.20241207130433-421bd5c4c837 mvdan.cc/xurls/v2 v2.5.0 ) diff --git a/go.sum b/go.sum index a86545a..6c0cd68 100644 --- a/go.sum +++ b/go.sum @@ -91,7 +91,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.22.1-0.20241205122504-933daead3b34 h1:oDfWbC8MwcMwrqtIhQ3uQBP23C/B9YqAUfKkDxToFm0= -maunium.net/go/mautrix v0.22.1-0.20241205122504-933daead3b34/go.mod h1:oqwf9WYC/brqucM+heYk4gX11O59nP+ljvyxVhndFIM= +maunium.net/go/mautrix v0.22.1-0.20241207130433-421bd5c4c837 h1:v3cRnMfhKxpnKjhikZ5HY72MKIsgYzldL2s3cqbkNbY= +maunium.net/go/mautrix v0.22.1-0.20241207130433-421bd5c4c837/go.mod h1:oqwf9WYC/brqucM+heYk4gX11O59nP+ljvyxVhndFIM= mvdan.cc/xurls/v2 v2.5.0 h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8= mvdan.cc/xurls/v2 v2.5.0/go.mod h1:yQgaGQ1rFtJUzkmKiHYSSfuQxqfYmd//X6PxvholpeE= diff --git a/pkg/hicli/profile.go b/pkg/hicli/profile.go index 44b8fe8..754ec6f 100644 --- a/pkg/hicli/profile.go +++ b/pkg/hicli/profile.go @@ -8,12 +8,13 @@ package hicli import ( "context" - "fmt" + "errors" "slices" - "strings" "github.com/rs/zerolog" + "maunium.net/go/mautrix" + "maunium.net/go/mautrix/crypto" "maunium.net/go/mautrix/id" ) @@ -59,81 +60,34 @@ type ProfileEncryptionInfo struct { func (h *HiClient) GetProfileEncryptionInfo(ctx context.Context, userID id.UserID) (*ProfileEncryptionInfo, error) { var resp ProfileEncryptionInfo log := zerolog.Ctx(ctx) - userIDs, err := h.CryptoStore.FilterTrackedUsers(ctx, []id.UserID{userID}) - if err != nil { - log.Err(err).Msg("Failed to check if user's devices are tracked") - return nil, fmt.Errorf("failed to check if user's devices are tracked: %w", err) - } else if len(userIDs) == 0 { + cachedDevices, err := h.Crypto.GetCachedDevices(ctx, userID) + if errors.Is(err, crypto.ErrUserNotTracked) { return &resp, nil - } - ownKeys := h.Crypto.GetOwnCrossSigningPublicKeys(ctx) - var ownUserSigningKey id.Ed25519 - if ownKeys != nil { - ownUserSigningKey = ownKeys.UserSigningKey + } else if err != nil { + log.Err(err).Msg("Failed to get cached devices") + return nil, err } resp.DevicesTracked = true - csKeys, err := h.CryptoStore.GetCrossSigningKeys(ctx, userID) - theirMasterKey := csKeys[id.XSUsageMaster] - theirSelfSignKey := csKeys[id.XSUsageSelfSigning] - if err != nil { - log.Err(err).Msg("Failed to get cross-signing keys") - return nil, fmt.Errorf("failed to get cross-signing keys: %w", err) - } else if csKeys != nil && theirMasterKey.Key != "" { - resp.MasterKey = theirMasterKey.Key.Fingerprint() - resp.FirstMasterKey = theirMasterKey.First.Fingerprint() - selfKeySigned, err := h.CryptoStore.IsKeySignedBy(ctx, userID, theirSelfSignKey.Key, userID, theirMasterKey.Key) - if err != nil { - log.Err(err).Msg("Failed to check if self-signing key is signed by master key") - return nil, fmt.Errorf("failed to check if self-signing key is signed by master key: %w", err) - } else if !selfKeySigned { - theirSelfSignKey = id.CrossSigningKey{} + if cachedDevices.MasterKey != nil { + resp.MasterKey = cachedDevices.MasterKey.Key.Fingerprint() + resp.FirstMasterKey = cachedDevices.MasterKey.First.Fingerprint() + if !cachedDevices.HasValidSelfSigningKey { resp.Errors = append(resp.Errors, "Self-signing key is not signed by master key") } } else { resp.Errors = append(resp.Errors, "Cross-signing keys not found") } - devices, err := h.CryptoStore.GetDevices(ctx, userID) - if err != nil { - log.Err(err).Msg("Failed to get devices for user") - return nil, fmt.Errorf("failed to get devices: %w", err) - } - if userID == h.Account.UserID { - resp.UserTrusted, err = h.CryptoStore.IsKeySignedBy(ctx, userID, theirMasterKey.Key, userID, h.Crypto.OwnIdentity().SigningKey) - } else if ownUserSigningKey != "" && theirMasterKey.Key != "" { - resp.UserTrusted, err = h.CryptoStore.IsKeySignedBy(ctx, userID, theirMasterKey.Key, h.Account.UserID, ownUserSigningKey) - } - if err != nil { - log.Err(err).Msg("Failed to check if user is trusted") - resp.Errors = append(resp.Errors, fmt.Sprintf("Failed to check if user is trusted: %v", err)) - } - resp.Devices = make([]*ProfileDevice, len(devices)) - i := 0 - for _, device := range devices { - signatures, err := h.CryptoStore.GetSignaturesForKeyBy(ctx, device.UserID, device.SigningKey, device.UserID) - if err != nil { - log.Err(err).Stringer("device_id", device.DeviceID).Msg("Failed to get signatures for device") - resp.Errors = append(resp.Errors, fmt.Sprintf("Failed to get signatures for device %s: %v", device.DeviceID, err)) - } else if _, signed := signatures[theirSelfSignKey.Key]; signed && device.Trust == id.TrustStateUnset && theirSelfSignKey.Key != "" { - if resp.UserTrusted { - device.Trust = id.TrustStateCrossSignedVerified - } else if theirMasterKey.Key == theirMasterKey.First { - device.Trust = id.TrustStateCrossSignedTOFU - } else { - device.Trust = id.TrustStateCrossSignedUntrusted - } - } + resp.UserTrusted = cachedDevices.MasterKeySignedByUs + resp.Devices = make([]*ProfileDevice, len(cachedDevices.Devices)) + for i, dev := range cachedDevices.Devices { resp.Devices[i] = &ProfileDevice{ - DeviceID: device.DeviceID, - Name: device.Name, - IdentityKey: device.IdentityKey, - SigningKey: device.SigningKey, - Fingerprint: device.Fingerprint(), - Trust: device.Trust, + DeviceID: dev.DeviceID, + Name: dev.Name, + IdentityKey: dev.IdentityKey, + SigningKey: dev.SigningKey, + Fingerprint: dev.Fingerprint(), + Trust: dev.Trust, } - i++ } - slices.SortFunc(resp.Devices, func(a, b *ProfileDevice) int { - return strings.Compare(a.DeviceID.String(), b.DeviceID.String()) - }) return &resp, nil }