/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/engine/puk_roll.go
222 строки
6 KB
Joshua Blum
Refactor trace to take a pointer to an error instead of a closure (#23779)
15 апр 2020, 21:08
Не верифицирован
15 апр 2020, 21:08
08da174
Код
Авторство
О чём код?
// Copyright 2017 Keybase, Inc. All rights reserved. Use of // this source code is governed by the included BSD license. // PerUserKeyRoll creates a new per-user-key for the active user. // This can be the first per-user-key for the user. package engine import ( "fmt" "github.com/keybase/client/go/libkb" "github.com/keybase/client/go/protocol/keybase1" ) // PerUserKeyRoll is an engine. type PerUserKeyRoll struct { libkb.Contextified args *PerUserKeyRollArgs DidNewKey bool } type PerUserKeyRollArgs struct { Me *libkb.User // optional } // NewPerUserKeyRoll creates a PerUserKeyRoll engine. func NewPerUserKeyRoll(g *libkb.GlobalContext, args *PerUserKeyRollArgs) *PerUserKeyRoll { return &PerUserKeyRoll{ args: args, Contextified: libkb.NewContextified(g), } } // Name is the unique engine name. func (e *PerUserKeyRoll) Name() string { return "PerUserKeyRoll" } // GetPrereqs returns the engine prereqs. func (e *PerUserKeyRoll) Prereqs() Prereqs { return Prereqs{ Device: true, } } // RequiredUIs returns the required UIs. func (e *PerUserKeyRoll) RequiredUIs() []libkb.UIKind { return []libkb.UIKind{} } // SubConsumers returns the other UI consumers for this engine. func (e *PerUserKeyRoll) SubConsumers() []libkb.UIConsumer { return []libkb.UIConsumer{} } // Run starts the engine. func (e *PerUserKeyRoll) Run(mctx libkb.MetaContext) (err error) { defer mctx.Trace("PerUserKeyRoll", &err)() return retryOnEphemeralRace(mctx, e.inner) } func (e *PerUserKeyRoll) inner(mctx libkb.MetaContext) error { var err error uid := mctx.G().GetMyUID() if uid.IsNil() { return libkb.NoUIDError{} } me := e.args.Me if me == nil { mctx.Debug("PerUserKeyRoll load self") loadArg := libkb.NewLoadUserArgWithMetaContext(mctx). WithUID(uid). WithSelf(true). WithPublicKeyOptional() me, err = libkb.LoadUser(loadArg) if err != nil { return err } } meUPAK := me.ExportToUserPlusAllKeys() sigKey, err := mctx.ActiveDevice().SigningKey() if err != nil { return fmt.Errorf("signing key not found: (%v)", err) } encKey, err := mctx.ActiveDevice().EncryptionKey() if err != nil { return fmt.Errorf("encryption key not found: (%v)", err) } pukring, err := mctx.G().GetPerUserKeyring(mctx.Ctx()) if err != nil { return err } err = pukring.Sync(mctx) if err != nil { return err } // Generation of the new key gen := pukring.CurrentGeneration() + keybase1.PerUserKeyGeneration(1) mctx.Debug("PerUserKeyRoll creating gen: %v", gen) pukSeed, err := libkb.GeneratePerUserKeySeed() if err != nil { return err } var pukPrev *libkb.PerUserKeyPrev if gen > 1 { pukPrevInner, err := pukring.PreparePrev(mctx, pukSeed, gen) if err != nil { return err } pukPrev = &pukPrevInner } pukReceivers, err := e.getPukReceivers(mctx, &meUPAK) if err != nil { return err } if len(pukReceivers) == 0 { return fmt.Errorf("no receivers") } // Create boxes of the new per-user-key pukBoxes, err := pukring.PrepareBoxesForDevices(mctx, pukSeed, gen, pukReceivers, encKey) if err != nil { return err } mctx.Debug("PerUserKeyRoll make sigs") sig, err := libkb.PerUserKeyProofReverseSigned(mctx, me, pukSeed, gen, sigKey) if err != nil { return err } // Seqno when the per-user-key will be signed in. pukSeqno := sig.Seqno payload := make(libkb.JSONPayload) payload["sigs"] = []libkb.JSONPayload{sig.Payload} mctx.Debug("PerUserKeyRoll pukBoxes:%v pukPrev:%v for generation %v", len(pukBoxes), pukPrev != nil, gen) libkb.AddPerUserKeyServerArg(payload, gen, pukBoxes, pukPrev) ekLib := mctx.G().GetEKLib() var myUserEKBox *keybase1.UserEkBoxed var newUserEKMetadata *keybase1.UserEkMetadata if ekLib != nil { merkleRoot, err := mctx.G().GetMerkleClient().FetchRootFromServer(mctx, libkb.EphemeralKeyMerkleFreshness) if err != nil { return err } sig, boxes, newMetadata, myBox, err := ekLib.PrepareNewUserEK(mctx, *merkleRoot, pukSeed) if err != nil { return err } // If there are no active deviceEKs, we can't publish this key. This // should mostly only come up in tests. if len(boxes) > 0 { myUserEKBox = myBox newUserEKMetadata = &newMetadata userEKSection := make(libkb.JSONPayload) userEKSection["sig"] = sig userEKSection["boxes"] = boxes payload["user_ek"] = userEKSection } else { mctx.Debug("skipping userEK publishing, there are no valid deviceEKs") } } mctx.Debug("PerUserKeyRoll post") _, err = mctx.G().API.PostJSON(mctx, libkb.APIArg{ Endpoint: "key/multi", SessionType: libkb.APISessionTypeREQUIRED, JSONPayload: payload, }) if err != nil { return err } if err = libkb.MerkleCheckPostedUserSig(mctx, uid, pukSeqno, sig.LinkID); err != nil { return err } e.DidNewKey = true // Add the per-user-key locally err = pukring.AddKey(mctx, gen, pukSeqno, pukSeed) if err != nil { return err } // Add the new userEK box to local storage, if it was created above. if myUserEKBox != nil { err = mctx.G().GetUserEKBoxStorage().Put(mctx, newUserEKMetadata.Generation, *myUserEKBox) if err != nil { mctx.Error("error while saving userEK box: %s", err) } } mctx.G().UserChanged(mctx.Ctx(), uid) return nil } // Get the receivers of the new per-user-key boxes. // Includes all the user's device subkeys. func (e *PerUserKeyRoll) getPukReceivers(mctx libkb.MetaContext, meUPAK *keybase1.UserPlusAllKeys) (res []libkb.NaclDHKeyPair, err error) { for _, dk := range meUPAK.Base.DeviceKeys { if !dk.IsSibkey && !dk.IsRevoked { receiver, err := libkb.ImportNaclDHKeyPairFromHex(dk.KID.String()) if err != nil { return res, err } res = append(res, receiver) } } return res, nil }