diff --git a/go/client/cmd_encrypt.go b/go/client/cmd_encrypt.go index 91ebe9c814bf..f8ef88a13773 100644 --- a/go/client/cmd_encrypt.go +++ b/go/client/cmd_encrypt.go @@ -17,8 +17,9 @@ import ( type CmdEncrypt struct { libkb.Contextified - filter UnixFilter - recipients []string + filter UnixFilter + recipients []string + noSelfEncrypt bool } func NewCmdEncrypt(cl *libcmdline.CommandLine, g *libkb.GlobalContext) cli.Command { @@ -36,17 +37,10 @@ func NewCmdEncrypt(cl *libcmdline.CommandLine, g *libkb.GlobalContext) cli.Comma // https://keybase.atlassian.net/browse/CORE-2142 // . // - // TODO: Make self-encryption optional: - // https://keybase.atlassian.net/browse/CORE-2143 - // . cli.StringFlag{ Name: "i, infile", Usage: "Specify an input file.", }, - cli.BoolFlag{ - Name: "l, local", - Usage: "Only track locally, don't send a statement to the server.", - }, cli.StringFlag{ Name: "m, message", Usage: "Provide the message on the command line.", @@ -56,8 +50,8 @@ func NewCmdEncrypt(cl *libcmdline.CommandLine, g *libkb.GlobalContext) cli.Comma Usage: "Specify an outfile (stdout by default).", }, cli.BoolFlag{ - Name: "y", - Usage: "Approve remote tracking without prompting.", + Name: "no-self", + Usage: "Don't encrypt for yourself", }, }, } @@ -84,7 +78,8 @@ func (c *CmdEncrypt) Run() error { } opts := keybase1.SaltPackEncryptOptions{ - Recipients: c.recipients, + Recipients: c.recipients, + NoSelfEncrypt: c.noSelfEncrypt, } arg := keybase1.SaltPackEncryptArg{Source: src, Sink: snk, Opts: opts} err = cli.SaltPackEncrypt(context.TODO(), arg) @@ -109,6 +104,7 @@ func (c *CmdEncrypt) ParseArgv(ctx *cli.Context) error { msg := ctx.String("message") outfile := ctx.String("outfile") infile := ctx.String("infile") + c.noSelfEncrypt = ctx.Bool("no-self") if err := c.filter.FilterInit(msg, infile, outfile); err != nil { return err } diff --git a/go/engine/saltpack_decrypt.go b/go/engine/saltpack_decrypt.go index ab934bf71ee7..889642501da3 100644 --- a/go/engine/saltpack_decrypt.go +++ b/go/engine/saltpack_decrypt.go @@ -50,7 +50,11 @@ func (e *SaltPackDecrypt) SubConsumers() []libkb.UIConsumer { // Run starts the engine. func (e *SaltPackDecrypt) Run(ctx *Context) (err error) { - me, err := libkb.LoadMe(libkb.NewLoadUserArg(e.G())) + + defer libkb.Trace(e.G().Log, "SaltPackDecrypt::Run", func() error { return err })() + + var me *libkb.User + me, err = libkb.LoadMe(libkb.NewLoadUserArg(e.G())) if err != nil { return err } @@ -59,6 +63,7 @@ func (e *SaltPackDecrypt) Run(ctx *Context) (err error) { Me: me, KeyType: libkb.DeviceEncryptionKeyType, } + e.G().Log.Debug("| GetSecretKeyWithPrompt") key, err := e.G().Keyrings.GetSecretKeyWithPrompt( ctx.LoginContext, ska, ctx.SecretUI, "decrypting a message/file") @@ -71,5 +76,7 @@ func (e *SaltPackDecrypt) Run(ctx *Context) (err error) { return libkb.KeyCannotDecryptError{} } - return libkb.SaltPackDecrypt(e.arg.Source, e.arg.Sink, kp) + e.G().Log.Debug("| SaltPackDecrypt") + err = libkb.SaltPackDecrypt(e.arg.Source, e.arg.Sink, kp) + return err } diff --git a/go/engine/saltpack_decrypt_test.go b/go/engine/saltpack_decrypt_test.go index 6d433b3e2eac..0589a5e5b9b1 100644 --- a/go/engine/saltpack_decrypt_test.go +++ b/go/engine/saltpack_decrypt_test.go @@ -25,7 +25,6 @@ func TestSaltPackDecrypt(t *testing.T) { } // Should encrypt for self, too. arg := &SaltPackEncryptArg{ - Recips: []string{}, Source: strings.NewReader(msg), Sink: sink, } diff --git a/go/engine/saltpack_encrypt.go b/go/engine/saltpack_encrypt.go index 3ac51191bb00..fc28b3f5acb7 100644 --- a/go/engine/saltpack_encrypt.go +++ b/go/engine/saltpack_encrypt.go @@ -5,15 +5,14 @@ package engine import ( "github.com/keybase/client/go/libkb" + keybase1 "github.com/keybase/client/go/protocol" "io" ) type SaltPackEncryptArg struct { - Recips []string // user assertions - Source io.Reader - Sink io.WriteCloser - NoSelfEncrypt bool - HideSender bool + Opts keybase1.SaltPackEncryptOptions + Source io.Reader + Sink io.WriteCloser } // SaltPackEncrypt encrypts data read from a source into a sink @@ -86,8 +85,10 @@ func (e *SaltPackEncrypt) loadMe(ctx *Context) error { // Run starts the engine. func (e *SaltPackEncrypt) Run(ctx *Context) (err error) { - - libkb.Trace(e.G().Log, "SaltPackEncrypt::Run", func() error { return err }) + e.G().Log.Debug("+ SaltPackEncrypt::Run") + defer func() { + e.G().Log.Debug("- SaltPackEncrypt::Run -> %v", err) + }() var receivers []libkb.NaclDHKeyPublic var sender libkb.NaclDHKeyPair @@ -96,7 +97,7 @@ func (e *SaltPackEncrypt) Run(ctx *Context) (err error) { return err } - if !e.arg.NoSelfEncrypt && e.me != nil { + if !e.arg.Opts.NoSelfEncrypt && e.me != nil { receivers, err = e.loadMyPublicKeys() if err != nil { return err @@ -104,7 +105,7 @@ func (e *SaltPackEncrypt) Run(ctx *Context) (err error) { } kfarg := DeviceKeyfinderArg{ - Users: e.arg.Recips, + Users: e.arg.Opts.Recipients, NeedEncryptKeys: true, Self: e.me, } @@ -128,7 +129,7 @@ func (e *SaltPackEncrypt) Run(ctx *Context) (err error) { } } - if !e.arg.HideSender && e.me != nil { + if !e.arg.Opts.HideSelf && e.me != nil { ska := libkb.SecretKeyArg{ Me: e.me, KeyType: libkb.DeviceEncryptionKeyType, diff --git a/go/engine/saltpack_encrypt_test.go b/go/engine/saltpack_encrypt_test.go index a838dc7246fa..b16a84d24282 100644 --- a/go/engine/saltpack_encrypt_test.go +++ b/go/engine/saltpack_encrypt_test.go @@ -4,10 +4,11 @@ package engine import ( + "github.com/keybase/client/go/libkb" + keybase1 "github.com/keybase/client/go/protocol" + saltpack "github.com/keybase/client/go/saltpack" "strings" "testing" - - "github.com/keybase/client/go/libkb" ) func TestSaltPackEncrypt(t *testing.T) { @@ -26,7 +27,7 @@ func TestSaltPackEncrypt(t *testing.T) { run := func(Recips []string) { sink := libkb.NewBufferCloser() arg := &SaltPackEncryptArg{ - Recips: Recips, + Opts: keybase1.SaltPackEncryptOptions{Recipients: Recips}, Source: strings.NewReader("id2 and encrypt, id2 and encrypt"), Sink: sink, } @@ -60,7 +61,9 @@ func TestSaltPackEncryptSelfNoKey(t *testing.T) { sink := libkb.NewBufferCloser() arg := &SaltPackEncryptArg{ - Recips: []string{"t_tracy+t_tracy@rooter", "t_george", "t_kb+gbrltest@twitter"}, + Opts: keybase1.SaltPackEncryptOptions{ + Recipients: []string{"t_tracy+t_tracy@rooter", "t_george", "t_kb+gbrltest@twitter"}, + }, Source: strings.NewReader("track and encrypt, track and encrypt"), Sink: sink, } @@ -83,7 +86,9 @@ func TestSaltPackEncryptLoggedOut(t *testing.T) { sink := libkb.NewBufferCloser() arg := &SaltPackEncryptArg{ - Recips: []string{"t_tracy+t_tracy@rooter", "t_george", "t_kb+gbrltest@twitter"}, + Opts: keybase1.SaltPackEncryptOptions{ + Recipients: []string{"t_tracy+t_tracy@rooter", "t_george", "t_kb+gbrltest@twitter"}, + }, Source: strings.NewReader("track and encrypt, track and encrypt"), Sink: sink, } @@ -94,3 +99,65 @@ func TestSaltPackEncryptLoggedOut(t *testing.T) { t.Fatalf("Got unexpected error: %s", err) } } + +func TestSaltPackEncryptNoSelf(t *testing.T) { + tc := SetupEngineTest(t, "SaltPackEncrypt") + defer tc.Cleanup() + + u1 := CreateAndSignupFakeUser(tc, "nalcp") + u2 := CreateAndSignupFakeUser(tc, "nalcp") + + msg := "for your eyes only (not even mine!)" + + trackUI := &FakeIdentifyUI{ + Proofs: make(map[string]string), + } + ctx := &Context{IdentifyUI: trackUI, SecretUI: u2.NewSecretUI()} + + sink := libkb.NewBufferCloser() + arg := &SaltPackEncryptArg{ + Opts: keybase1.SaltPackEncryptOptions{ + Recipients: []string{u1.Username}, + NoSelfEncrypt: true, + }, + Source: strings.NewReader(msg), + Sink: sink, + } + + eng := NewSaltPackEncrypt(arg, tc.G) + if err := RunEngine(eng, ctx); err != nil { + t.Fatal(err) + } + + out := sink.Bytes() + if len(out) == 0 { + t.Fatal("no output") + } + + // decrypt it + decoded := libkb.NewBufferCloser() + decarg := &SaltPackDecryptArg{ + Source: strings.NewReader(string(out)), + Sink: decoded, + } + dec := NewSaltPackDecrypt(decarg, tc.G) + err := RunEngine(dec, ctx) + if err != saltpack.ErrNoDecryptionKey { + t.Fatalf("Expected err=%v, but got %v", saltpack.ErrNoDecryptionKey, err) + } + + Logout(tc) + u1.Login(tc.G) + + ctx = &Context{IdentifyUI: trackUI, SecretUI: u1.NewSecretUI()} + decarg.Source = strings.NewReader(string(out)) + dec = NewSaltPackDecrypt(decarg, tc.G) + err = RunEngine(dec, ctx) + if err != nil { + t.Fatal(err) + } + decmsg := decoded.String() + if decmsg != msg { + t.Errorf("decoded: %s, expected: %s", decmsg, msg) + } +} diff --git a/go/protocol/keybase_v1.go b/go/protocol/keybase_v1.go index 6ab58cf9f68f..e902b44d787b 100644 --- a/go/protocol/keybase_v1.go +++ b/go/protocol/keybase_v1.go @@ -4606,9 +4606,9 @@ func (c RevokeClient) RevokeSigs(ctx context.Context, __arg RevokeSigsArg) (err } type SaltPackEncryptOptions struct { - Recipients []string `codec:"recipients" json:"recipients"` - HideSelf bool `codec:"hideSelf" json:"hideSelf"` - EncryptForSelf bool `codec:"encryptForSelf" json:"encryptForSelf"` + Recipients []string `codec:"recipients" json:"recipients"` + HideSelf bool `codec:"hideSelf" json:"hideSelf"` + NoSelfEncrypt bool `codec:"noSelfEncrypt" json:"noSelfEncrypt"` } type SaltPackEncryptArg struct { diff --git a/go/saltpack/decrypt.go b/go/saltpack/decrypt.go index 97239124e0b3..6869a5194595 100644 --- a/go/saltpack/decrypt.go +++ b/go/saltpack/decrypt.go @@ -242,7 +242,6 @@ func (ds *decryptStream) processEncryptionHeader(hdr *EncryptionHeader) error { ds.mki.SenderIsAnon = true ds.mki.SenderKey = ephemeralKey } - copy(ds.sessionKey[:], keys.SessionKey) return nil diff --git a/go/service/saltpack.go b/go/service/saltpack.go index 330959699728..b29c8b7ab7e9 100644 --- a/go/service/saltpack.go +++ b/go/service/saltpack.go @@ -45,7 +45,7 @@ func (h *SaltPackHandler) SaltPackEncrypt(_ context.Context, arg keybase1.SaltPa src := libkb.NewRemoteStreamBuffered(arg.Source, cli, arg.SessionID) snk := libkb.NewRemoteStreamBuffered(arg.Sink, cli, arg.SessionID) earg := &engine.SaltPackEncryptArg{ - Recips: arg.Opts.Recipients, + Opts: arg.Opts, Sink: snk, Source: src, } diff --git a/protocol/avdl/saltpack.avdl b/protocol/avdl/saltpack.avdl index b8049927ecd6..6fe243db5f50 100644 --- a/protocol/avdl/saltpack.avdl +++ b/protocol/avdl/saltpack.avdl @@ -7,7 +7,7 @@ protocol saltPack { record SaltPackEncryptOptions { array recipients; // user assertions boolean hideSelf; - boolean encryptForSelf; + boolean noSelfEncrypt; } void saltPackEncrypt(int sessionID, Stream source, Stream sink, SaltPackEncryptOptions opts); diff --git a/protocol/js/flow-types.js b/protocol/js/flow-types.js index 4525c78b5a56..07d0e0d30593 100644 --- a/protocol/js/flow-types.js +++ b/protocol/js/flow-types.js @@ -4175,13 +4175,13 @@ export type saltPack_RemoteProof = { export type saltPack_SaltPackEncryptOptions = { recipients: Array; hideSelf: boolean; - encryptForSelf: boolean; + noSelfEncrypt: boolean; } export type SaltPackEncryptOptions = { recipients: Array; hideSelf: boolean; - encryptForSelf: boolean; + noSelfEncrypt: boolean; } export type secretUi_Feature = { diff --git a/protocol/json/saltpack.json b/protocol/json/saltpack.json index 163cfc7e6629..fc1f09e61331 100644 --- a/protocol/json/saltpack.json +++ b/protocol/json/saltpack.json @@ -416,7 +416,7 @@ "name" : "hideSelf", "type" : "boolean" }, { - "name" : "encryptForSelf", + "name" : "noSelfEncrypt", "type" : "boolean" } ] } ], diff --git a/react-native/react/constants/types/flow-types.js b/react-native/react/constants/types/flow-types.js index 4525c78b5a56..07d0e0d30593 100644 --- a/react-native/react/constants/types/flow-types.js +++ b/react-native/react/constants/types/flow-types.js @@ -4175,13 +4175,13 @@ export type saltPack_RemoteProof = { export type saltPack_SaltPackEncryptOptions = { recipients: Array; hideSelf: boolean; - encryptForSelf: boolean; + noSelfEncrypt: boolean; } export type SaltPackEncryptOptions = { recipients: Array; hideSelf: boolean; - encryptForSelf: boolean; + noSelfEncrypt: boolean; } export type secretUi_Feature = {