Adding padding and length stuff

Este commit está contenido en:
Sarah Jamie Lewis 2018-05-28 10:44:47 -07:00
padre 7a94394e59
commit 6de91969ae
Se han modificado 8 ficheros con 108 adiciones y 31 borrados

Ver fichero

@ -50,6 +50,7 @@ func NewGroup(server string) *Group {
// SignGroup adds a signature to the group.
func (g *Group) SignGroup(signature []byte) {
g.SignedGroupID = signature
copy(g.Timeline.SignedGroupId[:], g.SignedGroupID)
}
// Compromised should be called if we detect a a groupkey leak.
@ -95,7 +96,7 @@ func (g *Group) AddMessage(message *protocol.DecryptedGroupMessage, verified boo
return timelineMessage
}
// GetTimeline provides a safe copy of the timeline
// GetTimeline provides a safe copy of the timeline-=
func (g *Group) GetTimeline() (t []Message) {
g.lock.Lock()
t = g.Timeline.GetMessages()

Ver fichero

@ -16,6 +16,7 @@ func TestGroup(t *testing.T) {
SignedGroupId: []byte{},
Signature: []byte{},
PreviousMessageSig: []byte{},
Padding: []byte{},
}
encMessage := g.EncryptMessage(dgm)
ok, message := g.DecryptMessage(encMessage)

Ver fichero

@ -9,8 +9,9 @@ import (
// Timeline encapsulates a collection of ordered messages, and a mechanism to access them
// in a threadsafe manner.
type Timeline struct {
Messages []Message
lock sync.Mutex
Messages []Message
SignedGroupId []byte
lock sync.Mutex
}
// Message is a local representation of a given message sent over a group chat channel.
@ -54,14 +55,14 @@ func (t *Timeline) Swap(i, j int) {
t.Messages[i], t.Messages[j] = t.Messages[j], t.Messages[i]
}
// Less checks 2 messages (i andj) in the timeline and returns true if i cccured before j, else false
// Less checks 2 messages (i andj) in the timeline and returns true if i occcured before j, else false
func (t *Timeline) Less(i, j int) bool {
if t.Messages[i].Timestamp.Before(t.Messages[j].Timestamp) {
return true
}
if compareSignatures(t.Messages[i].PreviousMessageSig, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) {
if compareSignatures(t.Messages[i].PreviousMessageSig, t.SignedGroupId) {
return true
}

Ver fichero

@ -3,10 +3,44 @@ package model
import (
"git.mascherari.press/cwtch/protocol"
"github.com/golang/protobuf/proto"
"strconv"
"testing"
"time"
)
func TestMessagePadding(t *testing.T) {
// Setup the Group
sarah := GenerateNewProfile("Sarah")
alice := GenerateNewProfile("Alice")
sarah.AddContact(alice.Onion, &alice.PublicProfile)
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
gid, invite, _ := alice.StartGroup("aaa.onion")
gci := &protocol.CwtchPeerPacket{}
proto.Unmarshal(invite, gci)
sarah.ProcessInvite(gci.GetGroupChatInvite(), alice.Onion)
group := alice.GetGroupByGroupID(gid)
c1, _ := sarah.EncryptMessageToGroup("Hello World 1", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c1))
alice.AttemptDecryption(c1)
c2, _ := alice.EncryptMessageToGroup("Hello World 2", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c2))
alice.AttemptDecryption(c2)
c3, _ := alice.EncryptMessageToGroup("Hello World 3", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c3))
alice.AttemptDecryption(c3)
c4, _ := 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)
}
func TestTranscriptConsistency(t *testing.T) {
timeline := new(Timeline)
@ -26,20 +60,25 @@ func TestTranscriptConsistency(t *testing.T) {
t.Logf("group: %v, sarah %v", group, sarah)
c1, _ := sarah.EncryptMessageToGroup("Hello World 1", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c1))
alice.AttemptDecryption(c1)
c2, _ := alice.EncryptMessageToGroup("Hello World 2", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c2))
alice.AttemptDecryption(c2)
c3, _ := alice.EncryptMessageToGroup("Hello World 3", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c3))
alice.AttemptDecryption(c3)
time.Sleep(time.Second * 1)
c4, _ := alice.EncryptMessageToGroup("Hello World 4", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c4))
alice.AttemptDecryption(c4)
c5, _ := alice.EncryptMessageToGroup("Hello World 5", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c5))
_, m1 := sarah.AttemptDecryption(c1)
_, m2 := sarah.AttemptDecryption(c2)
@ -55,6 +94,10 @@ func TestTranscriptConsistency(t *testing.T) {
timeline.Insert(m2)
for i, m := range timeline.GetMessages() {
if m.Message != "Hello World "+strconv.Itoa(i+1) {
t.Fatalf("Timeline Out of Order!: %v %v", i, m)
}
t.Logf("Messages %v: %v %x %x", i, m.Message, m.Signature, m.PreviousMessageSig)
}
}

Ver fichero

@ -10,6 +10,7 @@ import (
"github.com/golang/protobuf/proto"
"github.com/s-rah/go-ricochet/utils"
"golang.org/x/crypto/ed25519"
"io"
"io/ioutil"
"strconv"
"time"
@ -177,6 +178,12 @@ func (p *Profile) AttemptDecryption(ciphertext []byte) (bool, *Message) {
return false, nil
}
func getRandomness(arr *[]byte) {
if _, err := io.ReadFull(rand.Reader, (*arr)[:]); err != nil {
utils.CheckError(err)
}
}
// 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) {
@ -188,8 +195,13 @@ func (p *Profile) EncryptMessageToGroup(message string, groupID string) ([]byte,
if len(group.Timeline.Messages) > 0 {
prevSig = group.Timeline.Messages[len(group.Timeline.Messages)-1].Signature
} else {
prevSig = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
prevSig = group.SignedGroupID
}
lenPadding := 1024 - len(message)
padding := make([]byte, lenPadding)
getRandomness(&padding)
dm := &protocol.DecryptedGroupMessage{
Onion: proto.String(p.Onion),
Text: proto.String(message),
@ -197,6 +209,7 @@ func (p *Profile) EncryptMessageToGroup(message string, groupID string) ([]byte,
Timestamp: proto.Int32(int32(timestamp)),
Signature: signature,
PreviousMessageSig: prevSig,
Padding: padding[:],
}
ciphertext := group.EncryptMessage(dm)
return ciphertext, nil

Ver fichero

@ -90,7 +90,9 @@ type DecryptedGroupMessage struct {
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"`
XXX_unrecognized []byte `json:"-"`
// Used to prevent analysis on text length, length is 1024 - len(text)
Padding []byte `protobuf:"bytes,7,req,name=padding" json:"padding,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *DecryptedGroupMessage) Reset() { *m = DecryptedGroupMessage{} }
@ -140,6 +142,13 @@ func (m *DecryptedGroupMessage) GetPreviousMessageSig() []byte {
return nil
}
func (m *DecryptedGroupMessage) GetPadding() []byte {
if m != nil {
return m.Padding
}
return nil
}
var E_ServerNonce = &proto.ExtensionDesc{
ExtendedType: (*control.ChannelResult)(nil),
ExtensionType: ([]byte)(nil),
@ -160,28 +169,29 @@ func init() {
func init() { proto.RegisterFile("group_message.proto", fileDescriptor2) }
var fileDescriptor2 = []byte{
// 358 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0xcd, 0x4a, 0xeb, 0x40,
0x14, 0x26, 0xfd, 0xb9, 0xdc, 0x9e, 0xa6, 0xbd, 0xdc, 0xb9, 0xbd, 0x3a, 0x88, 0x48, 0xc8, 0x42,
0xba, 0x2a, 0xe2, 0xd2, 0x22, 0x08, 0x15, 0x45, 0x50, 0x91, 0xf4, 0x01, 0x42, 0x48, 0x4e, 0x93,
0xc1, 0x64, 0x66, 0x98, 0x99, 0x54, 0x7d, 0x03, 0x1f, 0xce, 0xbd, 0xaf, 0x23, 0x99, 0x34, 0x6d,
0xea, 0xc2, 0xd5, 0x70, 0xbe, 0xdf, 0xc3, 0x61, 0xe0, 0x5f, 0xaa, 0x44, 0x29, 0xc3, 0x02, 0xb5,
0x8e, 0x52, 0x9c, 0x49, 0x25, 0x8c, 0x20, 0xbf, 0xed, 0x13, 0x8b, 0xfc, 0x68, 0xb2, 0x10, 0xdc,
0x28, 0x91, 0x2f, 0xb2, 0x88, 0x73, 0xcc, 0x6b, 0xde, 0xff, 0x70, 0xe0, 0xef, 0xe2, 0xc5, 0xc4,
0xd9, 0x12, 0xd5, 0x1a, 0xd5, 0x53, 0x14, 0x3f, 0xa3, 0x21, 0x73, 0x18, 0xed, 0x85, 0x51, 0xc7,
0x73, 0xa6, 0xc3, 0xf3, 0x83, 0x59, 0x93, 0x36, 0xbb, 0xad, 0xe8, 0x87, 0x9a, 0x0d, 0xdc, 0xb4,
0x35, 0x55, 0xe6, 0x15, 0x9a, 0x38, 0xdb, 0x9a, 0x3b, 0xdf, 0xcd, 0x37, 0x15, 0xbd, 0x35, 0xaf,
0x5a, 0x13, 0xb9, 0x84, 0xf1, 0x5e, 0xb3, 0xa6, 0x5d, 0xaf, 0xfb, 0x43, 0xf5, 0xa8, 0x5d, 0xad,
0xfd, 0x31, 0xb8, 0xed, 0x70, 0xff, 0x1e, 0xdc, 0xb6, 0x9c, 0x9c, 0x00, 0xc4, 0x4c, 0x66, 0xa8,
0x0c, 0xbe, 0x1a, 0xea, 0x78, 0x9d, 0xa9, 0x1b, 0xb4, 0x10, 0x72, 0x0c, 0x03, 0x2d, 0xa3, 0x22,
0x2d, 0x23, 0x95, 0xd0, 0x8e, 0xa5, 0x77, 0x80, 0xff, 0xe9, 0xc0, 0xff, 0x6b, 0x8c, 0xd5, 0x9b,
0x34, 0x98, 0xec, 0xe5, 0x4e, 0xa0, 0x2f, 0x38, 0x13, 0xdc, 0x46, 0x0e, 0x82, 0x7a, 0xa8, 0xd2,
0x0c, 0x2b, 0x50, 0x9b, 0xa8, 0x90, 0x36, 0xad, 0x1f, 0xec, 0x00, 0x42, 0xa0, 0x67, 0xb7, 0xe8,
0x5a, 0x4b, 0x6f, 0xdb, 0xcf, 0x52, 0x1e, 0x99, 0x52, 0x21, 0xed, 0x6d, 0xfa, 0x1b, 0x80, 0x9c,
0xc2, 0x9f, 0x6a, 0xc0, 0x24, 0xac, 0x6f, 0xc4, 0x12, 0xda, 0xb7, 0x9a, 0x51, 0x0d, 0xdb, 0x95,
0xee, 0x12, 0x72, 0x06, 0x13, 0xa9, 0x70, 0xcd, 0x44, 0xa9, 0x9b, 0x3b, 0x86, 0x9a, 0xa5, 0xf4,
0x97, 0x15, 0x93, 0x86, 0xdb, 0x2c, 0xbf, 0x64, 0xe9, 0xc5, 0x1c, 0x5c, 0x6d, 0x3f, 0x40, 0xc8,
0x05, 0x8f, 0x91, 0x1c, 0xee, 0xce, 0xbd, 0xf9, 0x2f, 0x01, 0xea, 0x32, 0x37, 0xf4, 0xfd, 0xca,
0x73, 0xa6, 0x6e, 0x30, 0xac, 0xd5, 0x8f, 0x95, 0xf8, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x54, 0x1a,
0x6d, 0xda, 0x79, 0x02, 0x00, 0x00,
// 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,
}

Ver fichero

@ -31,4 +31,6 @@ message DecryptedGroupMessage {
required bytes signature = 4;
required bytes signed_group_id = 5;
required bytes previous_message_sig =6;
// Used to prevent analysis on text length, length is 1024 - len(text)
required bytes padding = 7;
}

Ver fichero

@ -79,6 +79,12 @@ func (sg *Guard) ValidateChallenge(message []byte, spamguard []byte) bool {
if len(spamguard) != 24 {
return false
}
// If the message is too large just throw it away.
if len(message) > 2048 {
return false
}
solve := make([]byte, len(sg.nonce)+len(message)+len(spamguard))
copy(solve[0:], sg.nonce[:])
copy(solve[len(sg.nonce):], message[:])