| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 | package jwtimport (	"crypto"	"crypto/hmac"	"errors")// Implements the HMAC-SHA family of signing methods signing methods// Expects key type of []byte for both signing and validationtype SigningMethodHMAC struct {	Name string	Hash crypto.Hash}// Specific instances for HS256 and companyvar (	SigningMethodHS256  *SigningMethodHMAC	SigningMethodHS384  *SigningMethodHMAC	SigningMethodHS512  *SigningMethodHMAC	ErrSignatureInvalid = errors.New("signature is invalid"))func init() {	// HS256	SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256}	RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod {		return SigningMethodHS256	})	// HS384	SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384}	RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod {		return SigningMethodHS384	})	// HS512	SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512}	RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod {		return SigningMethodHS512	})}func (m *SigningMethodHMAC) Alg() string {	return m.Name}// Verify the signature of HSXXX tokens.  Returns nil if the signature is valid.func (m *SigningMethodHMAC) Verify(signingString, signature string, key interface{}) error {	// Verify the key is the right type	keyBytes, ok := key.([]byte)	if !ok {		return ErrInvalidKeyType	}	// Decode signature, for comparison	sig, err := DecodeSegment(signature)	if err != nil {		return err	}	// Can we use the specified hashing method?	if !m.Hash.Available() {		return ErrHashUnavailable	}	// This signing method is symmetric, so we validate the signature	// by reproducing the signature from the signing string and key, then	// comparing that against the provided signature.	hasher := hmac.New(m.Hash.New, keyBytes)	hasher.Write([]byte(signingString))	if !hmac.Equal(sig, hasher.Sum(nil)) {		return ErrSignatureInvalid	}	// No validation errors.  Signature is good.	return nil}// Implements the Sign method from SigningMethod for this signing method.// Key must be []bytefunc (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) {	if keyBytes, ok := key.([]byte); ok {		if !m.Hash.Available() {			return "", ErrHashUnavailable		}		hasher := hmac.New(m.Hash.New, keyBytes)		hasher.Write([]byte(signingString))		return EncodeSegment(hasher.Sum(nil)), nil	}	return "", ErrInvalidKeyType}
 |