github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/appengine/login/googlesignin/jwt-go/rsa.go (about)

     1  package jwt
     2  
     3  import (
     4  	"crypto"
     5  	"crypto/rand"
     6  	"crypto/rsa"
     7  )
     8  
     9  // Implements the RSA family of signing methods signing methods
    10  type SigningMethodRSA struct {
    11  	Name string
    12  	Hash crypto.Hash
    13  }
    14  
    15  // Specific instances for RS256 and company
    16  var (
    17  	SigningMethodRS256 *SigningMethodRSA
    18  	SigningMethodRS384 *SigningMethodRSA
    19  	SigningMethodRS512 *SigningMethodRSA
    20  )
    21  
    22  func init() {
    23  	// RS256
    24  	SigningMethodRS256 = &SigningMethodRSA{"RS256", crypto.SHA256}
    25  	RegisterSigningMethod(SigningMethodRS256.Alg(), func() SigningMethod {
    26  		return SigningMethodRS256
    27  	})
    28  
    29  	// RS384
    30  	SigningMethodRS384 = &SigningMethodRSA{"RS384", crypto.SHA384}
    31  	RegisterSigningMethod(SigningMethodRS384.Alg(), func() SigningMethod {
    32  		return SigningMethodRS384
    33  	})
    34  
    35  	// RS512
    36  	SigningMethodRS512 = &SigningMethodRSA{"RS512", crypto.SHA512}
    37  	RegisterSigningMethod(SigningMethodRS512.Alg(), func() SigningMethod {
    38  		return SigningMethodRS512
    39  	})
    40  }
    41  
    42  func (m *SigningMethodRSA) Alg() string {
    43  	return m.Name
    44  }
    45  
    46  // Implements the Verify method from SigningMethod
    47  // For this signing method, must be either a PEM encoded PKCS1 or PKCS8 RSA public key as
    48  // []byte, or an rsa.PublicKey structure.
    49  func (m *SigningMethodRSA) Verify(signingString, signature string, key interface{}) error {
    50  	var err error
    51  
    52  	// Decode the signature
    53  	var sig []byte
    54  	if sig, err = DecodeSegment(signature); err != nil {
    55  		return err
    56  	}
    57  
    58  	var rsaKey *rsa.PublicKey
    59  
    60  	switch k := key.(type) {
    61  	case string:
    62  		if rsaKey, err = ParseRSAPublicKeyFromPEM([]byte(k)); err != nil {
    63  			return err
    64  		}
    65  	case []byte:
    66  		if rsaKey, err = ParseRSAPublicKeyFromPEM(k); err != nil {
    67  			return err
    68  		}
    69  	case *rsa.PublicKey:
    70  		rsaKey = k
    71  	default:
    72  		return ErrInvalidKey
    73  	}
    74  
    75  	// Create hasher
    76  	if !m.Hash.Available() {
    77  		return ErrHashUnavailable
    78  	}
    79  	hasher := m.Hash.New()
    80  	hasher.Write([]byte(signingString))
    81  
    82  	// Verify the signature
    83  	return rsa.VerifyPKCS1v15(rsaKey, m.Hash, hasher.Sum(nil), sig)
    84  }
    85  
    86  // Implements the Sign method from SigningMethod
    87  // For this signing method, must be either a PEM encoded PKCS1 or PKCS8 RSA private key as
    88  // []byte, or an rsa.PrivateKey structure.
    89  func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) {
    90  	var err error
    91  	var rsaKey *rsa.PrivateKey
    92  
    93  	switch k := key.(type) {
    94  	case []byte:
    95  		if rsaKey, err = ParseRSAPrivateKeyFromPEM(k); err != nil {
    96  			return "", err
    97  		}
    98  	case *rsa.PrivateKey:
    99  		rsaKey = k
   100  	default:
   101  		return "", ErrInvalidKey
   102  	}
   103  
   104  	// Create the hasher
   105  	if !m.Hash.Available() {
   106  		return "", ErrHashUnavailable
   107  	}
   108  
   109  	hasher := m.Hash.New()
   110  	hasher.Write([]byte(signingString))
   111  
   112  	// Sign the string and return the encoded bytes
   113  	if sigBytes, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil)); err == nil {
   114  		return EncodeSegment(sigBytes), nil
   115  	} else {
   116  		return "", err
   117  	}
   118  }