mirror of
https://dev.narayana.im/narayana/telegabber.git
synced 2026-08-05 12:17:06 +00:00
136 lines
3.4 KiB
Go
136 lines
3.4 KiB
Go
package omemo
|
|
|
|
import (
|
|
"bytes"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestEncryptOuterRoundTrip(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
version Version
|
|
}{
|
|
{"omemo0", Omemo0},
|
|
{"omemo1", Omemo1},
|
|
{"omemo2", Omemo2},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
plaintext := []byte("hello from telegram")
|
|
|
|
payload, err := EncryptOuter(tc.version, plaintext, "gateway@example.com")
|
|
if err != nil {
|
|
t.Fatalf("EncryptOuter: %v", err)
|
|
}
|
|
if len(payload.Ciphertext) == 0 {
|
|
t.Fatalf("expected non-empty ciphertext")
|
|
}
|
|
if tc.version == Omemo0 && len(payload.IV) != omemo0IVLen {
|
|
t.Fatalf("expected a %d-byte IV for omemo0, got %d", omemo0IVLen, len(payload.IV))
|
|
}
|
|
if tc.version != Omemo0 && payload.IV != nil {
|
|
t.Fatalf("expected no IV for %s (receiver re-derives it), got %d bytes", tc.name, len(payload.IV))
|
|
}
|
|
|
|
got, err := DecryptOuter(tc.version, payload)
|
|
if err != nil {
|
|
t.Fatalf("DecryptOuter: %v", err)
|
|
}
|
|
if !bytes.Equal(got, plaintext) {
|
|
t.Fatalf("round trip mismatch: got %q, want %q", got, plaintext)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEncryptOuterTamperDetection(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
version Version
|
|
}{
|
|
{"omemo0", Omemo0},
|
|
{"omemo1", Omemo1},
|
|
{"omemo2", Omemo2},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
payload, err := EncryptOuter(tc.version, []byte("secret"), "gateway@example.com")
|
|
if err != nil {
|
|
t.Fatalf("EncryptOuter: %v", err)
|
|
}
|
|
|
|
tampered := *payload
|
|
tampered.Ciphertext = append([]byte{}, payload.Ciphertext...)
|
|
tampered.Ciphertext[0] ^= 0xFF
|
|
|
|
if _, err := DecryptOuter(tc.version, &tampered); err == nil {
|
|
t.Fatalf("expected DecryptOuter to reject tampered ciphertext")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSCERoundTrip(t *testing.T) {
|
|
plaintext := []byte("hello sce")
|
|
|
|
t.Run("v0", func(t *testing.T) {
|
|
xmlBytes, err := sceEncodeV0(plaintext, "alice@example.com")
|
|
if err != nil {
|
|
t.Fatalf("sceEncodeV0: %v", err)
|
|
}
|
|
got, err := sceDecodeV0(xmlBytes)
|
|
if err != nil {
|
|
t.Fatalf("sceDecodeV0: %v", err)
|
|
}
|
|
if !bytes.Equal(got, plaintext) {
|
|
t.Fatalf("got %q, want %q", got, plaintext)
|
|
}
|
|
})
|
|
|
|
t.Run("v1", func(t *testing.T) {
|
|
xmlBytes, err := sceEncodeV1(plaintext, "alice@example.com")
|
|
if err != nil {
|
|
t.Fatalf("sceEncodeV1: %v", err)
|
|
}
|
|
got, err := sceDecodeV1(xmlBytes)
|
|
if err != nil {
|
|
t.Fatalf("sceDecodeV1: %v", err)
|
|
}
|
|
if !bytes.Equal(got, plaintext) {
|
|
t.Fatalf("got %q, want %q", got, plaintext)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestWireEnvelopeEncodeDecode(t *testing.T) {
|
|
env := &WireEnvelope{
|
|
Version: Omemo2,
|
|
SenderSID: 12345,
|
|
Payload: []byte("ciphertext-bytes"),
|
|
Keys: []WireKey{
|
|
{RecipientJID: "bob@example.com", DeviceID: 1, IsPreKey: true, Ciphertext: []byte("key-ciphertext-1")},
|
|
{RecipientJID: "bob@example.com", DeviceID: 2, IsPreKey: false, Ciphertext: []byte("key-ciphertext-2")},
|
|
},
|
|
}
|
|
|
|
raw, err := env.Encode()
|
|
if err != nil {
|
|
t.Fatalf("Encode: %v", err)
|
|
}
|
|
|
|
got, err := DecodeWireEnvelope(raw)
|
|
if err != nil {
|
|
t.Fatalf("DecodeWireEnvelope: %v", err)
|
|
}
|
|
|
|
if got.Version != env.Version || got.SenderSID != env.SenderSID || !bytes.Equal(got.Payload, env.Payload) {
|
|
t.Fatalf("round trip mismatch: got %+v", got)
|
|
}
|
|
if len(got.Keys) != len(env.Keys) {
|
|
t.Fatalf("expected %d keys, got %d", len(env.Keys), len(got.Keys))
|
|
}
|
|
for i := range env.Keys {
|
|
if !reflect.DeepEqual(got.Keys[i], env.Keys[i]) {
|
|
t.Fatalf("key %d mismatch: got %+v, want %+v", i, got.Keys[i], env.Keys[i])
|
|
}
|
|
}
|
|
}
|