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  }