forked from tangled.org/core
this repo has no description
at master 1.2 kB view raw
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 if h.c.Server.Dev { 13 return next 14 } 15 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 16 signature := r.Header.Get("X-Signature") 17 if signature == "" || !h.verifyHMAC(signature, r) { 18 writeError(w, "signature verification failed", http.StatusForbidden) 19 return 20 } 21 next.ServeHTTP(w, r) 22 }) 23} 24 25func (h *Handle) verifyHMAC(signature string, r *http.Request) bool { 26 secret := h.c.Server.Secret 27 timestamp := r.Header.Get("X-Timestamp") 28 if timestamp == "" { 29 return false 30 } 31 32 // Verify that the timestamp is not older than a minute 33 reqTime, err := time.Parse(time.RFC3339, timestamp) 34 if err != nil { 35 return false 36 } 37 if time.Since(reqTime) > time.Minute { 38 return false 39 } 40 41 message := r.Method + r.URL.Path + timestamp 42 43 mac := hmac.New(sha256.New, []byte(secret)) 44 mac.Write([]byte(message)) 45 expectedMAC := mac.Sum(nil) 46 47 signatureBytes, err := hex.DecodeString(signature) 48 if err != nil { 49 return false 50 } 51 52 return hmac.Equal(signatureBytes, expectedMAC) 53}