github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/kbfsmd/root_metadata_v2_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  	"context"
     9  	"fmt"
    10  	"sort"
    11  	"testing"
    12  
    13  	"github.com/keybase/client/go/externals"
    14  	"github.com/keybase/client/go/kbfs/kbfscodec"
    15  	"github.com/keybase/client/go/kbfs/kbfscrypto"
    16  	"github.com/keybase/client/go/kbfs/tlf"
    17  	"github.com/keybase/client/go/protocol/keybase1"
    18  	"github.com/keybase/go-codec/codec"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  func TestRootMetadataVersionV2(t *testing.T) {
    23  	tlfID := tlf.FakeID(1, tlf.Private)
    24  
    25  	// Metadata objects with unresolved assertions should have
    26  	// InitialExtraMetadataVer.
    27  
    28  	uid := keybase1.MakeTestUID(1)
    29  	bh, err := tlf.MakeHandle(
    30  		[]keybase1.UserOrTeamID{uid.AsUserOrTeam()}, nil, []keybase1.SocialAssertion{{}},
    31  		nil, nil)
    32  	require.NoError(t, err)
    33  
    34  	rmd, err := MakeInitialRootMetadataV2(tlfID, bh)
    35  	require.NoError(t, err)
    36  
    37  	require.Equal(t, InitialExtraMetadataVer, rmd.Version())
    38  
    39  	// All other folders should use PreExtraMetadataVer.
    40  	bh2, err := tlf.MakeHandle([]keybase1.UserOrTeamID{uid.AsUserOrTeam()}, nil, nil, nil, nil)
    41  	require.NoError(t, err)
    42  
    43  	rmd2, err := MakeInitialRootMetadata(
    44  		InitialExtraMetadataVer, tlfID, bh2)
    45  	require.NoError(t, err)
    46  
    47  	require.Equal(t, PreExtraMetadataVer, rmd2.Version())
    48  
    49  	// ... including if unresolved assertions get resolved.
    50  
    51  	rmd.SetUnresolvedWriters(nil)
    52  	require.Equal(t, PreExtraMetadataVer, rmd.Version())
    53  }
    54  
    55  func TestRootMetadataHardcodedV2(t *testing.T) {
    56  	tlfID := tlf.FakeID(1, tlf.Private)
    57  
    58  	uid := keybase1.MakeTestUID(1)
    59  	bh, err := tlf.MakeHandle(
    60  		[]keybase1.UserOrTeamID{uid.AsUserOrTeam()}, nil, nil, nil, nil)
    61  	require.NoError(t, err)
    62  
    63  	brmd, err := MakeInitialRootMetadataV2(tlfID, bh)
    64  	require.NoError(t, err)
    65  
    66  	// This should msgpack-encode as a uint8 (0xcc), and not an
    67  	// int8 (0xd0).
    68  	brmd.Revision = 128
    69  
    70  	codec := kbfscodec.NewMsgpack()
    71  
    72  	// This was generated by starting with []byte{} and copying
    73  	// the data in the error message for the require.Equal below.
    74  	expectedBuf := []byte{
    75  		0x8d, 0xa3, 0x42, 0x49, 0x44, 0xc4,
    76  		0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    77  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa9, 0x44, 0x69,
    78  		0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x0, 0xa5,
    79  		0x46, 0x6c, 0x61, 0x67, 0x73, 0x0, 0xa2, 0x49, 0x44,
    80  		0xc4, 0x10, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
    81  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0xb1, 0x4c,
    82  		0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79,
    83  		0x69, 0x6e, 0x67, 0x55, 0x73, 0x65, 0x72, 0xa0, 0xb3,
    84  		0x4c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66,
    85  		0x79, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69, 0x74, 0x65,
    86  		0x72, 0xa0, 0xa8, 0x50, 0x72, 0x65, 0x76, 0x52, 0x6f,
    87  		0x6f, 0x74, 0xc0, 0xa8, 0x52, 0x65, 0x66, 0x42, 0x79,
    88  		0x74, 0x65, 0x73, 0x0, 0xa8, 0x52, 0x65, 0x76, 0x69,
    89  		0x73, 0x69, 0x6f, 0x6e, 0xcc, 0x80, 0xaa, 0x55, 0x6e,
    90  		0x72, 0x65, 0x66, 0x42, 0x79, 0x74, 0x65, 0x73, 0x0,
    91  		0xa6, 0x57, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x0, 0xb5,
    92  		0x57, 0x72, 0x69, 0x74, 0x65, 0x72, 0x4d, 0x65, 0x74,
    93  		0x61, 0x64, 0x61, 0x74, 0x61, 0x53, 0x69, 0x67, 0x49,
    94  		0x6e, 0x66, 0x6f, 0x83, 0xa1, 0x6b, 0xc0, 0xa1, 0x73,
    95  		0xc0, 0xa1, 0x76, 0x0, 0xa4, 0x64, 0x61, 0x74, 0x61,
    96  		0xc0,
    97  	}
    98  
    99  	buf, err := codec.Encode(brmd)
   100  	require.NoError(t, err)
   101  	require.Equal(t, expectedBuf, buf)
   102  }
   103  
   104  func TestWriterMetadataV2Empty(t *testing.T) {
   105  	codec := kbfscodec.NewMsgpack()
   106  
   107  	wmd := WriterMetadataV2{
   108  		ID: tlf.FakeID(1, tlf.Public),
   109  	}
   110  	buf, err := codec.Encode(wmd)
   111  	require.NoError(t, err)
   112  	// Expected length derived by running with a known good
   113  	// codec. If the length is greater, something might be broken
   114  	// with omitempty with the Extra struct field.
   115  	require.Equal(t, 112, len(buf))
   116  }
   117  
   118  // Test that old encoded WriterMetadataV2 objects (i.e., without any
   119  // extra fields) can be deserialized and serialized to the same form,
   120  // which is important for RootMetadataV2.IsValidAndSigned().
   121  func testWriterMetadataV2UnchangedEncoding(t *testing.T, ver MetadataVer) {
   122  	encodedWm := []byte{
   123  		0x89, 0xa3, 0x42, 0x49, 0x44, 0xc4, 0x10, 0x0,
   124  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   125  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa9,
   126  		0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67,
   127  		0x65, 0x64, 0xa2, 0x49, 0x44, 0xc4, 0x10, 0x1,
   128  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   129  		0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0xb3,
   130  		0x4c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69,
   131  		0x66, 0x79, 0x69, 0x6e, 0x67, 0x57, 0x72, 0x69,
   132  		0x74, 0x65, 0x72, 0xa4, 0x75, 0x69, 0x64, 0x31,
   133  		0xa8, 0x52, 0x65, 0x66, 0x42, 0x79, 0x74, 0x65,
   134  		0x73, 0x63, 0xaa, 0x55, 0x6e, 0x72, 0x65, 0x66,
   135  		0x42, 0x79, 0x74, 0x65, 0x73, 0x65, 0xa6, 0x57,
   136  		0x46, 0x6c, 0x61, 0x67, 0x73, 0xa, 0xa7, 0x57,
   137  		0x72, 0x69, 0x74, 0x65, 0x72, 0x73, 0x92, 0xa4,
   138  		0x75, 0x69, 0x64, 0x31, 0xa4, 0x75, 0x69, 0x64,
   139  		0x32, 0xa4, 0x64, 0x61, 0x74, 0x61, 0xc4, 0x2,
   140  		0xa, 0xb,
   141  	}
   142  
   143  	expectedWm := WriterMetadataV2{
   144  		SerializedPrivateMetadata: []byte{0xa, 0xb},
   145  		LastModifyingWriter:       "uid1",
   146  		Writers:                   []keybase1.UserOrTeamID{"uid1", "uid2"},
   147  		ID:                        tlf.FakeID(1, tlf.Private),
   148  		BID:                       NullBranchID,
   149  		WFlags:                    0xa,
   150  		DiskUsage:                 100,
   151  		RefBytes:                  99,
   152  		UnrefBytes:                101,
   153  	}
   154  
   155  	c := kbfscodec.NewMsgpack()
   156  
   157  	var wm WriterMetadataV2
   158  	err := c.Decode(encodedWm, &wm)
   159  	require.NoError(t, err)
   160  
   161  	require.Equal(t, expectedWm, wm)
   162  
   163  	buf, err := c.Encode(wm)
   164  	require.NoError(t, err)
   165  	require.Equal(t, encodedWm, buf)
   166  }
   167  
   168  func TestWriterMetadataV2UnchangedEncoding(t *testing.T) {
   169  	runTestOverMetadataVers(t, testWriterMetadataV2UnchangedEncoding)
   170  }
   171  
   172  // Test that WriterMetadataV2 has only a fixed (frozen) set of fields.
   173  func TestWriterMetadataV2EncodedFields(t *testing.T) {
   174  	sa1, _ := externals.NormalizeSocialAssertionStatic(context.Background(), "uid1@twitter")
   175  	sa2, _ := externals.NormalizeSocialAssertionStatic(context.Background(), "uid2@twitter")
   176  	// Usually exactly one of Writers/WKeys is filled in, but we
   177  	// fill in both here for testing.
   178  	wm := WriterMetadataV2{
   179  		ID:      tlf.FakeID(0xa, tlf.Private),
   180  		Writers: []keybase1.UserOrTeamID{"uid1", "uid2"},
   181  		WKeys:   TLFWriterKeyGenerationsV2{{}},
   182  		Extra: WriterMetadataExtraV2{
   183  			UnresolvedWriters: []keybase1.SocialAssertion{sa1, sa2},
   184  		},
   185  	}
   186  
   187  	c := kbfscodec.NewMsgpack()
   188  
   189  	buf, err := c.Encode(wm)
   190  	require.NoError(t, err)
   191  
   192  	var m map[string]interface{}
   193  	err = c.Decode(buf, &m)
   194  	require.NoError(t, err)
   195  
   196  	expectedFields := []string{
   197  		"BID",
   198  		"DiskUsage",
   199  		"ID",
   200  		"LastModifyingWriter",
   201  		"RefBytes",
   202  		"UnrefBytes",
   203  		"WFlags",
   204  		"WKeys",
   205  		"Writers",
   206  		"data",
   207  		"x",
   208  	}
   209  
   210  	var fields []string
   211  	for field := range m {
   212  		fields = append(fields, field)
   213  	}
   214  	sort.Strings(fields)
   215  	require.Equal(t, expectedFields, fields)
   216  }
   217  
   218  type writerMetadataExtraV2Future struct {
   219  	WriterMetadataExtraV2
   220  	kbfscodec.Extra
   221  }
   222  
   223  func (wmef writerMetadataExtraV2Future) toCurrent() WriterMetadataExtraV2 {
   224  	return wmef.WriterMetadataExtraV2
   225  }
   226  
   227  type tlfWriterKeyGenerationsV2Future []*tlfWriterKeyBundleV2Future
   228  
   229  func (wkgf tlfWriterKeyGenerationsV2Future) toCurrent() TLFWriterKeyGenerationsV2 {
   230  	wkg := make(TLFWriterKeyGenerationsV2, len(wkgf))
   231  	for i, wkbf := range wkgf {
   232  		wkb := wkbf.toCurrent()
   233  		wkg[i] = wkb
   234  	}
   235  	return wkg
   236  }
   237  
   238  type writerMetadataV2Future struct {
   239  	WriterMetadataV2
   240  	// Override WriterMetadata.WKeys.
   241  	WKeys tlfWriterKeyGenerationsV2Future
   242  	// Override WriterMetadata.Extra.
   243  	//
   244  	// TODO: Remove omitempty and omitemptycheckstruct once we use
   245  	// a version of go-codec that supports omitemptyrecursive.
   246  	Extra writerMetadataExtraV2Future `codec:"x,omitemptyrecursive,omitempty,omitemptycheckstruct"`
   247  }
   248  
   249  func (wmf writerMetadataV2Future) toCurrent() WriterMetadataV2 {
   250  	wm := wmf.WriterMetadataV2
   251  	wm.WKeys = wmf.WKeys.toCurrent()
   252  	wm.Extra = wmf.Extra.toCurrent()
   253  	return wm
   254  }
   255  
   256  func (wmf writerMetadataV2Future) ToCurrentStruct() kbfscodec.CurrentStruct {
   257  	return wmf.toCurrent()
   258  }
   259  
   260  func makeFakeWriterMetadataV2Future(t *testing.T) writerMetadataV2Future {
   261  	wmd := WriterMetadataV2{
   262  		// This needs to be list format so it fails to compile if new fields
   263  		// are added, effectively checking at compile time whether new fields
   264  		// have been added
   265  		[]byte{0xa, 0xb},
   266  		"uid1",
   267  		[]keybase1.UserOrTeamID{"uid1", "uid2"},
   268  		nil,
   269  		tlf.FakeID(1, tlf.Private),
   270  		NullBranchID,
   271  		0xa,
   272  		100,
   273  		0,
   274  		99,
   275  		101,
   276  		0,
   277  		WriterMetadataExtraV2{},
   278  	}
   279  	wkb := makeFakeTLFWriterKeyBundleV2Future(t)
   280  	sa, _ := externals.NormalizeSocialAssertionStatic(context.Background(), "foo@twitter")
   281  	return writerMetadataV2Future{
   282  		wmd,
   283  		tlfWriterKeyGenerationsV2Future{&wkb},
   284  		writerMetadataExtraV2Future{
   285  			WriterMetadataExtraV2{
   286  				// This needs to be list format so it fails to compile if new
   287  				// fields are added, effectively checking at compile time
   288  				// whether new fields have been added
   289  				[]keybase1.SocialAssertion{sa},
   290  				codec.UnknownFieldSetHandler{},
   291  			},
   292  			kbfscodec.MakeExtraOrBust("WriterMetadata", t),
   293  		},
   294  	}
   295  }
   296  
   297  func TestWriterMetadataV2UnknownFields(t *testing.T) {
   298  	testStructUnknownFields(t, makeFakeWriterMetadataV2Future(t))
   299  }
   300  
   301  type tlfReaderKeyGenerationsV2Future []*tlfReaderKeyBundleV2Future
   302  
   303  func (rkgf tlfReaderKeyGenerationsV2Future) toCurrent() TLFReaderKeyGenerationsV2 {
   304  	rkg := make(TLFReaderKeyGenerationsV2, len(rkgf))
   305  	for i, rkbf := range rkgf {
   306  		rkb := rkbf.toCurrent()
   307  		rkg[i] = rkb
   308  	}
   309  	return rkg
   310  }
   311  
   312  // rootMetadataWrapper exists only to add extra depth to fields
   313  // in RootMetadata, so that they may be overridden in
   314  // rootMetadataV2Future.
   315  type rootMetadataWrapper struct {
   316  	RootMetadataV2
   317  }
   318  
   319  type rootMetadataV2Future struct {
   320  	// Override RootMetadata.WriterMetadata. Put it first to work
   321  	// around a bug in codec's field lookup code.
   322  	//
   323  	// TODO: Report and fix this bug upstream.
   324  	writerMetadataV2Future
   325  
   326  	rootMetadataWrapper
   327  	// Override RootMetadata.RKeys.
   328  	RKeys tlfReaderKeyGenerationsV2Future `codec:",omitempty"`
   329  	kbfscodec.Extra
   330  }
   331  
   332  func (brmf *rootMetadataV2Future) toCurrent() RootMetadata {
   333  	rm := brmf.rootMetadataWrapper.RootMetadataV2
   334  	rm.WriterMetadataV2 = brmf.writerMetadataV2Future.toCurrent()
   335  	rm.RKeys = brmf.RKeys.toCurrent()
   336  	return &rm
   337  }
   338  
   339  func (brmf *rootMetadataV2Future) ToCurrentStruct() kbfscodec.CurrentStruct {
   340  	return brmf.toCurrent()
   341  }
   342  
   343  func makeFakeRootMetadataV2Future(t *testing.T) *rootMetadataV2Future {
   344  	wmf := makeFakeWriterMetadataV2Future(t)
   345  	rkb := makeFakeTLFReaderKeyBundleV2Future(t)
   346  	sa, _ := externals.NormalizeSocialAssertionStatic(context.Background(), "bar@github")
   347  	rmf := rootMetadataV2Future{
   348  		wmf,
   349  		rootMetadataWrapper{
   350  			RootMetadataV2{
   351  				// This needs to be list format so it
   352  				// fails to compile if new fields are
   353  				// added, effectively checking at
   354  				// compile time whether new fields
   355  				// have been added
   356  				WriterMetadataV2{},
   357  				kbfscrypto.SignatureInfo{
   358  					Version:      100,
   359  					Signature:    []byte{0xc},
   360  					VerifyingKey: kbfscrypto.MakeFakeVerifyingKeyOrBust("fake kid"),
   361  				},
   362  				"uid1",
   363  				0xb,
   364  				5,
   365  				FakeID(1),
   366  				nil,
   367  				[]keybase1.SocialAssertion{sa},
   368  				nil,
   369  				nil,
   370  				codec.UnknownFieldSetHandler{},
   371  			},
   372  		},
   373  		[]*tlfReaderKeyBundleV2Future{&rkb},
   374  		kbfscodec.MakeExtraOrBust("RootMetadata", t),
   375  	}
   376  	return &rmf
   377  }
   378  
   379  func TestRootMetadataV2UnknownFields(t *testing.T) {
   380  	testStructUnknownFields(t, makeFakeRootMetadataV2Future(t))
   381  }
   382  
   383  func TestIsValidRekeyRequestBasicV2(t *testing.T) {
   384  	tlfID := tlf.FakeID(1, tlf.Private)
   385  
   386  	uid := keybase1.MakeTestUID(1)
   387  	bh, err := tlf.MakeHandle(
   388  		[]keybase1.UserOrTeamID{uid.AsUserOrTeam()}, nil, nil, nil, nil)
   389  	require.NoError(t, err)
   390  
   391  	brmd, err := MakeInitialRootMetadataV2(tlfID, bh)
   392  	require.NoError(t, err)
   393  
   394  	ctx := context.Background()
   395  	codec := kbfscodec.NewMsgpack()
   396  	signer := kbfscrypto.SigningKeySigner{
   397  		Key: kbfscrypto.MakeFakeSigningKeyOrBust("key1"),
   398  	}
   399  
   400  	err = brmd.SignWriterMetadataInternally(ctx, codec, signer)
   401  	require.NoError(t, err)
   402  
   403  	newBrmd, err := MakeInitialRootMetadataV2(tlfID, bh)
   404  	require.NoError(t, err)
   405  	ok, err := newBrmd.IsValidRekeyRequest(
   406  		codec, brmd, newBrmd.LastModifyingWriter(), nil, nil)
   407  	require.NoError(t, err)
   408  	// Should fail because the copy bit is unset.
   409  	require.False(t, ok)
   410  
   411  	// Set the copy bit; note the writer metadata is the same.
   412  	newBrmd.SetWriterMetadataCopiedBit()
   413  
   414  	signer2 := kbfscrypto.SigningKeySigner{
   415  		Key: kbfscrypto.MakeFakeSigningKeyOrBust("key2"),
   416  	}
   417  
   418  	err = newBrmd.SignWriterMetadataInternally(ctx, codec, signer2)
   419  	require.NoError(t, err)
   420  
   421  	ok, err = newBrmd.IsValidRekeyRequest(
   422  		codec, brmd, newBrmd.LastModifyingWriter(), nil, nil)
   423  	require.NoError(t, err)
   424  	// Should fail because of mismatched writer metadata siginfo.
   425  	require.False(t, ok)
   426  
   427  	// Re-sign to get the same signature.
   428  	err = newBrmd.SignWriterMetadataInternally(ctx, codec, signer)
   429  	require.NoError(t, err)
   430  	ok, err = newBrmd.IsValidRekeyRequest(
   431  		codec, brmd, newBrmd.LastModifyingWriter(), nil, nil)
   432  	require.NoError(t, err)
   433  	require.True(t, ok)
   434  }
   435  
   436  func TestRevokeRemovedDevicesV2(t *testing.T) {
   437  	uid1 := keybase1.MakeTestUID(0x1)
   438  	uid2 := keybase1.MakeTestUID(0x2)
   439  	uid3 := keybase1.MakeTestUID(0x3)
   440  
   441  	key1 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key1")
   442  	key2 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key2")
   443  	key3 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key3")
   444  
   445  	half1a := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x1})
   446  	half1b := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x2})
   447  	half2a := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x3})
   448  	half2b := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x4})
   449  	half3a := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x5})
   450  	half3b := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x6})
   451  
   452  	id1a, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid1, key1, half1a)
   453  	require.NoError(t, err)
   454  	id1b, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid1, key1, half1b)
   455  	require.NoError(t, err)
   456  	id2a, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid2, key2, half2a)
   457  	require.NoError(t, err)
   458  	id2b, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid2, key2, half2b)
   459  	require.NoError(t, err)
   460  	id3a, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid3, key3, half3a)
   461  	require.NoError(t, err)
   462  	id3b, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid3, key3, half3b)
   463  	require.NoError(t, err)
   464  
   465  	tlfID := tlf.FakeID(1, tlf.Private)
   466  
   467  	bh, err := tlf.MakeHandle(
   468  		[]keybase1.UserOrTeamID{uid1.AsUserOrTeam(), uid2.AsUserOrTeam()},
   469  		[]keybase1.UserOrTeamID{uid3.AsUserOrTeam()}, nil, nil, nil)
   470  	require.NoError(t, err)
   471  
   472  	brmd, err := MakeInitialRootMetadataV2(tlfID, bh)
   473  	require.NoError(t, err)
   474  
   475  	brmd.WKeys = TLFWriterKeyGenerationsV2{
   476  		TLFWriterKeyBundleV2{
   477  			WKeys: UserDeviceKeyInfoMapV2{
   478  				uid1: DeviceKeyInfoMapV2{
   479  					key1.KID(): TLFCryptKeyInfo{
   480  						ServerHalfID: id1a,
   481  						EPubKeyIndex: 0,
   482  					},
   483  				},
   484  				uid2: DeviceKeyInfoMapV2{
   485  					key2.KID(): TLFCryptKeyInfo{
   486  						ServerHalfID: id2a,
   487  						EPubKeyIndex: 1,
   488  					},
   489  				},
   490  			},
   491  		},
   492  		TLFWriterKeyBundleV2{
   493  			WKeys: UserDeviceKeyInfoMapV2{
   494  				uid1: DeviceKeyInfoMapV2{
   495  					key1.KID(): TLFCryptKeyInfo{
   496  						ServerHalfID: id1b,
   497  						EPubKeyIndex: 0,
   498  					},
   499  				},
   500  				uid2: DeviceKeyInfoMapV2{
   501  					key2.KID(): TLFCryptKeyInfo{
   502  						ServerHalfID: id2b,
   503  						EPubKeyIndex: 0,
   504  					},
   505  				},
   506  			},
   507  		},
   508  	}
   509  
   510  	brmd.RKeys = TLFReaderKeyGenerationsV2{
   511  		TLFReaderKeyBundleV2{
   512  			RKeys: UserDeviceKeyInfoMapV2{
   513  				uid3: DeviceKeyInfoMapV2{
   514  					key3.KID(): TLFCryptKeyInfo{
   515  						ServerHalfID: id3a,
   516  						EPubKeyIndex: 0,
   517  					},
   518  				},
   519  			},
   520  		},
   521  		TLFReaderKeyBundleV2{
   522  			RKeys: UserDeviceKeyInfoMapV2{
   523  				uid3: DeviceKeyInfoMapV2{
   524  					key3.KID(): TLFCryptKeyInfo{
   525  						ServerHalfID: id3b,
   526  						EPubKeyIndex: 0,
   527  					},
   528  				},
   529  			},
   530  		},
   531  	}
   532  
   533  	updatedWriterKeys := UserDevicePublicKeys{
   534  		uid1: {key1: true},
   535  	}
   536  	updatedReaderKeys := UserDevicePublicKeys{
   537  		uid3: {key3: true},
   538  	}
   539  
   540  	removalInfo, err := brmd.RevokeRemovedDevices(
   541  		updatedWriterKeys, updatedReaderKeys, nil)
   542  	require.NoError(t, err)
   543  	require.Equal(t, ServerHalfRemovalInfo{
   544  		uid2: UserServerHalfRemovalInfo{
   545  			UserRemoved: true,
   546  			DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{
   547  				key2: []kbfscrypto.TLFCryptKeyServerHalfID{id2a, id2b},
   548  			},
   549  		},
   550  	}, removalInfo)
   551  
   552  	expectedWKeys := TLFWriterKeyGenerationsV2{
   553  		TLFWriterKeyBundleV2{
   554  			WKeys: UserDeviceKeyInfoMapV2{
   555  				uid1: DeviceKeyInfoMapV2{
   556  					key1.KID(): TLFCryptKeyInfo{
   557  						ServerHalfID: id1a,
   558  						EPubKeyIndex: 0,
   559  					},
   560  				},
   561  			},
   562  		},
   563  		TLFWriterKeyBundleV2{
   564  			WKeys: UserDeviceKeyInfoMapV2{
   565  				uid1: DeviceKeyInfoMapV2{
   566  					key1.KID(): TLFCryptKeyInfo{
   567  						ServerHalfID: id1b,
   568  						EPubKeyIndex: 0,
   569  					},
   570  				},
   571  			},
   572  		},
   573  	}
   574  	require.Equal(t, expectedWKeys, brmd.WKeys)
   575  
   576  	expectedRKeys := TLFReaderKeyGenerationsV2{
   577  		TLFReaderKeyBundleV2{
   578  			RKeys: UserDeviceKeyInfoMapV2{
   579  				uid3: DeviceKeyInfoMapV2{
   580  					key3.KID(): TLFCryptKeyInfo{
   581  						ServerHalfID: id3a,
   582  						EPubKeyIndex: 0,
   583  					},
   584  				},
   585  			},
   586  		},
   587  		TLFReaderKeyBundleV2{
   588  			RKeys: UserDeviceKeyInfoMapV2{
   589  				uid3: DeviceKeyInfoMapV2{
   590  					key3.KID(): TLFCryptKeyInfo{
   591  						ServerHalfID: id3b,
   592  						EPubKeyIndex: 0,
   593  					},
   594  				},
   595  			},
   596  		},
   597  	}
   598  	require.Equal(t, expectedRKeys, brmd.RKeys)
   599  }
   600  
   601  // TestRevokeLastDeviceV2 checks behavior of RevokeRemovedDevices with
   602  // respect to removing the last device of a user vs. removing the user
   603  // completely.
   604  func TestRevokeLastDeviceV2(t *testing.T) {
   605  	uid1 := keybase1.MakeTestUID(0x1)
   606  	uid2 := keybase1.MakeTestUID(0x2)
   607  	uid3 := keybase1.MakeTestUID(0x3)
   608  	uid4 := keybase1.MakeTestUID(0x4)
   609  
   610  	key1 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key1")
   611  	key2 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key2")
   612  
   613  	half1 := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x1})
   614  	half2 := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x2})
   615  
   616  	id1, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid1, key1, half1)
   617  	require.NoError(t, err)
   618  	id2, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid2, key2, half2)
   619  	require.NoError(t, err)
   620  
   621  	tlfID := tlf.FakeID(1, tlf.Private)
   622  
   623  	bh, err := tlf.MakeHandle(
   624  		[]keybase1.UserOrTeamID{uid1.AsUserOrTeam(), uid2.AsUserOrTeam()},
   625  		[]keybase1.UserOrTeamID{uid3.AsUserOrTeam(), uid4.AsUserOrTeam()},
   626  		nil, nil, nil)
   627  	require.NoError(t, err)
   628  
   629  	brmd, err := MakeInitialRootMetadataV2(tlfID, bh)
   630  	require.NoError(t, err)
   631  
   632  	brmd.WKeys = TLFWriterKeyGenerationsV2{
   633  		TLFWriterKeyBundleV2{
   634  			WKeys: UserDeviceKeyInfoMapV2{
   635  				uid1: DeviceKeyInfoMapV2{
   636  					key1.KID(): TLFCryptKeyInfo{
   637  						ServerHalfID: id1,
   638  						EPubKeyIndex: 0,
   639  					},
   640  				},
   641  				uid2: DeviceKeyInfoMapV2{
   642  					key2.KID(): TLFCryptKeyInfo{
   643  						ServerHalfID: id2,
   644  						EPubKeyIndex: 1,
   645  					},
   646  				},
   647  			},
   648  		},
   649  	}
   650  
   651  	brmd.RKeys = TLFReaderKeyGenerationsV2{
   652  		TLFReaderKeyBundleV2{
   653  			RKeys: UserDeviceKeyInfoMapV2{
   654  				uid3: DeviceKeyInfoMapV2{},
   655  				uid4: DeviceKeyInfoMapV2{},
   656  			},
   657  		},
   658  	}
   659  
   660  	updatedWriterKeys := UserDevicePublicKeys{
   661  		uid1: {},
   662  	}
   663  	updatedReaderKeys := UserDevicePublicKeys{
   664  		uid3: {},
   665  	}
   666  
   667  	removalInfo, err := brmd.RevokeRemovedDevices(
   668  		updatedWriterKeys, updatedReaderKeys, nil)
   669  	require.NoError(t, err)
   670  	require.Equal(t, ServerHalfRemovalInfo{
   671  		uid1: UserServerHalfRemovalInfo{
   672  			DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{
   673  				key1: []kbfscrypto.TLFCryptKeyServerHalfID{id1},
   674  			},
   675  		},
   676  		uid2: UserServerHalfRemovalInfo{
   677  			UserRemoved: true,
   678  			DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{
   679  				key2: []kbfscrypto.TLFCryptKeyServerHalfID{id2},
   680  			},
   681  		},
   682  		uid4: UserServerHalfRemovalInfo{
   683  			UserRemoved:         true,
   684  			DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{},
   685  		},
   686  	}, removalInfo)
   687  
   688  	expectedWKeys := TLFWriterKeyGenerationsV2{
   689  		TLFWriterKeyBundleV2{
   690  			WKeys: UserDeviceKeyInfoMapV2{
   691  				uid1: DeviceKeyInfoMapV2{},
   692  			},
   693  		},
   694  	}
   695  	require.Equal(t, expectedWKeys, brmd.WKeys)
   696  
   697  	expectedRKeys := TLFReaderKeyGenerationsV2{
   698  		TLFReaderKeyBundleV2{
   699  			RKeys: UserDeviceKeyInfoMapV2{
   700  				uid3: DeviceKeyInfoMapV2{},
   701  			},
   702  		},
   703  	}
   704  	require.Equal(t, expectedRKeys, brmd.RKeys)
   705  }
   706  
   707  // userDevicePrivateKeys is a map from users to that user's set of
   708  // device private keys.
   709  type userDevicePrivateKeys map[keybase1.UID]map[kbfscrypto.CryptPrivateKey]bool
   710  
   711  func (udpk userDevicePrivateKeys) hasKeys() bool {
   712  	for _, privKeys := range udpk {
   713  		if len(privKeys) > 0 {
   714  			return true
   715  		}
   716  	}
   717  	return false
   718  }
   719  
   720  func (udpk userDevicePrivateKeys) toPublicKeys() UserDevicePublicKeys {
   721  	pubKeys := make(UserDevicePublicKeys)
   722  	for uid, privKeys := range udpk {
   723  		pubKeys[uid] = make(DevicePublicKeys)
   724  		for privKey := range privKeys {
   725  			pubKey := privKey.GetPublicKey()
   726  			pubKeys[uid][pubKey] = true
   727  		}
   728  	}
   729  	return pubKeys
   730  }
   731  
   732  // expectedRekeyInfoV2 contains all the information needed to check a
   733  // call to UpdateKeyBundles.
   734  //
   735  // If both writerPrivKeys and readerPrivKeys are empty, then
   736  // ePubKeyIndex and ePubKey are ignored.
   737  type expectedRekeyInfoV2 struct {
   738  	writerPrivKeys, readerPrivKeys userDevicePrivateKeys
   739  	serverHalves                   []UserDeviceKeyServerHalves
   740  	ePubKeyIndex                   int
   741  	ePubKey                        kbfscrypto.TLFEphemeralPublicKey
   742  }
   743  
   744  func checkCryptKeyInfo(t *testing.T, privKey kbfscrypto.CryptPrivateKey,
   745  	serverHalf kbfscrypto.TLFCryptKeyServerHalf, expectedEPubKeyIndex int,
   746  	expectedEPubKey kbfscrypto.TLFEphemeralPublicKey,
   747  	expectedTLFCryptKey kbfscrypto.TLFCryptKey, info TLFCryptKeyInfo,
   748  	ePubKey kbfscrypto.TLFEphemeralPublicKey) {
   749  	require.Equal(t, expectedEPubKeyIndex, info.EPubKeyIndex)
   750  	require.Equal(t, expectedEPubKey, ePubKey)
   751  
   752  	clientHalf, err := kbfscrypto.DecryptTLFCryptKeyClientHalf(
   753  		privKey, ePubKey, info.ClientHalf)
   754  	require.NoError(t, err)
   755  
   756  	tlfCryptKey := kbfscrypto.UnmaskTLFCryptKey(serverHalf, clientHalf)
   757  	require.Equal(t, expectedTLFCryptKey, tlfCryptKey)
   758  }
   759  
   760  // checkGetTLFCryptKeyV2 checks that wkb and rkb (for the given
   761  // KeyGen) contain the info necessary to get the TLF crypt key for
   762  // each user in expected, which must all match expectedTLFCryptKey.
   763  func checkGetTLFCryptKeyV2(t *testing.T, keyGen KeyGen,
   764  	expected expectedRekeyInfoV2,
   765  	expectedTLFCryptKey kbfscrypto.TLFCryptKey,
   766  	wkb *TLFWriterKeyBundleV2, rkb *TLFReaderKeyBundleV2) {
   767  	expectedServerHalves := expected.serverHalves[keyGen-FirstValidKeyGen]
   768  	for uid, privKeys := range expected.writerPrivKeys {
   769  		for privKey := range privKeys {
   770  			pubKey := privKey.GetPublicKey()
   771  			serverHalf, ok := expectedServerHalves[uid][pubKey]
   772  			require.True(t, ok, "writer uid=%s, key=%s",
   773  				uid, pubKey)
   774  
   775  			info, ok := wkb.WKeys[uid][pubKey.KID()]
   776  			require.True(t, ok)
   777  
   778  			ePubKey := wkb.TLFEphemeralPublicKeys[info.EPubKeyIndex]
   779  
   780  			checkCryptKeyInfo(t, privKey, serverHalf,
   781  				expected.ePubKeyIndex, expected.ePubKey,
   782  				expectedTLFCryptKey, info, ePubKey)
   783  		}
   784  	}
   785  
   786  	for uid, privKeys := range expected.readerPrivKeys {
   787  		for privKey := range privKeys {
   788  			pubKey := privKey.GetPublicKey()
   789  			serverHalf, ok := expectedServerHalves[uid][pubKey]
   790  			require.True(t, ok, "reader uid=%s, key=%s",
   791  				uid, pubKey)
   792  
   793  			info, ok := rkb.RKeys[uid][pubKey.KID()]
   794  			require.True(t, ok)
   795  
   796  			_, _, ePubKey, err := GetEphemeralPublicKeyInfoV2(
   797  				info, *wkb, *rkb)
   798  			require.NoError(t, err)
   799  
   800  			checkCryptKeyInfo(t, privKey, serverHalf,
   801  				expected.ePubKeyIndex, expected.ePubKey,
   802  				expectedTLFCryptKey, info, ePubKey)
   803  		}
   804  	}
   805  }
   806  
   807  // accumulatePublicKeys returns the union of each user's keys in
   808  // pubKeys1 and pubKeys2. A user's keys in pubKeys1 and pubKeys2 must
   809  // be disjoint.
   810  func accumulatePublicKeys(
   811  	pubKeys1, pubKeys2 UserDevicePublicKeys) UserDevicePublicKeys {
   812  	pubKeys := make(UserDevicePublicKeys)
   813  	for uid, keys := range pubKeys1 {
   814  		pubKeys[uid] = make(DevicePublicKeys)
   815  		for key := range keys {
   816  			pubKeys[uid][key] = true
   817  		}
   818  	}
   819  	for uid, keys := range pubKeys2 {
   820  		if pubKeys[uid] == nil {
   821  			pubKeys[uid] = make(DevicePublicKeys)
   822  		}
   823  		for key := range keys {
   824  			if pubKeys[uid][key] {
   825  				panic(fmt.Sprintf(
   826  					"uid=%s key=%s exists in both",
   827  					uid, key))
   828  			}
   829  			pubKeys[uid][key] = true
   830  		}
   831  	}
   832  	return pubKeys
   833  }
   834  
   835  // unionPublicKeyUsers returns the union of the usersin pubKeys1 and
   836  // pubKeys2, which must be disjoint. Not a deep copy.
   837  func unionPublicKeyUsers(
   838  	pubKeys1, pubKeys2 UserDevicePublicKeys) UserDevicePublicKeys {
   839  	pubKeys := make(UserDevicePublicKeys)
   840  	for uid, keys := range pubKeys1 {
   841  		pubKeys[uid] = keys
   842  	}
   843  	for uid, keys := range pubKeys2 {
   844  		if pubKeys[uid] != nil {
   845  			panic(fmt.Sprintf("uid=%s exists in both", uid))
   846  		}
   847  		pubKeys[uid] = keys
   848  	}
   849  	return pubKeys
   850  }
   851  
   852  func userDeviceKeyInfoMapV2ToPublicKeys(
   853  	udkimV2 UserDeviceKeyInfoMapV2) UserDevicePublicKeys {
   854  	pubKeys := make(UserDevicePublicKeys)
   855  	for uid, dkimV2 := range udkimV2 {
   856  		pubKeys[uid] = make(DevicePublicKeys)
   857  		for kid := range dkimV2 {
   858  			pubKeys[uid][kbfscrypto.MakeCryptPublicKey(kid)] = true
   859  		}
   860  	}
   861  	return pubKeys
   862  }
   863  
   864  func userDeviceServerHalvesToPublicKeys(
   865  	serverHalves UserDeviceKeyServerHalves) UserDevicePublicKeys {
   866  	pubKeys := make(UserDevicePublicKeys)
   867  	for uid, keys := range serverHalves {
   868  		pubKeys[uid] = make(DevicePublicKeys)
   869  		for key := range keys {
   870  			pubKeys[uid][key] = true
   871  		}
   872  	}
   873  	return pubKeys
   874  }
   875  
   876  // checkKeyBundlesV2 checks that rmd's key bundles contain exactly the
   877  // info expected from expectedRekeyInfos and expectedPubKey.
   878  func checkKeyBundlesV2(t *testing.T, expectedRekeyInfos []expectedRekeyInfoV2,
   879  	expectedTLFCryptKeys []kbfscrypto.TLFCryptKey,
   880  	expectedPubKeys []kbfscrypto.TLFPublicKey, rmd *RootMetadataV2) {
   881  	require.Equal(t, len(expectedTLFCryptKeys), len(expectedPubKeys))
   882  	require.Equal(t, len(expectedTLFCryptKeys),
   883  		int(rmd.LatestKeyGeneration()-FirstValidKeyGen+1))
   884  	for keyGen := FirstValidKeyGen; keyGen <= rmd.LatestKeyGeneration(); keyGen++ {
   885  		wkb, rkb, err := rmd.getTLFKeyBundles(keyGen)
   886  		require.NoError(t, err)
   887  
   888  		expectedWriterPubKeys := make(UserDevicePublicKeys)
   889  		expectedReaderPubKeys := make(UserDevicePublicKeys)
   890  		var expectedWriterEPublicKeys,
   891  			expectedReaderEPublicKeys kbfscrypto.TLFEphemeralPublicKeys
   892  		for _, expected := range expectedRekeyInfos {
   893  			expectedWriterPubKeys = accumulatePublicKeys(
   894  				expectedWriterPubKeys,
   895  				expected.writerPrivKeys.toPublicKeys())
   896  			expectedReaderPubKeys = accumulatePublicKeys(
   897  				expectedReaderPubKeys,
   898  				expected.readerPrivKeys.toPublicKeys())
   899  			if expected.writerPrivKeys.hasKeys() ||
   900  				expected.readerPrivKeys.hasKeys() {
   901  				if expected.ePubKeyIndex >= 0 {
   902  					require.Equal(t, expected.ePubKeyIndex,
   903  						len(expectedWriterEPublicKeys))
   904  					expectedWriterEPublicKeys = append(
   905  						expectedWriterEPublicKeys,
   906  						expected.ePubKey)
   907  				} else {
   908  					i := -1 - expected.ePubKeyIndex
   909  					require.Equal(t, i,
   910  						len(expectedReaderEPublicKeys))
   911  					expectedReaderEPublicKeys = append(
   912  						expectedReaderEPublicKeys,
   913  						expected.ePubKey)
   914  				}
   915  			}
   916  		}
   917  
   918  		writerPubKeys := userDeviceKeyInfoMapV2ToPublicKeys(wkb.WKeys)
   919  		readerPubKeys := userDeviceKeyInfoMapV2ToPublicKeys(rkb.RKeys)
   920  
   921  		require.Equal(t, expectedWriterPubKeys, writerPubKeys)
   922  		require.Equal(t, expectedReaderPubKeys, readerPubKeys)
   923  
   924  		require.Equal(t, expectedWriterEPublicKeys,
   925  			wkb.TLFEphemeralPublicKeys)
   926  		require.Equal(t, expectedReaderEPublicKeys,
   927  			rkb.TLFReaderEphemeralPublicKeys)
   928  
   929  		require.Equal(t, expectedPubKeys[keyGen-FirstValidKeyGen],
   930  			wkb.TLFPublicKey)
   931  
   932  		for _, expected := range expectedRekeyInfos {
   933  			require.Equal(t, len(expectedTLFCryptKeys),
   934  				len(expected.serverHalves))
   935  			expectedUserPubKeys := unionPublicKeyUsers(
   936  				expected.writerPrivKeys.toPublicKeys(),
   937  				expected.readerPrivKeys.toPublicKeys())
   938  			userPubKeys := userDeviceServerHalvesToPublicKeys(
   939  				expected.serverHalves[keyGen-FirstValidKeyGen])
   940  			require.Equal(t, expectedUserPubKeys.RemoveKeylessUsersForTest(), userPubKeys)
   941  			checkGetTLFCryptKeyV2(t, keyGen, expected,
   942  				expectedTLFCryptKeys[keyGen-FirstValidKeyGen],
   943  				wkb, rkb)
   944  		}
   945  	}
   946  }
   947  
   948  func TestRootMetadataV2UpdateKeyBundles(t *testing.T) {
   949  	uid1 := keybase1.MakeTestUID(1)
   950  	uid2 := keybase1.MakeTestUID(2)
   951  	uid3 := keybase1.MakeTestUID(3)
   952  
   953  	privKey1 := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key1")
   954  	privKey2 := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key2")
   955  	privKey3 := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key3")
   956  
   957  	updatedWriterKeys := UserDevicePublicKeys{
   958  		uid1: {privKey1.GetPublicKey(): true},
   959  		uid2: {privKey2.GetPublicKey(): true},
   960  	}
   961  
   962  	updatedReaderKeys := UserDevicePublicKeys{
   963  		uid3: {privKey3.GetPublicKey(): true},
   964  	}
   965  
   966  	tlfID := tlf.FakeID(1, tlf.Private)
   967  
   968  	bh, err := tlf.MakeHandle(
   969  		[]keybase1.UserOrTeamID{uid1.AsUserOrTeam(), uid2.AsUserOrTeam()},
   970  		[]keybase1.UserOrTeamID{uid3.AsUserOrTeam()},
   971  		[]keybase1.SocialAssertion{{}},
   972  		nil, nil)
   973  	require.NoError(t, err)
   974  
   975  	rmd, err := MakeInitialRootMetadataV2(tlfID, bh)
   976  	require.NoError(t, err)
   977  
   978  	codec := kbfscodec.NewMsgpack()
   979  
   980  	ePubKey1, ePrivKey1, err := kbfscrypto.MakeRandomTLFEphemeralKeys()
   981  	require.NoError(t, err)
   982  
   983  	// Add first key generations.
   984  
   985  	latestKeyGen := FirstValidKeyGen + 5
   986  	var pubKeys []kbfscrypto.TLFPublicKey
   987  	var tlfCryptKeys []kbfscrypto.TLFCryptKey
   988  	var serverHalves1 []UserDeviceKeyServerHalves
   989  	for keyGen := FirstValidKeyGen; keyGen <= latestKeyGen; keyGen++ {
   990  		fakeKeyData := [32]byte{byte(keyGen)}
   991  		pubKey := kbfscrypto.MakeTLFPublicKey(fakeKeyData)
   992  		tlfCryptKey := kbfscrypto.MakeTLFCryptKey(fakeKeyData)
   993  
   994  		// Use the same ephemeral keys for initial key
   995  		// generations, even though that can't happen in
   996  		// practice.
   997  		_, serverHalves1Gen, err := rmd.AddKeyGeneration(codec,
   998  			nil, updatedWriterKeys, updatedReaderKeys,
   999  			ePubKey1, ePrivKey1,
  1000  			pubKey, kbfscrypto.TLFCryptKey{}, tlfCryptKey)
  1001  		require.NoError(t, err)
  1002  		serverHalves1 = append(serverHalves1, serverHalves1Gen)
  1003  
  1004  		pubKeys = append(pubKeys, pubKey)
  1005  		tlfCryptKeys = append(tlfCryptKeys, tlfCryptKey)
  1006  	}
  1007  
  1008  	expectedRekeyInfo1 := expectedRekeyInfoV2{
  1009  		writerPrivKeys: userDevicePrivateKeys{
  1010  			uid1: {privKey1: true},
  1011  			uid2: {privKey2: true},
  1012  		},
  1013  		readerPrivKeys: userDevicePrivateKeys{
  1014  			uid3: {privKey3: true},
  1015  		},
  1016  		serverHalves: serverHalves1,
  1017  		ePubKeyIndex: 0,
  1018  		ePubKey:      ePubKey1,
  1019  	}
  1020  	expectedRekeyInfos := []expectedRekeyInfoV2{expectedRekeyInfo1}
  1021  
  1022  	checkKeyBundlesV2(t, expectedRekeyInfos, tlfCryptKeys, pubKeys, rmd)
  1023  
  1024  	// Do update to check idempotency.
  1025  
  1026  	serverHalves1b, err := rmd.UpdateKeyBundles(codec, nil,
  1027  		updatedWriterKeys, updatedReaderKeys,
  1028  		ePubKey1, ePrivKey1, tlfCryptKeys)
  1029  	require.NoError(t, err)
  1030  
  1031  	expectedRekeyInfo1b := expectedRekeyInfoV2{
  1032  		serverHalves: serverHalves1b,
  1033  	}
  1034  
  1035  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo1b)
  1036  
  1037  	checkKeyBundlesV2(t, expectedRekeyInfos, tlfCryptKeys, pubKeys, rmd)
  1038  
  1039  	// Rekey.
  1040  
  1041  	privKey1b := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key1b")
  1042  	updatedWriterKeys[uid1][privKey1b.GetPublicKey()] = true
  1043  
  1044  	privKey3b := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key3b")
  1045  	updatedReaderKeys[uid3][privKey3b.GetPublicKey()] = true
  1046  
  1047  	ePubKey2, ePrivKey2, err := kbfscrypto.MakeRandomTLFEphemeralKeys()
  1048  	require.NoError(t, err)
  1049  
  1050  	serverHalves2, err := rmd.UpdateKeyBundles(codec, nil,
  1051  		updatedWriterKeys, updatedReaderKeys,
  1052  		ePubKey2, ePrivKey2, tlfCryptKeys)
  1053  	require.NoError(t, err)
  1054  
  1055  	expectedRekeyInfo2 := expectedRekeyInfoV2{
  1056  		writerPrivKeys: userDevicePrivateKeys{
  1057  			uid1: {privKey1b: true},
  1058  		},
  1059  		readerPrivKeys: userDevicePrivateKeys{
  1060  			uid3: {privKey3b: true},
  1061  		},
  1062  		serverHalves: serverHalves2,
  1063  		ePubKeyIndex: 1,
  1064  		ePubKey:      ePubKey2,
  1065  	}
  1066  
  1067  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo2)
  1068  
  1069  	checkKeyBundlesV2(t, expectedRekeyInfos, tlfCryptKeys, pubKeys, rmd)
  1070  
  1071  	// Do again to check idempotency.
  1072  
  1073  	serverHalves2b, err := rmd.UpdateKeyBundles(codec, nil,
  1074  		updatedWriterKeys, updatedReaderKeys,
  1075  		ePubKey2, ePrivKey2, tlfCryptKeys)
  1076  	require.NoError(t, err)
  1077  
  1078  	expectedRekeyInfo2b := expectedRekeyInfoV2{
  1079  		serverHalves: serverHalves2b,
  1080  	}
  1081  
  1082  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo2b)
  1083  
  1084  	checkKeyBundlesV2(t, expectedRekeyInfos, tlfCryptKeys, pubKeys, rmd)
  1085  
  1086  	// Rekey writers only.
  1087  
  1088  	privKey1c := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key1c")
  1089  	updatedWriterKeys[uid1][privKey1c.GetPublicKey()] = true
  1090  
  1091  	ePubKey3, ePrivKey3, err := kbfscrypto.MakeRandomTLFEphemeralKeys()
  1092  	require.NoError(t, err)
  1093  
  1094  	serverHalves3, err := rmd.UpdateKeyBundles(codec, nil,
  1095  		updatedWriterKeys, updatedReaderKeys,
  1096  		ePubKey3, ePrivKey3, tlfCryptKeys)
  1097  	require.NoError(t, err)
  1098  
  1099  	expectedRekeyInfo3 := expectedRekeyInfoV2{
  1100  		writerPrivKeys: userDevicePrivateKeys{
  1101  			uid1: {privKey1c: true},
  1102  		},
  1103  		readerPrivKeys: nil,
  1104  		serverHalves:   serverHalves3,
  1105  		ePubKeyIndex:   2,
  1106  		ePubKey:        ePubKey3,
  1107  	}
  1108  
  1109  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo3)
  1110  
  1111  	checkKeyBundlesV2(t, expectedRekeyInfos, tlfCryptKeys, pubKeys, rmd)
  1112  
  1113  	// Do again to check idempotency.
  1114  
  1115  	serverHalves3b, err := rmd.UpdateKeyBundles(codec, nil,
  1116  		updatedWriterKeys, updatedReaderKeys,
  1117  		ePubKey3, ePrivKey3, tlfCryptKeys)
  1118  	require.NoError(t, err)
  1119  
  1120  	expectedRekeyInfo3b := expectedRekeyInfoV2{
  1121  		serverHalves: serverHalves3b,
  1122  	}
  1123  
  1124  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo3b)
  1125  
  1126  	checkKeyBundlesV2(t, expectedRekeyInfos, tlfCryptKeys, pubKeys, rmd)
  1127  
  1128  	// Reader rekey.
  1129  
  1130  	privKey3c := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key3c")
  1131  	privKey3d := kbfscrypto.MakeFakeCryptPrivateKeyOrBust("key3d")
  1132  	updatedReaderKeys[uid3][privKey3c.GetPublicKey()] = true
  1133  	updatedReaderKeys[uid3][privKey3d.GetPublicKey()] = true
  1134  
  1135  	ePubKey4, ePrivKey4, err := kbfscrypto.MakeRandomTLFEphemeralKeys()
  1136  	require.NoError(t, err)
  1137  
  1138  	filteredReaderKeys := UserDevicePublicKeys{
  1139  		uid3: updatedReaderKeys[uid3],
  1140  	}
  1141  	serverHalves4, err := rmd.UpdateKeyBundles(codec, nil,
  1142  		nil, filteredReaderKeys, ePubKey4, ePrivKey4, tlfCryptKeys)
  1143  	require.NoError(t, err)
  1144  
  1145  	expectedRekeyInfo4 := expectedRekeyInfoV2{
  1146  		writerPrivKeys: nil,
  1147  		readerPrivKeys: userDevicePrivateKeys{
  1148  			uid3: {privKey3c: true, privKey3d: true},
  1149  		},
  1150  		serverHalves: serverHalves4,
  1151  		ePubKeyIndex: -1,
  1152  		ePubKey:      ePubKey4,
  1153  	}
  1154  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo4)
  1155  	checkKeyBundlesV2(t, expectedRekeyInfos, tlfCryptKeys, pubKeys, rmd)
  1156  
  1157  	// Do again to check idempotency.
  1158  
  1159  	serverHalves4b, err := rmd.UpdateKeyBundles(codec, nil,
  1160  		nil, filteredReaderKeys, ePubKey4, ePrivKey4, tlfCryptKeys)
  1161  	require.NoError(t, err)
  1162  
  1163  	expectedRekeyInfo4b := expectedRekeyInfoV2{
  1164  		serverHalves: serverHalves4b,
  1165  	}
  1166  
  1167  	expectedRekeyInfos = append(expectedRekeyInfos, expectedRekeyInfo4b)
  1168  
  1169  	checkKeyBundlesV2(t, expectedRekeyInfos, tlfCryptKeys, pubKeys, rmd)
  1170  }
  1171  
  1172  // TestRootMetadataV2AddKeyGenerationKeylessUsers checks that
  1173  // keyless users are handled properly by AddKeyGeneration.
  1174  func TestRootMetadataV2AddKeyGenerationKeylessUsers(t *testing.T) {
  1175  	uid1 := keybase1.MakeTestUID(1)
  1176  	uid2 := keybase1.MakeTestUID(2)
  1177  	uid3 := keybase1.MakeTestUID(3)
  1178  
  1179  	updatedWriterKeys := UserDevicePublicKeys{
  1180  		uid1: {},
  1181  		uid2: {},
  1182  	}
  1183  
  1184  	updatedReaderKeys := UserDevicePublicKeys{
  1185  		uid3: {},
  1186  	}
  1187  
  1188  	tlfID := tlf.FakeID(1, tlf.Private)
  1189  
  1190  	bh, err := tlf.MakeHandle(
  1191  		[]keybase1.UserOrTeamID{uid1.AsUserOrTeam(), uid2.AsUserOrTeam()},
  1192  		[]keybase1.UserOrTeamID{uid3.AsUserOrTeam()},
  1193  		[]keybase1.SocialAssertion{{}},
  1194  		nil, nil)
  1195  	require.NoError(t, err)
  1196  
  1197  	rmd, err := MakeInitialRootMetadataV2(tlfID, bh)
  1198  	require.NoError(t, err)
  1199  
  1200  	codec := kbfscodec.NewMsgpack()
  1201  
  1202  	ePubKey1, ePrivKey1, err := kbfscrypto.MakeRandomTLFEphemeralKeys()
  1203  	require.NoError(t, err)
  1204  
  1205  	// Add first key generation.
  1206  
  1207  	fakeKeyData := [32]byte{1}
  1208  	pubKey := kbfscrypto.MakeTLFPublicKey(fakeKeyData)
  1209  	tlfCryptKey := kbfscrypto.MakeTLFCryptKey(fakeKeyData)
  1210  
  1211  	_, serverHalves1Gen, err := rmd.AddKeyGeneration(codec,
  1212  		nil, updatedWriterKeys, updatedReaderKeys,
  1213  		ePubKey1, ePrivKey1,
  1214  		pubKey, kbfscrypto.TLFCryptKey{}, tlfCryptKey)
  1215  	require.NoError(t, err)
  1216  	serverHalves1 := []UserDeviceKeyServerHalves{serverHalves1Gen}
  1217  
  1218  	pubKeys := []kbfscrypto.TLFPublicKey{pubKey}
  1219  	tlfCryptKeys := []kbfscrypto.TLFCryptKey{tlfCryptKey}
  1220  
  1221  	expectedRekeyInfo1 := expectedRekeyInfoV2{
  1222  		writerPrivKeys: userDevicePrivateKeys{
  1223  			uid1: {},
  1224  			uid2: {},
  1225  		},
  1226  		readerPrivKeys: userDevicePrivateKeys{
  1227  			uid3: {},
  1228  		},
  1229  		serverHalves: serverHalves1,
  1230  	}
  1231  	expectedRekeyInfos := []expectedRekeyInfoV2{expectedRekeyInfo1}
  1232  
  1233  	checkKeyBundlesV2(t, expectedRekeyInfos, tlfCryptKeys, pubKeys, rmd)
  1234  }