github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/service/pgp.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 service 5 6 import ( 7 "github.com/keybase/client/go/engine" 8 "github.com/keybase/client/go/libkb" 9 keybase1 "github.com/keybase/client/go/protocol/keybase1" 10 "github.com/keybase/go-framed-msgpack-rpc/rpc" 11 "golang.org/x/net/context" 12 ) 13 14 type RemotePgpUI struct { 15 sessionID int 16 cli keybase1.PGPUiClient 17 } 18 19 func NewRemotePgpUI(sessionID int, c *rpc.Client) *RemotePgpUI { 20 return &RemotePgpUI{ 21 sessionID: sessionID, 22 cli: keybase1.PGPUiClient{Cli: c}, 23 } 24 } 25 26 func (u *RemotePgpUI) OutputPGPWarning(ctx context.Context, arg keybase1.OutputPGPWarningArg) error { 27 arg.SessionID = u.sessionID 28 return u.cli.OutputPGPWarning(ctx, arg) 29 } 30 31 func (u *RemotePgpUI) OutputSignatureSuccess(ctx context.Context, arg keybase1.OutputSignatureSuccessArg) error { 32 return u.cli.OutputSignatureSuccess(ctx, arg) 33 } 34 35 func (u *RemotePgpUI) OutputSignatureNonKeybase(ctx context.Context, arg keybase1.OutputSignatureNonKeybaseArg) error { 36 return u.cli.OutputSignatureNonKeybase(ctx, arg) 37 } 38 39 func (u *RemotePgpUI) KeyGenerated(ctx context.Context, arg keybase1.KeyGeneratedArg) error { 40 arg.SessionID = u.sessionID 41 return u.cli.KeyGenerated(ctx, arg) 42 } 43 44 func (u *RemotePgpUI) ShouldPushPrivate(ctx context.Context, arg keybase1.ShouldPushPrivateArg) (bool, error) { 45 arg.SessionID = u.sessionID 46 return u.cli.ShouldPushPrivate(ctx, arg) 47 } 48 49 func (u *RemotePgpUI) Finished(ctx context.Context, sessionID int) error { 50 return u.cli.Finished(ctx, u.sessionID) 51 } 52 53 type PGPHandler struct { 54 *BaseHandler 55 libkb.Contextified 56 connID libkb.ConnectionID 57 } 58 59 func NewPGPHandler(xp rpc.Transporter, id libkb.ConnectionID, g *libkb.GlobalContext) *PGPHandler { 60 return &PGPHandler{ 61 BaseHandler: NewBaseHandler(g, xp), 62 Contextified: libkb.NewContextified(g), 63 connID: id, 64 } 65 } 66 67 func (h *PGPHandler) PGPSign(ctx context.Context, arg keybase1.PGPSignArg) (err error) { 68 cli := h.getStreamUICli() 69 src := libkb.NewRemoteStreamBuffered(arg.Source, cli, arg.SessionID) 70 snk := libkb.NewRemoteStreamBuffered(arg.Sink, cli, arg.SessionID) 71 earg := engine.PGPSignArg{Sink: snk, Source: src, Opts: arg.Opts} 72 uis := libkb.UIs{ 73 PgpUI: h.getPgpUI(arg.SessionID), 74 SecretUI: h.getSecretUI(arg.SessionID, h.G()), 75 SessionID: arg.SessionID, 76 } 77 eng := engine.NewPGPSignEngine(h.G(), &earg) 78 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 79 return engine.RunEngine2(m, eng) 80 } 81 82 func (h *PGPHandler) PGPPull(ctx context.Context, arg keybase1.PGPPullArg) error { 83 earg := engine.PGPPullEngineArg{ 84 UserAsserts: arg.UserAsserts, 85 } 86 uis := libkb.UIs{ 87 LogUI: h.getLogUI(arg.SessionID), 88 IdentifyUI: h.NewRemoteIdentifyUI(arg.SessionID, h.G()), 89 SessionID: arg.SessionID, 90 } 91 eng := engine.NewPGPPullEngine(h.G(), &earg) 92 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 93 return engine.RunEngine2(m, eng) 94 } 95 96 func (h *PGPHandler) PGPEncrypt(ctx context.Context, arg keybase1.PGPEncryptArg) error { 97 cli := h.getStreamUICli() 98 src := libkb.NewRemoteStreamBuffered(arg.Source, cli, arg.SessionID) 99 snk := libkb.NewRemoteStreamBuffered(arg.Sink, cli, arg.SessionID) 100 earg := &engine.PGPEncryptArg{ 101 Recips: arg.Opts.Recipients, 102 Sink: snk, 103 Source: src, 104 NoSign: arg.Opts.NoSign, 105 NoSelf: arg.Opts.NoSelf, 106 BinaryOutput: arg.Opts.BinaryOut, 107 KeyQuery: arg.Opts.KeyQuery, 108 } 109 uis := libkb.UIs{ 110 IdentifyUI: h.NewRemoteIdentifyUI(arg.SessionID, h.G()), 111 PgpUI: h.getPgpUI(arg.SessionID), 112 SecretUI: h.getSecretUI(arg.SessionID, h.G()), 113 SessionID: arg.SessionID, 114 } 115 eng := engine.NewPGPEncrypt(h.G(), earg) 116 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 117 return engine.RunEngine2(m, eng) 118 } 119 120 func (h *PGPHandler) PGPDecrypt(ctx context.Context, arg keybase1.PGPDecryptArg) (keybase1.PGPSigVerification, error) { 121 cli := h.getStreamUICli() 122 src := libkb.NewRemoteStreamBuffered(arg.Source, cli, arg.SessionID) 123 snk := libkb.NewRemoteStreamBuffered(arg.Sink, cli, arg.SessionID) 124 earg := &engine.PGPDecryptArg{ 125 Sink: snk, 126 Source: src, 127 AssertSigned: arg.Opts.AssertSigned, 128 SignedBy: arg.Opts.SignedBy, 129 } 130 uis := libkb.UIs{ 131 SecretUI: h.getSecretUI(arg.SessionID, h.G()), 132 IdentifyUI: h.NewRemoteSkipPromptIdentifyUI(arg.SessionID, h.G()), 133 LogUI: h.getLogUI(arg.SessionID), 134 PgpUI: h.getPgpUI(arg.SessionID), 135 SessionID: arg.SessionID, 136 } 137 eng := engine.NewPGPDecrypt(h.G(), earg) 138 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 139 err := engine.RunEngine2(m, eng) 140 if err != nil { 141 return keybase1.PGPSigVerification{}, err 142 } 143 144 return sigVer(h.G(), eng.SignatureStatus(), eng.Signer()), nil 145 } 146 147 func (h *PGPHandler) PGPVerify(ctx context.Context, arg keybase1.PGPVerifyArg) (keybase1.PGPSigVerification, error) { 148 cli := h.getStreamUICli() 149 src := libkb.NewRemoteStreamBuffered(arg.Source, cli, arg.SessionID) 150 earg := &engine.PGPVerifyArg{ 151 Source: src, 152 Signature: arg.Opts.Signature, 153 SignedBy: arg.Opts.SignedBy, 154 } 155 uis := libkb.UIs{ 156 SecretUI: h.getSecretUI(arg.SessionID, h.G()), 157 IdentifyUI: h.NewRemoteIdentifyUI(arg.SessionID, h.G()), 158 LogUI: h.getLogUI(arg.SessionID), 159 PgpUI: h.getPgpUI(arg.SessionID), 160 SessionID: arg.SessionID, 161 } 162 eng := engine.NewPGPVerify(h.G(), earg) 163 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 164 err := engine.RunEngine2(m, eng) 165 if err != nil { 166 return keybase1.PGPSigVerification{}, err 167 } 168 169 return sigVer(h.G(), eng.SignatureStatus(), eng.Signer()), nil 170 } 171 172 func sigVer(g *libkb.GlobalContext, ss *libkb.SignatureStatus, signer *libkb.User) keybase1.PGPSigVerification { 173 var res keybase1.PGPSigVerification 174 if ss.IsSigned { 175 res.IsSigned = ss.IsSigned 176 res.Verified = ss.Verified 177 if signer != nil { 178 signerExp := signer.Export() 179 if signerExp != nil { 180 res.Signer = *signerExp 181 } 182 } 183 if ss.Entity != nil { 184 bundle := libkb.NewPGPKeyBundle(ss.Entity) 185 res.SignKey = bundle.Export() 186 } 187 if len(ss.Warnings) > 0 { 188 res.Warnings = ss.Warnings.Strings() 189 } 190 } 191 return res 192 } 193 194 func (h *PGPHandler) PGPImport(ctx context.Context, arg keybase1.PGPImportArg) error { 195 uis := libkb.UIs{ 196 SecretUI: h.getSecretUI(arg.SessionID, h.G()), 197 LogUI: h.getLogUI(arg.SessionID), 198 SessionID: arg.SessionID, 199 } 200 eng, err := engine.NewPGPKeyImportEngineFromBytes(h.G(), arg.Key, arg.PushSecret) 201 if err != nil { 202 return err 203 } 204 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 205 err = engine.RunEngine2(m, eng) 206 return err 207 } 208 209 type exporter interface { 210 engine.Engine2 211 Results() []keybase1.KeyInfo 212 } 213 214 func (h *PGPHandler) export(ctx context.Context, sessionID int, ex exporter) ([]keybase1.KeyInfo, error) { 215 uis := libkb.UIs{ 216 SecretUI: h.getSecretUI(sessionID, h.G()), 217 LogUI: h.getLogUI(sessionID), 218 SessionID: sessionID, 219 } 220 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 221 if err := engine.RunEngine2(m, ex); err != nil { 222 return nil, err 223 } 224 return ex.Results(), nil 225 } 226 227 func (h *PGPHandler) PGPExport(ctx context.Context, arg keybase1.PGPExportArg) (ret []keybase1.KeyInfo, err error) { 228 return h.export(ctx, arg.SessionID, engine.NewPGPKeyExportEngine(h.G(), arg)) 229 } 230 231 func (h *PGPHandler) PGPExportByKID(ctx context.Context, arg keybase1.PGPExportByKIDArg) (ret []keybase1.KeyInfo, err error) { 232 return h.export(ctx, arg.SessionID, engine.NewPGPKeyExportByKIDEngine(h.G(), arg)) 233 } 234 235 func (h *PGPHandler) PGPExportByFingerprint(ctx context.Context, arg keybase1.PGPExportByFingerprintArg) (ret []keybase1.KeyInfo, err error) { 236 return h.export(ctx, arg.SessionID, engine.NewPGPKeyExportByFingerprintEngine(h.G(), arg)) 237 } 238 239 func (h *PGPHandler) PGPKeyGen(ctx context.Context, arg keybase1.PGPKeyGenArg) error { 240 uis := libkb.UIs{ 241 LogUI: h.getLogUI(arg.SessionID), 242 SecretUI: h.getSecretUI(arg.SessionID, h.G()), 243 SessionID: arg.SessionID, 244 } 245 earg := engine.ImportPGPKeyImportEngineArg(arg) 246 eng := engine.NewPGPKeyImportEngine(h.G(), earg) 247 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 248 return engine.RunEngine2(m, eng) 249 } 250 251 func (h *PGPHandler) PGPKeyGenDefault(ctx context.Context, arg keybase1.PGPKeyGenDefaultArg) error { 252 uis := libkb.UIs{ 253 LogUI: h.getLogUI(arg.SessionID), 254 PgpUI: h.getPgpUI(arg.SessionID), 255 SecretUI: h.getSecretUI(arg.SessionID, h.G()), 256 SessionID: arg.SessionID, 257 } 258 eng := engine.NewPGPKeyGen(h.G(), arg) 259 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 260 return engine.RunEngine2(m, eng) 261 } 262 263 func (h *PGPHandler) PGPDeletePrimary(ctx context.Context, sessionID int) (err error) { 264 return libkb.DeletePrimary(libkb.NewMetaContext(ctx, h.G())) 265 } 266 267 func (h *PGPHandler) PGPSelect(nctx context.Context, sarg keybase1.PGPSelectArg) error { 268 arg := engine.GPGImportKeyArg{ 269 HasProvisionedDevice: true, 270 Query: sarg.FingerprintQuery, 271 AllowMulti: sarg.AllowMulti, 272 SkipImport: sarg.SkipImport, 273 OnlyImport: sarg.OnlyImport, 274 } 275 gpg := engine.NewGPGImportKeyEngine(h.G(), &arg) 276 uis := libkb.UIs{ 277 GPGUI: h.getGPGUI(sarg.SessionID), 278 SecretUI: h.getSecretUI(sarg.SessionID, h.G()), 279 LogUI: h.getLogUI(sarg.SessionID), 280 LoginUI: h.getLoginUI(sarg.SessionID), 281 SessionID: sarg.SessionID, 282 283 // TODO: Pull this type from the connectionID, rather than always 284 // hardcoding CLI, which is all we use now. Note that if we did this, we'd 285 // have to send HelloIAm RPCs in Main() for the CLI commands. A bit of an 286 // annoying TODO, so postpone until we have a Desktop use for PGPSelect. 287 ClientType: keybase1.ClientType_CLI, 288 } 289 m := libkb.NewMetaContext(nctx, h.G()).WithUIs(uis) 290 291 return engine.RunEngine2(m, gpg) 292 } 293 294 func (h *PGPHandler) PGPUpdate(ctx context.Context, arg keybase1.PGPUpdateArg) error { 295 uis := libkb.UIs{ 296 LogUI: h.getLogUI(arg.SessionID), 297 SecretUI: h.getSecretUI(arg.SessionID, h.G()), 298 SessionID: arg.SessionID, 299 } 300 eng := engine.NewPGPUpdateEngine(h.G(), arg.Fingerprints, arg.All) 301 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 302 return engine.RunEngine2(m, eng) 303 } 304 305 func (h *PGPHandler) PGPPurge(ctx context.Context, arg keybase1.PGPPurgeArg) (keybase1.PGPPurgeRes, error) { 306 uis := libkb.UIs{ 307 LogUI: h.getLogUI(arg.SessionID), 308 SessionID: arg.SessionID, 309 SecretUI: h.getSecretUI(arg.SessionID, h.G()), 310 IdentifyUI: h.NewRemoteIdentifyUI(arg.SessionID, h.G()), 311 } 312 eng := engine.NewPGPPurge(h.G(), arg) 313 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 314 var res keybase1.PGPPurgeRes 315 if err := engine.RunEngine2(m, eng); err != nil { 316 return res, err 317 } 318 res.Filenames = eng.KeyFiles() 319 return res, nil 320 } 321 322 // Set the PGP storage notification dismiss flag in the local DB. 323 func (h *PGPHandler) PGPStorageDismiss(ctx context.Context, sessionID int) error { 324 username := h.G().Env.GetUsername() 325 if username.IsNil() { 326 return libkb.NewNoUsernameError() 327 } 328 329 key := libkb.DbKeyNotificationDismiss(libkb.NotificationDismissPGPPrefix, username) 330 return h.G().LocalDb.PutRaw(key, []byte(libkb.NotificationDismissPGPValue)) 331 } 332 333 func (h *PGPHandler) PGPPushPrivate(ctx context.Context, arg keybase1.PGPPushPrivateArg) error { 334 uis := libkb.UIs{ 335 LogUI: h.getLogUI(arg.SessionID), 336 SessionID: arg.SessionID, 337 SecretUI: h.getSecretUI(arg.SessionID, h.G()), 338 GPGUI: h.getGPGUI(arg.SessionID), 339 } 340 eng := engine.NewPGPPushPrivate(arg) 341 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 342 return engine.RunEngine2(m, eng) 343 } 344 345 func (h *PGPHandler) PGPPullPrivate(ctx context.Context, arg keybase1.PGPPullPrivateArg) error { 346 uis := libkb.UIs{ 347 LogUI: h.getLogUI(arg.SessionID), 348 SessionID: arg.SessionID, 349 SecretUI: h.getSecretUI(arg.SessionID, h.G()), 350 GPGUI: h.getGPGUI(arg.SessionID), 351 } 352 eng := engine.NewPGPPullPrivate(arg) 353 m := libkb.NewMetaContext(ctx, h.G()).WithUIs(uis) 354 return engine.RunEngine2(m, eng) 355 }