this repo has no description

knotserver: implement signature verification

Changed files
+51 -21
knotserver
+12
knotserver/handler.go
··· 17 17 db: db, 18 18 } 19 19 20 + // r.Group(func(r chi.Router) { 21 + // r.Route("/settings", func(r chi.Router) { 22 + // r.Get("/keys", h.Keys) 23 + // r.Put("/keys", h.Keys) 24 + // }) 25 + // }) 26 + 20 27 r.Get("/", h.Index) 21 28 r.Route("/{did}", func(r chi.Router) { 22 29 // Repo routes ··· 42 49 43 50 r.Route("/repo", func(r chi.Router) { 44 51 r.Put("/new", h.NewRepo) 52 + }) 53 + 54 + r.Route("/internal", func(r chi.Router) { 55 + r.Use(h.VerifySignature) 56 + r.Get("/health", h.Health) 45 57 }) 46 58 47 59 return r, nil
+35
knotserver/middleware.go
··· 1 + package knotserver 2 + 3 + import ( 4 + "crypto/hmac" 5 + "crypto/sha256" 6 + "encoding/hex" 7 + "net/http" 8 + ) 9 + 10 + func (h *Handle) VerifySignature(next http.Handler) http.Handler { 11 + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 12 + signature := r.Header.Get("X-Signature") 13 + if signature == "" || !h.verifyHMAC(signature, r) { 14 + writeError(w, "signature verification failed", http.StatusForbidden) 15 + return 16 + } 17 + next.ServeHTTP(w, r) 18 + }) 19 + } 20 + 21 + func (h *Handle) verifyHMAC(signature string, r *http.Request) bool { 22 + secret := h.c.Secret 23 + message := r.Method + r.URL.Path + r.URL.RawQuery 24 + 25 + mac := hmac.New(sha256.New, []byte(secret)) 26 + mac.Write([]byte(message)) 27 + expectedMAC := mac.Sum(nil) 28 + 29 + signatureBytes, err := hex.DecodeString(signature) 30 + if err != nil { 31 + return false 32 + } 33 + 34 + return hmac.Equal(signatureBytes, expectedMAC) 35 + }
+4 -21
knotserver/routes.go
··· 358 358 // return 359 359 // } 360 360 361 - // // store in pds too 362 - // resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 363 - // Collection: "sh.bild.publicKey", 364 - // Repo: did, 365 - // Rkey: uuid.New().String(), 366 - // Record: &lexutil.LexiconTypeDecoder{Val: &shbild.PublicKey{ 367 - // Created: time.Now().String(), 368 - // Key: key, 369 - // Name: name, 370 - // }}, 371 - // }) 372 - 373 - // // invalid record 374 - // if err != nil { 375 - // h.WriteOOBNotice(w, "keys", "Invalid inputs. Check your formatting and try again.") 376 - // log.Printf("failed to create record: %s", err) 377 - // return 378 - // } 379 - 380 - // log.Println("created atproto record: ", resp.Uri) 381 - 382 361 // h.WriteOOBNotice(w, "keys", "Key added!") 383 362 // return 384 363 // } ··· 423 402 // return 424 403 // } 425 404 // } 405 + 406 + func (h *Handle) Health(w http.ResponseWriter, r *http.Request) { 407 + w.Write([]byte("ok")) 408 + }