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 }
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 }
// 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 }
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 }
// 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 }
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 }