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