github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/kbfsmd/root_metadata_v3_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 kbfsmd
     6  
     7  import (
     8  	"testing"
     9  
    10  	"github.com/keybase/client/go/kbfs/kbfscodec"
    11  	"github.com/keybase/client/go/kbfs/kbfscrypto"
    12  	"github.com/keybase/client/go/kbfs/tlf"
    13  	"github.com/keybase/client/go/protocol/keybase1"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestRootMetadataVersionV3(t *testing.T) {
    18  	counter := uint32(1)
    19  	check := func(ty tlf.Type, keyType tlf.KeyingType, ver MetadataVer) {
    20  		tlfID := tlf.FakeID(byte(counter), ty)
    21  		var id keybase1.UserOrTeamID
    22  		var readers []keybase1.UserOrTeamID
    23  		if keyType == tlf.TeamKeying {
    24  			id = keybase1.MakeTestTeamID(
    25  				counter, ty == tlf.Public).AsUserOrTeam()
    26  		} else {
    27  			id = keybase1.MakeTestUID(counter).AsUserOrTeam()
    28  			if ty == tlf.Public {
    29  				readers = append(readers, keybase1.PublicUID.AsUserOrTeam())
    30  			}
    31  		}
    32  		bh, err := tlf.MakeHandle(
    33  			[]keybase1.UserOrTeamID{id}, readers, nil, nil, nil)
    34  		require.NoError(t, err)
    35  
    36  		rmd, err := MakeInitialRootMetadataV3(tlfID, bh)
    37  		require.NoError(t, err)
    38  
    39  		require.Equal(t, ver, rmd.Version())
    40  		counter++
    41  	}
    42  
    43  	// Classically-keyed V3 MDs, and single team MDs, should have
    44  	// SegregatedKeyBundlesVer.
    45  	check(tlf.Private, tlf.PrivateKeying, SegregatedKeyBundlesVer)
    46  	check(tlf.Public, tlf.PublicKeying, SegregatedKeyBundlesVer)
    47  	check(tlf.SingleTeam, tlf.TeamKeying, SegregatedKeyBundlesVer)
    48  
    49  	// Non-single-team MDs should have ImplicitTeamsVer.
    50  	check(tlf.Private, tlf.TeamKeying, ImplicitTeamsVer)
    51  	check(tlf.Public, tlf.TeamKeying, ImplicitTeamsVer)
    52  }
    53  
    54  func TestRootMetadataHardcodedV3(t *testing.T) {
    55  	tlfID := tlf.FakeID(1, tlf.Private)
    56  
    57  	uid := keybase1.MakeTestUID(1)
    58  	bh, err := tlf.MakeHandle(
    59  		[]keybase1.UserOrTeamID{uid.AsUserOrTeam()}, nil, nil, nil, nil)
    60  	require.NoError(t, err)
    61  
    62  	brmd, err := MakeInitialRootMetadataV3(tlfID, bh)
    63  	require.NoError(t, err)
    64  
    65  	// This should msgpack-encode as a uint8 (0xcc), and not an
    66  	// int8 (0xd0).
    67  	brmd.Revision = 128
    68  
    69  	codec := kbfscodec.NewMsgpack()
    70  
    71  	// The TLF{Writer,Reader}KeyBundleIDs should be encoded as
    72  	// nils (0xc0) and not omitted.
    73  	//
    74  	// This was generated by starting with []byte{} and copying
    75  	// the data in the error message for the require.Equal below.
    76  	expectedBuf := []byte{
    77  		0x86, 0xa5, 0x46, 0x6c, 0x61, 0x67,
    78  		0x73, 0x0, 0xb1, 0x4c, 0x61, 0x73, 0x74, 0x4d, 0x6f,
    79  		0x64, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x55, 0x73,
    80  		0x65, 0x72, 0xa0, 0xa8, 0x50, 0x72, 0x65, 0x76, 0x52,
    81  		0x6f, 0x6f, 0x74, 0xc0, 0xa8, 0x52, 0x65, 0x76, 0x69,
    82  		0x73, 0x69, 0x6f, 0x6e, 0xcc, 0x80, 0xa4, 0x72, 0x6b,
    83  		0x69, 0x64, 0xc0, 0xa3, 0x77, 0x6d, 0x64, 0x8a, 0xa3,
    84  		0x42, 0x49, 0x44, 0xc4, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0,
    85  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    86  		0xa9, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67,
    87  		0x65, 0x0, 0xa2, 0x49, 0x44, 0xc4, 0x10, 0x1, 0x0,
    88  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    89  		0x0, 0x0, 0x16, 0xa8, 0x52, 0x65, 0x66, 0x42, 0x79,
    90  		0x74, 0x65, 0x73, 0x0, 0xaa, 0x55, 0x6e, 0x72, 0x65,
    91  		0x66, 0x42, 0x79, 0x74, 0x65, 0x73, 0x0, 0xa6, 0x57,
    92  		0x46, 0x6c, 0x61, 0x67, 0x73, 0x0, 0xa4, 0x64, 0x61,
    93  		0x74, 0x61, 0xc0, 0xa3, 0x6c, 0x6b, 0x67, 0x0, 0xa3,
    94  		0x6c, 0x6d, 0x77, 0xa0, 0xa4, 0x77, 0x6b, 0x69, 0x64,
    95  		0xc0,
    96  	}
    97  
    98  	buf, err := codec.Encode(brmd)
    99  	require.NoError(t, err)
   100  	require.Equal(t, expectedBuf, buf)
   101  }
   102  
   103  func TestRootMetadataV3ExtraNew(t *testing.T) {
   104  	tlfID := tlf.FakeID(1, tlf.Private)
   105  
   106  	uid := keybase1.MakeTestUID(1)
   107  	bh, err := tlf.MakeHandle(
   108  		[]keybase1.UserOrTeamID{uid.AsUserOrTeam()}, nil, nil, nil, nil)
   109  	require.NoError(t, err)
   110  
   111  	rmd, err := MakeInitialRootMetadataV3(tlfID, bh)
   112  	require.NoError(t, err)
   113  
   114  	codec := kbfscodec.NewMsgpack()
   115  	extra := FakeInitialRekey(rmd, bh, kbfscrypto.TLFPublicKey{})
   116  	extraV3, ok := extra.(*ExtraMetadataV3)
   117  	require.True(t, ok)
   118  	require.True(t, extraV3.wkbNew)
   119  	require.True(t, extraV3.rkbNew)
   120  
   121  	err = rmd.FinalizeRekey(codec, extra)
   122  	require.NoError(t, err)
   123  	require.True(t, extraV3.wkbNew)
   124  	require.True(t, extraV3.rkbNew)
   125  
   126  	_, extraCopy, err := rmd.MakeSuccessorCopy(
   127  		codec, extra, -1, nil, true)
   128  	require.NoError(t, err)
   129  
   130  	extraV3Copy, ok := extraCopy.(*ExtraMetadataV3)
   131  	require.True(t, ok)
   132  	require.False(t, extraV3Copy.wkbNew)
   133  	require.False(t, extraV3Copy.rkbNew)
   134  }
   135  
   136  func TestIsValidRekeyRequestBasicV3(t *testing.T) {
   137  	tlfID := tlf.FakeID(1, tlf.Private)
   138  
   139  	uid := keybase1.MakeTestUID(1)
   140  	bh, err := tlf.MakeHandle(
   141  		[]keybase1.UserOrTeamID{uid.AsUserOrTeam()}, nil, nil, nil, nil)
   142  	require.NoError(t, err)
   143  
   144  	codec := kbfscodec.NewMsgpack()
   145  
   146  	brmd, err := MakeInitialRootMetadataV3(tlfID, bh)
   147  	require.NoError(t, err)
   148  	extra := FakeInitialRekey(brmd, bh, kbfscrypto.TLFPublicKey{})
   149  
   150  	newBrmd, err := brmd.DeepCopy(codec)
   151  	require.NoError(t, err)
   152  	newExtra, err := extra.DeepCopy(codec)
   153  	require.NoError(t, err)
   154  
   155  	ok, err := newBrmd.IsValidRekeyRequest(
   156  		codec, brmd, newBrmd.LastModifyingWriter(), extra, newExtra)
   157  	require.NoError(t, err)
   158  	// Should fail because the copy bit is unset.
   159  	require.False(t, ok)
   160  
   161  	// Set the copy bit; note the writer metadata is the same.
   162  	newBrmd.SetWriterMetadataCopiedBit()
   163  
   164  	// There's no internal signature to compare, so this should
   165  	// then work.
   166  
   167  	ok, err = newBrmd.IsValidRekeyRequest(
   168  		codec, brmd, newBrmd.LastModifyingWriter(), extra, newExtra)
   169  	require.NoError(t, err)
   170  	require.True(t, ok)
   171  }
   172  
   173  func TestRootMetadataPublicVersionV3(t *testing.T) {
   174  	tlfID := tlf.FakeID(1, tlf.Public)
   175  
   176  	uid := keybase1.MakeTestUID(1)
   177  	bh, err := tlf.MakeHandle(
   178  		[]keybase1.UserOrTeamID{uid.AsUserOrTeam()},
   179  		[]keybase1.UserOrTeamID{keybase1.UserOrTeamID(keybase1.PublicUID)},
   180  		nil, nil, nil)
   181  	require.NoError(t, err)
   182  
   183  	rmd, err := MakeInitialRootMetadataV3(tlfID, bh)
   184  	require.NoError(t, err)
   185  	require.Equal(t, SegregatedKeyBundlesVer, rmd.Version())
   186  
   187  	bh2, err := rmd.MakeBareTlfHandle(nil)
   188  	require.NoError(t, err)
   189  	require.Equal(t, bh, bh2)
   190  }
   191  
   192  func TestRootMetadataSingleTeamVersionV3(t *testing.T) {
   193  	tlfID := tlf.FakeID(1, tlf.SingleTeam)
   194  
   195  	tid := keybase1.MakeTestTeamID(1, false)
   196  	bh, err := tlf.MakeHandle(
   197  		[]keybase1.UserOrTeamID{tid.AsUserOrTeam()}, nil, nil, nil, nil)
   198  	require.NoError(t, err)
   199  
   200  	rmd, err := MakeInitialRootMetadataV3(tlfID, bh)
   201  	require.NoError(t, err)
   202  	require.Equal(t, SegregatedKeyBundlesVer, rmd.Version())
   203  
   204  	bh2, err := rmd.MakeBareTlfHandle(nil)
   205  	require.NoError(t, err)
   206  	require.Equal(t, bh, bh2)
   207  }
   208  
   209  func TestRevokeRemovedDevicesV3(t *testing.T) {
   210  	uid1 := keybase1.MakeTestUID(0x1)
   211  	uid2 := keybase1.MakeTestUID(0x2)
   212  	uid3 := keybase1.MakeTestUID(0x3)
   213  
   214  	key1 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key1")
   215  	key2 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key2")
   216  	key3 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key3")
   217  
   218  	half1a := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x1})
   219  	half2a := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x3})
   220  	half3a := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x5})
   221  
   222  	id1a, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid1, key1, half1a)
   223  	require.NoError(t, err)
   224  	id2a, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid2, key2, half2a)
   225  	require.NoError(t, err)
   226  	id3a, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid3, key3, half3a)
   227  	require.NoError(t, err)
   228  
   229  	tlfID := tlf.FakeID(1, tlf.Private)
   230  
   231  	bh, err := tlf.MakeHandle(
   232  		[]keybase1.UserOrTeamID{uid1.AsUserOrTeam(), uid2.AsUserOrTeam()},
   233  		[]keybase1.UserOrTeamID{uid3.AsUserOrTeam()}, nil, nil, nil)
   234  	require.NoError(t, err)
   235  
   236  	brmd, err := MakeInitialRootMetadataV3(tlfID, bh)
   237  	require.NoError(t, err)
   238  
   239  	extra := FakeInitialRekey(brmd, bh, kbfscrypto.TLFPublicKey{})
   240  
   241  	wkb, rkb, err := brmd.getTLFKeyBundles(extra)
   242  	require.NoError(t, err)
   243  
   244  	*wkb = TLFWriterKeyBundleV3{
   245  		Keys: UserDeviceKeyInfoMapV3{
   246  			uid1: DeviceKeyInfoMapV3{
   247  				key1: TLFCryptKeyInfo{
   248  					ServerHalfID: id1a,
   249  					EPubKeyIndex: 0,
   250  				},
   251  			},
   252  			uid2: DeviceKeyInfoMapV3{
   253  				key2: TLFCryptKeyInfo{
   254  					ServerHalfID: id2a,
   255  					EPubKeyIndex: 0,
   256  				},
   257  			},
   258  		},
   259  	}
   260  
   261  	*rkb = TLFReaderKeyBundleV3{
   262  		Keys: UserDeviceKeyInfoMapV3{
   263  			uid3: DeviceKeyInfoMapV3{
   264  				key3: TLFCryptKeyInfo{
   265  					ServerHalfID: id3a,
   266  					EPubKeyIndex: 0,
   267  				},
   268  			},
   269  		},
   270  	}
   271  
   272  	updatedWriterKeys := UserDevicePublicKeys{
   273  		uid1: {key1: true},
   274  	}
   275  	updatedReaderKeys := UserDevicePublicKeys{
   276  		uid3: {key3: true},
   277  	}
   278  
   279  	removalInfo, err := brmd.RevokeRemovedDevices(
   280  		updatedWriterKeys, updatedReaderKeys, extra)
   281  	require.NoError(t, err)
   282  	require.Equal(t, ServerHalfRemovalInfo{
   283  		uid2: UserServerHalfRemovalInfo{
   284  			UserRemoved: true,
   285  			DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{
   286  				key2: []kbfscrypto.TLFCryptKeyServerHalfID{id2a},
   287  			},
   288  		},
   289  	}, removalInfo)
   290  
   291  	expectedWKB := TLFWriterKeyBundleV3{
   292  		Keys: UserDeviceKeyInfoMapV3{
   293  			uid1: DeviceKeyInfoMapV3{
   294  				key1: TLFCryptKeyInfo{
   295  					ServerHalfID: id1a,
   296  					EPubKeyIndex: 0,
   297  				},
   298  			},
   299  		},
   300  	}
   301  	require.Equal(t, expectedWKB, *wkb)
   302  
   303  	expectedRKB := TLFReaderKeyBundleV3{
   304  		Keys: UserDeviceKeyInfoMapV3{
   305  			uid3: DeviceKeyInfoMapV3{
   306  				key3: TLFCryptKeyInfo{
   307  					ServerHalfID: id3a,
   308  					EPubKeyIndex: 0,
   309  				},
   310  			},
   311  		},
   312  	}
   313  	require.Equal(t, expectedRKB, *rkb)
   314  }
   315  
   316  // TestRevokeLastDeviceV3 checks behavior of RevokeRemovedDevices with
   317  // respect to removing the last device of a user vs. removing the user
   318  // completely.
   319  func TestRevokeLastDeviceV3(t *testing.T) {
   320  	uid1 := keybase1.MakeTestUID(0x1)
   321  	uid2 := keybase1.MakeTestUID(0x2)
   322  	uid3 := keybase1.MakeTestUID(0x3)
   323  	uid4 := keybase1.MakeTestUID(0x4)
   324  
   325  	key1 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key1")
   326  	key2 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key2")
   327  
   328  	half1 := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x1})
   329  	half2 := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x2})
   330  
   331  	id1, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid1, key1, half1)
   332  	require.NoError(t, err)
   333  	id2, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid2, key2, half2)
   334  	require.NoError(t, err)
   335  
   336  	tlfID := tlf.FakeID(1, tlf.Private)
   337  
   338  	bh, err := tlf.MakeHandle(
   339  		[]keybase1.UserOrTeamID{uid1.AsUserOrTeam(), uid2.AsUserOrTeam()},
   340  		[]keybase1.UserOrTeamID{uid3.AsUserOrTeam(), uid4.AsUserOrTeam()},
   341  		nil, nil, nil)
   342  	require.NoError(t, err)
   343  
   344  	brmd, err := MakeInitialRootMetadataV3(tlfID, bh)
   345  	require.NoError(t, err)
   346  
   347  	extra := FakeInitialRekey(brmd, bh, kbfscrypto.TLFPublicKey{})
   348  
   349  	wkb, rkb, err := brmd.getTLFKeyBundles(extra)
   350  	require.NoError(t, err)
   351  
   352  	*wkb = TLFWriterKeyBundleV3{
   353  		Keys: UserDeviceKeyInfoMapV3{
   354  			uid1: DeviceKeyInfoMapV3{
   355  				key1: TLFCryptKeyInfo{
   356  					ServerHalfID: id1,
   357  					EPubKeyIndex: 0,
   358  				},
   359  			},
   360  			uid2: DeviceKeyInfoMapV3{
   361  				key2: TLFCryptKeyInfo{
   362  					ServerHalfID: id2,
   363  					EPubKeyIndex: 1,
   364  				},
   365  			},
   366  		},
   367  	}
   368  
   369  	*rkb = TLFReaderKeyBundleV3{
   370  		Keys: UserDeviceKeyInfoMapV3{
   371  			uid3: DeviceKeyInfoMapV3{},
   372  			uid4: DeviceKeyInfoMapV3{},
   373  		},
   374  	}
   375  
   376  	updatedWriterKeys := UserDevicePublicKeys{
   377  		uid1: {},
   378  	}
   379  	updatedReaderKeys := UserDevicePublicKeys{
   380  		uid3: {},
   381  	}
   382  
   383  	removalInfo, err := brmd.RevokeRemovedDevices(
   384  		updatedWriterKeys, updatedReaderKeys, extra)
   385  	require.NoError(t, err)
   386  	require.Equal(t, ServerHalfRemovalInfo{
   387  		uid1: UserServerHalfRemovalInfo{
   388  			DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{
   389  				key1: []kbfscrypto.TLFCryptKeyServerHalfID{id1},
   390  			},
   391  		},
   392  		uid2: UserServerHalfRemovalInfo{
   393  			UserRemoved: true,
   394  			DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{
   395  				key2: []kbfscrypto.TLFCryptKeyServerHalfID{id2},
   396  			},
   397  		},
   398  		uid4: UserServerHalfRemovalInfo{
   399  			UserRemoved:         true,
   400  			DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{},
   401  		},
   402  	}, removalInfo)
   403  
   404  	expectedWKB := TLFWriterKeyBundleV3{
   405  		Keys: UserDeviceKeyInfoMapV3{
   406  			uid1: DeviceKeyInfoMapV3{},
   407  		},
   408  	}
   409  	require.Equal(t, expectedWKB, *wkb)
   410  
   411  	expectedRKB := TLFReaderKeyBundleV3{
   412  		Keys: UserDeviceKeyInfoMapV3{
   413  			uid3: DeviceKeyInfoMapV3{},
   414  		},
   415  	}
   416  	require.Equal(t, expectedRKB, *rkb)
   417  }
   418  
   419  // expectedRekeyInfoV3 contains all the information needed to check a
   420  // rekey run (that doesn't add a generation).
   421  //
   422  // If writerPrivKeys is empty, then writerEPubKeyIndex is ignored, and
   423  // similarly for readerPrivKeys. If both are empty, then ePubKey is
   424  // also ignored.
   425  type expectedRekeyInfoV3 struct {
   426  	writerPrivKeys, readerPrivKeys         userDevicePrivateKeys
   427  	serverHalves                           UserDeviceKeyServerHalves
   428  	writerEPubKeyIndex, readerEPubKeyIndex int
   429  	ePubKey                                kbfscrypto.TLFEphemeralPublicKey
   430  }
   431  
   432  // checkGetTLFCryptKeyV3 checks that wkb and rkb contain the info
   433  // necessary to get the TLF crypt key for each user in expected, which
   434  // must all match expectedTLFCryptKey.
   435  func checkGetTLFCryptKeyV3(t *testing.T, expected expectedRekeyInfoV3,
   436  	expectedTLFCryptKey kbfscrypto.TLFCryptKey,
   437  	wkb *TLFWriterKeyBundleV3, rkb *TLFReaderKeyBundleV3) {
   438  	for uid, privKeys := range expected.writerPrivKeys {
   439  		for privKey := range privKeys {
   440  			pubKey := privKey.GetPublicKey()
   441  			serverHalf, ok := expected.serverHalves[uid][pubKey]
   442  			require.True(t, ok, "writer uid=%s, key=%s",
   443  				uid, pubKey)
   444  
   445  			info, ok := wkb.Keys[uid][pubKey]
   446  			require.True(t, ok)
   447  
   448  			ePubKey := wkb.TLFEphemeralPublicKeys[info.EPubKeyIndex]
   449  
   450  			checkCryptKeyInfo(t, privKey, serverHalf,
   451  				expected.writerEPubKeyIndex, expected.ePubKey,
   452  				expectedTLFCryptKey, info, ePubKey)
   453  		}
   454  	}
   455  
   456  	for uid, privKeys := range expected.readerPrivKeys {
   457  		for privKey := range privKeys {
   458  			pubKey := privKey.GetPublicKey()
   459  			serverHalf, ok := expected.serverHalves[uid][pubKey]
   460  			require.True(t, ok, "reader uid=%s, key=%s",
   461  				uid, pubKey)
   462  
   463  			info, ok := rkb.Keys[uid][pubKey]
   464  			require.True(t, ok)
   465  
   466  			ePubKey := rkb.TLFEphemeralPublicKeys[info.EPubKeyIndex]
   467  
   468  			checkCryptKeyInfo(t, privKey, serverHalf,
   469  				expected.readerEPubKeyIndex, expected.ePubKey,
   470  				expectedTLFCryptKey, info, ePubKey)
   471  		}
   472  	}
   473  }
   474  
   475  func userDeviceKeyInfoMapV3ToPublicKeys(udkimV3 UserDeviceKeyInfoMapV3) UserDevicePublicKeys {
   476  	pubKeys := make(UserDevicePublicKeys)
   477  	for uid, dkimV3 := range udkimV3 {
   478  		pubKeys[uid] = make(DevicePublicKeys)
   479  		for key := range dkimV3 {
   480  			pubKeys[uid][key] = true
   481  		}
   482  	}
   483  	return pubKeys
   484  }
   485  
   486  // checkKeyBundlesV3 checks that wkb and rkb contain exactly the info
   487  // expected from expectedRekeyInfos and expectedPubKey.
   488  func checkKeyBundlesV3(t *testing.T, expectedRekeyInfos []expectedRekeyInfoV3,
   489  	expectedTLFCryptKey kbfscrypto.TLFCryptKey,
   490  	expectedPubKey kbfscrypto.TLFPublicKey,
   491  	wkb *TLFWriterKeyBundleV3, rkb *TLFReaderKeyBundleV3) {
   492  	expectedWriterPubKeys := make(UserDevicePublicKeys)
   493  	expectedReaderPubKeys := make(UserDevicePublicKeys)
   494  	var expectedWriterEPublicKeys,
   495  		expectedReaderEPublicKeys kbfscrypto.TLFEphemeralPublicKeys
   496  	for _, expected := range expectedRekeyInfos {
   497  		expectedWriterPubKeys = accumulatePublicKeys(
   498  			expectedWriterPubKeys,
   499  			expected.writerPrivKeys.toPublicKeys())
   500  		expectedReaderPubKeys = accumulatePublicKeys(
   501  			expectedReaderPubKeys,
   502  			expected.readerPrivKeys.toPublicKeys())
   503  
   504  		if expected.writerPrivKeys.hasKeys() {
   505  			require.Equal(t, expected.writerEPubKeyIndex,
   506  				len(expectedWriterEPublicKeys))
   507  			expectedWriterEPublicKeys = append(
   508  				expectedWriterEPublicKeys,
   509  				expected.ePubKey)
   510  		}
   511  
   512  		if expected.readerPrivKeys.hasKeys() {
   513  			require.Equal(t, expected.readerEPubKeyIndex,
   514  				len(expectedReaderEPublicKeys))
   515  			expectedReaderEPublicKeys = append(
   516  				expectedReaderEPublicKeys,
   517  				expected.ePubKey)
   518  		}
   519  	}
   520  
   521  	writerPubKeys := userDeviceKeyInfoMapV3ToPublicKeys(wkb.Keys)
   522  	readerPubKeys := userDeviceKeyInfoMapV3ToPublicKeys(rkb.Keys)
   523  
   524  	require.Equal(t, expectedWriterPubKeys, writerPubKeys)
   525  	require.Equal(t, expectedReaderPubKeys, readerPubKeys)
   526  
   527  	require.Equal(t, expectedWriterEPublicKeys, wkb.TLFEphemeralPublicKeys)
   528  	require.Equal(t, expectedReaderEPublicKeys, rkb.TLFEphemeralPublicKeys)
   529  
   530  	require.Equal(t, expectedPubKey, wkb.TLFPublicKey)
   531  
   532  	for _, expected := range expectedRekeyInfos {
   533  		expectedUserPubKeys := unionPublicKeyUsers(
   534  			expected.writerPrivKeys.toPublicKeys(),
   535  			expected.readerPrivKeys.toPublicKeys())
   536  		userPubKeys := userDeviceServerHalvesToPublicKeys(
   537  			expected.serverHalves)
   538  		require.Equal(t, expectedUserPubKeys.RemoveKeylessUsersForTest(), userPubKeys)
   539  		checkGetTLFCryptKeyV3(t,
   540  			expected, expectedTLFCryptKey, wkb, rkb)
   541  	}
   542  }
   543  
   544  func TestRootMetadataV3UpdateKeyBundles(t *testing.T) {
   545  	uid1 := keybase1.MakeTestUID(1)
   546  	uid2 := keybase1.MakeTestUID(2)
   547  	uid3 := keybase1.MakeTestUID(3)
   548  
   549  	privKey1 := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key1")
   550  	privKey2 := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key2")
   551  	privKey3 := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key3")
   552  
   553  	updatedWriterKeys := UserDevicePublicKeys{
   554  		uid1: {privKey1.GetPublicKey(): true},
   555  		uid2: {privKey2.GetPublicKey(): true},
   556  	}
   557  
   558  	updatedReaderKeys := UserDevicePublicKeys{
   559  		uid3: {privKey3.GetPublicKey(): true},
   560  	}
   561  
   562  	tlfID := tlf.FakeID(1, tlf.Private)
   563  
   564  	bh, err := tlf.MakeHandle(
   565  		[]keybase1.UserOrTeamID{uid1.AsUserOrTeam(), uid2.AsUserOrTeam()},
   566  		[]keybase1.UserOrTeamID{uid3.AsUserOrTeam()},
   567  		[]keybase1.SocialAssertion{{}},
   568  		nil, nil)
   569  	require.NoError(t, err)
   570  
   571  	rmd, err := MakeInitialRootMetadataV3(tlfID, bh)
   572  	require.NoError(t, err)
   573  
   574  	codec := kbfscodec.NewMsgpack()
   575  
   576  	ePubKey1, ePrivKey1, err := kbfscrypto.MakeRandomTLFEphemeralKeys()
   577  	require.NoError(t, err)
   578  
   579  	// Add first key generations, although only the last one
   580  	// matters.
   581  
   582  	latestKeyGen := FirstValidKeyGen + 5
   583  	var pubKey kbfscrypto.TLFPublicKey
   584  	var tlfCryptKey kbfscrypto.TLFCryptKey
   585  	var extra ExtraMetadata
   586  	var serverHalves1 UserDeviceKeyServerHalves
   587  	for keyGen := FirstValidKeyGen; keyGen <= latestKeyGen; keyGen++ {
   588  		fakeKeyData := [32]byte{byte(keyGen)}
   589  		pubKey = kbfscrypto.MakeTLFPublicKey(fakeKeyData)
   590  		nextTLFCryptKey := kbfscrypto.MakeTLFCryptKey(fakeKeyData)
   591  
   592  		// Use the same ephemeral keys for initial key
   593  		// generations, even though that can't happen in
   594  		// practice.
   595  		var err error
   596  		extra, serverHalves1, err = rmd.AddKeyGeneration(codec,
   597  			extra, updatedWriterKeys, updatedReaderKeys,
   598  			ePubKey1, ePrivKey1,
   599  			pubKey, tlfCryptKey, nextTLFCryptKey)
   600  		require.NoError(t, err)
   601  
   602  		tlfCryptKey = nextTLFCryptKey
   603  	}
   604  
   605  	wkb, rkb, err := rmd.getTLFKeyBundles(extra)
   606  	require.NoError(t, err)
   607  
   608  	expectedRekeyInfo1 := expectedRekeyInfoV3{
   609  		writerPrivKeys: userDevicePrivateKeys{
   610  			uid1: {privKey1: true},
   611  			uid2: {privKey2: true},
   612  		},
   613  		readerPrivKeys: userDevicePrivateKeys{
   614  			uid3: {privKey3: true},
   615  		},
   616  		serverHalves:       serverHalves1,
   617  		writerEPubKeyIndex: 0,
   618  		readerEPubKeyIndex: 0,
   619  		ePubKey:            ePubKey1,
   620  	}
   621  	expectedRekeyInfos := []expectedRekeyInfoV3{expectedRekeyInfo1}
   622  
   623  	checkKeyBundlesV3(t, expectedRekeyInfos, tlfCryptKey, pubKey, wkb, rkb)
   624  
   625  	// Do update to check idempotency.
   626  
   627  	tlfCryptKeys := []kbfscrypto.TLFCryptKey{tlfCryptKey}
   628  
   629  	serverHalves1b, err := rmd.UpdateKeyBundles(codec,
   630  		extra, updatedWriterKeys, updatedReaderKeys,
   631  		ePubKey1, ePrivKey1, tlfCryptKeys)
   632  	require.NoError(t, err)
   633  	require.Equal(t, 1, len(serverHalves1b))
   634  
   635  	expectedRekeyInfo1b := expectedRekeyInfoV3{
   636  		serverHalves: serverHalves1b[0],
   637  	}
   638  
   639  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo1b)
   640  
   641  	checkKeyBundlesV3(t, expectedRekeyInfos, tlfCryptKey, pubKey, wkb, rkb)
   642  
   643  	// Rekey.
   644  
   645  	privKey1b := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key1b")
   646  	updatedWriterKeys[uid1][privKey1b.GetPublicKey()] = true
   647  
   648  	privKey3b := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key3b")
   649  	updatedReaderKeys[uid3][privKey3b.GetPublicKey()] = true
   650  
   651  	ePubKey2, ePrivKey2, err := kbfscrypto.MakeRandomTLFEphemeralKeys()
   652  	require.NoError(t, err)
   653  
   654  	serverHalves2, err := rmd.UpdateKeyBundles(codec,
   655  		extra, updatedWriterKeys, updatedReaderKeys,
   656  		ePubKey2, ePrivKey2, tlfCryptKeys)
   657  	require.NoError(t, err)
   658  	require.Equal(t, 1, len(serverHalves2))
   659  
   660  	expectedRekeyInfo2 := expectedRekeyInfoV3{
   661  		writerPrivKeys: userDevicePrivateKeys{
   662  			uid1: {privKey1b: true},
   663  		},
   664  		readerPrivKeys: userDevicePrivateKeys{
   665  			uid3: {privKey3b: true},
   666  		},
   667  		serverHalves:       serverHalves2[0],
   668  		writerEPubKeyIndex: 1,
   669  		readerEPubKeyIndex: 1,
   670  		ePubKey:            ePubKey2,
   671  	}
   672  
   673  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo2)
   674  
   675  	checkKeyBundlesV3(t, expectedRekeyInfos, tlfCryptKey, pubKey, wkb, rkb)
   676  
   677  	// Do again to check idempotency.
   678  
   679  	serverHalves2b, err := rmd.UpdateKeyBundles(codec,
   680  		extra, updatedWriterKeys, updatedReaderKeys,
   681  		ePubKey2, ePrivKey2, tlfCryptKeys)
   682  	require.NoError(t, err)
   683  	require.Equal(t, 1, len(serverHalves2b))
   684  
   685  	expectedRekeyInfo2b := expectedRekeyInfoV3{
   686  		serverHalves: serverHalves2b[0],
   687  	}
   688  
   689  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo2b)
   690  
   691  	checkKeyBundlesV3(t, expectedRekeyInfos, tlfCryptKey, pubKey, wkb, rkb)
   692  
   693  	// Rekey writers only.
   694  
   695  	privKey1c := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key1c")
   696  	updatedWriterKeys[uid1][privKey1c.GetPublicKey()] = true
   697  
   698  	ePubKey3, ePrivKey3, err := kbfscrypto.MakeRandomTLFEphemeralKeys()
   699  	require.NoError(t, err)
   700  
   701  	serverHalves3, err := rmd.UpdateKeyBundles(codec,
   702  		extra, updatedWriterKeys, updatedReaderKeys,
   703  		ePubKey3, ePrivKey3, tlfCryptKeys)
   704  	require.NoError(t, err)
   705  	require.Equal(t, 1, len(serverHalves3))
   706  
   707  	expectedRekeyInfo3 := expectedRekeyInfoV3{
   708  		writerPrivKeys: userDevicePrivateKeys{
   709  			uid1: {privKey1c: true},
   710  		},
   711  		readerPrivKeys:     nil,
   712  		serverHalves:       serverHalves3[0],
   713  		writerEPubKeyIndex: 2,
   714  		readerEPubKeyIndex: -1,
   715  		ePubKey:            ePubKey3,
   716  	}
   717  
   718  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo3)
   719  
   720  	checkKeyBundlesV3(t, expectedRekeyInfos, tlfCryptKey, pubKey, wkb, rkb)
   721  
   722  	// Do again to check idempotency.
   723  
   724  	serverHalves3b, err := rmd.UpdateKeyBundles(codec,
   725  		extra, updatedWriterKeys, updatedReaderKeys,
   726  		ePubKey3, ePrivKey3, tlfCryptKeys)
   727  	require.NoError(t, err)
   728  	require.Equal(t, 1, len(serverHalves3b))
   729  
   730  	expectedRekeyInfo3b := expectedRekeyInfoV3{
   731  		serverHalves: serverHalves3b[0],
   732  	}
   733  
   734  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo3b)
   735  
   736  	checkKeyBundlesV3(t, expectedRekeyInfos, tlfCryptKey, pubKey, wkb, rkb)
   737  
   738  	// Reader rekey.
   739  
   740  	privKey3c := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key3c")
   741  	privKey3d := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key3d")
   742  	updatedReaderKeys[uid3][privKey3c.GetPublicKey()] = true
   743  	updatedReaderKeys[uid3][privKey3d.GetPublicKey()] = true
   744  
   745  	ePubKey4, ePrivKey4, err := kbfscrypto.MakeRandomTLFEphemeralKeys()
   746  	require.NoError(t, err)
   747  
   748  	filteredReaderKeys := UserDevicePublicKeys{
   749  		uid3: updatedReaderKeys[uid3],
   750  	}
   751  	serverHalves4, err := rmd.UpdateKeyBundles(codec,
   752  		extra, nil, filteredReaderKeys,
   753  		ePubKey4, ePrivKey4, tlfCryptKeys)
   754  	require.NoError(t, err)
   755  	require.Equal(t, 1, len(serverHalves4))
   756  
   757  	expectedRekeyInfo4 := expectedRekeyInfoV3{
   758  		writerPrivKeys: nil,
   759  		readerPrivKeys: userDevicePrivateKeys{
   760  			uid3: {privKey3c: true, privKey3d: true},
   761  		},
   762  		serverHalves:       serverHalves4[0],
   763  		writerEPubKeyIndex: -1,
   764  		readerEPubKeyIndex: 2,
   765  		ePubKey:            ePubKey4,
   766  	}
   767  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo4)
   768  	checkKeyBundlesV3(t, expectedRekeyInfos, tlfCryptKey, pubKey, wkb, rkb)
   769  
   770  	// Do again to check idempotency.
   771  
   772  	serverHalves4b, err := rmd.UpdateKeyBundles(codec,
   773  		extra, nil, filteredReaderKeys,
   774  		ePubKey4, ePrivKey4, tlfCryptKeys)
   775  	require.NoError(t, err)
   776  	require.Equal(t, 1, len(serverHalves4b))
   777  
   778  	expectedRekeyInfo4b := expectedRekeyInfoV3{
   779  		serverHalves: serverHalves4b[0],
   780  	}
   781  
   782  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo4b)
   783  
   784  	checkKeyBundlesV3(t, expectedRekeyInfos, tlfCryptKey, pubKey, wkb, rkb)
   785  }
   786  
   787  // TestRootMetadataV3AddKeyGenerationKeylessUsers checks that
   788  // keyless users are handled properly by AddKeyGeneration.
   789  func TestRootMetadataV3AddKeyGenerationKeylessUsers(t *testing.T) {
   790  	uid1 := keybase1.MakeTestUID(1)
   791  	uid2 := keybase1.MakeTestUID(2)
   792  	uid3 := keybase1.MakeTestUID(3)
   793  
   794  	updatedWriterKeys := UserDevicePublicKeys{
   795  		uid1: {},
   796  		uid2: {},
   797  	}
   798  
   799  	updatedReaderKeys := UserDevicePublicKeys{
   800  		uid3: {},
   801  	}
   802  
   803  	tlfID := tlf.FakeID(1, tlf.Private)
   804  
   805  	bh, err := tlf.MakeHandle(
   806  		[]keybase1.UserOrTeamID{uid1.AsUserOrTeam(), uid2.AsUserOrTeam()},
   807  		[]keybase1.UserOrTeamID{uid3.AsUserOrTeam()},
   808  		[]keybase1.SocialAssertion{{}},
   809  		nil, nil)
   810  	require.NoError(t, err)
   811  
   812  	rmd, err := MakeInitialRootMetadataV3(tlfID, bh)
   813  	require.NoError(t, err)
   814  
   815  	codec := kbfscodec.NewMsgpack()
   816  
   817  	ePubKey1, ePrivKey1, err := kbfscrypto.MakeRandomTLFEphemeralKeys()
   818  	require.NoError(t, err)
   819  
   820  	// Add first key generation.
   821  
   822  	fakeKeyData := [32]byte{1}
   823  	pubKey := kbfscrypto.MakeTLFPublicKey(fakeKeyData)
   824  	tlfCryptKey := kbfscrypto.MakeTLFCryptKey(fakeKeyData)
   825  
   826  	extra, serverHalves1, err := rmd.AddKeyGeneration(codec,
   827  		nil, updatedWriterKeys, updatedReaderKeys,
   828  		ePubKey1, ePrivKey1,
   829  		pubKey, kbfscrypto.TLFCryptKey{}, tlfCryptKey)
   830  	require.NoError(t, err)
   831  
   832  	wkb, rkb, err := rmd.getTLFKeyBundles(extra)
   833  	require.NoError(t, err)
   834  
   835  	expectedRekeyInfo1 := expectedRekeyInfoV3{
   836  		writerPrivKeys: userDevicePrivateKeys{
   837  			uid1: {},
   838  			uid2: {},
   839  		},
   840  		readerPrivKeys: userDevicePrivateKeys{
   841  			uid3: {},
   842  		},
   843  		serverHalves: serverHalves1,
   844  	}
   845  	expectedRekeyInfos := []expectedRekeyInfoV3{expectedRekeyInfo1}
   846  
   847  	checkKeyBundlesV3(t, expectedRekeyInfos, tlfCryptKey, pubKey, wkb, rkb)
   848  }