Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hmac Verify and Sign should allow key to be of type string #245

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 24 additions & 12 deletions hmac.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ func (m *SigningMethodHMAC) Alg() string {
// Verify implements token verification for the SigningMethod. 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
keyBytes, err := m.keyBytesFrom(key)
if err != nil {
return err
}

// Decode signature, for comparison
Expand Down Expand Up @@ -80,16 +80,28 @@ func (m *SigningMethodHMAC) Verify(signingString, signature string, key interfac
// Sign implements token signing for the SigningMethod.
// Key must be []byte
func (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))
keyBytes, err := m.keyBytesFrom(key)
if err != nil {
return "", err
}

return EncodeSegment(hasher.Sum(nil)), nil
if !m.Hash.Available() {
return "", ErrHashUnavailable
}

return "", ErrInvalidKeyType
hasher := hmac.New(m.Hash.New, keyBytes)
hasher.Write([]byte(signingString))

return EncodeSegment(hasher.Sum(nil)), nil
}

func (m *SigningMethodHMAC) keyBytesFrom(value interface{}) ([]byte, error) {
switch v := value.(type) {
case []byte:
return v, nil
case string:
return []byte(v), nil
default:
return nil, ErrInvalidKeyType
}
}
30 changes: 18 additions & 12 deletions hmac_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,21 @@ var hmacTestData = []struct {
// Sample data from http://tools.ietf.org/html/draft-jones-json-web-signature-04#appendix-A.1
var hmacTestKey, _ = os.ReadFile("test/hmacTestKey")

var hmacTestKeyString = string(hmacTestKey)

func TestHMACVerify(t *testing.T) {
for _, data := range hmacTestData {
parts := strings.Split(data.tokenString, ".")

method := jwt.GetSigningMethod(data.alg)
err := method.Verify(strings.Join(parts[0:2], "."), parts[2], hmacTestKey)
if data.valid && err != nil {
t.Errorf("[%v] Error while verifying key: %v", data.name, err)
}
if !data.valid && err == nil {
t.Errorf("[%v] Invalid key passed validation", data.name)
for _, hmacTestKey := range []interface{}{hmacTestKey, hmacTestKeyString} {
err := method.Verify(strings.Join(parts[0:2], "."), parts[2], hmacTestKey)
if data.valid && err != nil {
t.Errorf("[%v] Error while verifying key: %v", data.name, err)
}
if !data.valid && err == nil {
t.Errorf("[%v] Invalid key passed validation", data.name)
}
}
}
}
Expand All @@ -68,12 +72,14 @@ func TestHMACSign(t *testing.T) {
if data.valid {
parts := strings.Split(data.tokenString, ".")
method := jwt.GetSigningMethod(data.alg)
sig, err := method.Sign(strings.Join(parts[0:2], "."), hmacTestKey)
if err != nil {
t.Errorf("[%v] Error signing token: %v", data.name, err)
}
if sig != parts[2] {
t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", data.name, sig, parts[2])
for _, hmacTestKey := range []interface{}{hmacTestKey, hmacTestKeyString} {
sig, err := method.Sign(strings.Join(parts[0:2], "."), hmacTestKey)
if err != nil {
t.Errorf("[%v] Error signing token: %v", data.name, err)
}
if sig != parts[2] {
t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", data.name, sig, parts[2])
}
}
}
}
Expand Down