github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/engine/pgp_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 "runtime/debug" 8 "strings" 9 "testing" 10 11 "github.com/keybase/client/go/libkb" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestGenerateNewPGPKey(t *testing.T) { 16 tc := SetupEngineTest(t, "pgp") 17 defer tc.Cleanup() 18 fu := CreateAndSignupFakeUser(tc, "pgp") 19 secui := &libkb.TestSecretUI{Passphrase: fu.Passphrase} 20 arg := PGPKeyImportEngineArg{ 21 Gen: &libkb.PGPGenArg{ 22 PrimaryBits: 768, 23 SubkeyBits: 768, 24 }, 25 } 26 err := arg.Gen.MakeAllIds(tc.G) 27 require.NoError(t, err) 28 uis := libkb.UIs{ 29 LogUI: tc.G.UI.GetLogUI(), 30 SecretUI: secui, 31 } 32 eng := NewPGPKeyImportEngine(tc.G, arg) 33 m := NewMetaContextForTest(tc).WithUIs(uis) 34 err = RunEngine2(m, eng) 35 if err != nil { 36 t.Fatal(err) 37 } 38 } 39 40 func TestPGPUserInterface(t *testing.T) { 41 p := newPgpPair(t) 42 defer p.cleanup() 43 44 p.assert(!p.senderTracksRecipient(), "sender shouldn't track recipient") 45 p.assert(!p.recipientTracksSender(), "recipient shouldn't track sender") 46 47 // encrypt, not signed 48 notSigned, idCount := p.encrypt(false) 49 50 // test that identify ui was shown once to sender for recipient 51 p.assertEqual(idCount, 1, "identify ui count [encrypt, not signed]") 52 // with identify2, no tracking, so test that sender doesn't track recipient 53 p.assert(!p.senderTracksRecipient(), "after encrypt, sender shouldn't track recipient") 54 p.assert(!p.recipientTracksSender(), "after encrypt, recipient shouldn't track sender") 55 56 // encrypt, signed 57 signed, idCount := p.encrypt(true) 58 59 // test that identify ui was *not* shown to sender for recipient since 60 // just shown in previous p.encrypt() call. 61 p.assertEqual(idCount, 0, "identify ui count [encrypt, signed]") 62 // with identify2, not tracking, so test that sender doesn't track recipient 63 p.assert(!p.senderTracksRecipient(), "after encrypt, sender shouldn't track recipient") 64 p.assert(!p.recipientTracksSender(), "after encrypt, recipient shouldn't track sender") 65 66 // decrypt, not signed 67 p.checkIdentifyUIAndPgpUI("decrypt not signed", p.decrypt, notSigned, 0) 68 69 // decrypt signed 70 p.checkIdentifyUIAndPgpUI("decrypt signed", p.decrypt, signed, 1) 71 72 // decrypt signed, assert signed by anyone 73 p.checkIdentifyUIAndPgpUI("decrypt assert signed", p.decryptAssertSigned, signed, 1) 74 75 // decrypt signed with user assertion 76 p.checkIdentifyUIAndPgpUI("decrypt assert signed by", p.decryptAssertSignedBySender, signed, 1) 77 78 // decrypt signed by self 79 p.checkIdentifyUIAndPgpUI("decrypt self", p.decryptSelf, signed, 1) 80 81 // decrypt assert signed by self 82 p.checkIdentifyUIAndPgpUI("decrypt assert signed by self", p.decryptAssertSignedBySelf, signed, 1) 83 84 // verify signed 85 p.checkIdentifyUIAndPgpUI("verify signed", p.verify, signed, 1) 86 87 // verify signed with assertion 88 p.checkIdentifyUIAndPgpUI("verify assert signed by", p.verifyAssertSignedBySender, signed, 1) 89 90 // verify signed by self 91 p.checkIdentifyUIAndPgpUI("verify self", p.verifySelf, signed, 1) 92 93 // verify assert signed by self 94 p.checkIdentifyUIAndPgpUI("verify assert signed by self", p.verifyAssertSignedBySelf, signed, 1) 95 } 96 97 type pgpPair struct { 98 t *testing.T 99 tcS libkb.TestContext 100 tcR libkb.TestContext 101 sender *FakeUser 102 recipient *FakeUser 103 } 104 105 func newPgpPair(t *testing.T) *pgpPair { 106 p := pgpPair{t: t} 107 p.tcS = SetupEngineTest(t, "sender") 108 p.sender = createFakeUserWithPGPSibkey(p.tcS) 109 110 p.tcR = SetupEngineTest(t, "recip") 111 p.recipient = createFakeUserWithPGPSibkey(p.tcR) 112 return &p 113 } 114 115 func (p *pgpPair) cleanup() { 116 p.tcS.Cleanup() 117 p.tcR.Cleanup() 118 } 119 120 func (p *pgpPair) assert(b bool, m string) { 121 if b { 122 return 123 } 124 p.t.Fatal(m) 125 } 126 127 func (p *pgpPair) assertEqual(actual, expected int, m string) { 128 if actual == expected { 129 return 130 } 131 p.t.Fatalf("%s: %d, expected %d", m, actual, expected) 132 } 133 134 func (p *pgpPair) checkIdentifyUIAndPgpUI(name string, f func(string) (int, int), m string, n int) { 135 idCount, sigCount := f(m) 136 137 // test that identify ui was shown n times 138 p.assertEqual(idCount, n, name+": identify ui count") 139 // test that recipient does not track sender 140 p.assert(!p.recipientTracksSender(), name+": recipient shouldn't track sender") 141 // test that signature success was shown n times 142 p.assertEqual(sigCount, n, name+": sig ui count") 143 } 144 145 func (p *pgpPair) senderTracksRecipient() bool { 146 return p.isTracking(p.tcS, p.recipient.Username) 147 } 148 149 func (p *pgpPair) recipientTracksSender() bool { 150 return p.isTracking(p.tcR, p.sender.Username) 151 } 152 153 func (p *pgpPair) isTracking(meContext libkb.TestContext, username string) bool { 154 me, err := libkb.LoadMe(libkb.NewLoadUserArg(meContext.G)) 155 if err != nil { 156 p.t.Fatal(err) 157 } 158 them, err := libkb.LoadUser(libkb.NewLoadUserByNameArg(meContext.G, username)) 159 if err != nil { 160 p.t.Fatal(err) 161 } 162 m := NewMetaContextForTest(meContext) 163 s, err := me.TrackChainLinkFor(m, them.GetNormalizedName(), them.GetUID()) 164 if err != nil { 165 p.t.Fatal(err) 166 } 167 return s != nil 168 } 169 170 func (p *pgpPair) encrypt(sign bool) (string, int) { 171 uis := libkb.UIs{ 172 IdentifyUI: &FakeIdentifyUI{}, 173 PgpUI: &TestPgpUI{}, 174 SecretUI: p.sender.NewSecretUI(), 175 } 176 sink := libkb.NewBufferCloser() 177 arg := &PGPEncryptArg{ 178 Recips: []string{p.recipient.Username}, 179 Source: strings.NewReader("thank you for your order"), 180 Sink: sink, 181 NoSign: !sign, 182 } 183 184 eng := NewPGPEncrypt(p.tcS.G, arg) 185 m := NewMetaContextForTest(p.tcS).WithUIs(uis) 186 if err := RunEngine2(m, eng); err != nil { 187 p.t.Fatal(err) 188 } 189 190 out := sink.Bytes() 191 192 return string(out), p.idc(m) 193 } 194 195 func (p *pgpPair) decrypt(msg string) (int, int) { 196 return p.doDecrypt(msg, &PGPDecryptArg{}) 197 } 198 199 func (p *pgpPair) decryptAssertSigned(msg string) (int, int) { 200 return p.doDecrypt(msg, &PGPDecryptArg{AssertSigned: true}) 201 } 202 203 func (p *pgpPair) decryptAssertSignedBySender(msg string) (int, int) { 204 return p.doDecrypt(msg, &PGPDecryptArg{SignedBy: p.sender.Username}) 205 } 206 207 func (p *pgpPair) decryptSelf(msg string) (int, int) { 208 ctx := decengctx(p.sender, p.tcS) 209 arg := &PGPDecryptArg{ 210 Source: strings.NewReader(msg), 211 Sink: libkb.NewBufferCloser(), 212 } 213 dec := NewPGPDecrypt(p.tcS.G, arg) 214 if err := RunEngine2(ctx, dec); err != nil { 215 p.t.Fatal(err) 216 } 217 return p.idc(ctx), p.sigc(ctx) 218 } 219 220 func (p *pgpPair) decryptAssertSignedBySelf(msg string) (int, int) { 221 ctx := decengctx(p.sender, p.tcS) 222 arg := &PGPDecryptArg{ 223 Source: strings.NewReader(msg), 224 Sink: libkb.NewBufferCloser(), 225 SignedBy: p.sender.Username, 226 } 227 dec := NewPGPDecrypt(p.tcS.G, arg) 228 if err := RunEngine2(ctx, dec); err != nil { 229 p.t.Fatal(err) 230 } 231 return p.idc(ctx), p.sigc(ctx) 232 } 233 234 func (p *pgpPair) doDecrypt(msg string, arg *PGPDecryptArg) (int, int) { 235 ctx := decengctx(p.recipient, p.tcR) 236 arg.Source = strings.NewReader(msg) 237 arg.Sink = libkb.NewBufferCloser() 238 dec := NewPGPDecrypt(p.tcR.G, arg) 239 if err := RunEngine2(ctx, dec); err != nil { 240 debug.PrintStack() 241 p.t.Fatal(err) 242 } 243 return p.idc(ctx), p.sigc(ctx) 244 } 245 246 func (p *pgpPair) verify(msg string) (int, int) { 247 ctx := decengctx(p.recipient, p.tcR) 248 arg := &PGPVerifyArg{ 249 Source: strings.NewReader(msg), 250 } 251 eng := NewPGPVerify(p.tcR.G, arg) 252 if err := RunEngine2(ctx, eng); err != nil { 253 p.t.Fatal(err) 254 } 255 return p.idc(ctx), p.sigc(ctx) 256 } 257 258 func (p *pgpPair) verifyAssertSignedBySender(msg string) (int, int) { 259 ctx := decengctx(p.recipient, p.tcR) 260 arg := &PGPVerifyArg{ 261 Source: strings.NewReader(msg), 262 SignedBy: p.sender.Username, 263 } 264 eng := NewPGPVerify(p.tcR.G, arg) 265 if err := RunEngine2(ctx, eng); err != nil { 266 p.t.Fatal(err) 267 } 268 return p.idc(ctx), p.sigc(ctx) 269 } 270 271 func (p *pgpPair) verifySelf(msg string) (int, int) { 272 ctx := decengctx(p.sender, p.tcS) 273 arg := &PGPVerifyArg{ 274 Source: strings.NewReader(msg), 275 } 276 eng := NewPGPVerify(p.tcS.G, arg) 277 if err := RunEngine2(ctx, eng); err != nil { 278 p.t.Fatal(err) 279 } 280 return p.idc(ctx), p.sigc(ctx) 281 } 282 283 func (p *pgpPair) verifyAssertSignedBySelf(msg string) (int, int) { 284 ctx := decengctx(p.sender, p.tcS) 285 arg := &PGPVerifyArg{ 286 Source: strings.NewReader(msg), 287 SignedBy: p.sender.Username, 288 } 289 eng := NewPGPVerify(p.tcS.G, arg) 290 if err := RunEngine2(ctx, eng); err != nil { 291 p.t.Fatal(err) 292 } 293 return p.idc(ctx), p.sigc(ctx) 294 } 295 296 func (p *pgpPair) idc(m libkb.MetaContext) int { 297 ui, ok := m.UIs().IdentifyUI.(*FakeIdentifyUI) 298 if !ok { 299 p.t.Fatalf("not FakeIdentifyUI: %T", m.UIs().IdentifyUI) 300 } 301 p.t.Logf("FakeIdentifyUI: %+v", ui) 302 return ui.StartCount 303 } 304 305 func (p *pgpPair) sigc(m libkb.MetaContext) int { 306 ui, ok := m.UIs().PgpUI.(*TestPgpUI) 307 if !ok { 308 p.t.Fatalf("not TestPgpUI: %T", m.UIs().PgpUI) 309 } 310 return ui.OutputCount 311 }