github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/kbfsmd/key_bundle_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 "reflect" 9 "strings" 10 "testing" 11 12 "github.com/keybase/client/go/kbfs/kbfscodec" 13 "github.com/keybase/client/go/kbfs/kbfscrypto" 14 "github.com/keybase/client/go/protocol/keybase1" 15 "github.com/keybase/go-codec/codec" 16 "github.com/stretchr/testify/require" 17 ) 18 19 // TestRemoveDevicesNotInV2 checks basic functionality of 20 // removeDevicesNotIn(). 21 func TestRemoveDevicesNotInV2(t *testing.T) { 22 uid1 := keybase1.MakeTestUID(0x1) 23 uid2 := keybase1.MakeTestUID(0x2) 24 uid3 := keybase1.MakeTestUID(0x3) 25 26 key1a := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key1") 27 key1b := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key2") 28 key2a := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key3") 29 key2b := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key4") 30 key2c := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key5") 31 key3a := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key6") 32 33 half1a := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x1}) 34 half1b := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x2}) 35 half2a := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x3}) 36 half2b := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x4}) 37 half2c := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x5}) 38 half3a := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x6}) 39 40 id1a, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid1, key1a, half1a) 41 require.NoError(t, err) 42 id1b, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid1, key1b, half1b) 43 require.NoError(t, err) 44 id2a, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid2, key2a, half2a) 45 require.NoError(t, err) 46 id2b, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid2, key2b, half2b) 47 require.NoError(t, err) 48 id2c, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid2, key2c, half2c) 49 require.NoError(t, err) 50 id3a, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid2, key3a, half3a) 51 require.NoError(t, err) 52 53 udkimV2 := UserDeviceKeyInfoMapV2{ 54 uid1: DeviceKeyInfoMapV2{ 55 key1a.KID(): TLFCryptKeyInfo{ 56 ServerHalfID: id1a, 57 EPubKeyIndex: -1, 58 }, 59 key1b.KID(): TLFCryptKeyInfo{ 60 ServerHalfID: id1b, 61 EPubKeyIndex: +2, 62 }, 63 }, 64 uid2: DeviceKeyInfoMapV2{ 65 key2a.KID(): TLFCryptKeyInfo{ 66 ServerHalfID: id2a, 67 EPubKeyIndex: -2, 68 }, 69 key2b.KID(): TLFCryptKeyInfo{ 70 ServerHalfID: id2b, 71 EPubKeyIndex: 0, 72 }, 73 key2c.KID(): TLFCryptKeyInfo{ 74 ServerHalfID: id2c, 75 EPubKeyIndex: 0, 76 }, 77 }, 78 uid3: DeviceKeyInfoMapV2{ 79 key3a.KID(): TLFCryptKeyInfo{ 80 ServerHalfID: id3a, 81 EPubKeyIndex: -2, 82 }, 83 }, 84 } 85 86 removalInfo := udkimV2.RemoveDevicesNotIn(UserDevicePublicKeys{ 87 uid2: {key2a: true, key2c: true}, 88 uid3: {key3a: true}, 89 }) 90 91 require.Equal(t, UserDeviceKeyInfoMapV2{ 92 uid2: DeviceKeyInfoMapV2{ 93 key2a.KID(): TLFCryptKeyInfo{ 94 ServerHalfID: id2a, 95 EPubKeyIndex: -2, 96 }, 97 key2c.KID(): TLFCryptKeyInfo{ 98 ServerHalfID: id2c, 99 EPubKeyIndex: 0, 100 }, 101 }, 102 uid3: DeviceKeyInfoMapV2{ 103 key3a.KID(): TLFCryptKeyInfo{ 104 ServerHalfID: id3a, 105 EPubKeyIndex: -2, 106 }, 107 }, 108 }, udkimV2) 109 110 require.Equal(t, ServerHalfRemovalInfo{ 111 uid1: UserServerHalfRemovalInfo{ 112 UserRemoved: true, 113 DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{ 114 key1a: []kbfscrypto.TLFCryptKeyServerHalfID{id1a}, 115 key1b: []kbfscrypto.TLFCryptKeyServerHalfID{id1b}, 116 }, 117 }, 118 uid2: UserServerHalfRemovalInfo{ 119 UserRemoved: false, 120 DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{ 121 key2b: []kbfscrypto.TLFCryptKeyServerHalfID{id2b}, 122 }, 123 }, 124 }, removalInfo) 125 } 126 127 // TestRemoveLastDeviceV2 checks behavior of removeDevicesNotIn() with 128 // respect to removing the last device of a user vs. removing the user 129 // completely. 130 // 131 // This is a regression test for KBFS-1898. 132 func TestRemoveLastDeviceV2(t *testing.T) { 133 uid1 := keybase1.MakeTestUID(0x1) 134 uid2 := keybase1.MakeTestUID(0x2) 135 uid3 := keybase1.MakeTestUID(0x3) 136 uid4 := keybase1.MakeTestUID(0x4) 137 138 key1 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key1") 139 key2 := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key2") 140 141 half1 := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x1}) 142 half2 := kbfscrypto.MakeTLFCryptKeyServerHalf([32]byte{0x2}) 143 144 id1, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid1, key1, half1) 145 require.NoError(t, err) 146 id2, err := kbfscrypto.MakeTLFCryptKeyServerHalfID(uid2, key2, half2) 147 require.NoError(t, err) 148 149 udkimV2 := UserDeviceKeyInfoMapV2{ 150 uid1: DeviceKeyInfoMapV2{ 151 key1.KID(): TLFCryptKeyInfo{ 152 ServerHalfID: id1, 153 EPubKeyIndex: -1, 154 }, 155 }, 156 uid2: DeviceKeyInfoMapV2{ 157 key2.KID(): TLFCryptKeyInfo{ 158 ServerHalfID: id2, 159 EPubKeyIndex: -2, 160 }, 161 }, 162 uid3: DeviceKeyInfoMapV2{}, 163 uid4: DeviceKeyInfoMapV2{}, 164 } 165 166 removalInfo := udkimV2.RemoveDevicesNotIn(UserDevicePublicKeys{ 167 uid1: {}, 168 uid3: {}, 169 }) 170 171 require.Equal(t, UserDeviceKeyInfoMapV2{ 172 uid1: DeviceKeyInfoMapV2{}, 173 uid3: DeviceKeyInfoMapV2{}, 174 }, udkimV2) 175 176 require.Equal(t, ServerHalfRemovalInfo{ 177 uid1: UserServerHalfRemovalInfo{ 178 UserRemoved: false, 179 DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{ 180 key1: []kbfscrypto.TLFCryptKeyServerHalfID{id1}, 181 }, 182 }, 183 uid2: UserServerHalfRemovalInfo{ 184 UserRemoved: true, 185 DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{ 186 key2: []kbfscrypto.TLFCryptKeyServerHalfID{id2}, 187 }, 188 }, 189 uid4: UserServerHalfRemovalInfo{ 190 UserRemoved: true, 191 DeviceServerHalfIDs: DeviceServerHalfRemovalInfo{}, 192 }, 193 }, removalInfo) 194 } 195 196 func TestToTLFWriterKeyBundleV3(t *testing.T) { 197 uid1 := keybase1.MakeTestUID(0x1) 198 uid2 := keybase1.MakeTestUID(0x2) 199 200 key1a := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key1") 201 key1b := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key2") 202 key2a := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key3") 203 key2b := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key4") 204 key2c := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key5") 205 206 wEPubKey1 := kbfscrypto.MakeTLFEphemeralPublicKey([32]byte{0x1}) 207 wEPubKey2 := kbfscrypto.MakeTLFEphemeralPublicKey([32]byte{0x2}) 208 209 tlfPublicKey := kbfscrypto.MakeTLFPublicKey([32]byte{0x1}) 210 211 wkbV2 := TLFWriterKeyBundleV2{ 212 WKeys: UserDeviceKeyInfoMapV2{ 213 uid1: DeviceKeyInfoMapV2{ 214 key1a.KID(): TLFCryptKeyInfo{ 215 EPubKeyIndex: 0, 216 }, 217 key1b.KID(): TLFCryptKeyInfo{ 218 EPubKeyIndex: 1, 219 }, 220 }, 221 uid2: DeviceKeyInfoMapV2{ 222 key2a.KID(): TLFCryptKeyInfo{ 223 EPubKeyIndex: 1, 224 }, 225 key2b.KID(): TLFCryptKeyInfo{ 226 EPubKeyIndex: 0, 227 }, 228 key2c.KID(): TLFCryptKeyInfo{ 229 EPubKeyIndex: 0, 230 }, 231 }, 232 }, 233 TLFPublicKey: tlfPublicKey, 234 TLFEphemeralPublicKeys: kbfscrypto.TLFEphemeralPublicKeys{ 235 wEPubKey1, wEPubKey2, 236 }, 237 } 238 239 wkg := TLFWriterKeyGenerationsV2{TLFWriterKeyBundleV2{}, wkbV2} 240 241 codec := kbfscodec.NewMsgpack() 242 tlfCryptKey1 := kbfscrypto.MakeTLFCryptKey([32]byte{0x1}) 243 tlfCryptKey2 := kbfscrypto.MakeTLFCryptKey([32]byte{0x2}) 244 tlfCryptKeyGetter := func() ([]kbfscrypto.TLFCryptKey, error) { 245 return []kbfscrypto.TLFCryptKey{tlfCryptKey1, tlfCryptKey2}, nil 246 } 247 248 expectedWKBV3 := TLFWriterKeyBundleV3{ 249 Keys: UserDeviceKeyInfoMapV3{ 250 uid1: DeviceKeyInfoMapV3{ 251 key1a: TLFCryptKeyInfo{ 252 EPubKeyIndex: 0, 253 }, 254 key1b: TLFCryptKeyInfo{ 255 EPubKeyIndex: 1, 256 }, 257 }, 258 uid2: DeviceKeyInfoMapV3{ 259 key2a: TLFCryptKeyInfo{ 260 EPubKeyIndex: 1, 261 }, 262 key2b: TLFCryptKeyInfo{ 263 EPubKeyIndex: 0, 264 }, 265 key2c: TLFCryptKeyInfo{ 266 EPubKeyIndex: 0, 267 }, 268 }, 269 }, 270 TLFPublicKey: tlfPublicKey, 271 TLFEphemeralPublicKeys: kbfscrypto.TLFEphemeralPublicKeys{ 272 wEPubKey1, wEPubKey2, 273 }, 274 } 275 276 retrievedWKBV2, wkbV3, err := wkg.ToTLFWriterKeyBundleV3( 277 codec, tlfCryptKeyGetter) 278 require.NoError(t, err) 279 require.Equal(t, wkbV2, retrievedWKBV2) 280 encryptedOldKeys := wkbV3.EncryptedHistoricTLFCryptKeys 281 wkbV3.EncryptedHistoricTLFCryptKeys = kbfscrypto.EncryptedTLFCryptKeys{} 282 require.Equal(t, expectedWKBV3, wkbV3) 283 oldKeys, err := 284 kbfscrypto.DecryptTLFCryptKeys(codec, encryptedOldKeys, tlfCryptKey2) 285 require.NoError(t, err) 286 require.Equal(t, oldKeys, []kbfscrypto.TLFCryptKey{tlfCryptKey1}) 287 } 288 289 func TestToTLFReaderKeyBundleV3(t *testing.T) { 290 uid1 := keybase1.MakeTestUID(0x1) 291 uid2 := keybase1.MakeTestUID(0x2) 292 293 key1a := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key1") 294 key1b := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key2") 295 key2a := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key3") 296 key2b := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key4") 297 key2c := kbfscrypto.MakeFakeCryptPublicKeyOrBust("key5") 298 299 rEPubKey1 := kbfscrypto.MakeTLFEphemeralPublicKey([32]byte{0x1}) 300 rEPubKey2 := kbfscrypto.MakeTLFEphemeralPublicKey([32]byte{0x2}) 301 302 rkbV2 := TLFReaderKeyBundleV2{ 303 RKeys: UserDeviceKeyInfoMapV2{ 304 uid1: DeviceKeyInfoMapV2{ 305 key1a.KID(): TLFCryptKeyInfo{ 306 EPubKeyIndex: -1, 307 }, 308 key1b.KID(): TLFCryptKeyInfo{ 309 EPubKeyIndex: +2, 310 }, 311 }, 312 uid2: DeviceKeyInfoMapV2{ 313 key2a.KID(): TLFCryptKeyInfo{ 314 EPubKeyIndex: -2, 315 }, 316 key2b.KID(): TLFCryptKeyInfo{ 317 EPubKeyIndex: 0, 318 }, 319 key2c.KID(): TLFCryptKeyInfo{ 320 EPubKeyIndex: 0, 321 }, 322 }, 323 }, 324 TLFReaderEphemeralPublicKeys: kbfscrypto.TLFEphemeralPublicKeys{ 325 rEPubKey1, rEPubKey2, 326 }, 327 } 328 329 rkg := TLFReaderKeyGenerationsV2{TLFReaderKeyBundleV2{}, rkbV2} 330 331 codec := kbfscodec.NewMsgpack() 332 _, err := rkg.ToTLFReaderKeyBundleV3(codec, TLFWriterKeyBundleV2{}) 333 require.Error(t, err) 334 require.True(t, strings.HasPrefix(err.Error(), "Invalid key in WriterEPubKeys with index "), 335 "err: %v", err) 336 337 wEPubKey1 := kbfscrypto.MakeTLFEphemeralPublicKey([32]byte{0x3}) 338 wEPubKey2 := kbfscrypto.MakeTLFEphemeralPublicKey([32]byte{0x4}) 339 wEPubKey3 := kbfscrypto.MakeTLFEphemeralPublicKey([32]byte{0x5}) 340 341 wkbV2 := TLFWriterKeyBundleV2{ 342 TLFEphemeralPublicKeys: kbfscrypto.TLFEphemeralPublicKeys{ 343 wEPubKey1, wEPubKey2, wEPubKey3, 344 }, 345 } 346 347 // We need two expectedRKBV3s since the result depends on map 348 // iteration order. 349 350 expectedRKBV3a := TLFReaderKeyBundleV3{ 351 Keys: UserDeviceKeyInfoMapV3{ 352 uid1: DeviceKeyInfoMapV3{ 353 key1a: TLFCryptKeyInfo{ 354 EPubKeyIndex: 0, 355 }, 356 key1b: TLFCryptKeyInfo{ 357 EPubKeyIndex: 2, 358 }, 359 }, 360 uid2: DeviceKeyInfoMapV3{ 361 key2a: TLFCryptKeyInfo{ 362 EPubKeyIndex: 1, 363 }, 364 key2b: TLFCryptKeyInfo{ 365 EPubKeyIndex: 3, 366 }, 367 key2c: TLFCryptKeyInfo{ 368 EPubKeyIndex: 3, 369 }, 370 }, 371 }, 372 TLFEphemeralPublicKeys: kbfscrypto.TLFEphemeralPublicKeys{ 373 rEPubKey1, rEPubKey2, wEPubKey3, wEPubKey1, 374 }, 375 } 376 377 expectedRKBV3b := TLFReaderKeyBundleV3{ 378 Keys: UserDeviceKeyInfoMapV3{ 379 uid1: DeviceKeyInfoMapV3{ 380 key1a: TLFCryptKeyInfo{ 381 EPubKeyIndex: 0, 382 }, 383 key1b: TLFCryptKeyInfo{ 384 EPubKeyIndex: 3, 385 }, 386 }, 387 uid2: DeviceKeyInfoMapV3{ 388 key2a: TLFCryptKeyInfo{ 389 EPubKeyIndex: 1, 390 }, 391 key2b: TLFCryptKeyInfo{ 392 EPubKeyIndex: 2, 393 }, 394 key2c: TLFCryptKeyInfo{ 395 EPubKeyIndex: 2, 396 }, 397 }, 398 }, 399 TLFEphemeralPublicKeys: kbfscrypto.TLFEphemeralPublicKeys{ 400 rEPubKey1, rEPubKey2, wEPubKey1, wEPubKey3, 401 }, 402 } 403 404 rkbV3, err := rkg.ToTLFReaderKeyBundleV3(codec, wkbV2) 405 require.NoError(t, err) 406 if !reflect.DeepEqual(expectedRKBV3a, rkbV3) { 407 require.Equal(t, expectedRKBV3b, rkbV3) 408 } 409 } 410 411 type deviceKeyInfoMapV2Future map[keybase1.KID]tlfCryptKeyInfoFuture 412 413 func (dkimf deviceKeyInfoMapV2Future) toCurrent() DeviceKeyInfoMapV2 { 414 dkim := make(DeviceKeyInfoMapV2, len(dkimf)) 415 for k, kif := range dkimf { 416 ki := kif.toCurrent() 417 dkim[k] = ki 418 } 419 return dkim 420 } 421 422 type userDeviceKeyInfoMapV2Future map[keybase1.UID]deviceKeyInfoMapV2Future 423 424 func (udkimf userDeviceKeyInfoMapV2Future) toCurrent() UserDeviceKeyInfoMapV2 { 425 udkim := make(UserDeviceKeyInfoMapV2) 426 for u, dkimf := range udkimf { 427 dkim := dkimf.toCurrent() 428 udkim[u] = dkim 429 } 430 return udkim 431 } 432 433 type tlfWriterKeyBundleV2Future struct { 434 TLFWriterKeyBundleV2 435 // Override TLFWriterKeyBundleV2.WKeys. 436 WKeys userDeviceKeyInfoMapV2Future 437 kbfscodec.Extra 438 } 439 440 func (wkbf tlfWriterKeyBundleV2Future) toCurrent() TLFWriterKeyBundleV2 { 441 wkb := wkbf.TLFWriterKeyBundleV2 442 wkb.WKeys = wkbf.WKeys.toCurrent() 443 return wkb 444 } 445 446 func (wkbf tlfWriterKeyBundleV2Future) ToCurrentStruct() kbfscodec.CurrentStruct { 447 return wkbf.toCurrent() 448 } 449 450 func makeFakeDeviceKeyInfoMapV2Future(t *testing.T) userDeviceKeyInfoMapV2Future { 451 return userDeviceKeyInfoMapV2Future{ 452 "fake uid": deviceKeyInfoMapV2Future{ 453 "fake kid": makeFakeTLFCryptKeyInfoFuture(t), 454 }, 455 } 456 } 457 458 func makeFakeTLFWriterKeyBundleV2Future( 459 t *testing.T) tlfWriterKeyBundleV2Future { 460 wkb := TLFWriterKeyBundleV2{ 461 nil, 462 kbfscrypto.MakeTLFPublicKey([32]byte{0xa}), 463 kbfscrypto.TLFEphemeralPublicKeys{ 464 kbfscrypto.MakeTLFEphemeralPublicKey([32]byte{0xb}), 465 }, 466 codec.UnknownFieldSetHandler{}, 467 } 468 return tlfWriterKeyBundleV2Future{ 469 wkb, 470 makeFakeDeviceKeyInfoMapV2Future(t), 471 kbfscodec.MakeExtraOrBust("TLFWriterKeyBundleV2", t), 472 } 473 } 474 475 func TestTLFWriterKeyBundleV2UnknownFields(t *testing.T) { 476 testStructUnknownFields(t, makeFakeTLFWriterKeyBundleV2Future(t)) 477 } 478 479 type tlfReaderKeyBundleV2Future struct { 480 TLFReaderKeyBundleV2 481 // Override TLFReaderKeyBundleV2.RKeys. 482 RKeys userDeviceKeyInfoMapV2Future 483 kbfscodec.Extra 484 } 485 486 func (rkbf tlfReaderKeyBundleV2Future) toCurrent() TLFReaderKeyBundleV2 { 487 rkb := rkbf.TLFReaderKeyBundleV2 488 rkb.RKeys = rkbf.RKeys.toCurrent() 489 return rkb 490 } 491 492 func (rkbf tlfReaderKeyBundleV2Future) ToCurrentStruct() kbfscodec.CurrentStruct { 493 return rkbf.toCurrent() 494 } 495 496 func makeFakeTLFReaderKeyBundleV2Future( 497 t *testing.T) tlfReaderKeyBundleV2Future { 498 rkb := TLFReaderKeyBundleV2{ 499 nil, 500 kbfscrypto.TLFEphemeralPublicKeys{ 501 kbfscrypto.MakeTLFEphemeralPublicKey([32]byte{0xc}), 502 }, 503 codec.UnknownFieldSetHandler{}, 504 } 505 return tlfReaderKeyBundleV2Future{ 506 rkb, 507 makeFakeDeviceKeyInfoMapV2Future(t), 508 kbfscodec.MakeExtraOrBust("TLFReaderKeyBundleV2", t), 509 } 510 } 511 512 func TestTLFReaderKeyBundleV2UnknownFields(t *testing.T) { 513 testStructUnknownFields(t, makeFakeTLFReaderKeyBundleV2Future(t)) 514 }