versia-go/pkg/lysand/crypto.go

62 lines
1.1 KiB
Go
Raw Normal View History

2024-08-11 03:51:22 +02:00
package lysand
import (
"bytes"
"crypto/ed25519"
"crypto/sha256"
"io"
"net/http"
)
func (c *FederationClient) ValidateSignatureHeader(req *http.Request) (bool, error) {
2024-08-15 19:22:17 +02:00
fedHeaders, err := ExtractFederationHeaders(req.Header)
2024-08-11 03:51:22 +02:00
if err != nil {
return false, err
}
// TODO: Fetch user from database instead of using the URI
2024-08-15 19:22:17 +02:00
user, err := c.GetUser(req.Context(), fedHeaders.SignedBy)
2024-08-11 03:51:22 +02:00
if err != nil {
return false, err
}
body, err := copyBody(req)
if err != nil {
return false, err
}
v := Verifier{ed25519.PublicKey(user.PublicKey.PublicKey)}
2024-08-15 19:22:17 +02:00
valid := v.Verify(req.Method, req.URL, body, fedHeaders)
2024-08-11 03:51:22 +02:00
return valid, nil
}
func hashSHA256(data []byte) []byte {
h := sha256.New()
h.Write(data)
return h.Sum(nil)
}
func must[In any, Out any](fn func(In) (Out, error), v In) Out {
out, err := fn(v)
if err != nil {
panic(err)
}
return out
}
func copyBody(req *http.Request) ([]byte, error) {
body, err := io.ReadAll(req.Body)
if err != nil {
return nil, err
}
if err := req.Body.Close(); err != nil {
return nil, err
}
req.Body = io.NopCloser(bytes.NewBuffer(body))
return body, nil
}