rsa.go raw

   1  package jwt
   2  
   3  import (
   4  	"crypto"
   5  	"crypto/rand"
   6  	"crypto/rsa"
   7  )
   8  
   9  // SigningMethodRSA implements the RSA family of signing methods.
  10  // Expects *rsa.PrivateKey for signing and *rsa.PublicKey for validation
  11  type SigningMethodRSA struct {
  12  	Name string
  13  	Hash crypto.Hash
  14  }
  15  
  16  // Specific instances for RS256 and company
  17  var (
  18  	SigningMethodRS256 *SigningMethodRSA
  19  	SigningMethodRS384 *SigningMethodRSA
  20  	SigningMethodRS512 *SigningMethodRSA
  21  )
  22  
  23  func init() {
  24  	// RS256
  25  	SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256}
  26  	RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod {
  27  		return SigningMethodRS256
  28  	})
  29  
  30  	// RS384
  31  	SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384}
  32  	RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod {
  33  		return SigningMethodRS384
  34  	})
  35  
  36  	// RS512
  37  	SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512}
  38  	RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod {
  39  		return SigningMethodRS512
  40  	})
  41  }
  42  
  43  func (m *SigningMethodRSA) Alg() string {
  44  	return m.Name
  45  }
  46  
  47  // Verify implements token verification for the SigningMethod
  48  // For this signing method, must be an *rsa.PublicKey structure.
  49  func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key any) error {
  50  	var rsaKey *rsa.PublicKey
  51  	var ok bool
  52  
  53  	if rsaKey, ok = key.(*rsa.PublicKey); !ok {
  54  		return newError("RSA verify expects *rsa.PublicKey", ErrInvalidKeyType)
  55  	}
  56  
  57  	// Create hasher
  58  	if !m.Hash.Available() {
  59  		return ErrHashUnavailable
  60  	}
  61  	hasher := m.Hash.New()
  62  	hasher.Write([]byte(signingString))
  63  
  64  	// Verify the signature
  65  	return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig)
  66  }
  67  
  68  // Sign implements token signing for the SigningMethod
  69  // For this signing method, must be an *rsa.PrivateKey structure.
  70  func (m *SigningMethodRSA) Sign(signingString string, key any) ([]byte, error) {
  71  	var rsaKey *rsa.PrivateKey
  72  	var ok bool
  73  
  74  	// Validate type of key
  75  	if rsaKey, ok = key.(*rsa.PrivateKey); !ok {
  76  		return nil, newError("RSA sign expects *rsa.PrivateKey", ErrInvalidKeyType)
  77  	}
  78  
  79  	// Create the hasher
  80  	if !m.Hash.Available() {
  81  		return nil, ErrHashUnavailable
  82  	}
  83  
  84  	hasher := m.Hash.New()
  85  	hasher.Write([]byte(signingString))
  86  
  87  	// Sign the string and return the encoded bytes
  88  	if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil {
  89  		return sigBytes, nil
  90  	} else {
  91  		return nil, err
  92  	}
  93  }
  94