From c6ea2bf6fe01fc9da82b9643f4673dfc91f4e23d Mon Sep 17 00:00:00 2001 From: FChannel <> Date: Thu, 13 May 2021 23:59:31 -0700 Subject: Managing server info added to README --- verification.go | 2 -- 1 file changed, 2 deletions(-) (limited to 'verification.go') diff --git a/verification.go b/verification.go index 97f80bf..8dc5a6b 100644 --- a/verification.go +++ b/verification.go @@ -330,8 +330,6 @@ func HasAuth(db *sql.DB, code string, board string) bool { return true } - fmt.Println("has auth is false") - return false; } -- cgit v1.2.3 From b4e551b3db5a5fc69befeffb7fba17b50dc2e258 Mon Sep 17 00:00:00 2001 From: FChannel <> Date: Sun, 30 May 2021 17:00:51 -0700 Subject: added pem keys to users accounts --- verification.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) (limited to 'verification.go') diff --git a/verification.go b/verification.go index 8dc5a6b..ec64f63 100644 --- a/verification.go +++ b/verification.go @@ -8,6 +8,10 @@ import "time" import "os/exec" import "os" import "math/rand" +import "crypto/rsa" +import "crypto/x509" +import "encoding/pem" +import crand "crypto/rand" type Verify struct { Type string @@ -471,4 +475,68 @@ func Captcha() string { return newID } +func CreatePem(db *sql.DB, actor Actor) { + privatekey, err := rsa.GenerateKey(crand.Reader, 2048) + CheckError(err, "error creating private pem key") + privateKeyBytes := x509.MarshalPKCS1PrivateKey(privatekey) + + privateKeyBlock := &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: privateKeyBytes, + } + + privatePem, err := os.Create("./pem/board/" + actor.Name + "-private.pem") + CheckError(err, "error creating private pem file for " + actor.Name) + + err = pem.Encode(privatePem, privateKeyBlock) + CheckError(err, "error encoding private pem") + + publickey := &privatekey.PublicKey + publicKeyBytes, err := x509.MarshalPKIXPublicKey(publickey) + CheckError(err, "error Marshaling public key to X509") + + publicKeyBlock := &pem.Block{ + Type: "PUBLIC KEY", + Bytes: publicKeyBytes, + } + + publicPem, err := os.Create("./pem/board/" + actor.Name + "-public.pem") + CheckError(err, "error creating public pem file for " + actor.Name) + + err = pem.Encode(publicPem, publicKeyBlock) + CheckError(err, "error encoding public pem") + + _, err = os.Stat("./pem/board/" + actor.Name + "-public.pem") + if os.IsNotExist(err) { + CheckError(err, "public pem file for actor does not exist") + } else { + StorePemToDB(db, actor) + } +} + +func StorePemToDB(db *sql.DB, actor Actor) { + query := "select publicKeyPem from actor where id=$1" + rows, err := db.Query(query, actor.Id) + + CheckError(err, "error selecting publicKeyPem id from actor") + + var result string + defer rows.Close() + rows.Next() + rows.Scan(&result) + + if(result != "") { + return + } + + publicKeyPem := actor.Id + "#main-key" + query = "update actor set publicKeyPem=$1 where id=$2" + _, err = db.Exec(query, publicKeyPem, actor.Id) + CheckError(err, "error updating publicKeyPem id to actor") + + file := "./pem/board/" + actor.Name + "-public.pem" + query = "insert into publicKeyPem (id, file) values($1, $2)" + _, err = db.Exec(query, publicKeyPem, file) + CheckError(err, "error creating publicKeyPem for actor ") +} -- cgit v1.2.3 From 869b0262ac1c69fe41cc8d6bc59bd47f6e48f685 Mon Sep 17 00:00:00 2001 From: FChannel <> Date: Sun, 30 May 2021 17:41:12 -0700 Subject: added publickeypem to actor activity requests --- verification.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'verification.go') diff --git a/verification.go b/verification.go index ec64f63..99f5fb7 100644 --- a/verification.go +++ b/verification.go @@ -536,7 +536,7 @@ func StorePemToDB(db *sql.DB, actor Actor) { CheckError(err, "error updating publicKeyPem id to actor") file := "./pem/board/" + actor.Name + "-public.pem" - query = "insert into publicKeyPem (id, file) values($1, $2)" - _, err = db.Exec(query, publicKeyPem, file) + query = "insert into publicKeyPem (id, owner, file) values($1, $2, $3)" + _, err = db.Exec(query, publicKeyPem, actor.Id, file) CheckError(err, "error creating publicKeyPem for actor ") } -- cgit v1.2.3 From d496ab89d560ea59f19669ea47ba9f991f7d8a94 Mon Sep 17 00:00:00 2001 From: FChannel <> Date: Fri, 4 Jun 2021 12:29:16 -0700 Subject: added activity sign and verify with pem keys --- verification.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'verification.go') diff --git a/verification.go b/verification.go index 99f5fb7..8c6cf98 100644 --- a/verification.go +++ b/verification.go @@ -8,10 +8,15 @@ import "time" import "os/exec" import "os" import "math/rand" +import "crypto" import "crypto/rsa" import "crypto/x509" +import "crypto/sha256" import "encoding/pem" +import "encoding/base64" import crand "crypto/rand" +import "io/ioutil" +import "strings" type Verify struct { Type string @@ -540,3 +545,48 @@ func StorePemToDB(db *sql.DB, actor Actor) { _, err = db.Exec(query, publicKeyPem, actor.Id, file) CheckError(err, "error creating publicKeyPem for actor ") } + +func ActivitySign(db *sql.DB, actor Actor, signature string) string { + query := `select file from publicKeyPem where id=$1 ` + + rows, err := db.Query(query, actor.PublicKey.Id) + + CheckError(err, "there was error geting actors public key id") + + var file string + defer rows.Close() + rows.Next() + rows.Scan(&file) + + file = strings.ReplaceAll(file, "public.pem", "private.pem") + _, err = os.Stat(file) + if err == nil { + publickey, err:= ioutil.ReadFile(file) + CheckError(err, "error reading file") + + block, _ := pem.Decode(publickey) + + pub, _ := x509.ParsePKCS1PrivateKey(block.Bytes) + rng :=crand.Reader + hashed := sha256.New() + hashed.Write([]byte(signature)) + cipher, _ := rsa.SignPKCS1v15(rng, pub, crypto.SHA256, hashed.Sum(nil)) + + return base64.StdEncoding.EncodeToString(cipher) + } + + return "" +} + +func ActivityVerify(db *sql.DB, actor Actor, signature string, verify string) error { + + sig, _ := base64.StdEncoding.DecodeString(signature) + + block, _ := pem.Decode([]byte(actor.PublicKey.PublicKeyPem)) + pub, _ := x509.ParsePKIXPublicKey(block.Bytes) + + hashed := sha256.New() + hashed.Write([]byte(verify)) + + return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.SHA256, hashed.Sum(nil), sig) +} -- cgit v1.2.3 From 8d9218e8cd7f18808bbd6b60e8a489cee967efb4 Mon Sep 17 00:00:00 2001 From: FChannel <> Date: Fri, 4 Jun 2021 16:02:52 -0700 Subject: added verfication based on signature header with pem keys --- verification.go | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'verification.go') diff --git a/verification.go b/verification.go index 8c6cf98..e193746 100644 --- a/verification.go +++ b/verification.go @@ -17,6 +17,7 @@ import "encoding/base64" import crand "crypto/rand" import "io/ioutil" import "strings" +import "net/http" type Verify struct { Type string @@ -578,10 +579,14 @@ func ActivitySign(db *sql.DB, actor Actor, signature string) string { return "" } -func ActivityVerify(db *sql.DB, actor Actor, signature string, verify string) error { +func ActivityVerify(actor Actor, signature string, verify string) error { sig, _ := base64.StdEncoding.DecodeString(signature) + if actor.PublicKey.PublicKeyPem == "" { + actor = FingerActor(actor.Id) + } + block, _ := pem.Decode([]byte(actor.PublicKey.PublicKeyPem)) pub, _ := x509.ParsePKIXPublicKey(block.Bytes) @@ -590,3 +595,25 @@ func ActivityVerify(db *sql.DB, actor Actor, signature string, verify string) er return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.SHA256, hashed.Sum(nil), sig) } + +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") + + sig := fmt.Sprintf("(request-target): %s %s\\nhost: %s\\ndate: %s", method, path, host, date) + + t, _ := time.Parse(time.RFC1123, date) + + if(time.Now().Sub(t).Seconds() > 30) { + return false + } + + if ActivityVerify(actor, sig, encSig) != nil { + return false + } + + return true +} -- cgit v1.2.3 From 42cf749f7923ac33194ab87b8dce060f46a220bc Mon Sep 17 00:00:00 2001 From: FChannel <> Date: Sun, 6 Jun 2021 12:39:06 -0700 Subject: signature verify arguments mixed up fix --- verification.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'verification.go') diff --git a/verification.go b/verification.go index e193746..86b539e 100644 --- a/verification.go +++ b/verification.go @@ -611,7 +611,7 @@ func VerifyHeaderSignature(r *http.Request, actor Actor) bool { return false } - if ActivityVerify(actor, sig, encSig) != nil { + if ActivityVerify(actor, encSig, sig) != nil { return false } -- cgit v1.2.3 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 --- verification.go | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 7 deletions(-) (limited to 'verification.go') 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 From 3b806e4603a7da8bb6a24029a0115e18a6b7ba5b Mon Sep 17 00:00:00 2001 From: FChannel <> Date: Fri, 25 Jun 2021 01:39:50 -0700 Subject: expanded header signature support to known possible values at this time --- verification.go | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'verification.go') diff --git a/verification.go b/verification.go index 3215688..7c634e1 100644 --- a/verification.go +++ b/verification.go @@ -38,6 +38,7 @@ type Signature struct { KeyId string Headers []string Signature string + Algorithm string } func DeleteBoardMod(db *sql.DB, verify Verify) { @@ -606,10 +607,12 @@ func ActivityVerify(actor Actor, signature string, verify string) error { func VerifyHeaderSignature(r *http.Request, actor Actor) bool { s := ParseHeaderSignature(r.Header.Get("Signature")) - var method string - var path string - var host string - var date string + var method string + var path string + var host string + var date string + var digest string + var contentLength string var sig string for _, e := range s.Headers { @@ -630,7 +633,19 @@ func VerifyHeaderSignature(r *http.Request, actor Actor) bool { date = r.Header.Get("date") sig += "date: " + date continue - } + } + + if e == "digest" { + digest = r.Header.Get("digest") + sig += "digest: " + digest + continue + } + + if e == "content-length" { + contentLength = r.Header.Get("content-length") + sig += "content-length: " + contentLength + continue + } } if s.KeyId != actor.PublicKey.Id { @@ -656,6 +671,7 @@ func ParseHeaderSignature(signature string) Signature { keyId := regexp.MustCompile(`keyId=`) headers := regexp.MustCompile(`headers=`) sig := regexp.MustCompile(`signature=`) + algo := regexp.MustCompile(`algorithm=`) signature = strings.ReplaceAll(signature, "\"", "") parts := strings.Split(signature, ",") @@ -676,6 +692,11 @@ func ParseHeaderSignature(signature string) Signature { nsig.Signature = sig.ReplaceAllString(e, "") continue } + + if algo.MatchString(e) { + nsig.Algorithm = algo.ReplaceAllString(e, "") + continue + } } return nsig -- cgit v1.2.3 From 80bcce22a2368c3911137dec97d6744dee328809 Mon Sep 17 00:00:00 2001 From: FChannel <> Date: Fri, 25 Jun 2021 14:55:18 -0700 Subject: more cleaning up to better intergrate with plemroma standards. can verify signatures better --- verification.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'verification.go') diff --git a/verification.go b/verification.go index 7c634e1..db44689 100644 --- a/verification.go +++ b/verification.go @@ -615,35 +615,42 @@ func VerifyHeaderSignature(r *http.Request, actor Actor) bool { var contentLength string var sig string - for _, e := range s.Headers { + for i, e := range s.Headers { + + var nl string + if i < len(s.Headers) - 1 { + nl = "\n" + } + + if e == "(request-target)" { method = strings.ToLower(r.Method) path = r.URL.Path - sig += "(request-target): " + method + " " + path + "\\n" + sig += "(request-target): " + method + " " + path + "" + nl continue } if e == "host" { host = r.Host - sig += "host: " + host + "\\n" + sig += "host: " + host + "" + nl continue } if e == "date" { date = r.Header.Get("date") - sig += "date: " + date + sig += "date: " + date + "" + nl continue } if e == "digest" { digest = r.Header.Get("digest") - sig += "digest: " + digest + sig += "digest: " + digest + "" + nl continue } if e == "content-length" { contentLength = r.Header.Get("content-length") - sig += "content-length: " + contentLength + sig += "content-length: " + contentLength + "" + nl continue } } -- cgit v1.2.3