forked from mirror/jwt
Added support for RS384 and RS512 signing methods
Renamed type SigningMethodRS256 to SigningMethodRSA Added contstants SigningMethodRS256, SigningMethodRS384, and SigningMethodRS512 to support each of these methods Added simple tests to support these new methods
This commit is contained in:
parent
97430c0b8b
commit
629af62465
52
rsa.go
52
rsa.go
|
@ -4,25 +4,47 @@ import (
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/sha256"
|
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SigningMethodRS256 struct{}
|
type SigningMethodRSA struct {
|
||||||
|
Name string
|
||||||
|
Hash crypto.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
SigningMethodRS256 *SigningMethodRSA
|
||||||
|
SigningMethodRS384 *SigningMethodRSA
|
||||||
|
SigningMethodRS512 *SigningMethodRSA
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
RegisterSigningMethod("RS256", func() SigningMethod {
|
// RS256
|
||||||
return new(SigningMethodRS256)
|
SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256}
|
||||||
|
RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodRS256
|
||||||
|
})
|
||||||
|
|
||||||
|
// RS384
|
||||||
|
SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384}
|
||||||
|
RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodRS384
|
||||||
|
})
|
||||||
|
|
||||||
|
// RS512
|
||||||
|
SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512}
|
||||||
|
RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod {
|
||||||
|
return SigningMethodRS512
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SigningMethodRS256) Alg() string {
|
func (m *SigningMethodRSA) Alg() string {
|
||||||
return "RS256"
|
return m.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SigningMethodRS256) Verify(signingString, signature string, key []byte) error {
|
func (m *SigningMethodRSA) Verify(signingString, signature string, key []byte) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// Decode the signature
|
// Decode the signature
|
||||||
|
@ -38,30 +60,30 @@ func (m *SigningMethodRS256) Verify(signingString, signature string, key []byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create hasher
|
// Create hasher
|
||||||
hasher := sha256.New()
|
hasher := m.Hash.New()
|
||||||
hasher.Write([]byte(signingString))
|
hasher.Write([]byte(signingString))
|
||||||
|
|
||||||
// Verify the signature
|
// Verify the signature
|
||||||
return rsa.VerifyPKCS1v15(rsaKey, crypto.SHA256, hasher.Sum(nil), sig)
|
return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements the Sign method from SigningMethod
|
// Implements the Sign method from SigningMethod
|
||||||
// For this signing method, must be PEM encoded PKCS1 or PKCS8 RSA private key
|
// For this signing method, must be PEM encoded PKCS1 or PKCS8 RSA private key
|
||||||
func (m *SigningMethodRS256) Sign(signingString string, key []byte) (string, error) {
|
func (m *SigningMethodRSA) Sign(signingString string, key []byte) (string, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// Key
|
// Parse private key
|
||||||
var rsaKey *rsa.PrivateKey
|
var rsaKey *rsa.PrivateKey
|
||||||
if rsaKey, err = m.parsePrivateKey(key); err != nil {
|
if rsaKey, err = m.parsePrivateKey(key); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the hasher
|
// Create the hasher
|
||||||
hasher := sha256.New()
|
hasher := m.Hash.New()
|
||||||
hasher.Write([]byte(signingString))
|
hasher.Write([]byte(signingString))
|
||||||
|
|
||||||
// Sign the string and return the encoded bytes
|
// Sign the string and return the encoded bytes
|
||||||
if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, crypto.SHA256, hasher.Sum(nil)); err == nil {
|
if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil {
|
||||||
return EncodeSegment(sigBytes), nil
|
return EncodeSegment(sigBytes), nil
|
||||||
} else {
|
} else {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -70,7 +92,7 @@ func (m *SigningMethodRS256) Sign(signingString string, key []byte) (string, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse PEM encoded PKCS1 or PKCS8 public key
|
// Parse PEM encoded PKCS1 or PKCS8 public key
|
||||||
func (m *SigningMethodRS256) parsePublicKey(key []byte) (*rsa.PublicKey, error) {
|
func (m *SigningMethodRSA) parsePublicKey(key []byte) (*rsa.PublicKey, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// Parse PEM block
|
// Parse PEM block
|
||||||
|
@ -99,7 +121,7 @@ func (m *SigningMethodRS256) parsePublicKey(key []byte) (*rsa.PublicKey, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse PEM encoded PKCS1 or PKCS8 private key
|
// Parse PEM encoded PKCS1 or PKCS8 private key
|
||||||
func (m *SigningMethodRS256) parsePrivateKey(key []byte) (*rsa.PrivateKey, error) {
|
func (m *SigningMethodRSA) parsePrivateKey(key []byte) (*rsa.PrivateKey, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// Parse PEM block
|
// Parse PEM block
|
||||||
|
|
18
rsa_test.go
18
rsa_test.go
|
@ -14,12 +14,26 @@ var rsaTestData = []struct {
|
||||||
valid bool
|
valid bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"basic: foo => bar",
|
"Basic RS256",
|
||||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
||||||
"RS256",
|
"RS256",
|
||||||
map[string]interface{}{"foo": "bar"},
|
map[string]interface{}{"foo": "bar"},
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"Basic RS384",
|
||||||
|
"eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.W-jEzRfBigtCWsinvVVuldiuilzVdU5ty0MvpLaSaqK9PlAWWlDQ1VIQ_qSKzwL5IXaZkvZFJXT3yL3n7OUVu7zCNJzdwznbC8Z-b0z2lYvcklJYi2VOFRcGbJtXUqgjk2oGsiqUMUMOLP70TTefkpsgqDxbRh9CDUfpOJgW-dU7cmgaoswe3wjUAUi6B6G2YEaiuXC0XScQYSYVKIzgKXJV8Zw-7AN_DBUI4GkTpsvQ9fVVjZM9csQiEXhYekyrKu1nu_POpQonGd8yqkIyXPECNmmqH5jH4sFiF67XhD7_JpkvLziBpI-uh86evBUadmHhb9Otqw3uV3NTaXLzJw",
|
||||||
|
"RS384",
|
||||||
|
map[string]interface{}{"foo": "bar"},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Basic RS512",
|
||||||
|
"eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.zBlLlmRrUxx4SJPUbV37Q1joRcI9EW13grnKduK3wtYKmDXbgDpF1cZ6B-2Jsm5RB8REmMiLpGms-EjXhgnyh2TSHE-9W2gA_jvshegLWtwRVDX40ODSkTb7OVuaWgiy9y7llvcknFBTIg-FnVPVpXMmeV_pvwQyhaz1SSwSPrDyxEmksz1hq7YONXhXPpGaNbMMeDTNP_1oj8DZaqTIL9TwV8_1wb2Odt_Fy58Ke2RVFijsOLdnyEAjt2n9Mxihu9i3PhNBkkxa2GbnXBfq3kzvZ_xxGGopLdHhJjcGWXO-NiwI9_tiu14NRv4L2xC0ItD9Yz68v2ZIZEp_DuzwRQ",
|
||||||
|
"RS512",
|
||||||
|
map[string]interface{}{"foo": "bar"},
|
||||||
|
true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"basic invalid: foo => bar",
|
"basic invalid: foo => bar",
|
||||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
|
||||||
|
@ -68,7 +82,7 @@ func TestRSAKeyParsing(t *testing.T) {
|
||||||
key, _ := ioutil.ReadFile("test/sample_key")
|
key, _ := ioutil.ReadFile("test/sample_key")
|
||||||
pubKey, _ := ioutil.ReadFile("test/sample_key.pub")
|
pubKey, _ := ioutil.ReadFile("test/sample_key.pub")
|
||||||
badKey := []byte("All your base are belong to key")
|
badKey := []byte("All your base are belong to key")
|
||||||
method := GetSigningMethod("RS256").(*SigningMethodRS256)
|
method := GetSigningMethod("RS256").(*SigningMethodRSA)
|
||||||
|
|
||||||
if _, e := method.parsePrivateKey(key); e != nil {
|
if _, e := method.parsePrivateKey(key); e != nil {
|
||||||
t.Errorf("Failed to parse valid private key: %v", e)
|
t.Errorf("Failed to parse valid private key: %v", e)
|
||||||
|
|
Loading…
Reference in New Issue