github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/libkbfs/root_metadata_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  	"bytes"
     9  	"fmt"
    10  	"reflect"
    11  	"runtime"
    12  	"strings"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/keybase/client/go/kbfs/data"
    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  	"github.com/keybase/client/go/kbfs/tlf"
    22  	"github.com/keybase/client/go/kbfs/tlfhandle"
    23  	kbname "github.com/keybase/client/go/kbun"
    24  	"github.com/keybase/client/go/protocol/keybase1"
    25  	"github.com/keybase/go-codec/codec"
    26  	"github.com/pkg/errors"
    27  	"github.com/stretchr/testify/require"
    28  	"golang.org/x/net/context"
    29  )
    30  
    31  var testMetadataVers = []kbfsmd.MetadataVer{
    32  	kbfsmd.InitialExtraMetadataVer, kbfsmd.ImplicitTeamsVer,
    33  }
    34  
    35  // runTestOverMetadataVers runs the given test function over all
    36  // metadata versions to test. The test is assumed to be parallelizable
    37  // with other instances of itself. Example use:
    38  //
    39  //	func TestFoo(t *testing.T) {
    40  //		runTestOverMetadataVers(t, testFoo)
    41  //	}
    42  //
    43  //	func testFoo(t *testing.T, ver MetadataVer) {
    44  //		...
    45  //		brmd, err := MakeInitialRootMetadata(ver, ...)
    46  //		...
    47  //	}
    48  func runTestOverMetadataVers(
    49  	t *testing.T, f func(t *testing.T, ver kbfsmd.MetadataVer)) {
    50  	for _, ver := range testMetadataVers {
    51  		ver := ver // capture range variable.
    52  		t.Run(ver.String(), func(t *testing.T) {
    53  			f(t, ver)
    54  		})
    55  	}
    56  }
    57  
    58  // runTestsOverMetadataVers runs the given list of test functions over
    59  // all metadata versions to test. prefix should be the common prefix
    60  // for all the test function names, and the names of the subtest will
    61  // be taken to be the strings after that prefix. Example use:
    62  //
    63  //	func TestFoo(t *testing.T) {
    64  //		tests := []func(*testing.T, kbfsmd.MetadataVer){
    65  //			testFooBar1,
    66  //			testFooBar2,
    67  //			testFooBar3,
    68  //			...
    69  //		}
    70  //		runTestsOverMetadataVers(t, "testFoo", tests)
    71  //	}
    72  func runTestsOverMetadataVers(t *testing.T, prefix string,
    73  	fs []func(t *testing.T, ver kbfsmd.MetadataVer)) {
    74  	for _, f := range fs {
    75  		f := f // capture range variable.
    76  		name := runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
    77  		i := strings.LastIndex(name, prefix)
    78  		if i >= 0 {
    79  			i += len(prefix)
    80  		} else {
    81  			i = 0
    82  		}
    83  		name = name[i:]
    84  		t.Run(name, func(t *testing.T) {
    85  			runTestOverMetadataVers(t, f)
    86  		})
    87  	}
    88  }
    89  
    90  // runBenchmarkOverMetadataVers runs the given benchmark function over
    91  // all metadata versions to test. Example use:
    92  //
    93  //	func BenchmarkFoo(b *testing.B) {
    94  //		runBenchmarkOverMetadataVers(b, testFoo)
    95  //	}
    96  //
    97  //	func benchmarkFoo(b *testing.B, ver kbfsmd.MetadataVer) {
    98  //		...
    99  //		brmd, err := MakeInitialRootMetadata(ver, ...)
   100  //		...
   101  //	}
   102  func runBenchmarkOverMetadataVers(
   103  	b *testing.B, f func(b *testing.B, ver kbfsmd.MetadataVer)) {
   104  	for _, ver := range testMetadataVers {
   105  		ver := ver // capture range variable.
   106  		b.Run(ver.String(), func(b *testing.B) {
   107  			f(b, ver)
   108  		})
   109  	}
   110  }
   111  
   112  // TODO: Add way to test with all possible (ver, maxVer) combos,
   113  // e.g. for upconversion tests.
   114  
   115  type privateMetadataFuture struct {
   116  	PrivateMetadata
   117  	kbfscodec.Extra
   118  }
   119  
   120  func (pmf privateMetadataFuture) toCurrent() PrivateMetadata {
   121  	pm := pmf.PrivateMetadata
   122  	pm.Dir = pmf.Dir
   123  	pm.Changes.Ops = make(opsList, len(pmf.Changes.Ops))
   124  	for i, opFuture := range pmf.Changes.Ops {
   125  		currentOp := opFuture.(kbfscodec.FutureStruct).ToCurrentStruct()
   126  		// A generic version of "v := currentOp; ...Ops[i] = &v".
   127  		v := reflect.New(reflect.TypeOf(currentOp))
   128  		v.Elem().Set(reflect.ValueOf(currentOp))
   129  		pm.Changes.Ops[i] = v.Interface().(op)
   130  	}
   131  	return pm
   132  }
   133  
   134  func (pmf privateMetadataFuture) ToCurrentStruct() kbfscodec.CurrentStruct {
   135  	return pmf.toCurrent()
   136  }
   137  
   138  func makeFakePrivateMetadataFuture(t *testing.T) privateMetadataFuture {
   139  	createOp := makeFakeCreateOpFuture(t)
   140  	rmOp := makeFakeRmOpFuture(t)
   141  	renameOp := makeFakeRenameOpFuture(t)
   142  	syncOp := makeFakeSyncOpFuture(t)
   143  	setAttrOp := makeFakeSetAttrOpFuture(t)
   144  	resolutionOp := makeFakeResolutionOpFuture(t)
   145  	rekeyOp := makeFakeRekeyOpFuture(t)
   146  	gcOp := makeFakeGcOpFuture(t)
   147  
   148  	pmf := privateMetadataFuture{
   149  		PrivateMetadata{
   150  			data.DirEntry{},
   151  			kbfscrypto.MakeTLFPrivateKey([32]byte{0xb}),
   152  			BlockChanges{
   153  				makeFakeBlockInfo(t),
   154  				opsList{
   155  					&createOp,
   156  					&rmOp,
   157  					&renameOp,
   158  					&syncOp,
   159  					&setAttrOp,
   160  					&resolutionOp,
   161  					&rekeyOp,
   162  					&gcOp,
   163  				},
   164  				0,
   165  			},
   166  			0,
   167  			codec.UnknownFieldSetHandler{},
   168  			BlockChanges{},
   169  		},
   170  		kbfscodec.MakeExtraOrBust("PrivateMetadata", t),
   171  	}
   172  	return pmf
   173  }
   174  
   175  func TestPrivateMetadataUnknownFields(t *testing.T) {
   176  	testStructUnknownFields(t, makeFakePrivateMetadataFuture(t))
   177  }
   178  
   179  // makeFakeTlfHandle should only be used in this file.
   180  func makeFakeTlfHandle(
   181  	t *testing.T, x uint32, ty tlf.Type,
   182  	unresolvedWriters, unresolvedReaders []keybase1.SocialAssertion) *tlfhandle.Handle {
   183  	id := keybase1.MakeTestUID(x).AsUserOrTeam()
   184  	return tlfhandle.NewHandle(
   185  		ty, map[keybase1.UserOrTeamID]kbname.NormalizedUsername{
   186  			id: "test_user",
   187  		}, unresolvedWriters, unresolvedReaders, "", tlf.NullID)
   188  }
   189  
   190  // Test that GetTlfHandle() and MakeBareTlfHandle() work properly for
   191  // public TLFs.
   192  func testRootMetadataGetTlfHandlePublic(t *testing.T, ver kbfsmd.MetadataVer) {
   193  	uw := []keybase1.SocialAssertion{
   194  		{
   195  			User:    "user2",
   196  			Service: "service3",
   197  		},
   198  		{
   199  			User:    "user1",
   200  			Service: "service1",
   201  		},
   202  	}
   203  	h := makeFakeTlfHandle(t, 14, tlf.Public, uw, nil)
   204  	tlfID := tlf.FakeID(0, tlf.Public)
   205  	rmd, err := makeInitialRootMetadata(ver, tlfID, h)
   206  	require.NoError(t, err)
   207  
   208  	dirHandle := rmd.GetTlfHandle()
   209  	require.Equal(t, h, dirHandle)
   210  
   211  	rmd.tlfHandle = nil
   212  	bh, err := rmd.MakeBareTlfHandle()
   213  	require.NoError(t, err)
   214  	require.Equal(t, h.ToBareHandleOrBust(), bh)
   215  }
   216  
   217  // Test that GetTlfHandle() and MakeBareTlfHandle() work properly for
   218  // non-public TLFs.
   219  func testRootMetadataGetTlfHandlePrivate(t *testing.T, ver kbfsmd.MetadataVer) {
   220  	uw := []keybase1.SocialAssertion{
   221  		{
   222  			User:    "user2",
   223  			Service: "service3",
   224  		},
   225  		{
   226  			User:    "user1",
   227  			Service: "service1",
   228  		},
   229  	}
   230  	ur := []keybase1.SocialAssertion{
   231  		{
   232  			User:    "user5",
   233  			Service: "service3",
   234  		},
   235  		{
   236  			User:    "user1",
   237  			Service: "service2",
   238  		},
   239  	}
   240  	h := makeFakeTlfHandle(t, 14, tlf.Private, uw, ur)
   241  	tlfID := tlf.FakeID(0, tlf.Private)
   242  	rmd, err := makeInitialRootMetadata(ver, tlfID, h)
   243  	require.NoError(t, err)
   244  
   245  	rmd.fakeInitialRekey()
   246  
   247  	dirHandle := rmd.GetTlfHandle()
   248  	require.Equal(t, h, dirHandle)
   249  
   250  	rmd.tlfHandle = nil
   251  	bh, err := rmd.MakeBareTlfHandle()
   252  	require.NoError(t, err)
   253  	require.Equal(t, h.ToBareHandleOrBust(), bh)
   254  }
   255  
   256  // Test that key generations work as expected for private TLFs.
   257  func testRootMetadataLatestKeyGenerationPrivate(t *testing.T, ver kbfsmd.MetadataVer) {
   258  	tlfID := tlf.FakeID(0, tlf.Private)
   259  	h := makeFakeTlfHandle(t, 14, tlf.Private, nil, nil)
   260  	rmd, err := makeInitialRootMetadata(ver, tlfID, h)
   261  	require.NoError(t, err)
   262  
   263  	if rmd.LatestKeyGeneration() != 0 {
   264  		t.Errorf("Expected key generation to be invalid (0)")
   265  	}
   266  	rmd.fakeInitialRekey()
   267  	if rmd.LatestKeyGeneration() != kbfsmd.FirstValidKeyGen {
   268  		t.Errorf("Expected key generation to be valid(%d)", kbfsmd.FirstValidKeyGen)
   269  	}
   270  }
   271  
   272  // Test that key generations work as expected for public TLFs.
   273  func testRootMetadataLatestKeyGenerationPublic(t *testing.T, ver kbfsmd.MetadataVer) {
   274  	tlfID := tlf.FakeID(0, tlf.Public)
   275  	h := makeFakeTlfHandle(t, 14, tlf.Public, nil, nil)
   276  	rmd, err := makeInitialRootMetadata(ver, tlfID, h)
   277  	require.NoError(t, err)
   278  
   279  	if rmd.LatestKeyGeneration() != kbfsmd.PublicKeyGen {
   280  		t.Errorf("Expected key generation to be public (%d)", kbfsmd.PublicKeyGen)
   281  	}
   282  }
   283  
   284  func testMakeRekeyReadError(t *testing.T, ver kbfsmd.MetadataVer) {
   285  	ctx := context.Background()
   286  	config := MakeTestConfigOrBust(t, "alice", "bob")
   287  	config.SetMetadataVersion(ver)
   288  	defer CheckConfigAndShutdown(ctx, t, config)
   289  
   290  	tlfID := tlf.FakeID(1, tlf.Private)
   291  	h := parseTlfHandleOrBust(t, config, "alice", tlf.Private, tlfID)
   292  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), tlfID, h)
   293  	require.NoError(t, err)
   294  
   295  	rmd.fakeInitialRekey()
   296  
   297  	u, id, err := config.KBPKI().Resolve(
   298  		ctx, "bob", keybase1.OfflineAvailability_NONE)
   299  	require.NoError(t, err)
   300  	uid, err := id.AsUser()
   301  	require.NoError(t, err)
   302  
   303  	dummyErr := errors.New("dummy")
   304  	err = makeRekeyReadErrorHelper(dummyErr, rmd.ReadOnly(), h, uid, u)
   305  	require.Equal(
   306  		t, tlfhandle.NewReadAccessError(h, u, "/keybase/private/alice"), err)
   307  
   308  	err = makeRekeyReadErrorHelper(dummyErr,
   309  		rmd.ReadOnly(), h, h.FirstResolvedWriter().AsUserOrBust(), "alice")
   310  	require.Equal(t, NeedSelfRekeyError{"alice", dummyErr}, err)
   311  }
   312  
   313  func testMakeRekeyReadErrorResolvedHandle(t *testing.T, ver kbfsmd.MetadataVer) {
   314  	ctx := context.Background()
   315  	config := MakeTestConfigOrBust(t, "alice", "bob")
   316  	defer CheckConfigAndShutdown(ctx, t, config)
   317  
   318  	tlfID := tlf.FakeID(1, tlf.Private)
   319  	h, err := tlfhandle.ParseHandle(
   320  		ctx, config.KBPKI(), config.MDOps(), nil,
   321  		"alice,bob@twitter", tlf.Private)
   322  	require.NoError(t, err)
   323  	rmd, err := makeInitialRootMetadata(config.MetadataVersion(), tlfID, h)
   324  	require.NoError(t, err)
   325  
   326  	rmd.fakeInitialRekey()
   327  
   328  	u, id, err := config.KBPKI().Resolve(
   329  		ctx, "bob", keybase1.OfflineAvailability_NONE)
   330  	require.NoError(t, err)
   331  	uid, err := id.AsUser()
   332  	require.NoError(t, err)
   333  
   334  	err = makeRekeyReadErrorHelper(errors.New("dummy"),
   335  		rmd.ReadOnly(), h, uid, u)
   336  	require.Equal(t, tlfhandle.NewReadAccessError(
   337  		h, u, "/keybase/private/alice,bob@twitter"), err)
   338  
   339  	config.KeybaseService().(*KeybaseDaemonLocal).AddNewAssertionForTestOrBust(
   340  		"bob", "bob@twitter")
   341  
   342  	resolvedHandle, err := h.ResolveAgain(ctx, config.KBPKI(), nil, nil)
   343  	require.NoError(t, err)
   344  
   345  	dummyErr := errors.New("dummy")
   346  	err = makeRekeyReadErrorHelper(dummyErr,
   347  		rmd.ReadOnly(), resolvedHandle, uid, u)
   348  	require.Equal(t, NeedOtherRekeyError{"alice,bob", dummyErr}, err)
   349  }
   350  
   351  // Test that MakeSuccessor fails when the final bit is set.
   352  
   353  func testRootMetadataFinalIsFinal(t *testing.T, ver kbfsmd.MetadataVer) {
   354  	tlfID := tlf.FakeID(0, tlf.Public)
   355  	h := makeFakeTlfHandle(t, 14, tlf.Public, nil, nil)
   356  	rmd, err := makeInitialRootMetadata(ver, tlfID, h)
   357  	require.NoError(t, err)
   358  
   359  	rmd.SetFinalBit()
   360  	_, err = rmd.MakeSuccessor(context.Background(), -1, nil, nil, nil,
   361  		nil, nil, kbfsmd.FakeID(1), true)
   362  	_, isFinalError := err.(kbfsmd.MetadataIsFinalError)
   363  	require.Equal(t, isFinalError, true)
   364  }
   365  
   366  func getAllUsersKeysForTest(
   367  	t *testing.T, config Config, rmd *RootMetadata, un string) []kbfscrypto.TLFCryptKey {
   368  	var keys []kbfscrypto.TLFCryptKey
   369  	for keyGen := kbfsmd.FirstValidKeyGen; keyGen <= rmd.LatestKeyGeneration(); keyGen++ {
   370  		key, err := config.KeyManager().(*KeyManagerStandard).getTLFCryptKeyUsingCurrentDevice(
   371  			context.Background(), rmd, keyGen, true)
   372  		require.NoError(t, err)
   373  		keys = append(keys, key)
   374  	}
   375  	return keys
   376  }
   377  
   378  // We always want misses for the tests below.
   379  type dummyNoKeyCache struct {
   380  }
   381  
   382  func (kc *dummyNoKeyCache) GetTLFCryptKey(_ tlf.ID, _ kbfsmd.KeyGen) (kbfscrypto.TLFCryptKey, error) {
   383  	return kbfscrypto.TLFCryptKey{}, KeyCacheMissError{}
   384  }
   385  
   386  func (kc *dummyNoKeyCache) PutTLFCryptKey(_ tlf.ID, _ kbfsmd.KeyGen, _ kbfscrypto.TLFCryptKey) error {
   387  	return nil
   388  }
   389  
   390  // Test upconversion from MDv2 to MDv3 for a private folder.
   391  func TestRootMetadataUpconversionPrivate(t *testing.T) {
   392  	config := MakeTestConfigOrBust(t, "alice", "bob", "charlie")
   393  	config.SetKeyCache(&dummyNoKeyCache{})
   394  	ctx := context.Background()
   395  	defer CheckConfigAndShutdown(ctx, t, config)
   396  
   397  	tlfID := tlf.FakeID(1, tlf.Private)
   398  	h := parseTlfHandleOrBust(t, config, "alice,alice@twitter#bob,charlie@twitter,eve@reddit", tlf.Private, tlfID)
   399  	rmd, err := makeInitialRootMetadata(kbfsmd.InitialExtraMetadataVer, tlfID, h)
   400  	require.NoError(t, err)
   401  	require.Equal(t, kbfsmd.KeyGen(0), rmd.LatestKeyGeneration())
   402  	require.Equal(t, kbfsmd.Revision(1), rmd.Revision())
   403  	require.Equal(t, kbfsmd.InitialExtraMetadataVer, rmd.Version())
   404  
   405  	// set some dummy numbers
   406  	diskUsage, refBytes, unrefBytes := uint64(12345), uint64(4321), uint64(1234)
   407  	rmd.SetDiskUsage(diskUsage)
   408  	rmd.SetRefBytes(refBytes)
   409  	rmd.SetUnrefBytes(unrefBytes)
   410  	// Make sure the MD looks readable.
   411  	rmd.data.Dir.BlockPointer = data.BlockPointer{ID: kbfsblock.FakeID(1)}
   412  
   413  	// key it once
   414  	done, _, err := config.KeyManager().Rekey(context.Background(), rmd, false)
   415  	require.NoError(t, err)
   416  	require.True(t, done)
   417  	require.Equal(t, kbfsmd.KeyGen(1), rmd.LatestKeyGeneration())
   418  	require.Equal(t, kbfsmd.Revision(1), rmd.Revision())
   419  	require.Equal(t, kbfsmd.InitialExtraMetadataVer, rmd.Version())
   420  	require.Equal(t, 0, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).RKeys[0].TLFReaderEphemeralPublicKeys))
   421  	require.Equal(t, 1, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).WKeys[0].TLFEphemeralPublicKeys))
   422  
   423  	// revoke bob's device
   424  	_, bobID, err := config.KBPKI().Resolve(
   425  		context.Background(), "bob", keybase1.OfflineAvailability_NONE)
   426  	require.NoError(t, err)
   427  	bobUID, err := bobID.AsUser()
   428  	require.NoError(t, err)
   429  
   430  	RevokeDeviceForLocalUserOrBust(t, config, bobUID, 0)
   431  
   432  	// rekey it
   433  	done, _, err = config.KeyManager().Rekey(context.Background(), rmd, false)
   434  	require.NoError(t, err)
   435  	require.True(t, done)
   436  	require.Equal(t, kbfsmd.KeyGen(2), rmd.LatestKeyGeneration())
   437  	require.Equal(t, kbfsmd.Revision(1), rmd.Revision())
   438  	require.Equal(t, kbfsmd.InitialExtraMetadataVer, rmd.Version())
   439  	require.Equal(t, 1, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).WKeys[0].TLFEphemeralPublicKeys))
   440  	require.Equal(t, 0, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).RKeys[0].TLFReaderEphemeralPublicKeys))
   441  
   442  	// prove charlie
   443  	config.KeybaseService().(*KeybaseDaemonLocal).AddNewAssertionForTestOrBust(
   444  		"charlie", "charlie@twitter")
   445  
   446  	// rekey it
   447  	done, _, err = config.KeyManager().Rekey(context.Background(), rmd, false)
   448  	require.NoError(t, err)
   449  	require.True(t, done)
   450  	require.Equal(t, kbfsmd.KeyGen(2), rmd.LatestKeyGeneration())
   451  	require.Equal(t, kbfsmd.Revision(1), rmd.Revision())
   452  	require.Equal(t, kbfsmd.InitialExtraMetadataVer, rmd.Version())
   453  	require.Equal(t, 2, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).WKeys[0].TLFEphemeralPublicKeys))
   454  	require.Equal(t, 0, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).RKeys[0].TLFReaderEphemeralPublicKeys))
   455  
   456  	// add a device for charlie and rekey as charlie
   457  	_, charlieID, err := config.KBPKI().Resolve(
   458  		context.Background(), "charlie", keybase1.OfflineAvailability_NONE)
   459  	require.NoError(t, err)
   460  	charlieUID, err := charlieID.AsUser()
   461  	require.NoError(t, err)
   462  
   463  	config2 := ConfigAsUser(config, "charlie")
   464  	config2.SetKeyCache(&dummyNoKeyCache{})
   465  	defer CheckConfigAndShutdown(ctx, t, config2)
   466  	AddDeviceForLocalUserOrBust(t, config, charlieUID)
   467  	AddDeviceForLocalUserOrBust(t, config2, charlieUID)
   468  
   469  	// rekey it
   470  	done, _, err = config2.KeyManager().Rekey(context.Background(), rmd, false)
   471  	require.NoError(t, err)
   472  	require.True(t, done)
   473  	require.Equal(t, kbfsmd.KeyGen(2), rmd.LatestKeyGeneration())
   474  	require.Equal(t, kbfsmd.Revision(1), rmd.Revision())
   475  	require.Equal(t, kbfsmd.InitialExtraMetadataVer, rmd.Version())
   476  	require.Equal(t, 2, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).WKeys[0].TLFEphemeralPublicKeys))
   477  	require.Equal(t, 1, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).RKeys[0].TLFReaderEphemeralPublicKeys))
   478  
   479  	// override the metadata version
   480  	config.metadataVersion = kbfsmd.SegregatedKeyBundlesVer
   481  
   482  	// create an MDv3 successor
   483  	rmd2, err := rmd.MakeSuccessor(context.Background(),
   484  		config.MetadataVersion(), config.Codec(),
   485  		config.KeyManager(), config.KBPKI(), config.KBPKI(), nil,
   486  		kbfsmd.FakeID(1), true)
   487  	require.NoError(t, err)
   488  	require.Equal(t, kbfsmd.KeyGen(2), rmd2.LatestKeyGeneration())
   489  	require.Equal(t, kbfsmd.Revision(2), rmd2.Revision())
   490  	require.Equal(t, kbfsmd.SegregatedKeyBundlesVer, rmd2.Version())
   491  	extra, ok := rmd2.extra.(*kbfsmd.ExtraMetadataV3)
   492  	require.True(t, ok)
   493  	require.True(t, extra.IsWriterKeyBundleNew())
   494  	require.True(t, extra.IsReaderKeyBundleNew())
   495  
   496  	// compare numbers
   497  	require.Equal(t, diskUsage, rmd2.DiskUsage())
   498  	require.Equal(t, rmd.data.Dir, rmd2.data.Dir)
   499  
   500  	// These should be 0 since they are reset for successors.
   501  	require.Equal(t, uint64(0), rmd2.RefBytes())
   502  	require.Equal(t, uint64(0), rmd2.UnrefBytes())
   503  
   504  	// create and compare bare tlf handles (this verifies unresolved+resolved writer/reader sets are identical)
   505  	rmd.tlfHandle, rmd2.tlfHandle = nil, nil // avoid a panic due to the handle already existing
   506  	handle, err := rmd.MakeBareTlfHandle()
   507  	require.NoError(t, err)
   508  	handle2, err := rmd2.MakeBareTlfHandle()
   509  	require.NoError(t, err)
   510  	require.Equal(t, handle, handle2)
   511  
   512  	// compare tlf crypt keys
   513  	keys, err := config.KeyManager().GetTLFCryptKeyOfAllGenerations(context.Background(), rmd)
   514  	require.NoError(t, err)
   515  	require.Equal(t, 2, len(keys))
   516  
   517  	keys2, err := config.KeyManager().GetTLFCryptKeyOfAllGenerations(context.Background(), rmd2)
   518  	require.NoError(t, err)
   519  	require.Equal(t, 2, len(keys2))
   520  	require.Equal(t, keys, keys2)
   521  
   522  	// get each key generation for alice from each version of metadata
   523  	aliceKeys := getAllUsersKeysForTest(t, config, rmd, "alice")
   524  	aliceKeys2 := getAllUsersKeysForTest(t, config, rmd2, "alice")
   525  
   526  	// compare alice's keys
   527  	require.Equal(t, 2, len(aliceKeys))
   528  	require.Equal(t, aliceKeys, aliceKeys2)
   529  
   530  	// get each key generation for charlie from each version of metadata
   531  	charlieKeys := getAllUsersKeysForTest(t, config2, rmd, "charlie")
   532  	charlieKeys2 := getAllUsersKeysForTest(t, config2, rmd2, "charlie")
   533  
   534  	// compare charlie's keys
   535  	require.Equal(t, 2, len(charlieKeys))
   536  	require.Equal(t, charlieKeys, charlieKeys2)
   537  
   538  	// compare alice and charlie's keys
   539  	require.Equal(t, aliceKeys, charlieKeys)
   540  
   541  	// Rekeying again shouldn't change wkbNew/rkbNew.
   542  	err = rmd2.finalizeRekey(config.Codec())
   543  	require.NoError(t, err)
   544  	extra, ok = rmd2.extra.(*kbfsmd.ExtraMetadataV3)
   545  	require.True(t, ok)
   546  	require.True(t, extra.IsWriterKeyBundleNew())
   547  	require.True(t, extra.IsReaderKeyBundleNew())
   548  }
   549  
   550  // Test upconversion from MDv2 to MDv3 for a public folder.
   551  func TestRootMetadataUpconversionPublic(t *testing.T) {
   552  	ctx := context.Background()
   553  	config := MakeTestConfigOrBust(t, "alice", "bob")
   554  	defer CheckConfigAndShutdown(ctx, t, config)
   555  
   556  	tlfID := tlf.FakeID(1, tlf.Public)
   557  	h := parseTlfHandleOrBust(
   558  		t, config, "alice,bob,charlie@twitter", tlf.Public, tlfID)
   559  	rmd, err := makeInitialRootMetadata(kbfsmd.InitialExtraMetadataVer, tlfID, h)
   560  	require.NoError(t, err)
   561  	require.Equal(t, kbfsmd.PublicKeyGen, rmd.LatestKeyGeneration())
   562  	require.Equal(t, kbfsmd.Revision(1), rmd.Revision())
   563  	require.Equal(t, kbfsmd.InitialExtraMetadataVer, rmd.Version())
   564  
   565  	// set some dummy numbers
   566  	diskUsage, refBytes, unrefBytes := uint64(12345), uint64(4321), uint64(1234)
   567  	rmd.SetDiskUsage(diskUsage)
   568  	rmd.SetRefBytes(refBytes)
   569  	rmd.SetUnrefBytes(unrefBytes)
   570  
   571  	// override the metadata version
   572  	config.metadataVersion = kbfsmd.SegregatedKeyBundlesVer
   573  
   574  	// create an MDv3 successor
   575  	rmd2, err := rmd.MakeSuccessor(context.Background(),
   576  		config.MetadataVersion(), config.Codec(),
   577  		config.KeyManager(), config.KBPKI(), config.KBPKI(), config,
   578  		kbfsmd.FakeID(1), true)
   579  	require.NoError(t, err)
   580  	require.Equal(t, kbfsmd.PublicKeyGen, rmd2.LatestKeyGeneration())
   581  	require.Equal(t, kbfsmd.Revision(2), rmd2.Revision())
   582  	require.Equal(t, kbfsmd.SegregatedKeyBundlesVer, rmd2.Version())
   583  	// Do this instead of require.Nil because we want to assert
   584  	// that it's untyped nil.
   585  	require.True(t, rmd2.extra == nil)
   586  
   587  	// compare numbers
   588  	require.Equal(t, diskUsage, rmd2.DiskUsage())
   589  	// we expect this and the below to be zero this time because the folder is public.
   590  	// they aren't reset in the private version because the private metadata isn't
   591  	// initialized therefor it's considered unreadable.
   592  	require.Equal(t, uint64(0), rmd2.RefBytes())
   593  	require.Equal(t, uint64(0), rmd2.UnrefBytes())
   594  
   595  	// create and compare bare tlf handles (this verifies unresolved+resolved writer sets are identical)
   596  	rmd.tlfHandle, rmd2.tlfHandle = nil, nil // avoid a panic due to the handle already existing
   597  	handle, err := rmd.MakeBareTlfHandle()
   598  	require.NoError(t, err)
   599  	handle2, err := rmd2.MakeBareTlfHandle()
   600  	require.NoError(t, err)
   601  	require.Equal(t, handle, handle2)
   602  }
   603  
   604  // Test upconversion from MDv2 to MDv3 for a private conflict folder.
   605  // Regression test for KBFS-2381.
   606  func TestRootMetadataUpconversionPrivateConflict(t *testing.T) {
   607  	ctx := context.Background()
   608  	config := MakeTestConfigOrBust(t, "alice", "bob")
   609  	defer CheckConfigAndShutdown(ctx, t, config)
   610  
   611  	tlfID := tlf.FakeID(1, tlf.Private)
   612  	h := parseTlfHandleOrBust(
   613  		t, config, "alice,bob (conflicted copy 2017-08-24)", tlf.Private, tlfID)
   614  	rmd, err := makeInitialRootMetadata(kbfsmd.InitialExtraMetadataVer, tlfID, h)
   615  	require.NoError(t, err)
   616  	require.Equal(t, kbfsmd.KeyGen(0), rmd.LatestKeyGeneration())
   617  	require.Equal(t, kbfsmd.Revision(1), rmd.Revision())
   618  	require.Equal(t, kbfsmd.InitialExtraMetadataVer, rmd.Version())
   619  	require.NotNil(t, h.ConflictInfo())
   620  
   621  	// set some dummy numbers
   622  	diskUsage, refBytes, unrefBytes :=
   623  		uint64(12345), uint64(4321), uint64(1234)
   624  	rmd.SetDiskUsage(diskUsage)
   625  	rmd.SetRefBytes(refBytes)
   626  	rmd.SetUnrefBytes(unrefBytes)
   627  	// Make sure the MD looks readable.
   628  	rmd.data.Dir.BlockPointer = data.BlockPointer{ID: kbfsblock.FakeID(1)}
   629  
   630  	// key it once
   631  	done, _, err := config.KeyManager().Rekey(context.Background(), rmd, false)
   632  	require.NoError(t, err)
   633  	require.True(t, done)
   634  	require.Equal(t, kbfsmd.KeyGen(1), rmd.LatestKeyGeneration())
   635  	require.Equal(t, kbfsmd.Revision(1), rmd.Revision())
   636  	require.Equal(t, kbfsmd.InitialExtraMetadataVer, rmd.Version())
   637  	require.Equal(t, 0, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).RKeys[0].TLFReaderEphemeralPublicKeys))
   638  	require.Equal(t, 1, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).WKeys[0].TLFEphemeralPublicKeys))
   639  	require.True(t, rmd.IsReadable())
   640  
   641  	// override the metadata version
   642  	config.metadataVersion = kbfsmd.SegregatedKeyBundlesVer
   643  
   644  	// create an MDv3 successor
   645  	rmd2, err := rmd.MakeSuccessor(context.Background(),
   646  		config.MetadataVersion(), config.Codec(),
   647  		config.KeyManager(), config.KBPKI(), config.KBPKI(), config,
   648  		kbfsmd.FakeID(1), true)
   649  	require.NoError(t, err)
   650  	require.Equal(t, kbfsmd.KeyGen(1), rmd2.LatestKeyGeneration())
   651  	require.Equal(t, kbfsmd.Revision(2), rmd2.Revision())
   652  	require.Equal(t, kbfsmd.SegregatedKeyBundlesVer, rmd2.Version())
   653  	extra, ok := rmd2.extra.(*kbfsmd.ExtraMetadataV3)
   654  	require.True(t, ok)
   655  	require.True(t, extra.IsWriterKeyBundleNew())
   656  	require.True(t, extra.IsReaderKeyBundleNew())
   657  
   658  	// Check the handle, but the cached handle in the MD is a direct copy...
   659  	require.Equal(
   660  		t, h.GetCanonicalPath(), rmd2.GetTlfHandle().GetCanonicalPath())
   661  	// So also check that the conflict info is set in the MD itself.
   662  	require.NotNil(t, rmd2.bareMd.(*kbfsmd.RootMetadataV3).ConflictInfo)
   663  }
   664  
   665  // The server will be reusing IsLastModifiedBy and we don't want a client
   666  // to be able to construct an MD that will crash the server.
   667  func TestRootMetadataV3NoPanicOnWriterMismatch(t *testing.T) {
   668  	ctx := context.Background()
   669  	config := MakeTestConfigOrBust(t, "alice", "bob")
   670  	defer CheckConfigAndShutdown(ctx, t, config)
   671  
   672  	_, id, err := config.KBPKI().Resolve(
   673  		context.Background(), "alice", keybase1.OfflineAvailability_NONE)
   674  	require.NoError(t, err)
   675  	uid, err := id.AsUser()
   676  	require.NoError(t, err)
   677  
   678  	tlfID := tlf.FakeID(0, tlf.Private)
   679  	h := makeFakeTlfHandle(t, 14, tlf.Private, nil, nil)
   680  	rmd, err := makeInitialRootMetadata(kbfsmd.SegregatedKeyBundlesVer, tlfID, h)
   681  	require.NoError(t, err)
   682  	rmd.fakeInitialRekey()
   683  	rmd.SetLastModifyingWriter(uid)
   684  	rmd.SetLastModifyingUser(uid)
   685  
   686  	// sign with a mismatched writer
   687  	config2 := ConfigAsUser(config, "bob")
   688  	defer CheckConfigAndShutdown(ctx, t, config2)
   689  	rmds, err := SignBareRootMetadata(
   690  		context.Background(), config.Codec(), config.Crypto(), config2.Crypto(), rmd.bareMd, time.Now())
   691  	require.NoError(t, err)
   692  
   693  	// verify last modifier
   694  	session, err := config.KBPKI().GetCurrentSession(context.Background())
   695  	require.NoError(t, err)
   696  	session2, err := config2.KBPKI().GetCurrentSession(context.Background())
   697  	require.NoError(t, err)
   698  
   699  	err = rmds.IsLastModifiedBy(uid, session.VerifyingKey)
   700  	require.EqualError(t, err, fmt.Sprintf("Last writer verifying key %s != %s", session2.VerifyingKey, session.VerifyingKey))
   701  }
   702  
   703  // Test that a reader can't upconvert a private folder from v2 to v3.
   704  func TestRootMetadataReaderUpconversionPrivate(t *testing.T) {
   705  	ctx := context.Background()
   706  	configWriter := MakeTestConfigOrBust(t, "alice", "bob")
   707  	configWriter.SetKeyCache(&dummyNoKeyCache{})
   708  	defer CheckConfigAndShutdown(ctx, t, configWriter)
   709  
   710  	tlfID := tlf.FakeID(1, tlf.Private)
   711  	h := parseTlfHandleOrBust(t, configWriter, "alice#bob", tlf.Private, tlfID)
   712  	rmd, err := makeInitialRootMetadata(kbfsmd.InitialExtraMetadataVer, tlfID, h)
   713  	require.NoError(t, err)
   714  	require.Equal(t, kbfsmd.KeyGen(0), rmd.LatestKeyGeneration())
   715  	require.Equal(t, kbfsmd.Revision(1), rmd.Revision())
   716  	require.Equal(t, kbfsmd.PreExtraMetadataVer, rmd.Version())
   717  
   718  	// set some dummy numbers
   719  	diskUsage, refBytes, unrefBytes := uint64(12345), uint64(4321), uint64(1234)
   720  	rmd.SetDiskUsage(diskUsage)
   721  	rmd.SetRefBytes(refBytes)
   722  	rmd.SetUnrefBytes(unrefBytes)
   723  
   724  	// Have the writer key it first.
   725  	done, _, err := configWriter.KeyManager().Rekey(
   726  		context.Background(), rmd, false)
   727  	require.NoError(t, err)
   728  	require.True(t, done)
   729  	require.Equal(t, kbfsmd.KeyGen(1), rmd.LatestKeyGeneration())
   730  	require.Equal(t, kbfsmd.Revision(1), rmd.Revision())
   731  	require.Equal(t, kbfsmd.PreExtraMetadataVer, rmd.Version())
   732  	require.Equal(t, 1, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).WKeys[0].TLFEphemeralPublicKeys))
   733  	require.Equal(t, 0, len(rmd.bareMd.(*kbfsmd.RootMetadataV2).RKeys[0].TLFReaderEphemeralPublicKeys))
   734  
   735  	// Set the private MD, to make sure it gets copied properly during
   736  	// upconversion.
   737  	_, aliceID, err := configWriter.KBPKI().Resolve(
   738  		context.Background(), "alice", keybase1.OfflineAvailability_NONE)
   739  	require.NoError(t, err)
   740  	aliceUID, err := aliceID.AsUser()
   741  	require.NoError(t, err)
   742  
   743  	err = encryptMDPrivateData(context.Background(), configWriter.Codec(),
   744  		configWriter.Crypto(), configWriter.Crypto(),
   745  		configWriter.KeyManager(), aliceUID, rmd)
   746  	require.NoError(t, err)
   747  
   748  	// add a device for bob and rekey as bob
   749  	_, bobID, err := configWriter.KBPKI().Resolve(
   750  		context.Background(), "bob", keybase1.OfflineAvailability_NONE)
   751  	require.NoError(t, err)
   752  	bobUID, err := bobID.AsUser()
   753  	require.NoError(t, err)
   754  
   755  	configReader := ConfigAsUser(configWriter, "bob")
   756  	configReader.SetKeyCache(&dummyNoKeyCache{})
   757  	defer CheckConfigAndShutdown(ctx, t, configReader)
   758  	AddDeviceForLocalUserOrBust(t, configWriter, bobUID)
   759  	AddDeviceForLocalUserOrBust(t, configReader, bobUID)
   760  
   761  	// Override the metadata version, make a successor, and rekey as
   762  	// reader.  This should keep the version the same, since readers
   763  	// can't upconvert.
   764  	configReader.metadataVersion = kbfsmd.SegregatedKeyBundlesVer
   765  	rmd2, err := rmd.MakeSuccessor(context.Background(),
   766  		configReader.MetadataVersion(), configReader.Codec(),
   767  		configReader.KeyManager(), configReader.KBPKI(),
   768  		configReader.KBPKI(), configReader, kbfsmd.FakeID(1), false)
   769  	require.NoError(t, err)
   770  	require.Equal(t, kbfsmd.KeyGen(1), rmd2.LatestKeyGeneration())
   771  	require.Equal(t, kbfsmd.Revision(2), rmd2.Revision())
   772  	require.Equal(t, kbfsmd.PreExtraMetadataVer, rmd2.Version())
   773  	// Do this instead of require.Nil because we want to assert
   774  	// that it's untyped nil.
   775  	require.True(t, rmd2.extra == nil)
   776  	done, _, err = configReader.KeyManager().Rekey(
   777  		context.Background(), rmd2, false)
   778  	require.NoError(t, err)
   779  	require.True(t, done)
   780  	require.Equal(t, kbfsmd.KeyGen(1), rmd2.LatestKeyGeneration())
   781  	require.Equal(t, kbfsmd.Revision(2), rmd2.Revision())
   782  	require.Equal(t, kbfsmd.PreExtraMetadataVer, rmd2.Version())
   783  	require.True(t, rmd2.IsWriterMetadataCopiedSet())
   784  	require.True(t, bytes.Equal(rmd.GetSerializedPrivateMetadata(),
   785  		rmd2.GetSerializedPrivateMetadata()))
   786  
   787  	rmds, err := SignBareRootMetadata(context.Background(),
   788  		configReader.Codec(), configReader.Crypto(), configReader.Crypto(),
   789  		rmd2.bareMd, configReader.Clock().Now())
   790  	require.NoError(t, err)
   791  	err = rmds.IsValidAndSigned(
   792  		ctx, configReader.Codec(), nil, rmd2.extra,
   793  		keybase1.OfflineAvailability_NONE)
   794  	require.NoError(t, err)
   795  }
   796  
   797  // Check writer/reader methods with teams
   798  func TestRootMetadataTeamMembership(t *testing.T) {
   799  	config := MakeTestConfigOrBust(t, "alice", "bob", "charlie")
   800  	ctx := context.Background()
   801  	defer CheckConfigAndShutdown(ctx, t, config)
   802  
   803  	teamInfos := AddEmptyTeamsForTestOrBust(t, config, "t1")
   804  	tid := teamInfos[0].TID
   805  
   806  	tlfID := tlf.FakeID(1, tlf.SingleTeam)
   807  	h := tlfhandle.NewHandle(
   808  		tlf.SingleTeam,
   809  		map[keybase1.UserOrTeamID]kbname.NormalizedUsername{
   810  			tid.AsUserOrTeam(): "t1",
   811  		}, nil, nil, "t1", tlf.NullID)
   812  	rmd, err := makeInitialRootMetadata(kbfsmd.InitialExtraMetadataVer, tlfID, h)
   813  	require.NoError(t, err)
   814  
   815  	getUser := func(name string) (keybase1.UID, kbfscrypto.VerifyingKey) {
   816  		_, id, err := config.KBPKI().Resolve(
   817  			context.Background(), name, keybase1.OfflineAvailability_NONE)
   818  		require.NoError(t, err)
   819  		uid, err := id.AsUser()
   820  		require.NoError(t, err)
   821  
   822  		userInfo, err := config.KeybaseService().LoadUserPlusKeys(
   823  			context.Background(), uid, keybase1.KID(""),
   824  			keybase1.OfflineAvailability_NONE)
   825  		require.NoError(t, err)
   826  
   827  		return uid, userInfo.VerifyingKeys[0]
   828  	}
   829  	aliceUID, aliceKey := getUser("alice")
   830  	bobUID, bobKey := getUser("bob")
   831  	charlieUID, charlieKey := getUser("charlie")
   832  
   833  	// No user should be able to read this yet.
   834  	checkWriter := func(uid keybase1.UID, key kbfscrypto.VerifyingKey,
   835  		expectedIsWriter bool) {
   836  		isWriter, err := rmd.IsWriter(ctx, config.KBPKI(), config, uid, key)
   837  		require.NoError(t, err)
   838  		require.Equal(t, expectedIsWriter, isWriter)
   839  	}
   840  	checkReader := func(uid keybase1.UID, expectedIsReader bool) {
   841  		isReader, err := rmd.IsReader(ctx, config.KBPKI(), config, uid)
   842  		require.NoError(t, err)
   843  		require.Equal(t, expectedIsReader, isReader)
   844  	}
   845  	checkWriter(aliceUID, aliceKey, false)
   846  	checkWriter(bobUID, bobKey, false)
   847  	checkWriter(charlieUID, charlieKey, false)
   848  	checkReader(aliceUID, false)
   849  	checkReader(bobUID, false)
   850  	checkReader(charlieUID, false)
   851  
   852  	// Make bob a writer.
   853  	AddTeamWriterForTestOrBust(t, config, tid, bobUID)
   854  	checkWriter(aliceUID, aliceKey, false)
   855  	checkWriter(bobUID, bobKey, true)
   856  	checkWriter(charlieUID, charlieKey, false)
   857  	checkReader(aliceUID, false)
   858  	checkReader(bobUID, true)
   859  	checkReader(charlieUID, false)
   860  
   861  	// Make alice a writer, and charlie a reader.
   862  	AddTeamWriterForTestOrBust(t, config, tid, aliceUID)
   863  	AddTeamReaderForTestOrBust(t, config, tid, charlieUID)
   864  	checkWriter(aliceUID, aliceKey, true)
   865  	checkWriter(bobUID, bobKey, true)
   866  	checkWriter(charlieUID, charlieKey, false)
   867  	checkReader(aliceUID, true)
   868  	checkReader(bobUID, true)
   869  	checkReader(charlieUID, true)
   870  
   871  	// Promote charlie to writer.
   872  	AddTeamWriterForTestOrBust(t, config, tid, charlieUID)
   873  	checkWriter(aliceUID, aliceKey, true)
   874  	checkWriter(bobUID, bobKey, true)
   875  	checkWriter(charlieUID, charlieKey, true)
   876  	checkReader(aliceUID, true)
   877  	checkReader(bobUID, true)
   878  	checkReader(charlieUID, true)
   879  }
   880  
   881  // Check that MakeSuccessor gets the right key gen for teams.
   882  func TestRootMetadataTeamMakeSuccessor(t *testing.T) {
   883  	config := MakeTestConfigOrBust(t, "alice")
   884  	ctx := context.Background()
   885  	defer CheckConfigAndShutdown(ctx, t, config)
   886  
   887  	teamInfos := AddEmptyTeamsForTestOrBust(t, config, "t1")
   888  	tid := teamInfos[0].TID
   889  
   890  	tlfID := tlf.FakeID(1, tlf.SingleTeam)
   891  	h := tlfhandle.NewHandle(
   892  		tlf.SingleTeam,
   893  		map[keybase1.UserOrTeamID]kbname.NormalizedUsername{
   894  			tid.AsUserOrTeam(): "t1",
   895  		}, nil, nil, "t1", tlf.NullID)
   896  	rmd, err := makeInitialRootMetadata(kbfsmd.SegregatedKeyBundlesVer, tlfID, h)
   897  	require.NoError(t, err)
   898  	rmd.bareMd.SetLatestKeyGenerationForTeamTLF(teamInfos[0].LatestKeyGen)
   899  	// Make sure the MD looks readable.
   900  	rmd.data.Dir.BlockPointer = data.BlockPointer{ID: kbfsblock.FakeID(1)}
   901  
   902  	firstKeyGen := rmd.LatestKeyGeneration()
   903  	require.Equal(t, kbfsmd.FirstValidKeyGen, firstKeyGen)
   904  
   905  	rmd2, err := rmd.MakeSuccessor(context.Background(),
   906  		config.MetadataVersion(), config.Codec(),
   907  		config.KeyManager(), config.KBPKI(), config.KBPKI(), config,
   908  		kbfsmd.FakeID(1), true)
   909  	require.NoError(t, err)
   910  
   911  	// No increase yet.
   912  	kg := rmd2.LatestKeyGeneration()
   913  	require.Equal(t, firstKeyGen, kg)
   914  
   915  	AddTeamKeyForTestOrBust(t, config, tid)
   916  
   917  	rmd3, err := rmd2.MakeSuccessor(context.Background(),
   918  		config.MetadataVersion(), config.Codec(),
   919  		config.KeyManager(), config.KBPKI(), config.KBPKI(), config,
   920  		kbfsmd.FakeID(2), true)
   921  	require.NoError(t, err)
   922  
   923  	// Should have been bumped by one.
   924  	kg = rmd3.LatestKeyGeneration()
   925  	require.Equal(t, firstKeyGen+1, kg)
   926  }
   927  
   928  func TestRootMetadata(t *testing.T) {
   929  	tests := []func(*testing.T, kbfsmd.MetadataVer){
   930  		testRootMetadataGetTlfHandlePublic,
   931  		testRootMetadataGetTlfHandlePrivate,
   932  		testRootMetadataLatestKeyGenerationPrivate,
   933  		testRootMetadataLatestKeyGenerationPublic,
   934  		testMakeRekeyReadError,
   935  		testMakeRekeyReadErrorResolvedHandle,
   936  		testRootMetadataFinalIsFinal,
   937  	}
   938  	runTestsOverMetadataVers(t, "testRootMetadata", tests)
   939  }