func (e *loginProvision) switchToGPGSign(ctx *Context, key *libkb.GpgPrimaryKey, importError error) (libkb.GenericKey, error) { gk := keybase1.GPGKey{ Algorithm: key.AlgoString(), KeyID: key.ID64, Creation: key.CreatedString(), Identities: key.GetPGPIdentities(), } arg := keybase1.SwitchToGPGSignOKArg{ Key: gk, ImportError: importError.Error(), } ok, err := ctx.ProvisionUI.SwitchToGPGSignOK(ctx.GetNetContext(), arg) if err != nil { return nil, err } if !ok { return nil, fmt.Errorf("user chose not to switch to GPG sign, original import error: %s", importError) } e.G().Log.Debug("switching to GPG sign") return e.gpgSignKey(ctx, key.GetFingerprint()) }
func (e *GPGImportKeyEngine) Run(ctx *Context) (err error) { gpg := e.G().GetGpgClient() me := e.arg.Me if me == nil { if me, err = libkb.LoadMe(libkb.NewLoadUserPubOptionalArg(e.G())); err != nil { return err } } if !e.arg.OnlyImport { if err = PGPCheckMulti(me, e.arg.AllowMulti); err != nil { return err } } if err = gpg.Configure(); err != nil { return err } index, warns, err := gpg.Index(true, e.arg.Query) if err != nil { return err } warns.Warn() var gks []keybase1.GPGKey for _, key := range index.Keys { gk := keybase1.GPGKey{ Algorithm: fmt.Sprintf("%d%s", key.Bits, key.AlgoString()), KeyID: key.GetFingerprint().ToKeyID(), Expiration: key.ExpirationString(), Identities: key.GetPGPIdentities(), } gks = append(gks, gk) } if len(gks) == 0 { return fmt.Errorf("No PGP keys available to choose from.") } res, err := ctx.GPGUI.SelectKeyAndPushOption(context.TODO(), keybase1.SelectKeyAndPushOptionArg{Keys: gks}) if err != nil { return err } e.G().Log.Debug("SelectKey result: %+v", res) var selected *libkb.GpgPrimaryKey for _, key := range index.Keys { if key.GetFingerprint().ToKeyID() == res.KeyID { selected = key break } } if selected == nil { return nil } publicKeys := me.GetActivePGPKeys(false) duplicate := false for _, key := range publicKeys { if key.GetFingerprint().Eq(*(selected.GetFingerprint())) { duplicate = true break } } if duplicate && !e.arg.OnlyImport { // This key's already been posted to the server. res, err := ctx.GPGUI.ConfirmDuplicateKeyChosen(context.TODO(), 0) if err != nil { return err } if !res { return libkb.SibkeyAlreadyExistsError{} } // We're sending a key update, then. fp := fmt.Sprintf("%s", *(selected.GetFingerprint())) eng := NewPGPUpdateEngine([]string{fp}, false, e.G()) err = RunEngine(eng, ctx) e.duplicatedFingerprints = eng.duplicatedFingerprints return err } bundle, err := gpg.ImportKey(true, *(selected.GetFingerprint())) if err != nil { return fmt.Errorf("ImportKey error: %s", err) } if err := bundle.Unlock("Import of key into keybase keyring", ctx.SecretUI); err != nil { return err } e.G().Log.Info("Bundle unlocked: %s", selected.GetFingerprint().ToKeyID()) eng := NewPGPKeyImportEngine(PGPKeyImportEngineArg{ Pregen: bundle, SigningKey: e.arg.Signer, Me: me, AllowMulti: e.arg.AllowMulti, NoSave: e.arg.SkipImport, OnlySave: e.arg.OnlyImport, Lks: e.arg.Lks, }) if err = RunEngine(eng, ctx); err != nil { // It's important to propagate a CanceledError unmolested, // since the UI needs to know that. See: // https://github.com/keybase/client/issues/226 if _, ok := err.(libkb.CanceledError); !ok { err = libkb.KeyGenError{Msg: err.Error()} } return } e.G().Log.Info("Key %s imported", selected.GetFingerprint().ToKeyID()) e.last = bundle return nil }