1// Copyright 2015 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package engine
5
6import (
7	"bytes"
8	"strings"
9	"testing"
10
11	"github.com/keybase/client/go/libkb"
12)
13
14func TestPGPEncrypt(t *testing.T) {
15	tc := SetupEngineTest(t, "PGPEncrypt")
16	defer tc.Cleanup()
17
18	u := createFakeUserWithPGPSibkey(tc)
19	trackUI := &FakeIdentifyUI{
20		Proofs: make(map[string]string),
21	}
22	uis := libkb.UIs{
23		IdentifyUI: trackUI,
24		PgpUI:      &TestPgpUI{},
25		SecretUI:   u.NewSecretUI(),
26	}
27
28	sink := libkb.NewBufferCloser()
29	arg := &PGPEncryptArg{
30		Recips: []string{"t_alice", "t_bob+kbtester1@twitter", "t_charlie+tacovontaco@twitter"},
31		Source: strings.NewReader("track and encrypt, track and encrypt"),
32		Sink:   sink,
33		NoSign: true,
34	}
35
36	eng := NewPGPEncrypt(tc.G, arg)
37	m := NewMetaContextForTest(tc).WithUIs(uis)
38	if err := RunEngine2(m, eng); err != nil {
39		t.Fatal(err)
40	}
41
42	out := sink.Bytes()
43	if len(out) == 0 {
44		t.Fatal("no output")
45	}
46}
47
48func TestPGPEncryptNoPGPNaClOnly(t *testing.T) {
49	tc := SetupEngineTest(t, "TestPGPEncryptNoPGPNaClOnly")
50	defer tc.Cleanup()
51
52	u1 := CreateAndSignupFakeUser(tc, "nalcp")
53	Logout(tc)
54	u2 := createFakeUserWithPGPSibkey(tc)
55	trackUI := &FakeIdentifyUI{
56		Proofs: make(map[string]string),
57	}
58	uis := libkb.UIs{
59		IdentifyUI: trackUI,
60		PgpUI:      &TestPgpUI{},
61		SecretUI:   u2.NewSecretUI(),
62	}
63
64	sink := libkb.NewBufferCloser()
65	arg := &PGPEncryptArg{
66		Recips: []string{u1.Username},
67		Source: strings.NewReader("track and encrypt, track and encrypt"),
68		Sink:   sink,
69		NoSign: true,
70	}
71
72	eng := NewPGPEncrypt(tc.G, arg)
73	m := NewMetaContextForTest(tc).WithUIs(uis)
74	err := RunEngine2(m, eng)
75	if perr, ok := err.(libkb.NoPGPEncryptionKeyError); !ok {
76		t.Fatalf("Got wrong error type: %T %v", err, err)
77	} else if !perr.HasKeybaseEncryptionKey {
78		t.Fatalf("Should have a keybase encryption key")
79	} else if perr.User != u1.Username {
80		t.Fatalf("Wrong username")
81	}
82}
83
84func TestPGPEncryptSelfNoKey(t *testing.T) {
85	tc := SetupEngineTest(t, "PGPEncrypt")
86	defer tc.Cleanup()
87
88	u := CreateAndSignupFakeUser(tc, "login")
89	trackUI := &FakeIdentifyUI{
90		Proofs: make(map[string]string),
91	}
92	uis := libkb.UIs{
93		IdentifyUI: trackUI,
94		PgpUI:      &TestPgpUI{},
95		SecretUI:   u.NewSecretUI(),
96	}
97
98	sink := libkb.NewBufferCloser()
99	arg := &PGPEncryptArg{
100		Recips: []string{"t_alice", "t_bob+twitter:kbtester1", "t_charlie+twitter:tacovontaco"},
101		Source: strings.NewReader("track and encrypt, track and encrypt"),
102		Sink:   sink,
103		NoSign: true,
104	}
105
106	eng := NewPGPEncrypt(tc.G, arg)
107	m := NewMetaContextForTest(tc).WithUIs(uis)
108	err := RunEngine2(m, eng)
109	if err == nil {
110		t.Fatal("no error encrypting for self without pgp key")
111	}
112	if _, ok := err.(libkb.NoKeyError); !ok {
113		t.Fatalf("expected error type libkb.NoKeyError, got %T (%s)", err, err)
114	}
115}
116
117func TestPGPEncryptNoTrack(t *testing.T) {
118	tc := SetupEngineTest(t, "PGPEncrypt")
119	defer tc.Cleanup()
120
121	u := createFakeUserWithPGPSibkey(tc)
122	trackUI := &FakeIdentifyUI{
123		Proofs: make(map[string]string),
124	}
125	uis := libkb.UIs{
126		IdentifyUI: trackUI,
127		PgpUI:      &TestPgpUI{},
128		SecretUI:   u.NewSecretUI(),
129	}
130
131	sink := libkb.NewBufferCloser()
132	arg := &PGPEncryptArg{
133		Recips: []string{"t_alice", "t_bob+kbtester1@twitter", "t_charlie+tacovontaco@twitter"},
134		Source: strings.NewReader("identify and encrypt, identify and encrypt"),
135		Sink:   sink,
136		NoSign: true,
137	}
138
139	eng := NewPGPEncrypt(tc.G, arg)
140	m := NewMetaContextForTest(tc).WithUIs(uis)
141	if err := RunEngine2(m, eng); err != nil {
142		t.Fatal(err)
143	}
144
145	out := sink.Bytes()
146	if len(out) == 0 {
147		t.Fatal("no output")
148	}
149
150	assertNotTracking(tc, "t_alice")
151	assertNotTracking(tc, "t_bob")
152	assertNotTracking(tc, "t_charlie")
153}
154
155// encrypt for self via NoSelf: false and username in recipients
156func TestPGPEncryptSelfTwice(t *testing.T) {
157	tc := SetupEngineTest(t, "PGPEncrypt")
158	defer tc.Cleanup()
159
160	u := createFakeUserWithPGPSibkey(tc)
161	trackUI := &FakeIdentifyUI{
162		Proofs: make(map[string]string),
163	}
164	uis := libkb.UIs{
165		IdentifyUI: trackUI,
166		PgpUI:      &TestPgpUI{},
167		SecretUI:   u.NewSecretUI(),
168	}
169
170	msg := "encrypt for self only once"
171	sink := libkb.NewBufferCloser()
172	arg := &PGPEncryptArg{
173		Recips: []string{u.Username},
174		Source: strings.NewReader(msg),
175		Sink:   sink,
176		NoSign: true,
177	}
178
179	eng := NewPGPEncrypt(tc.G, arg)
180	m := NewMetaContextForTest(tc).WithUIs(uis)
181	err := RunEngine2(m, eng)
182	if err != nil {
183		t.Fatal(err)
184	}
185	out := sink.Bytes()
186
187	// decrypt it
188	decoded := libkb.NewBufferCloser()
189	decarg := &PGPDecryptArg{
190		Source: bytes.NewReader(out),
191		Sink:   decoded,
192	}
193	dec := NewPGPDecrypt(tc.G, decarg)
194	m = m.WithLogUI(tc.G.UI.GetLogUI()).WithPgpUI(&TestPgpUI{})
195	if err := RunEngine2(m, dec); err != nil {
196		t.Fatal(err)
197	}
198	decmsg := decoded.String()
199	if decmsg != msg {
200		t.Errorf("decoded: %q, expected: %q", decmsg, msg)
201	}
202
203	recips := dec.signStatus.RecipientKeyIDs
204	if len(recips) != 1 {
205		t.Logf("recipient key ids: %v", recips)
206		t.Errorf("num recipient key ids: %d, expected 1", len(recips))
207	}
208}
209