diff --git a/crypto/verificationhelper/sas.go b/crypto/verificationhelper/sas.go index f5f13773..4cd1dd9e 100644 --- a/crypto/verificationhelper/sas.go +++ b/crypto/verificationhelper/sas.go @@ -157,7 +157,7 @@ func (vh *VerificationHelper) ConfirmSAS(ctx context.Context, txnID id.Verificat if txn.ReceivedTheirMAC { txn.VerificationState = VerificationStateSASMACExchanged - if err := vh.trustKeysAfterMACCheck(ctx, txn, masterKey); err != nil { + if err := vh.trustKeysAfterMACCheck(ctx, txn, txn.TheirMasterKey); err != nil { return fmt.Errorf("failed to trust keys: %w", err) } @@ -750,6 +750,7 @@ func (vh *VerificationHelper) onVerificationMAC(ctx context.Context, txn Verific log.Info().Msg("All MACs verified") txn.ReceivedTheirMAC = true + txn.TheirMasterKey = masterKey if txn.SentOurMAC { txn.VerificationState = VerificationStateSASMACExchanged diff --git a/crypto/verificationhelper/verificationhelper_sas_test.go b/crypto/verificationhelper/verificationhelper_sas_test.go index 283eca84..60768fb9 100644 --- a/crypto/verificationhelper/verificationhelper_sas_test.go +++ b/crypto/verificationhelper/verificationhelper_sas_test.go @@ -358,3 +358,76 @@ func TestVerification_SAS_BothCallStart(t *testing.T) { assert.True(t, sendingCallbacks.IsVerificationDone(txnID)) assert.True(t, receivingCallbacks.IsVerificationDone(txnID)) } + +func TestCrossSignVerification_SAS(t *testing.T) { + ctx := log.Logger.WithContext(t.Context()) + + testCases := []struct { + sendingConfirmsFirst bool + }{ + {true}, + {false}, + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("sendingConfirmsFirst=%t", tc.sendingConfirmsFirst), func(t *testing.T) { + ts, sendingClient, receivingClient, _, _, sendingMachine, receivingMachine := initServerAndLoginAliceBob(t, ctx) + sendingCallbacks, receivingCallbacks, sendingHelper, receivingHelper := initDefaultCallbacks(t, ctx, sendingClient, receivingClient, sendingMachine, receivingMachine) + var err error + + _, _, err = sendingMachine.GenerateAndUploadCrossSigningKeys(ctx, nil, "") + require.NoError(t, err) + _, _, err = receivingMachine.GenerateAndUploadCrossSigningKeys(ctx, nil, "") + require.NoError(t, err) + + _, err = sendingMachine.FetchKeys(ctx, []id.UserID{bobUserID}, true) + require.NoError(t, err) + _, err = receivingMachine.FetchKeys(ctx, []id.UserID{aliceUserID}, true) + require.NoError(t, err) + + txnID, err := sendingHelper.StartVerification(ctx, bobUserID) + require.NoError(t, err) + ts.DispatchToDevice(t, ctx, receivingClient) + err = receivingHelper.AcceptVerification(ctx, txnID) + require.NoError(t, err) + ts.DispatchToDevice(t, ctx, sendingClient) + + err = sendingHelper.StartSAS(ctx, txnID) + require.NoError(t, err) + + ts.DispatchToDevice(t, ctx, receivingClient) + ts.DispatchToDevice(t, ctx, sendingClient) + ts.DispatchToDevice(t, ctx, receivingClient) + ts.DispatchToDevice(t, ctx, sendingClient) + + assert.Equal(t, sendingCallbacks.GetDecimalsShown(txnID), receivingCallbacks.GetDecimalsShown(txnID)) + + if tc.sendingConfirmsFirst { + err = sendingHelper.ConfirmSAS(ctx, txnID) + require.NoError(t, err) + + ts.DispatchToDevice(t, ctx, receivingClient) + + err = receivingHelper.ConfirmSAS(ctx, txnID) + require.NoError(t, err) + + ts.DispatchToDevice(t, ctx, sendingClient) + ts.DispatchToDevice(t, ctx, receivingClient) + } else { + err = receivingHelper.ConfirmSAS(ctx, txnID) + require.NoError(t, err) + + ts.DispatchToDevice(t, ctx, sendingClient) + + err = sendingHelper.ConfirmSAS(ctx, txnID) + require.NoError(t, err) + + ts.DispatchToDevice(t, ctx, receivingClient) + ts.DispatchToDevice(t, ctx, sendingClient) + } + + assert.True(t, sendingCallbacks.IsVerificationDone(txnID)) + assert.True(t, receivingCallbacks.IsVerificationDone(txnID)) + }) + } +} diff --git a/crypto/verificationhelper/verificationstore.go b/crypto/verificationhelper/verificationstore.go index 1eb8f752..77679c1e 100644 --- a/crypto/verificationhelper/verificationstore.go +++ b/crypto/verificationhelper/verificationstore.go @@ -90,6 +90,7 @@ type VerificationTransaction struct { EphemeralPublicKeyShared bool `json:"ephemeral_public_key_shared,omitempty"` // Whether this device's ephemeral public key has been shared OtherPublicKey *ECDHPublicKey `json:"other_public_key,omitempty"` // The other device's ephemeral public key ReceivedTheirMAC bool `json:"received_their_mac,omitempty"` // Whether we have received their MAC + TheirMasterKey string `json:"their_master_key,omitempty"` // The other user's master key from their MAC event SentOurMAC bool `json:"sent_our_mac,omitempty"` // Whether we have sent our MAC ReceivedTheirDone bool `json:"received_their_done,omitempty"` // Whether we have received their done event SentOurDone bool `json:"sent_our_done,omitempty"` // Whether we have sent our done event