Actually implementing correct signature construction

This commit is contained in:
Sarah Jamie Lewis 2018-06-22 11:11:23 -07:00
förälder 1ea1521fee
incheckning 22aebae0e5
14 ändrade filer med 98 tillägg och 92 borttagningar

Visa fil

@ -80,13 +80,13 @@ func (g *Group) Invite() ([]byte, error) {
}
// AddMessage takes a DecryptedGroupMessage and adds it to the Groups Timeline
func (g *Group) AddMessage(message *protocol.DecryptedGroupMessage, verified bool) *Message {
func (g *Group) AddMessage(message *protocol.DecryptedGroupMessage, sig []byte, verified bool) *Message {
g.lock.Lock()
timelineMessage := &Message{
Message: message.GetText(),
Timestamp: time.Unix(int64(message.GetTimestamp()), 0),
Received: time.Now(),
Signature: message.GetSignature(),
Signature: sig,
Verified: verified,
PeerID: message.GetOnion(),
PreviousMessageSig: message.GetPreviousMessageSig(),

Visa fil

@ -14,7 +14,6 @@ func TestGroup(t *testing.T) {
Text: proto.String("Hello World!"),
Timestamp: proto.Int32(int32(time.Now().Unix())),
SignedGroupId: []byte{},
Signature: []byte{},
PreviousMessageSig: []byte{},
Padding: []byte{},
}

Visa fil

@ -23,21 +23,21 @@ func TestMessagePadding(t *testing.T) {
group := alice.GetGroupByGroupID(gid)
c1, _ := sarah.EncryptMessageToGroup("Hello World 1", group.GroupID)
c1, s1, _ := sarah.EncryptMessageToGroup("Hello World 1", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c1))
alice.AttemptDecryption(c1)
alice.AttemptDecryption(c1, s1)
c2, _ := alice.EncryptMessageToGroup("Hello World 2", group.GroupID)
c2, s2, _ := alice.EncryptMessageToGroup("Hello World 2", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c2))
alice.AttemptDecryption(c2)
alice.AttemptDecryption(c2, s2)
c3, _ := alice.EncryptMessageToGroup("Hello World 3", group.GroupID)
c3, s3, _ := alice.EncryptMessageToGroup("Hello World 3", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c3))
alice.AttemptDecryption(c3)
alice.AttemptDecryption(c3, s3)
c4, _ := alice.EncryptMessageToGroup("Hello World this is a much longer message 3", group.GroupID)
c4, s4, _ := alice.EncryptMessageToGroup("Hello World this is a much longer message 3", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c4))
alice.AttemptDecryption(c4)
alice.AttemptDecryption(c4, s4)
}
@ -59,33 +59,33 @@ func TestTranscriptConsistency(t *testing.T) {
t.Logf("group: %v, sarah %v", group, sarah)
c1, _ := alice.EncryptMessageToGroup("Hello World 1", group.GroupID)
c1, s1, _ := alice.EncryptMessageToGroup("Hello World 1", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c1))
alice.AttemptDecryption(c1)
alice.AttemptDecryption(c1, s1)
c2, _ := alice.EncryptMessageToGroup("Hello World 2", group.GroupID)
c2, s2, _ := alice.EncryptMessageToGroup("Hello World 2", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c2))
alice.AttemptDecryption(c2)
alice.AttemptDecryption(c2, s2)
c3, _ := alice.EncryptMessageToGroup("Hello World 3", group.GroupID)
c3, s3, _ := alice.EncryptMessageToGroup("Hello World 3", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c3))
alice.AttemptDecryption(c3)
alice.AttemptDecryption(c3, s3)
time.Sleep(time.Second * 1)
c4, _ := alice.EncryptMessageToGroup("Hello World 4", group.GroupID)
c4, s4, _ := alice.EncryptMessageToGroup("Hello World 4", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c4))
alice.AttemptDecryption(c4)
alice.AttemptDecryption(c4, s4)
c5, _ := alice.EncryptMessageToGroup("Hello World 5", group.GroupID)
c5, s5, _ := alice.EncryptMessageToGroup("Hello World 5", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c5))
_, m1 := sarah.AttemptDecryption(c1)
sarah.AttemptDecryption(c1) // Try a duplicate
_, m2 := sarah.AttemptDecryption(c2)
_, m3 := sarah.AttemptDecryption(c3)
_, m4 := sarah.AttemptDecryption(c4)
_, m5 := sarah.AttemptDecryption(c5)
_, m1 := sarah.AttemptDecryption(c1, s1)
sarah.AttemptDecryption(c1, s1) // Try a duplicate
_, m2 := sarah.AttemptDecryption(c2, s2)
_, m3 := sarah.AttemptDecryption(c3, s3)
_, m4 := sarah.AttemptDecryption(c4, s4)
_, m5 := sarah.AttemptDecryption(c5, s5)
// Now we simulate a client receiving these messages completely out of order
timeline.Insert(m1)

Visa fil

@ -10,7 +10,6 @@ import (
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
"golang.org/x/crypto/ed25519"
"io"
"strconv"
"sync"
"time"
)
@ -171,16 +170,21 @@ func (p *Profile) GetContact(onion string) (*PublicProfile, bool) {
}
// VerifyGroupMessage confirms the authenticity of a message given an onion, message and signature.
func (p *Profile) VerifyGroupMessage(onion string, groupID string, message string, timestamp int32, signature []byte) bool {
func (p *Profile) VerifyGroupMessage(onion string, groupID string, message string, timestamp int32, ciphertext []byte, signature []byte) bool {
group := p.GetGroupByGroupID(groupID)
if group == nil {
return false
}
if onion == p.Onion {
m := message + groupID + strconv.Itoa(int(timestamp))
m := groupID + group.GroupServer + string(ciphertext)
return ed25519.Verify(p.Ed25519PublicKey, []byte(m), signature)
}
contact, found := p.GetContact(onion)
if found {
m := message + groupID + strconv.Itoa(int(timestamp))
m := groupID + group.GroupServer + string(ciphertext)
return ed25519.Verify(contact.Ed25519PublicKey, []byte(m), signature)
}
return false
@ -250,7 +254,7 @@ func (p *Profile) AddGroup(group *Group) {
}
// AttemptDecryption takes a ciphertext and signature and attempts to decrypt it under known groups.
func (p *Profile) AttemptDecryption(ciphertext []byte) (bool, *Message) {
func (p *Profile) AttemptDecryption(ciphertext []byte, signature []byte) (bool, *Message) {
for _, group := range p.Groups {
success, dgm := group.DecryptMessage(ciphertext)
if success {
@ -269,8 +273,8 @@ func (p *Profile) AttemptDecryption(ciphertext []byte) (bool, *Message) {
}
}
verified := p.VerifyGroupMessage(dgm.GetOnion(), group.GroupID, dgm.GetText(), dgm.GetTimestamp(), dgm.GetSignature())
return true, group.AddMessage(dgm, verified)
verified := p.VerifyGroupMessage(dgm.GetOnion(), group.GroupID, dgm.GetText(), dgm.GetTimestamp(), ciphertext, signature)
return true, group.AddMessage(dgm, signature, verified)
}
}
return false, nil
@ -284,11 +288,11 @@ func getRandomness(arr *[]byte) {
// EncryptMessageToGroup when given a message and a group, encrypts and signs the message under the group and
// profile
func (p *Profile) EncryptMessageToGroup(message string, groupID string) ([]byte, error) {
func (p *Profile) EncryptMessageToGroup(message string, groupID string) ([]byte, []byte, error) {
group := p.GetGroupByGroupID(groupID)
if group != nil {
timestamp := time.Now().Unix()
signature := p.SignMessage(message + groupID + strconv.Itoa(int(timestamp)))
var prevSig []byte
if len(group.Timeline.Messages) > 0 {
prevSig = group.Timeline.Messages[len(group.Timeline.Messages)-1].Signature
@ -305,12 +309,12 @@ func (p *Profile) EncryptMessageToGroup(message string, groupID string) ([]byte,
Text: proto.String(message),
SignedGroupId: group.SignedGroupID[:],
Timestamp: proto.Int32(int32(timestamp)),
Signature: signature,
PreviousMessageSig: prevSig,
Padding: padding[:],
}
ciphertext := group.EncryptMessage(dm)
return ciphertext, nil
signature := p.SignMessage(groupID + group.GroupServer + string(ciphertext))
return ciphertext, signature, nil
}
return nil, errors.New("group does not exist")
return nil, nil, errors.New("group does not exist")
}

Visa fil

@ -104,29 +104,29 @@ func TestProfileGroup(t *testing.T) {
group := alice.GetGroupByGroupID(gid)
sarah.AcceptInvite(group.GroupID)
c, _ := sarah.EncryptMessageToGroup("Hello World", group.GroupID)
alice.AttemptDecryption(c)
c, s1, _ := sarah.EncryptMessageToGroup("Hello World", group.GroupID)
alice.AttemptDecryption(c, s1)
gid2, invite2, _ := alice.StartGroup("bbb.onion")
gci2 := &protocol.CwtchPeerPacket{}
proto.Unmarshal(invite2, gci2)
sarah.ProcessInvite(gci2.GetGroupChatInvite(), alice.Onion)
group2 := alice.GetGroupByGroupID(gid2)
c2, _ := sarah.EncryptMessageToGroup("Hello World", group2.GroupID)
alice.AttemptDecryption(c2)
c2, s2, _ := sarah.EncryptMessageToGroup("Hello World", group2.GroupID)
alice.AttemptDecryption(c2, s2)
bob := GenerateNewProfile("bob")
bob.AddContact(alice.Onion, &alice.PublicProfile)
bob.ProcessInvite(gci2.GetGroupChatInvite(), alice.Onion)
c3, err := bob.EncryptMessageToGroup("Bobs Message", group2.GroupID)
c3, s3, err := bob.EncryptMessageToGroup("Bobs Message", group2.GroupID)
if err == nil {
ok, message := alice.AttemptDecryption(c3)
ok, message := alice.AttemptDecryption(c3, s3)
if ok != true || message.Verified == true {
t.Errorf("Bobs message to the group should be decrypted but not verified by alice instead %v %v", message, ok)
}
eve := GenerateNewProfile("eve")
ok, _ = eve.AttemptDecryption(c3)
ok, _ = eve.AttemptDecryption(c3, s3)
if ok {
t.Errorf("Eves hould not be able to decrypt messages!")
}

Visa fil

@ -29,7 +29,7 @@ func (ts *TestServer) HandleGroupMessage(gm *protocol.GroupMessage) {
}
func (ts *TestServer) HandleFetchRequest() []*protocol.GroupMessage {
return []*protocol.GroupMessage{{Ciphertext: []byte("hello"), Spamguard: []byte{}}, {Ciphertext: []byte("hello"), Spamguard: []byte{}}}
return []*protocol.GroupMessage{{Ciphertext: []byte("hello"), Signature: []byte{}, Spamguard: []byte{}}, {Ciphertext: []byte("hello"), Signature: []byte{}, Spamguard: []byte{}}}
}
func runtestserver(t *testing.T, ts *TestServer, privateKey *rsa.PrivateKey) {
@ -92,7 +92,7 @@ func TestPeerServerConnection(t *testing.T) {
t.Errorf("connection should now be authed(%v), instead was %v", AUTHENTICATED, state)
}
gm := &protocol.GroupMessage{Ciphertext: []byte("hello")}
gm := &protocol.GroupMessage{Ciphertext: []byte("hello"), Signature: []byte{}}
psc.SendGroupMessage(gm)
time.Sleep(time.Second * 2)
if ts.Received == false {

Visa fil

@ -214,7 +214,7 @@ func (cp *cwtchPeer) InviteOnionToGroup(onion string, groupid string) error {
// ReceiveGroupMessage is a callback function that processes GroupMessages from a given server
func (cp *cwtchPeer) ReceiveGroupMessage(server string, gm *protocol.GroupMessage) {
cp.Profile.AttemptDecryption(gm.Ciphertext)
cp.Profile.AttemptDecryption(gm.Ciphertext, gm.Signature)
}
// JoinServer manages a new server connection with the given onion address
@ -232,12 +232,13 @@ func (cp *cwtchPeer) SendMessageToGroup(groupid string, message string) error {
if psc == nil {
return errors.New("could not find server connection to send message to")
}
ct, err := cp.Profile.EncryptMessageToGroup(message, groupid)
ct, sig, err := cp.Profile.EncryptMessageToGroup(message, groupid)
if err != nil {
return err
}
gm := &protocol.GroupMessage{
Ciphertext: ct,
Signature: sig,
}
err = psc.SendGroupMessage(gm)
return err

Visa fil

@ -74,7 +74,7 @@ func TestPeerFetchChannel(t *testing.T) {
csp := &protocol.CwtchServerPacket{
GroupMessage: &protocol.GroupMessage{
Ciphertext: []byte("hello"), Spamguard: []byte{},
Ciphertext: []byte("hello"), Signature: []byte{}, Spamguard: []byte{},
},
}
packet, _ := proto.Marshal(csp)

Visa fil

@ -71,7 +71,7 @@ func TestPeerListenChannel(t *testing.T) {
}
csp := &protocol.CwtchServerPacket{
GroupMessage: &protocol.GroupMessage{Ciphertext: []byte("hello"), Spamguard: []byte{}},
GroupMessage: &protocol.GroupMessage{Ciphertext: []byte("hello"), Signature: []byte{}, Spamguard: []byte{}},
}
packet, _ := proto.Marshal(csp)

Visa fil

@ -50,6 +50,7 @@ func (*FetchMessage) Descriptor() ([]byte, []int) { return fileDescriptor2, []in
type GroupMessage struct {
Ciphertext []byte `protobuf:"bytes,1,req,name=ciphertext" json:"ciphertext,omitempty"`
Spamguard []byte `protobuf:"bytes,2,req,name=spamguard" json:"spamguard,omitempty"`
Signature []byte `protobuf:"bytes,3,req,name=signature" json:"signature,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
@ -72,6 +73,13 @@ func (m *GroupMessage) GetSpamguard() []byte {
return nil
}
func (m *GroupMessage) GetSignature() []byte {
if m != nil {
return m.Signature
}
return nil
}
// DecryptedGroupMessage is *never* sent in the clear on the wire
// and is only ever sent when encrypted in the ciphertext parameter of
// GroupMessage
@ -79,11 +87,10 @@ type DecryptedGroupMessage struct {
Onion *string `protobuf:"bytes,1,req,name=onion" json:"onion,omitempty"`
Timestamp *int32 `protobuf:"varint,2,req,name=timestamp" json:"timestamp,omitempty"`
Text *string `protobuf:"bytes,3,req,name=text" json:"text,omitempty"`
Signature []byte `protobuf:"bytes,4,req,name=signature" json:"signature,omitempty"`
SignedGroupId []byte `protobuf:"bytes,5,req,name=signed_group_id,json=signedGroupId" json:"signed_group_id,omitempty"`
PreviousMessageSig []byte `protobuf:"bytes,6,req,name=previous_message_sig,json=previousMessageSig" json:"previous_message_sig,omitempty"`
SignedGroupId []byte `protobuf:"bytes,4,req,name=signed_group_id,json=signedGroupId" json:"signed_group_id,omitempty"`
PreviousMessageSig []byte `protobuf:"bytes,5,req,name=previous_message_sig,json=previousMessageSig" json:"previous_message_sig,omitempty"`
// Used to prevent analysis on text length, length is 1024 - len(text)
Padding []byte `protobuf:"bytes,7,req,name=padding" json:"padding,omitempty"`
Padding []byte `protobuf:"bytes,6,req,name=padding" json:"padding,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
@ -113,13 +120,6 @@ func (m *DecryptedGroupMessage) GetText() string {
return ""
}
func (m *DecryptedGroupMessage) GetSignature() []byte {
if m != nil {
return m.Signature
}
return nil
}
func (m *DecryptedGroupMessage) GetSignedGroupId() []byte {
if m != nil {
return m.SignedGroupId
@ -161,29 +161,28 @@ func init() {
func init() { proto.RegisterFile("group_message.proto", fileDescriptor2) }
var fileDescriptor2 = []byte{
// 372 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0xdd, 0xaa, 0xd3, 0x30,
0x1c, 0xa7, 0xfb, 0x70, 0xee, 0xbf, 0x6e, 0x62, 0x9c, 0x1a, 0x44, 0xa4, 0xf4, 0x42, 0x76, 0x35,
0xc4, 0x4b, 0x87, 0x20, 0x4c, 0x14, 0x41, 0x45, 0xba, 0x07, 0x28, 0xa1, 0xfd, 0x2f, 0x0d, 0xb6,
0x49, 0x48, 0xd2, 0x9d, 0x73, 0xde, 0xe0, 0x3c, 0xdc, 0x79, 0x99, 0xf3, 0x06, 0x87, 0xa6, 0xeb,
0xd6, 0x9d, 0x8b, 0x73, 0x55, 0x7e, 0xdf, 0x21, 0x0d, 0xbc, 0xe2, 0x46, 0xd5, 0x3a, 0xad, 0xd0,
0x5a, 0xc6, 0x71, 0xad, 0x8d, 0x72, 0x8a, 0x3c, 0xf7, 0x9f, 0x4c, 0x95, 0xef, 0x96, 0x5b, 0x25,
0x9d, 0x51, 0xe5, 0xb6, 0x60, 0x52, 0x62, 0xd9, 0xea, 0xf1, 0x5d, 0x00, 0x2f, 0xb7, 0x57, 0x2e,
0x2b, 0x76, 0x68, 0x0e, 0x68, 0xfe, 0xb1, 0xec, 0x3f, 0x3a, 0xb2, 0x81, 0xf9, 0x45, 0x19, 0x0d,
0xa2, 0x60, 0x35, 0xfb, 0xfc, 0x66, 0xdd, 0xb5, 0xad, 0x7f, 0x36, 0xf2, 0x9f, 0x56, 0x4d, 0x42,
0xde, 0x43, 0x4d, 0x78, 0x8f, 0x2e, 0x2b, 0x4e, 0xe1, 0xc1, 0xe3, 0xf0, 0x8f, 0x46, 0x3e, 0x85,
0xf7, 0x3d, 0x44, 0xbe, 0xc2, 0xe2, 0x62, 0xd9, 0xd2, 0x61, 0x34, 0x7c, 0x62, 0x7a, 0xde, 0x9f,
0xb6, 0xf1, 0x02, 0xc2, 0x7e, 0x79, 0xfc, 0x1b, 0xc2, 0xbe, 0x9d, 0x7c, 0x00, 0xc8, 0x84, 0x2e,
0xd0, 0x38, 0xbc, 0x76, 0x34, 0x88, 0x06, 0xab, 0x30, 0xe9, 0x31, 0xe4, 0x3d, 0x4c, 0xad, 0x66,
0x15, 0xaf, 0x99, 0xc9, 0xe9, 0xc0, 0xcb, 0x67, 0x22, 0xbe, 0x0f, 0xe0, 0xf5, 0x77, 0xcc, 0xcc,
0x8d, 0x76, 0x98, 0x5f, 0xf4, 0x2e, 0x61, 0xac, 0xa4, 0x50, 0xd2, 0x57, 0x4e, 0x93, 0x16, 0x34,
0x6d, 0x4e, 0x54, 0x68, 0x1d, 0xab, 0xb4, 0x6f, 0x1b, 0x27, 0x67, 0x82, 0x10, 0x18, 0xf9, 0x53,
0x0c, 0x7d, 0x64, 0x74, 0xda, 0x17, 0x5c, 0x32, 0x57, 0x1b, 0xa4, 0xa3, 0xe3, 0x7e, 0x47, 0x90,
0x8f, 0xf0, 0xa2, 0x01, 0x98, 0xa7, 0xed, 0x1d, 0x89, 0x9c, 0x8e, 0xbd, 0x67, 0xde, 0xd2, 0xfe,
0x48, 0xbf, 0x72, 0xf2, 0x09, 0x96, 0xda, 0xe0, 0x41, 0xa8, 0xda, 0x76, 0xf7, 0x98, 0x5a, 0xc1,
0xe9, 0x33, 0x6f, 0x26, 0x9d, 0x76, 0x3c, 0xfc, 0x4e, 0x70, 0x42, 0x61, 0xa2, 0x59, 0x9e, 0x0b,
0xc9, 0xe9, 0xc4, 0x9b, 0x3a, 0xf8, 0x65, 0x03, 0xa1, 0xf5, 0x4f, 0x23, 0x95, 0x4a, 0x66, 0x48,
0xde, 0x9e, 0x7f, 0xc4, 0xf1, 0x25, 0x25, 0x68, 0xeb, 0xd2, 0xd1, 0xdb, 0x6f, 0x51, 0xb0, 0x0a,
0x93, 0x59, 0xeb, 0xfe, 0xdb, 0x98, 0x1f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x3c, 0x2e, 0xc6, 0x75,
0x93, 0x02, 0x00, 0x00,
// 360 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x92, 0x4d, 0x6e, 0xdb, 0x30,
0x10, 0x85, 0x21, 0xff, 0xb4, 0xf5, 0x58, 0x6e, 0x51, 0xd6, 0x6d, 0x89, 0xa2, 0x28, 0x0c, 0x2d,
0x0a, 0xaf, 0x8c, 0x20, 0xcb, 0x78, 0x13, 0xc0, 0x41, 0x82, 0x2c, 0x12, 0x04, 0xf2, 0x01, 0x04,
0x42, 0x1a, 0x53, 0x4c, 0x24, 0x92, 0x20, 0x29, 0x27, 0xb9, 0x41, 0x36, 0x39, 0x5d, 0x2e, 0x14,
0x88, 0xb2, 0x6c, 0x39, 0x2b, 0x69, 0xde, 0x37, 0x6f, 0xde, 0x80, 0x24, 0xfc, 0xe0, 0x46, 0x55,
0x3a, 0x29, 0xd1, 0x5a, 0xc6, 0x71, 0xa1, 0x8d, 0x72, 0x8a, 0x7c, 0xf1, 0x9f, 0x54, 0x15, 0x7f,
0xa6, 0x2b, 0x25, 0x9d, 0x51, 0xc5, 0x2a, 0x67, 0x52, 0x62, 0xd1, 0xf0, 0xe8, 0x35, 0x80, 0xef,
0xab, 0x47, 0x97, 0xe6, 0x6b, 0x34, 0x5b, 0x34, 0x77, 0x2c, 0x7d, 0x40, 0x47, 0x96, 0x30, 0x39,
0x1a, 0x46, 0x83, 0x59, 0x30, 0x1f, 0x9f, 0xfe, 0x5a, 0xb4, 0xd3, 0x16, 0x57, 0x35, 0xbe, 0x69,
0x68, 0x1c, 0xf2, 0x4e, 0x55, 0x9b, 0x37, 0xe8, 0xd2, 0x7c, 0x6f, 0xee, 0x7d, 0x34, 0x5f, 0xd6,
0x78, 0x6f, 0xde, 0x74, 0xaa, 0xe8, 0x2b, 0x84, 0x5d, 0x1a, 0xdd, 0x43, 0xd8, 0x8d, 0x22, 0xff,
0x00, 0x52, 0xa1, 0x73, 0x34, 0x0e, 0x9f, 0x1c, 0x0d, 0x66, 0xbd, 0x79, 0x18, 0x77, 0x14, 0xf2,
0x17, 0x46, 0x56, 0xb3, 0x92, 0x57, 0xcc, 0x64, 0xb4, 0xe7, 0xf1, 0x41, 0xf0, 0x54, 0x70, 0xc9,
0x5c, 0x65, 0x90, 0xf6, 0x77, 0xb4, 0x15, 0xa2, 0xb7, 0x00, 0x7e, 0x5e, 0x60, 0x6a, 0x9e, 0xb5,
0xc3, 0xec, 0x28, 0x75, 0x0a, 0x43, 0x25, 0x85, 0x92, 0x3e, 0x70, 0x14, 0x37, 0x45, 0x3d, 0xcd,
0x89, 0x12, 0xad, 0x63, 0xa5, 0xf6, 0x59, 0xc3, 0xf8, 0x20, 0x10, 0x02, 0x03, 0xbf, 0x63, 0xdf,
0x5b, 0xfc, 0x3f, 0xf9, 0x0f, 0xdf, 0xea, 0x38, 0xcc, 0x92, 0xe6, 0x78, 0x45, 0x46, 0x07, 0x7e,
0x8b, 0x49, 0x23, 0xfb, 0xd0, 0xeb, 0x8c, 0x9c, 0xc0, 0x54, 0x1b, 0xdc, 0x0a, 0x55, 0xd9, 0xf6,
0x14, 0x13, 0x2b, 0x38, 0x1d, 0xfa, 0x66, 0xd2, 0xb2, 0xdd, 0x7a, 0x6b, 0xc1, 0x09, 0x85, 0xcf,
0x9a, 0x65, 0x99, 0x90, 0x9c, 0x7e, 0xf2, 0x4d, 0x6d, 0x79, 0xb6, 0x84, 0xd0, 0xfa, 0xbb, 0x4d,
0xa4, 0x92, 0x29, 0x92, 0xdf, 0x87, 0x7b, 0xd8, 0x3d, 0x85, 0x18, 0x6d, 0x55, 0x38, 0xfa, 0x72,
0x3e, 0x0b, 0xe6, 0x61, 0x3c, 0x6e, 0xba, 0x6f, 0xeb, 0xe6, 0xf7, 0x00, 0x00, 0x00, 0xff, 0xff,
0x33, 0x30, 0xca, 0x8b, 0x54, 0x02, 0x00, 0x00,
}

Visa fil

@ -18,6 +18,7 @@ message FetchMessage {
message GroupMessage {
required bytes ciphertext = 1;
required bytes spamguard = 2;
required bytes signature = 3;
}
// DecryptedGroupMessage is *never* sent in the clear on the wire
@ -27,9 +28,8 @@ message DecryptedGroupMessage {
required string onion = 1;
required int32 timestamp = 2;
required string text = 3;
required bytes signature = 4;
required bytes signed_group_id = 5;
required bytes previous_message_sig =6;
required bytes signed_group_id = 4;
required bytes previous_message_sig =5;
// Used to prevent analysis on text length, length is 1024 - len(text)
required bytes padding = 7;
required bytes padding = 6;
}

Visa fil

@ -69,6 +69,7 @@ func TestServerListenChannel(t *testing.T) {
if control.GetChannelResult() != nil {
gm := &protocol.GroupMessage{
Ciphertext: []byte("Hello"),
Signature: []byte{},
Spamguard: []byte{},
}
cslc.SendGroupMessage(gm)

Visa fil

@ -86,6 +86,7 @@ func TestServerSendChannel(t *testing.T) {
gm := &protocol.GroupMessage{
Ciphertext: []byte("Hello"),
Signature: []byte{},
Spamguard: sgsolve,
}
@ -147,6 +148,7 @@ func TestServerSendChannelNoSpamGuard(t *testing.T) {
gm := &protocol.GroupMessage{
Ciphertext: []byte("hello"),
Signature: []byte{},
Spamguard: sgsolve,
}

Visa fil

@ -182,7 +182,7 @@ func TestCwtchPeerIntegration(t *testing.T) {
bob.JoinServer(serverAddr)
fmt.Println("Waiting for peerings and server joins...")
time.Sleep(time.Second * 60)
time.Sleep(time.Second * 120)
fmt.Println("Alice inviting Bob to group...")
err = alice.InviteOnionToGroup(bob.GetProfile().Onion, groupID)