2016-12-26 02:16:37 +01:00
package jwt
import (
"crypto"
"crypto/rand"
"crypto/rsa"
)
// Implements the RSA family of signing methods signing methods
2019-07-06 17:16:43 +02:00
// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation
2016-12-26 02:16:37 +01:00
type SigningMethodRSA struct {
Name string
Hash crypto . Hash
}
// Specific instances for RS256 and company
var (
SigningMethodRS256 * SigningMethodRSA
SigningMethodRS384 * SigningMethodRSA
SigningMethodRS512 * SigningMethodRSA
)
func init ( ) {
// 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 * SigningMethodRSA ) Alg ( ) string {
return m . Name
}
// Implements the Verify method from SigningMethod
2019-07-06 17:16:43 +02:00
// For this signing method, must be an *rsa.PublicKey structure.
2016-12-26 02:16:37 +01:00
func ( m * SigningMethodRSA ) Verify ( signingString , signature string , key interface { } ) error {
var err error
// Decode the signature
var sig [ ] byte
if sig , err = DecodeSegment ( signature ) ; err != nil {
return err
}
var rsaKey * rsa . PublicKey
var ok bool
if rsaKey , ok = key . ( * rsa . PublicKey ) ; ! ok {
return ErrInvalidKeyType
}
// Create hasher
if ! m . Hash . Available ( ) {
return ErrHashUnavailable
}
hasher := m . Hash . New ( )
hasher . Write ( [ ] byte ( signingString ) )
// Verify the signature
return rsa . VerifyPKCS1v15 ( rsaKey , m . Hash , hasher . Sum ( nil ) , sig )
}
// Implements the Sign method from SigningMethod
2019-07-06 17:16:43 +02:00
// For this signing method, must be an *rsa.PrivateKey structure.
2016-12-26 02:16:37 +01:00
func ( m * SigningMethodRSA ) Sign ( signingString string , key interface { } ) ( string , error ) {
var rsaKey * rsa . PrivateKey
var ok bool
// Validate type of key
if rsaKey , ok = key . ( * rsa . PrivateKey ) ; ! ok {
return "" , ErrInvalidKey
}
// Create the hasher
if ! m . Hash . Available ( ) {
return "" , ErrHashUnavailable
}
hasher := m . Hash . New ( )
hasher . Write ( [ ] byte ( signingString ) )
// Sign the string and return the encoded bytes
if sigBytes , err := rsa . SignPKCS1v15 ( rand . Reader , rsaKey , m . Hash , hasher . Sum ( nil ) ) ; err == nil {
return EncodeSegment ( sigBytes ) , nil
} else {
return "" , err
}
}