Skip to content

Commit 53f63a7

Browse files
authored
Merge pull request #387 from adnanh/revert-355-master
Revert "Multiple Signature Support"
2 parents e72a7d2 + 8c5b2e0 commit 53f63a7

File tree

3 files changed

+36
-96
lines changed

3 files changed

+36
-96
lines changed

docs/Hook-Rules.md

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,6 @@ For the regex syntax, check out <http://golang.org/pkg/regexp/syntax/>
186186
}
187187
```
188188

189-
Note that if multiple signatures were passed via a comma separated string, each
190-
will be tried unless a match is found. For example:
191-
192-
```
193-
X-Hub-Signature: sha1=the-first-signature,sha1=the-second-signature
194-
```
195-
196189
### 4. Match payload-hash-sha256
197190
```json
198191
{
@@ -209,13 +202,6 @@ X-Hub-Signature: sha1=the-first-signature,sha1=the-second-signature
209202
}
210203
```
211204

212-
Note that if multiple signatures were passed via a comma separated string, each
213-
will be tried unless a match is found. For example:
214-
215-
```
216-
X-Hub-Signature: sha256=the-first-signature,sha256=the-second-signature
217-
```
218-
219205
### 5. Match payload-hash-sha512
220206
```json
221207
{
@@ -232,13 +218,6 @@ X-Hub-Signature: sha256=the-first-signature,sha256=the-second-signature
232218
}
233219
```
234220

235-
Note that if multiple signatures were passed via a comma separated string, each
236-
will be tried unless a match is found. For example:
237-
238-
```
239-
X-Hub-Signature: sha512=the-first-signature,sha512=the-second-signature
240-
```
241-
242221
### 6. Match Whitelisted IP range
243222

244223
The IP can be IPv4- or IPv6-formatted, using [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_blocks). To match a single IP address only, use `/32`.

hook/hook.go

Lines changed: 36 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"encoding/json"
1313
"errors"
1414
"fmt"
15-
"hash"
1615
"io/ioutil"
1716
"log"
1817
"math"
@@ -49,19 +48,13 @@ const (
4948

5049
// SignatureError describes an invalid payload signature passed to Hook.
5150
type SignatureError struct {
52-
Signature string
53-
Signatures []string
51+
Signature string
5452
}
5553

5654
func (e *SignatureError) Error() string {
5755
if e == nil {
5856
return "<nil>"
5957
}
60-
61-
if e.Signatures != nil {
62-
return fmt.Sprintf("invalid payload signatures %s", e.Signatures)
63-
}
64-
6558
return fmt.Sprintf("invalid payload signature %s", e.Signature)
6659
}
6760

@@ -101,67 +94,25 @@ func (e *ParseError) Error() string {
10194
return e.Err.Error()
10295
}
10396

104-
// ExtractCommaSeparatedValues will extract the values matching the key.
105-
func ExtractCommaSeparatedValues(source, prefix string) []string {
106-
parts := strings.Split(source, ",")
107-
values := make([]string, 0)
108-
for _, part := range parts {
109-
if strings.HasPrefix(part, prefix) {
110-
values = append(values, strings.TrimPrefix(part, prefix))
111-
}
112-
}
113-
114-
return values
115-
}
116-
117-
// ExtractSignatures will extract all the signatures from the source.
118-
func ExtractSignatures(source, prefix string) []string {
119-
// If there are multiple possible matches, let the comma seperated extractor
120-
// do it's work.
121-
if strings.Contains(source, ",") {
122-
return ExtractCommaSeparatedValues(source, prefix)
97+
// CheckPayloadSignature calculates and verifies SHA1 signature of the given payload
98+
func CheckPayloadSignature(payload []byte, secret string, signature string) (string, error) {
99+
if secret == "" {
100+
return "", errors.New("signature validation secret can not be empty")
123101
}
124102

125-
// There were no commas, so just trim the prefix (if it even exists) and
126-
// pass it back.
127-
return []string{
128-
strings.TrimPrefix(source, prefix),
129-
}
130-
}
103+
signature = strings.TrimPrefix(signature, "sha1=")
131104

132-
// ValidateMAC will verify that the expected mac for the given hash will match
133-
// the one provided.
134-
func ValidateMAC(payload []byte, mac hash.Hash, signatures []string) (string, error) {
135-
// Write the payload to the provided hash.
105+
mac := hmac.New(sha1.New, []byte(secret))
136106
_, err := mac.Write(payload)
137107
if err != nil {
138108
return "", err
139109
}
140-
141110
expectedMAC := hex.EncodeToString(mac.Sum(nil))
142111

143-
for _, signature := range signatures {
144-
if hmac.Equal([]byte(signature), []byte(expectedMAC)) {
145-
return expectedMAC, err
146-
}
147-
}
148-
149-
return expectedMAC, &SignatureError{
150-
Signatures: signatures,
112+
if !hmac.Equal([]byte(signature), []byte(expectedMAC)) {
113+
return expectedMAC, &SignatureError{signature}
151114
}
152-
}
153-
154-
// CheckPayloadSignature calculates and verifies SHA1 signature of the given payload
155-
func CheckPayloadSignature(payload []byte, secret string, signature string) (string, error) {
156-
if secret == "" {
157-
return "", errors.New("signature validation secret can not be empty")
158-
}
159-
160-
// Extract the signatures.
161-
signatures := ExtractSignatures(signature, "sha1=")
162-
163-
// Validate the MAC.
164-
return ValidateMAC(payload, hmac.New(sha1.New, []byte(secret)), signatures)
115+
return expectedMAC, err
165116
}
166117

167118
// CheckPayloadSignature256 calculates and verifies SHA256 signature of the given payload
@@ -170,11 +121,19 @@ func CheckPayloadSignature256(payload []byte, secret string, signature string) (
170121
return "", errors.New("signature validation secret can not be empty")
171122
}
172123

173-
// Extract the signatures.
174-
signatures := ExtractSignatures(signature, "sha256=")
124+
signature = strings.TrimPrefix(signature, "sha256=")
125+
126+
mac := hmac.New(sha256.New, []byte(secret))
127+
_, err := mac.Write(payload)
128+
if err != nil {
129+
return "", err
130+
}
131+
expectedMAC := hex.EncodeToString(mac.Sum(nil))
175132

176-
// Validate the MAC.
177-
return ValidateMAC(payload, hmac.New(sha256.New, []byte(secret)), signatures)
133+
if !hmac.Equal([]byte(signature), []byte(expectedMAC)) {
134+
return expectedMAC, &SignatureError{signature}
135+
}
136+
return expectedMAC, err
178137
}
179138

180139
// CheckPayloadSignature512 calculates and verifies SHA512 signature of the given payload
@@ -183,11 +142,19 @@ func CheckPayloadSignature512(payload []byte, secret string, signature string) (
183142
return "", errors.New("signature validation secret can not be empty")
184143
}
185144

186-
// Extract the signatures.
187-
signatures := ExtractSignatures(signature, "sha512=")
145+
signature = strings.TrimPrefix(signature, "sha512=")
146+
147+
mac := hmac.New(sha512.New, []byte(secret))
148+
_, err := mac.Write(payload)
149+
if err != nil {
150+
return "", err
151+
}
152+
expectedMAC := hex.EncodeToString(mac.Sum(nil))
188153

189-
// Validate the MAC.
190-
return ValidateMAC(payload, hmac.New(sha512.New, []byte(secret)), signatures)
154+
if !hmac.Equal([]byte(signature), []byte(expectedMAC)) {
155+
return expectedMAC, &SignatureError{signature}
156+
}
157+
return expectedMAC, err
191158
}
192159

193160
func CheckScalrSignature(headers map[string]interface{}, body []byte, signingKey string, checkDate bool) (bool, error) {
@@ -210,7 +177,7 @@ func CheckScalrSignature(headers map[string]interface{}, body []byte, signingKey
210177
expectedSignature := hex.EncodeToString(mac.Sum(nil))
211178

212179
if !hmac.Equal([]byte(providedSignature), []byte(expectedSignature)) {
213-
return false, &SignatureError{Signature: providedSignature}
180+
return false, &SignatureError{providedSignature}
214181
}
215182

216183
if !checkDate {
@@ -225,7 +192,7 @@ func CheckScalrSignature(headers map[string]interface{}, body []byte, signingKey
225192
delta := math.Abs(now.Sub(date).Seconds())
226193

227194
if delta > 300 {
228-
return false, &SignatureError{Signature: "outdated"}
195+
return false, &SignatureError{"outdated"}
229196
}
230197
return true, nil
231198
}

hook/hook_test.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,8 @@ var checkPayloadSignatureTests = []struct {
4848
}{
4949
{[]byte(`{"a": "z"}`), "secret", "b17e04cbb22afa8ffbff8796fc1894ed27badd9e", "b17e04cbb22afa8ffbff8796fc1894ed27badd9e", true},
5050
{[]byte(`{"a": "z"}`), "secret", "sha1=b17e04cbb22afa8ffbff8796fc1894ed27badd9e", "b17e04cbb22afa8ffbff8796fc1894ed27badd9e", true},
51-
{[]byte(`{"a": "z"}`), "secret", "sha1=XXXe04cbb22afa8ffbff8796fc1894ed27badd9e,sha1=b17e04cbb22afa8ffbff8796fc1894ed27badd9e", "b17e04cbb22afa8ffbff8796fc1894ed27badd9e", true},
5251
// failures
5352
{[]byte(`{"a": "z"}`), "secret", "XXXe04cbb22afa8ffbff8796fc1894ed27badd9e", "b17e04cbb22afa8ffbff8796fc1894ed27badd9e", false},
54-
{[]byte(`{"a": "z"}`), "secret", "sha1=XXXe04cbb22afa8ffbff8796fc1894ed27badd9e", "b17e04cbb22afa8ffbff8796fc1894ed27badd9e", false},
55-
{[]byte(`{"a": "z"}`), "secret", "sha1=XXXe04cbb22afa8ffbff8796fc1894ed27badd9e,sha1=XXXe04cbb22afa8ffbff8796fc1894ed27badd9e", "b17e04cbb22afa8ffbff8796fc1894ed27badd9e", false},
5653
{[]byte(`{"a": "z"}`), "secreX", "b17e04cbb22afa8ffbff8796fc1894ed27badd9e", "900225703e9342328db7307692736e2f7cc7b36e", false},
5754
{[]byte(`{"a": "z"}`), "", "b17e04cbb22afa8ffbff8796fc1894ed27badd9e", "", false},
5855
}
@@ -79,11 +76,8 @@ var checkPayloadSignature256Tests = []struct {
7976
}{
8077
{[]byte(`{"a": "z"}`), "secret", "f417af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", "f417af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", true},
8178
{[]byte(`{"a": "z"}`), "secret", "sha256=f417af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", "f417af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", true},
82-
{[]byte(`{"a": "z"}`), "secret", "sha256=XXX7af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89,sha256=f417af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", "f417af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", true},
8379
// failures
8480
{[]byte(`{"a": "z"}`), "secret", "XXX7af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", "f417af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", false},
85-
{[]byte(`{"a": "z"}`), "secret", "sha256=XXX7af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", "f417af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", false},
86-
{[]byte(`{"a": "z"}`), "secret", "sha256=XXX7af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89,sha256=XXX7af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", "f417af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", false},
8781
{[]byte(`{"a": "z"}`), "", "XXX7af3a21bd70379b5796d5f013915e7029f62c580fb0f500f59a35a6f04c89", "", false},
8882
}
8983

0 commit comments

Comments
 (0)