// findPaperKeys checks if the user has paper backup keys. If he/she // does, it prompts for a paperkey phrase. This is used to // regenerate paper keys, which are then matched against the // paper keys found in the keyfamily. func findPaperKeys(ctx *Context, g *libkb.GlobalContext, me *libkb.User) (*keypair, error) { cki := me.GetComputedKeyInfos() if cki == nil { return nil, fmt.Errorf("no computed key infos") } bdevs := cki.PaperDevices() if len(bdevs) == 0 { return nil, libkb.NoPaperKeysError{} } passphrase, err := ctx.SecretUI.GetPaperKeyPassphrase(keybase1.GetPaperKeyPassphraseArg{Username: me.GetName()}) if err != nil { return nil, err } paperPhrase := libkb.NewPaperKeyPhrase(passphrase) if paperPhrase.Version() != libkb.PaperKeyVersion { g.Log.Debug("paper version mismatch: generated paper key version = %d, libkb version = %d", paperPhrase.Version(), libkb.PaperKeyVersion) return nil, libkb.KeyVersionError{} } bkarg := &PaperKeyGenArg{ Passphrase: libkb.NewPaperKeyPhrase(passphrase), SkipPush: true, Me: me, } bkeng := NewPaperKeyGen(bkarg, g) if err := RunEngine(bkeng, ctx); err != nil { return nil, err } sigKey := bkeng.SigKey() encKey := bkeng.EncKey() var match bool ckf := me.GetComputedKeyFamily() for _, bdev := range bdevs { sk, err := ckf.GetSibkeyForDevice(bdev.ID) if err != nil { continue } ek, err := ckf.GetEncryptionSubkeyForDevice(bdev.ID) if err != nil { continue } if sk.GetKID().Equal(sigKey.GetKID()) && ek.GetKID().Equal(encKey.GetKID()) { match = true break } } if !match { return nil, libkb.PassphraseError{Msg: "no matching paper backup keys found"} } return &keypair{sigKey: sigKey, encKey: encKey}, nil }
// check all the user's paper keys for arg.Bundles match func matchingPaperKey(g *libkb.GlobalContext, secretUI libkb.SecretUI, arg keybase1.UnboxBytes32AnyArg, me *libkb.User) (key libkb.GenericKey, index int, err error) { cki := me.GetComputedKeyInfos() if cki == nil { return nil, 0, nil } var matchingPaper []*libkb.Device for _, pdev := range cki.PaperDevices() { enckey, err := me.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(pdev.ID) if err != nil { return nil, 0, err } if _, ok := kidMatch(enckey, arg.Bundles); ok { g.Log.Debug("matching paper key: %s", *pdev.Description) matchingPaper = append(matchingPaper, pdev) } } if len(matchingPaper) == 0 { g.Log.Debug("no matching paper keys found") return nil, 0, nil } phrase, err := libkb.GetPaperKeyForCryptoPassphrase(secretUI, arg.Reason, matchingPaper) if err != nil { return nil, 0, err } paperPhrase, err := libkb.NewPaperKeyPhraseCheckVersion(g, phrase) if err != nil { return nil, 0, err } bkarg := &PaperKeyGenArg{ Passphrase: paperPhrase, SkipPush: true, } bkeng := NewPaperKeyGen(bkarg, g) if err := RunEngine(bkeng, &Context{}); err != nil { return nil, 0, err } // find the index for the key they entered (and make sure the key they entered matches) if n, ok := kidMatch(bkeng.EncKey(), arg.Bundles); ok { // this key matches, so cache this paper key if err := g.LoginState().Account(func(a *libkb.Account) { a.SetUnlockedPaperKey(bkeng.SigKey(), bkeng.EncKey()) }, "UnboxBytes32Any - cache paper key"); err != nil { return nil, 0, err } return bkeng.EncKey(), n, nil } return nil, 0, nil }
func (e *SaltpackDecrypt) makeMessageInfo(me *libkb.User, mki *saltpack.MessageKeyInfo) { if mki == nil { return } ckf := me.GetComputedKeyFamily() for _, nr := range mki.NamedReceivers { kid := keybase1.KIDFromRawKey(nr, libkb.KIDNaclDH) if dev, _ := ckf.GetDeviceForKID(kid); dev != nil { edev := dev.ProtExport() edev.EncryptKey = kid e.res.Devices = append(e.res.Devices, *edev) } } e.res.NumAnonReceivers = mki.NumAnonReceivers e.res.ReceiverIsAnon = mki.ReceiverIsAnon }
func (e *RevokeEngine) getKIDsToRevoke(me *libkb.User) ([]keybase1.KID, error) { if e.mode == RevokeDevice { deviceKeys, err := me.GetComputedKeyFamily().GetAllActiveKeysForDevice(e.deviceID) if err != nil { return nil, err } if len(deviceKeys) == 0 { return nil, fmt.Errorf("No active keys to revoke for device %s.", e.deviceID) } return deviceKeys, nil } else if e.mode == RevokeKey { kid := e.kid key, err := me.GetComputedKeyFamily().FindKeyWithKIDUnsafe(kid) if err != nil { return nil, err } if !libkb.IsPGP(key) { return nil, fmt.Errorf("Key %s is not a PGP key. To revoke device keys, use the `device remove` command.", e.kid) } for _, activePGPKey := range me.GetComputedKeyFamily().GetActivePGPKeys(false /* sibkeys only */) { if activePGPKey.GetKID().Equal(kid) { return []keybase1.KID{kid}, nil } } return nil, fmt.Errorf("PGP key %s is not active", e.kid) } else { return nil, fmt.Errorf("Unknown revoke mode: %d", e.mode) } }
func newProblemSetDevices(u *libkb.User, pset keybase1.ProblemSet) (keybase1.ProblemSetDevices, error) { var set keybase1.ProblemSetDevices set.ProblemSet = pset ckf := u.GetComputedKeyFamily() dset := make(map[keybase1.DeviceID]bool) for _, f := range pset.Tlfs { for _, kid := range f.Solution_kids { dev, err := ckf.GetDeviceForKID(kid) if err != nil { return keybase1.ProblemSetDevices{}, err } if dset[dev.ID] { continue } dset[dev.ID] = true set.Devices = append(set.Devices, *(dev.ProtExport())) } } return set, nil }