func PrepareTestAccountDaemon(name string, rootDir string, denameConfig *denameClient.Config, serverAddr string, serverPk *[32]byte, t testing.TB) *Daemon { dnmClient, err := denameClient.NewClient(denameConfig, nil, nil) //get port from serverAddr addr, portStr, err := net.SplitHostPort(serverAddr) if err != nil { t.Fatal(err) } var port int if _, err := fmt.Sscanf(portStr, "%d", &port); err != nil { t.Fatal(err) } //create the accounts with Init torAddr := "DANGEROUS_NO_TOR" err = Init(rootDir, name, addr, port, serverPk, torAddr) if err != nil { t.Fatal(err) } //initialize daemon with Load theDaemon, err := Load(rootDir, denameConfig) if err != nil { t.Fatal(err) } cbProfile := new(proto.Profile) if err := persistence.UnmarshalFromFile(theDaemon.OurChatterboxProfilePath(), cbProfile); err != nil { t.Fatal(err) } chatProfileBytes, err := protobuf.Marshal(cbProfile) if err != nil { t.Fatal(err) } denameProfile, sk, err := denameClient.NewProfile(nil, nil) if err != nil { t.Fatal(err) } if err := denameClient.SetProfileField(denameProfile, cbClient.PROFILE_FIELD_ID, chatProfileBytes); err != nil { t.Fatal(err) } err = dnmClient.Register(sk, name, denameProfile, testutil2.MakeToken()) if err != nil { t.Fatal(err) } return theDaemon }
func createNewUser(name string, t *testing.T, config *client.Config) (*[32]byte, *client.Client) { newClient, err := client.NewClient(config, nil, nil) if err != nil { t.Fatal(err) } //TODO: All these names are horrible, please change them pkAuth, skAuth, err := box.GenerateKey(rand.Reader) chatProfile := &proto.Profile{ ServerAddressTCP: "", ServerPortTCP: -1, ServerTransportPK: (proto.Byte32)([32]byte{}), UserIDAtServer: (proto.Byte32)([32]byte{}), KeySigningKey: (proto.Byte32)([32]byte{}), MessageAuthKey: (proto.Byte32)(*pkAuth), } chatProfileBytes, err := protobuf.Marshal(chatProfile) if err != nil { t.Fatal(err) } profile, sk, err := client.NewProfile(nil, nil) if err != nil { t.Fatal(err) } client.SetProfileField(profile, PROFILE_FIELD_ID, chatProfileBytes) err = newClient.Register(sk, name, profile, testutil2.MakeToken()) if err != nil { t.Fatal(err) } //Remove this outside of the test profile2, err := newClient.Lookup(name) if !profile.Equal(profile2) { t.Error("Correct profile not added to server.") fmt.Printf("profile: %v\n", profile) fmt.Printf("profile2: %v\n", profile2) } return skAuth, newClient }
func TestEncryptFirstMessage(t *testing.T) { alice := "alice" bob := "bob" denameConfig, denameTeardown := denameTestutil.SingleServer(t) defer denameTeardown() aliceDnmc, err := denameClient.NewClient(denameConfig, nil, nil) bobDnmc, err := denameClient.NewClient(denameConfig, nil, nil) if err != nil { t.Fatal(err) } _, serverPubkey, serverAddr, serverTeardown := server.CreateTestServer(t) defer serverTeardown() aliceDir, err := ioutil.TempDir("", "daemon-alice") if err != nil { t.Fatal(err) } defer shred.RemoveAll(aliceDir) bobDir, err := ioutil.TempDir("", "daemon-bob") if err != nil { t.Fatal(err) } defer shred.RemoveAll(bobDir) aliceConf := &Daemon{ Paths: persistence.Paths{ RootDir: aliceDir, Application: "daemon", }, Now: time.Now, foreignDenameClient: aliceDnmc, timelessDenameClient: aliceDnmc, inBuf: make([]byte, proto.SERVER_MESSAGE_SIZE), outBuf: make([]byte, proto.SERVER_MESSAGE_SIZE), LocalAccountConfig: proto.LocalAccountConfig{}, LocalAccount: proto.LocalAccount{ Dename: alice, }, cc: util.NewConnectionCache(util.NewAnonDialer("DANGEROUS_NO_TOR")), } bobConf := &Daemon{ Paths: persistence.Paths{ RootDir: bobDir, Application: "daemon", }, Now: time.Now, foreignDenameClient: bobDnmc, timelessDenameClient: bobDnmc, inBuf: make([]byte, proto.SERVER_MESSAGE_SIZE), outBuf: make([]byte, proto.SERVER_MESSAGE_SIZE), LocalAccountConfig: proto.LocalAccountConfig{}, LocalAccount: proto.LocalAccount{ Dename: bob, }, cc: util.NewConnectionCache(util.NewAnonDialer("DANGEROUS_NO_TOR")), } aliceHomeConn := util.CreateTestAccount(alice, aliceDnmc, &aliceConf.LocalAccountConfig, serverAddr, serverPubkey, t) defer aliceHomeConn.Close() bobHomeConn := util.CreateTestAccount(bob, bobDnmc, &bobConf.LocalAccountConfig, serverAddr, serverPubkey, t) defer bobHomeConn.Close() //fmt.Printf("CBob: %v\n", ([32]byte)(bobConf.TransportSecretKeyForServer)) aliceNotifies := make(chan *util.EnvelopeWithId) aliceReplies := make(chan *proto.ServerToClient) aliceConnToServer := &util.ConnectionToServer{ InBuf: aliceConf.inBuf, Conn: aliceHomeConn, ReadReply: aliceReplies, ReadEnvelope: aliceNotifies, } go aliceConnToServer.ReceiveMessages() bobNotifies := make(chan *util.EnvelopeWithId) bobReplies := make(chan *proto.ServerToClient) bobConnToServer := &util.ConnectionToServer{ InBuf: bobConf.inBuf, Conn: bobHomeConn, ReadReply: bobReplies, ReadEnvelope: bobNotifies, } go bobConnToServer.ReceiveMessages() if err := InitFs(aliceConf); err != nil { t.Fatal(err) } if err := InitFs(bobConf); err != nil { t.Fatal(err) } //Bob uploads keys bobPublicPrekeys, bobSecretPrekeys, err := GeneratePrekeys(maxPrekeys) var bobSigningKey [64]byte copy(bobSigningKey[:], bobConf.KeySigningSecretKey[:64]) err = util.UploadKeys(bobConnToServer, util.SignKeys(bobPublicPrekeys, &bobSigningKey)) if err != nil { t.Fatal(err) } //Bob enables notifications if err = util.EnablePush(bobConnToServer); err != nil { t.Fatal(err) } //Alice uploads keys alicePublicPrekeys, _, err := GeneratePrekeys(maxPrekeys) var aliceSigningKey [64]byte copy(aliceSigningKey[:], aliceConf.KeySigningSecretKey[:64]) err = util.UploadKeys(aliceConnToServer, util.SignKeys(alicePublicPrekeys, &aliceSigningKey)) if err != nil { t.Fatal(err) } //Alice enables notification if err = util.EnablePush(aliceConnToServer); err != nil { t.Fatal(err) } participants := make([]string, 0, 2) participants = append(participants, alice) participants = append(participants, bob) msg1 := []byte("Envelope") payload := proto.Message{ Subject: "Subject1", Participants: participants, Dename: alice, Contents: msg1, } envelope, err := payload.Marshal() if err != nil { t.Fatal(err) } err = aliceConf.sendFirstMessage(envelope, bob) if err != nil { t.Fatal(err) } incoming := <-bobConnToServer.ReadEnvelope out, bobRatch, _, err := bobConf.decryptFirstMessage(incoming.Envelope, bobPublicPrekeys, bobSecretPrekeys) if err != nil { t.Fatal(err) } fmt.Printf("Bob hears: %s\n", out) msg2 := []byte("Envelope2") payload2 := proto.Message{ Subject: "Subject3", Participants: participants, Dename: bob, Contents: msg2, } envelope2, err := payload2.Marshal() if err != nil { t.Fatal(err) } err = bobConf.sendMessage(envelope2, alice, bobRatch) if err != nil { t.Fatal(err) } incomingAlice := <-aliceConnToServer.ReadEnvelope aliceConf.fillAuth = util.FillAuthWith((*[32]byte)(&aliceConf.MessageAuthSecretKey)) aliceConf.checkAuth = util.CheckAuthWith(aliceConf.ProfileRatchet) aliceRatchets, err := AllRatchets(aliceConf, aliceConf.fillAuth, aliceConf.checkAuth) outAlice, _, err := decryptMessage(incomingAlice.Envelope, aliceRatchets) if err != nil { t.Fatal(err) } ha := sha256.Sum256(incomingAlice.Envelope) if err := aliceConf.saveMessage(outAlice); err != nil { t.Fatal(err) } if err := util.DeleteMessages(aliceConnToServer, []*[32]byte{&ha}); err != nil { t.Fatal(err) } fmt.Printf("Alice hears: %s\n", outAlice) //TODO: Confirm message is as expected within the test }
// Load initializes a chatterbox daemon from rootDir func Load(rootDir string, denameConfig *client.Config) (*Daemon, error) { d := &Daemon{ Paths: persistence.Paths{ RootDir: rootDir, Application: "daemon", }, Now: time.Now, inBuf: make([]byte, proto.SERVER_MESSAGE_SIZE), outBuf: make([]byte, proto.SERVER_MESSAGE_SIZE), } if err := persistence.UnmarshalFromFile(d.configPath(), &d.LocalAccountConfig); err != nil { return nil, err } d.cc = util.NewConnectionCache(util.NewAnonDialer(d.TorAddress)) if err := persistence.UnmarshalFromFile(d.AccountPath(), &d.LocalAccount); err != nil { return nil, err } if err := persistence.UnmarshalFromFile(d.configPath(), &d.LocalAccountConfig); err != nil { return nil, err } d.ourDenameLookup = new(dename.ClientReply) persistence.UnmarshalFromFile(d.ourDenameLookupReplyPath(), d.ourDenameLookup) // ensure that we have a correct directory structure // including a correctly-populated outbox if err := InitFs(d); err != nil { return nil, err } ourDenameClient, err := client.NewClient(denameConfig, util.NewAnonDialer(d.TorAddress), nil) if err != nil { return nil, err } d.foreignDenameClient, err = client.NewClient(denameConfig, util.NewAnonDialer(d.TorAddress), nil) if err != nil { return nil, err } if denameConfig == nil { denameConfig = &client.DefaultConfig } timelessCfg := *denameConfig // TODO: make very sure this is a deep copy timelessCfg.Freshness.Threshold = fmt.Sprintf("%dh", 100*365*24) d.timelessDenameClient, err = client.NewClient(&timelessCfg, nil, nil) if err != nil { return nil, err } d.psd, err = profilesyncd.New(ourDenameClient, 10*time.Minute, d.Dename, d.onOurDenameProfileDownload, nil) if err != nil { return nil, err } d.fillAuth = util.FillAuthWith((*[32]byte)(&d.MessageAuthSecretKey)) d.checkAuth = util.CheckAuthWith(d.ProfileRatchet) return d, nil }