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  }