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