github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/saltpackkeys/saltpack_recipient_keyfinder_engine_test.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 package saltpackkeys 4 5 import ( 6 "bytes" 7 "context" 8 "encoding/hex" 9 "fmt" 10 "testing" 11 12 "github.com/stretchr/testify/require" 13 14 "github.com/keybase/client/go/engine" 15 "github.com/keybase/client/go/externalstest" 16 "github.com/keybase/client/go/kbtest" 17 "github.com/keybase/client/go/libkb" 18 "github.com/keybase/client/go/protocol/keybase1" 19 "github.com/keybase/client/go/teams" 20 insecureTriplesec "github.com/keybase/go-triplesec-insecure" 21 ) 22 23 func InstallInsecureTriplesec(g *libkb.GlobalContext) { 24 g.NewTriplesec = func(passphrase []byte, salt []byte) (libkb.Triplesec, error) { 25 warner := func() { g.Log.Warning("Installing insecure Triplesec with weak stretch parameters") } 26 isProduction := func() bool { 27 return g.Env.GetRunMode() == libkb.ProductionRunMode 28 } 29 return insecureTriplesec.NewCipher(passphrase, salt, libkb.ClientTriplesecVersion, warner, isProduction) 30 } 31 } 32 33 func SetupKeyfinderEngineTest(tb libkb.TestingTB, name string) (tc libkb.TestContext) { 34 // SetupTest ignores the depth argument, so we can safely pass 0. 35 tc = externalstest.SetupTest(tb, name, 0) 36 37 // use an insecure triplesec in tests 38 InstallInsecureTriplesec(tc.G) 39 40 return tc 41 42 } 43 44 func TestSaltpackRecipientKeyfinderPUKs(t *testing.T) { 45 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 46 defer tc.Cleanup() 47 48 u1, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 49 require.NoError(t, err) 50 u2, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 51 require.NoError(t, err) 52 u3, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 53 require.NoError(t, err) 54 55 trackUI := &kbtest.FakeIdentifyUI{ 56 Proofs: make(map[string]string), 57 } 58 59 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u3.NewSecretUI()} 60 arg := libkb.SaltpackRecipientKeyfinderArg{ 61 Recipients: []string{u1.Username, u2.Username, u3.Username}, 62 UseEntityKeys: true, 63 // Since no user has a paper key, this option should not lead to the addition of any keys. 64 UsePaperKeys: true, 65 } 66 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 67 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 68 if err := engine.RunEngine2(m, eng); err != nil { 69 t.Fatal(err) 70 } 71 72 fDHKeys := eng.GetPublicKIDs() 73 if len(fDHKeys) != 3 { 74 t.Errorf("number of per user keys found: %d, expected 3", len(fDHKeys)) 75 } 76 fDHKeyset := make(map[keybase1.KID]struct{}) 77 for _, fPUK := range fDHKeys { 78 fDHKeyset[fPUK] = struct{}{} 79 } 80 KID := u1.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 81 if _, ok := fDHKeyset[KID]; !ok { 82 t.Errorf("expected to find key %v, which was not retrieved", KID) 83 } 84 KID = u2.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 85 if _, ok := fDHKeyset[KID]; !ok { 86 t.Errorf("expected to find key %v, which was not retrieved", KID) 87 } 88 KID = u3.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 89 if _, ok := fDHKeyset[KID]; !ok { 90 t.Errorf("expected to find key %v, which was not retrieved", KID) 91 } 92 93 symKeys := eng.GetSymmetricKeys() 94 if len(symKeys) != 0 { 95 t.Errorf("number of symmetric keys found: %d, expected 0", len(symKeys)) 96 } 97 98 } 99 100 func TestSaltpackRecipientKeyfinderFailsOnNonExistingUserWithoutLogin(t *testing.T) { 101 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 102 defer tc.Cleanup() 103 104 u3, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 105 require.NoError(t, err) 106 kbtest.Logout(tc) 107 108 trackUI := &kbtest.FakeIdentifyUI{ 109 Proofs: make(map[string]string), 110 } 111 112 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u3.NewSecretUI()} 113 arg := libkb.SaltpackRecipientKeyfinderArg{ 114 Recipients: []string{"not_a_user"}, 115 UseEntityKeys: true, 116 NoSelfEncrypt: true, 117 } 118 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 119 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 120 err = engine.RunEngine2(m, eng) 121 _, ok := engine.RunEngine2(m, eng).(libkb.RecipientNotFoundError) 122 require.True(t, ok, err.Error()) 123 } 124 125 func TestSaltpackRecipientKeyfinderFailsOnNonExistingUserWithLogin(t *testing.T) { 126 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 127 defer tc.Cleanup() 128 129 u3, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 130 require.NoError(t, err) 131 132 trackUI := &kbtest.FakeIdentifyUI{ 133 Proofs: make(map[string]string), 134 } 135 136 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u3.NewSecretUI()} 137 arg := libkb.SaltpackRecipientKeyfinderArg{ 138 Recipients: []string{"not_a_user"}, 139 UseEntityKeys: true, 140 } 141 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 142 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 143 err = engine.RunEngine2(m, eng) 144 _, ok := engine.RunEngine2(m, eng).(libkb.RecipientNotFoundError) 145 require.True(t, ok, err.Error()) 146 } 147 148 func TestSaltpackRecipientKeyfinderPUKSelfEncrypt(t *testing.T) { 149 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 150 defer tc.Cleanup() 151 152 u1, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 153 require.NoError(t, err) 154 u2, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 155 require.NoError(t, err) 156 u3, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 157 require.NoError(t, err) 158 159 trackUI := &kbtest.FakeIdentifyUI{ 160 Proofs: make(map[string]string), 161 } 162 163 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u3.NewSecretUI()} 164 arg := libkb.SaltpackRecipientKeyfinderArg{ 165 Recipients: []string{u1.Username, u2.Username}, 166 UseEntityKeys: true, 167 } 168 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 169 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 170 if err := engine.RunEngine2(m, eng); err != nil { 171 t.Fatal(err) 172 } 173 174 fDHKeys := eng.GetPublicKIDs() 175 if len(fDHKeys) != 3 { 176 t.Errorf("number of per user keys found: %d, expected 3", len(fDHKeys)) 177 } 178 fDHKeyset := make(map[keybase1.KID]struct{}) 179 for _, fPUK := range fDHKeys { 180 fDHKeyset[fPUK] = struct{}{} 181 } 182 KID := u1.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 183 if _, ok := fDHKeyset[KID]; !ok { 184 t.Errorf("expected to find key %v, which was not retrieved", KID) 185 } 186 KID = u2.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 187 if _, ok := fDHKeyset[KID]; !ok { 188 t.Errorf("expected to find key %v, which was not retrieved", KID) 189 } 190 KID = u3.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 191 if _, ok := fDHKeyset[KID]; !ok { 192 t.Errorf("expected to find key %v, which was not retrieved", KID) 193 } 194 195 symKeys := eng.GetSymmetricKeys() 196 if len(symKeys) != 0 { 197 t.Errorf("number of symmetric keys found: %d, expected 0", len(symKeys)) 198 } 199 200 } 201 202 func TestSaltpackRecipientKeyfinderPUKNoSelfEncrypt(t *testing.T) { 203 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 204 defer tc.Cleanup() 205 206 u1, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 207 require.NoError(t, err) 208 u2, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 209 require.NoError(t, err) 210 u3, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 211 require.NoError(t, err) 212 213 trackUI := &kbtest.FakeIdentifyUI{ 214 Proofs: make(map[string]string), 215 } 216 217 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u3.NewSecretUI()} 218 arg := libkb.SaltpackRecipientKeyfinderArg{ 219 Recipients: []string{u1.Username, u2.Username}, 220 UseEntityKeys: true, 221 NoSelfEncrypt: true, // Since this is set, u3's keys should NOT be included. 222 } 223 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 224 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 225 if err := engine.RunEngine2(m, eng); err != nil { 226 t.Fatal(err) 227 } 228 229 fDHKeys := eng.GetPublicKIDs() 230 if len(fDHKeys) != 2 { 231 t.Errorf("number of per user keys found: %d, expected 2", len(fDHKeys)) 232 } 233 fDHKeyset := make(map[keybase1.KID]struct{}) 234 for _, fPUK := range fDHKeys { 235 fDHKeyset[fPUK] = struct{}{} 236 } 237 KID := u1.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 238 if _, ok := fDHKeyset[KID]; !ok { 239 t.Errorf("expected to find key %v, which was not retrieved", KID) 240 } 241 KID = u2.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 242 if _, ok := fDHKeyset[KID]; !ok { 243 t.Errorf("expected to find key %v, which was not retrieved", KID) 244 } 245 246 symKeys := eng.GetSymmetricKeys() 247 if len(symKeys) != 0 { 248 t.Errorf("number of symmetric keys found: %d, expected 0", len(symKeys)) 249 } 250 251 } 252 253 func TestSaltpackRecipientKeyfinderCreatesImplicitTeamIfUserHasNoPUK(t *testing.T) { 254 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 255 defer tc.Cleanup() 256 teams.ServiceInit(tc.G) 257 258 u1, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 259 require.NoError(t, err) 260 u2, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 261 require.NoError(t, err) 262 263 trackUI := &kbtest.FakeIdentifyUI{ 264 Proofs: make(map[string]string), 265 } 266 267 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u2.NewSecretUI()} 268 arg := libkb.SaltpackRecipientKeyfinderArg{ 269 Recipients: []string{u1.Username}, 270 UseEntityKeys: true, 271 } 272 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 273 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 274 275 // This should work with no errors, as both users exist and have PUKs 276 if err := engine.RunEngine2(m, eng); err != nil { 277 t.Fatal(err) 278 } 279 fDHKeys := eng.GetPublicKIDs() 280 if len(fDHKeys) != 2 { 281 t.Errorf("number of per user keys found: %d, expected 2", len(fDHKeys)) 282 } 283 fDHKeyset := make(map[keybase1.KID]struct{}) 284 for _, fPUK := range fDHKeys { 285 fDHKeyset[fPUK] = struct{}{} 286 } 287 KID := u1.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 288 if _, ok := fDHKeyset[KID]; !ok { 289 t.Errorf("expected to find key %v, which was not retrieved", KID) 290 } 291 KID = u2.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 292 if _, ok := fDHKeyset[KID]; !ok { 293 t.Errorf("expected to find key %v, which was not retrieved", KID) 294 } 295 296 require.Empty(t, eng.GetSymmetricKeys()) 297 298 // Now, let's create a user without PUK 299 tc.Tp.DisableUpgradePerUserKey = true 300 u3, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 301 require.NoError(t, err) 302 kbtest.Logout(tc) 303 304 err = u2.Login(tc.G) 305 require.NoError(t, err) 306 307 // This should create an implicit team, as u3 has no PUK 308 arg = libkb.SaltpackRecipientKeyfinderArg{ 309 Recipients: []string{u1.Username, u3.Username}, 310 UseEntityKeys: true, 311 } 312 eng = NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 313 err = engine.RunEngine2(m, eng) 314 require.NoError(t, err) 315 fDHKeys = eng.GetPublicKIDs() 316 if len(fDHKeys) != 2 { 317 t.Errorf("number of per user keys found: %d, expected 2", len(fDHKeys)) 318 } 319 fDHKeyset = make(map[keybase1.KID]struct{}) 320 for _, fPUK := range fDHKeys { 321 fDHKeyset[fPUK] = struct{}{} 322 } 323 KID = u1.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 324 if _, ok := fDHKeyset[KID]; !ok { 325 t.Errorf("expected to find key %v, which was not retrieved", KID) 326 } 327 KID = u2.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 328 if _, ok := fDHKeyset[KID]; !ok { 329 t.Errorf("expected to find key %v, which was not retrieved", KID) 330 } 331 332 symKeys := eng.GetSymmetricKeys() 333 require.Len(t, symKeys, 1) 334 team, _, _, err := teams.LookupImplicitTeam(m.Ctx(), m.G(), u2.Username+","+u3.Username, false, teams.ImplicitTeamOptions{}) 335 require.NoError(t, err) 336 teamSaltpackKey, err := team.SaltpackEncryptionKeyLatest(m.Ctx()) 337 require.NoError(t, err) 338 require.True(t, bytes.Equal(teamSaltpackKey.Key[:], symKeys[0].Key[:])) 339 } 340 341 func TestSaltpackRecipientKeyfinderDeviceKeys(t *testing.T) { 342 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 343 defer tc.Cleanup() 344 345 u1, err := kbtest.CreateAndSignupFakeUserPaper("spkfe", tc.G) 346 require.NoError(t, err) 347 348 // u2 has 2 devices 349 u2, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 350 require.NoError(t, err) 351 tcY := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine2") // context for second device 352 defer tcY.Cleanup() 353 kbtest.ProvisionNewDeviceKex(&tc, &tcY, u2, keybase1.DeviceTypeV2_DESKTOP) 354 m := libkb.NewMetaContextForTest(tc) 355 tc.G.BustLocalUserCache(m.Ctx(), u2.GetUID()) 356 tc.G.GetUPAKLoader().ClearMemory() 357 u2new, err := libkb.LoadMe(libkb.NewLoadUserArgWithMetaContext(m)) 358 require.NoError(t, err) 359 360 u3, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 361 require.NoError(t, err) 362 363 trackUI := &kbtest.FakeIdentifyUI{ 364 Proofs: make(map[string]string), 365 } 366 367 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u3.NewSecretUI()} 368 arg := libkb.SaltpackRecipientKeyfinderArg{ 369 Recipients: []string{u1.Username, u2.Username, u3.Username}, 370 UseDeviceKeys: true, 371 } 372 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 373 m = m.WithUIs(uis) 374 if err := engine.RunEngine2(m, eng); err != nil { 375 t.Fatal(err) 376 } 377 378 fDHKeys := eng.GetPublicKIDs() 379 if len(fDHKeys) != 4 { 380 t.Errorf("number of device keys found: %d, expected 4", len(fDHKeys)) 381 } 382 fDHKeyset := make(map[keybase1.KID]struct{}) 383 for _, fPUK := range fDHKeys { 384 fDHKeyset[fPUK] = struct{}{} 385 } 386 387 u1Device, err := selectOneActiveNonPaperDeviceID(u1.User) 388 require.NoError(t, err) 389 key, err := u1.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u1Device) 390 require.NoError(t, err) 391 KID := key.GetKID() 392 if _, ok := fDHKeyset[KID]; !ok { 393 t.Errorf("expected to find key %v, which was not retrieved", KID) 394 } 395 key, err = u2new.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u2new.GetComputedKeyFamily().GetAllActiveDevices()[0].ID) 396 require.NoError(t, err) 397 KID = key.GetKID() 398 if _, ok := fDHKeyset[KID]; !ok { 399 t.Errorf("expected to find key %v, which was not retrieved", KID) 400 } 401 key, err = u2new.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u2new.GetComputedKeyFamily().GetAllActiveDevices()[1].ID) 402 require.NoError(t, err) 403 KID = key.GetKID() 404 if _, ok := fDHKeyset[KID]; !ok { 405 t.Errorf("expected to find key %v, which was not retrieved", KID) 406 } 407 key, err = u3.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u3.User.GetComputedKeyFamily().GetAllActiveDevices()[0].ID) 408 require.NoError(t, err) 409 KID = key.GetKID() 410 if _, ok := fDHKeyset[KID]; !ok { 411 t.Errorf("expected to find key %v, which was not retrieved", KID) 412 } 413 414 symKeys := eng.GetSymmetricKeys() 415 if len(symKeys) != 0 { 416 t.Errorf("number of symmetric keys found: %d, expected 0", len(symKeys)) 417 } 418 419 } 420 421 func TestSaltpackRecipientKeyfinderSkipsMissingKeys(t *testing.T) { 422 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 423 defer tc.Cleanup() 424 425 u1, err := kbtest.CreateAndSignupFakeUserPaper("spkfe", tc.G) 426 require.NoError(t, err) 427 u2, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 428 require.NoError(t, err) 429 u3, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 430 require.NoError(t, err) 431 432 trackUI := &kbtest.FakeIdentifyUI{ 433 Proofs: make(map[string]string), 434 } 435 436 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u3.NewSecretUI()} 437 arg := libkb.SaltpackRecipientKeyfinderArg{ 438 Recipients: []string{u1.Username, u2.Username, u3.Username}, 439 UseDeviceKeys: true, 440 UsePaperKeys: true, // only u1 has a paper key 441 } 442 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 443 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 444 if err := engine.RunEngine2(m, eng); err != nil { 445 t.Fatal(err) 446 } 447 448 fDHKeys := eng.GetPublicKIDs() 449 if len(fDHKeys) != 4 { 450 t.Errorf("number of device keys found: %d, expected 4", len(fDHKeys)) 451 } 452 fDHKeyset := make(map[keybase1.KID]struct{}) 453 for _, fPUK := range fDHKeys { 454 fDHKeyset[fPUK] = struct{}{} 455 } 456 457 key, err := u1.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u1.User.GetComputedKeyFamily().GetAllActiveDevices()[0].ID) 458 require.NoError(t, err) 459 KID := key.GetKID() 460 if _, ok := fDHKeyset[KID]; !ok { 461 t.Errorf("expected to find key %v, which was not retrieved", KID) 462 } 463 key, err = u1.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u1.User.GetComputedKeyFamily().GetAllActiveDevices()[1].ID) 464 require.NoError(t, err) 465 KID = key.GetKID() 466 if _, ok := fDHKeyset[KID]; !ok { 467 t.Errorf("expected to find key %v, which was not retrieved", KID) 468 } 469 key, err = u2.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u2.User.GetComputedKeyFamily().GetAllActiveDevices()[0].ID) 470 require.NoError(t, err) 471 KID = key.GetKID() 472 if _, ok := fDHKeyset[KID]; !ok { 473 t.Errorf("expected to find key %v, which was not retrieved", KID) 474 } 475 key, err = u3.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u3.User.GetComputedKeyFamily().GetAllActiveDevices()[0].ID) 476 require.NoError(t, err) 477 KID = key.GetKID() 478 if _, ok := fDHKeyset[KID]; !ok { 479 t.Errorf("expected to find key %v, which was not retrieved", KID) 480 } 481 482 symKeys := eng.GetSymmetricKeys() 483 if len(symKeys) != 0 { 484 t.Errorf("number of symmetric keys found: %d, expected 0", len(symKeys)) 485 } 486 487 } 488 489 func selectOneActivePaperDeviceID(u *libkb.User) (keybase1.DeviceID, error) { 490 for _, d := range u.GetComputedKeyFamily().GetAllActiveDevices() { 491 if d.Type == keybase1.DeviceTypeV2_PAPER { 492 return d.ID, nil 493 } 494 } 495 return "", fmt.Errorf("No paper devices found") 496 } 497 498 func selectOneActiveNonPaperDeviceID(u *libkb.User) (keybase1.DeviceID, error) { 499 for _, d := range u.GetComputedKeyFamily().GetAllActiveDevices() { 500 if d.Type != keybase1.DeviceTypeV2_PAPER { 501 return d.ID, nil 502 } 503 } 504 return "", fmt.Errorf("No paper devices found") 505 } 506 507 func TestSaltpackRecipientKeyfinderPaperKeys(t *testing.T) { 508 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 509 defer tc.Cleanup() 510 511 u1, err := kbtest.CreateAndSignupFakeUserPaper("spkfe", tc.G) 512 require.NoError(t, err) 513 u2, err := kbtest.CreateAndSignupFakeUserPaper("spkfe", tc.G) 514 require.NoError(t, err) 515 u3, err := kbtest.CreateAndSignupFakeUserPaper("spkfe", tc.G) 516 require.NoError(t, err) 517 518 trackUI := &kbtest.FakeIdentifyUI{ 519 Proofs: make(map[string]string), 520 } 521 522 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u3.NewSecretUI()} 523 arg := libkb.SaltpackRecipientKeyfinderArg{ 524 Recipients: []string{u1.Username, u2.Username, u3.Username}, 525 UsePaperKeys: true, 526 } 527 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 528 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 529 if err := engine.RunEngine2(m, eng); err != nil { 530 t.Fatal(err) 531 } 532 533 fDHKeys := eng.GetPublicKIDs() 534 if len(fDHKeys) != 3 { 535 t.Errorf("number of device keys found: %d, expected 3", len(fDHKeys)) 536 } 537 fDHKeyset := make(map[keybase1.KID]struct{}) 538 for _, fPUK := range fDHKeys { 539 fDHKeyset[fPUK] = struct{}{} 540 } 541 542 id, err := selectOneActivePaperDeviceID(u1.User) 543 require.NoError(t, err) 544 key, err := u1.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(id) 545 require.NoError(t, err) 546 KID := key.GetKID() 547 if _, ok := fDHKeyset[KID]; !ok { 548 t.Errorf("expected to find key %v, which was not retrieved", KID) 549 } 550 id, err = selectOneActivePaperDeviceID(u1.User) 551 require.NoError(t, err) 552 key, err = u1.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(id) 553 require.NoError(t, err) 554 KID = key.GetKID() 555 if _, ok := fDHKeyset[KID]; !ok { 556 t.Errorf("expected to find key %v, which was not retrieved", KID) 557 } 558 id, err = selectOneActivePaperDeviceID(u1.User) 559 require.NoError(t, err) 560 key, err = u1.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(id) 561 require.NoError(t, err) 562 KID = key.GetKID() 563 if _, ok := fDHKeyset[KID]; !ok { 564 t.Errorf("expected to find key %v, which was not retrieved", KID) 565 } 566 567 symKeys := eng.GetSymmetricKeys() 568 if len(symKeys) != 0 { 569 t.Errorf("number of symmetric keys found: %d, expected 0", len(symKeys)) 570 } 571 } 572 573 func TestSaltpackRecipientKeyfinderDevicePaperAndPerUserKeys(t *testing.T) { 574 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 575 defer tc.Cleanup() 576 577 u1, err := kbtest.CreateAndSignupFakeUserPaper("spkfe", tc.G) 578 require.NoError(t, err) 579 580 // u2 has 2 devices + 1 paper device 581 u2, err := kbtest.CreateAndSignupFakeUserPaper("spkfe", tc.G) 582 require.NoError(t, err) 583 tcY := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine2") // context for second device 584 defer tcY.Cleanup() 585 kbtest.ProvisionNewDeviceKex(&tc, &tcY, u2, keybase1.DeviceTypeV2_DESKTOP) 586 m := libkb.NewMetaContextForTest(tc) 587 tc.G.BustLocalUserCache(m.Ctx(), u2.GetUID()) 588 tc.G.GetUPAKLoader().ClearMemory() 589 u2new, err := libkb.LoadMe(libkb.NewLoadUserArgWithMetaContext(m)) 590 require.NoError(t, err) 591 592 u3, err := kbtest.CreateAndSignupFakeUserPaper("spkfe", tc.G) 593 require.NoError(t, err) 594 595 trackUI := &kbtest.FakeIdentifyUI{ 596 Proofs: make(map[string]string), 597 } 598 599 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u3.NewSecretUI()} 600 arg := libkb.SaltpackRecipientKeyfinderArg{ 601 Recipients: []string{u1.Username, u2.Username, u3.Username}, 602 UseDeviceKeys: true, 603 UsePaperKeys: true, 604 UseEntityKeys: true, 605 } 606 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 607 m = m.WithUIs(uis) 608 if err := engine.RunEngine2(m, eng); err != nil { 609 t.Fatal(err) 610 } 611 612 fDHKeys := eng.GetPublicKIDs() 613 if len(fDHKeys) != 10 { // 3 keys per user (1 paper, 1 device, 1 puk), plus an extra device for u2 614 t.Errorf("number of device keys found: %d, expected 4", len(fDHKeys)) 615 } 616 fDHKeyset := make(map[keybase1.KID]struct{}) 617 for _, fPUK := range fDHKeys { 618 fDHKeyset[fPUK] = struct{}{} 619 } 620 621 allKeyFamilies := []*libkb.ComputedKeyFamily{} 622 allKeyFamilies = append(allKeyFamilies, u1.User.GetComputedKeyFamily()) 623 allKeyFamilies = append(allKeyFamilies, u2new.GetComputedKeyFamily()) 624 allKeyFamilies = append(allKeyFamilies, u3.User.GetComputedKeyFamily()) 625 626 var allKIDs []keybase1.KID 627 for _, kf := range allKeyFamilies { 628 for _, d := range kf.GetAllActiveDevices() { 629 k, err := kf.GetEncryptionSubkeyForDevice(d.ID) 630 require.NoError(t, err) 631 allKIDs = append(allKIDs, k.GetKID()) 632 } 633 allKIDs = append(allKIDs, kf.GetLatestPerUserKey().EncKID) 634 } 635 require.Equal(t, 10, len(allKIDs)) // 3 keys for u1 and u3 (1 paper, 1 device, 1 puk), 4 for u2 (has 2 devices) 636 637 for _, KID := range allKIDs { 638 if _, ok := fDHKeyset[KID]; !ok { 639 t.Errorf("expected to find key %v, which was not retrieved", KID) 640 } 641 } 642 symKeys := eng.GetSymmetricKeys() 643 if len(symKeys) != 0 { 644 t.Errorf("number of symmetric keys found: %d, expected 0", len(symKeys)) 645 } 646 } 647 648 func TestSaltpackRecipientKeyfinderExistingUserAssertions(t *testing.T) { 649 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 650 defer tc.Cleanup() 651 652 u1, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 653 require.NoError(t, err) 654 655 trackUI := &kbtest.FakeIdentifyUI{ 656 Proofs: make(map[string]string), 657 } 658 659 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u1.NewSecretUI()} 660 arg := libkb.SaltpackRecipientKeyfinderArg{ 661 Recipients: []string{"t_tracy+t_tracy@rooter", "t_george", "t_kb+gbrltest@twitter"}, 662 UseDeviceKeys: true, 663 NoSelfEncrypt: true, 664 } 665 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 666 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 667 if err := engine.RunEngine2(m, eng); err != nil { 668 t.Fatal(err) 669 } 670 671 fDHKeys := eng.GetPublicKIDs() 672 if len(fDHKeys) != 6 { // t_tracy has 1 device (+ a paper key, excluded here), t_george has 2 devices and a web key, t_kb has a device and a web key. 673 t.Errorf("number of DH keys found: %d, expected 6", len(fDHKeys)) 674 } 675 676 symKeys := eng.GetSymmetricKeys() 677 if len(symKeys) != 0 { 678 t.Errorf("number of symmetric keys found: %d, expected 0", len(symKeys)) 679 } 680 681 } 682 683 func createTeam(tc libkb.TestContext) (keybase1.TeamID, string) { 684 teams.ServiceInit(tc.G) 685 686 b, err := libkb.RandBytes(4) 687 require.NoError(tc.T, err) 688 name := "t_" + hex.EncodeToString(b) 689 teamID, err := teams.CreateRootTeam(context.TODO(), tc.G, name, keybase1.TeamSettings{}) 690 require.NoError(tc.T, err) 691 require.NotNil(tc.T, teamID) 692 693 return *teamID, name 694 } 695 696 func TestSaltpackRecipientKeyfinderTeamBasic(t *testing.T) { 697 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 698 defer tc.Cleanup() 699 700 u1, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 701 require.NoError(t, err) 702 u2, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 703 require.NoError(t, err) 704 705 _, teamName := createTeam(tc) 706 _, err = teams.AddMember(context.TODO(), tc.G, teamName, u1.Username, keybase1.TeamRole_WRITER, nil) 707 require.NoError(t, err) 708 709 u3, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 710 require.NoError(t, err) 711 712 err = u3.Login(tc.G) 713 require.NoError(t, err) 714 715 trackUI := &kbtest.FakeIdentifyUI{ 716 Proofs: make(map[string]string), 717 } 718 719 // u3 is not part of the team, keyfinding should fail. 720 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u3.NewSecretUI()} 721 arg := libkb.SaltpackRecipientKeyfinderArg{ 722 TeamRecipients: []string{teamName}, 723 UseEntityKeys: true, 724 } 725 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 726 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 727 err = engine.RunEngine2(m, eng) 728 if e, ok := err.(libkb.AppStatusError); !ok || e.Code != libkb.SCTeamReadError { 729 t.Fatalf("expected error type libkb.AppStatusError with code %v, got %T (%+v)", libkb.SCTeamReadError, err, err) 730 } 731 kbtest.Logout(tc) 732 733 // u2 is part of the team, keyfinding should succeed. 734 err = u2.Login(tc.G) 735 require.NoError(t, err) 736 uis = libkb.UIs{IdentifyUI: trackUI, SecretUI: u2.NewSecretUI()} 737 eng = NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 738 m = libkb.NewMetaContextForTest(tc).WithUIs(uis) 739 err = engine.RunEngine2(m, eng) 740 require.NoError(t, err) 741 742 fDHKeys := eng.GetPublicKIDs() 743 if len(fDHKeys) != 1 { // We requested Entity Keys only, so no PUKs or Device Keys (except for the sender's own key) 744 t.Errorf("number of DH keys found: %d, expected 1", len(fDHKeys)) 745 } 746 fDHKeyset := make(map[keybase1.KID]struct{}) 747 for _, fPUK := range fDHKeys { 748 fDHKeyset[fPUK] = struct{}{} 749 } 750 751 u2PUK := u2.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 752 if _, ok := fDHKeyset[u2PUK]; !ok { 753 t.Errorf("expected to find key %v, which was not retrieved", u2PUK) 754 } 755 756 symKeys := eng.GetSymmetricKeys() 757 if len(symKeys) != 1 { 758 t.Errorf("number of symmetric keys found: %d, expected 1", len(symKeys)) 759 } 760 761 team, err := teams.Load(m.Ctx(), m.G(), keybase1.LoadTeamArg{Name: teamName}) 762 require.NoError(t, err) 763 teamSaltpackKey, err := team.SaltpackEncryptionKeyLatest(m.Ctx()) 764 require.NoError(t, err) 765 require.True(t, bytes.Equal(teamSaltpackKey.Key[:], symKeys[0].Key[:])) 766 767 // Now we look for keys for a team, without including the sender's keys 768 arg = libkb.SaltpackRecipientKeyfinderArg{ 769 TeamRecipients: []string{teamName}, 770 UseEntityKeys: true, 771 NoSelfEncrypt: true, 772 } 773 eng = NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 774 err = engine.RunEngine2(m, eng) 775 require.NoError(t, err) 776 777 fDHKeys = eng.GetPublicKIDs() 778 if len(fDHKeys) != 0 { 779 t.Errorf("number of DH keys found: %d, expected 0", len(fDHKeys)) 780 } 781 782 symKeys = eng.GetSymmetricKeys() 783 if len(symKeys) != 1 { 784 t.Errorf("number of symmetric keys found: %d, expected 1", len(symKeys)) 785 } 786 787 require.True(t, bytes.Equal(teamSaltpackKey.Key[:], symKeys[0].Key[:])) 788 789 // Now we look for keys for a team, including the device keys of the members 790 arg = libkb.SaltpackRecipientKeyfinderArg{ 791 TeamRecipients: []string{teamName}, 792 UseEntityKeys: true, 793 UseDeviceKeys: true, 794 } 795 eng = NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 796 err = engine.RunEngine2(m, eng) 797 require.NoError(t, err) 798 799 fDHKeys = eng.GetPublicKIDs() 800 if len(fDHKeys) != 3 { // 1 device key for u1, 1 device key + 1 puk for u2 (as he is the sender). 801 t.Errorf("number of DH keys found: %d, expected 3", len(fDHKeys)) 802 } 803 fDHKeyset = make(map[keybase1.KID]struct{}) 804 for _, fPUK := range fDHKeys { 805 fDHKeyset[fPUK] = struct{}{} 806 } 807 808 if _, ok := fDHKeyset[u2PUK]; !ok { 809 t.Errorf("expected to find key %v, which was not retrieved", u2PUK) 810 } 811 key, err := u1.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u1.User.GetComputedKeyFamily().GetAllActiveDevices()[0].ID) 812 require.NoError(t, err) 813 KID := key.GetKID() 814 if _, ok := fDHKeyset[KID]; !ok { 815 t.Errorf("expected to find key %v, which was not retrieved", KID) 816 } 817 key, err = u2.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u2.User.GetComputedKeyFamily().GetAllActiveDevices()[0].ID) 818 require.NoError(t, err) 819 KID = key.GetKID() 820 if _, ok := fDHKeyset[KID]; !ok { 821 t.Errorf("expected to find key %v, which was not retrieved", KID) 822 } 823 824 symKeys = eng.GetSymmetricKeys() 825 if len(symKeys) != 1 { 826 t.Errorf("number of symmetric keys found: %d, expected 1", len(symKeys)) 827 } 828 require.True(t, bytes.Equal(teamSaltpackKey.Key[:], symKeys[0].Key[:])) 829 830 } 831 832 func TestSaltpackRecipientKeyfinderTeamWithDeletedUser(t *testing.T) { 833 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 834 defer tc.Cleanup() 835 836 u1, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 837 require.NoError(t, err) 838 u2, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 839 require.NoError(t, err) 840 841 _, teamName := createTeam(tc) 842 _, err = teams.AddMember(context.TODO(), tc.G, teamName, u1.Username, keybase1.TeamRole_WRITER, nil) 843 require.NoError(t, err) 844 845 // u2 is part of the team, keyfinding should succeed. 846 // We look for keys for the team, including the device keys of the members 847 trackUI := &kbtest.FakeIdentifyUI{ 848 Proofs: make(map[string]string), 849 } 850 uis := libkb.UIs{IdentifyUI: trackUI, SecretUI: u2.NewSecretUI()} 851 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 852 arg := libkb.SaltpackRecipientKeyfinderArg{ 853 TeamRecipients: []string{teamName}, 854 UseEntityKeys: true, 855 UseDeviceKeys: true, 856 } 857 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 858 err = engine.RunEngine2(m, eng) 859 require.NoError(t, err) 860 861 fDHKeys := eng.GetPublicKIDs() 862 if len(fDHKeys) != 3 { // 1 device key for u1, 1 device key + 1 puk for u2 (as he is the sender). 863 t.Errorf("number of DH keys found: %d, expected 3", len(fDHKeys)) 864 } 865 fDHKeyset := make(map[keybase1.KID]struct{}) 866 for _, fPUK := range fDHKeys { 867 fDHKeyset[fPUK] = struct{}{} 868 } 869 870 u2PUK := u2.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 871 if _, ok := fDHKeyset[u2PUK]; !ok { 872 t.Errorf("expected to find key %v, which was not retrieved", u2PUK) 873 } 874 875 key, err := u1.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u1.User.GetComputedKeyFamily().GetAllActiveDevices()[0].ID) 876 require.NoError(t, err) 877 KID := key.GetKID() 878 if _, ok := fDHKeyset[KID]; !ok { 879 t.Errorf("expected to find key %v, which was not retrieved", KID) 880 } 881 key, err = u2.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u2.User.GetComputedKeyFamily().GetAllActiveDevices()[0].ID) 882 require.NoError(t, err) 883 KID = key.GetKID() 884 if _, ok := fDHKeyset[KID]; !ok { 885 t.Errorf("expected to find key %v, which was not retrieved", KID) 886 } 887 888 symKeys := eng.GetSymmetricKeys() 889 890 team, err := teams.Load(m.Ctx(), m.G(), keybase1.LoadTeamArg{Name: teamName}) 891 require.NoError(t, err) 892 teamSaltpackKey, err := team.SaltpackEncryptionKeyLatest(m.Ctx()) 893 require.NoError(t, err) 894 895 if len(symKeys) != 1 { 896 t.Errorf("number of symmetric keys found: %d, expected 1", len(symKeys)) 897 } 898 require.True(t, bytes.Equal(teamSaltpackKey.Key[:], symKeys[0].Key[:])) 899 900 // Now we delete user u2, and we check that u1 is still able to find keys for the team (which do not include keys for u2). 901 kbtest.DeleteAccount(tc, u2) 902 903 err = u1.Login(tc.G) 904 require.NoError(t, err) 905 uis = libkb.UIs{IdentifyUI: trackUI, SecretUI: u1.NewSecretUI()} 906 m = libkb.NewMetaContextForTest(tc).WithUIs(uis) 907 arg = libkb.SaltpackRecipientKeyfinderArg{ 908 TeamRecipients: []string{teamName}, 909 UseEntityKeys: true, 910 UseDeviceKeys: true, 911 } 912 eng = NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 913 err = engine.RunEngine2(m, eng) 914 require.NoError(t, err) 915 916 fDHKeys = eng.GetPublicKIDs() 917 if len(fDHKeys) != 2 { // 1 device key + 1 puk for u1 (as he is the sender and the only member of the team). 918 t.Errorf("number of DH keys found: %d, expected 3", len(fDHKeys)) 919 } 920 fDHKeyset = make(map[keybase1.KID]struct{}) 921 for _, fPUK := range fDHKeys { 922 fDHKeyset[fPUK] = struct{}{} 923 } 924 925 u1PUK := u1.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 926 if _, ok := fDHKeyset[u1PUK]; !ok { 927 t.Errorf("expected to find key %v, which was not retrieved", u2PUK) 928 } 929 930 key, err = u1.User.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(u1.User.GetComputedKeyFamily().GetAllActiveDevices()[0].ID) 931 require.NoError(t, err) 932 KID = key.GetKID() 933 if _, ok := fDHKeyset[KID]; !ok { 934 t.Errorf("expected to find key %v, which was not retrieved", KID) 935 } 936 937 symKeys = eng.GetSymmetricKeys() 938 939 if len(symKeys) != 1 { 940 t.Errorf("number of symmetric keys found: %d, expected 1", len(symKeys)) 941 } 942 require.True(t, bytes.Equal(teamSaltpackKey.Key[:], symKeys[0].Key[:])) 943 } 944 945 func TestSaltpackRecipientKeyfinderImplicitTeam(t *testing.T) { 946 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 947 defer tc.Cleanup() 948 949 teams.ServiceInit(tc.G) 950 951 // First, try to get keys for a non existing user assertion without logging in, which should fail 952 b, err := libkb.RandBytes(4) 953 require.NoError(tc.T, err) 954 nonExistingUserAssertion := "u_" + hex.EncodeToString(b) + "@rooter" 955 956 trackUI := &kbtest.FakeIdentifyUI{ 957 Proofs: make(map[string]string), 958 } 959 960 uis := libkb.UIs{IdentifyUI: trackUI} 961 arg := libkb.SaltpackRecipientKeyfinderArg{ 962 Recipients: []string{nonExistingUserAssertion}, 963 UseEntityKeys: true, 964 NoSelfEncrypt: true, 965 } 966 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 967 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 968 err = engine.RunEngine2(m, eng) // Should fail 969 if _, ok := err.(libkb.RecipientNotFoundError); !ok { 970 t.Fatalf("expected error type libkb.RecipientNotFoundError, got %T (%s)", err, err) 971 } 972 973 // Now, retry with a valid user logged in, which should succeed 974 u1, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 975 require.NoError(t, err) 976 err = u1.Login(tc.G) 977 require.NoError(t, err) 978 979 uis = libkb.UIs{IdentifyUI: trackUI, SecretUI: u1.NewSecretUI()} 980 arg = libkb.SaltpackRecipientKeyfinderArg{ 981 Recipients: []string{nonExistingUserAssertion}, 982 UseEntityKeys: true, 983 } 984 eng = NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 985 m = libkb.NewMetaContextForTest(tc).WithUIs(uis) 986 err = engine.RunEngine2(m, eng) 987 require.NoError(t, err) 988 989 fDHKeys := eng.GetPublicKIDs() 990 if len(fDHKeys) != 1 { // This is the sender's own PUK 991 t.Errorf("number of DH keys found: %d, expected 1", len(fDHKeys)) 992 } 993 fDHKeyset := make(map[keybase1.KID]struct{}) 994 for _, fPUK := range fDHKeys { 995 fDHKeyset[fPUK] = struct{}{} 996 } 997 998 u1PUK := u1.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 999 if _, ok := fDHKeyset[u1PUK]; !ok { 1000 t.Errorf("expected to find key %v, which was not retrieved", u1PUK) 1001 } 1002 1003 symKeys := eng.GetSymmetricKeys() 1004 if len(symKeys) != 1 { 1005 t.Errorf("number of symmetric keys found: %d, expected 1", len(symKeys)) 1006 } 1007 1008 team, _, _, err := teams.LookupImplicitTeam(m.Ctx(), m.G(), u1.Username+","+nonExistingUserAssertion, false, teams.ImplicitTeamOptions{}) 1009 require.NoError(t, err) 1010 teamSaltpackKey, err := team.SaltpackEncryptionKeyLatest(m.Ctx()) 1011 require.NoError(t, err) 1012 require.True(t, bytes.Equal(teamSaltpackKey.Key[:], symKeys[0].Key[:])) 1013 } 1014 1015 func TestSaltpackRecipientKeyfinderImplicitTeamNoSelfEncrypt(t *testing.T) { 1016 tc := SetupKeyfinderEngineTest(t, "SaltpackRecipientKeyfinderEngine") 1017 defer tc.Cleanup() 1018 1019 teams.ServiceInit(tc.G) 1020 1021 // First, try to get keys for a non existing user assertion with NoSelfEncrypt, which should fail 1022 u1, err := kbtest.CreateAndSignupFakeUser("spkfe", tc.G) 1023 require.NoError(t, err) 1024 err = u1.Login(tc.G) 1025 require.NoError(t, err) 1026 1027 b, err := libkb.RandBytes(4) 1028 require.NoError(tc.T, err) 1029 nonExistingUserAssertion := "u_" + hex.EncodeToString(b) + "@rooter" 1030 1031 trackUI := &kbtest.FakeIdentifyUI{ 1032 Proofs: make(map[string]string), 1033 } 1034 1035 uis := libkb.UIs{IdentifyUI: trackUI} 1036 arg := libkb.SaltpackRecipientKeyfinderArg{ 1037 Recipients: []string{nonExistingUserAssertion}, 1038 UseEntityKeys: true, 1039 NoSelfEncrypt: true, 1040 } 1041 eng := NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 1042 m := libkb.NewMetaContextForTest(tc).WithUIs(uis) 1043 err = engine.RunEngine2(m, eng) // Should fail 1044 if _, ok := err.(libkb.RecipientNotFoundError); !ok { 1045 t.Fatalf("expected error type libkb.RecipientNotFoundError, got %T (%s)", err, err) 1046 } 1047 1048 // Now, try again without NoSelfEncrypt, which should succeed 1049 arg = libkb.SaltpackRecipientKeyfinderArg{ 1050 Recipients: []string{nonExistingUserAssertion}, 1051 UseEntityKeys: true, 1052 } 1053 eng = NewSaltpackRecipientKeyfinderEngineAsInterface(arg) 1054 m = libkb.NewMetaContextForTest(tc).WithUIs(uis) 1055 err = engine.RunEngine2(m, eng) 1056 require.NoError(t, err) 1057 1058 fDHKeys := eng.GetPublicKIDs() 1059 if len(fDHKeys) != 1 { // This is the sender's own PUK 1060 t.Errorf("number of DH keys found: %d, expected 1", len(fDHKeys)) 1061 } 1062 fDHKeyset := make(map[keybase1.KID]struct{}) 1063 for _, fPUK := range fDHKeys { 1064 fDHKeyset[fPUK] = struct{}{} 1065 } 1066 1067 u1PUK := u1.User.GetComputedKeyFamily().GetLatestPerUserKey().EncKID 1068 if _, ok := fDHKeyset[u1PUK]; !ok { 1069 t.Errorf("expected to find key %v, which was not retrieved", u1PUK) 1070 } 1071 1072 symKeys := eng.GetSymmetricKeys() 1073 if len(symKeys) != 1 { 1074 t.Errorf("number of symmetric keys found: %d, expected 1", len(symKeys)) 1075 } 1076 1077 team, _, _, err := teams.LookupImplicitTeam(m.Ctx(), m.G(), u1.Username+","+nonExistingUserAssertion, false, teams.ImplicitTeamOptions{}) 1078 require.NoError(t, err) 1079 teamSaltpackKey, err := team.SaltpackEncryptionKeyLatest(m.Ctx()) 1080 require.NoError(t, err) 1081 require.True(t, bytes.Equal(teamSaltpackKey.Key[:], symKeys[0].Key[:])) 1082 }