Beispiel #1
0
func TestNewAccount(t *testing.T) {
	t.Parallel()

	groupPrivateKey, err := bbssig.GenerateGroup(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}

	oneShotTest(t, &pond.Request{
		NewAccount: &pond.NewAccount{
			Generation: proto.Uint32(0),
			Group:      groupPrivateKey.Group.Marshal(),
		},
	}, func(t *testing.T, reply *pond.Reply) {
		if reply.AccountCreated == nil {
			t.Errorf("Bad reply to new account: %s", reply)
		}
	})
}
Beispiel #2
0
// Creates a chatroom, autogenerating all the keys for the chatroom
func createChatroom() *chatroom {
	id := uuid.New()

	groupPriv, err := bbssig.GenerateGroup(rand.Reader)

	if err != nil {
		log.Fatalf("Error while generating group key: %s", err)
		panic("Error!")
	}

	memberPriv, err := groupPriv.NewMember(rand.Reader)

	if err != nil {
		log.Fatalf("Create Chatroom: Error while generating member key: %s", err)
		panic("Error!")
	}

	chatRoom := newChatroom(id, groupPriv, groupPriv.Group, memberPriv)
	chatRoom.valid = true

	return chatRoom
}
Beispiel #3
0
func main() {
	/* Generate parameters for a new ring and store in public and
	private. */
	var sk *bbssig.PrivateKey
	var randread, err = os.Open("/dev/random")
	if err != nil {
		log.Fatal(err)
	}

	sk, err = bbssig.GenerateGroup(randread)
	if err != nil {
		log.Fatal(err)
	}
	/* Need to output marshelled form of group ring */
	var pubhandle *os.File
	pubhandle, err = os.Create(os.Args[1])
	if err != nil {
		log.Fatal(err)
	}
	objpack.PackGroup(pubhandle, sk.Group)
	pubhandle.Close()

	/*Now to save private key*/
	var priv []byte
	var privhandle *os.File
	privhandle, err = os.Create(os.Args[2])
	if err != nil {
		log.Fatal("err")
	}
	priv = sk.Marshal()
	/*TODO: pros and cons of encrypting this file*/
	/*We write the group first as it is needed information for
	unmarshalling*/
	objpack.PackGroup(privhandle, sk.Group)
	basepack.Packout(privhandle, priv)
	privhandle.Close()
}
Beispiel #4
0
func (c *client) loadUI() error {
	c.ui.initUI()

	c.torAddress = "127.0.0.1:9050" // default for dev mode.
	if !c.dev && !c.detectTor() {
		if err := c.ui.torPromptUI(); err != nil {
			return err
		}
	}

	c.ui.loadingUI()

	stateFile := &disk.StateFile{
		Path: c.stateFilename,
		Rand: c.rand,
		Log: func(format string, args ...interface{}) {
			c.log.Printf(format, args...)
		},
	}

	var newAccount bool
	var err error
	if c.stateLock, err = stateFile.Lock(false /* don't create */); err == nil && c.stateLock == nil {
		c.ui.errorUI("State file locked by another process. Waiting for lock.", false)
		c.log.Errorf("Waiting for locked state file")

		for {
			if c.stateLock, err = stateFile.Lock(false /* don't create */); c.stateLock != nil {
				break
			}
			if err := c.ui.sleepUI(1 * time.Second); err != nil {
				return err
			}
		}
	} else if err == nil {
	} else if os.IsNotExist(err) {
		newAccount = true
	} else {
		c.ui.errorUI(err.Error(), true)
		if err := c.ui.ShutdownAndSuspend(); err != nil {
			return err
		}
	}

	if newAccount {
		pub, priv, err := ed25519.GenerateKey(rand.Reader)
		if err != nil {
			panic(err)
		}
		copy(c.priv[:], priv[:])
		copy(c.pub[:], pub[:])

		if c.disableV2Ratchet {
			c.randBytes(c.identity[:])
		} else {
			extra25519.PrivateKeyToCurve25519(&c.identity, priv)
		}
		curve25519.ScalarBaseMult(&c.identityPublic, &c.identity)

		c.groupPriv, err = bbssig.GenerateGroup(rand.Reader)
		if err != nil {
			panic(err)
		}
		pw, err := c.ui.createPassphraseUI()
		if err != nil {
			return err
		}
		c.ui.createErasureStorage(pw, stateFile)
		if err := c.ui.createAccountUI(); err != nil {
			return err
		}
		newAccount = true
	} else {
		// First try with zero key.
		err := c.loadState(stateFile, "")
		for err == disk.BadPasswordError {
			// That didn't work, try prompting for a key.
			err = c.ui.keyPromptUI(stateFile)
		}
		if err == errInterrupted {
			return err
		}
		if err != nil {
			// Fatal error loading state. Abort.
			c.ui.errorUI(err.Error(), true)
			if err := c.ui.ShutdownAndSuspend(); err != nil {
				return err
			}
		}
	}

	if newAccount {
		c.stateLock, err = stateFile.Lock(true /* create */)
		if err != nil {
			err = errors.New("Failed to create state file: " + err.Error())
		} else if c.stateLock == nil {
			err = errors.New("Failed to obtain lock on created state file")
		}
		if err != nil {
			c.ui.errorUI(err.Error(), true)
			if err := c.ui.ShutdownAndSuspend(); err != nil {
				return err
			}
		}
		c.lastErasureStorageTime = time.Now()
	}

	c.writerChan = make(chan disk.NewState)
	c.writerDone = make(chan struct{})
	c.fetchNowChan = make(chan chan bool, 1)

	// Start disk and network workers.
	go stateFile.StartWriter(c.writerChan, c.writerDone)
	go c.transact()
	if newAccount {
		c.save()
	}

	// Start any pending key exchanges.
	for _, contact := range c.contacts {
		if len(contact.pandaKeyExchange) == 0 {
			continue
		}
		c.pandaWaitGroup.Add(1)
		contact.pandaShutdownChan = make(chan struct{})
		go c.runPANDA(contact.pandaKeyExchange, contact.id, contact.name, contact.pandaShutdownChan)
	}

	c.ui.mainUI()

	return nil
}
Beispiel #5
0
func runScript(t *testing.T, s script) {
	server := NewTestServer(s.setupDir)
	defer server.Close()

	identities := make([][32]byte, s.numPlayers)
	publicIdentities := make([][32]byte, s.numPlayers)
	for i := range identities {
		io.ReadFull(rand.Reader, identities[i][:])
		curve25519.ScalarBaseMult(&publicIdentities[i], &identities[i])
	}

	groupPrivateKeys := make([]*bbssig.PrivateKey, s.numPlayersWithAccounts)
	for i := range groupPrivateKeys {
		var err error
		groupPrivateKeys[i], err = bbssig.GenerateGroup(rand.Reader)
		if err != nil {
			panic(err)
		}

		conn := server.Dial(&identities[i], &publicIdentities[i])
		if err := conn.WriteProto(&pond.Request{
			NewAccount: &pond.NewAccount{
				Generation: proto.Uint32(0),
				Group:      groupPrivateKeys[i].Group.Marshal(),
			},
		}); err != nil {
			t.Fatal(err)
		}

		reply := new(pond.Reply)
		if err := conn.ReadProto(reply); err != nil {
			t.Fatalf("Error while reading reply from server: %s", err)
		}
		if reply.AccountCreated == nil {
			t.Fatalf("Failed to create 1st account: %s", err)
		}
		conn.Close()
	}

	state := &scriptState{
		identities:       identities,
		publicIdentities: publicIdentities,
		groupPrivateKeys: groupPrivateKeys,
		testServer:       server,
	}

	for _, a := range s.actions {
		conn := server.Dial(&identities[a.player], &publicIdentities[a.player])

		req := a.request
		if a.buildRequest != nil {
			req = a.buildRequest(state)
		}
		if err := conn.WriteProto(req); err != nil {
			t.Fatal(err)
		}

		reply := new(pond.Reply)
		if err := conn.ReadProto(reply); err != nil {
			t.Fatal(err)
		}
		if a.validate != nil {
			a.validate(t, reply)
		}

		if len(a.payload) > 0 {
			_, err := conn.Write(a.payload)
			if err != nil {
				t.Fatalf("Failed to write payload: %s", err)
			}
		}
		if a.payloadSize > 0 {
			fromServer := make([]byte, a.payloadSize)
			if _, err := io.ReadFull(conn, fromServer); err != nil {
				t.Errorf("Failed to read payload: %s", err)
			}
			if a.validatePayload != nil {
				a.validatePayload(t, fromServer)
			}
		}
		conn.Close()
	}
}
Beispiel #6
0
func (c *client) loadUI() {
	ui := VBox{
		widgetBase: widgetBase{
			background: colorWhite,
		},
		children: []Widget{
			EventBox{
				widgetBase: widgetBase{background: 0x333355},
				child: HBox{
					children: []Widget{
						Label{
							widgetBase: widgetBase{
								foreground: colorWhite,
								padding:    10,
								font:       fontLoadTitle,
							},
							text: "Pond",
						},
					},
				},
			},
			HBox{
				widgetBase: widgetBase{
					name:    "body",
					padding: 30,
					expand:  true,
					fill:    true,
				},
			},
		},
	}
	c.ui.Actions() <- Reset{ui}

	c.torAddress = "127.0.0.1:9050" // default for dev mode.
	if !c.dev && !c.detectTor() {
		c.torPromptUI()
	}

	loading := EventBox{
		widgetBase: widgetBase{expand: true, fill: true},
		child: Label{
			widgetBase: widgetBase{
				foreground: colorTitleForeground,
				font:       fontLoadLarge,
			},
			text:   "Loading...",
			xAlign: 0.5,
			yAlign: 0.5,
		},
	}

	c.ui.Actions() <- SetBoxContents{name: "body", child: loading}
	c.ui.Actions() <- UIState{uiStateLoading}
	c.ui.Signal()

	stateFile := &disk.StateFile{
		Path: c.stateFilename,
		Rand: c.rand,
		Log: func(format string, args ...interface{}) {
			c.log.Printf(format, args...)
		},
	}

	var newAccount bool
	var err error
	if c.stateLock, err = stateFile.Lock(false /* don't create */); err == nil && c.stateLock == nil {
		c.errorUI("State file locked by another process. Waiting for lock.", colorDefault)
		c.log.Errorf("Waiting for locked state file")

		for {
			if c.stateLock, err = stateFile.Lock(false /* don't create */); c.stateLock != nil {
				break
			}
			select {
			case _, ok := <-c.ui.Events():
				if !ok {
					// User asked to close the window.
					close(c.ui.Actions())
					select {}
				}
			case <-time.After(1 * time.Second):
				break
			}
		}
	} else if err == nil {
	} else if os.IsNotExist(err) {
		newAccount = true
	} else {
		c.errorUI(err.Error(), colorError)
		c.ShutdownAndSuspend()
	}

	if newAccount {
		pub, priv, err := ed25519.GenerateKey(rand.Reader)
		if err != nil {
			panic(err)
		}
		copy(c.priv[:], priv[:])
		copy(c.pub[:], pub[:])

		c.groupPriv, err = bbssig.GenerateGroup(rand.Reader)
		if err != nil {
			panic(err)
		}
		pw := c.createPassphraseUI()
		c.createErasureStorage(pw, stateFile)
		c.createAccountUI()
		newAccount = true
	} else {
		// First try with zero key.
		err := c.loadState(stateFile, "")
		for err == disk.BadPasswordError {
			// That didn't work, try prompting for a key.
			err = c.keyPromptUI(stateFile)
		}
		if err != nil {
			// Fatal error loading state. Abort.
			c.errorUI(err.Error(), colorError)
			c.ShutdownAndSuspend()
		}
	}

	if newAccount {
		c.stateLock, err = stateFile.Lock(true /* create */)
		if err != nil {
			err = errors.New("Failed to create state file: " + err.Error())
		} else if c.stateLock == nil {
			err = errors.New("Failed to obtain lock on created state file")
		}
		if err != nil {
			c.errorUI(err.Error(), colorError)
			c.ShutdownAndSuspend()
		}
		c.lastErasureStorageTime = time.Now()
	}

	c.writerChan = make(chan disk.NewState)
	c.writerDone = make(chan struct{})
	c.fetchNowChan = make(chan chan bool, 1)
	c.revocationUpdateChan = make(chan revocationUpdate, 8)

	// Start disk and network workers.
	go stateFile.StartWriter(c.writerChan, c.writerDone)
	go c.transact()
	if newAccount {
		c.save()
	}

	// Start any pending key exchanges.
	for _, contact := range c.contacts {
		if len(contact.pandaKeyExchange) == 0 {
			continue
		}
		c.pandaWaitGroup.Add(1)
		go c.runPANDA(contact.pandaKeyExchange, contact.id, contact.name)
	}

	c.mainUI()
}