1package jwt_test
2
3import (
4	"github.com/dgrijalva/jwt-go"
5	"io/ioutil"
6	"strings"
7	"testing"
8)
9
10var rsaTestData = []struct {
11	name        string
12	tokenString string
13	alg         string
14	claims      map[string]interface{}
15	valid       bool
16}{
17	{
18		"Basic RS256",
19		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
20		"RS256",
21		map[string]interface{}{"foo": "bar"},
22		true,
23	},
24	{
25		"Basic RS384",
26		"eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.W-jEzRfBigtCWsinvVVuldiuilzVdU5ty0MvpLaSaqK9PlAWWlDQ1VIQ_qSKzwL5IXaZkvZFJXT3yL3n7OUVu7zCNJzdwznbC8Z-b0z2lYvcklJYi2VOFRcGbJtXUqgjk2oGsiqUMUMOLP70TTefkpsgqDxbRh9CDUfpOJgW-dU7cmgaoswe3wjUAUi6B6G2YEaiuXC0XScQYSYVKIzgKXJV8Zw-7AN_DBUI4GkTpsvQ9fVVjZM9csQiEXhYekyrKu1nu_POpQonGd8yqkIyXPECNmmqH5jH4sFiF67XhD7_JpkvLziBpI-uh86evBUadmHhb9Otqw3uV3NTaXLzJw",
27		"RS384",
28		map[string]interface{}{"foo": "bar"},
29		true,
30	},
31	{
32		"Basic RS512",
33		"eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.zBlLlmRrUxx4SJPUbV37Q1joRcI9EW13grnKduK3wtYKmDXbgDpF1cZ6B-2Jsm5RB8REmMiLpGms-EjXhgnyh2TSHE-9W2gA_jvshegLWtwRVDX40ODSkTb7OVuaWgiy9y7llvcknFBTIg-FnVPVpXMmeV_pvwQyhaz1SSwSPrDyxEmksz1hq7YONXhXPpGaNbMMeDTNP_1oj8DZaqTIL9TwV8_1wb2Odt_Fy58Ke2RVFijsOLdnyEAjt2n9Mxihu9i3PhNBkkxa2GbnXBfq3kzvZ_xxGGopLdHhJjcGWXO-NiwI9_tiu14NRv4L2xC0ItD9Yz68v2ZIZEp_DuzwRQ",
34		"RS512",
35		map[string]interface{}{"foo": "bar"},
36		true,
37	},
38	{
39		"basic invalid: foo => bar",
40		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
41		"RS256",
42		map[string]interface{}{"foo": "bar"},
43		false,
44	},
45}
46
47func TestRSAVerify(t *testing.T) {
48	keyData, _ := ioutil.ReadFile("test/sample_key.pub")
49	key, _ := jwt.ParseRSAPublicKeyFromPEM(keyData)
50
51	for _, data := range rsaTestData {
52		parts := strings.Split(data.tokenString, ".")
53
54		method := jwt.GetSigningMethod(data.alg)
55		err := method.Verify(strings.Join(parts[0:2], "."), parts[2], key)
56		if data.valid && err != nil {
57			t.Errorf("[%v] Error while verifying key: %v", data.name, err)
58		}
59		if !data.valid && err == nil {
60			t.Errorf("[%v] Invalid key passed validation", data.name)
61		}
62	}
63}
64
65func TestRSASign(t *testing.T) {
66	keyData, _ := ioutil.ReadFile("test/sample_key")
67	key, _ := jwt.ParseRSAPrivateKeyFromPEM(keyData)
68
69	for _, data := range rsaTestData {
70		if data.valid {
71			parts := strings.Split(data.tokenString, ".")
72			method := jwt.GetSigningMethod(data.alg)
73			sig, err := method.Sign(strings.Join(parts[0:2], "."), key)
74			if err != nil {
75				t.Errorf("[%v] Error signing token: %v", data.name, err)
76			}
77			if sig != parts[2] {
78				t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", data.name, sig, parts[2])
79			}
80		}
81	}
82}
83
84func TestRSAVerifyWithPreParsedPrivateKey(t *testing.T) {
85	key, _ := ioutil.ReadFile("test/sample_key.pub")
86	parsedKey, err := jwt.ParseRSAPublicKeyFromPEM(key)
87	if err != nil {
88		t.Fatal(err)
89	}
90	testData := rsaTestData[0]
91	parts := strings.Split(testData.tokenString, ".")
92	err = jwt.SigningMethodRS256.Verify(strings.Join(parts[0:2], "."), parts[2], parsedKey)
93	if err != nil {
94		t.Errorf("[%v] Error while verifying key: %v", testData.name, err)
95	}
96}
97
98func TestRSAWithPreParsedPrivateKey(t *testing.T) {
99	key, _ := ioutil.ReadFile("test/sample_key")
100	parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)
101	if err != nil {
102		t.Fatal(err)
103	}
104	testData := rsaTestData[0]
105	parts := strings.Split(testData.tokenString, ".")
106	sig, err := jwt.SigningMethodRS256.Sign(strings.Join(parts[0:2], "."), parsedKey)
107	if err != nil {
108		t.Errorf("[%v] Error signing token: %v", testData.name, err)
109	}
110	if sig != parts[2] {
111		t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", testData.name, sig, parts[2])
112	}
113}
114
115func TestRSAKeyParsing(t *testing.T) {
116	key, _ := ioutil.ReadFile("test/sample_key")
117	secureKey, _ := ioutil.ReadFile("test/privateSecure.pem")
118	pubKey, _ := ioutil.ReadFile("test/sample_key.pub")
119	badKey := []byte("All your base are belong to key")
120
121	// Test parsePrivateKey
122	if _, e := jwt.ParseRSAPrivateKeyFromPEM(key); e != nil {
123		t.Errorf("Failed to parse valid private key: %v", e)
124	}
125
126	if k, e := jwt.ParseRSAPrivateKeyFromPEM(pubKey); e == nil {
127		t.Errorf("Parsed public key as valid private key: %v", k)
128	}
129
130	if k, e := jwt.ParseRSAPrivateKeyFromPEM(badKey); e == nil {
131		t.Errorf("Parsed invalid key as valid private key: %v", k)
132	}
133
134	if _, e := jwt.ParseRSAPrivateKeyFromPEMWithPassword(secureKey, "password"); e != nil {
135		t.Errorf("Failed to parse valid private key with password: %v", e)
136	}
137
138	if k, e := jwt.ParseRSAPrivateKeyFromPEMWithPassword(secureKey, "123132"); e == nil {
139		t.Errorf("Parsed private key with invalid password %v", k)
140	}
141
142	// Test parsePublicKey
143	if _, e := jwt.ParseRSAPublicKeyFromPEM(pubKey); e != nil {
144		t.Errorf("Failed to parse valid public key: %v", e)
145	}
146
147	if k, e := jwt.ParseRSAPublicKeyFromPEM(key); e == nil {
148		t.Errorf("Parsed private key as valid public key: %v", k)
149	}
150
151	if k, e := jwt.ParseRSAPublicKeyFromPEM(badKey); e == nil {
152		t.Errorf("Parsed invalid key as valid private key: %v", k)
153	}
154
155}
156
157func BenchmarkRS256Signing(b *testing.B) {
158	key, _ := ioutil.ReadFile("test/sample_key")
159	parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)
160	if err != nil {
161		b.Fatal(err)
162	}
163
164	benchmarkSigning(b, jwt.SigningMethodRS256, parsedKey)
165}
166
167func BenchmarkRS384Signing(b *testing.B) {
168	key, _ := ioutil.ReadFile("test/sample_key")
169	parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)
170	if err != nil {
171		b.Fatal(err)
172	}
173
174	benchmarkSigning(b, jwt.SigningMethodRS384, parsedKey)
175}
176
177func BenchmarkRS512Signing(b *testing.B) {
178	key, _ := ioutil.ReadFile("test/sample_key")
179	parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)
180	if err != nil {
181		b.Fatal(err)
182	}
183
184	benchmarkSigning(b, jwt.SigningMethodRS512, parsedKey)
185}
186