...

Source file src/github.com/golang-jwt/jwt/v5/rsa_pss.go

Documentation: github.com/golang-jwt/jwt/v5

     1  //go:build go1.4
     2  // +build go1.4
     3  
     4  package jwt
     5  
     6  import (
     7  	"crypto"
     8  	"crypto/rand"
     9  	"crypto/rsa"
    10  )
    11  
    12  // SigningMethodRSAPSS implements the RSAPSS family of signing methods signing methods
    13  type SigningMethodRSAPSS struct {
    14  	*SigningMethodRSA
    15  	Options *rsa.PSSOptions
    16  	// VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS.
    17  	// Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow
    18  	// https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously.
    19  	// See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details.
    20  	VerifyOptions *rsa.PSSOptions
    21  }
    22  
    23  // Specific instances for RS/PS and company.
    24  var (
    25  	SigningMethodPS256 *SigningMethodRSAPSS
    26  	SigningMethodPS384 *SigningMethodRSAPSS
    27  	SigningMethodPS512 *SigningMethodRSAPSS
    28  )
    29  
    30  func init() {
    31  	// PS256
    32  	SigningMethodPS256 = &SigningMethodRSAPSS{
    33  		SigningMethodRSA: &SigningMethodRSA{
    34  			Name: "PS256",
    35  			Hash: crypto.SHA256,
    36  		},
    37  		Options: &rsa.PSSOptions{
    38  			SaltLength: rsa.PSSSaltLengthEqualsHash,
    39  		},
    40  		VerifyOptions: &rsa.PSSOptions{
    41  			SaltLength: rsa.PSSSaltLengthAuto,
    42  		},
    43  	}
    44  	RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod {
    45  		return SigningMethodPS256
    46  	})
    47  
    48  	// PS384
    49  	SigningMethodPS384 = &SigningMethodRSAPSS{
    50  		SigningMethodRSA: &SigningMethodRSA{
    51  			Name: "PS384",
    52  			Hash: crypto.SHA384,
    53  		},
    54  		Options: &rsa.PSSOptions{
    55  			SaltLength: rsa.PSSSaltLengthEqualsHash,
    56  		},
    57  		VerifyOptions: &rsa.PSSOptions{
    58  			SaltLength: rsa.PSSSaltLengthAuto,
    59  		},
    60  	}
    61  	RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod {
    62  		return SigningMethodPS384
    63  	})
    64  
    65  	// PS512
    66  	SigningMethodPS512 = &SigningMethodRSAPSS{
    67  		SigningMethodRSA: &SigningMethodRSA{
    68  			Name: "PS512",
    69  			Hash: crypto.SHA512,
    70  		},
    71  		Options: &rsa.PSSOptions{
    72  			SaltLength: rsa.PSSSaltLengthEqualsHash,
    73  		},
    74  		VerifyOptions: &rsa.PSSOptions{
    75  			SaltLength: rsa.PSSSaltLengthAuto,
    76  		},
    77  	}
    78  	RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod {
    79  		return SigningMethodPS512
    80  	})
    81  }
    82  
    83  // Verify implements token verification for the SigningMethod.
    84  // For this verify method, key must be an rsa.PublicKey struct
    85  func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key interface{}) error {
    86  	var rsaKey *rsa.PublicKey
    87  	switch k := key.(type) {
    88  	case *rsa.PublicKey:
    89  		rsaKey = k
    90  	default:
    91  		return newError("RSA-PSS verify expects *rsa.PublicKey", ErrInvalidKeyType)
    92  	}
    93  
    94  	// Create hasher
    95  	if !m.Hash.Available() {
    96  		return ErrHashUnavailable
    97  	}
    98  	hasher := m.Hash.New()
    99  	hasher.Write([]byte(signingString))
   100  
   101  	opts := m.Options
   102  	if m.VerifyOptions != nil {
   103  		opts = m.VerifyOptions
   104  	}
   105  
   106  	return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts)
   107  }
   108  
   109  // Sign implements token signing for the SigningMethod.
   110  // For this signing method, key must be an rsa.PrivateKey struct
   111  func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) ([]byte, error) {
   112  	var rsaKey *rsa.PrivateKey
   113  
   114  	switch k := key.(type) {
   115  	case *rsa.PrivateKey:
   116  		rsaKey = k
   117  	default:
   118  		return nil, newError("RSA-PSS sign expects *rsa.PrivateKey", ErrInvalidKeyType)
   119  	}
   120  
   121  	// Create the hasher
   122  	if !m.Hash.Available() {
   123  		return nil, ErrHashUnavailable
   124  	}
   125  
   126  	hasher := m.Hash.New()
   127  	hasher.Write([]byte(signingString))
   128  
   129  	// Sign the string and return the encoded bytes
   130  	if sigBytes, err := rsa.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil {
   131  		return sigBytes, nil
   132  	} else {
   133  		return nil, err
   134  	}
   135  }
   136  

View as plain text