123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- //go:build go1.4
- // +build go1.4
-
- package jwt
-
- import (
- "crypto"
- "crypto/rand"
- "crypto/rsa"
- )
-
- // SigningMethodRSAPSS implements the RSAPSS family of signing methods signing methods
- type SigningMethodRSAPSS struct {
- *SigningMethodRSA
- Options *rsa.PSSOptions
- // VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS.
- // Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow
- // https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously.
- // See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details.
- VerifyOptions *rsa.PSSOptions
- }
-
- // Specific instances for RS/PS and company.
- var (
- SigningMethodPS256 *SigningMethodRSAPSS
- SigningMethodPS384 *SigningMethodRSAPSS
- SigningMethodPS512 *SigningMethodRSAPSS
- )
-
- func init() {
- // PS256
- SigningMethodPS256 = &SigningMethodRSAPSS{
- SigningMethodRSA: &SigningMethodRSA{
- Name: "PS256",
- Hash: crypto.SHA256,
- },
- Options: &rsa.PSSOptions{
- SaltLength: rsa.PSSSaltLengthEqualsHash,
- },
- VerifyOptions: &rsa.PSSOptions{
- SaltLength: rsa.PSSSaltLengthAuto,
- },
- }
- RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod {
- return SigningMethodPS256
- })
-
- // PS384
- SigningMethodPS384 = &SigningMethodRSAPSS{
- SigningMethodRSA: &SigningMethodRSA{
- Name: "PS384",
- Hash: crypto.SHA384,
- },
- Options: &rsa.PSSOptions{
- SaltLength: rsa.PSSSaltLengthEqualsHash,
- },
- VerifyOptions: &rsa.PSSOptions{
- SaltLength: rsa.PSSSaltLengthAuto,
- },
- }
- RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod {
- return SigningMethodPS384
- })
-
- // PS512
- SigningMethodPS512 = &SigningMethodRSAPSS{
- SigningMethodRSA: &SigningMethodRSA{
- Name: "PS512",
- Hash: crypto.SHA512,
- },
- Options: &rsa.PSSOptions{
- SaltLength: rsa.PSSSaltLengthEqualsHash,
- },
- VerifyOptions: &rsa.PSSOptions{
- SaltLength: rsa.PSSSaltLengthAuto,
- },
- }
- RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod {
- return SigningMethodPS512
- })
- }
-
- // Verify implements token verification for the SigningMethod.
- // For this verify method, key must be an rsa.PublicKey struct
- func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key interface{}) error {
- var rsaKey *rsa.PublicKey
- switch k := key.(type) {
- case *rsa.PublicKey:
- rsaKey = k
- default:
- return newError("RSA-PSS verify expects *rsa.PublicKey", ErrInvalidKeyType)
- }
-
- // Create hasher
- if !m.Hash.Available() {
- return ErrHashUnavailable
- }
- hasher := m.Hash.New()
- hasher.Write([]byte(signingString))
-
- opts := m.Options
- if m.VerifyOptions != nil {
- opts = m.VerifyOptions
- }
-
- return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts)
- }
-
- // Sign implements token signing for the SigningMethod.
- // For this signing method, key must be an rsa.PrivateKey struct
- func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) ([]byte, error) {
- var rsaKey *rsa.PrivateKey
-
- switch k := key.(type) {
- case *rsa.PrivateKey:
- rsaKey = k
- default:
- return nil, newError("RSA-PSS sign expects *rsa.PrivateKey", ErrInvalidKeyType)
- }
-
- // Create the hasher
- if !m.Hash.Available() {
- return nil, ErrHashUnavailable
- }
-
- hasher := m.Hash.New()
- hasher.Write([]byte(signingString))
-
- // Sign the string and return the encoded bytes
- if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil {
- return sigBytes, nil
- } else {
- return nil, err
- }
- }
|