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