Skip to content

Commit 3383956

Browse files
committed
Wire in new ratchet system.
1 parent a2f9c94 commit 3383956

File tree

12 files changed

+618
-106
lines changed

12 files changed

+618
-106
lines changed

client/client.go

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,11 @@ import (
6969
"sync"
7070
"time"
7171

72-
"code.google.com/p/go.crypto/curve25519"
7372
"code.google.com/p/goprotobuf/proto"
7473
"github.com/agl/ed25519"
7574
"github.com/agl/pond/bbssig"
7675
"github.com/agl/pond/client/disk"
76+
"github.com/agl/pond/client/ratchet"
7777
"github.com/agl/pond/panda"
7878
pond "github.com/agl/pond/protos"
7979
)
@@ -200,6 +200,10 @@ type client struct {
200200
// nowFunc is a function that, if not nil, will be used by the GUI to
201201
// get the current time. This is used in testing.
202202
nowFunc func() time.Time
203+
204+
// simulateOldClient causes the client to act like a pre-ratchet client
205+
// for testing purposes.
206+
simulateOldClient bool
203207
}
204208

205209
// UI abstracts behaviour that is specific to a given interface (GUI or CLI).
@@ -406,11 +410,14 @@ type Contact struct {
406410
// exchange failed.
407411
pandaResult string
408412

409-
lastDHPrivate [32]byte
410-
currentDHPrivate [32]byte
411-
413+
// Members for the old ratchet.
414+
lastDHPrivate [32]byte
415+
currentDHPrivate [32]byte
412416
theirLastDHPublic [32]byte
413417
theirCurrentDHPublic [32]byte
418+
419+
// New ratchet support.
420+
ratchet *ratchet.Ratchet
414421
}
415422

416423
// previousTagLifetime contains the amount of time that we'll store a previous
@@ -679,7 +686,7 @@ func (c *client) loadUI() error {
679686
return nil
680687
}
681688

682-
func (contact *Contact) processKeyExchange(kxsBytes []byte, testing bool) error {
689+
func (contact *Contact) processKeyExchange(kxsBytes []byte, testing, simulateOldClient bool) error {
683690
var kxs pond.SignedKeyExchange
684691
if err := proto.Unmarshal(kxsBytes, &kxs); err != nil {
685692
return err
@@ -723,10 +730,25 @@ func (contact *Contact) processKeyExchange(kxsBytes []byte, testing bool) error
723730
}
724731
copy(contact.theirIdentityPublic[:], kx.IdentityPublic)
725732

726-
if len(kx.Dh) != len(contact.theirCurrentDHPublic) {
727-
return errors.New("invalid public DH value")
733+
if simulateOldClient {
734+
kx.Dh1 = nil
735+
}
736+
737+
if len(kx.Dh1) == 0 {
738+
// They are using an old-style ratchet. We have to extract the
739+
// private value from the Ratchet in order to use it with the
740+
// old code.
741+
contact.lastDHPrivate = contact.ratchet.GetKXPrivateForTransition()
742+
if len(kx.Dh) != len(contact.theirCurrentDHPublic) {
743+
return errors.New("invalid public DH value")
744+
}
745+
copy(contact.theirCurrentDHPublic[:], kx.Dh)
746+
contact.ratchet = nil
747+
} else {
748+
if err := contact.ratchet.CompleteKeyExchange(&kx); err != nil {
749+
return err
750+
}
728751
}
729-
copy(contact.theirCurrentDHPublic[:], kx.Dh)
730752

731753
contact.generation = *kx.Generation
732754

@@ -774,26 +796,34 @@ func (c *client) registerId(id uint64) {
774796
c.usedIds[id] = true
775797
}
776798

799+
func (c *client) newRatchet(contact *Contact) *ratchet.Ratchet {
800+
r := ratchet.New(c.rand)
801+
r.MyIdentityPrivate = &c.identity
802+
r.MySigningPublic = &c.pub
803+
r.TheirIdentityPublic = &contact.theirIdentityPublic
804+
r.TheirSigningPublic = &contact.theirPub
805+
return r
806+
}
807+
777808
func (c *client) newKeyExchange(contact *Contact) {
778809
var err error
779-
c.randBytes(contact.lastDHPrivate[:])
780-
c.randBytes(contact.currentDHPrivate[:])
781-
782-
var pub [32]byte
783-
curve25519.ScalarBaseMult(&pub, &contact.lastDHPrivate)
784810
if contact.groupKey, err = c.groupPriv.NewMember(c.rand); err != nil {
785811
panic(err)
786812
}
813+
contact.ratchet = c.newRatchet(contact)
787814

788815
kx := &pond.KeyExchange{
789816
PublicKey: c.pub[:],
790817
IdentityPublic: c.identityPublic[:],
791818
Server: proto.String(c.server),
792-
Dh: pub[:],
793819
Group: contact.groupKey.Group.Marshal(),
794820
GroupKey: contact.groupKey.Marshal(),
795821
Generation: proto.Uint32(c.generation),
796822
}
823+
contact.ratchet.FillKeyExchange(kx)
824+
if c.simulateOldClient {
825+
kx.Dh1 = nil
826+
}
797827

798828
kxBytes, err := proto.Marshal(kx)
799829
if err != nil {

0 commit comments

Comments
 (0)