package jwt

import (
	
	
	
)

// SigningMethodRSA implements the RSA family of signing methods.
// Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation
type SigningMethodRSA struct {
	Name string
	Hash crypto.Hash
}

// Specific instances for RS256 and company
var (
	SigningMethodRS256 *SigningMethodRSA
	SigningMethodRS384 *SigningMethodRSA
	SigningMethodRS512 *SigningMethodRSA
)

func () {
	// 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 ( *SigningMethodRSA) () string {
	return .Name
}

// Verify implements token verification for the SigningMethod
// For this signing method, must be an *rsa.PublicKey structure.
func ( *SigningMethodRSA) ( string,  []byte,  interface{}) error {
	var  *rsa.PublicKey
	var  bool

	if ,  = .(*rsa.PublicKey); ! {
		return newError("RSA verify expects *rsa.PublicKey", ErrInvalidKeyType)
	}

	// Create hasher
	if !.Hash.Available() {
		return ErrHashUnavailable
	}
	 := .Hash.New()
	.Write([]byte())

	// Verify the signature
	return rsa.VerifyPKCS1v15(, .Hash, .Sum(nil), )
}

// Sign implements token signing for the SigningMethod
// For this signing method, must be an *rsa.PrivateKey structure.
func ( *SigningMethodRSA) ( string,  interface{}) ([]byte, error) {
	var  *rsa.PrivateKey
	var  bool

	// Validate type of key
	if ,  = .(*rsa.PrivateKey); ! {
		return nil, newError("RSA sign expects *rsa.PrivateKey", ErrInvalidKeyType)
	}

	// Create the hasher
	if !.Hash.Available() {
		return nil, ErrHashUnavailable
	}

	 := .Hash.New()
	.Write([]byte())

	// Sign the string and return the encoded bytes
	if ,  := rsa.SignPKCS1v15(rand.Reader, , .Hash, .Sum(nil));  == nil {
		return , nil
	} else {
		return nil, 
	}
}