pomerium/pkg/cryptutil/hmac.go
2021-04-07 14:57:24 -06:00

54 lines
1.4 KiB
Go

package cryptutil
import (
"crypto/hmac"
"crypto/sha512"
"errors"
"strconv"
"time"
)
const (
// DefaultLeeway defines the default leeway for matching NotBefore/Expiry claims.
DefaultLeeway = 5.0 * time.Minute
)
var (
errTimestampMalformed = errors.New("internal/cryptutil: timestamp malformed")
errTimestampExpired = errors.New("internal/cryptutil: timestamp expired")
errTimestampTooSoon = errors.New("internal/cryptutil: timestamp too soon")
)
// GenerateHMAC produces a symmetric signature using a shared secret key.
func GenerateHMAC(data, key []byte) []byte {
h := hmac.New(sha512.New512_256, key)
h.Write(data)
return h.Sum(nil)
}
// CheckHMAC securely checks the supplied MAC against a message using the
// shared secret key.
func CheckHMAC(data, suppliedMAC, key []byte) bool {
expectedMAC := GenerateHMAC(data, key)
return hmac.Equal(expectedMAC, suppliedMAC)
}
// ValidTimestamp is a helper function often used in conjunction with an HMAC
// function to verify that the timestamp (in unix seconds) is within leeway
// period.
func ValidTimestamp(ts string) error {
var timeStamp int64
var err error
if timeStamp, err = strconv.ParseInt(ts, 10, 64); err != nil {
return errTimestampMalformed
}
// unix time in seconds
tm := time.Unix(timeStamp, 0)
if time.Since(tm) > DefaultLeeway {
return errTimestampExpired
}
if time.Until(tm) > DefaultLeeway {
return errTimestampTooSoon
}
return nil
}