github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/paperkey_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 keybase1 "github.com/keybase/client/go/protocol/keybase1" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func paperDevs(tc libkb.TestContext, fu *FakeUser) (*libkb.User, []*libkb.Device) { 15 arg := libkb.NewLoadUserForceArg(tc.G).WithName(fu.Username) 16 u, err := libkb.LoadUser(arg) 17 require.NoError(tc.T, err) 18 cki := u.GetComputedKeyInfos() 19 require.NotNil(tc.T, cki) 20 return u, cki.PaperDevices() 21 } 22 23 func hasZeroPaperDev(tc libkb.TestContext, fu *FakeUser) { 24 _, bdevs := paperDevs(tc, fu) 25 require.Equal(tc.T, 0, len(bdevs), "num backup devices") 26 } 27 28 func hasOnePaperDev(tc libkb.TestContext, fu *FakeUser) keybase1.DeviceID { 29 u, bdevs := paperDevs(tc, fu) 30 31 require.Equal(tc.T, 1, len(bdevs), "num backup devices") 32 33 devid := bdevs[0].ID 34 sibkey, err := u.GetComputedKeyFamily().GetSibkeyForDevice(devid) 35 require.NoError(tc.T, err) 36 require.NotNil(tc.T, sibkey) 37 38 enckey, err := u.GetComputedKeyFamily().GetEncryptionSubkeyForDevice(devid) 39 require.NoError(tc.T, err) 40 require.NotNil(tc.T, enckey) 41 42 return devid 43 } 44 45 func TestPaperKey(t *testing.T) { 46 tc := SetupEngineTest(t, "backup") 47 defer tc.Cleanup() 48 49 f := func(arg *SignupEngineRunArg) { 50 arg.SkipPaper = true 51 } 52 53 fu, _, _ := CreateAndSignupFakeUserCustomArg(tc, "login", f) 54 55 userDeviceID := tc.G.Env.GetDeviceID() 56 57 uis := libkb.UIs{ 58 LogUI: tc.G.UI.GetLogUI(), 59 LoginUI: &libkb.TestLoginUI{}, 60 SecretUI: &libkb.TestSecretUI{}, 61 } 62 eng := NewPaperKey(tc.G) 63 m := NewMetaContextForTest(tc).WithUIs(uis) 64 err := RunEngine2(m, eng) 65 require.NoError(t, err) 66 require.NotZero(t, len(eng.Passphrase())) 67 Logout(tc) 68 69 // check for the backup key 70 devid := hasOnePaperDev(tc, fu) 71 72 // ok, just log in again: 73 err = fu.Login(tc.G) 74 require.NoError(t, err) 75 Logout(tc) 76 77 // make sure the passphrase authentication didn't change: 78 m = m.WithNewProvisionalLoginContext() 79 err = libkb.PassphraseLoginNoPrompt(m, fu.Username, fu.Passphrase) 80 require.NoError(t, err, "passphrase login still worked") 81 m.CommitProvisionalLogin() 82 83 // make sure the backup key device id is different than the actual device id 84 // and that the actual device id didn't change. 85 // (investigating bug theory) 86 require.NotEqual(t, userDeviceID, devid) 87 require.Equal(t, userDeviceID, tc.G.Env.GetDeviceID()) 88 require.NotEqual(t, tc.G.Env.GetDeviceID(), devid) 89 } 90 91 func TestPaperKeyMulti(t *testing.T) { 92 testPaperKeyMulti(t, false) 93 } 94 95 func TestPaperKeyMultiPUK(t *testing.T) { 96 testPaperKeyMulti(t, true) 97 } 98 99 // Generate multiple paper keys 100 func testPaperKeyMulti(t *testing.T, upgradePerUserKey bool) { 101 tc := SetupEngineTest(t, "backup") 102 defer tc.Cleanup() 103 tc.Tp.DisableUpgradePerUserKey = !upgradePerUserKey 104 105 f := func(arg *SignupEngineRunArg) { 106 arg.SkipPaper = true 107 } 108 109 fu, _, _ := CreateAndSignupFakeUserCustomArg(tc, "login", f) 110 111 for i := 0; i < 3; i++ { 112 uis := libkb.UIs{ 113 LogUI: tc.G.UI.GetLogUI(), 114 LoginUI: &libkb.TestLoginUI{}, 115 SecretUI: &libkb.TestSecretUI{}, 116 } 117 eng := NewPaperKey(tc.G) 118 m := NewMetaContextForTest(tc).WithUIs(uis) 119 err := RunEngine2(m, eng) 120 require.NoError(t, err) 121 require.NotZero(t, eng.Passphrase()) 122 123 // check for the backup key 124 _, bdevs := paperDevs(tc, fu) 125 require.Equal(tc.T, i+1, len(bdevs), "num backup devices") 126 } 127 } 128 129 // tests revoking of existing backup keys 130 func TestPaperKeyRevoke(t *testing.T) { 131 tc := SetupEngineTest(t, "backup") 132 defer tc.Cleanup() 133 134 fu := CreateAndSignupFakeUser(tc, "login") 135 136 uis := libkb.UIs{ 137 LogUI: tc.G.UI.GetLogUI(), 138 LoginUI: &libkb.TestLoginUI{RevokeBackup: true}, 139 SecretUI: &libkb.TestSecretUI{}, 140 } 141 142 eng := NewPaperKey(tc.G) 143 m := NewMetaContextForTest(tc).WithUIs(uis) 144 err := RunEngine2(m, eng) 145 require.NoError(t, err) 146 require.NotZero(t, len(eng.Passphrase())) 147 148 // check for the backup key 149 _, bdevs := paperDevs(tc, fu) 150 require.Len(t, bdevs, 1) 151 152 // generate another one, first should be revoked 153 eng = NewPaperKey(tc.G) 154 err = RunEngine2(m, eng) 155 require.NoError(t, err) 156 require.NotZero(t, len(eng.Passphrase())) 157 158 // check for the backup key 159 _, bdevs = paperDevs(tc, fu) 160 require.Len(t, bdevs, 1) 161 } 162 163 // make a paperkey after revoking a previous one 164 func TestPaperKeyAfterRevokePUK(t *testing.T) { 165 tc := SetupEngineTest(t, "backup") 166 defer tc.Cleanup() 167 168 fu := CreateAndSignupFakeUser(tc, "login") 169 170 gen := func() { 171 uis := libkb.UIs{ 172 LogUI: tc.G.UI.GetLogUI(), 173 LoginUI: &libkb.TestLoginUI{}, 174 SecretUI: &libkb.TestSecretUI{}, 175 } 176 eng := NewPaperKey(tc.G) 177 m := NewMetaContextForTest(tc).WithUIs(uis) 178 err := RunEngine2(m, eng) 179 require.NoError(t, err) 180 require.NotEqual(t, 0, len(eng.Passphrase()), "empty passphrase") 181 } 182 183 revoke := func(devid keybase1.DeviceID) { 184 err := doRevokeDevice(tc, fu, devid, false /* force */, false /* forceLast */) 185 require.NoError(t, err) 186 } 187 188 hasZeroPaperDev(tc, fu) 189 gen() 190 devid := hasOnePaperDev(tc, fu) 191 revoke(devid) 192 hasZeroPaperDev(tc, fu) 193 gen() 194 hasOnePaperDev(tc, fu) 195 } 196 197 // tests not revoking existing backup keys 198 func TestPaperKeyNoRevoke(t *testing.T) { 199 tc := SetupEngineTest(t, "backup") 200 defer tc.Cleanup() 201 202 fu := CreateAndSignupFakeUserPaper(tc, "login") 203 204 uis := libkb.UIs{ 205 LogUI: tc.G.UI.GetLogUI(), 206 LoginUI: &libkb.TestLoginUI{RevokeBackup: false}, 207 SecretUI: &libkb.TestSecretUI{}, 208 } 209 210 eng := NewPaperKey(tc.G) 211 m := NewMetaContextForTest(tc).WithUIs(uis) 212 err := RunEngine2(m, eng) 213 require.NoError(t, err) 214 require.NotZero(t, len(eng.Passphrase())) 215 216 // check for the backup key 217 _, bdevs := paperDevs(tc, fu) 218 require.Len(t, bdevs, 2) 219 220 // generate another one, first should be left alone 221 eng = NewPaperKey(tc.G) 222 err = RunEngine2(m, eng) 223 require.NoError(t, err) 224 require.NotZero(t, len(eng.Passphrase())) 225 226 // check for the backup key 227 _, bdevs = paperDevs(tc, fu) 228 require.Len(t, bdevs, 3) 229 } 230 231 // Make sure PaperKeyGen uses the secret store. 232 func TestPaperKeyGenWithSecretStore(t *testing.T) { 233 testEngineWithSecretStore(t, func( 234 tc libkb.TestContext, fu *FakeUser, secretUI libkb.SecretUI) { 235 uis := libkb.UIs{ 236 LogUI: tc.G.UI.GetLogUI(), 237 LoginUI: &libkb.TestLoginUI{}, 238 SecretUI: secretUI, 239 } 240 eng := NewPaperKey(tc.G) 241 m := NewMetaContextForTest(tc).WithUIs(uis) 242 err := RunEngine2(m, eng) 243 require.NoError(t, err) 244 }) 245 }