mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-07-30 23:08:46 +00:00
73 lines
1.9 KiB
Go
73 lines
1.9 KiB
Go
package bitbucketcloud
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha1" // nolint: gosec
|
|
"crypto/sha256"
|
|
"crypto/sha512"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"hash"
|
|
"strings"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// Attribution: This code is taken from https://github.com/google/go-github.
|
|
|
|
func ValidateSignature(payload []byte, signature string, secretKey []byte) error {
|
|
messageMAC, hashFunc, err := messageMAC(signature)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !checkMAC(payload, messageMAC, secretKey, hashFunc) {
|
|
return errors.New("payload signature check failed")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// genMAC generates the HMAC signature for a message provided the secret key
|
|
// and hashFunc.
|
|
func genMAC(message, key []byte, hashFunc func() hash.Hash) []byte {
|
|
mac := hmac.New(hashFunc, key)
|
|
// nolint: errcheck
|
|
mac.Write(message)
|
|
return mac.Sum(nil)
|
|
}
|
|
|
|
// checkMAC reports whether messageMAC is a valid HMAC tag for message.
|
|
func checkMAC(message, messageMAC, key []byte, hashFunc func() hash.Hash) bool {
|
|
expectedMAC := genMAC(message, key, hashFunc)
|
|
return hmac.Equal(messageMAC, expectedMAC)
|
|
}
|
|
|
|
// messageMAC returns the hex-decoded HMAC tag from the signature and its
|
|
// corresponding hash function.
|
|
func messageMAC(signature string) ([]byte, func() hash.Hash, error) {
|
|
if signature == "" {
|
|
return nil, nil, errors.New("missing signature")
|
|
}
|
|
sigParts := strings.SplitN(signature, "=", 2)
|
|
if len(sigParts) != 2 {
|
|
return nil, nil, fmt.Errorf("error parsing signature %q", signature)
|
|
}
|
|
|
|
var hashFunc func() hash.Hash
|
|
switch sigParts[0] {
|
|
case "sha1":
|
|
hashFunc = sha1.New
|
|
case "sha256":
|
|
hashFunc = sha256.New
|
|
case "sha512":
|
|
hashFunc = sha512.New
|
|
default:
|
|
return nil, nil, fmt.Errorf("unknown hash type prefix: %q", sigParts[0])
|
|
}
|
|
|
|
buf, err := hex.DecodeString(sigParts[1])
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("error decoding signature %q: %v", signature, err)
|
|
}
|
|
return buf, hashFunc, nil
|
|
}
|