From 24bdae7a803461bd9b13408f4fd332ebed5b5ac3 Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Tue, 23 Sep 2025 22:14:57 -0700 Subject: Use HMAC instead of ed25519 --- roseh.moe.go | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'roseh.moe.go') diff --git a/roseh.moe.go b/roseh.moe.go index e2500ca..c75acca 100644 --- a/roseh.moe.go +++ b/roseh.moe.go @@ -4,8 +4,9 @@ import ( "bytes" "crypto/aes" "crypto/cipher" - "crypto/ed25519" + "crypto/hmac" "crypto/rand" + "crypto/sha512" "crypto/subtle" "embed" "encoding/base64" @@ -36,8 +37,7 @@ var ( var ( notepadPassword []byte notepadPasswordSalt []byte - privateKey ed25519.PrivateKey - publicKey ed25519.PublicKey + privateKey []byte encryptionKeyMu sync.Mutex encryptionKey cipher.AEAD @@ -54,21 +54,19 @@ func loadSecrets() error { if _, err := hex.Decode(notepadPassword, pw); err != nil { return err } - } else if key, ok := bytes.CutPrefix(line, []byte("secret-key=")); ok { - seed := make([]byte, hex.DecodedLen(len(key))) - if _, err := hex.Decode(seed, key); err != nil { - return err - } - if len(seed) != ed25519.SeedSize { - return fmt.Errorf("invalid ed25519 key") - } - privateKey = ed25519.NewKeyFromSeed(seed) - publicKey = privateKey.Public().(ed25519.PublicKey) } else if salt, ok := bytes.CutPrefix(line, []byte("salt=")); ok { notepadPasswordSalt = make([]byte, hex.DecodedLen(len(salt))) if _, err := hex.Decode(notepadPasswordSalt, salt); err != nil { return err } + } else if key, ok := bytes.CutPrefix(line, []byte("secret-key=")); ok { + if hex.DecodedLen(len(key)) != sha512.Size256 { + return fmt.Errorf("invalid HMAC-SHA512/256 key") + } + privateKey = make([]byte, hex.DecodedLen(len(key))) + if _, err := hex.Decode(privateKey, key); err != nil { + return err + } } } return nil @@ -146,10 +144,11 @@ func attachCookie(w http.ResponseWriter) error { if err != nil { return err } - sig := ed25519.Sign(privateKey, nowBytes) + mac := hmac.New(sha512.New512_256, privateKey) + mac.Write(nowBytes) http.SetCookie(w, &http.Cookie{ Name: "auth", - Value: base64.RawStdEncoding.EncodeToString(append(nowBytes, sig...)), + Value: base64.RawStdEncoding.EncodeToString(append(nowBytes, mac.Sum(nil)...)), Path: "/notepad", Expires: time.Now().Add(cookieExpiration), Secure: true, @@ -171,11 +170,14 @@ func cookieAuth(w http.ResponseWriter, r *http.Request) (string, bool) { if err != nil { return "", false } - if len(bytes) < ed25519.SignatureSize { + mac := hmac.New(sha512.New512_256, privateKey) + macSize := mac.Size() + if len(bytes) < macSize { return "", false } - msg, sig := bytes[:len(bytes)-ed25519.SignatureSize], bytes[len(bytes)-ed25519.SignatureSize:] - if !ed25519.Verify(publicKey, msg, sig) { + msg, sig := bytes[:len(bytes)-macSize], bytes[len(bytes)-macSize:] + mac.Write(msg) + if !hmac.Equal(sig, mac.Sum(nil)) { return "", false } var t time.Time -- cgit v1.3.1