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 }