this repo has no description
1package knotserver 2 3import ( 4 "crypto/hmac" 5 "crypto/sha256" 6 "encoding/hex" 7 "net/http" 8 "time" 9) 10 11func (h *Handle) VerifySignature(next http.Handler) http.Handler { 12 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 13 signature := r.Header.Get("X-Signature") 14 if signature == "" || !h.verifyHMAC(signature, r) { 15 writeError(w, "signature verification failed", http.StatusForbidden) 16 return 17 } 18 next.ServeHTTP(w, r) 19 }) 20} 21 22func (h *Handle) verifyHMAC(signature string, r *http.Request) bool { 23 secret := h.c.Secret 24 timestamp := r.Header.Get("X-Timestamp") 25 if timestamp == "" { 26 return false 27 } 28 29 // Verify that the timestamp is not older than a minute 30 reqTime, err := time.Parse(time.RFC3339, timestamp) 31 if err != nil { 32 return false 33 } 34 if time.Since(reqTime) > time.Minute { 35 return false 36 } 37 38 message := r.Method + r.URL.Path + timestamp 39 40 mac := hmac.New(sha256.New, []byte(secret)) 41 mac.Write([]byte(message)) 42 expectedMAC := mac.Sum(nil) 43 44 signatureBytes, err := hex.DecodeString(signature) 45 if err != nil { 46 return false 47 } 48 49 return hmac.Equal(signatureBytes, expectedMAC) 50}