1// Copyright 2015 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package libkb
5
6import (
7	"bytes"
8	"crypto/rand"
9	"io/ioutil"
10	"strings"
11	"testing"
12	"testing/quick"
13
14	"github.com/keybase/go-crypto/openpgp"
15)
16
17// give a private key and a public key, test the encryption of a
18// message
19func TestPGPEncrypt(t *testing.T) {
20	tc := SetupTest(t, "pgp_encrypt", 1)
21	defer tc.Cleanup()
22	bundleSrc, err := tc.MakePGPKey("src@keybase.io")
23	if err != nil {
24		t.Fatal(err)
25	}
26	bundleDst, err := tc.MakePGPKey("dst@keybase.io")
27	if err != nil {
28		t.Fatal(err)
29	}
30
31	msg := "59 seconds"
32	sink := NewBufferCloser()
33	recipients := []*PGPKeyBundle{bundleSrc, bundleDst}
34	if err := PGPEncrypt(strings.NewReader(msg), sink, bundleSrc, recipients); err != nil {
35		t.Fatal(err)
36	}
37	out := sink.Bytes()
38	if len(out) == 0 {
39		t.Fatal("no output")
40	}
41
42	// check that each recipient can read the message
43	for _, recip := range recipients {
44		kr := openpgp.EntityList{recip.Entity}
45		emsg := bytes.NewBuffer(out)
46		md, err := openpgp.ReadMessage(emsg, kr, nil, nil)
47		if err != nil {
48			t.Fatal(err)
49		}
50		text, err := ioutil.ReadAll(md.UnverifiedBody)
51		if err != nil {
52			t.Fatal(err)
53		}
54		if string(text) != msg {
55			t.Errorf("message: %q, expected %q", string(text), msg)
56		}
57	}
58}
59
60func TestPGPEncryptString(t *testing.T) {
61	tc := SetupTest(t, "pgp_encrypt", 1)
62	defer tc.Cleanup()
63	bundleSrc, err := tc.MakePGPKey("src@keybase.io")
64	if err != nil {
65		t.Fatal(err)
66	}
67	bundleDst, err := tc.MakePGPKey("dst@keybase.io")
68	if err != nil {
69		t.Fatal(err)
70	}
71
72	msg := "59 seconds"
73	recipients := []*PGPKeyBundle{bundleSrc, bundleDst}
74	out, err := PGPEncryptString(msg, bundleSrc, recipients)
75	if err != nil {
76		t.Fatal(err)
77	}
78
79	if len(out) == 0 {
80		t.Fatal("no output")
81	}
82
83	// check that each recipient can read the message
84	for _, recip := range recipients {
85		kr := openpgp.EntityList{recip.Entity}
86		emsg := bytes.NewBuffer(out)
87		md, err := openpgp.ReadMessage(emsg, kr, nil, nil)
88		if err != nil {
89			t.Fatal(err)
90		}
91		text, err := ioutil.ReadAll(md.UnverifiedBody)
92		if err != nil {
93			t.Fatal(err)
94		}
95		if string(text) != msg {
96			t.Errorf("message: %q, expected %q", string(text), msg)
97		}
98	}
99}
100
101func TestPGPEncryptQuick(t *testing.T) {
102	tc := SetupTest(t, "pgp_encrypt", 1)
103	defer tc.Cleanup()
104	bundleSrc, err := tc.MakePGPKey("src@keybase.io")
105	if err != nil {
106		t.Fatal(err)
107	}
108	bundleDst, err := tc.MakePGPKey("dst@keybase.io")
109	if err != nil {
110		t.Fatal(err)
111	}
112
113	f := func(msg []byte) bool {
114		sink := NewBufferCloser()
115		recipients := []*PGPKeyBundle{bundleSrc, bundleDst}
116		if err := PGPEncrypt(bytes.NewReader(msg), sink, bundleSrc, recipients); err != nil {
117			return false
118		}
119		out := sink.Bytes()
120		if len(out) == 0 {
121			return false
122		}
123
124		// check that each recipient can read the message
125		for _, recip := range recipients {
126			kr := openpgp.EntityList{recip.Entity}
127			emsg := bytes.NewBuffer(out)
128			md, err := openpgp.ReadMessage(emsg, kr, nil, nil)
129			if err != nil {
130				return false
131			}
132			data, err := ioutil.ReadAll(md.UnverifiedBody)
133			if err != nil {
134				return false
135			}
136			if !bytes.Equal(data, msg) {
137				return false
138			}
139		}
140		return true
141	}
142
143	if err := quick.Check(f, nil); err != nil {
144		t.Error(err)
145	}
146}
147
148func TestPGPEncryptLong(t *testing.T) {
149	tc := SetupTest(t, "pgp_encrypt", 1)
150	defer tc.Cleanup()
151	bundleSrc, err := tc.MakePGPKey("src@keybase.io")
152	if err != nil {
153		t.Fatal(err)
154	}
155	bundleDst, err := tc.MakePGPKey("dst@keybase.io")
156	if err != nil {
157		t.Fatal(err)
158	}
159
160	msg := make([]byte, 1024*1024)
161
162	_, err = rand.Read(msg)
163	if err != nil {
164		t.Fatal(err)
165	}
166
167	tc.G.Log.Info("msg size: %d", len(msg))
168
169	sink := NewBufferCloser()
170	recipients := []*PGPKeyBundle{bundleSrc, bundleDst}
171	if err := PGPEncrypt(bytes.NewReader(msg), sink, bundleSrc, recipients); err != nil {
172		t.Fatal(err)
173	}
174
175	out := sink.Bytes()
176	if len(out) == 0 {
177		t.Fatal("no output")
178	}
179
180	// check that each recipient can read the message
181	for _, recip := range recipients {
182		kr := openpgp.EntityList{recip.Entity}
183		emsg := bytes.NewBuffer(out)
184		md, err := openpgp.ReadMessage(emsg, kr, nil, nil)
185		if err != nil {
186			t.Fatal(err)
187		}
188		text, err := ioutil.ReadAll(md.UnverifiedBody)
189		if err != nil {
190			t.Fatal(err)
191		}
192		if string(text) != string(msg) {
193			t.Errorf("message: %q, expected %q", string(text), string(msg))
194		}
195	}
196}
197