github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/pgp_decrypt_test.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  	"bytes"
     8  	"crypto/rand"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  
    14  	"golang.org/x/net/context"
    15  
    16  	"github.com/keybase/client/go/libkb"
    17  	keybase1 "github.com/keybase/client/go/protocol/keybase1"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func decengctx(fu *FakeUser, tc libkb.TestContext) libkb.MetaContext {
    22  	return NewMetaContextForTest(tc).WithUIs(libkb.UIs{
    23  		IdentifyUI: &FakeIdentifyUI{},
    24  		SecretUI:   fu.NewSecretUI(),
    25  		LogUI:      tc.G.UI.GetLogUI(),
    26  		PgpUI:      &TestPgpUI{},
    27  	})
    28  }
    29  
    30  func TestPGPDecrypt(t *testing.T) {
    31  	tc := SetupEngineTest(t, "PGPDecrypt")
    32  	defer tc.Cleanup()
    33  	fu := createFakeUserWithPGPSibkeyPushed(tc)
    34  
    35  	// encrypt a message
    36  	msg := "10 days in Japan"
    37  	sink := libkb.NewBufferCloser()
    38  	ctx := decengctx(fu, tc)
    39  	arg := &PGPEncryptArg{
    40  		Source:       strings.NewReader(msg),
    41  		Sink:         sink,
    42  		NoSign:       true,
    43  		BinaryOutput: true,
    44  	}
    45  	enc := NewPGPEncrypt(tc.G, arg)
    46  	if err := RunEngine2(ctx, enc); err != nil {
    47  		t.Fatal(err)
    48  	}
    49  	out := sink.Bytes()
    50  
    51  	t.Logf("encrypted data: %x", out)
    52  
    53  	// decrypt it
    54  	decoded := libkb.NewBufferCloser()
    55  	decarg := &PGPDecryptArg{
    56  		Source: bytes.NewReader(out),
    57  		Sink:   decoded,
    58  	}
    59  	dec := NewPGPDecrypt(tc.G, decarg)
    60  	if err := RunEngine2(ctx, dec); err != nil {
    61  		t.Fatal(err)
    62  	}
    63  	decmsg := decoded.String()
    64  	if decmsg != msg {
    65  		t.Errorf("decoded: %q, expected: %q", decmsg, msg)
    66  	}
    67  
    68  	if dec.Signer() != nil {
    69  		t.Errorf("signer exists, but NoSign flag was true")
    70  	}
    71  }
    72  
    73  func TestPGPDecryptArmored(t *testing.T) {
    74  	tc := SetupEngineTest(t, "PGPDecrypt")
    75  	defer tc.Cleanup()
    76  	fu := createFakeUserWithPGPSibkeyPushed(tc)
    77  
    78  	// encrypt a message
    79  	msg := "10 days in Japan"
    80  	ctx := decengctx(fu, tc)
    81  	sink := libkb.NewBufferCloser()
    82  	arg := &PGPEncryptArg{
    83  		Source: strings.NewReader(msg),
    84  		Sink:   sink,
    85  		NoSign: true,
    86  	}
    87  	enc := NewPGPEncrypt(tc.G, arg)
    88  	if err := RunEngine2(ctx, enc); err != nil {
    89  		t.Fatal(err)
    90  	}
    91  	out := sink.Bytes()
    92  
    93  	t.Logf("encrypted data: %x", out)
    94  
    95  	// decrypt it
    96  	decoded := libkb.NewBufferCloser()
    97  	decarg := &PGPDecryptArg{
    98  		Source: bytes.NewReader(out),
    99  		Sink:   decoded,
   100  	}
   101  	dec := NewPGPDecrypt(tc.G, decarg)
   102  	if err := RunEngine2(ctx, dec); err != nil {
   103  		t.Fatal(err)
   104  	}
   105  	decmsg := decoded.String()
   106  	if decmsg != msg {
   107  		t.Errorf("decoded: %q, expected: %q", decmsg, msg)
   108  	}
   109  
   110  	// A saltpack message
   111  	saltpack := `BEGIN KEYBASE SALTPACK ENCRYPTED MESSAGE.
   112  	kiOUtMhcc4NXXRb XMxIeCbf5rGHq6R lPA7tN3yNXtviMm fQULSIc4k93xPgP ranhF1KYLsndSXH 5hK5WHvPJYOvN3G XLzn8MQ3Q5nwFfY K81cz83VtMGh4CC QnNDeIWVZawH75I jFf8SlDWsdj139W FeS69yb9b7Mo5fA rusOzT3JaydVWgf qC7hU3CUvYR65nP xUpmT2HdHPG5MQu XsOhrf5Zv39u9BB AOkyDAgD7hVSSl9 JQ3eYiduTli4Bqh Ri3uJyBayvkWZTF PSOdMhIbjCptBQ3 oTdvh6pOaUPQeoJ ENL1iuVK04KCOy9 xFekloWTI94hkgt gZakcYbimhmzhea Dsgl2mVqgIwmHgv hp5Indezz4TNtOh VJ8c4BBt1NEzIDg ZfFUiAALL0jRfrB cz7tQc1ussnYzrI IfHSFPDe9Cvz9lp gb1BBogunZOkoNW skfxofDP2lX3Qx7 QP5ah5zm8VV0iw1 zfQaNoxicwkqrM8 tfxyKUWZAypOKoF wUIaC1CQIkTZANa bIJyCxs9g6WceUE jLhh4PazAPCMOU9 M3zOBPP1ieDvc0M OzBLKtBWwz0J1nU 0wtMiADTMKMV.
   113  	END KEYBASE SALTPACK ENCRYPTED MESSAGE.`
   114  
   115  	decoded = libkb.NewBufferCloser()
   116  	decarg = &PGPDecryptArg{
   117  		Source: strings.NewReader(saltpack),
   118  		Sink:   decoded,
   119  	}
   120  	dec = NewPGPDecrypt(tc.G, decarg)
   121  	err := RunEngine2(ctx, dec)
   122  	if wse, ok := err.(libkb.WrongCryptoFormatError); !ok {
   123  		t.Fatalf("Wanted a WrongCryptoFormat error, but got %T (%v)", err, err)
   124  	} else if wse.Wanted != libkb.CryptoMessageFormatPGP ||
   125  		wse.Received != libkb.CryptoMessageFormatSaltpack ||
   126  		wse.Operation != "decrypt" {
   127  		t.Fatalf("Bad error: %v", wse)
   128  	}
   129  }
   130  
   131  // TestPGPDecryptSignedSelf tests that the user who signed the
   132  // message can decrypt it.
   133  func TestPGPDecryptSignedSelf(t *testing.T) {
   134  	tc := SetupEngineTest(t, "PGPDecrypt")
   135  	defer tc.Cleanup()
   136  	fu := createFakeUserWithPGPSibkeyPushed(tc)
   137  
   138  	// encrypt a message
   139  	msg := "We pride ourselves on being meticulous; no issue is too small."
   140  	ctx := decengctx(fu, tc)
   141  	sink := libkb.NewBufferCloser()
   142  	arg := &PGPEncryptArg{
   143  		Source:       strings.NewReader(msg),
   144  		Sink:         sink,
   145  		BinaryOutput: true,
   146  	}
   147  	enc := NewPGPEncrypt(tc.G, arg)
   148  	if err := RunEngine2(ctx, enc); err != nil {
   149  		t.Fatal(err)
   150  	}
   151  	out := sink.Bytes()
   152  
   153  	t.Logf("encrypted data: %x", out)
   154  
   155  	// decrypt it
   156  	decoded := libkb.NewBufferCloser()
   157  	decarg := &PGPDecryptArg{
   158  		Source:       bytes.NewReader(out),
   159  		Sink:         decoded,
   160  		AssertSigned: true,
   161  	}
   162  	dec := NewPGPDecrypt(tc.G, decarg)
   163  	if err := RunEngine2(ctx, dec); err != nil {
   164  		t.Fatal(err)
   165  	}
   166  	decmsg := decoded.String()
   167  	if decmsg != msg {
   168  		t.Errorf("decoded: %q, expected: %q", decmsg, msg)
   169  	}
   170  }
   171  
   172  // TestPGPDecryptSignedOther tests that a user who didn't sign the
   173  // message can verify the signature.
   174  func TestPGPDecryptSignedOther(t *testing.T) {
   175  	tcRecipient := SetupEngineTest(t, "PGPDecrypt - Recipient")
   176  	defer tcRecipient.Cleanup()
   177  	recipient := createFakeUserWithPGPSibkey(tcRecipient)
   178  	Logout(tcRecipient)
   179  
   180  	tcSigner := SetupEngineTest(t, "PGPDecrypt - Signer")
   181  	defer tcSigner.Cleanup()
   182  	signer := createFakeUserWithPGPSibkey(tcSigner)
   183  
   184  	// encrypt a message
   185  	msg := "We pride ourselves on being meticulous; no issue is too small."
   186  	ctx := decengctx(signer, tcSigner)
   187  	sink := libkb.NewBufferCloser()
   188  	arg := &PGPEncryptArg{
   189  		Recips:       []string{recipient.Username},
   190  		Source:       strings.NewReader(msg),
   191  		Sink:         sink,
   192  		BinaryOutput: true,
   193  	}
   194  	enc := NewPGPEncrypt(tcSigner.G, arg)
   195  	if err := RunEngine2(ctx, enc); err != nil {
   196  		t.Fatal(err)
   197  	}
   198  	out := sink.Bytes()
   199  
   200  	t.Logf("encrypted data: %x", out)
   201  
   202  	// signer logs out, recipient logs in:
   203  	t.Logf("signer (%q) logging out", signer.Username)
   204  	Logout(tcSigner)
   205  	// G = libkb.G
   206  	t.Logf("recipient (%q) logging in", recipient.Username)
   207  	recipient.LoginOrBust(tcRecipient)
   208  
   209  	rtrackUI := &FakeIdentifyUI{}
   210  	uis := libkb.UIs{
   211  		IdentifyUI: rtrackUI,
   212  		SecretUI:   recipient.NewSecretUI(),
   213  		LogUI:      tcRecipient.G.UI.GetLogUI(),
   214  		PgpUI:      &TestPgpUI{},
   215  	}
   216  
   217  	// decrypt it
   218  	decoded := libkb.NewBufferCloser()
   219  	decarg := &PGPDecryptArg{
   220  		Source:       bytes.NewReader(out),
   221  		Sink:         decoded,
   222  		AssertSigned: true,
   223  	}
   224  	dec := NewPGPDecrypt(tcRecipient.G, decarg)
   225  	m := NewMetaContextForTest(tcRecipient).WithUIs(uis)
   226  	if err := RunEngine2(m, dec); err != nil {
   227  		t.Fatal(err)
   228  	}
   229  	decmsg := decoded.String()
   230  	if decmsg != msg {
   231  		t.Errorf("decoded: %q, expected: %q", decmsg, msg)
   232  	}
   233  }
   234  
   235  // TestPGPDecryptSignedIdentify tests that the signer is
   236  // identified regardless of AssertSigned, SignedBy args.
   237  func TestPGPDecryptSignedIdentify(t *testing.T) {
   238  	tcRecipient := SetupEngineTest(t, "PGPDecrypt - Recipient")
   239  	defer tcRecipient.Cleanup()
   240  	recipient := createFakeUserWithPGPSibkey(tcRecipient)
   241  	Logout(tcRecipient)
   242  
   243  	tcSigner := SetupEngineTest(t, "PGPDecrypt - Signer")
   244  	defer tcSigner.Cleanup()
   245  	signer := createFakeUserWithPGPSibkey(tcSigner)
   246  
   247  	// encrypt a message
   248  	msg := "We pride ourselves on being meticulous; no issue is too small."
   249  	ctx := decengctx(signer, tcSigner)
   250  	sink := libkb.NewBufferCloser()
   251  	arg := &PGPEncryptArg{
   252  		Recips:       []string{recipient.Username},
   253  		Source:       strings.NewReader(msg),
   254  		Sink:         sink,
   255  		BinaryOutput: true,
   256  	}
   257  	enc := NewPGPEncrypt(tcSigner.G, arg)
   258  	if err := RunEngine2(ctx, enc); err != nil {
   259  		t.Fatal(err)
   260  	}
   261  	out := sink.Bytes()
   262  
   263  	t.Logf("encrypted data: %x", out)
   264  
   265  	// signer logs out, recipient logs in:
   266  	t.Logf("signer (%q) logging out", signer.Username)
   267  	Logout(tcSigner)
   268  	t.Logf("recipient (%q) logging in", recipient.Username)
   269  	recipient.LoginOrBust(tcRecipient)
   270  
   271  	idUI := &FakeIdentifyUI{}
   272  	pgpUI := &TestPgpUI{}
   273  	uis := libkb.UIs{
   274  		IdentifyUI: idUI,
   275  		SecretUI:   recipient.NewSecretUI(),
   276  		LogUI:      tcRecipient.G.UI.GetLogUI(),
   277  		PgpUI:      pgpUI,
   278  	}
   279  
   280  	// decrypt it
   281  	decoded := libkb.NewBufferCloser()
   282  	decarg := &PGPDecryptArg{
   283  		Source:       bytes.NewReader(out),
   284  		Sink:         decoded,
   285  		AssertSigned: false,
   286  	}
   287  	dec := NewPGPDecrypt(tcRecipient.G, decarg)
   288  	m := NewMetaContextForTest(tcRecipient).WithUIs(uis)
   289  	if err := RunEngine2(m, dec); err != nil {
   290  		t.Fatal(err)
   291  	}
   292  
   293  	if idUI.User == nil {
   294  		t.Fatal("identify ui user is nil")
   295  	}
   296  	if idUI.User.Username != signer.Username {
   297  		t.Errorf("idUI username: %q, expected %q", idUI.User.Username, signer.Username)
   298  	}
   299  	if pgpUI.OutputCount != 1 {
   300  		t.Errorf("PgpUI output called %d times, expected 1", pgpUI.OutputCount)
   301  	}
   302  }
   303  
   304  func TestPGPDecryptLong(t *testing.T) {
   305  	tc := SetupEngineTest(t, "PGPDecrypt")
   306  	defer tc.Cleanup()
   307  	fu := createFakeUserWithPGPSibkey(tc)
   308  
   309  	// encrypt a message
   310  	msg := make([]byte, 1024*1024)
   311  
   312  	if _, err := rand.Read(msg); err != nil {
   313  		t.Fatal(err)
   314  	}
   315  
   316  	sink := libkb.NewBufferCloser()
   317  	ctx := decengctx(fu, tc)
   318  	arg := &PGPEncryptArg{
   319  		Source:       bytes.NewReader(msg),
   320  		Sink:         sink,
   321  		NoSign:       true,
   322  		BinaryOutput: true,
   323  	}
   324  	enc := NewPGPEncrypt(tc.G, arg)
   325  	if err := RunEngine2(ctx, enc); err != nil {
   326  		t.Fatal(err)
   327  	}
   328  	out := sink.Bytes()
   329  
   330  	// decrypt it
   331  	decoded := libkb.NewBufferCloser()
   332  	decarg := &PGPDecryptArg{
   333  		Source: bytes.NewReader(out),
   334  		Sink:   decoded,
   335  	}
   336  	dec := NewPGPDecrypt(tc.G, decarg)
   337  	if err := RunEngine2(ctx, dec); err != nil {
   338  		t.Fatal(err)
   339  	}
   340  	decmsg := decoded.Bytes()
   341  	if len(decmsg) != len(msg) {
   342  		t.Fatalf("decoded msg size: %d, expected %d", len(decmsg), len(msg))
   343  	}
   344  
   345  	for i, b := range msg {
   346  		if decmsg[i] != b {
   347  			t.Errorf("decode msg differs at byte %d: %x, expected %x", i, decmsg[i], b)
   348  		}
   349  	}
   350  
   351  	if dec.Signer() != nil {
   352  		t.Errorf("signer exists, but NoSign flag set to true")
   353  	}
   354  }
   355  
   356  type cstest struct {
   357  	name string
   358  	msg  string
   359  }
   360  
   361  var cstests = []cstest{
   362  	{name: "ascii", msg: "hello"},
   363  	{name: "emoji", msg: "😓😕😙"},
   364  }
   365  
   366  func TestPGPDecryptClearsign(t *testing.T) {
   367  	tc := SetupEngineTest(t, "PGPDecrypt")
   368  	defer tc.Cleanup()
   369  
   370  	fu := createFakeUserWithPGPSibkey(tc)
   371  	ctx := decengctx(fu, tc)
   372  
   373  	for _, test := range cstests {
   374  		signedMsg := sign(ctx, tc, test.msg, keybase1.SignMode_CLEAR)
   375  		t.Logf("%s: signed message:\n\n%s\n", test.name, signedMsg)
   376  
   377  		decoded := libkb.NewBufferCloser()
   378  		arg := &PGPDecryptArg{
   379  			Source: strings.NewReader(signedMsg),
   380  			Sink:   decoded,
   381  		}
   382  		eng := NewPGPDecrypt(tc.G, arg)
   383  		if err := RunEngine2(ctx, eng); err != nil {
   384  			t.Errorf("%s: decrypt error: %q", test.name, err)
   385  			continue
   386  		}
   387  		msg := decoded.Bytes()
   388  		trimmed := strings.TrimSpace(string(msg))
   389  		t.Logf("clearsign test %q decoded message: %s\n", test.name, trimmed)
   390  		if trimmed != test.msg {
   391  			t.Errorf("%s: expected msg %q, got %q", test.name, test.msg, trimmed)
   392  		}
   393  
   394  		status := eng.SignatureStatus()
   395  		if !status.IsSigned {
   396  			t.Errorf("%s: expected IsSigned", test.name)
   397  		}
   398  		if !status.Verified {
   399  			t.Errorf("%s: expected Verified", test.name)
   400  		}
   401  		if status.Entity == nil {
   402  			t.Errorf("%s: signature status entity is nil", test.name)
   403  		}
   404  	}
   405  }
   406  
   407  // TestPGPDecryptNonKeybase tests decrypt on a message
   408  // created with a key unknown to keybase.
   409  func TestPGPDecryptNonKeybase(t *testing.T) {
   410  	tcRecipient := SetupEngineTest(t, "PGPDecrypt - Recipient")
   411  	defer tcRecipient.Cleanup()
   412  	recipient := createFakeUserWithPGPSibkey(tcRecipient)
   413  
   414  	tcSigner := SetupEngineTest(t, "PGPDecrypt - Signer")
   415  	defer tcSigner.Cleanup()
   416  	keyA, err := tcSigner.MakePGPKey("keya@keybase.io")
   417  	require.NoError(t, err)
   418  
   419  	// find recipient key
   420  	ur, err := libkb.LoadUser(libkb.NewLoadUserByNameArg(tcSigner.G, recipient.Username))
   421  	if err != nil {
   422  		t.Fatal(err)
   423  	}
   424  	rkeys := ur.GetActivePGPKeys(false)
   425  	if len(rkeys) == 0 {
   426  		t.Fatal("recipient has no active pgp keys")
   427  	}
   428  
   429  	// encrypt and sign a message with keyA
   430  	mid := libkb.NewBufferCloser()
   431  	msg := "Is it time for lunch?"
   432  	recipients := []*libkb.PGPKeyBundle{keyA, rkeys[0]}
   433  	if err := libkb.PGPEncrypt(strings.NewReader(msg), mid, keyA, recipients); err != nil {
   434  		t.Fatal(err)
   435  	}
   436  
   437  	t.Logf("encrypted data: %x", mid.Bytes())
   438  
   439  	idUI := &FakeIdentifyUI{}
   440  	pgpUI := &TestPgpUI{}
   441  	uis := libkb.UIs{
   442  		IdentifyUI: idUI,
   443  		SecretUI:   recipient.NewSecretUI(),
   444  		LogUI:      tcRecipient.G.UI.GetLogUI(),
   445  		PgpUI:      pgpUI,
   446  	}
   447  
   448  	// decrypt it
   449  	decoded := libkb.NewBufferCloser()
   450  	decarg := &PGPDecryptArg{
   451  		Source:       bytes.NewReader(mid.Bytes()),
   452  		Sink:         decoded,
   453  		AssertSigned: false,
   454  	}
   455  	dec := NewPGPDecrypt(tcRecipient.G, decarg)
   456  	m := NewMetaContextForTest(tcRecipient).WithUIs(uis)
   457  	err = RunEngine2(m, dec)
   458  	assert.IsType(t, libkb.BadSigError{}, err, "expected a bad sig error")
   459  	assert.Contains(t, err.Error(), "Message signed by an unknown key", "bad sig error text")
   460  
   461  	if idUI.User != nil {
   462  		if idUI.User.Username == recipient.Username {
   463  			t.Errorf("pgp decrypt identified recipient")
   464  		} else {
   465  			t.Errorf("identify ui user is not nil: %s", idUI.User.Username)
   466  		}
   467  	}
   468  	if pgpUI.OutputCount != 0 {
   469  		t.Errorf("PgpUI OutputSignatureSuccess called %d times, expected 0", pgpUI.OutputCount)
   470  	}
   471  	if pgpUI.OutputNonKeybaseCount != 1 {
   472  		t.Errorf("PgpUI OutputSignatureNonKeybase called %d times, expected 0", pgpUI.OutputNonKeybaseCount)
   473  	}
   474  }
   475  
   476  type TestPgpUI struct {
   477  	OutputWarnings        int
   478  	OutputCount           int
   479  	OutputNonKeybaseCount int
   480  	ShouldPush            bool
   481  	Generated             keybase1.KeyGeneratedArg
   482  }
   483  
   484  func (t *TestPgpUI) OutputPGPWarning(context.Context, keybase1.OutputPGPWarningArg) error {
   485  	t.OutputWarnings++
   486  	return nil
   487  }
   488  
   489  func (t *TestPgpUI) OutputSignatureSuccess(context.Context, keybase1.OutputSignatureSuccessArg) error {
   490  	t.OutputCount++
   491  	return nil
   492  }
   493  
   494  func (t *TestPgpUI) OutputSignatureNonKeybase(context.Context, keybase1.OutputSignatureNonKeybaseArg) error {
   495  	t.OutputNonKeybaseCount++
   496  	return nil
   497  }
   498  
   499  func (t *TestPgpUI) KeyGenerated(ctx context.Context, arg keybase1.KeyGeneratedArg) error {
   500  	t.Generated = arg
   501  	return nil
   502  }
   503  
   504  func (t *TestPgpUI) ShouldPushPrivate(context.Context, keybase1.ShouldPushPrivateArg) (bool, error) {
   505  	return t.ShouldPush, nil
   506  }
   507  
   508  func (t *TestPgpUI) Finished(context.Context, int) error {
   509  	return nil
   510  }
   511  
   512  func TestPGPDecryptWithSyncedKey(t *testing.T) {
   513  	tc0 := SetupEngineTest(t, "pgpg")
   514  	defer tc0.Cleanup()
   515  
   516  	u := createFakeUserWithPGPOnly(t, tc0)
   517  	t.Log("Created fake user with PGP synced only")
   518  
   519  	// find recipient key
   520  	ur, err := libkb.LoadUser(libkb.NewLoadUserByNameArg(tc0.G, u.Username))
   521  	require.NoError(t, err, "loaded the user")
   522  	rkeys := ur.GetActivePGPKeys(false)
   523  	require.True(t, len(rkeys) > 0, "recipient has no active pgp keys")
   524  
   525  	// encrypt and message with rkeys[0]
   526  	mid := libkb.NewBufferCloser()
   527  	msg := "Is it time for lunch?"
   528  	recipients := []*libkb.PGPKeyBundle{rkeys[0]}
   529  	err = libkb.PGPEncrypt(strings.NewReader(msg), mid, nil, recipients)
   530  	require.NoError(t, err, "pgp encryption failed")
   531  	t.Logf("encrypted data: %x", mid.Bytes())
   532  
   533  	Logout(tc0)
   534  
   535  	// redo SetupEngineTest to get a new home directory...should look like a new device.
   536  	tc := SetupEngineTest(t, "login")
   537  	defer tc.Cleanup()
   538  
   539  	uis := libkb.UIs{
   540  		ProvisionUI: newTestProvisionUIPassphrase(),
   541  		LoginUI:     &libkb.TestLoginUI{Username: u.Username},
   542  		LogUI:       tc.G.UI.GetLogUI(),
   543  		SecretUI:    u.NewSecretUI(),
   544  		GPGUI:       &gpgtestui{},
   545  	}
   546  	eng := NewLogin(tc.G, keybase1.DeviceTypeV2_DESKTOP, "", keybase1.ClientType_CLI)
   547  	m := NewMetaContextForTest(tc).WithUIs(uis)
   548  	err = RunEngine2(m, eng)
   549  	require.NoError(t, err, "no error when checking login")
   550  
   551  	// decrypt it
   552  	decryptIt := func() bool {
   553  		decoded := libkb.NewBufferCloser()
   554  		decarg := &PGPDecryptArg{
   555  			Source:       bytes.NewReader(mid.Bytes()),
   556  			Sink:         decoded,
   557  			AssertSigned: false,
   558  		}
   559  		idUI := &FakeIdentifyUI{}
   560  		pgpUI := &TestPgpUI{}
   561  		secretUI := u.NewSecretUI()
   562  		uis = libkb.UIs{
   563  			IdentifyUI: idUI,
   564  			SecretUI:   secretUI,
   565  			LogUI:      tc.G.UI.GetLogUI(),
   566  			PgpUI:      pgpUI,
   567  		}
   568  		dec := NewPGPDecrypt(tc.G, decarg)
   569  		m = NewMetaContextForTest(tc).WithUIs(uis)
   570  		err = RunEngine2(m, dec)
   571  		require.NoError(t, err, "no error for PGP decrypt")
   572  
   573  		decryptedMsg := decoded.Bytes()
   574  		trimmed := strings.TrimSpace(string(decryptedMsg))
   575  		t.Logf("decrypted msg: %s", trimmed)
   576  		require.Equal(t, trimmed, msg, "msg equality failed")
   577  		return secretUI.CalledGetPassphrase
   578  	}
   579  
   580  	decryptCalledPassphrase := decryptIt()
   581  	// No need to get a passphrase, since we just logged in.
   582  	require.False(t, decryptCalledPassphrase, "passphrase get wasn't called")
   583  
   584  	clearCaches(m.G())
   585  
   586  	decryptCalledPassphrase = decryptIt()
   587  	require.True(t, decryptCalledPassphrase, "passphrase get was called")
   588  
   589  	decryptCalledPassphrase = decryptIt()
   590  	require.False(t, decryptCalledPassphrase, "passphrase get wasn't called")
   591  
   592  }