1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package rsa
6
7import (
8	"bytes"
9	"crypto"
10	"crypto/rand"
11	"crypto/sha1"
12	"crypto/sha256"
13	"encoding/base64"
14	"encoding/hex"
15	"io"
16	"math/big"
17	"testing"
18	"testing/quick"
19)
20
21func decodeBase64(in string) []byte {
22	out := make([]byte, base64.StdEncoding.DecodedLen(len(in)))
23	n, err := base64.StdEncoding.Decode(out, []byte(in))
24	if err != nil {
25		return nil
26	}
27	return out[0:n]
28}
29
30type DecryptPKCS1v15Test struct {
31	in, out string
32}
33
34// These test vectors were generated with `openssl rsautl -pkcs -encrypt`
35var decryptPKCS1v15Tests = []DecryptPKCS1v15Test{
36	{
37		"gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==",
38		"x",
39	},
40	{
41		"Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==",
42		"testing.",
43	},
44	{
45		"arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==",
46		"testing.\n",
47	},
48	{
49		"WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==",
50		"01234567890123456789012345678901234567890123456789012",
51	},
52}
53
54func TestDecryptPKCS1v15(t *testing.T) {
55	decryptionFuncs := []func([]byte) ([]byte, error){
56		func(ciphertext []byte) (plaintext []byte, err error) {
57			return DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext)
58		},
59		func(ciphertext []byte) (plaintext []byte, err error) {
60			return rsaPrivateKey.Decrypt(nil, ciphertext, nil)
61		},
62	}
63
64	for _, decryptFunc := range decryptionFuncs {
65		for i, test := range decryptPKCS1v15Tests {
66			out, err := decryptFunc(decodeBase64(test.in))
67			if err != nil {
68				t.Errorf("#%d error decrypting", i)
69			}
70			want := []byte(test.out)
71			if !bytes.Equal(out, want) {
72				t.Errorf("#%d got:%#v want:%#v", i, out, want)
73			}
74		}
75	}
76}
77
78func TestEncryptPKCS1v15(t *testing.T) {
79	random := rand.Reader
80	k := (rsaPrivateKey.N.BitLen() + 7) / 8
81
82	tryEncryptDecrypt := func(in []byte, blind bool) bool {
83		if len(in) > k-11 {
84			in = in[0 : k-11]
85		}
86
87		ciphertext, err := EncryptPKCS1v15(random, &rsaPrivateKey.PublicKey, in)
88		if err != nil {
89			t.Errorf("error encrypting: %s", err)
90			return false
91		}
92
93		var rand io.Reader
94		if !blind {
95			rand = nil
96		} else {
97			rand = random
98		}
99		plaintext, err := DecryptPKCS1v15(rand, rsaPrivateKey, ciphertext)
100		if err != nil {
101			t.Errorf("error decrypting: %s", err)
102			return false
103		}
104
105		if !bytes.Equal(plaintext, in) {
106			t.Errorf("output mismatch: %#v %#v", plaintext, in)
107			return false
108		}
109		return true
110	}
111
112	config := new(quick.Config)
113	if testing.Short() {
114		config.MaxCount = 10
115	}
116	quick.Check(tryEncryptDecrypt, config)
117}
118
119// These test vectors were generated with `openssl rsautl -pkcs -encrypt`
120var decryptPKCS1v15SessionKeyTests = []DecryptPKCS1v15Test{
121	{
122		"e6ukkae6Gykq0fKzYwULpZehX+UPXYzMoB5mHQUDEiclRbOTqas4Y0E6nwns1BBpdvEJcilhl5zsox/6DtGsYg==",
123		"1234",
124	},
125	{
126		"Dtis4uk/q/LQGGqGk97P59K03hkCIVFMEFZRgVWOAAhxgYpCRG0MX2adptt92l67IqMki6iVQyyt0TtX3IdtEw==",
127		"FAIL",
128	},
129	{
130		"LIyFyCYCptPxrvTxpol8F3M7ZivlMsf53zs0vHRAv+rDIh2YsHS69ePMoPMe3TkOMZ3NupiL3takPxIs1sK+dw==",
131		"abcd",
132	},
133	{
134		"bafnobel46bKy76JzqU/RIVOH0uAYvzUtauKmIidKgM0sMlvobYVAVQPeUQ/oTGjbIZ1v/6Gyi5AO4DtHruGdw==",
135		"FAIL",
136	},
137}
138
139func TestEncryptPKCS1v15SessionKey(t *testing.T) {
140	for i, test := range decryptPKCS1v15SessionKeyTests {
141		key := []byte("FAIL")
142		err := DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, decodeBase64(test.in), key)
143		if err != nil {
144			t.Errorf("#%d error decrypting", i)
145		}
146		want := []byte(test.out)
147		if !bytes.Equal(key, want) {
148			t.Errorf("#%d got:%#v want:%#v", i, key, want)
149		}
150	}
151}
152
153func TestEncryptPKCS1v15DecrypterSessionKey(t *testing.T) {
154	for i, test := range decryptPKCS1v15SessionKeyTests {
155		plaintext, err := rsaPrivateKey.Decrypt(rand.Reader, decodeBase64(test.in), &PKCS1v15DecryptOptions{SessionKeyLen: 4})
156		if err != nil {
157			t.Fatalf("#%d: error decrypting: %s", i, err)
158		}
159		if len(plaintext) != 4 {
160			t.Fatalf("#%d: incorrect length plaintext: got %d, want 4", i, len(plaintext))
161		}
162
163		if test.out != "FAIL" && !bytes.Equal(plaintext, []byte(test.out)) {
164			t.Errorf("#%d: incorrect plaintext: got %x, want %x", i, plaintext, test.out)
165		}
166	}
167}
168
169func TestNonZeroRandomBytes(t *testing.T) {
170	random := rand.Reader
171
172	b := make([]byte, 512)
173	err := nonZeroRandomBytes(b, random)
174	if err != nil {
175		t.Errorf("returned error: %s", err)
176	}
177	for _, b := range b {
178		if b == 0 {
179			t.Errorf("Zero octet found")
180			return
181		}
182	}
183}
184
185type signPKCS1v15Test struct {
186	in, out string
187}
188
189// These vectors have been tested with
190//   `openssl rsautl -verify -inkey pk -in signature | hexdump -C`
191var signPKCS1v15Tests = []signPKCS1v15Test{
192	{"Test.\n", "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e336ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"},
193}
194
195func TestSignPKCS1v15(t *testing.T) {
196	for i, test := range signPKCS1v15Tests {
197		h := sha1.New()
198		h.Write([]byte(test.in))
199		digest := h.Sum(nil)
200
201		s, err := SignPKCS1v15(nil, rsaPrivateKey, crypto.SHA1, digest)
202		if err != nil {
203			t.Errorf("#%d %s", i, err)
204		}
205
206		expected, _ := hex.DecodeString(test.out)
207		if !bytes.Equal(s, expected) {
208			t.Errorf("#%d got: %x want: %x", i, s, expected)
209		}
210	}
211}
212
213func TestVerifyPKCS1v15(t *testing.T) {
214	for i, test := range signPKCS1v15Tests {
215		h := sha1.New()
216		h.Write([]byte(test.in))
217		digest := h.Sum(nil)
218
219		sig, _ := hex.DecodeString(test.out)
220
221		err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA1, digest, sig)
222		if err != nil {
223			t.Errorf("#%d %s", i, err)
224		}
225	}
226}
227
228func TestOverlongMessagePKCS1v15(t *testing.T) {
229	ciphertext := decodeBase64("fjOVdirUzFoLlukv80dBllMLjXythIf22feqPrNo0YoIjzyzyoMFiLjAc/Y4krkeZ11XFThIrEvw\nkRiZcCq5ng==")
230	_, err := DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext)
231	if err == nil {
232		t.Error("RSA decrypted a message that was too long.")
233	}
234}
235
236func TestUnpaddedSignature(t *testing.T) {
237	msg := []byte("Thu Dec 19 18:06:16 EST 2013\n")
238	// This base64 value was generated with:
239	// % echo Thu Dec 19 18:06:16 EST 2013 > /tmp/msg
240	// % openssl rsautl -sign -inkey key -out /tmp/sig -in /tmp/msg
241	//
242	// Where "key" contains the RSA private key given at the bottom of this
243	// file.
244	expectedSig := decodeBase64("pX4DR8azytjdQ1rtUiC040FjkepuQut5q2ZFX1pTjBrOVKNjgsCDyiJDGZTCNoh9qpXYbhl7iEym30BWWwuiZg==")
245
246	sig, err := SignPKCS1v15(nil, rsaPrivateKey, crypto.Hash(0), msg)
247	if err != nil {
248		t.Fatalf("SignPKCS1v15 failed: %s", err)
249	}
250	if !bytes.Equal(sig, expectedSig) {
251		t.Fatalf("signature is not expected value: got %x, want %x", sig, expectedSig)
252	}
253	if err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.Hash(0), msg, sig); err != nil {
254		t.Fatalf("signature failed to verify: %s", err)
255	}
256}
257
258func TestShortSessionKey(t *testing.T) {
259	// This tests that attempting to decrypt a session key where the
260	// ciphertext is too small doesn't run outside the array bounds.
261	ciphertext, err := EncryptPKCS1v15(rand.Reader, &rsaPrivateKey.PublicKey, []byte{1})
262	if err != nil {
263		t.Fatalf("Failed to encrypt short message: %s", err)
264	}
265
266	var key [32]byte
267	if err := DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, ciphertext, key[:]); err != nil {
268		t.Fatalf("Failed to decrypt short message: %s", err)
269	}
270
271	for _, v := range key {
272		if v != 0 {
273			t.Fatal("key was modified when ciphertext was invalid")
274		}
275	}
276}
277
278// In order to generate new test vectors you'll need the PEM form of this key (and s/TESTING/PRIVATE/):
279// -----BEGIN RSA TESTING KEY-----
280// MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
281// fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
282// /ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
283// RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
284// EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
285// IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
286// tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
287// -----END RSA TESTING KEY-----
288
289var rsaPrivateKey = &PrivateKey{
290	PublicKey: PublicKey{
291		N: fromBase10("9353930466774385905609975137998169297361893554149986716853295022578535724979677252958524466350471210367835187480748268864277464700638583474144061408845077"),
292		E: 65537,
293	},
294	D: fromBase10("7266398431328116344057699379749222532279343923819063639497049039389899328538543087657733766554155839834519529439851673014800261285757759040931985506583861"),
295	Primes: []*big.Int{
296		fromBase10("98920366548084643601728869055592650835572950932266967461790948584315647051443"),
297		fromBase10("94560208308847015747498523884063394671606671904944666360068158221458669711639"),
298	},
299}
300
301func TestShortPKCS1v15Signature(t *testing.T) {
302	pub := &PublicKey{
303		E: 65537,
304		N: fromBase10("8272693557323587081220342447407965471608219912416565371060697606400726784709760494166080686904546560026343451112103559482851304715739629410219358933351333"),
305	}
306	sig, err := hex.DecodeString("193a310d0dcf64094c6e3a00c8219b80ded70535473acff72c08e1222974bb24a93a535b1dc4c59fc0e65775df7ba2007dd20e9193f4c4025a18a7070aee93")
307	if err != nil {
308		t.Fatalf("failed to decode signature: %s", err)
309	}
310
311	h := sha256.Sum256([]byte("hello"))
312	err = VerifyPKCS1v15(pub, crypto.SHA256, h[:], sig)
313	if err == nil {
314		t.Fatal("VerifyPKCS1v15 accepted a truncated signature")
315	}
316}
317