Example #1
0
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
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
// 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
}