// This is used by SaltpackDecrypt as well. func getPaperKey(g *libkb.GlobalContext, ctx *Context) (*keypair, error) { passphrase, err := libkb.GetPaperKeyPassphrase(g, ctx.SecretUI, "") if err != nil { return nil, err } paperPhrase, err := libkb.NewPaperKeyPhraseCheckVersion(g, passphrase) if err != nil { return nil, err } bkarg := &PaperKeyGenArg{ Passphrase: paperPhrase, SkipPush: true, } bkeng := NewPaperKeyGen(bkarg, g) if err := RunEngine(bkeng, ctx); err != nil { return nil, err } kp := &keypair{sigKey: bkeng.SigKey(), encKey: bkeng.EncKey()} if err := g.LoginState().Account(func(a *libkb.Account) { a.SetUnlockedPaperKey(kp.sigKey, kp.encKey) }, "UnlockedPaperKey"); err != nil { return nil, err } return kp, 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 }