From ffe36ca74a2fee81a085d24b6d20a606a2ae77bf Mon Sep 17 00:00:00 2001 From: Anirudh Oppiliappan Date: Fri, 31 Jan 2025 14:09:00 +0200 Subject: [PATCH] knotserver: implement signature verification --- knotserver/handler.go | 12 ++++++++++++ knotserver/middleware.go | 35 +++++++++++++++++++++++++++++++++++ knotserver/routes.go | 25 ++++--------------------- 3 files changed, 51 insertions(+), 21 deletions(-) create mode 100644 knotserver/middleware.go diff --git a/knotserver/handler.go b/knotserver/handler.go index 9c743a97..19e9f61d 100644 --- a/knotserver/handler.go +++ b/knotserver/handler.go @@ -17,6 +17,13 @@ func Setup(c *config.Config, db *db.DB) (http.Handler, error) { db: db, } + // r.Group(func(r chi.Router) { + // r.Route("/settings", func(r chi.Router) { + // r.Get("/keys", h.Keys) + // r.Put("/keys", h.Keys) + // }) + // }) + r.Get("/", h.Index) r.Route("/{did}", func(r chi.Router) { // Repo routes @@ -44,6 +51,11 @@ func Setup(c *config.Config, db *db.DB) (http.Handler, error) { r.Put("/new", h.NewRepo) }) + r.Route("/internal", func(r chi.Router) { + r.Use(h.VerifySignature) + r.Get("/health", h.Health) + }) + return r, nil } diff --git a/knotserver/middleware.go b/knotserver/middleware.go new file mode 100644 index 00000000..4494186c --- /dev/null +++ b/knotserver/middleware.go @@ -0,0 +1,35 @@ +package knotserver + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "net/http" +) + +func (h *Handle) VerifySignature(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + signature := r.Header.Get("X-Signature") + if signature == "" || !h.verifyHMAC(signature, r) { + writeError(w, "signature verification failed", http.StatusForbidden) + return + } + next.ServeHTTP(w, r) + }) +} + +func (h *Handle) verifyHMAC(signature string, r *http.Request) bool { + secret := h.c.Secret + message := r.Method + r.URL.Path + r.URL.RawQuery + + mac := hmac.New(sha256.New, []byte(secret)) + mac.Write([]byte(message)) + expectedMAC := mac.Sum(nil) + + signatureBytes, err := hex.DecodeString(signature) + if err != nil { + return false + } + + return hmac.Equal(signatureBytes, expectedMAC) +} diff --git a/knotserver/routes.go b/knotserver/routes.go index d4a39192..76cdedc9 100644 --- a/knotserver/routes.go +++ b/knotserver/routes.go @@ -358,27 +358,6 @@ func (h *Handle) Refs(w http.ResponseWriter, r *http.Request) { // return // } -// // store in pds too -// resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ -// Collection: "sh.bild.publicKey", -// Repo: did, -// Rkey: uuid.New().String(), -// Record: &lexutil.LexiconTypeDecoder{Val: &shbild.PublicKey{ -// Created: time.Now().String(), -// Key: key, -// Name: name, -// }}, -// }) - -// // invalid record -// if err != nil { -// h.WriteOOBNotice(w, "keys", "Invalid inputs. Check your formatting and try again.") -// log.Printf("failed to create record: %s", err) -// return -// } - -// log.Println("created atproto record: ", resp.Uri) - // h.WriteOOBNotice(w, "keys", "Key added!") // return // } @@ -423,3 +402,7 @@ func (h *Handle) NewRepo(w http.ResponseWriter, r *http.Request) { // return // } // } + +func (h *Handle) Health(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("ok")) +} -- knotmirror 0.0.1