diff --git a/model/group.go b/model/group.go index 07448ad..eede82c 100644 --- a/model/group.go +++ b/model/group.go @@ -23,6 +23,7 @@ type Group struct { Timeline Timeline Accepted bool Owner string + IsCompromised bool lock sync.Mutex } @@ -51,6 +52,11 @@ func (g *Group) SignGroup(signature []byte) { g.SignedGroupID = signature } +// Compromised should be called if we detect a a groupkey leak. +func (g *Group) Compromised() { + g.IsCompromised = true +} + // Invite generates a invitation that can be sent to a cwtch peer func (g *Group) Invite() ([]byte, error) { diff --git a/model/profile.go b/model/profile.go index 2422397..6762a68 100644 --- a/model/profile.go +++ b/model/profile.go @@ -148,17 +148,28 @@ func (p *Profile) AddGroup(group *Group) { // If we are sent an invite or group update by someone who is not an owner // then we reject the group. - - // FIXME: This opens up an attack vector!! - } // AttemptDecryption takes a ciphertext and signature and attempts to decrypt it under known groups. func (p *Profile) AttemptDecryption(ciphertext []byte) (bool, *Message) { for _, group := range p.Groups { success, dgm := group.DecryptMessage(ciphertext) - //log.Printf("Decrypt Attempt %v %v", success, dgm) if success { + + // Asser that we know the owner of the group + owner, ok := p.Contacts[group.Owner] + if ok { + valid := ed25519.Verify(owner.Ed25519PublicKey, []byte(group.GroupID+group.GroupServer), dgm.SignedGroupId) + // If we can decrypt the message, but the group id is wrong that means that + // this message is from someone who was not invited to the group. + // As such this group has been compromised, probably by one of the other members. + // We set the flag to be handled by the UX and reject the message. + if !valid { + group.Compromised() + return false, nil + } + } + verified := p.VerifyGroupMessage(dgm.GetOnion(), group.GroupID, dgm.GetText(), dgm.GetTimestamp(), dgm.GetSignature()) return true, group.AddMessage(dgm, verified) } diff --git a/model/profile_test b/model/profile_test index ea03e7e..1b91fa7 100644 --- a/model/profile_test +++ b/model/profile_test @@ -1 +1 @@ -{"Name":"Sarah","Ed25519PublicKey":"SgRpJJw2l4dMsGR149urJkwm2hWplFkOjHbyGxs+Eyg=","Trusted":false,"Blocked":false,"Onion":"p6ehgils34x47nyg","Contacts":{"p6ehgils34x47nyg":{"Name":"Sarah","Ed25519PublicKey":"SgRpJJw2l4dMsGR149urJkwm2hWplFkOjHbyGxs+Eyg=","Trusted":false,"Blocked":false,"Onion":"p6ehgils34x47nyg"}},"Ed25519PrivateKey":"QRL3hvZP5wmSdIe24cxN0L/4z/BnCpXa9n9A/JzFFEBKBGkknDaXh0ywZHXj26smTCbaFamUWQ6MdvIbGz4TKA==","OnionPrivateKey":{"N":151025771385966457315600103418087241110098664615614044467509585189952787361645163139595526204706389976899022537376049028041109114981491273832411774529216922191266316467163925107525714054510209765670955357908880636058201272225362200898015155059147874275999278481661208123978874126707190377553876855779404877717,"E":65537,"D":125243750080960236029198010599655514703034199355997493061395523833693090015076261828797126107383425986152630970045178885591440549462579447358251789582806798697737114991639329317994231561839015645204535496591732604621896238281646079430628006514324350534478950620213366125076645317906712748091678643287136521633,"Primes":[12998312283988098720258413423813336955357486672773091346977952106979604643331780603112919326243156235893536425556333045796625578558333990999466915635186681,11618875442160806051497378349343120970680061048618412772214305744446841325704429100064680636090245448365592590278817388980936340830366040119964714124504957],"Precomputed":{"Dp":9178370959398770839028313746644030002640926663654429532387791471301633643277306116701352940484833622662697181217791848273958861390421015632121251428193753,"Dq":3284069284382665842164539672905869552479934248815287214741257604256119271821243643279340587804380833506633461133784172505346060661026603707557965186723985,"Qinv":1616368906391224777304872606094694481250124880102681898802568811243640263040569336684936819346045620346829342124911001383838948453617533259204103210517135,"CRTValues":[]}},"Groups":{}} \ No newline at end of file +{"Name":"Sarah","Ed25519PublicKey":"W9PpKZvtZgVlHZ6wT2oTaStaUXHFYO553TyM/kcx+j0=","Trusted":false,"Blocked":false,"Onion":"b56kmtfigbjj4oed","Contacts":{"b56kmtfigbjj4oed":{"Name":"Sarah","Ed25519PublicKey":"W9PpKZvtZgVlHZ6wT2oTaStaUXHFYO553TyM/kcx+j0=","Trusted":false,"Blocked":false,"Onion":"b56kmtfigbjj4oed"}},"Ed25519PrivateKey":"D9VtCjO9WRscq1J1hBHj5KNTWhJqCzeZHTv76iuD5Alb0+kpm+1mBWUdnrBPahNpK1pRccVg7nndPIz+RzH6PQ==","OnionPrivateKey":{"N":131431908350807887726680282316542867215751372260346817354651281962467765863817142968881902964613976074829288548976846611912590630516744102978481639231882423095250930957765239944153566210775495249916207632888810237972001419936958220195829843082407234641091082084103419783680884292376945307398827177826045917213,"E":65537,"D":6527776091091744732751641346725468556498935207706011726038572452016915298025921240882411372962120513962636895599731994472976829917939515925278205223000399956250499414440500849418156829119221518850817208974047327356576252006802914743934160449516927022744695396017974696922331017645717939347896803326305764673,"Primes":[13025701017471365410286943463589035042960291474418354951794759000498929713389834945845345637495625867751746594507969387541024007744235240081409789677106193,10090198460299245573384301425475815284645715053514216764835542359499265357695622569689478708035086000871913905222809009531316465232841423534462476890808141],"Precomputed":{"Dp":5662484123285460129988785255316105533880688833882828517885052473018516372956900645545781729591686848226913964287838134962597829937794863816155223887281313,"Dq":5664872700127415683157635940750372271896095940903643615749255314942947793934002728674713209079496380915836859007400929195649145090211137792804253699748153,"Qinv":7915626106616008088617615457915827664685512673801991601529702673140410770136418670435683522388873693637240686678200328224101409032168571783863608820704490,"CRTValues":[]}},"Groups":{}} \ No newline at end of file