github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/key_manager_test.go (about)

     1  // Copyright 2016 Keybase Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD
     3  // license that can be found in the LICENSE file.
     4  
     5  package libkbfs
     6  
     7  import (
     8  	"fmt"
     9  	"sync"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/golang/mock/gomock"
    14  	"github.com/keybase/client/go/externals"
    15  	"github.com/keybase/client/go/kbfs/data"
    16  	"github.com/keybase/client/go/kbfs/idutil"
    17  	"github.com/keybase/client/go/kbfs/kbfsblock"
    18  	"github.com/keybase/client/go/kbfs/kbfscodec"
    19  	"github.com/keybase/client/go/kbfs/kbfscrypto"
    20  	"github.com/keybase/client/go/kbfs/kbfsmd"
    21  	libkeytest "github.com/keybase/client/go/kbfs/libkey/test"
    22  	"github.com/keybase/client/go/kbfs/test/clocktest"
    23  	"github.com/keybase/client/go/kbfs/tlf"
    24  	"github.com/keybase/client/go/kbfs/tlfhandle"
    25  	kbname "github.com/keybase/client/go/kbun"
    26  	"github.com/keybase/client/go/protocol/keybase1"
    27  	"github.com/pkg/errors"
    28  	"github.com/stretchr/testify/require"
    29  	"golang.org/x/net/context"
    30  )
    31  
    32  type shimKMCrypto struct {
    33  	Crypto
    34  	pure cryptoPure
    35  }
    36  
    37  func mockNormalizeSocialAssertion(config *ConfigMock) {
    38  	config.mockKbpki.EXPECT().NormalizeSocialAssertion(gomock.Any(), gomock.Any()).DoAndReturn(
    39  		func(ctx context.Context, assertion string) (keybase1.SocialAssertion, error) {
    40  			socialAssertion, isSocialAssertion := externals.NormalizeSocialAssertionStatic(context.Background(), assertion)
    41  			if !isSocialAssertion {
    42  				return keybase1.SocialAssertion{}, fmt.Errorf("Invalid social assertion")
    43  			}
    44  			return socialAssertion, nil
    45  		}).AnyTimes()
    46  }
    47  
    48  func keyManagerInit(t *testing.T, ver kbfsmd.MetadataVer) (mockCtrl *gomock.Controller,
    49  	config *ConfigMock, ctx context.Context) {
    50  	ctr := NewSafeTestReporter(t)
    51  	mockCtrl = gomock.NewController(ctr)
    52  	config = NewConfigMock(mockCtrl, ctr)
    53  	keyCache := NewKeyCacheStandard(100)
    54  	config.SetKeyCache(keyCache)
    55  	keyman := NewKeyManagerStandard(config)
    56  	config.SetKeyManager(keyman)
    57  	interposeDaemonKBPKI(config, "alice", "bob", "charlie", "dave")
    58  	ctx = context.Background()
    59  	codec := kbfscodec.NewMsgpack()
    60  	config.SetCodec(codec)
    61  	cryptoPure := MakeCryptoCommon(codec, makeBlockCryptV1())
    62  	config.SetCrypto(shimKMCrypto{config.Crypto(), cryptoPure})
    63  	config.SetMetadataVersion(ver)
    64  
    65  	// Don't test implicit teams.
    66  	config.mockKbpki.EXPECT().ResolveImplicitTeam(
    67  		gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
    68  		AnyTimes().Return(idutil.ImplicitTeamInfo{}, errors.New("No such team"))
    69  
    70  	mockNormalizeSocialAssertion(config)
    71  	return mockCtrl, config, ctx
    72  }
    73  
    74  func keyManagerShutdown(mockCtrl *gomock.Controller, config *ConfigMock) {
    75  	config.ctr.CheckForFailures()
    76  	mockCtrl.Finish()
    77  }
    78  
    79  var serverHalf = kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x2})
    80  
    81  func expectUncachedGetTLFCryptKey(t *testing.T, config *ConfigMock, tlfID tlf.ID, keyGen, currKeyGen kbfsmd.KeyGen,
    82  	storesHistoric bool, tlfCryptKey, currTLFCryptKey kbfscrypto.TLFCryptKey) {
    83  	if keyGen == currKeyGen {
    84  		require.Equal(t, tlfCryptKey, currTLFCryptKey)
    85  	}
    86  	var keyToUse kbfscrypto.TLFCryptKey
    87  	if storesHistoric {
    88  		keyToUse = currTLFCryptKey
    89  	} else {
    90  		keyToUse = tlfCryptKey
    91  	}
    92  	clientHalf := kbfscrypto.MaskTLFCryptKey(serverHalf, keyToUse)
    93  
    94  	// get the xor'd key out of the metadata
    95  	config.mockCrypto.EXPECT().DecryptTLFCryptKeyClientHalf(
    96  		gomock.Any(), kbfscrypto.TLFEphemeralPublicKey{},
    97  		gomock.Any()).Return(clientHalf, nil)
    98  
    99  	// get the server-side half and retrieve the real
   100  	// current secret key
   101  	config.mockKops.EXPECT().GetTLFCryptKeyServerHalf(gomock.Any(),
   102  		gomock.Any(), gomock.Any()).Return(serverHalf, nil)
   103  }
   104  
   105  func expectUncachedGetTLFCryptKeyAnyDevice(
   106  	config *ConfigMock, tlfID tlf.ID, keyGen kbfsmd.KeyGen, uid keybase1.UID,
   107  	subkey kbfscrypto.CryptPublicKey, tlfCryptKey kbfscrypto.TLFCryptKey) {
   108  	clientHalf := kbfscrypto.MaskTLFCryptKey(serverHalf, tlfCryptKey)
   109  
   110  	// get the xor'd key out of the metadata
   111  	config.mockKbpki.EXPECT().GetCryptPublicKeys(
   112  		gomock.Any(), uid, gomock.Any()).
   113  		Return([]kbfscrypto.CryptPublicKey{subkey}, nil)
   114  	config.mockCrypto.EXPECT().DecryptTLFCryptKeyClientHalfAny(gomock.Any(),
   115  		gomock.Any(), false).Return(clientHalf, 0, nil)
   116  
   117  	// get the server-side half and retrieve the real secret key
   118  	config.mockKops.EXPECT().GetTLFCryptKeyServerHalf(gomock.Any(),
   119  		gomock.Any(), gomock.Any()).Return(serverHalf, nil)
   120  }
   121  
   122  func expectRekey(config *ConfigMock, bh tlf.Handle, numDevices int,
   123  	handleChange, expectNewKeyGen bool,
   124  	tlfCryptKey kbfscrypto.TLFCryptKey) {
   125  	if handleChange {
   126  		// if the handle changes the key manager checks for a conflict
   127  		config.mockMdops.EXPECT().GetLatestHandleForTLF(gomock.Any(), gomock.Any()).
   128  			Return(bh, nil)
   129  	}
   130  
   131  	// generate new keys
   132  	config.mockCrypto.EXPECT().MakeRandomTLFEphemeralKeys().Return(
   133  		kbfscrypto.TLFEphemeralPublicKey{},
   134  		kbfscrypto.TLFEphemeralPrivateKey{}, nil)
   135  	if expectNewKeyGen {
   136  		config.mockCrypto.EXPECT().MakeRandomTLFKeys().Return(
   137  			kbfscrypto.TLFPublicKey{}, kbfscrypto.TLFPrivateKey{},
   138  			tlfCryptKey, nil)
   139  	}
   140  
   141  	subkey := kbfscrypto.MakeFakeCryptPublicKeyOrBust("crypt public key")
   142  	config.mockKbpki.EXPECT().GetCryptPublicKeys(
   143  		gomock.Any(), gomock.Any(), gomock.Any()).
   144  		Return([]kbfscrypto.CryptPublicKey{subkey}, nil).Times(numDevices)
   145  
   146  	// make keys for the one device
   147  	config.mockKops.EXPECT().PutTLFCryptKeyServerHalves(gomock.Any(), gomock.Any()).Return(nil)
   148  
   149  	// Ignore Notify and Flush calls for now
   150  	config.mockRep.EXPECT().Notify(gomock.Any(), gomock.Any()).AnyTimes()
   151  	config.mockKbs.EXPECT().FlushUserFromLocalCache(gomock.Any(),
   152  		gomock.Any()).AnyTimes()
   153  }
   154  
   155  func testKeyManagerPublicTLFCryptKey(t *testing.T, ver kbfsmd.MetadataVer) {
   156  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   157  	defer keyManagerShutdown(mockCtrl, config)
   158  
   159  	id := tlf.FakeID(1, tlf.Public)
   160  	kmd := libkeytest.NewEmptyKeyMetadata(id, 1)
   161  
   162  	tlfCryptKey, err := config.KeyManager().
   163  		GetTLFCryptKeyForEncryption(ctx, kmd)
   164  	if err != nil {
   165  		t.Error(err)
   166  	}
   167  
   168  	if tlfCryptKey != kbfscrypto.PublicTLFCryptKey {
   169  		t.Errorf("got %v, expected %v",
   170  			tlfCryptKey, kbfscrypto.PublicTLFCryptKey)
   171  	}
   172  
   173  	tlfCryptKey, err = config.KeyManager().
   174  		GetTLFCryptKeyForMDDecryption(ctx, kmd, kmd)
   175  	if err != nil {
   176  		t.Error(err)
   177  	}
   178  
   179  	if tlfCryptKey != kbfscrypto.PublicTLFCryptKey {
   180  		t.Errorf("got %v, expected %v",
   181  			tlfCryptKey, kbfscrypto.PublicTLFCryptKey)
   182  	}
   183  
   184  	tlfCryptKey, err = config.KeyManager().
   185  		GetTLFCryptKeyForBlockDecryption(ctx, kmd, data.BlockPointer{})
   186  	if err != nil {
   187  		t.Error(err)
   188  	}
   189  
   190  	if tlfCryptKey != kbfscrypto.PublicTLFCryptKey {
   191  		t.Errorf("got %v, expected %v",
   192  			tlfCryptKey, kbfscrypto.PublicTLFCryptKey)
   193  	}
   194  }
   195  
   196  func testKeyManagerCachedSecretKeyForEncryptionSuccess(t *testing.T, ver kbfsmd.MetadataVer) {
   197  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   198  	defer keyManagerShutdown(mockCtrl, config)
   199  
   200  	id := tlf.FakeID(1, tlf.Private)
   201  	kmd := libkeytest.NewEmptyKeyMetadata(id, 1)
   202  
   203  	cachedTLFCryptKey := kbfscrypto.MakeTLFCryptKey([32]byte{0x1})
   204  	err := config.KeyCache().PutTLFCryptKey(id, 1, cachedTLFCryptKey)
   205  	require.NoError(t, err)
   206  
   207  	tlfCryptKey, err := config.KeyManager().
   208  		GetTLFCryptKeyForEncryption(ctx, kmd)
   209  	require.NoError(t, err)
   210  	require.Equal(t, cachedTLFCryptKey, tlfCryptKey)
   211  }
   212  
   213  func testKeyManagerCachedSecretKeyForMDDecryptionSuccess(t *testing.T, ver kbfsmd.MetadataVer) {
   214  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   215  	defer keyManagerShutdown(mockCtrl, config)
   216  
   217  	id := tlf.FakeID(1, tlf.Private)
   218  	kmd := libkeytest.NewEmptyKeyMetadata(id, 1)
   219  
   220  	cachedTLFCryptKey := kbfscrypto.MakeTLFCryptKey([32]byte{0x1})
   221  	err := config.KeyCache().PutTLFCryptKey(id, 1, cachedTLFCryptKey)
   222  	require.NoError(t, err)
   223  
   224  	tlfCryptKey, err := config.KeyManager().
   225  		GetTLFCryptKeyForMDDecryption(ctx, kmd, kmd)
   226  	require.NoError(t, err)
   227  	require.Equal(t, cachedTLFCryptKey, tlfCryptKey)
   228  }
   229  
   230  func testKeyManagerCachedSecretKeyForBlockDecryptionSuccess(t *testing.T, ver kbfsmd.MetadataVer) {
   231  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   232  	defer keyManagerShutdown(mockCtrl, config)
   233  
   234  	id := tlf.FakeID(1, tlf.Private)
   235  	kmd := libkeytest.NewEmptyKeyMetadata(id, 2)
   236  
   237  	cachedTLFCryptKey := kbfscrypto.MakeTLFCryptKey([32]byte{0x1})
   238  	err := config.KeyCache().PutTLFCryptKey(id, 1, cachedTLFCryptKey)
   239  	require.NoError(t, err)
   240  
   241  	tlfCryptKey, err := config.KeyManager().GetTLFCryptKeyForBlockDecryption(
   242  		ctx, kmd, data.BlockPointer{KeyGen: 1})
   243  	require.NoError(t, err)
   244  	require.Equal(t, cachedTLFCryptKey, tlfCryptKey)
   245  }
   246  
   247  // makeDirWKeyInfoMap creates a new user device key info map with a writer key.
   248  func makeDirWKeyInfoMap(uid keybase1.UID,
   249  	cryptPublicKey kbfscrypto.CryptPublicKey) kbfsmd.UserDevicePublicKeys {
   250  	return kbfsmd.UserDevicePublicKeys{
   251  		uid: {
   252  			cryptPublicKey: true,
   253  		},
   254  	}
   255  }
   256  
   257  func testKeyManagerUncachedSecretKeyForEncryptionSuccess(t *testing.T, ver kbfsmd.MetadataVer) {
   258  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   259  	defer keyManagerShutdown(mockCtrl, config)
   260  
   261  	id := tlf.FakeID(1, tlf.Private)
   262  	h := parseTlfHandleOrBust(t, config, "alice", tlf.Private, id)
   263  	uid := h.FirstResolvedWriter()
   264  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   265  	require.NoError(t, err)
   266  
   267  	session, err := config.KBPKI().GetCurrentSession(ctx)
   268  	require.NoError(t, err)
   269  	storedTLFCryptKey := kbfscrypto.MakeTLFCryptKey([32]byte{0x1})
   270  
   271  	_, err = rmd.AddKeyGeneration(config.Codec(),
   272  		makeDirWKeyInfoMap(uid.AsUserOrBust(), session.CryptPublicKey),
   273  		kbfsmd.UserDevicePublicKeys{},
   274  		kbfscrypto.TLFEphemeralPublicKey{},
   275  		kbfscrypto.TLFEphemeralPrivateKey{},
   276  		kbfscrypto.TLFPublicKey{}, kbfscrypto.TLFPrivateKey{},
   277  		kbfscrypto.TLFCryptKey{}, storedTLFCryptKey)
   278  	require.NoError(t, err)
   279  
   280  	storesHistoric := rmd.StoresHistoricTLFCryptKeys()
   281  	expectUncachedGetTLFCryptKey(t, config, rmd.TlfID(),
   282  		rmd.LatestKeyGeneration(), rmd.LatestKeyGeneration(),
   283  		storesHistoric, storedTLFCryptKey, storedTLFCryptKey)
   284  
   285  	tlfCryptKey, err := config.KeyManager().GetTLFCryptKeyForEncryption(ctx, rmd)
   286  	require.NoError(t, err)
   287  	require.Equal(t, storedTLFCryptKey, tlfCryptKey)
   288  }
   289  
   290  func testKeyManagerUncachedSecretKeyForMDDecryptionSuccess(t *testing.T, ver kbfsmd.MetadataVer) {
   291  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   292  	defer keyManagerShutdown(mockCtrl, config)
   293  
   294  	id := tlf.FakeID(1, tlf.Private)
   295  	h := parseTlfHandleOrBust(t, config, "alice", tlf.Private, id)
   296  	uid := h.FirstResolvedWriter()
   297  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   298  	require.NoError(t, err)
   299  
   300  	subkey := kbfscrypto.MakeFakeCryptPublicKeyOrBust("crypt public key")
   301  	storedTLFCryptKey := kbfscrypto.MakeTLFCryptKey([32]byte{0x1})
   302  
   303  	_, err = rmd.AddKeyGeneration(config.Codec(),
   304  		makeDirWKeyInfoMap(uid.AsUserOrBust(), subkey), kbfsmd.UserDevicePublicKeys{},
   305  		kbfscrypto.TLFEphemeralPublicKey{},
   306  		kbfscrypto.TLFEphemeralPrivateKey{},
   307  		kbfscrypto.TLFPublicKey{}, kbfscrypto.TLFPrivateKey{},
   308  		kbfscrypto.TLFCryptKey{}, storedTLFCryptKey)
   309  	require.NoError(t, err)
   310  
   311  	expectUncachedGetTLFCryptKeyAnyDevice(
   312  		config, rmd.TlfID(), rmd.LatestKeyGeneration(), uid.AsUserOrBust(),
   313  		subkey, storedTLFCryptKey)
   314  
   315  	tlfCryptKey, err := config.KeyManager().
   316  		GetTLFCryptKeyForMDDecryption(ctx, rmd, rmd)
   317  	require.NoError(t, err)
   318  	require.Equal(t, storedTLFCryptKey, tlfCryptKey)
   319  }
   320  
   321  func testKeyManagerUncachedSecretKeyForBlockDecryptionSuccess(t *testing.T, ver kbfsmd.MetadataVer) {
   322  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   323  	defer keyManagerShutdown(mockCtrl, config)
   324  
   325  	id := tlf.FakeID(1, tlf.Private)
   326  	h := parseTlfHandleOrBust(t, config, "alice", tlf.Private, id)
   327  	uid := h.FirstResolvedWriter()
   328  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   329  	require.NoError(t, err)
   330  
   331  	session, err := config.KBPKI().GetCurrentSession(ctx)
   332  	require.NoError(t, err)
   333  	storedTLFCryptKey1 := kbfscrypto.MakeTLFCryptKey([32]byte{0x1})
   334  	storedTLFCryptKey2 := kbfscrypto.MakeTLFCryptKey([32]byte{0x2})
   335  
   336  	_, err = rmd.AddKeyGeneration(config.Codec(),
   337  		makeDirWKeyInfoMap(uid.AsUserOrBust(), session.CryptPublicKey),
   338  		kbfsmd.UserDevicePublicKeys{},
   339  		kbfscrypto.TLFEphemeralPublicKey{},
   340  		kbfscrypto.TLFEphemeralPrivateKey{},
   341  		kbfscrypto.TLFPublicKey{}, kbfscrypto.TLFPrivateKey{},
   342  		kbfscrypto.TLFCryptKey{}, storedTLFCryptKey1)
   343  	require.NoError(t, err)
   344  
   345  	var currCryptKey kbfscrypto.TLFCryptKey
   346  	if rmd.StoresHistoricTLFCryptKeys() {
   347  		currCryptKey = storedTLFCryptKey1
   348  	}
   349  	_, err = rmd.AddKeyGeneration(config.Codec(),
   350  		makeDirWKeyInfoMap(uid.AsUserOrBust(), session.CryptPublicKey),
   351  		kbfsmd.UserDevicePublicKeys{},
   352  		kbfscrypto.TLFEphemeralPublicKey{},
   353  		kbfscrypto.TLFEphemeralPrivateKey{},
   354  		kbfscrypto.TLFPublicKey{}, kbfscrypto.TLFPrivateKey{},
   355  		currCryptKey, storedTLFCryptKey2)
   356  	require.NoError(t, err)
   357  
   358  	keyGen := rmd.LatestKeyGeneration() - 1
   359  	storesHistoric := rmd.StoresHistoricTLFCryptKeys()
   360  	expectUncachedGetTLFCryptKey(t, config, rmd.TlfID(), keyGen,
   361  		rmd.LatestKeyGeneration(), storesHistoric, storedTLFCryptKey1,
   362  		storedTLFCryptKey2)
   363  
   364  	tlfCryptKey, err := config.KeyManager().GetTLFCryptKeyForBlockDecryption(
   365  		ctx, rmd, data.BlockPointer{KeyGen: 1})
   366  	require.NoError(t, err)
   367  	require.Equal(t, storedTLFCryptKey1, tlfCryptKey)
   368  }
   369  
   370  func testKeyManagerRekeySuccessPrivate(t *testing.T, ver kbfsmd.MetadataVer) {
   371  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   372  	defer keyManagerShutdown(mockCtrl, config)
   373  
   374  	id := tlf.FakeID(1, tlf.Private)
   375  	h := parseTlfHandleOrBust(t, config, "alice", tlf.Private, id)
   376  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   377  	require.NoError(t, err)
   378  
   379  	oldKeyGen := rmd.LatestKeyGeneration()
   380  
   381  	tlfCryptKey := kbfscrypto.MakeTLFCryptKey([32]byte{0x1})
   382  	expectRekey(config, h.ToBareHandleOrBust(), 1, false, true, tlfCryptKey)
   383  
   384  	if done, _, err := config.KeyManager().Rekey(ctx, rmd, false); !done || err != nil {
   385  		t.Errorf("Got error on rekey: %t, %+v", done, err)
   386  	} else if rmd.LatestKeyGeneration() != oldKeyGen+1 {
   387  		t.Errorf("Bad key generation after rekey: %d", rmd.LatestKeyGeneration())
   388  	}
   389  }
   390  
   391  func testKeyManagerRekeyResolveAgainSuccessPublic(t *testing.T, ver kbfsmd.MetadataVer) {
   392  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   393  	defer keyManagerShutdown(mockCtrl, config)
   394  
   395  	id := tlf.FakeID(1, tlf.Public)
   396  	h, err := tlfhandle.ParseHandle(
   397  		ctx, config.KBPKI(), tlfhandle.ConstIDGetter{ID: id}, nil,
   398  		"alice,bob@twitter", tlf.Public)
   399  	require.NoError(t, err)
   400  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   401  	require.NoError(t, err)
   402  
   403  	daemon := config.KeybaseService().(*KeybaseDaemonLocal)
   404  	daemon.AddNewAssertionForTestOrBust("bob", "bob@twitter")
   405  
   406  	config.mockMdops.EXPECT().GetLatestHandleForTLF(gomock.Any(), gomock.Any()).
   407  		Return(rmd.tlfHandle.ToBareHandleOrBust(), nil)
   408  
   409  	done, cryptKey, err := config.KeyManager().Rekey(ctx, rmd, false)
   410  	require.NoError(t, err)
   411  	require.True(t, done)
   412  	require.Nil(t, cryptKey)
   413  
   414  	newH := rmd.GetTlfHandle()
   415  	require.Equal(t, tlf.CanonicalName("alice,bob"), newH.GetCanonicalName())
   416  
   417  	// Also check MakeBareTlfHandle.
   418  	oldHandle := rmd.tlfHandle
   419  	rmd.tlfHandle = nil
   420  	newBareH, err := rmd.MakeBareTlfHandle()
   421  	require.NoError(t, err)
   422  	require.Equal(t, newH.ToBareHandleOrBust(), newBareH)
   423  	rmd.tlfHandle = oldHandle
   424  
   425  	// Rekey again, which shouldn't do anything.
   426  	done, cryptKey, err = config.KeyManager().Rekey(ctx, rmd, false)
   427  	require.False(t, done)
   428  	require.Nil(t, cryptKey)
   429  	require.NoError(t, err)
   430  }
   431  
   432  func testKeyManagerRekeyResolveAgainSuccessPublicSelf(t *testing.T, ver kbfsmd.MetadataVer) {
   433  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   434  	defer keyManagerShutdown(mockCtrl, config)
   435  
   436  	id := tlf.FakeID(1, tlf.Public)
   437  	h, err := tlfhandle.ParseHandle(
   438  		ctx, config.KBPKI(), tlfhandle.ConstIDGetter{ID: id}, nil,
   439  		"alice@twitter,bob,charlie@twitter", tlf.Public)
   440  	require.NoError(t, err)
   441  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   442  	require.NoError(t, err)
   443  
   444  	daemon := config.KeybaseService().(*KeybaseDaemonLocal)
   445  	daemon.AddNewAssertionForTestOrBust("alice", "alice@twitter")
   446  	daemon.AddNewAssertionForTestOrBust("charlie", "charlie@twitter")
   447  
   448  	config.mockMdops.EXPECT().GetLatestHandleForTLF(gomock.Any(), gomock.Any()).
   449  		Return(rmd.tlfHandle.ToBareHandleOrBust(), nil)
   450  
   451  	done, cryptKey, err := config.KeyManager().Rekey(ctx, rmd, false)
   452  	require.True(t, done)
   453  	require.Nil(t, cryptKey)
   454  	require.NoError(t, err)
   455  
   456  	newH := rmd.GetTlfHandle()
   457  	require.Equal(t, tlf.CanonicalName("alice,bob,charlie"), newH.GetCanonicalName())
   458  
   459  	// Also check MakeBareTlfHandle.
   460  	oldHandle := rmd.tlfHandle
   461  	rmd.tlfHandle = nil
   462  	newBareH, err := rmd.MakeBareTlfHandle()
   463  	require.NoError(t, err)
   464  	require.Equal(t, newH.ToBareHandleOrBust(), newBareH)
   465  	rmd.tlfHandle = oldHandle
   466  }
   467  
   468  func testKeyManagerRekeyResolveAgainSuccessPrivate(t *testing.T, ver kbfsmd.MetadataVer) {
   469  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   470  	defer keyManagerShutdown(mockCtrl, config)
   471  
   472  	id := tlf.FakeID(1, tlf.Private)
   473  	h, err := tlfhandle.ParseHandle(
   474  		ctx, config.KBPKI(), tlfhandle.ConstIDGetter{ID: id}, nil,
   475  		"alice,bob@twitter,dave@twitter#charlie@twitter", tlf.Private)
   476  	if err != nil {
   477  		t.Fatal(err)
   478  	}
   479  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   480  	require.NoError(t, err)
   481  
   482  	oldKeyGen := rmd.LatestKeyGeneration()
   483  
   484  	tlfCryptKey1 := kbfscrypto.MakeTLFCryptKey([32]byte{0x1})
   485  	expectRekey(config, h.ToBareHandleOrBust(), 3, true, true, tlfCryptKey1)
   486  
   487  	// Pretend that {bob,charlie}@twitter now resolve to {bob,charlie}.
   488  	daemon := config.KeybaseService().(*KeybaseDaemonLocal)
   489  	daemon.AddNewAssertionForTestOrBust("bob", "bob@twitter")
   490  	daemon.AddNewAssertionForTestOrBust("charlie", "charlie@twitter")
   491  
   492  	if done, _, err := config.KeyManager().Rekey(ctx, rmd, false); !done || err != nil {
   493  		t.Fatalf("Got error on rekey: %t, %+v", done, err)
   494  	}
   495  
   496  	if rmd.LatestKeyGeneration() != oldKeyGen+1 {
   497  		t.Fatalf("Bad key generation after rekey: %d", rmd.LatestKeyGeneration())
   498  	}
   499  
   500  	newH := rmd.GetTlfHandle()
   501  	require.Equal(t, tlf.CanonicalName("alice,bob,dave@twitter#charlie"),
   502  		newH.GetCanonicalName())
   503  
   504  	// Also check MakeBareTlfHandle.
   505  	oldHandle := rmd.tlfHandle
   506  	rmd.tlfHandle = nil
   507  	newBareH, err := rmd.MakeBareTlfHandle()
   508  	require.NoError(t, err)
   509  	require.Equal(t, newH.ToBareHandleOrBust(), newBareH)
   510  	rmd.tlfHandle = oldHandle
   511  
   512  	// Now resolve using only a device addition, which won't bump the
   513  	// generation number.
   514  	daemon.AddNewAssertionForTestOrBust("dave", "dave@twitter")
   515  	oldKeyGen = rmd.LatestKeyGeneration()
   516  
   517  	tlfCryptKey2 := kbfscrypto.MakeTLFCryptKey([32]byte{0x2})
   518  	err = config.KeyCache().PutTLFCryptKey(id, 1, tlfCryptKey2)
   519  	require.NoError(t, err)
   520  
   521  	expectRekey(config, oldHandle.ToBareHandleOrBust(), 1, true, false, tlfCryptKey2)
   522  	subkey := kbfscrypto.MakeFakeCryptPublicKeyOrBust("crypt public key")
   523  	config.mockKbpki.EXPECT().GetCryptPublicKeys(
   524  		gomock.Any(), gomock.Any(), gomock.Any()).
   525  		Return([]kbfscrypto.CryptPublicKey{subkey}, nil).Times(3)
   526  	if done, _, err :=
   527  		config.KeyManager().Rekey(ctx, rmd, false); !done || err != nil {
   528  		t.Fatalf("Got error on rekey: %t, %+v", done, err)
   529  	}
   530  
   531  	if rmd.LatestKeyGeneration() != oldKeyGen {
   532  		t.Fatalf("Bad key generation after rekey: %d",
   533  			rmd.LatestKeyGeneration())
   534  	}
   535  
   536  	newH = rmd.GetTlfHandle()
   537  	require.Equal(t, tlf.CanonicalName("alice,bob,dave#charlie"),
   538  		newH.GetCanonicalName())
   539  
   540  	// Also check MakeBareTlfHandle.
   541  	rmd.tlfHandle = nil
   542  	newBareH, err = rmd.MakeBareTlfHandle()
   543  	require.NoError(t, err)
   544  	require.Equal(t, newH.ToBareHandleOrBust(), newBareH)
   545  }
   546  
   547  func hasWriterKey(t *testing.T, rmd *RootMetadata, uid keybase1.UID) bool {
   548  	writers, _, err := rmd.getUserDevicePublicKeys()
   549  	require.NoError(t, err)
   550  	return len(writers[uid]) > 0
   551  }
   552  
   553  func testKeyManagerPromoteReaderSuccess(t *testing.T, ver kbfsmd.MetadataVer) {
   554  	ctx := context.Background()
   555  
   556  	config := MakeTestConfigOrBust(t, "alice", "bob")
   557  	defer CheckConfigAndShutdown(ctx, t, config)
   558  
   559  	id := tlf.FakeID(1, tlf.Private)
   560  	h, err := tlfhandle.ParseHandle(
   561  		ctx, config.KBPKI(), tlfhandle.ConstIDGetter{ID: id}, nil,
   562  		"alice,bob@twitter#bob", tlf.Private)
   563  	require.NoError(t, err)
   564  
   565  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   566  	require.NoError(t, err)
   567  
   568  	// Make the first key generation.
   569  	done, _, err := config.KeyManager().Rekey(ctx, rmd, false)
   570  	require.NoError(t, err)
   571  	require.True(t, done)
   572  
   573  	aliceUID := keybase1.MakeTestUID(1)
   574  	bobUID := keybase1.MakeTestUID(2)
   575  
   576  	require.True(t, hasWriterKey(t, rmd, aliceUID))
   577  	require.False(t, hasWriterKey(t, rmd, bobUID))
   578  
   579  	oldKeyGen := rmd.LatestKeyGeneration()
   580  
   581  	// Pretend that bob@twitter now resolves to bob.
   582  	daemon := config.KeybaseService().(*KeybaseDaemonLocal)
   583  	daemon.AddNewAssertionForTestOrBust("bob", "bob@twitter")
   584  
   585  	// Rekey as alice.
   586  	done, _, err = config.KeyManager().Rekey(ctx, rmd, false)
   587  	require.NoError(t, err)
   588  	require.True(t, done)
   589  
   590  	// Reader promotion shouldn't increase the key generation.
   591  	require.Equal(t, oldKeyGen, rmd.LatestKeyGeneration())
   592  
   593  	require.True(t, hasWriterKey(t, rmd, aliceUID))
   594  	require.True(t, hasWriterKey(t, rmd, bobUID))
   595  
   596  	newH := rmd.GetTlfHandle()
   597  	require.Equal(t,
   598  		tlf.CanonicalName("alice,bob"),
   599  		newH.GetCanonicalName())
   600  }
   601  
   602  func testKeyManagerPromoteReaderSelf(t *testing.T, ver kbfsmd.MetadataVer) {
   603  	ctx := context.Background()
   604  
   605  	config := MakeTestConfigOrBust(t, "alice", "bob")
   606  	defer CheckConfigAndShutdown(ctx, t, config)
   607  
   608  	id := tlf.FakeID(1, tlf.Private)
   609  	h, err := tlfhandle.ParseHandle(
   610  		ctx, config.KBPKI(), tlfhandle.ConstIDGetter{ID: id}, nil,
   611  		"alice,bob@twitter#bob", tlf.Private)
   612  	require.NoError(t, err)
   613  
   614  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   615  	require.NoError(t, err)
   616  
   617  	// Make the first key generation.
   618  	done, _, err := config.KeyManager().Rekey(ctx, rmd, false)
   619  	require.NoError(t, err)
   620  	require.True(t, done)
   621  
   622  	aliceUID := keybase1.MakeTestUID(1)
   623  	bobUID := keybase1.MakeTestUID(2)
   624  
   625  	require.True(t, hasWriterKey(t, rmd, aliceUID))
   626  	require.False(t, hasWriterKey(t, rmd, bobUID))
   627  
   628  	oldKeyGen := rmd.LatestKeyGeneration()
   629  
   630  	config2 := ConfigAsUser(config, "bob")
   631  	defer CheckConfigAndShutdown(ctx, t, config2)
   632  
   633  	// Pretend that bob@twitter now resolves to bob.
   634  	daemon := config2.KeybaseService().(*KeybaseDaemonLocal)
   635  	daemon.AddNewAssertionForTestOrBust("bob", "bob@twitter")
   636  
   637  	// Rekey as bob, which should still succeed.
   638  	done, _, err = config2.KeyManager().Rekey(ctx, rmd, false)
   639  	require.NoError(t, err)
   640  	require.True(t, done)
   641  
   642  	// Reader promotion shouldn't increase the key generation.
   643  	require.Equal(t, oldKeyGen, rmd.LatestKeyGeneration())
   644  
   645  	require.True(t, hasWriterKey(t, rmd, aliceUID))
   646  	require.True(t, hasWriterKey(t, rmd, bobUID))
   647  
   648  	newH := rmd.GetTlfHandle()
   649  	require.Equal(t,
   650  		tlf.CanonicalName("alice,bob"),
   651  		newH.GetCanonicalName())
   652  }
   653  
   654  func testKeyManagerReaderRekeyShouldNotPromote(t *testing.T, ver kbfsmd.MetadataVer) {
   655  	ctx := context.Background()
   656  
   657  	config := MakeTestConfigOrBust(t, "alice", "bob", "charlie")
   658  	defer CheckConfigAndShutdown(ctx, t, config)
   659  
   660  	id := tlf.FakeID(1, tlf.Private)
   661  	h, err := tlfhandle.ParseHandle(
   662  		ctx, config.KBPKI(), tlfhandle.ConstIDGetter{ID: id}, nil,
   663  		"alice,charlie@twitter#bob,charlie", tlf.Private)
   664  	require.NoError(t, err)
   665  
   666  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   667  	require.NoError(t, err)
   668  
   669  	// Make the first key generation.
   670  	done, _, err := config.KeyManager().Rekey(ctx, rmd, false)
   671  	require.NoError(t, err)
   672  	require.True(t, done)
   673  
   674  	aliceUID := keybase1.MakeTestUID(1)
   675  	bobUID := keybase1.MakeTestUID(2)
   676  	charlieUID := keybase1.MakeTestUID(3)
   677  
   678  	require.True(t, hasWriterKey(t, rmd, aliceUID))
   679  	require.False(t, hasWriterKey(t, rmd, bobUID))
   680  	require.False(t, hasWriterKey(t, rmd, charlieUID))
   681  
   682  	config2 := ConfigAsUser(config, "bob")
   683  	defer CheckConfigAndShutdown(ctx, t, config2)
   684  
   685  	// Pretend that charlie@twitter now resolves to charlie.
   686  	daemon := config2.KeybaseService().(*KeybaseDaemonLocal)
   687  	daemon.AddNewAssertionForTestOrBust("charlie", "charlie@twitter")
   688  
   689  	AddDeviceForLocalUserOrBust(t, config2, bobUID)
   690  
   691  	// Try to rekey as bob, which should succeed partially.
   692  	done, _, err = config2.KeyManager().Rekey(ctx, rmd, false)
   693  	require.NoError(t, err)
   694  	require.True(t, done)
   695  
   696  	require.True(t, hasWriterKey(t, rmd, aliceUID))
   697  	require.False(t, hasWriterKey(t, rmd, bobUID))
   698  	require.False(t, hasWriterKey(t, rmd, charlieUID))
   699  }
   700  
   701  func testKeyManagerReaderRekeyResolveAgainSuccessPrivate(t *testing.T, ver kbfsmd.MetadataVer) {
   702  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   703  	defer keyManagerShutdown(mockCtrl, config)
   704  
   705  	id := tlf.FakeID(1, tlf.Private)
   706  	h, err := tlfhandle.ParseHandle(
   707  		ctx, config.KBPKI(), tlfhandle.ConstIDGetter{ID: id}, nil,
   708  		"alice,dave@twitter#bob@twitter,charlie@twitter", tlf.Private)
   709  	if err != nil {
   710  		t.Fatal(err)
   711  	}
   712  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   713  	require.NoError(t, err)
   714  
   715  	oldKeyGen := rmd.LatestKeyGeneration()
   716  
   717  	tlfCryptKey1 := kbfscrypto.MakeTLFCryptKey([32]byte{0x1})
   718  	expectRekey(config, h.ToBareHandleOrBust(), 1, true, true, tlfCryptKey1)
   719  
   720  	// Make the first key generation
   721  	if done, _, err := config.KeyManager().Rekey(ctx, rmd, false); !done || err != nil {
   722  		t.Fatalf("Got error on rekey: %t, %+v", done, err)
   723  	}
   724  
   725  	if rmd.LatestKeyGeneration() != oldKeyGen+1 {
   726  		t.Fatalf("Bad key generation after rekey: %d", rmd.LatestKeyGeneration())
   727  	}
   728  
   729  	newH := rmd.GetTlfHandle()
   730  	require.Equal(t,
   731  		tlf.CanonicalName("alice,dave@twitter#bob@twitter,charlie@twitter"),
   732  		newH.GetCanonicalName())
   733  
   734  	// Now resolve everyone, but have reader bob to do the rekey
   735  	daemon := config.KeybaseService().(*KeybaseDaemonLocal)
   736  	daemon.AddNewAssertionForTestOrBust("bob", "bob@twitter")
   737  	daemon.AddNewAssertionForTestOrBust("charlie", "charlie@twitter")
   738  	daemon.AddNewAssertionForTestOrBust("dave", "dave@twitter")
   739  
   740  	_, bobID, err := daemon.Resolve(
   741  		ctx, "bob", keybase1.OfflineAvailability_NONE)
   742  	require.NoError(t, err)
   743  	bobUID, err := bobID.AsUser()
   744  	require.NoError(t, err)
   745  	daemon.SetCurrentUID(bobUID)
   746  
   747  	// Now resolve using only a device addition, which won't bump the
   748  	// generation number.
   749  	oldKeyGen = rmd.LatestKeyGeneration()
   750  	// Pretend bob has the key in the cache (in reality it would be
   751  	// decrypted via bob's paper key)
   752  
   753  	tlfCryptKey2 := kbfscrypto.MakeTLFCryptKey([32]byte{0x2})
   754  	err = config.KeyCache().PutTLFCryptKey(rmd.TlfID(), oldKeyGen, tlfCryptKey2)
   755  	require.NoError(t, err)
   756  
   757  	expectRekey(config, h.ToBareHandleOrBust(), 1, false, false, tlfCryptKey2)
   758  	subkey := kbfscrypto.MakeFakeCryptPublicKeyOrBust("crypt public key")
   759  	config.mockKbpki.EXPECT().GetCryptPublicKeys(
   760  		gomock.Any(), gomock.Any(), gomock.Any()).
   761  		Return([]kbfscrypto.CryptPublicKey{subkey}, nil)
   762  	if done, _, err :=
   763  		config.KeyManager().Rekey(ctx, rmd, false); !done || err != nil {
   764  		t.Fatalf("Got error on rekey: %t, %+v", done, err)
   765  	}
   766  
   767  	if rmd.LatestKeyGeneration() != oldKeyGen {
   768  		t.Fatalf("Bad key generation after rekey: %d",
   769  			rmd.LatestKeyGeneration())
   770  	}
   771  
   772  	// bob shouldn't have been able to resolve other users since he's
   773  	// just a reader.
   774  	newH = rmd.GetTlfHandle()
   775  	require.Equal(t, tlf.CanonicalName("alice,dave@twitter#bob,charlie@twitter"),
   776  		newH.GetCanonicalName())
   777  
   778  	// Also check MakeBareTlfHandle.
   779  	rmd.tlfHandle = nil
   780  	newBareH, err := rmd.MakeBareTlfHandle()
   781  	require.NoError(t, err)
   782  	require.Equal(t, newH.ToBareHandleOrBust(), newBareH)
   783  }
   784  
   785  func testKeyManagerRekeyResolveAgainNoChangeSuccessPrivate(t *testing.T, ver kbfsmd.MetadataVer) {
   786  	mockCtrl, config, ctx := keyManagerInit(t, ver)
   787  	defer keyManagerShutdown(mockCtrl, config)
   788  
   789  	id := tlf.FakeID(1, tlf.Private)
   790  	h, err := tlfhandle.ParseHandle(
   791  		ctx, config.KBPKI(), tlfhandle.ConstIDGetter{ID: id}, nil,
   792  		"alice,bob,bob@twitter", tlf.Private)
   793  	if err != nil {
   794  		t.Fatal(err)
   795  	}
   796  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), id, h)
   797  	require.NoError(t, err)
   798  
   799  	oldKeyGen := rmd.LatestKeyGeneration()
   800  
   801  	tlfCryptKey1 := kbfscrypto.MakeTLFCryptKey([32]byte{0x1})
   802  	expectRekey(config, h.ToBareHandleOrBust(), 2, true, true, tlfCryptKey1)
   803  
   804  	// Make the first key generation
   805  	if done, _, err := config.KeyManager().Rekey(ctx, rmd, false); !done || err != nil {
   806  		t.Fatalf("Got error on rekey: %t, %+v", done, err)
   807  	}
   808  
   809  	if rmd.LatestKeyGeneration() != oldKeyGen+1 {
   810  		t.Fatalf("Bad key generation after rekey: %d", rmd.LatestKeyGeneration())
   811  	}
   812  
   813  	newH := rmd.GetTlfHandle()
   814  	require.Equal(t,
   815  		tlf.CanonicalName("alice,bob,bob@twitter"),
   816  		newH.GetCanonicalName())
   817  
   818  	// Now resolve everyone, but have reader bob to do the rekey
   819  	daemon := config.KeybaseService().(*KeybaseDaemonLocal)
   820  	daemon.AddNewAssertionForTestOrBust("bob", "bob@twitter")
   821  
   822  	// Now resolve which gets rid of the unresolved writers, but
   823  	// doesn't otherwise change the handle since bob is already in it.
   824  	oldKeyGen = rmd.LatestKeyGeneration()
   825  	config.mockCrypto.EXPECT().MakeRandomTLFEphemeralKeys().Return(
   826  		kbfscrypto.TLFEphemeralPublicKey{},
   827  		kbfscrypto.TLFEphemeralPrivateKey{}, nil)
   828  
   829  	subkey := kbfscrypto.MakeFakeCryptPublicKeyOrBust("crypt public key")
   830  	config.mockKbpki.EXPECT().GetCryptPublicKeys(
   831  		gomock.Any(), gomock.Any(), gomock.Any()).
   832  		Return([]kbfscrypto.CryptPublicKey{subkey}, nil).Times(2)
   833  	if done, _, err :=
   834  		config.KeyManager().Rekey(ctx, rmd, false); !done || err != nil {
   835  		t.Fatalf("Got error on rekey: %t, %+v", done, err)
   836  	}
   837  
   838  	if rmd.LatestKeyGeneration() != oldKeyGen {
   839  		t.Fatalf("Bad key generation after rekey: %d",
   840  			rmd.LatestKeyGeneration())
   841  	}
   842  
   843  	// bob shouldn't have been able to resolve other users since he's
   844  	// just a reader.
   845  	newH = rmd.GetTlfHandle()
   846  	require.Equal(t, tlf.CanonicalName("alice,bob"), newH.GetCanonicalName())
   847  
   848  	// Also check MakeBareTlfHandle.
   849  	rmd.tlfHandle = nil
   850  	newBareH, err := rmd.MakeBareTlfHandle()
   851  	require.NoError(t, err)
   852  	require.Equal(t, newH.ToBareHandleOrBust(), newBareH)
   853  }
   854  
   855  func testKeyManagerRekeyAddAndRevokeDevice(t *testing.T, ver kbfsmd.MetadataVer) {
   856  	var u1, u2 kbname.NormalizedUsername = "u1", "u2"
   857  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2)
   858  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
   859  	clock := clocktest.NewTestClockNow()
   860  	config1.SetClock(clock)
   861  
   862  	config1.SetMetadataVersion(ver)
   863  
   864  	config2 := ConfigAsUser(config1, u2)
   865  	defer CheckConfigAndShutdown(ctx, t, config2)
   866  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
   867  	if err != nil {
   868  		t.Fatal(err)
   869  	}
   870  	uid2 := session2.UID
   871  
   872  	// Create a shared folder
   873  	name := u1.String() + "," + u2.String()
   874  
   875  	rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
   876  
   877  	kbfsOps1 := config1.KBFSOps()
   878  
   879  	// user 1 creates a file
   880  	_, _, err = kbfsOps1.CreateFile(ctx, rootNode1, testPPS("a"), false, NoExcl)
   881  	if err != nil {
   882  		t.Fatalf("Couldn't create file: %+v", err)
   883  	}
   884  	err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
   885  	if err != nil {
   886  		t.Fatalf("Couldn't sync file: %+v", err)
   887  	}
   888  
   889  	rootNode2 := GetRootNodeOrBust(ctx, t, config2, name, tlf.Private)
   890  
   891  	kbfsOps2 := config2.KBFSOps()
   892  
   893  	// user 2 creates a file
   894  	_, _, err = kbfsOps2.CreateFile(ctx, rootNode2, testPPS("b"), false, NoExcl)
   895  	if err != nil {
   896  		t.Fatalf("Couldn't create file: %+v", err)
   897  	}
   898  	err = kbfsOps2.SyncAll(ctx, rootNode2.GetFolderBranch())
   899  	if err != nil {
   900  		t.Fatalf("Couldn't sync file: %+v", err)
   901  	}
   902  
   903  	config2Dev2 := ConfigAsUser(config1, u2)
   904  	defer CheckConfigAndShutdown(ctx, t, config2Dev2)
   905  
   906  	// Now give u2 a new device.  The configs don't share a Keybase
   907  	// Daemon so we have to do it in all places.
   908  	AddDeviceForLocalUserOrBust(t, config1, uid2)
   909  	AddDeviceForLocalUserOrBust(t, config2, uid2)
   910  	devIndex := AddDeviceForLocalUserOrBust(t, config2Dev2, uid2)
   911  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
   912  
   913  	// user 2 should be unable to read the data now since its device
   914  	// wasn't registered when the folder was originally created.
   915  	_, err = GetRootNodeForTest(ctx, config2Dev2, name, tlf.Private)
   916  	if _, ok := err.(NeedSelfRekeyError); !ok {
   917  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
   918  	}
   919  
   920  	// GetTLFCryptKeys needs to return the same error.
   921  	rmd, err := config1.MDOps().GetForTLF(ctx, rootNode1.GetFolderBranch().Tlf, nil)
   922  	if err != nil {
   923  		t.Fatalf("Couldn't get latest md: %+v", err)
   924  	}
   925  	_, _, err = config2Dev2.KBFSOps().GetTLFCryptKeys(ctx, rmd.GetTlfHandle())
   926  	if _, ok := err.(NeedSelfRekeyError); !ok {
   927  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
   928  	}
   929  
   930  	// Set the KBPKI so we can count the identify calls
   931  	countKBPKI := &identifyCountingKBPKI{
   932  		KBPKI: config1.KBPKI(),
   933  	}
   934  	config1.SetKBPKI(countKBPKI)
   935  	// Force the FBO to forget about its previous identify, so that we
   936  	// can make sure the rekey doesn't trigger a full identify.
   937  	kbfsOps1.(*KBFSOpsStandard).getOpsNoAdd(
   938  		ctx, rootNode1.GetFolderBranch()).identifyDone = false
   939  
   940  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
   941  		kbfsOps1, rootNode1.GetFolderBranch().Tlf)
   942  	if err != nil {
   943  		t.Fatalf("Couldn't rekey: %+v", err)
   944  	}
   945  
   946  	// Only u2 should be identified as part of the rekey.
   947  	if g, e := countKBPKI.getIdentifyCalls(), 1; g != e {
   948  		t.Errorf("Expected %d identify calls, but got %d", e, g)
   949  	}
   950  
   951  	// u2 syncs after the rekey
   952  	if err := kbfsOps2.SyncFromServer(ctx,
   953  		rootNode2.GetFolderBranch(), nil); err != nil {
   954  		t.Fatalf("Couldn't sync from server: %+v", err)
   955  	}
   956  
   957  	// user 2 creates another file
   958  	_, _, err = kbfsOps2.CreateFile(ctx, rootNode2, testPPS("c"), false, NoExcl)
   959  	if err != nil {
   960  		t.Fatalf("Couldn't create file: %+v", err)
   961  	}
   962  	err = kbfsOps2.SyncAll(ctx, rootNode2.GetFolderBranch())
   963  	if err != nil {
   964  		t.Fatalf("Couldn't sync file: %+v", err)
   965  	}
   966  
   967  	// add a third device for user 2
   968  	config2Dev3 := ConfigAsUser(config1, u2)
   969  	defer CheckConfigAndShutdown(ctx, t, config2Dev3)
   970  	defer config2Dev3.SetKeyCache(NewKeyCacheStandard(5000))
   971  	AddDeviceForLocalUserOrBust(t, config1, uid2)
   972  	AddDeviceForLocalUserOrBust(t, config2, uid2)
   973  	AddDeviceForLocalUserOrBust(t, config2Dev2, uid2)
   974  	devIndex = AddDeviceForLocalUserOrBust(t, config2Dev3, uid2)
   975  	SwitchDeviceForLocalUserOrBust(t, config2Dev3, devIndex)
   976  
   977  	// Now revoke the original user 2 device (the last writer)
   978  	clock.Add(1 * time.Minute)
   979  	RevokeDeviceForLocalUserOrBust(t, config1, uid2, 0)
   980  	RevokeDeviceForLocalUserOrBust(t, config2Dev2, uid2, 0)
   981  	RevokeDeviceForLocalUserOrBust(t, config2Dev3, uid2, 0)
   982  
   983  	SetGlobalMerkleRootForTestOrBust(
   984  		t, config1, keybase1.MerkleRootV2{}, clock.Now())
   985  	SetGlobalMerkleRootForTestOrBust(
   986  		t, config2Dev2, keybase1.MerkleRootV2{}, clock.Now())
   987  	SetGlobalMerkleRootForTestOrBust(
   988  		t, config2Dev3, keybase1.MerkleRootV2{}, clock.Now())
   989  	SetKbfsMerkleRootForTestOrBust(
   990  		t, config1, keybase1.MerkleTreeID_KBFS_PRIVATE, &kbfsmd.MerkleRoot{
   991  			Timestamp: clock.Now().Unix(),
   992  		})
   993  
   994  	// First request a rekey from the new device, which will only be
   995  	// able to set the rekey bit (copying the root MD).
   996  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
   997  		config2Dev3.KBFSOps(), rootNode1.GetFolderBranch().Tlf)
   998  	if err != nil {
   999  		t.Fatalf("Couldn't rekey: %+v", err)
  1000  	}
  1001  
  1002  	err = kbfsOps1.SyncFromServer(ctx,
  1003  		rootNode1.GetFolderBranch(), nil)
  1004  	if err != nil {
  1005  		t.Fatalf("Couldn't sync from server: %+v", err)
  1006  	}
  1007  
  1008  	// rekey again
  1009  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1010  		kbfsOps1, rootNode1.GetFolderBranch().Tlf)
  1011  	if err != nil {
  1012  		t.Fatalf("Couldn't rekey: %+v", err)
  1013  	}
  1014  
  1015  	// Only u2 should be identified again as part of the rekey.
  1016  	if g, e := countKBPKI.getIdentifyCalls(), 2; g != e {
  1017  		t.Errorf("Expected %d identify calls, but got %d", e, g)
  1018  	}
  1019  
  1020  	// force re-encryption of the root dir
  1021  	_, _, err = kbfsOps1.CreateFile(ctx, rootNode1, testPPS("d"), false, NoExcl)
  1022  	if err != nil {
  1023  		t.Fatalf("Couldn't create file: %+v", err)
  1024  	}
  1025  	err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
  1026  	if err != nil {
  1027  		t.Fatalf("Couldn't sync file: %+v", err)
  1028  	}
  1029  
  1030  	// this device should be able to read now
  1031  	root2Dev2 := GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
  1032  
  1033  	kbfsOps2Dev2 := config2Dev2.KBFSOps()
  1034  	err = kbfsOps2Dev2.SyncFromServer(ctx,
  1035  		root2Dev2.GetFolderBranch(), nil)
  1036  	if err != nil {
  1037  		t.Fatalf("Couldn't sync from server: %+v", err)
  1038  	}
  1039  
  1040  	// device 2 should still work
  1041  	rootNode2Dev2 := GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
  1042  
  1043  	children, err := kbfsOps2Dev2.GetDirChildren(ctx, rootNode2Dev2)
  1044  	require.NoError(t, err)
  1045  	if _, ok := children[rootNode2Dev2.ChildName("d")]; !ok {
  1046  		t.Fatalf("Device 2 couldn't see the new dir entry")
  1047  	}
  1048  
  1049  	// But device 1 should now fail to see any updates.  TODO: when a
  1050  	// device sees it has been revoked from the TLF, we should delete
  1051  	// all its cached data and refuse to serve any more.  (However, in
  1052  	// production the device's session would likely be revoked,
  1053  	// probably leading to NoCurrentSession errors anyway.)
  1054  	err = kbfsOps2.SyncFromServer(ctx,
  1055  		rootNode2.GetFolderBranch(), nil)
  1056  	if err == nil {
  1057  		// This is not expected to succeed; the node will be unable to
  1058  		// deserialize the private MD.
  1059  		t.Fatalf("Unexpectedly could sync from server")
  1060  	}
  1061  	// Should still be seeing the old children, since the updates from
  1062  	// the latest revision were never applied.
  1063  	children, err = kbfsOps2.GetDirChildren(ctx, rootNode2)
  1064  	require.NoError(t, err)
  1065  	if _, ok := children[rootNode2.ChildName("d")]; ok {
  1066  		t.Fatalf("Found c unexpectedly: %v", children)
  1067  	}
  1068  
  1069  	// meanwhile, device 3 should be able to read both the new and the
  1070  	// old files
  1071  	kbfsOps3 := config2Dev3.KBFSOps()
  1072  	err = kbfsOps3.SyncFromServer(
  1073  		ctx, rootNode2.GetFolderBranch(), nil)
  1074  	require.NoError(t, err)
  1075  	rootNode2Dev3 := GetRootNodeOrBust(ctx, t, config2Dev3, name, tlf.Private)
  1076  
  1077  	kbfsOps2Dev3 := config2Dev3.KBFSOps()
  1078  	aNode, _, err := kbfsOps2Dev3.Lookup(ctx, rootNode2Dev3, testPPS("a"))
  1079  	if err != nil {
  1080  		t.Fatalf("Device 3 couldn't lookup a: %+v", err)
  1081  	}
  1082  
  1083  	buf := []byte{0}
  1084  	_, err = kbfsOps2Dev3.Read(ctx, aNode, buf, 0)
  1085  	if err != nil {
  1086  		t.Fatalf("Device 3 couldn't read a: %+v", err)
  1087  	}
  1088  
  1089  	bNode, _, err := kbfsOps2Dev3.Lookup(ctx, rootNode2Dev3, testPPS("b"))
  1090  	if err != nil {
  1091  		t.Fatalf("Device 3 couldn't lookup b: %+v", err)
  1092  	}
  1093  
  1094  	_, err = kbfsOps2Dev3.Read(ctx, bNode, buf, 0)
  1095  	if err != nil {
  1096  		t.Fatalf("Device 3 couldn't read b: %+v", err)
  1097  	}
  1098  
  1099  	// Make sure the server-side keys for the revoked device are gone
  1100  	// for all keygens.
  1101  	rmd, err = config1.MDOps().GetForTLF(ctx, rootNode1.GetFolderBranch().Tlf, nil)
  1102  	if err != nil {
  1103  		t.Fatalf("Couldn't get latest md: %+v", err)
  1104  	}
  1105  	currKeyGen := rmd.LatestKeyGeneration()
  1106  	// clear the key cache
  1107  	config2.SetKeyCache(NewKeyCacheStandard(5000))
  1108  	km2, ok := config2.KeyManager().(*KeyManagerStandard)
  1109  	if !ok {
  1110  		t.Fatal("Wrong kind of key manager for config2")
  1111  	}
  1112  	for keyGen := kbfsmd.FirstValidKeyGen; keyGen <= currKeyGen; keyGen++ {
  1113  		_, err = km2.getTLFCryptKeyUsingCurrentDevice(ctx, rmd.ReadOnly(), keyGen, true)
  1114  		if err == nil {
  1115  			t.Errorf("User 2 could still fetch a key for keygen %d", keyGen)
  1116  		}
  1117  	}
  1118  }
  1119  
  1120  func testKeyManagerRekeyAddWriterAndReaderDevice(t *testing.T, ver kbfsmd.MetadataVer) {
  1121  	var u1, u2, u3 kbname.NormalizedUsername = "u1", "u2", "u3"
  1122  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2, u3)
  1123  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
  1124  
  1125  	config1.SetMetadataVersion(ver)
  1126  
  1127  	// Revoke user 3's device for now, to test the "other" rekey error.
  1128  	_, id3, err := config1.KBPKI().Resolve(
  1129  		ctx, u3.String(), keybase1.OfflineAvailability_NONE)
  1130  	if err != nil {
  1131  		t.Fatalf("Couldn't resolve u3: %+v", err)
  1132  	}
  1133  	uid3, err := id3.AsUser()
  1134  	require.NoError(t, err)
  1135  
  1136  	RevokeDeviceForLocalUserOrBust(t, config1, uid3, 0)
  1137  
  1138  	config2 := ConfigAsUser(config1, u2)
  1139  	defer CheckConfigAndShutdown(ctx, t, config2)
  1140  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
  1141  	if err != nil {
  1142  		t.Fatal(err)
  1143  	}
  1144  	uid2 := session2.UID
  1145  
  1146  	// Create a shared folder
  1147  	name := u1.String() + "," + u2.String() + tlf.ReaderSep + u3.String()
  1148  
  1149  	rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
  1150  
  1151  	kbfsOps1 := config1.KBFSOps()
  1152  
  1153  	// user 1 creates a file
  1154  	_, _, err = kbfsOps1.CreateFile(ctx, rootNode1, testPPS("a"), false, NoExcl)
  1155  	if err != nil {
  1156  		t.Fatalf("Couldn't create file: %+v", err)
  1157  	}
  1158  	err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
  1159  	if err != nil {
  1160  		t.Fatalf("Couldn't sync file: %+v", err)
  1161  	}
  1162  	err = kbfsOps1.SyncFromServer(ctx, rootNode1.GetFolderBranch(), nil)
  1163  	if err != nil {
  1164  		t.Fatalf("Couldn't sync from server: %+v", err)
  1165  	}
  1166  
  1167  	config2Dev2 := ConfigAsUser(config1, u2)
  1168  	defer CheckConfigAndShutdown(ctx, t, config2Dev2)
  1169  
  1170  	config3 := ConfigAsUser(config1, u3)
  1171  	defer CheckConfigAndShutdown(ctx, t, config3)
  1172  
  1173  	// Now give u2 and u3 new devices.  The configs don't share a
  1174  	// Keybase Daemon so we have to do it in all places.
  1175  	AddDeviceForLocalUserOrBust(t, config1, uid2)
  1176  	AddDeviceForLocalUserOrBust(t, config2, uid2)
  1177  	devIndex := AddDeviceForLocalUserOrBust(t, config2Dev2, uid2)
  1178  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
  1179  	AddDeviceForLocalUserOrBust(t, config1, uid3)
  1180  	AddDeviceForLocalUserOrBust(t, config2, uid3)
  1181  	devIndex = AddDeviceForLocalUserOrBust(t, config3, uid3)
  1182  	t.Logf("Switching to device %d", devIndex)
  1183  	SwitchDeviceForLocalUserOrBust(t, config3, devIndex)
  1184  
  1185  	// Users 2 and 3 should be unable to read the data now since its
  1186  	// device wasn't registered when the folder was originally
  1187  	// created.
  1188  	_, err = GetRootNodeForTest(ctx, config2Dev2, name, tlf.Private)
  1189  	if _, ok := err.(NeedSelfRekeyError); !ok {
  1190  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
  1191  	}
  1192  	_, err = GetRootNodeForTest(ctx, config3, name, tlf.Private)
  1193  	if _, ok := err.(NeedOtherRekeyError); !ok {
  1194  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
  1195  	}
  1196  
  1197  	// Set the KBPKI so we can count the identify calls
  1198  	countKBPKI := &identifyCountingKBPKI{
  1199  		KBPKI: config1.KBPKI(),
  1200  	}
  1201  	config1.SetKBPKI(countKBPKI)
  1202  	// Force the FBO to forget about its previous identify, so that we
  1203  	// can make sure the rekey doesn't trigger a full identify.
  1204  	kbfsOps1.(*KBFSOpsStandard).getOpsNoAdd(
  1205  		ctx, rootNode1.GetFolderBranch()).identifyDone = false
  1206  
  1207  	// now user 1 should rekey
  1208  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1209  		kbfsOps1, rootNode1.GetFolderBranch().Tlf)
  1210  	if err != nil {
  1211  		t.Fatalf("Couldn't rekey: %+v", err)
  1212  	}
  1213  
  1214  	// u2 and u3 should be identified as part of the rekey.
  1215  	if g, e := countKBPKI.getIdentifyCalls(), 2; g != e {
  1216  		t.Errorf("Expected %d identify calls, but got %d", e, g)
  1217  	}
  1218  
  1219  	// The new devices should be able to read now.
  1220  	_, err = GetRootNodeForTest(ctx, config2Dev2, name, tlf.Private)
  1221  	if err != nil {
  1222  		t.Fatalf("Got unexpected error after rekey: %+v", err)
  1223  	}
  1224  
  1225  	_ = GetRootNodeOrBust(ctx, t, config3, name, tlf.Private)
  1226  }
  1227  
  1228  func testKeyManagerSelfRekeyAcrossDevices(t *testing.T, ver kbfsmd.MetadataVer) {
  1229  	var u1, u2 kbname.NormalizedUsername = "u1", "u2"
  1230  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2)
  1231  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
  1232  
  1233  	config1.SetMetadataVersion(ver)
  1234  
  1235  	config2 := ConfigAsUser(config1, u2)
  1236  	defer CheckConfigAndShutdown(ctx, t, config2)
  1237  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
  1238  	if err != nil {
  1239  		t.Fatal(err)
  1240  	}
  1241  	uid2 := session2.UID
  1242  
  1243  	t.Log("Create a shared folder")
  1244  	name := u1.String() + "," + u2.String()
  1245  
  1246  	rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
  1247  
  1248  	kbfsOps1 := config1.KBFSOps()
  1249  
  1250  	t.Log("User 1 creates a file")
  1251  	_, _, err = kbfsOps1.CreateFile(ctx, rootNode1, testPPS("a"), false, NoExcl)
  1252  	if err != nil {
  1253  		t.Fatalf("Couldn't create file: %+v", err)
  1254  	}
  1255  	err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
  1256  	if err != nil {
  1257  		t.Fatalf("Couldn't sync file: %+v", err)
  1258  	}
  1259  
  1260  	t.Log("User 2 adds a device")
  1261  	// The configs don't share a Keybase Daemon so we have to do it in all
  1262  	// places.
  1263  	AddDeviceForLocalUserOrBust(t, config1, uid2)
  1264  	devIndex := AddDeviceForLocalUserOrBust(t, config2, uid2)
  1265  
  1266  	config2Dev2 := ConfigAsUser(config2, u2)
  1267  	defer CheckConfigAndShutdown(ctx, t, config2Dev2)
  1268  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
  1269  
  1270  	t.Log("Check that user 2 device 2 is unable to read the file")
  1271  	// user 2 device 2 should be unable to read the data now since its device
  1272  	// wasn't registered when the folder was originally created.
  1273  	_, err = GetRootNodeForTest(ctx, config2Dev2, name, tlf.Private)
  1274  	if _, ok := err.(NeedSelfRekeyError); !ok {
  1275  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
  1276  	}
  1277  
  1278  	t.Log("User 2 rekeys from device 1")
  1279  	root2dev1 := GetRootNodeOrBust(ctx, t, config2, name, tlf.Private)
  1280  
  1281  	kbfsOps2 := config2.KBFSOps()
  1282  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1283  		kbfsOps2, root2dev1.GetFolderBranch().Tlf)
  1284  	if err != nil {
  1285  		t.Fatalf("Couldn't rekey: %+v", err)
  1286  	}
  1287  
  1288  	t.Log("User 2 device 2 should be able to read now")
  1289  	root2dev2 := GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
  1290  
  1291  	t.Log("User 2 device 2 reads user 1's file")
  1292  	kbfsOps2Dev2 := config2Dev2.KBFSOps()
  1293  	children2, err := kbfsOps2Dev2.GetDirChildren(ctx, root2dev2)
  1294  	require.NoError(t, err)
  1295  	if _, ok := children2[root2dev2.ChildName("a")]; !ok {
  1296  		t.Fatalf("Device 2 couldn't see user 1's dir entry")
  1297  	}
  1298  
  1299  	t.Log("User 2 device 2 creates a file")
  1300  	_, _, err = kbfsOps2Dev2.CreateFile(
  1301  		ctx, root2dev2, testPPS("b"), false, NoExcl)
  1302  	if err != nil {
  1303  		t.Fatalf("Couldn't create file: %+v", err)
  1304  	}
  1305  	err = kbfsOps2Dev2.SyncAll(ctx, root2dev2.GetFolderBranch())
  1306  	if err != nil {
  1307  		t.Fatalf("Couldn't sync file: %+v", err)
  1308  	}
  1309  
  1310  	t.Log("User 1 syncs from the server")
  1311  	err = kbfsOps1.SyncFromServer(ctx,
  1312  		rootNode1.GetFolderBranch(), nil)
  1313  	if err != nil {
  1314  		t.Fatalf("Couldn't sync from server: %+v", err)
  1315  	}
  1316  
  1317  	t.Log("User 1 should be able to read the file that user 2 device 2 created")
  1318  	children1, err := kbfsOps1.GetDirChildren(ctx, rootNode1)
  1319  	require.NoError(t, err)
  1320  	if _, ok := children1[rootNode1.ChildName("b")]; !ok {
  1321  		t.Fatalf("Device 1 couldn't see the new dir entry")
  1322  	}
  1323  }
  1324  
  1325  func testKeyManagerReaderRekey(t *testing.T, ver kbfsmd.MetadataVer) {
  1326  	var u1, u2 kbname.NormalizedUsername = "u1", "u2"
  1327  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2)
  1328  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
  1329  	session1, err := config1.KBPKI().GetCurrentSession(ctx)
  1330  	require.NoError(t, err)
  1331  
  1332  	config1.SetMetadataVersion(ver)
  1333  
  1334  	config2 := ConfigAsUser(config1, u2)
  1335  	defer CheckConfigAndShutdown(ctx, t, config2)
  1336  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
  1337  	if err != nil {
  1338  		t.Fatal(err)
  1339  	}
  1340  	uid2 := session2.UID
  1341  
  1342  	t.Log("Create a shared folder")
  1343  	name := u1.String() + tlf.ReaderSep + u2.String()
  1344  
  1345  	rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
  1346  
  1347  	kbfsOps1 := config1.KBFSOps()
  1348  
  1349  	t.Log("User 1 creates a file")
  1350  	_, _, err = kbfsOps1.CreateFile(ctx, rootNode1, testPPS("a"), false, NoExcl)
  1351  	if err != nil {
  1352  		t.Fatalf("Couldn't create file: %+v", err)
  1353  	}
  1354  	err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
  1355  	if err != nil {
  1356  		t.Fatalf("Couldn't sync file: %+v", err)
  1357  	}
  1358  
  1359  	t.Log("User 1 adds a device")
  1360  	// The configs don't share a Keybase Daemon so we have to do it in all
  1361  	// places.
  1362  	AddDeviceForLocalUserOrBust(t, config1, session1.UID)
  1363  	devIndex := AddDeviceForLocalUserOrBust(t, config2, session1.UID)
  1364  
  1365  	config1Dev2 := ConfigAsUser(config2, u1)
  1366  	defer CheckConfigAndShutdown(ctx, t, config1Dev2)
  1367  	SwitchDeviceForLocalUserOrBust(t, config1Dev2, devIndex)
  1368  
  1369  	t.Log("User 2 adds a device")
  1370  	// The configs don't share a Keybase Daemon so we have to do it in all
  1371  	// places.
  1372  	AddDeviceForLocalUserOrBust(t, config1, uid2)
  1373  	AddDeviceForLocalUserOrBust(t, config1Dev2, uid2)
  1374  	devIndex = AddDeviceForLocalUserOrBust(t, config2, uid2)
  1375  
  1376  	config2Dev2 := ConfigAsUser(config2, u2)
  1377  	defer CheckConfigAndShutdown(ctx, t, config2Dev2)
  1378  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
  1379  
  1380  	t.Log("Check that user 2 device 2 is unable to read the file")
  1381  	// user 2 device 2 should be unable to read the data now since its device
  1382  	// wasn't registered when the folder was originally created.
  1383  	kbfsOps2Dev2 := config2Dev2.KBFSOps()
  1384  	_, err = GetRootNodeForTest(ctx, config2Dev2, name, tlf.Private)
  1385  	if _, ok := err.(NeedSelfRekeyError); !ok {
  1386  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
  1387  	}
  1388  
  1389  	t.Log("User 2 rekeys from device 1")
  1390  	root2dev1 := GetRootNodeOrBust(ctx, t, config2, name, tlf.Private)
  1391  
  1392  	kbfsOps2 := config2.KBFSOps()
  1393  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1394  		kbfsOps2, root2dev1.GetFolderBranch().Tlf)
  1395  	if err != nil {
  1396  		t.Fatalf("Expected reader rekey to partially complete. Actual error: %#v", err)
  1397  	}
  1398  
  1399  	t.Log("User 2 device 2 should be able to read now")
  1400  	root2dev2 := GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
  1401  
  1402  	t.Log("User 1 device 2 should still be unable to read")
  1403  	_, err = GetRootNodeForTest(ctx, config1Dev2, name, tlf.Private)
  1404  	if _, ok := err.(NeedSelfRekeyError); !ok {
  1405  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
  1406  	}
  1407  
  1408  	t.Log("User 2 device 2 reads user 1's file")
  1409  	children2, err := kbfsOps2Dev2.GetDirChildren(ctx, root2dev2)
  1410  	require.NoError(t, err)
  1411  	if _, ok := children2[root2dev2.ChildName("a")]; !ok {
  1412  		t.Fatalf("Device 2 couldn't see user 1's dir entry")
  1413  	}
  1414  }
  1415  
  1416  func testKeyManagerReaderRekeyAndRevoke(t *testing.T, ver kbfsmd.MetadataVer) {
  1417  	var u1, u2 kbname.NormalizedUsername = "u1", "u2"
  1418  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2)
  1419  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
  1420  	clock := clocktest.NewTestClockNow()
  1421  	config1.SetClock(clock)
  1422  
  1423  	config1.SetMetadataVersion(ver)
  1424  
  1425  	config2 := ConfigAsUser(config1, u2)
  1426  	defer CheckConfigAndShutdown(ctx, t, config2)
  1427  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
  1428  	if err != nil {
  1429  		t.Fatal(err)
  1430  	}
  1431  	uid2 := session2.UID
  1432  
  1433  	// The reader has a second device at the start.
  1434  	AddDeviceForLocalUserOrBust(t, config1, uid2)
  1435  	devIndex := AddDeviceForLocalUserOrBust(t, config2, uid2)
  1436  	config2Dev2 := ConfigAsUser(config2, u2)
  1437  	defer CheckConfigAndShutdown(ctx, t, config2Dev2)
  1438  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
  1439  
  1440  	t.Log("Create a shared folder")
  1441  	name := u1.String() + tlf.ReaderSep + u2.String()
  1442  
  1443  	rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
  1444  
  1445  	kbfsOps1 := config1.KBFSOps()
  1446  
  1447  	t.Log("User 1 creates a file")
  1448  	_, _, err = kbfsOps1.CreateFile(ctx, rootNode1, testPPS("a"), false, NoExcl)
  1449  	if err != nil {
  1450  		t.Fatalf("Couldn't create file: %+v", err)
  1451  	}
  1452  	err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
  1453  	if err != nil {
  1454  		t.Fatalf("Couldn't sync file: %+v", err)
  1455  	}
  1456  
  1457  	t.Log("User 2 adds a device")
  1458  	// The configs don't share a Keybase Daemon so we have to do it in all
  1459  	// places.
  1460  	AddDeviceForLocalUserOrBust(t, config1, uid2)
  1461  	AddDeviceForLocalUserOrBust(t, config2, uid2)
  1462  	devIndex = AddDeviceForLocalUserOrBust(t, config2Dev2, uid2)
  1463  	config2Dev3 := ConfigAsUser(config2, u2)
  1464  	defer CheckConfigAndShutdown(ctx, t, config2Dev3)
  1465  	SwitchDeviceForLocalUserOrBust(t, config2Dev3, devIndex)
  1466  
  1467  	// Revoke the original user 2 device
  1468  	clock.Add(1 * time.Minute)
  1469  	RevokeDeviceForLocalUserOrBust(t, config1, uid2, 0)
  1470  	RevokeDeviceForLocalUserOrBust(t, config2Dev2, uid2, 0)
  1471  	RevokeDeviceForLocalUserOrBust(t, config2Dev3, uid2, 0)
  1472  
  1473  	t.Log("Check that user 2 device 3 is unable to read the file")
  1474  	// user 2 device 3 should be unable to read the data now since its device
  1475  	// wasn't registered when the folder was originally created.
  1476  	_, err = GetRootNodeForTest(ctx, config2Dev3, name, tlf.Private)
  1477  	if _, ok := err.(NeedSelfRekeyError); !ok {
  1478  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
  1479  	}
  1480  
  1481  	t.Log("User 2 rekeys from device 2")
  1482  	root2Dev2 := GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
  1483  	kbfsOps2Dev2 := config2Dev2.KBFSOps()
  1484  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1485  		kbfsOps2Dev2, root2Dev2.GetFolderBranch().Tlf)
  1486  	if err != nil {
  1487  		t.Fatalf("Expected reader rekey to partially complete. "+
  1488  			"Actual error: %#v", err)
  1489  	}
  1490  
  1491  	t.Log("User 2 device 3 should be able to read now")
  1492  	GetRootNodeOrBust(ctx, t, config2Dev3, name, tlf.Private)
  1493  
  1494  	// A second rekey by the same reader shouldn't change the
  1495  	// revision, since the rekey bit is already set, even though a
  1496  	// rekey is still needed (due to the revoke, which has to be
  1497  	// rekeyed by a writer).
  1498  	ops := getOps(config2Dev2, root2Dev2.GetFolderBranch().Tlf)
  1499  	rev1 := ops.head.Revision()
  1500  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1501  		kbfsOps2Dev2, root2Dev2.GetFolderBranch().Tlf)
  1502  	if err != nil {
  1503  		t.Fatalf("Expected reader rekey to partially complete. "+
  1504  			"Actual error: %#v", err)
  1505  	}
  1506  	rev2 := ops.head.Revision()
  1507  	if rev1 != rev2 {
  1508  		t.Fatalf("Reader rekey made two incomplete rekeys in a row.")
  1509  	}
  1510  }
  1511  
  1512  func keyManagerTestSimulateSelfRekeyBit(
  1513  	ctx context.Context, t *testing.T, config Config, tlfID tlf.ID) {
  1514  	// Simulate the mdserver sending back this node's own rekey
  1515  	// request.  This shouldn't increase the MD version.  Since this
  1516  	// doesn't kick off a rekey request, we don't need to wait for the
  1517  	// whole rekey to finish; we just wait for the event to be
  1518  	// processed.
  1519  	rekeyWaiter := make(chan struct{})
  1520  	ops := getOps(config, tlfID)
  1521  	rev1 := ops.head.Revision()
  1522  	ops.rekeyFSM.listenOnEvent(rekeyRequestEvent, func(e RekeyEvent) {
  1523  		close(rekeyWaiter)
  1524  	}, false)
  1525  	ops.rekeyFSM.Event(newRekeyRequestEventWithContext(ctx))
  1526  	<-rekeyWaiter
  1527  	rev2 := ops.head.Revision()
  1528  
  1529  	if rev1 != rev2 {
  1530  		t.Errorf("Revision changed after second rekey: %v vs %v", rev1, rev2)
  1531  	}
  1532  
  1533  	// Make sure just the rekey bit is set
  1534  	if !ops.head.IsRekeySet() {
  1535  		t.Fatalf("Couldn't set rekey bit")
  1536  	}
  1537  }
  1538  
  1539  // This tests 2 variations of the situation where clients w/o the folder key set the rekey bit.
  1540  // In one case the client is a writer and in the other a reader. They both blindly copy the existing
  1541  // metadata and simply set the rekey bit. Then another participant rekeys the folder and they try to read.
  1542  
  1543  func testKeyManagerRekeyBit(t *testing.T, ver kbfsmd.MetadataVer) {
  1544  	var u1, u2, u3 kbname.NormalizedUsername = "u1", "u2", "u3"
  1545  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2, u3)
  1546  	doShutdown1 := true
  1547  	defer func() {
  1548  		if doShutdown1 {
  1549  			kbfsConcurTestShutdown(ctx, t, config1, cancel)
  1550  		}
  1551  	}()
  1552  
  1553  	config1.SetMetadataVersion(ver)
  1554  
  1555  	config2 := ConfigAsUser(config1, u2)
  1556  	defer CheckConfigAndShutdown(ctx, t, config2)
  1557  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
  1558  	if err != nil {
  1559  		t.Fatal(err)
  1560  	}
  1561  	uid2 := session2.UID
  1562  
  1563  	config2.MDServer().DisableRekeyUpdatesForTesting()
  1564  
  1565  	config3 := ConfigAsUser(config1, u3)
  1566  	defer CheckConfigAndShutdown(ctx, t, config3)
  1567  	session3, err := config3.KBPKI().GetCurrentSession(ctx)
  1568  	if err != nil {
  1569  		t.Fatal(err)
  1570  	}
  1571  	uid3 := session3.UID
  1572  
  1573  	config3.MDServer().DisableRekeyUpdatesForTesting()
  1574  
  1575  	// 2 writers 1 reader
  1576  	name := u1.String() + "," + u2.String() + "#" + u3.String()
  1577  
  1578  	rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
  1579  
  1580  	kbfsOps1 := config1.KBFSOps()
  1581  
  1582  	// user 1 creates a file
  1583  	_, _, err = kbfsOps1.CreateFile(ctx, rootNode1, testPPS("a"), false, NoExcl)
  1584  	if err != nil {
  1585  		t.Fatalf("Couldn't create file: %+v", err)
  1586  	}
  1587  	err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
  1588  	if err != nil {
  1589  		t.Fatalf("Couldn't sync file: %+v", err)
  1590  	}
  1591  
  1592  	config2Dev2 := ConfigAsUser(config1, u2)
  1593  	// we don't check the config because this device can't read all of the md blocks.
  1594  	defer func() { _ = config2Dev2.Shutdown(ctx) }()
  1595  	config2Dev2.MDServer().DisableRekeyUpdatesForTesting()
  1596  
  1597  	// Now give u2 a new device.  The configs don't share a Keybase
  1598  	// Daemon so we have to do it in all places.
  1599  	AddDeviceForLocalUserOrBust(t, config1, uid2)
  1600  	AddDeviceForLocalUserOrBust(t, config2, uid2)
  1601  	AddDeviceForLocalUserOrBust(t, config3, uid2)
  1602  	devIndex := AddDeviceForLocalUserOrBust(t, config2Dev2, uid2)
  1603  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
  1604  
  1605  	// user 2 should be unable to read the data now since its device
  1606  	// wasn't registered when the folder was originally created.
  1607  	_, err = GetRootNodeForTest(ctx, config2Dev2, name, tlf.Private)
  1608  	if _, ok := err.(NeedSelfRekeyError); !ok {
  1609  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
  1610  	}
  1611  
  1612  	// now user 2 should set the rekey bit
  1613  	kbfsOps2Dev2 := config2Dev2.KBFSOps()
  1614  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1615  		kbfsOps2Dev2, rootNode1.GetFolderBranch().Tlf)
  1616  	if err != nil {
  1617  		t.Fatalf("Couldn't rekey: %+v", err)
  1618  	}
  1619  
  1620  	// Do it again, to simulate the mdserver sending back this node's
  1621  	// own rekey request.
  1622  	keyManagerTestSimulateSelfRekeyBit(
  1623  		ctx, t, config2Dev2, rootNode1.GetFolderBranch().Tlf)
  1624  
  1625  	// user 1 syncs from server
  1626  	err = kbfsOps1.SyncFromServer(ctx,
  1627  		rootNode1.GetFolderBranch(), nil)
  1628  	if err != nil {
  1629  		t.Fatalf("Couldn't sync from server: %+v", err)
  1630  	}
  1631  
  1632  	// user 1 should try to rekey
  1633  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1634  		kbfsOps1, rootNode1.GetFolderBranch().Tlf)
  1635  	if err != nil {
  1636  		t.Fatalf("Couldn't rekey: %+v", err)
  1637  	}
  1638  
  1639  	// user 2 syncs from server
  1640  	err = kbfsOps2Dev2.SyncFromServer(ctx,
  1641  		rootNode1.GetFolderBranch(), nil)
  1642  	if err != nil {
  1643  		t.Fatalf("Couldn't sync from server: %+v", err)
  1644  	}
  1645  
  1646  	// this device should be able to read now
  1647  	rootNode2Dev2 := GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
  1648  
  1649  	// look for the file
  1650  	aNode, _, err := kbfsOps2Dev2.Lookup(ctx, rootNode2Dev2, testPPS("a"))
  1651  	if err != nil {
  1652  		t.Fatalf("Device 2 couldn't lookup a: %+v", err)
  1653  	}
  1654  
  1655  	// read it
  1656  	buf := []byte{0}
  1657  	_, err = kbfsOps2Dev2.Read(ctx, aNode, buf, 0)
  1658  	if err != nil {
  1659  		t.Fatalf("Device 2 couldn't read a: %+v", err)
  1660  	}
  1661  
  1662  	config3Dev2 := ConfigAsUser(config1, u3)
  1663  	// we don't check the config because this device can't read all of the md blocks.
  1664  	defer func() { _ = config3Dev2.Shutdown(ctx) }()
  1665  	config3Dev2.MDServer().DisableRekeyUpdatesForTesting()
  1666  
  1667  	// Now give u3 a new device.
  1668  	AddDeviceForLocalUserOrBust(t, config1, uid3)
  1669  	AddDeviceForLocalUserOrBust(t, config2, uid3)
  1670  	AddDeviceForLocalUserOrBust(t, config2Dev2, uid3)
  1671  	AddDeviceForLocalUserOrBust(t, config3, uid3)
  1672  	devIndex = AddDeviceForLocalUserOrBust(t, config3Dev2, uid3)
  1673  	SwitchDeviceForLocalUserOrBust(t, config3Dev2, devIndex)
  1674  
  1675  	// user 3 dev 2 should be unable to read the data now since its device
  1676  	// wasn't registered when the folder was originally created.
  1677  	_, err = GetRootNodeForTest(ctx, config3Dev2, name, tlf.Private)
  1678  	if _, ok := err.(NeedSelfRekeyError); !ok {
  1679  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
  1680  	}
  1681  
  1682  	// now user 3 dev 2 should set the rekey bit
  1683  	kbfsOps3Dev2 := config3Dev2.KBFSOps()
  1684  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1685  		kbfsOps3Dev2, rootNode1.GetFolderBranch().Tlf)
  1686  	if err != nil {
  1687  		t.Fatalf("Couldn't rekey: %+v", err)
  1688  	}
  1689  
  1690  	// user 2 dev 2 syncs from server
  1691  	err = kbfsOps2Dev2.SyncFromServer(ctx,
  1692  		rootNode1.GetFolderBranch(), nil)
  1693  	if err != nil {
  1694  		t.Fatalf("Couldn't sync from server: %+v", err)
  1695  	}
  1696  
  1697  	// user 2 dev 2 should try to rekey
  1698  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1699  		kbfsOps2Dev2, rootNode1.GetFolderBranch().Tlf)
  1700  	if err != nil {
  1701  		t.Fatalf("Couldn't rekey: %+v", err)
  1702  	}
  1703  
  1704  	// user 3 dev 2 syncs from server
  1705  	err = kbfsOps3Dev2.SyncFromServer(ctx,
  1706  		rootNode1.GetFolderBranch(), nil)
  1707  	if err != nil {
  1708  		t.Fatalf("Couldn't sync from server: %+v", err)
  1709  	}
  1710  
  1711  	// this device should be able to read now
  1712  	rootNode3Dev2 := GetRootNodeOrBust(ctx, t, config3Dev2, name, tlf.Private)
  1713  
  1714  	// look for the file
  1715  	a2Node, _, err := kbfsOps3Dev2.Lookup(ctx, rootNode3Dev2, testPPS("a"))
  1716  	if err != nil {
  1717  		t.Fatalf("Device 3 couldn't lookup a: %+v", err)
  1718  	}
  1719  
  1720  	// read it
  1721  	buf = []byte{0}
  1722  	_, err = kbfsOps3Dev2.Read(ctx, a2Node, buf, 0)
  1723  	if err != nil {
  1724  		t.Fatalf("Device 3 couldn't read a: %+v", err)
  1725  	}
  1726  
  1727  	// Explicitly run the checks with config1 before the deferred shutdowns begin.
  1728  	// This way the shared mdserver hasn't been shutdown.
  1729  	kbfsConcurTestShutdown(ctx, t, config1, cancel)
  1730  	doShutdown1 = false
  1731  }
  1732  
  1733  // Two devices conflict when revoking a 3rd device.
  1734  // Test that after this both can still read the latest version of the folder.
  1735  
  1736  func testKeyManagerRekeyAddAndRevokeDeviceWithConflict(t *testing.T, ver kbfsmd.MetadataVer) {
  1737  	var u1, u2 kbname.NormalizedUsername = "u1", "u2"
  1738  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2)
  1739  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
  1740  	clock := clocktest.NewTestClockNow()
  1741  	config1.SetClock(clock)
  1742  
  1743  	config1.SetMetadataVersion(ver)
  1744  
  1745  	config2 := ConfigAsUser(config1, u2)
  1746  	defer CheckConfigAndShutdown(ctx, t, config2)
  1747  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
  1748  	if err != nil {
  1749  		t.Fatal(err)
  1750  	}
  1751  	uid2 := session2.UID
  1752  
  1753  	// create a shared folder
  1754  	name := u1.String() + "," + u2.String()
  1755  
  1756  	rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
  1757  
  1758  	kbfsOps1 := config1.KBFSOps()
  1759  
  1760  	// user 1 creates a file
  1761  	_, _, err = kbfsOps1.CreateFile(ctx, rootNode1, testPPS("a"), false, NoExcl)
  1762  	if err != nil {
  1763  		t.Fatalf("Couldn't create file: %+v", err)
  1764  	}
  1765  	err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
  1766  	if err != nil {
  1767  		t.Fatalf("Couldn't sync file: %+v", err)
  1768  	}
  1769  
  1770  	config2Dev2 := ConfigAsUser(config1, u2)
  1771  	defer CheckConfigAndShutdown(ctx, t, config2Dev2)
  1772  
  1773  	// give user 2 a new device
  1774  	AddDeviceForLocalUserOrBust(t, config1, uid2)
  1775  	AddDeviceForLocalUserOrBust(t, config2, uid2)
  1776  	devIndex := AddDeviceForLocalUserOrBust(t, config2Dev2, uid2)
  1777  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
  1778  
  1779  	// user 2 should be unable to read the data now since its device
  1780  	// wasn't registered when the folder was originally created.
  1781  	kbfsOps2Dev2 := config2Dev2.KBFSOps()
  1782  	_, err = GetRootNodeForTest(ctx, config2Dev2, name, tlf.Private)
  1783  	if _, ok := err.(NeedSelfRekeyError); !ok {
  1784  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
  1785  	}
  1786  
  1787  	// now user 1 should rekey
  1788  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1789  		kbfsOps1, rootNode1.GetFolderBranch().Tlf)
  1790  	if err != nil {
  1791  		t.Fatalf("Couldn't rekey: %+v", err)
  1792  	}
  1793  
  1794  	// this device should be able to read now
  1795  	root2Dev2 := GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
  1796  
  1797  	// Now revoke the original user 2 device
  1798  	clock.Add(1 * time.Minute)
  1799  	RevokeDeviceForLocalUserOrBust(t, config1, uid2, 0)
  1800  	RevokeDeviceForLocalUserOrBust(t, config2Dev2, uid2, 0)
  1801  
  1802  	// Stall user 1's rekey, to ensure a conflict.
  1803  	onPutStalledCh, putUnstallCh, putCtx :=
  1804  		StallMDOp(ctx, config1, StallableMDPut, 1)
  1805  
  1806  	// Have user 1 also try to rekey but fail due to conflict
  1807  	errChan := make(chan error, 1)
  1808  	go func() {
  1809  		_, err := RequestRekeyAndWaitForOneFinishEvent(putCtx, kbfsOps1, rootNode1.GetFolderBranch().Tlf)
  1810  		errChan <- err
  1811  	}()
  1812  	select {
  1813  	case <-ctx.Done():
  1814  		t.Fatal(ctx.Err())
  1815  	case <-onPutStalledCh:
  1816  	}
  1817  
  1818  	// rekey again but with user 2 device 2
  1819  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1820  		kbfsOps2Dev2, root2Dev2.GetFolderBranch().Tlf)
  1821  	if err != nil {
  1822  		t.Fatalf("Couldn't rekey: %+v", err)
  1823  	}
  1824  
  1825  	// Make sure user 1's rekey failed.
  1826  	select {
  1827  	case <-ctx.Done():
  1828  		t.Fatal(ctx.Err())
  1829  	case putUnstallCh <- struct{}{}:
  1830  	}
  1831  	select {
  1832  	case <-ctx.Done():
  1833  		t.Fatal(ctx.Err())
  1834  	case err = <-errChan:
  1835  	}
  1836  	if _, isConflict := err.(RekeyConflictError); !isConflict {
  1837  		t.Fatalf("Expected failure due to conflict")
  1838  	}
  1839  
  1840  	err = kbfsOps2Dev2.SyncFromServer(ctx,
  1841  		root2Dev2.GetFolderBranch(), nil)
  1842  	if err != nil {
  1843  		t.Fatalf("Couldn't sync from server: %+v", err)
  1844  	}
  1845  
  1846  	// force re-encryption of the root dir
  1847  	_, _, err = kbfsOps2Dev2.CreateFile(
  1848  		ctx, root2Dev2, testPPS("b"), false, NoExcl)
  1849  	if err != nil {
  1850  		t.Fatalf("Couldn't create file: %+v", err)
  1851  	}
  1852  	err = kbfsOps2Dev2.SyncAll(ctx, root2Dev2.GetFolderBranch())
  1853  	if err != nil {
  1854  		t.Fatalf("Couldn't sync file: %+v", err)
  1855  	}
  1856  
  1857  	// device 1 should still work
  1858  	err = kbfsOps1.SyncFromServer(ctx,
  1859  		rootNode1.GetFolderBranch(), nil)
  1860  	if err != nil {
  1861  		t.Fatalf("Couldn't sync from server: %+v", err)
  1862  	}
  1863  
  1864  	rootNode1 = GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
  1865  
  1866  	children, err := kbfsOps1.GetDirChildren(ctx, rootNode1)
  1867  	require.NoError(t, err)
  1868  	if _, ok := children[rootNode1.ChildName("b")]; !ok {
  1869  		t.Fatalf("Device 1 couldn't see the new dir entry")
  1870  	}
  1871  }
  1872  
  1873  // cryptoLocalTrapAny traps every DecryptTLFCryptKeyClientHalfAny
  1874  // call, and closes the given channel the first time it receives one
  1875  // with promptPaper set to true.
  1876  type cryptoLocalTrapAny struct {
  1877  	Crypto
  1878  	promptPaperChOnce sync.Once
  1879  	promptPaperCh     chan<- struct{}
  1880  	cryptoToUse       Crypto
  1881  }
  1882  
  1883  func (clta *cryptoLocalTrapAny) DecryptTLFCryptKeyClientHalfAny(
  1884  	ctx context.Context,
  1885  	keys []EncryptedTLFCryptKeyClientAndEphemeral, promptPaper bool) (
  1886  	kbfscrypto.TLFCryptKeyClientHalf, int, error) {
  1887  	if promptPaper {
  1888  		clta.promptPaperChOnce.Do(func() {
  1889  			close(clta.promptPaperCh)
  1890  		})
  1891  	}
  1892  	return clta.cryptoToUse.DecryptTLFCryptKeyClientHalfAny(
  1893  		ctx, keys, promptPaper)
  1894  }
  1895  
  1896  func testKeyManagerRekeyAddDeviceWithPrompt(t *testing.T, ver kbfsmd.MetadataVer) {
  1897  	var u1, u2 kbname.NormalizedUsername = "u1", "u2"
  1898  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2)
  1899  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
  1900  
  1901  	config1.SetMetadataVersion(ver)
  1902  
  1903  	config2 := ConfigAsUser(config1, u2)
  1904  	defer CheckConfigAndShutdown(ctx, t, config2)
  1905  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
  1906  	if err != nil {
  1907  		t.Fatal(err)
  1908  	}
  1909  	uid2 := session2.UID
  1910  
  1911  	// Create a shared folder
  1912  	name := u1.String() + "," + u2.String()
  1913  
  1914  	rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
  1915  
  1916  	kbfsOps1 := config1.KBFSOps()
  1917  
  1918  	// user 1 creates a file
  1919  	_, _, err = kbfsOps1.CreateFile(ctx, rootNode1, testPPS("a"), false, NoExcl)
  1920  	if err != nil {
  1921  		t.Fatalf("Couldn't create file: %+v", err)
  1922  	}
  1923  	err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
  1924  	if err != nil {
  1925  		t.Fatalf("Couldn't sync file: %+v", err)
  1926  	}
  1927  
  1928  	config2Dev2 := ConfigAsUser(config1, u2)
  1929  	defer CheckConfigAndShutdown(ctx, t, config2Dev2)
  1930  
  1931  	config2Dev2.SetKeyCache(&dummyNoKeyCache{})
  1932  
  1933  	// Now give u2 a new device.  The configs don't share a Keybase
  1934  	// Daemon so we have to do it in all places.
  1935  	AddDeviceForLocalUserOrBust(t, config1, uid2)
  1936  	AddDeviceForLocalUserOrBust(t, config2, uid2)
  1937  	devIndex := AddDeviceForLocalUserOrBust(t, config2Dev2, uid2)
  1938  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
  1939  
  1940  	t.Log("Doing first rekey")
  1941  
  1942  	// The new device should be unable to rekey on its own, and will
  1943  	// just set the rekey bit.
  1944  	kbfsOps2Dev2 := config2Dev2.KBFSOps()
  1945  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  1946  		kbfsOps2Dev2, rootNode1.GetFolderBranch().Tlf)
  1947  	if err != nil {
  1948  		t.Fatalf("First rekey failed %+v", err)
  1949  	}
  1950  
  1951  	t.Log("Doing second rekey")
  1952  
  1953  	// Do it again, to simulate the mdserver sending back this node's
  1954  	// own rekey request.
  1955  	keyManagerTestSimulateSelfRekeyBit(
  1956  		ctx, t, config2Dev2, rootNode1.GetFolderBranch().Tlf)
  1957  
  1958  	t.Log("Switching crypto")
  1959  
  1960  	c := make(chan struct{}, 1)
  1961  	// Use our other device as a standin for the paper key.
  1962  	clta := &cryptoLocalTrapAny{config2Dev2.Crypto(), sync.Once{}, c, config2.Crypto()}
  1963  	config2Dev2.SetCrypto(clta)
  1964  
  1965  	ops := getOps(config2Dev2, rootNode1.GetFolderBranch().Tlf)
  1966  	ops.rekeyFSM.Event(newRekeyKickoffEvent())
  1967  	select {
  1968  	case <-c:
  1969  	case <-ctx.Done():
  1970  		t.Fatal(ctx.Err())
  1971  	}
  1972  
  1973  	// Take the mdWriterLock to ensure that the rekeyWithPrompt finishes.
  1974  	lState := makeFBOLockState()
  1975  	ops.mdWriterLock.Lock(lState)
  1976  	ops.mdWriterLock.Unlock(lState)
  1977  
  1978  	config2Dev2.SetCrypto(clta.Crypto)
  1979  
  1980  	rootNode2Dev2 := GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
  1981  
  1982  	kbfsOps2 := config2Dev2.KBFSOps()
  1983  	children, err := kbfsOps2.GetDirChildren(ctx, rootNode2Dev2)
  1984  	require.NoError(t, err)
  1985  	if _, ok := children[rootNode2Dev2.ChildName("a")]; !ok {
  1986  		t.Fatalf("Device 2 couldn't see the dir entry after rekey")
  1987  	}
  1988  	// user 2 creates another file to make a new revision
  1989  	_, _, err = kbfsOps2.CreateFile(
  1990  		ctx, rootNode2Dev2, testPPS("b"), false, NoExcl)
  1991  	if err != nil {
  1992  		t.Fatalf("Couldn't create file: %+v", err)
  1993  	}
  1994  	err = kbfsOps2.SyncAll(ctx, rootNode2Dev2.GetFolderBranch())
  1995  	if err != nil {
  1996  		t.Fatalf("Couldn't sync file: %+v", err)
  1997  	}
  1998  
  1999  	// device 1 should be able to read the new file
  2000  	err = kbfsOps1.SyncFromServer(ctx,
  2001  		rootNode1.GetFolderBranch(), nil)
  2002  	if err != nil {
  2003  		t.Fatalf("Couldn't sync from server: %+v", err)
  2004  	}
  2005  	children, err = kbfsOps1.GetDirChildren(ctx, rootNode1)
  2006  	require.NoError(t, err)
  2007  	if _, ok := children[rootNode1.ChildName("b")]; !ok {
  2008  		t.Fatalf("Device 2 couldn't see the dir entry after rekey")
  2009  	}
  2010  }
  2011  
  2012  func testKeyManagerRekeyAddDeviceWithPromptAfterRestart(t *testing.T, ver kbfsmd.MetadataVer) {
  2013  	var u1, u2 kbname.NormalizedUsername = "u1", "u2"
  2014  	config1, uid1, ctx, cancel := kbfsOpsConcurInit(t, u1, u2)
  2015  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
  2016  	clock := clocktest.NewTestClockNow()
  2017  	config1.SetClock(clock)
  2018  
  2019  	config1.SetMetadataVersion(ver)
  2020  
  2021  	config2 := ConfigAsUser(config1, u2)
  2022  	defer CheckConfigAndShutdown(ctx, t, config2)
  2023  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
  2024  	if err != nil {
  2025  		t.Fatal(err)
  2026  	}
  2027  	uid2 := session2.UID
  2028  
  2029  	// Create a shared folder
  2030  	name := u1.String() + "," + u2.String()
  2031  
  2032  	rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
  2033  
  2034  	kbfsOps1 := config1.KBFSOps()
  2035  
  2036  	// user 1 creates a file
  2037  	_, _, err = kbfsOps1.CreateFile(ctx, rootNode1, testPPS("a"), false, NoExcl)
  2038  	if err != nil {
  2039  		t.Fatalf("Couldn't create file: %+v", err)
  2040  	}
  2041  	err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
  2042  	if err != nil {
  2043  		t.Fatalf("Couldn't sync file: %+v", err)
  2044  	}
  2045  
  2046  	config2Dev2 := ConfigAsUser(config1, u2)
  2047  	defer CheckConfigAndShutdown(ctx, t, config2Dev2)
  2048  
  2049  	config2Dev2.SetKeyCache(&dummyNoKeyCache{})
  2050  
  2051  	// Now give u2 a new device.  The configs don't share a Keybase
  2052  	// Daemon so we have to do it in all places.
  2053  	AddDeviceForLocalUserOrBust(t, config1, uid2)
  2054  	AddDeviceForLocalUserOrBust(t, config2, uid2)
  2055  	devIndex := AddDeviceForLocalUserOrBust(t, config2Dev2, uid2)
  2056  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
  2057  	// Revoke some previous device
  2058  	clock.Add(1 * time.Minute)
  2059  	RevokeDeviceForLocalUserOrBust(t, config2Dev2, uid1, 0)
  2060  
  2061  	SetGlobalMerkleRootForTestOrBust(
  2062  		t, config2Dev2, keybase1.MerkleRootV2{}, clock.Now())
  2063  	SetKbfsMerkleRootForTestOrBust(
  2064  		t, config2Dev2, keybase1.MerkleTreeID_KBFS_PRIVATE, &kbfsmd.MerkleRoot{
  2065  			Timestamp: clock.Now().Unix(),
  2066  		})
  2067  
  2068  	t.Log("Doing first rekey")
  2069  
  2070  	// The new device should be unable to rekey on its own, and will
  2071  	// just set the rekey bit.
  2072  	kbfsOps2Dev2 := config2Dev2.KBFSOps()
  2073  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  2074  		kbfsOps2Dev2, rootNode1.GetFolderBranch().Tlf)
  2075  	if err != nil {
  2076  		t.Fatalf("First rekey failed %+v", err)
  2077  	}
  2078  
  2079  	t.Log("Doing second rekey")
  2080  
  2081  	// Do it again, to simulate the mdserver sending back this node's
  2082  	// own rekey request.
  2083  	keyManagerTestSimulateSelfRekeyBit(
  2084  		ctx, t, config2Dev2, rootNode1.GetFolderBranch().Tlf)
  2085  
  2086  	// Simulate a restart after the rekey bit was set
  2087  	ops := getOps(config2Dev2, rootNode1.GetFolderBranch().Tlf)
  2088  	ops.rekeyFSM.Event(newRekeyCancelEventForTest())
  2089  
  2090  	t.Log("Doing third rekey")
  2091  
  2092  	// Try again, which should reset the timer (and so the Reset below
  2093  	// will be on a non-nil timer).
  2094  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  2095  		kbfsOps2Dev2, rootNode1.GetFolderBranch().Tlf)
  2096  	if err != nil {
  2097  		t.Fatalf("Third rekey failed %+v", err)
  2098  	}
  2099  
  2100  	t.Log("Switching crypto")
  2101  
  2102  	c := make(chan struct{}, 1)
  2103  	// Use our other device as a standin for the paper key.
  2104  	clta := &cryptoLocalTrapAny{config2Dev2.Crypto(), sync.Once{}, c, config2.Crypto()}
  2105  	config2Dev2.SetCrypto(clta)
  2106  
  2107  	ops.rekeyFSM.Event(newRekeyKickoffEvent())
  2108  	select {
  2109  	case <-c:
  2110  	case <-ctx.Done():
  2111  		t.Fatal(ctx.Err())
  2112  	}
  2113  
  2114  	// Take the mdWriterLock to ensure that the rekeyWithPrompt finishes.
  2115  	lState := makeFBOLockState()
  2116  	ops.mdWriterLock.Lock(lState)
  2117  	ops.mdWriterLock.Unlock(lState)
  2118  
  2119  	config2Dev2.SetCrypto(clta.Crypto)
  2120  
  2121  	rootNode2Dev2 := GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
  2122  
  2123  	kbfsOps2 := config2Dev2.KBFSOps()
  2124  	children, err := kbfsOps2.GetDirChildren(ctx, rootNode2Dev2)
  2125  	require.NoError(t, err)
  2126  	if _, ok := children[rootNode2Dev2.ChildName("a")]; !ok {
  2127  		t.Fatalf("Device 2 couldn't see the dir entry after rekey")
  2128  	}
  2129  	// user 2 creates another file to make a new revision
  2130  	_, _, err = kbfsOps2.CreateFile(
  2131  		ctx, rootNode2Dev2, testPPS("b"), false, NoExcl)
  2132  	if err != nil {
  2133  		t.Fatalf("Couldn't create file: %+v", err)
  2134  	}
  2135  	err = kbfsOps2.SyncAll(ctx, rootNode2Dev2.GetFolderBranch())
  2136  	if err != nil {
  2137  		t.Fatalf("Couldn't sync file: %+v", err)
  2138  	}
  2139  }
  2140  
  2141  func testKeyManagerRekeyAddDeviceWithPromptViaFolderAccess(t *testing.T, ver kbfsmd.MetadataVer) {
  2142  	var u1, u2 kbname.NormalizedUsername = "u1", "u2"
  2143  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2)
  2144  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
  2145  
  2146  	config1.SetMetadataVersion(ver)
  2147  
  2148  	config2 := ConfigAsUser(config1, u2)
  2149  	defer CheckConfigAndShutdown(ctx, t, config2)
  2150  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
  2151  	if err != nil {
  2152  		t.Fatal(err)
  2153  	}
  2154  	uid2 := session2.UID
  2155  
  2156  	// Create a shared folder
  2157  	name := u1.String() + "," + u2.String()
  2158  
  2159  	rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
  2160  	config2Dev2 := ConfigAsUser(config1, u2)
  2161  	defer CheckConfigAndShutdown(ctx, t, config2Dev2)
  2162  
  2163  	config2Dev2.SetKeyCache(&dummyNoKeyCache{})
  2164  
  2165  	// Now give u2 a new device.  The configs don't share a Keybase
  2166  	// Daemon so we have to do it in all places.
  2167  	AddDeviceForLocalUserOrBust(t, config1, uid2)
  2168  	AddDeviceForLocalUserOrBust(t, config2, uid2)
  2169  	devIndex := AddDeviceForLocalUserOrBust(t, config2Dev2, uid2)
  2170  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
  2171  
  2172  	t.Log("Doing first rekey")
  2173  
  2174  	// The new device should be unable to rekey on its own, and will
  2175  	// just set the rekey bit.
  2176  	kbfsOps2Dev2 := config2Dev2.KBFSOps()
  2177  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  2178  		kbfsOps2Dev2, rootNode1.GetFolderBranch().Tlf)
  2179  	if err != nil {
  2180  		t.Fatalf("First rekey failed %+v", err)
  2181  	}
  2182  
  2183  	ops := getOps(config2Dev2, rootNode1.GetFolderBranch().Tlf)
  2184  
  2185  	// Make sure just the rekey bit is set
  2186  	if !ops.head.IsRekeySet() {
  2187  		t.Fatalf("Couldn't set rekey bit")
  2188  	}
  2189  
  2190  	t.Log("Switching crypto")
  2191  
  2192  	// Allow the prompt rekey attempt to fail by using dev2's crypto
  2193  	// (which still isn't keyed for)
  2194  	c := make(chan struct{}, 1)
  2195  	clta := &cryptoLocalTrapAny{config2Dev2.Crypto(), sync.Once{}, c, config2Dev2.Crypto()}
  2196  	config2Dev2.SetCrypto(clta)
  2197  	ops.rekeyFSM.Event(newRekeyKickoffEvent())
  2198  	select {
  2199  	case <-c:
  2200  	case <-ctx.Done():
  2201  		t.Fatal(ctx.Err())
  2202  	}
  2203  	// Make sure the rekey attempt is finished by taking the lock.
  2204  	// Keep the lock for a while, to control when the second rekey starts.
  2205  	lState := makeFBOLockState()
  2206  	func() {
  2207  		ops.mdWriterLock.Lock(lState)
  2208  		defer ops.mdWriterLock.Unlock(lState)
  2209  
  2210  		// Now cause a paper prompt unlock via a folder access
  2211  		errCh := make(chan error, 1)
  2212  		go func() {
  2213  			_, err := GetRootNodeForTest(ctx, config2Dev2, name, tlf.Private)
  2214  			select {
  2215  			case errCh <- err:
  2216  			case <-ctx.Done():
  2217  				errCh <- errors.WithStack(ctx.Err())
  2218  			}
  2219  		}()
  2220  		select {
  2221  		case err = <-errCh:
  2222  		case <-ctx.Done():
  2223  			t.Fatal(ctx.Err())
  2224  		}
  2225  		if _, ok := err.(NeedSelfRekeyError); !ok {
  2226  			t.Fatalf("Got unexpected error when reading with new key: %+v", err)
  2227  		}
  2228  
  2229  		t.Log("Switching crypto again")
  2230  
  2231  		// Let the background rekeyer decrypt.
  2232  		c = make(chan struct{}, 1)
  2233  		clta = &cryptoLocalTrapAny{config2Dev2.Crypto(), sync.Once{}, c, config2.Crypto()}
  2234  		config2Dev2.SetCrypto(clta)
  2235  	}()
  2236  
  2237  	t.Log("Waiting for rekey attempt")
  2238  
  2239  	select {
  2240  	case <-c:
  2241  	case <-ctx.Done():
  2242  		t.Fatal(ctx.Err())
  2243  	}
  2244  	// Make sure the rekey attempt is finished
  2245  	ops.mdWriterLock.Lock(lState)
  2246  	ops.mdWriterLock.Unlock(lState)
  2247  
  2248  	t.Log("Getting the root node, which should now succeed")
  2249  
  2250  	GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
  2251  }
  2252  
  2253  func testKeyManagerRekeyMinimal(t *testing.T, ver kbfsmd.MetadataVer) {
  2254  	var u1, u2 kbname.NormalizedUsername = "u1", "u2"
  2255  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2)
  2256  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
  2257  	clock := clocktest.NewTestClockNow()
  2258  	config1.SetClock(clock)
  2259  
  2260  	config1.SetMetadataVersion(ver)
  2261  
  2262  	// User 2 is in minimal mode.
  2263  	config2 := ConfigAsUserWithMode(config1, u2, InitMinimal)
  2264  	defer CheckConfigAndShutdown(ctx, t, config2)
  2265  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
  2266  	if err != nil {
  2267  		t.Fatal(err)
  2268  	}
  2269  	uid2 := session2.UID
  2270  
  2271  	// Create a shared folder
  2272  	name := u1.String() + "," + u2.String()
  2273  
  2274  	rootNode1 := GetRootNodeOrBust(ctx, t, config1, name, tlf.Private)
  2275  
  2276  	kbfsOps1 := config1.KBFSOps()
  2277  
  2278  	// user 1 creates a file
  2279  	_, _, err = kbfsOps1.CreateFile(ctx, rootNode1, testPPS("a"), false, NoExcl)
  2280  	if err != nil {
  2281  		t.Fatalf("Couldn't create file: %+v", err)
  2282  	}
  2283  	err = kbfsOps1.SyncAll(ctx, rootNode1.GetFolderBranch())
  2284  	if err != nil {
  2285  		t.Fatalf("Couldn't sync file: %+v", err)
  2286  	}
  2287  
  2288  	// Device 2 is in default mode, so we can check that the rekey
  2289  	// worked.
  2290  	config2Dev2 := ConfigAsUser(config1, u2)
  2291  	defer CheckConfigAndShutdown(ctx, t, config2Dev2)
  2292  
  2293  	// Now give u2 a new device.  The configs don't share a Keybase
  2294  	// Daemon so we have to do it in all places.
  2295  	AddDeviceForLocalUserOrBust(t, config1, uid2)
  2296  	AddDeviceForLocalUserOrBust(t, config2, uid2)
  2297  	devIndex := AddDeviceForLocalUserOrBust(t, config2Dev2, uid2)
  2298  	SwitchDeviceForLocalUserOrBust(t, config2Dev2, devIndex)
  2299  
  2300  	// user 2 should be unable to read the data now since its device
  2301  	// wasn't registered when the folder was originally created.
  2302  	_, err = GetRootNodeForTest(ctx, config2Dev2, name, tlf.Private)
  2303  	if _, ok := err.(NeedSelfRekeyError); !ok {
  2304  		t.Fatalf("Got unexpected error when reading with new key: %+v", err)
  2305  	}
  2306  
  2307  	// Have the minimal instance do the rekey.
  2308  	_, err = RequestRekeyAndWaitForOneFinishEvent(ctx,
  2309  		config2.KBFSOps(), rootNode1.GetFolderBranch().Tlf)
  2310  	if err != nil {
  2311  		t.Fatalf("Couldn't rekey: %+v", err)
  2312  	}
  2313  
  2314  	root2Dev2 := GetRootNodeOrBust(ctx, t, config2Dev2, name, tlf.Private)
  2315  	kbfsOps2Dev2 := config2Dev2.KBFSOps()
  2316  	err = kbfsOps2Dev2.SyncFromServer(ctx,
  2317  		root2Dev2.GetFolderBranch(), nil)
  2318  	if err != nil {
  2319  		t.Fatalf("Couldn't sync from server: %+v", err)
  2320  	}
  2321  
  2322  	children, err := kbfsOps2Dev2.GetDirChildren(ctx, root2Dev2)
  2323  	require.NoError(t, err)
  2324  	if _, ok := children[root2Dev2.ChildName("a")]; !ok {
  2325  		t.Fatalf("Device 2 couldn't see the dir entry")
  2326  	}
  2327  }
  2328  
  2329  // maybeReplaceContext, defined on *protectedContext, enables replacing context
  2330  // stored in protectedContext.
  2331  //
  2332  // This is importantly defined in a _test.go file since we should not use it
  2333  // anywhere other than in tests.
  2334  //
  2335  // For now, the only application for this is to cause states in rekey_fsm
  2336  // to replace existing context when new request comes in. This is needed
  2337  // because stallers store staller key in context, and context needs to be
  2338  // updated in states in order for stalling to be effective.
  2339  func (c *protectedContext) maybeReplaceContext(newCtx context.Context) {
  2340  	c.mu.Lock()
  2341  	defer c.mu.Unlock()
  2342  	if c.log != nil {
  2343  		c.log.CDebugf(c.ctx, "Replacing context")
  2344  		defer c.log.CDebugf(newCtx, "Context replaced")
  2345  	}
  2346  	c.ctx = newCtx
  2347  }
  2348  
  2349  func TestKeyManagerGetTeamTLFCryptKey(t *testing.T) {
  2350  	var u1, u2 kbname.NormalizedUsername = "u1", "u2"
  2351  	config1, uid1, ctx, cancel := kbfsOpsConcurInit(t, u1, u2)
  2352  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
  2353  
  2354  	config2 := ConfigAsUser(config1, u2)
  2355  	defer CheckConfigAndShutdown(ctx, t, config2)
  2356  	session2, err := config2.KBPKI().GetCurrentSession(ctx)
  2357  	if err != nil {
  2358  		t.Fatal(err)
  2359  	}
  2360  	uid2 := session2.UID
  2361  
  2362  	// These are deterministic, and should add the same TeamInfos for
  2363  	// both user configs.
  2364  	name := kbname.NormalizedUsername("t1")
  2365  	teamInfos := AddEmptyTeamsForTestOrBust(t, config1, name)
  2366  	_ = AddEmptyTeamsForTestOrBust(t, config2, name)
  2367  	tid := teamInfos[0].TID
  2368  	AddTeamWriterForTestOrBust(t, config1, tid, uid1)
  2369  	AddTeamWriterForTestOrBust(t, config2, tid, uid1)
  2370  	AddTeamWriterForTestOrBust(t, config1, tid, uid2)
  2371  	AddTeamWriterForTestOrBust(t, config2, tid, uid2)
  2372  
  2373  	tlfID := tlf.FakeID(1, tlf.SingleTeam)
  2374  	h := tlfhandle.NewHandle(
  2375  		tlf.SingleTeam,
  2376  		map[keybase1.UserOrTeamID]kbname.NormalizedUsername{
  2377  			tid.AsUserOrTeam(): name,
  2378  		}, nil, nil, tlf.CanonicalName(name), tlf.NullID)
  2379  
  2380  	rmd, err := makeInitialRootMetadata(kbfsmd.SegregatedKeyBundlesVer, tlfID, h)
  2381  	require.NoError(t, err)
  2382  	rmd.bareMd.SetLatestKeyGenerationForTeamTLF(teamInfos[0].LatestKeyGen)
  2383  	// Make sure the MD looks readable.
  2384  	rmd.data.Dir.BlockPointer = data.BlockPointer{ID: kbfsblock.FakeID(1)}
  2385  
  2386  	// Both users should see the same key.
  2387  	key1, err := config1.KeyManager().GetTLFCryptKeyForEncryption(ctx, rmd)
  2388  	require.NoError(t, err)
  2389  	key2, err := config2.KeyManager().GetTLFCryptKeyForEncryption(ctx, rmd)
  2390  	require.NoError(t, err)
  2391  	require.Equal(t, key1, key2)
  2392  
  2393  	// Bump the key generation.
  2394  	AddTeamKeyForTestOrBust(t, config1, tid)
  2395  	AddTeamKeyForTestOrBust(t, config2, tid)
  2396  	rmd2, err := rmd.MakeSuccessor(context.Background(),
  2397  		config1.MetadataVersion(), config1.Codec(),
  2398  		config1.KeyManager(), config1.KBPKI(), config1.KBPKI(),
  2399  		config1, kbfsmd.FakeID(2), true)
  2400  	require.NoError(t, err)
  2401  
  2402  	// Both users should see the same new key.
  2403  	key1b, err := config1.KeyManager().GetTLFCryptKeyForEncryption(ctx, rmd2)
  2404  	require.NoError(t, err)
  2405  	key2b, err := config2.KeyManager().GetTLFCryptKeyForEncryption(ctx, rmd2)
  2406  	require.NoError(t, err)
  2407  	require.Equal(t, key1b, key2b)
  2408  	require.NotEqual(t, key1, key1b)
  2409  }
  2410  
  2411  func testKeyManagerGetImplicitTeamTLFCryptKey(t *testing.T, ty tlf.Type) {
  2412  	var u1, u2 kbname.NormalizedUsername = "u1", "u2"
  2413  	config1, _, ctx, cancel := kbfsOpsConcurInit(t, u1, u2)
  2414  	defer kbfsConcurTestShutdown(ctx, t, config1, cancel)
  2415  
  2416  	config2 := ConfigAsUser(config1, u2)
  2417  	defer CheckConfigAndShutdown(ctx, t, config2)
  2418  
  2419  	// These are deterministic, and should add the same
  2420  	// ImplicitTeamInfos for both user configs.
  2421  	iname := "u1,u2"
  2422  	err := EnableImplicitTeamsForTest(config1)
  2423  	require.NoError(t, err)
  2424  	teamID := AddImplicitTeamForTestOrBust(t, config1, iname, "", 1, ty)
  2425  	_ = AddImplicitTeamForTestOrBust(t, config2, iname, "", 1, ty)
  2426  	tlfID := tlf.FakeID(1, ty)
  2427  
  2428  	asUserName := kbname.NormalizedUsername(iname)
  2429  	h := tlfhandle.NewHandle(
  2430  		ty, map[keybase1.UserOrTeamID]kbname.NormalizedUsername{
  2431  			teamID.AsUserOrTeam(): asUserName,
  2432  		}, nil, nil, tlf.CanonicalName(asUserName), tlfID)
  2433  
  2434  	_, latestKeyGen, err := config1.KBPKI().GetTeamTLFCryptKeys(
  2435  		ctx, teamID, kbfsmd.UnspecifiedKeyGen,
  2436  		keybase1.OfflineAvailability_NONE)
  2437  	require.NoError(t, err)
  2438  
  2439  	rmd, err := makeInitialRootMetadata(config1.MetadataVersion(), tlfID, h)
  2440  	require.NoError(t, err)
  2441  	rmd.bareMd.SetLatestKeyGenerationForTeamTLF(latestKeyGen)
  2442  	// Make sure the MD looks readable.
  2443  	rmd.data.Dir.BlockPointer = data.BlockPointer{ID: kbfsblock.FakeID(1)}
  2444  
  2445  	// Both users should see the same key.
  2446  	key1, err := config1.KeyManager().GetTLFCryptKeyForEncryption(ctx, rmd)
  2447  	require.NoError(t, err)
  2448  	key2, err := config2.KeyManager().GetTLFCryptKeyForEncryption(ctx, rmd)
  2449  	require.NoError(t, err)
  2450  	require.Equal(t, key1, key2)
  2451  
  2452  	// Bump the key generation.
  2453  	AddTeamKeyForTestOrBust(t, config1, teamID)
  2454  	AddTeamKeyForTestOrBust(t, config2, teamID)
  2455  	rmd2, err := rmd.MakeSuccessor(context.Background(),
  2456  		config1.MetadataVersion(), config1.Codec(),
  2457  		config1.KeyManager(), config1.KBPKI(), config1.KBPKI(),
  2458  		config1, kbfsmd.FakeID(2), true)
  2459  	require.NoError(t, err)
  2460  
  2461  	// Both users should see the same new key.
  2462  	key1b, err := config1.KeyManager().GetTLFCryptKeyForEncryption(ctx, rmd2)
  2463  	require.NoError(t, err)
  2464  	key2b, err := config2.KeyManager().GetTLFCryptKeyForEncryption(ctx, rmd2)
  2465  	require.NoError(t, err)
  2466  	require.Equal(t, key1b, key2b)
  2467  	if ty == tlf.Public {
  2468  		// Bumping the key generation shouldn't do anything for public TLFs.
  2469  		require.Equal(t, key1, key1b)
  2470  	} else {
  2471  		require.NotEqual(t, key1, key1b)
  2472  	}
  2473  }
  2474  
  2475  func TestKeyManagerGetPrivateImplicitTeamTLFCryptKey(t *testing.T) {
  2476  	testKeyManagerGetImplicitTeamTLFCryptKey(t, tlf.Private)
  2477  }
  2478  
  2479  func TestKeyManagerGetPublicImplicitTeamTLFCryptKey(t *testing.T) {
  2480  	testKeyManagerGetImplicitTeamTLFCryptKey(t, tlf.Public)
  2481  }
  2482  
  2483  func TestKeyManager(t *testing.T) {
  2484  	tests := []func(*testing.T, kbfsmd.MetadataVer){
  2485  		testKeyManagerPublicTLFCryptKey,
  2486  		testKeyManagerCachedSecretKeyForEncryptionSuccess,
  2487  		testKeyManagerCachedSecretKeyForMDDecryptionSuccess,
  2488  		testKeyManagerCachedSecretKeyForBlockDecryptionSuccess,
  2489  		testKeyManagerUncachedSecretKeyForEncryptionSuccess,
  2490  		testKeyManagerUncachedSecretKeyForMDDecryptionSuccess,
  2491  		testKeyManagerUncachedSecretKeyForBlockDecryptionSuccess,
  2492  		testKeyManagerRekeySuccessPrivate,
  2493  		testKeyManagerRekeyResolveAgainSuccessPublic,
  2494  		testKeyManagerRekeyResolveAgainSuccessPublicSelf,
  2495  		testKeyManagerRekeyResolveAgainSuccessPrivate,
  2496  		testKeyManagerPromoteReaderSuccess,
  2497  		testKeyManagerPromoteReaderSelf,
  2498  		testKeyManagerReaderRekeyShouldNotPromote,
  2499  		testKeyManagerReaderRekeyResolveAgainSuccessPrivate,
  2500  		testKeyManagerRekeyResolveAgainNoChangeSuccessPrivate,
  2501  		testKeyManagerRekeyAddAndRevokeDevice,
  2502  		testKeyManagerRekeyAddWriterAndReaderDevice,
  2503  		testKeyManagerSelfRekeyAcrossDevices,
  2504  		testKeyManagerReaderRekey,
  2505  		testKeyManagerReaderRekeyAndRevoke,
  2506  		testKeyManagerRekeyBit,
  2507  		testKeyManagerRekeyAddAndRevokeDeviceWithConflict,
  2508  		testKeyManagerRekeyAddDeviceWithPrompt,
  2509  		testKeyManagerRekeyAddDeviceWithPromptAfterRestart,
  2510  		testKeyManagerRekeyAddDeviceWithPromptViaFolderAccess,
  2511  		testKeyManagerRekeyMinimal,
  2512  	}
  2513  	runTestsOverMetadataVers(t, "testKeyManager", tests)
  2514  }