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:
Dave Grijalva 2014-07-05 15:34:31 -07:00
parent 97430c0b8b
commit 629af62465
2 changed files with 53 additions and 17 deletions

52
rsa.go
View File

@ -4,25 +4,47 @@ import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"errors"
)
type SigningMethodRS256 struct{}
type SigningMethodRSA struct {
Name string
Hash crypto.Hash
}
var (
SigningMethodRS256 *SigningMethodRSA
SigningMethodRS384 *SigningMethodRSA
SigningMethodRS512 *SigningMethodRSA
)
func init() {
RegisterSigningMethod("RS256", func() SigningMethod {
return new(SigningMethodRS256)
// RS256
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 {
return "RS256"
func (m *SigningMethodRSA) Alg() string {
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
// Decode the signature
@ -38,30 +60,30 @@ func (m *SigningMethodRS256) Verify(signingString, signature string, key []byte)
}
// Create hasher
hasher := sha256.New()
hasher := m.Hash.New()
hasher.Write([]byte(signingString))
// 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
// 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
// Key
// Parse private key
var rsaKey *rsa.PrivateKey
if rsaKey, err = m.parsePrivateKey(key); err != nil {
return "", err
}
// Create the hasher
hasher := sha256.New()
hasher := m.Hash.New()
hasher.Write([]byte(signingString))
// 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
} else {
return "", err
@ -70,7 +92,7 @@ func (m *SigningMethodRS256) Sign(signingString string, key []byte) (string, err
}
// 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
// Parse PEM block
@ -99,7 +121,7 @@ func (m *SigningMethodRS256) parsePublicKey(key []byte) (*rsa.PublicKey, error)
}
// 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
// Parse PEM block

View File

@ -14,12 +14,26 @@ var rsaTestData = []struct {
valid bool
}{
{
"basic: foo => bar",
"Basic RS256",
"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
"RS256",
map[string]interface{}{"foo": "bar"},
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",
"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")
pubKey, _ := ioutil.ReadFile("test/sample_key.pub")
badKey := []byte("All your base are belong to key")
method := GetSigningMethod("RS256").(*SigningMethodRS256)
method := GetSigningMethod("RS256").(*SigningMethodRSA)
if _, e := method.parsePrivateKey(key); e != nil {
t.Errorf("Failed to parse valid private key: %v", e)