github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/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 }