github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/passphrase_change_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 4 package engine 5 6 import ( 7 "fmt" 8 "testing" 9 10 "github.com/keybase/client/go/libkb" 11 keybase1 "github.com/keybase/client/go/protocol/keybase1" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func withNewProvisionalLoginForFakeUser(m libkb.MetaContext, u *FakeUser) libkb.MetaContext { 16 m = m.WithNewProvisionalLoginContextForUserVersionAndUsername(u.UserVersion(), libkb.NewNormalizedUsername(u.Username)) 17 return m 18 } 19 20 func tryPassphrase(tc libkb.TestContext, u *FakeUser, pp string) error { 21 m := NewMetaContextForTest(tc) 22 m = withNewProvisionalLoginForFakeUser(m, u) 23 _, err := libkb.VerifyPassphraseGetStreamInLoginContext(m, pp) 24 return err 25 } 26 27 func verifyPassphraseChange(tc libkb.TestContext, u *FakeUser, newPassphrase string) { 28 err := tryPassphrase(tc, u, newPassphrase) 29 require.NoError(tc.T, err, "verified new passphrase works") 30 err = tryPassphrase(tc, u, u.Passphrase) 31 require.Error(tc.T, err, "verified old passphrase fails") 32 if testing.Verbose() { 33 fmt.Printf("browser test -- username: %s password: %s\n", u.Username, newPassphrase) 34 } 35 } 36 37 func assertLoadSecretKeys(tc libkb.TestContext, u *FakeUser, msg string) { 38 tc.G.Log.Debug("In assertLoadSecretKeys") 39 40 me, err := libkb.LoadMe(libkb.NewLoadUserArg(tc.G)) 41 if err != nil { 42 tc.T.Fatalf("%s: %s", msg, err) 43 } 44 if me == nil { 45 tc.T.Fatalf("%s: nil LoadMe result", msg) 46 } 47 skarg := libkb.SecretKeyArg{ 48 Me: me, 49 KeyType: libkb.DeviceSigningKeyType, 50 } 51 parg := libkb.SecretKeyPromptArg{ 52 Ska: skarg, 53 SecretUI: u.NewSecretUI(), 54 Reason: "testing sig", 55 } 56 m := NewMetaContextForTest(tc) 57 m = withNewProvisionalLoginForFakeUser(m, u) 58 59 tc.G.Log.Debug("doing a silent passphrase login for session token") 60 err = libkb.PassphraseLoginNoPrompt(m, u.Username, u.Passphrase) 61 require.NoError(tc.T, err) 62 63 tc.G.Log.Debug("Calling GetSecretKeyWithPrompt (for signing)") 64 sigKey, err := tc.G.Keyrings.GetSecretKeyWithPrompt(m, parg) 65 if err != nil { 66 tc.T.Fatalf("%s: %s", msg, err) 67 } 68 if sigKey == nil { 69 tc.T.Fatalf("%s: got nil signing key", msg) 70 } 71 72 parg.Ska.KeyType = libkb.DeviceEncryptionKeyType 73 tc.G.Log.Debug("Calling GetSecretKeyWithPrompt (for encryption)") 74 encKey, err := tc.G.Keyrings.GetSecretKeyWithPrompt(m, parg) 75 if err != nil { 76 tc.T.Fatalf("%s: %s", msg, err) 77 } 78 if encKey == nil { 79 tc.T.Fatalf("%s: got nil encryption key", msg) 80 } 81 } 82 83 func assertLoadPGPKeys(tc libkb.TestContext, u *FakeUser) { 84 me, err := libkb.LoadMe(libkb.NewLoadUserArg(tc.G)) 85 if err != nil { 86 tc.T.Fatal(err) 87 } 88 89 ska := libkb.SecretKeyArg{ 90 Me: me, 91 KeyType: libkb.PGPKeyType, 92 } 93 parg := libkb.SecretKeyPromptArg{ 94 Ska: ska, 95 SecretUI: u.NewSecretUI(), 96 Reason: "pgp test", 97 } 98 m := NewMetaContextForTest(tc) 99 key, err := tc.G.Keyrings.GetSecretKeyWithPrompt(m, parg) 100 if err != nil { 101 tc.T.Fatal(err) 102 } 103 104 var ok bool 105 _, ok = key.(*libkb.PGPKeyBundle) 106 if !ok { 107 tc.T.Errorf("key type: %T, expected libkb.PGPKeyBundle", key) 108 } 109 } 110 111 // Test changing the passphrase when user knows current 112 // passphrase. 113 func TestPassphraseChangeKnown(t *testing.T) { 114 tc := SetupEngineTest(t, "PassphraseChange") 115 defer tc.Cleanup() 116 117 u := CreateAndSignupFakeUser(tc, "login") 118 newPassphrase := "password1234" 119 arg := &keybase1.PassphraseChangeArg{ 120 OldPassphrase: u.Passphrase, 121 Passphrase: newPassphrase, 122 } 123 124 // using an empty secret ui to make sure existing pp doesn't come from ui prompt: 125 uis := libkb.UIs{ 126 SecretUI: &libkb.TestSecretUI{}, 127 } 128 eng := NewPassphraseChange(tc.G, arg) 129 m := NewMetaContextForTest(tc).WithUIs(uis) 130 if err := RunEngine2(m, eng); err != nil { 131 t.Fatal(err) 132 } 133 134 verifyPassphraseChange(tc, u, newPassphrase) 135 136 u.Passphrase = newPassphrase 137 assertLoadSecretKeys(tc, u, "passphrase change known") 138 } 139 140 // Test error when trying to change passphrase to shorter than 6 141 // chars long. 142 func TestPassphraseChangeShort(t *testing.T) { 143 tc := SetupEngineTest(t, "PassphraseChange") 144 defer tc.Cleanup() 145 146 u := CreateAndSignupFakeUser(tc, "login") 147 newPassphrase := "pass" 148 arg := &keybase1.PassphraseChangeArg{ 149 OldPassphrase: u.Passphrase, 150 Passphrase: newPassphrase, 151 } 152 uis := libkb.UIs{ 153 SecretUI: &libkb.TestSecretUI{}, 154 } 155 eng := NewPassphraseChange(tc.G, arg) 156 m := NewMetaContextForTest(tc).WithUIs(uis) 157 err := RunEngine2(m, eng) 158 if err == nil { 159 t.Fatal("expected error with new short passphrase") 160 } 161 if _, ok := err.(libkb.PassphraseError); !ok { 162 t.Fatalf("expected libkb.PassphraseError, got %T", err) 163 } 164 } 165 166 // Test changing the passphrase when user knows current 167 // passphrase, prompt for it. 168 func TestPassphraseChangeKnownPrompt(t *testing.T) { 169 tc := SetupEngineTest(t, "PassphraseChange") 170 defer tc.Cleanup() 171 172 u := CreateAndSignupFakeUser(tc, "login") 173 174 // clear the passphrase stream cache to force a prompt 175 // for the existing passphrase. 176 clearCaches(tc.G) 177 178 // Test changing passphrase 3 times; so that old passphrase 179 // cache is properly busted. 180 newPassphrase := "password1234" 181 numChanges := 3 182 for i := 0; i < numChanges; i++ { 183 184 arg := &keybase1.PassphraseChangeArg{ 185 Passphrase: newPassphrase, 186 } 187 secui := u.NewSecretUI() 188 uis := libkb.UIs{ 189 SecretUI: secui, 190 } 191 eng := NewPassphraseChange(tc.G, arg) 192 m := NewMetaContextForTest(tc).WithUIs(uis) 193 if err := RunEngine2(m, eng); err != nil { 194 t.Fatal(err) 195 } 196 197 // We only call this the last time through, since internally, 198 // verifyPassphraseChange calls ClearStreamCache(), which is 199 // the bug fix that we're actually trying to test by doing multiple 200 // passphrase changes. 201 if i == numChanges-1 { 202 verifyPassphraseChange(tc, u, newPassphrase) 203 } 204 205 if !secui.CalledGetPassphrase { 206 t.Errorf("get passphrase not called") 207 } 208 209 u.Passphrase = newPassphrase 210 assertLoadSecretKeys(tc, u, "passphrase change known prompt") 211 newPassphrase += "-xo" 212 } 213 } 214 215 // Test changing the passphrase when user knows current 216 // passphrase, prompt for it. 217 func TestPassphraseChangeKnownPromptRepeatOld(t *testing.T) { 218 tc := SetupEngineTest(t, "PassphraseChange") 219 defer tc.Cleanup() 220 221 u := CreateAndSignupFakeUser(tc, "login") 222 m := NewMetaContextForTest(tc) 223 224 // clear the passphrase stream cache to force a prompt 225 // for the existing passphrase. 226 m.ActiveDevice().ClearCaches() 227 228 // Test changing passphrase 3 times; so that old passphrase 229 // cache is properly busted. 230 newPassphrase := "password1234" 231 numChanges := 3 232 for i := 0; i < numChanges; i++ { 233 234 arg := &keybase1.PassphraseChangeArg{ 235 Passphrase: newPassphrase, 236 } 237 secui := u.NewSecretUI() 238 uis := libkb.UIs{ 239 SecretUI: secui, 240 } 241 eng := NewPassphraseChange(tc.G, arg) 242 m = m.WithUIs(uis) 243 if err := RunEngine2(m, eng); err != nil { 244 t.Fatal(err) 245 } 246 247 // We only call this the last time through, since internally, 248 // verifyPassphraseChange calls ClearStreamCache(), which is 249 // the bug fix that we're actually trying to test by doing multiple 250 // passphrase changes. 251 if i == numChanges-1 { 252 m := NewMetaContextForTest(tc) 253 _, err := libkb.VerifyPassphraseForLoggedInUser(m, newPassphrase) 254 if err != nil { 255 t.Fatal(err) 256 } 257 } 258 259 if !secui.CalledGetPassphrase { 260 t.Errorf("get passphrase not called") 261 } 262 263 u.Passphrase = newPassphrase 264 assertLoadSecretKeys(tc, u, "passphrase change known prompt") 265 } 266 } 267 268 // Test changing the passphrase after logging in via pubkey. 269 func TestPassphraseChangeAfterPubkeyLogin(t *testing.T) { 270 tc := SetupEngineTest(t, "PassphraseChange") 271 defer tc.Cleanup() 272 273 u := CreateAndSignupFakeUser(tc, "login") 274 275 // this should do a pubkey login 276 Logout(tc) 277 278 secui := u.NewSecretUI() 279 if err := u.LoginWithSecretUI(secui, tc.G); err != nil { 280 t.Fatal(err) 281 } 282 if !secui.CalledGetPassphrase { 283 t.Errorf("get keybase passphrase not called") 284 } 285 286 newPassphrase := "password1234" 287 arg := &keybase1.PassphraseChangeArg{ 288 Passphrase: newPassphrase, 289 } 290 uis := libkb.UIs{ 291 SecretUI: secui, 292 } 293 eng := NewPassphraseChange(tc.G, arg) 294 m := NewMetaContextForTest(tc).WithUIs(uis) 295 if err := RunEngine2(m, eng); err != nil { 296 t.Fatal(err) 297 } 298 299 verifyPassphraseChange(tc, u, newPassphrase) 300 301 u.Passphrase = newPassphrase 302 assertLoadSecretKeys(tc, u, "passphrase change after pubkey login") 303 } 304 305 // Test changing the passphrase when previous pp stream available. 306 func TestPassphraseChangeKnownNotSupplied(t *testing.T) { 307 tc := SetupEngineTest(t, "PassphraseChange") 308 defer tc.Cleanup() 309 310 u := CreateAndSignupFakeUser(tc, "login") 311 newPassphrase := "password1234" 312 arg := &keybase1.PassphraseChangeArg{ 313 Passphrase: newPassphrase, 314 } 315 secui := &libkb.TestSecretUI{} 316 uis := libkb.UIs{ 317 SecretUI: secui, 318 } 319 eng := NewPassphraseChange(tc.G, arg) 320 m := NewMetaContextForTest(tc).WithUIs(uis) 321 if err := RunEngine2(m, eng); err != nil { 322 t.Fatal(err) 323 } 324 325 verifyPassphraseChange(tc, u, newPassphrase) 326 327 if secui.CalledGetPassphrase { 328 t.Errorf("get kb passphrase called") 329 } 330 331 u.Passphrase = newPassphrase 332 assertLoadSecretKeys(tc, u, "passphrase change known, not supplied") 333 } 334 335 // Test changing the passphrase when user forgets current 336 // passphrase. 337 func TestPassphraseChangeUnknown(t *testing.T) { 338 tc := SetupEngineTest(t, "PassphraseChange") 339 defer tc.Cleanup() 340 341 u := CreateAndSignupFakeUser(tc, "login") 342 343 // this has a flaw: the passphrase stream cache is available. 344 // it is being used to unlock the secret key to generate the 345 // change passphrase proof. 346 // 347 348 newPassphrase := "password1234" 349 arg := &keybase1.PassphraseChangeArg{ 350 Passphrase: newPassphrase, 351 Force: true, 352 } 353 uis := libkb.UIs{ 354 SecretUI: &libkb.TestSecretUI{}, 355 } 356 eng := NewPassphraseChange(tc.G, arg) 357 m := NewMetaContextForTest(tc).WithUIs(uis) 358 if err := RunEngine2(m, eng); err != nil { 359 t.Fatal(err) 360 } 361 362 verifyPassphraseChange(tc, u, newPassphrase) 363 364 u.Passphrase = newPassphrase 365 assertLoadSecretKeys(tc, u, "passphrase change unknown") 366 } 367 368 // Test changing the passphrase when user forgets current 369 // passphrase and there's no passphrase stream cache. 370 // No backup key available. 371 func TestPassphraseChangeUnknownNoPSCache(t *testing.T) { 372 tc := SetupEngineTest(t, "PassphraseChange") 373 defer tc.Cleanup() 374 375 f := func(arg *SignupEngineRunArg) { 376 arg.SkipPaper = true 377 } 378 379 u, _, _ := CreateAndSignupFakeUserCustomArg(tc, "paper", f) 380 381 tc.SimulateServiceRestart() 382 383 newPassphrase := "password1234" 384 arg := &keybase1.PassphraseChangeArg{ 385 Passphrase: newPassphrase, 386 Force: true, 387 } 388 uis := libkb.UIs{ 389 SecretUI: &libkb.TestSecretUI{}, 390 } 391 eng := NewPassphraseChange(tc.G, arg) 392 m := NewMetaContextForTest(tc).WithUIs(uis) 393 err := RunEngine2(m, eng) 394 if err == nil { 395 t.Fatal("passphrase change should have failed") 396 } 397 if _, ok := err.(libkb.NoPaperKeysError); !ok { 398 t.Fatalf("unexpected error: %s (%T)", err, err) 399 } 400 401 assertLoadSecretKeys(tc, u, "passphrase change unknown, no ps cache") 402 } 403 404 // Test changing the passphrase when user forgets current 405 // passphrase and there's no passphrase stream cache. 406 // Backup key exists 407 func TestPassphraseChangeUnknownBackupKey(t *testing.T) { 408 tc := SetupEngineTest(t, "PassphraseChange") 409 defer tc.Cleanup() 410 411 u := CreateAndSignupFakeUser(tc, "login") 412 413 uis := libkb.UIs{ 414 LogUI: tc.G.UI.GetLogUI(), 415 LoginUI: &libkb.TestLoginUI{}, 416 SecretUI: &libkb.TestSecretUI{}, 417 } 418 beng := NewPaperKey(tc.G) 419 m := NewMetaContextForTest(tc).WithUIs(uis) 420 if err := RunEngine2(m, beng); err != nil { 421 t.Fatal(err) 422 } 423 backupPassphrase := beng.Passphrase() 424 m = m.WithSecretUI(&libkb.TestSecretUI{Passphrase: backupPassphrase}) 425 426 m.ActiveDevice().ClearCaches() 427 428 newPassphrase := "password1234" 429 arg := &keybase1.PassphraseChangeArg{ 430 Passphrase: newPassphrase, 431 Force: true, 432 } 433 eng := NewPassphraseChange(tc.G, arg) 434 if err := RunEngine2(m, eng); err != nil { 435 t.Fatal(err) 436 } 437 438 verifyPassphraseChange(tc, u, newPassphrase) 439 440 u.Passphrase = newPassphrase 441 assertLoadSecretKeys(tc, u, "passphrase change unknown, backup key") 442 } 443 444 // Test changing the passphrase when user forgets current 445 // passphrase and is logged out, but has a backup key. 446 func TestPassphraseChangeLoggedOutBackupKey(t *testing.T) { 447 tc := SetupEngineTest(t, "PassphraseChange") 448 defer tc.Cleanup() 449 450 u := CreateAndSignupFakeUser(tc, "login") 451 452 assertLoadSecretKeys(tc, u, "logged out w/ backup key, before passphrase change") 453 454 uis := libkb.UIs{ 455 LogUI: tc.G.UI.GetLogUI(), 456 LoginUI: &libkb.TestLoginUI{}, 457 SecretUI: &libkb.TestSecretUI{}, 458 } 459 beng := NewPaperKey(tc.G) 460 m := NewMetaContextForTest(tc).WithUIs(uis) 461 if err := RunEngine2(m, beng); err != nil { 462 t.Fatal(err) 463 } 464 backupPassphrase := beng.Passphrase() 465 m = m.WithSecretUI(&libkb.TestSecretUI{Passphrase: backupPassphrase}) 466 467 Logout(tc) 468 469 newPassphrase := "password1234" 470 arg := &keybase1.PassphraseChangeArg{ 471 Passphrase: newPassphrase, 472 Force: true, 473 } 474 eng := NewPassphraseChange(tc.G, arg) 475 if err := RunEngine2(m, eng); err != nil { 476 t.Fatal(err) 477 } 478 479 verifyPassphraseChange(tc, u, newPassphrase) 480 481 u.Passphrase = newPassphrase 482 assertLoadSecretKeys(tc, u, "logged out w/ backup key, after passphrase change") 483 } 484 485 // Test changing the passphrase when user forgets current passphrase 486 // and is logged out, but has a backup key (generated by a secret from 487 // the secret store). 488 func TestPassphraseChangeLoggedOutBackupKeySecretStore(t *testing.T) { 489 490 tc := SetupEngineTest(t, "PassphraseChange") 491 defer tc.Cleanup() 492 493 u := NewFakeUserOrBust(tc.T, "login") 494 signupArg := MakeTestSignupEngineRunArg(u) 495 signupArg.StoreSecret = true 496 _ = SignupFakeUserWithArg(tc, u, signupArg) 497 498 // This needs to happen *before* resetting the login state, as 499 // this call will cause the login state to be reloaded. 500 assertLoadSecretKeys(tc, u, "logged out w/ backup key, before passphrase change") 501 502 tc.SimulateServiceRestart() 503 504 secretUI := libkb.TestSecretUI{} 505 uis := libkb.UIs{ 506 LogUI: tc.G.UI.GetLogUI(), 507 LoginUI: &libkb.TestLoginUI{}, 508 SecretUI: &secretUI, 509 } 510 beng := NewPaperKey(tc.G) 511 m := NewMetaContextForTest(tc).WithUIs(uis) 512 if err := RunEngine2(m, beng); err != nil { 513 t.Fatal(err) 514 } 515 516 if secretUI.CalledGetPassphrase { 517 t.Fatal("GetPassphrase() unexpectedly called") 518 } 519 520 backupPassphrase := beng.Passphrase() 521 m = m.WithSecretUI(&libkb.TestSecretUI{Passphrase: backupPassphrase}) 522 523 Logout(tc) 524 525 newPassphrase := "password1234" 526 arg := &keybase1.PassphraseChangeArg{ 527 Passphrase: newPassphrase, 528 Force: true, 529 } 530 eng := NewPassphraseChange(tc.G, arg) 531 if err := RunEngine2(m, eng); err != nil { 532 t.Fatal(err) 533 } 534 535 verifyPassphraseChange(tc, u, newPassphrase) 536 537 u.Passphrase = newPassphrase 538 assertLoadSecretKeys(tc, u, "logged out w/ backup key, after passphrase change") 539 } 540 541 // Test using an lksec-encrypted pgp private key after changing the 542 // passphrase. 543 func TestPassphraseChangePGPUsage(t *testing.T) { 544 tc := SetupEngineTest(t, "PassphraseChange") 545 defer tc.Cleanup() 546 547 u := createFakeUserWithPGPSibkey(tc) 548 549 // clear the passphrase stream cache to force a prompt 550 // for the existing passphrase. 551 clearCaches(tc.G) 552 553 newPassphrase := "password1234" 554 arg := &keybase1.PassphraseChangeArg{ 555 Passphrase: newPassphrase, 556 } 557 secui := u.NewSecretUI() 558 uis := libkb.UIs{ 559 SecretUI: secui, 560 } 561 eng := NewPassphraseChange(tc.G, arg) 562 m := NewMetaContextForTest(tc).WithUIs(uis) 563 if err := RunEngine2(m, eng); err != nil { 564 t.Fatal(err) 565 } 566 567 verifyPassphraseChange(tc, u, newPassphrase) 568 569 if !secui.CalledGetPassphrase { 570 t.Errorf("get kb passphrase not called") 571 } 572 573 u.Passphrase = newPassphrase 574 assertLoadSecretKeys(tc, u, "passphrase change pgp") 575 assertLoadPGPKeys(tc, u) 576 } 577 578 // Test using a 3sec-encrypted pgp private key after changing the 579 // passphrase. 580 func TestPassphraseChangePGP3Sec(t *testing.T) { 581 tc := SetupEngineTest(t, "PassphraseChange") 582 defer tc.Cleanup() 583 584 u := createFakeUserWithPGPSibkeyPushed(tc) 585 586 // clear the passphrase stream cache to force a prompt 587 // for the existing passphrase. 588 clearCaches(tc.G) 589 590 newPassphrase := "password1234" 591 arg := &keybase1.PassphraseChangeArg{ 592 Passphrase: newPassphrase, 593 } 594 secui := u.NewSecretUI() 595 uis := libkb.UIs{ 596 SecretUI: secui, 597 } 598 eng := NewPassphraseChange(tc.G, arg) 599 m := NewMetaContextForTest(tc).WithUIs(uis) 600 if err := RunEngine2(m, eng); err != nil { 601 t.Fatal(err) 602 } 603 604 verifyPassphraseChange(tc, u, newPassphrase) 605 606 if !secui.CalledGetPassphrase { 607 t.Errorf("get kb passphrase not called") 608 } 609 610 u.Passphrase = newPassphrase 611 assertLoadSecretKeys(tc, u, "passphrase change pgp") 612 assertLoadPGPKeys(tc, u) 613 } 614 615 // Test changing the passphrase when user forgets current 616 // passphrase and is logged out, but has a backup key. 617 // Also, this user has a 3sec-encrypted private pgp key 618 // that will be unusable after changing passphrase. 619 func TestPassphraseChangeLoggedOutBackupKeyPlusPGP(t *testing.T) { 620 tc := SetupEngineTest(t, "PassphraseChange") 621 defer tc.Cleanup() 622 623 u := createFakeUserWithPGPSibkeyPushed(tc) 624 625 assertLoadSecretKeys(tc, u, "logged out w/ backup key, before passphrase change") 626 627 uis := libkb.UIs{ 628 LogUI: tc.G.UI.GetLogUI(), 629 LoginUI: &libkb.TestLoginUI{}, 630 SecretUI: &libkb.TestSecretUI{}, 631 } 632 beng := NewPaperKey(tc.G) 633 m := NewMetaContextForTest(tc).WithUIs(uis) 634 if err := RunEngine2(m, beng); err != nil { 635 t.Fatal(err) 636 } 637 backupPassphrase := beng.Passphrase() 638 m = m.WithSecretUI(&libkb.TestSecretUI{Passphrase: backupPassphrase}) 639 Logout(tc) 640 641 newPassphrase := "password1234" 642 arg := &keybase1.PassphraseChangeArg{ 643 Passphrase: newPassphrase, 644 Force: true, 645 } 646 eng := NewPassphraseChange(tc.G, arg) 647 if err := RunEngine2(m, eng); err != nil { 648 t.Fatal(err) 649 } 650 651 verifyPassphraseChange(tc, u, newPassphrase) 652 653 u.Passphrase = newPassphrase 654 assertLoadSecretKeys(tc, u, "logged out w/ backup key, after passphrase change") 655 } 656 657 // Test changing the passphrase when user forgets current passphrase 658 // and is logged out, but has a backup key (generated by a secret from 659 // the secret store). And test using an lksec pgp key after the change. 660 func TestPassphraseChangeLoggedOutBackupKeySecretStorePGP(t *testing.T) { 661 662 tc := SetupEngineTest(t, "PassphraseChange") 663 defer tc.Cleanup() 664 665 u := NewFakeUserOrBust(tc.T, "login") 666 signupArg := MakeTestSignupEngineRunArg(u) 667 signupArg.StoreSecret = true 668 _ = SignupFakeUserWithArg(tc, u, signupArg) 669 670 // add a pgp sibkey, pushed to server and stored locally (lksec) 671 arg := PGPKeyImportEngineArg{ 672 Gen: &libkb.PGPGenArg{ 673 PrimaryBits: 768, 674 SubkeyBits: 768, 675 }, 676 PushSecret: true, 677 } 678 err := arg.Gen.MakeAllIds(tc.G) 679 require.NoError(t, err) 680 uis := libkb.UIs{ 681 LogUI: tc.G.UI.GetLogUI(), 682 SecretUI: u.NewSecretUI(), 683 } 684 eng := NewPGPKeyImportEngine(tc.G, arg) 685 m := NewMetaContextForTest(tc).WithUIs(uis) 686 err = RunEngine2(m, eng) 687 if err != nil { 688 tc.T.Fatal(err) 689 } 690 691 // This needs to happen *before* resetting the login state, as 692 // this call will cause the login state to be reloaded. 693 assertLoadSecretKeys(tc, u, "logged out w/ backup key, before passphrase change") 694 695 tc.SimulateServiceRestart() 696 697 secretUI := libkb.TestSecretUI{} 698 uis = libkb.UIs{ 699 LogUI: tc.G.UI.GetLogUI(), 700 LoginUI: &libkb.TestLoginUI{}, 701 SecretUI: &secretUI, 702 } 703 beng := NewPaperKey(tc.G) 704 m = NewMetaContextForTest(tc).WithUIs(uis) 705 if err := RunEngine2(m, beng); err != nil { 706 t.Fatal(err) 707 } 708 709 if secretUI.CalledGetPassphrase { 710 t.Fatal("GetPassphrase() unexpectedly called") 711 } 712 713 backupPassphrase := beng.Passphrase() 714 m = m.WithSecretUI(&libkb.TestSecretUI{Passphrase: backupPassphrase}) 715 716 Logout(tc) 717 718 newPassphrase := "password1234" 719 pcarg := &keybase1.PassphraseChangeArg{ 720 Passphrase: newPassphrase, 721 Force: true, 722 } 723 pceng := NewPassphraseChange(tc.G, pcarg) 724 if err := RunEngine2(m, pceng); err != nil { 725 t.Fatal(err) 726 } 727 728 verifyPassphraseChange(tc, u, newPassphrase) 729 730 u.Passphrase = newPassphrase 731 assertLoadSecretKeys(tc, u, "logged out w/ backup key, after passphrase change") 732 assertLoadPGPKeys(tc, u) 733 } 734 735 // test pp change when user has multiple 3sec encrypted pgp keys. 736 func TestPassphraseChangePGP3SecMultiple(t *testing.T) { 737 tc := SetupEngineTest(t, "PassphraseChange") 738 defer tc.Cleanup() 739 740 u := createFakeUserWithPGPSibkeyPushed(tc) 741 742 // create/push another pgp key 743 parg := PGPKeyImportEngineArg{ 744 Gen: &libkb.PGPGenArg{ 745 PrimaryBits: 768, 746 SubkeyBits: 768, 747 }, 748 PushSecret: true, 749 NoSave: true, 750 AllowMulti: true, 751 } 752 err := parg.Gen.MakeAllIds(tc.G) 753 require.NoError(t, err) 754 uis := libkb.UIs{ 755 LogUI: tc.G.UI.GetLogUI(), 756 SecretUI: u.NewSecretUI(), 757 } 758 peng := NewPGPKeyImportEngine(tc.G, parg) 759 m := NewMetaContextForTest(tc).WithUIs(uis) 760 err = RunEngine2(m, peng) 761 if err != nil { 762 t.Fatal(err) 763 } 764 765 // clear the passphrase stream cache to force a prompt 766 // for the existing passphrase. 767 clearCaches(tc.G) 768 769 newPassphrase := "password1234" 770 arg := &keybase1.PassphraseChangeArg{ 771 Passphrase: newPassphrase, 772 } 773 secui := u.NewSecretUI() 774 uis = libkb.UIs{ 775 SecretUI: secui, 776 } 777 eng := NewPassphraseChange(tc.G, arg) 778 m = NewMetaContextForTest(tc).WithUIs(uis) 779 if err := RunEngine2(m, eng); err != nil { 780 t.Fatal(err) 781 } 782 783 verifyPassphraseChange(tc, u, newPassphrase) 784 785 if !secui.CalledGetPassphrase { 786 t.Errorf("get kb passphrase not called") 787 } 788 789 u.Passphrase = newPassphrase 790 assertLoadSecretKeys(tc, u, "passphrase change pgp") 791 assertLoadPGPKeys(tc, u) 792 793 me, err := libkb.LoadMe(libkb.NewLoadUserForceArg(tc.G)) 794 if err != nil { 795 t.Fatal(err) 796 } 797 syncKeys, err := me.AllSyncedSecretKeys(m) 798 if err != nil { 799 t.Fatal(err) 800 } 801 if len(syncKeys) != 2 { 802 t.Errorf("num pgp sync keys: %d, expected 2", len(syncKeys)) 803 } 804 for _, key := range syncKeys { 805 parg := libkb.SecretKeyPromptArg{ 806 SecretUI: u.NewSecretUI(), 807 } 808 unlocked, err := key.PromptAndUnlock(m, parg, nil, me) 809 if err != nil { 810 t.Fatal(err) 811 } 812 if unlocked == nil { 813 t.Fatal("failed to unlock key") 814 } 815 } 816 } 817 818 // Make sure passphrase generations are stored properly alongside encrypted keys. 819 // We'll create a user, check the ppgens of the initial pair of keys, change the 820 // passphrase, create a new key, and then they the ppgen of that new one (which 821 // should be higher). 822 func TestPassphraseGenerationStored(t *testing.T) { 823 tc := SetupEngineTest(t, "PassphraseChange") 824 defer tc.Cleanup() 825 826 u := CreateAndSignupFakeUser(tc, "login") 827 mctx := tc.MetaContext() 828 829 // All of the keys initially created with the user should be stored as 830 // passphrase generation 1. 831 skbKeyringFile, err := libkb.LoadSKBKeyring(mctx, u.NormalizedUsername()) 832 if err != nil { 833 t.Fatal(err) 834 } 835 initialGenerationOneCount := 0 836 for _, block := range skbKeyringFile.Blocks { 837 if block.Priv.PassphraseGeneration != 1 { 838 t.Fatalf("Expected all encrypted keys to be ppgen 1. Found %d.", 839 block.Priv.PassphraseGeneration) 840 } 841 initialGenerationOneCount++ 842 } 843 844 // 845 // Do a passphrase change. 846 // 847 newPassphrase := "password1234" 848 arg := &keybase1.PassphraseChangeArg{ 849 OldPassphrase: u.Passphrase, 850 Passphrase: newPassphrase, 851 } 852 uis := libkb.UIs{ 853 LogUI: tc.G.UI.GetLogUI(), 854 SecretUI: u.NewSecretUI(), 855 } 856 eng := NewPassphraseChange(tc.G, arg) 857 m := NewMetaContextForTest(tc).WithUIs(uis) 858 if err := RunEngine2(m, eng); err != nil { 859 t.Fatal(err) 860 } 861 u.Passphrase = newPassphrase 862 863 // 864 // Now, generate a new key. This one should be stored with ppgen 2. 865 // 866 pgpArg := PGPKeyImportEngineArg{ 867 Gen: &libkb.PGPGenArg{ 868 PrimaryBits: 768, 869 SubkeyBits: 768, 870 }, 871 } 872 err = pgpArg.Gen.MakeAllIds(tc.G) 873 require.NoError(t, err) 874 pgpEng := NewPGPKeyImportEngine(tc.G, pgpArg) 875 uis = libkb.UIs{ 876 LogUI: tc.G.UI.GetLogUI(), 877 SecretUI: u.NewSecretUI(), 878 } 879 m = NewMetaContextForTest(tc).WithUIs(uis) 880 err = RunEngine2(m, pgpEng) 881 if err != nil { 882 t.Fatal(err) 883 } 884 885 // 886 // Finally, check that the new key (and only the new key) is marked as ppgen 2. 887 // 888 finalSKBKeyringFile, err := libkb.LoadSKBKeyring(mctx, u.NormalizedUsername()) 889 if err != nil { 890 t.Fatal(err) 891 } 892 finalGenOneCount := 0 893 finalGenTwoCount := 0 894 for _, block := range finalSKBKeyringFile.Blocks { 895 if block.Priv.PassphraseGeneration == 1 { 896 finalGenOneCount++ 897 } else if block.Priv.PassphraseGeneration == 2 { 898 finalGenTwoCount++ 899 } else { 900 t.Fatalf("Expected all encrypted keys to be ppgen 1 or 2. Found %d.", 901 block.Priv.PassphraseGeneration) 902 } 903 } 904 if finalGenOneCount != initialGenerationOneCount { 905 t.Fatalf("Expected initial count of ppgen 1 keys (%d) to equal final count (%d).", 906 initialGenerationOneCount, finalGenOneCount) 907 } 908 if finalGenTwoCount != 1 { 909 t.Fatalf("Expected one key in ppgen 2. Found %d keys.", finalGenTwoCount) 910 } 911 }