From f3a73b3a9f8b7895eeb54f007bde72126eae56d2 Mon Sep 17 00:00:00 2001 From: FChannel <> Date: Sun, 6 Jun 2021 18:34:24 -0700 Subject: basic header signature conversion --- main.go | 8 +++--- verification.go | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/main.go b/main.go index 9e34264..dd6e25a 100644 --- a/main.go +++ b/main.go @@ -1769,10 +1769,11 @@ func MakeActivityRequestOutbox(db *sql.DB, activity Activity) { sig := fmt.Sprintf("(request-target): %s %s\\nhost: %s\\ndate: %s", "post", path, instance, date) encSig := ActivitySign(db, *activity.Actor, sig) + signature := fmt.Sprintf("keyId=\"%s\",headers=\"(request-target) host date\",signature=\"%s\"", activity.Actor.PublicKey.Id, encSig) req.Header.Set("Content-Type", activitystreams) req.Header.Set("Date", date) - req.Header.Set("Signature", encSig) + req.Header.Set("Signature", signature) req.Host = instance _, err = http.DefaultClient.Do(req) @@ -1803,10 +1804,11 @@ func MakeActivityRequest(db *sql.DB, activity Activity) { sig := fmt.Sprintf("(request-target): %s %s\\nhost: %s\\ndate: %s", "post", path, instance, date) encSig := ActivitySign(db, *activity.Actor, sig) - + signature := fmt.Sprintf("keyId=\"%s\",headers=\"(request-target) host date\",signature=\"%s\"", activity.Actor.PublicKey.Id, encSig) + req.Header.Set("Content-Type", activitystreams) req.Header.Set("Date", date) - req.Header.Set("Signature", encSig) + req.Header.Set("Signature", signature) req.Host = instance CheckError(err, "error with sending activity req to") diff --git a/verification.go b/verification.go index 86b539e..3215688 100644 --- a/verification.go +++ b/verification.go @@ -18,6 +18,7 @@ import crand "crypto/rand" import "io/ioutil" import "strings" import "net/http" +import "regexp" type Verify struct { Type string @@ -33,6 +34,12 @@ type VerifyCooldown struct { Time int } +type Signature struct { + KeyId string + Headers []string + Signature string +} + func DeleteBoardMod(db *sql.DB, verify Verify) { query := `select code from boardaccess where identifier=$1 and board=$1` @@ -597,13 +604,38 @@ func ActivityVerify(actor Actor, signature string, verify string) error { } func VerifyHeaderSignature(r *http.Request, actor Actor) bool { - method := strings.ToLower(r.Method) - path := r.URL.Path - host := r.Host - date := r.Header.Get("Date") - encSig := r.Header.Get("Signature") + s := ParseHeaderSignature(r.Header.Get("Signature")) + + var method string + var path string + var host string + var date string + + var sig string + for _, e := range s.Headers { + if e == "(request-target)" { + method = strings.ToLower(r.Method) + path = r.URL.Path + sig += "(request-target): " + method + " " + path + "\\n" + continue + } - sig := fmt.Sprintf("(request-target): %s %s\\nhost: %s\\ndate: %s", method, path, host, date) + if e == "host" { + host = r.Host + sig += "host: " + host + "\\n" + continue + } + + if e == "date" { + date = r.Header.Get("date") + sig += "date: " + date + continue + } + } + + if s.KeyId != actor.PublicKey.Id { + return false + } t, _ := time.Parse(time.RFC1123, date) @@ -611,9 +643,40 @@ func VerifyHeaderSignature(r *http.Request, actor Actor) bool { return false } - if ActivityVerify(actor, encSig, sig) != nil { + if ActivityVerify(actor, s.Signature, sig) != nil { return false } return true } + +func ParseHeaderSignature(signature string) Signature { + var nsig Signature + + keyId := regexp.MustCompile(`keyId=`) + headers := regexp.MustCompile(`headers=`) + sig := regexp.MustCompile(`signature=`) + + signature = strings.ReplaceAll(signature, "\"", "") + parts := strings.Split(signature, ",") + + for _, e := range parts { + if keyId.MatchString(e) { + nsig.KeyId = keyId.ReplaceAllString(e, "") + continue + } + + if headers.MatchString(e) { + header := headers.ReplaceAllString(e, "") + nsig.Headers = strings.Split(header, " ") + continue + } + + if sig.MatchString(e) { + nsig.Signature = sig.ReplaceAllString(e, "") + continue + } + } + + return nsig +} -- cgit v1.2.3