github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/engine/pgp_update_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 "testing" 8 9 "github.com/keybase/client/go/libkb" 10 "github.com/keybase/go-crypto/openpgp" 11 ) 12 13 func doUpdate(fingerprints []string, all bool, fu *FakeUser, tc libkb.TestContext) (err error) { 14 eng := NewPGPUpdateEngine(tc.G, fingerprints, all) 15 uis := libkb.UIs{ 16 LogUI: tc.G.UI.GetLogUI(), 17 SecretUI: fu.NewSecretUI(), 18 } 19 m := NewMetaContextForTest(tc).WithUIs(uis) 20 err = RunEngine2(m, eng) 21 return 22 } 23 24 func getFakeUsersKeyBundleFromServer(tc libkb.TestContext, fu *FakeUser) *libkb.PGPKeyBundle { 25 arg := libkb.NewLoadUserForceArg(tc.G).WithName(fu.Username) 26 user, err := libkb.LoadUser(arg) 27 if err != nil { 28 tc.T.Fatal("Failed loading user", err) 29 } 30 ckf := user.GetComputedKeyFamily() 31 keys := ckf.GetActivePGPKeys(true /* sibkeys */) 32 if len(keys) != 1 { 33 tc.T.Fatal("Expected only one key.") 34 } 35 return keys[0] 36 } 37 38 func getFakeUsersBundlesList(tc libkb.TestContext, fu *FakeUser) []string { 39 arg := libkb.NewLoadUserForceArg(tc.G).WithName(fu.Username) 40 user, err := libkb.LoadUser(arg) 41 if err != nil { 42 tc.T.Fatal("Failed loading user", err) 43 } 44 return user.GetKeyFamily().BundlesForTesting 45 } 46 47 func TestPGPUpdate(t *testing.T) { 48 tc := SetupEngineTest(t, "pgp_update") 49 defer tc.Cleanup() 50 51 // Note that this user's key is not created in the GPG keyring. For the 52 // purposes of this test that's ok. 53 fakeUser := createFakeUserWithPGPSibkey(tc) 54 bundle := getFakeUsersKeyBundleFromServer(tc, fakeUser) 55 if len(bundle.Subkeys) != 1 { 56 t.Fatal("expected exactly 1 subkey") 57 } 58 originalBundlesLen := len(getFakeUsersBundlesList(tc, fakeUser)) 59 60 // Modify the key by deleting the subkey. 61 bundle.Subkeys = []openpgp.Subkey{} 62 63 gpgCLI := libkb.NewGpgCLI(tc.G, tc.G.UI.GetLogUI()) 64 err := gpgCLI.Configure(tc.MetaContext()) 65 if err != nil { 66 t.Fatal("Error initializing GpgCLI", err) 67 } 68 69 // Add the modified key to the gpg keyring 70 if err := gpgCLI.ExportKey(tc.MetaContext(), *bundle, false /* export public key only */, false /* no batch mode */); err != nil { 71 t.Fatal(err) 72 } 73 74 // Now run `client pgp update` with a fingerprint that doesn't match. 75 err = doUpdate([]string{"not_a_real_fingerprint"}, false, fakeUser, tc) 76 if err != nil { 77 t.Fatal("Error in PGPUpdateEngine:", err) 78 } 79 // Get the list of bundles from the server. 80 bundles := getFakeUsersBundlesList(tc, fakeUser) 81 // Check that the key hasn't been modified. 82 if len(bundles) != originalBundlesLen { 83 t.Fatal("Key changes should not have been uploaded.") 84 } 85 86 // Do the same thing without the fingerprint. It should go through this time. 87 err = doUpdate([]string{}, false, fakeUser, tc) 88 if err != nil { 89 t.Fatal("Error in PGPUpdateEngine:", err) 90 } 91 // Load the user from the server again. 92 reloadedBundles := getFakeUsersBundlesList(tc, fakeUser) 93 // Check that the key hasn't been modified. 94 if len(reloadedBundles) != originalBundlesLen+1 { 95 t.Fatal("Key changes should have been uploaded.") 96 } 97 } 98 99 func TestPGPUpdateMultiKey(t *testing.T) { 100 tc := SetupEngineTest(t, "pgp_update") 101 defer tc.Cleanup() 102 103 // Get a user with one PGP sibkey. Note that this user's key is not created 104 // in the GPG keyring. For the purposes of this test that's ok. 105 fu := createFakeUserWithPGPSibkey(tc) 106 107 // Generate a second PGP sibkey. 108 arg := PGPKeyImportEngineArg{ 109 AllowMulti: true, 110 DoExport: true, 111 Gen: &libkb.PGPGenArg{ 112 PrimaryBits: 768, 113 SubkeyBits: 768, 114 }, 115 } 116 err := arg.Gen.MakeAllIds(tc.G) 117 if err != nil { 118 tc.T.Fatal(err) 119 } 120 uis := libkb.UIs{ 121 LogUI: tc.G.UI.GetLogUI(), 122 SecretUI: fu.NewSecretUI(), 123 } 124 eng := NewPGPKeyImportEngine(tc.G, arg) 125 m := NewMetaContextForTest(tc).WithUIs(uis) 126 err = RunEngine2(m, eng) 127 if err != nil { 128 tc.T.Fatal(err) 129 } 130 131 // `client pgp update` should fail by default, because there are multiple keys. 132 err = doUpdate([]string{}, false /* all */, fu, tc) 133 if err == nil { 134 t.Fatal("Update should fail with multiple keys and no --all.") 135 } 136 137 // `client pgp update` should fail with both specific fingerprints and --all. 138 err = doUpdate([]string{"foo"}, true /* all */, fu, tc) 139 if err == nil { 140 t.Fatal("Update should fail with explicit fingerprint and --all.") 141 } 142 143 // It should finally succeed with just --all. 144 err = doUpdate([]string{}, true /* all */, fu, tc) 145 if err != nil { 146 t.Fatal("Update should succeed with --all. Error:", err) 147 } 148 }