1
1
package signature
2
2
3
+ /*
4
+ Package signature implements signature verification for MessageBird webhooks.
5
+
6
+ To use define a new validator using your MessageBird Signing key. You can use the
7
+ ValidRequest method, just pass the request as a parameter:
8
+
9
+ validator := signature.NewValidator("your signing key")
10
+ if err := validator.ValidRequest(r); err != nil {
11
+ // handle error
12
+ }
13
+
14
+ Or use the handler as a middleware for your server:
15
+
16
+ http.Handle("/path", validator.Validate(YourHandler))
17
+
18
+ It will reject the requests that contain invalid signatures.
19
+ The validator uses a 5ms seconds window to accept requests as valid, to change
20
+ this value, set the ValidityWindow to the disired duration.
21
+ Take into account that the validity window works around the current time:
22
+ [now - ValidityWindow/2, now + ValidityWindow/2]
23
+ */
24
+
3
25
import (
4
26
"bytes"
5
27
"crypto/hmac"
@@ -18,10 +40,10 @@ const (
18
40
sHeader = "MessageBird-Signature"
19
41
)
20
42
21
- // Window of acceptance for a request, if the time stamp is within this time, it will evaluated as valid
43
+ // ValidityWindow defines the time window in which to validate a request.
22
44
var ValidityWindow = 5 * time .Second
23
45
24
- // StringToTime converts from Unicod Epoch enconded timestamps to time.Time Go objects
46
+ // StringToTime converts from Unicod Epoch enconded timestamps to time.Time Go objects.
25
47
func stringToTime (s string ) (time.Time , error ) {
26
48
sec , err := strconv .ParseInt (s , 10 , 64 )
27
49
if err != nil {
@@ -31,7 +53,7 @@ func stringToTime(s string) (time.Time, error) {
31
53
}
32
54
33
55
// HMACSHA256 generates HMACS enconded hashes using the provided Key and SHA256
34
- // encoding for the message
56
+ // encoding for the message.
35
57
func hMACSHA256 (message , key []byte ) ([]byte , error ) {
36
58
mac := hmac .New (sha256 .New , []byte (key ))
37
59
if _ , err := mac .Write (message ); err != nil {
@@ -40,17 +62,15 @@ func hMACSHA256(message, key []byte) ([]byte, error) {
40
62
return mac .Sum (nil ), nil
41
63
}
42
64
43
- // Validator type represents a MessageBird signature validator
65
+ // Validator type represents a MessageBird signature validator.
44
66
type Validator struct {
45
- SigningKey string // Signing Key provided by MessageBird
46
- Period * time.Duration // Period for a message to be accepted as real, set no nil to bypass the time validator
47
- } // Five seconds by default
67
+ SigningKey string // Signing Key provided by MessageBird.
68
+ }
48
69
49
- // NewValidator returns a signature validator object
70
+ // NewValidator returns a signature validator object.
50
71
func NewValidator (signingKey string ) * Validator {
51
72
return & Validator {
52
73
SigningKey : signingKey ,
53
- Period : & ValidityWindow ,
54
74
}
55
75
}
56
76
@@ -61,12 +81,8 @@ func (v *Validator) validTimestamp(ts string) bool {
61
81
if err != nil {
62
82
return false
63
83
}
64
- if v .Period == nil {
65
- return true
66
- }
67
-
68
- diff := time .Now ().Add (* v .Period / 2 ).Sub (t )
69
- return diff < * v .Period && diff > 0
84
+ diff := time .Now ().Add (ValidityWindow / 2 ).Sub (t )
85
+ return diff < ValidityWindow && diff > 0
70
86
}
71
87
72
88
// calculateSignature calculates the MessageBird-Signature using HMAC_SHA_256
@@ -100,7 +116,7 @@ func (v *Validator) validSignature(ts, rqp string, b []byte, rs string) bool {
100
116
}
101
117
102
118
// ValidRequest is a method that takes care of the signature validation of
103
- // incoming requests
119
+ // incoming requests.
104
120
// To use just pass the request:
105
121
// signature.Validate(request)
106
122
func (v * Validator ) ValidRequest (r * http.Request ) error {
0 commit comments