github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/pgp_pull_private.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package engine 5 6 import ( 7 "errors" 8 "fmt" 9 10 "github.com/keybase/client/go/libkb" 11 keybase1 "github.com/keybase/client/go/protocol/keybase1" 12 ) 13 14 type PGPPullPrivate struct { 15 arg keybase1.PGPPullPrivateArg 16 } 17 18 func (e *PGPPullPrivate) Name() string { 19 return "PGPPullPrivate" 20 } 21 22 func (e *PGPPullPrivate) Prereqs() Prereqs { 23 return Prereqs{} 24 } 25 26 func (e *PGPPullPrivate) RequiredUIs() []libkb.UIKind { 27 return []libkb.UIKind{} 28 } 29 30 func (e *PGPPullPrivate) SubConsumers() []libkb.UIConsumer { 31 return []libkb.UIConsumer{} 32 } 33 34 func NewPGPPullPrivate(arg keybase1.PGPPullPrivateArg) *PGPPullPrivate { 35 return &PGPPullPrivate{arg} 36 } 37 38 func (e *PGPPullPrivate) read(m libkb.MetaContext, fs *keybase1.SimpleFSClient, filepath string) (armored string, err error) { 39 opid, err := fs.SimpleFSMakeOpid(m.Ctx()) 40 if err != nil { 41 return "", err 42 } 43 err = fs.SimpleFSOpen(m.Ctx(), keybase1.SimpleFSOpenArg{ 44 OpID: opid, 45 Dest: keybase1.NewPathWithKbfsPath(filepath), 46 Flags: keybase1.OpenFlags_READ | keybase1.OpenFlags_EXISTING, 47 }) 48 if err != nil { 49 return "", fmt.Errorf("pgp key not found; you may need to run `keybase pgp push-private` first (error: %s)", err) 50 } 51 defer fs.SimpleFSClose(m.Ctx(), opid) 52 var offset int64 53 bufsize := 64 * 1024 54 var data []byte 55 for { 56 m.Debug("SimpleFS: Reading at %d", offset) 57 58 content, err := fs.SimpleFSRead(m.Ctx(), keybase1.SimpleFSReadArg{ 59 OpID: opid, 60 Offset: offset, 61 Size: bufsize, 62 }) 63 if err != nil { 64 return "", err 65 } 66 m.Debug("SimpleFS: Read %d", len(content.Data)) 67 68 if len(content.Data) > 0 { 69 offset += int64(len(content.Data)) 70 data = append(data, content.Data...) 71 } else { 72 break 73 } 74 } 75 return string(data), nil 76 } 77 78 func (e *PGPPullPrivate) pull(m libkb.MetaContext, fp libkb.PGPFingerprint, tty string, fs *keybase1.SimpleFSClient) error { 79 80 username := m.CurrentUsername() 81 if username.IsNil() { 82 return libkb.NewLoginRequiredError("no username found") 83 } 84 85 filepath := "/private/" + username.String() + "/.keys/pgp/" + fp.String() + ".asc" 86 87 armored, err := e.read(m, fs, filepath) 88 if err != nil { 89 return err 90 } 91 92 err = m.G().GetGpgClient().ExportKeyArmored(m, armored) 93 if err != nil { 94 return err 95 } 96 return nil 97 } 98 99 func (e *PGPPullPrivate) Run(m libkb.MetaContext) (err error) { 100 101 defer m.Trace("PGPPullPrivate#Run", &err)() 102 103 tty, err := m.UIs().GPGUI.GetTTY(m.Ctx()) 104 if err != nil { 105 return err 106 } 107 108 fingerprints, err := getPrivateFingerprints(m, e.arg.Fingerprints) 109 if err != nil { 110 return err 111 } 112 if len(fingerprints) == 0 { 113 return errors.New("no PGP keys provided") 114 } 115 116 fs, err := simpleFSClient(m) 117 if err != nil { 118 return err 119 } 120 121 for _, fp := range fingerprints { 122 err = e.pull(m, fp, tty, fs) 123 if err != nil { 124 return err 125 } 126 } 127 128 return nil 129 }