diff --git a/crypto/verificationhelper/callbacks_test.go b/crypto/verificationhelper/callbacks_test.go index 5faf2009..466a60fc 100644 --- a/crypto/verificationhelper/callbacks_test.go +++ b/crypto/verificationhelper/callbacks_test.go @@ -28,6 +28,7 @@ type baseVerificationCallbacks struct { doneTransactions map[id.VerificationTransactionID]struct{} verificationCancellation map[id.VerificationTransactionID]*event.VerificationCancelEventContent emojisShown map[id.VerificationTransactionID][]rune + emojiDescriptionsShown map[id.VerificationTransactionID][]string decimalsShown map[id.VerificationTransactionID][]int } @@ -39,6 +40,7 @@ func newBaseVerificationCallbacks() *baseVerificationCallbacks { doneTransactions: map[id.VerificationTransactionID]struct{}{}, verificationCancellation: map[id.VerificationTransactionID]*event.VerificationCancelEventContent{}, emojisShown: map[id.VerificationTransactionID][]rune{}, + emojiDescriptionsShown: map[id.VerificationTransactionID][]string{}, decimalsShown: map[id.VerificationTransactionID][]int{}, } } @@ -69,8 +71,8 @@ func (c *baseVerificationCallbacks) GetVerificationCancellation(txnID id.Verific return c.verificationCancellation[txnID] } -func (c *baseVerificationCallbacks) GetEmojisShown(txnID id.VerificationTransactionID) []rune { - return c.emojisShown[txnID] +func (c *baseVerificationCallbacks) GetEmojisAndDescriptionsShown(txnID id.VerificationTransactionID) ([]rune, []string) { + return c.emojisShown[txnID], c.emojiDescriptionsShown[txnID] } func (c *baseVerificationCallbacks) GetDecimalsShown(txnID id.VerificationTransactionID) []int { @@ -104,8 +106,9 @@ func newSASVerificationCallbacksWithBase(base *baseVerificationCallbacks) *sasVe return &sasVerificationCallbacks{base} } -func (c *sasVerificationCallbacks) ShowSAS(ctx context.Context, txnID id.VerificationTransactionID, emojis []rune, decimals []int) { +func (c *sasVerificationCallbacks) ShowSAS(ctx context.Context, txnID id.VerificationTransactionID, emojis []rune, emojiDescriptions []string, decimals []int) { c.emojisShown[txnID] = emojis + c.emojiDescriptionsShown[txnID] = emojiDescriptions c.decimalsShown[txnID] = decimals } diff --git a/crypto/verificationhelper/sas.go b/crypto/verificationhelper/sas.go index 178838b8..a78b4b57 100644 --- a/crypto/verificationhelper/sas.go +++ b/crypto/verificationhelper/sas.go @@ -360,6 +360,7 @@ func (vh *VerificationHelper) onVerificationKey(ctx context.Context, txn Verific var decimals []int var emojis []rune + var emojiDescriptions []string if slices.Contains(txn.StartEventContent.ShortAuthenticationString, event.SASMethodDecimal) { decimals = []int{ (int(sasBytes[0])<<5 | int(sasBytes[1])>>3) + 1000, @@ -375,9 +376,10 @@ func (vh *VerificationHelper) onVerificationKey(ctx context.Context, txn Verific // Right shift the number and then mask the lowest 6 bits. emojiIdx := (sasNum >> uint(48-(i+1)*6)) & 0b111111 emojis = append(emojis, allEmojis[emojiIdx]) + emojiDescriptions = append(emojiDescriptions, allEmojiDescriptions[emojiIdx]) } } - vh.showSAS(ctx, txn.TransactionID, emojis, decimals) + vh.showSAS(ctx, txn.TransactionID, emojis, emojiDescriptions, decimals) if err := vh.store.SaveVerificationTransaction(ctx, txn); err != nil { log.Err(err).Msg("failed to save verification transaction") @@ -575,6 +577,73 @@ var allEmojis = []rune{ '📌', } +var allEmojiDescriptions = []string{ + "Dog", + "Cat", + "Lion", + "Horse", + "Unicorn", + "Pig", + "Elephant", + "Rabbit", + "Panda", + "Rooster", + "Penguin", + "Turtle", + "Fish", + "Octopus", + "Butterfly", + "Flower", + "Tree", + "Cactus", + "Mushroom", + "Globe", + "Moon", + "Cloud", + "Fire", + "Banana", + "Apple", + "Strawberry", + "Corn", + "Pizza", + "Cake", + "Heart", + "Smiley", + "Robot", + "Hat", + "Glasses", + "Spanner", + "Santa", + "Thumbs Up", + "Umbrella", + "Hourglass", + "Clock", + "Gift", + "Light Bulb", + "Book", + "Pencil", + "Paperclip", + "Scissors", + "Lock", + "Key", + "Hammer", + "Telephone", + "Flag", + "Train", + "Bicycle", + "Aeroplane", + "Rocket", + "Trophy", + "Ball", + "Guitar", + "Trumpet", + "Bell", + "Anchor", + "Headphones", + "Folder", + "Pin", +} + func (vh *VerificationHelper) onVerificationMAC(ctx context.Context, txn VerificationTransaction, evt *event.Event) { log := vh.getLog(ctx).With(). Str("verification_action", "mac"). diff --git a/crypto/verificationhelper/verificationhelper.go b/crypto/verificationhelper/verificationhelper.go index de943976..be547e7e 100644 --- a/crypto/verificationhelper/verificationhelper.go +++ b/crypto/verificationhelper/verificationhelper.go @@ -42,8 +42,9 @@ type RequiredCallbacks interface { type ShowSASCallbacks interface { // ShowSAS is a callback that is called when the SAS verification has // generated a short authentication string to show. It is guaranteed that - // either the emojis list, or the decimals list, or both will be present. - ShowSAS(ctx context.Context, txnID id.VerificationTransactionID, emojis []rune, decimals []int) + // either the emojis and emoji descriptions lists, or the decimals list, or + // both will be present. + ShowSAS(ctx context.Context, txnID id.VerificationTransactionID, emojis []rune, emojiDescriptions []string, decimals []int) } type ShowQRCodeCallbacks interface { @@ -75,7 +76,7 @@ type VerificationHelper struct { verificationCancelledCallback func(ctx context.Context, txnID id.VerificationTransactionID, code event.VerificationCancelCode, reason string) verificationDone func(ctx context.Context, txnID id.VerificationTransactionID) - showSAS func(ctx context.Context, txnID id.VerificationTransactionID, emojis []rune, decimals []int) + showSAS func(ctx context.Context, txnID id.VerificationTransactionID, emojis []rune, emojiDescriptions []string, decimals []int) scanQRCode func(ctx context.Context, txnID id.VerificationTransactionID) showQRCode func(ctx context.Context, txnID id.VerificationTransactionID, qrCode *QRCode) diff --git a/crypto/verificationhelper/verificationhelper_sas_test.go b/crypto/verificationhelper/verificationhelper_sas_test.go index 20e52e0f..22b1563c 100644 --- a/crypto/verificationhelper/verificationhelper_sas_test.go +++ b/crypto/verificationhelper/verificationhelper_sas_test.go @@ -165,7 +165,9 @@ func TestVerification_SAS(t *testing.T) { // Ensure that the receiving device showed emojis and SAS numbers. assert.Len(t, receivingCallbacks.GetDecimalsShown(txnID), 3) - assert.Len(t, receivingCallbacks.GetEmojisShown(txnID), 7) + emojis, descriptions := receivingCallbacks.GetEmojisAndDescriptionsShown(txnID) + assert.Len(t, emojis, 7) + assert.Len(t, descriptions, 7) } else { // Process the first key event on the sending device. ts.dispatchToDevice(t, ctx, sendingClient) @@ -178,7 +180,9 @@ func TestVerification_SAS(t *testing.T) { // Ensure that the sending device showed emojis and SAS numbers. assert.Len(t, sendingCallbacks.GetDecimalsShown(txnID), 3) - assert.Len(t, sendingCallbacks.GetEmojisShown(txnID), 7) + emojis, descriptions := sendingCallbacks.GetEmojisAndDescriptionsShown(txnID) + assert.Len(t, emojis, 7) + assert.Len(t, descriptions, 7) } assert.Equal(t, txnID, secondKeyEvt.TransactionID) assert.NotEmpty(t, secondKeyEvt.Key) @@ -193,7 +197,10 @@ func TestVerification_SAS(t *testing.T) { ts.dispatchToDevice(t, ctx, receivingClient) } assert.Equal(t, sendingCallbacks.GetDecimalsShown(txnID), receivingCallbacks.GetDecimalsShown(txnID)) - assert.Equal(t, sendingCallbacks.GetEmojisShown(txnID), receivingCallbacks.GetEmojisShown(txnID)) + sendingEmojis, sendingDescriptions := sendingCallbacks.GetEmojisAndDescriptionsShown(txnID) + receivingEmojis, receivingDescriptions := receivingCallbacks.GetEmojisAndDescriptionsShown(txnID) + assert.Equal(t, sendingEmojis, receivingEmojis) + assert.Equal(t, sendingDescriptions, receivingDescriptions) // Test that the first MAC event is correct var firstMACEvt *event.VerificationMACEventContent diff --git a/crypto/verificationhelper/verificationhelper_test.go b/crypto/verificationhelper/verificationhelper_test.go index af4a28c3..49c8db07 100644 --- a/crypto/verificationhelper/verificationhelper_test.go +++ b/crypto/verificationhelper/verificationhelper_test.go @@ -138,7 +138,7 @@ func TestVerification_Start(t *testing.T) { assert.NotEmpty(t, toDeviceInbox[receivingDeviceID]) assert.NotEmpty(t, toDeviceInbox[receivingDeviceID2]) assert.Equal(t, toDeviceInbox[receivingDeviceID], toDeviceInbox[receivingDeviceID2]) - assert.Len(t, toDeviceInbox[receivingDeviceID], 1) + require.Len(t, toDeviceInbox[receivingDeviceID], 1) // Ensure that the verification request is correct. verificationRequest := toDeviceInbox[receivingDeviceID][0].Content.AsVerificationRequest()