summaryrefslogtreecommitdiffstats
path: root/roseh.moe.go
diff options
context:
space:
mode:
Diffstat (limited to 'roseh.moe.go')
-rw-r--r--roseh.moe.go56
1 files changed, 39 insertions, 17 deletions
diff --git a/roseh.moe.go b/roseh.moe.go
index 99d1bed..c8d61e9 100644
--- a/roseh.moe.go
+++ b/roseh.moe.go
@@ -4,6 +4,7 @@ import (
"bytes"
"crypto/aes"
"crypto/cipher"
+ "crypto/hkdf"
"crypto/hmac"
"crypto/rand"
"crypto/sha512"
@@ -54,6 +55,9 @@ func loadSecrets() error {
if _, err := hex.Decode(buf, pw); err != nil {
return err
}
+ if len(buf) < pwhash.SaltLen {
+ return fmt.Errorf("bad password hash")
+ }
notepadPasswordSalt, notepadPassword = buf[:pwhash.SaltLen], buf[pwhash.SaltLen:]
} else if key, ok := bytes.CutPrefix(line, []byte("secret-key=")); ok {
if hex.DecodedLen(len(key)) != sha512.Size256 {
@@ -155,9 +159,25 @@ func attachCookie(w http.ResponseWriter) error {
return nil
}
-func cookieAuth(w http.ResponseWriter, r *http.Request) (string, bool) {
+func attachCSRFToken(w http.ResponseWriter) string {
const csrfTokenLen = 32
+ buf := make([]byte, csrfTokenLen)
+ rand.Read(buf)
+ csrfToken := base64.RawStdEncoding.EncodeToString(buf)
+ http.SetCookie(w, &http.Cookie{
+ Name: "csrf-token",
+ Value: csrfToken,
+ Path: "/notepad",
+ Secure: true,
+ HttpOnly: true,
+ SameSite: http.SameSiteStrictMode,
+ Partitioned: true,
+ })
+ return csrfToken
+}
+
+func cookieAuth(w http.ResponseWriter, r *http.Request) (string, bool) {
cookie, err := r.Cookie("auth")
if err != nil {
return "", false
@@ -188,18 +208,7 @@ func cookieAuth(w http.ResponseWriter, r *http.Request) (string, bool) {
if csrfToken, err := r.Cookie("csrf-token"); err == nil {
return csrfToken.Value, true
}
- buf := make([]byte, csrfTokenLen)
- rand.Read(buf)
- csrfToken := base64.RawStdEncoding.EncodeToString(buf)
- http.SetCookie(w, &http.Cookie{
- Name: "csrf-token",
- Value: csrfToken,
- Path: "/notepad",
- Secure: true,
- HttpOnly: true,
- SameSite: http.SameSiteStrictMode,
- Partitioned: true,
- })
+ csrfToken := attachCSRFToken(w)
return csrfToken, true
}
@@ -215,7 +224,9 @@ type loginTemplateArgs struct {
}
func login(w http.ResponseWriter, r *http.Request) {
- key, pwHash, err := pwhash.Hash(r.FormValue("password"), notepadPasswordSalt)
+ const aesKeySize = 32
+
+ rawKey, pwHash, err := pwhash.Hash(r.FormValue("password"), notepadPasswordSalt)
if err != nil {
http.Error(w, fmt.Sprintf("Unable to hash password: %s", err), http.StatusInternalServerError)
return
@@ -227,11 +238,22 @@ func login(w http.ResponseWriter, r *http.Request) {
return
}
encryptionKeyMu.Lock()
- if encryptionKey == nil {
- encryptionKey = key
- }
+ currentKey := encryptionKey
encryptionKeyMu.Unlock()
+ if currentKey == nil {
+ key, err := hkdf.Expand(sha512.New, rawKey, "encrypt", aesKeySize)
+ if err != nil {
+ http.Error(w, fmt.Sprintf("Unable to derive encryption key: %s", err), http.StatusInternalServerError)
+ return
+ }
+ encryptionKeyMu.Lock()
+ if encryptionKey == nil {
+ encryptionKey = key
+ }
+ encryptionKeyMu.Unlock()
+ }
attachCookie(w)
+ attachCSRFToken(w)
http.Redirect(w, r, r.FormValue("redirect"), http.StatusSeeOther)
}