func (e *Kex2Provisionee) pushLKSServerHalf() error {
	// make new lks
	ppstream := libkb.NewPassphraseStream(e.pps.PassphraseStream)
	ppstream.SetGeneration(libkb.PassphraseGeneration(e.pps.Generation))
	e.lks = libkb.NewLKSec(ppstream, e.uid, e.G())
	e.lks.GenerateServerHalf()

	// make client half recovery
	chrKID := e.dh.GetKID()
	chrText, err := e.lks.EncryptClientHalfRecovery(e.dh)
	if err != nil {
		return err
	}

	err = libkb.PostDeviceLKS(e, e.device.ID, e.device.Type, e.lks.GetServerHalf(), e.lks.Generation(), chrText, chrKID)
	if err != nil {
		return err
	}

	// Sync the LKS stuff back from the server, so that subsequent
	// attempts to use public key login will work.
	/*
		err = e.G().LoginState().RunSecretSyncer(e.uid)
		if err != nil {
			return err
		}
	*/

	return nil
}
Exemple #2
0
func (s *SignupJoinEngine) Post(arg SignupJoinEngineRunArg) (err error) {
	var res *libkb.APIRes
	var ppGenTmp int
	res, err = s.G().API.Post(libkb.APIArg{
		Endpoint: "signup",
		Args: libkb.HTTPArgs{
			"salt":          libkb.S{Val: hex.EncodeToString(arg.PWSalt)},
			"pwh":           libkb.S{Val: hex.EncodeToString(arg.PWHash)},
			"username":      libkb.S{Val: arg.Username},
			"email":         libkb.S{Val: arg.Email},
			"invitation_id": libkb.S{Val: arg.InviteCode},
			"pwh_version":   libkb.I{Val: int(triplesec.Version)},
			"skip_mail":     libkb.B{Val: arg.SkipMail},
		}})
	if err == nil {
		s.username = libkb.NewNormalizedUsername(arg.Username)
		libkb.GetUIDVoid(res.Body.AtKey("uid"), &s.uid, &err)
		res.Body.AtKey("session").GetStringVoid(&s.session, &err)
		res.Body.AtKey("csrf_token").GetStringVoid(&s.csrf, &err)
		res.Body.AtPath("me.basics.passphrase_generation").GetIntVoid(&ppGenTmp, &err)
	}
	if err == nil {
		err = libkb.CheckUIDAgainstUsername(s.uid, arg.Username)
		s.ppGen = libkb.PassphraseGeneration(ppGenTmp)
	}
	return
}
Exemple #3
0
// fetchLKS gets the encrypted LKS client half from the server.
// It uses encKey to decrypt it.  It also returns the passphrase
// generation.
func fetchLKS(ctx *Context, g *libkb.GlobalContext, encKey libkb.GenericKey) (libkb.PassphraseGeneration, []byte, error) {
	arg := libkb.APIArg{
		Endpoint:    "passphrase/recover",
		NeedSession: true,
		Args: libkb.HTTPArgs{
			"kid": encKey.GetKID(),
		},
	}
	if ctx.LoginContext != nil {
		arg.SessionR = ctx.LoginContext.LocalSession()
	}
	res, err := g.API.Get(arg)
	if err != nil {
		return 0, nil, err
	}
	ctext, err := res.Body.AtKey("ctext").GetString()
	if err != nil {
		return 0, nil, err
	}
	ppGen, err := res.Body.AtKey("passphrase_generation").GetInt()
	if err != nil {
		return 0, nil, err
	}

	//  Now try to decrypt with the unlocked device key
	msg, _, err := encKey.DecryptFromString(ctext)
	if err != nil {
		return 0, nil, err
	}

	return libkb.PassphraseGeneration(ppGen), msg, nil
}
Exemple #4
0
func (e *Kex2Provisionee) pushLKSServerHalf() error {
	// make new lks
	ppstream := libkb.NewPassphraseStream(e.pps.PassphraseStream)
	ppstream.SetGeneration(libkb.PassphraseGeneration(e.pps.Generation))
	e.lks = libkb.NewLKSec(ppstream, e.uid, e.G())
	e.lks.GenerateServerHalf()

	// make client half recovery
	chrKID := e.dh.GetKID()
	chrText, err := e.lks.EncryptClientHalfRecovery(e.dh)
	if err != nil {
		return err
	}

	err = libkb.PostDeviceLKS(e, e.device.ID, e.device.Type, e.lks.GetServerHalf(), e.lks.Generation(), chrText, chrKID)
	if err != nil {
		return err
	}

	// Sync the LKS stuff back from the server, so that subsequent
	// attempts to use public key login will work.
	err = e.ctx.LoginContext.RunSecretSyncer(e.uid)
	if err != nil {
		return err
	}

	// Cache the passphrase stream.  Note that we don't have the triplesec
	// portion of the stream cache, and that the only bytes in ppstream
	// are the lksec portion (no pwhash, eddsa, dh).  Currently passes
	// all tests with this situation and code that uses those portions
	// looks to be ok.
	e.ctx.LoginContext.CreateStreamCache(nil, ppstream)

	return nil
}
Exemple #5
0
// fetchLKS gets the encrypted LKS client half from the server.
// It uses encKey to decrypt it.  It also returns the passphrase
// generation.
func (c *PassphraseChange) fetchLKS(ctx *Context, encKey libkb.GenericKey) (libkb.PassphraseGeneration, []byte, error) {
	res, err := c.G().API.Get(
		libkb.APIArg{
			Endpoint:    "passphrase/recover",
			NeedSession: true,
			Args: libkb.HTTPArgs{
				"kid": encKey.GetKID(),
			},
		})
	if err != nil {
		return 0, nil, err
	}
	ctext, err := res.Body.AtKey("ctext").GetString()
	if err != nil {
		return 0, nil, err
	}
	ppGen, err := res.Body.AtKey("passphrase_generation").GetInt()
	if err != nil {
		return 0, nil, err
	}

	//  Now try to decrypt with the unlocked device key
	msg, _, err := encKey.DecryptFromString(ctext)
	if err != nil {
		return 0, nil, err
	}

	return libkb.PassphraseGeneration(ppGen), msg, nil
}
Exemple #6
0
func (e *PaperKeyGen) getClientHalfFromSecretStore() ([]byte, libkb.PassphraseGeneration, error) {
	zeroGen := libkb.PassphraseGeneration(0)

	secretStore := libkb.NewSecretStore(e.G(), e.arg.Me.GetNormalizedName())
	if secretStore == nil {
		return nil, zeroGen, errors.New("No secret store available")
	}

	secret, err := secretStore.RetrieveSecret()
	if err != nil {
		return nil, zeroGen, err
	}

	devid := e.G().Env.GetDeviceID()
	if devid.IsNil() {
		return nil, zeroGen, fmt.Errorf("no device id set")
	}

	var dev libkb.DeviceKey
	aerr := e.G().LoginState().Account(func(a *libkb.Account) {
		if err = libkb.RunSyncer(a.SecretSyncer(), e.arg.Me.GetUID(), a.LoggedIn(), a.LocalSession()); err != nil {
			return
		}
		dev, err = a.SecretSyncer().FindDevice(devid)
	}, "BackupKeygen.Run() -- retrieving passphrase generation)")
	if aerr != nil {
		return nil, zeroGen, aerr
	}
	if err != nil {
		return nil, zeroGen, err
	}

	serverHalf, err := hex.DecodeString(dev.LksServerHalf)
	if err != nil {
		return nil, zeroGen, err
	}

	if len(secret) != len(serverHalf) {
		return nil, zeroGen, fmt.Errorf("secret has length %d, server half has length %d", len(secret), len(serverHalf))
	}

	clientHalf := make([]byte, len(secret))
	libkb.XORBytes(clientHalf, secret, serverHalf)

	return clientHalf, dev.PPGen, nil
}