summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2026-10-17 11:41:00 -0700
committerRose Hogenson <rosehogenson@posteo.net>2026-10-17 11:41:16 -0700
commitb6f885635661c6c519a019e05d31d24fff191e1d (patch)
treee7a260b2eb233826ba612a4956202112c639479b
parentMake the 404 image not quite so ass (diff)
downloadroseh.moe-b6f885635661c6c519a019e05d31d24fff191e1d.tar.zst
Use a more insane cookie format
-rw-r--r--roseh.moe.go37
-rw-r--r--roseh.moe_test.go18
2 files changed, 44 insertions, 11 deletions
diff --git a/roseh.moe.go b/roseh.moe.go
index a7842b7..2640250 100644
--- a/roseh.moe.go
+++ b/roseh.moe.go
@@ -706,40 +706,55 @@ func verify(signedMsg, purpose string) (string, bool) {
return msg, true
}
-func marshalInt(x int64) []byte {
+func marshalInt(x uint64) []byte {
buf := make([]byte, 8)
- binary.BigEndian.PutUint64(buf, uint64(x))
+ binary.BigEndian.PutUint64(buf, x)
for ; len(buf) > 0 && buf[0] == 0; buf = buf[1:] {
}
return buf
}
-func unmarshalInt(b []byte) (int64, bool) {
+func unmarshalInt(b []byte) (uint64, bool) {
if len(b) > 8 {
return 0, false
}
buf := make([]byte, 8)
copy(buf[8-len(b):], b)
- return int64(binary.BigEndian.Uint64(buf)), true
+ return binary.BigEndian.Uint64(buf), true
}
-var myUnixEpoch = time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC)
-
func marshalTime(t time.Time) []byte {
- return marshalInt(int64(t.Sub(myUnixEpoch) / time.Second))
+ t = t.UTC()
+ year, month, day := t.Date()
+ hour, minute, second := t.Clock()
+ u := uint64(year)
+ u = u<<4 | uint64(month)
+ u = u<<5 | uint64(day)
+ u = u<<5 | uint64(hour)
+ u = u<<6 | uint64(minute)
+ u = u<<6 | uint64(second)
+ return marshalInt(u)
}
func unmarshalTime(b []byte) (time.Time, bool) {
- n, ok := unmarshalInt(b)
+ u, ok := unmarshalInt(b)
if !ok {
return time.Time{}, false
}
- return myUnixEpoch.Add(time.Duration(n) * time.Second), true
+ second, u := int(u&0x3f), u>>6
+ minute, u := int(u&0x3f), u>>6
+ hour, u := int(u&0x1f), u>>5
+ day, u := int(u&0x1f), u>>5
+ month, u := time.Month(u&0xf), u>>4
+ year := int(u)
+ return time.Date(year, month, day, hour, minute, second, 0, time.UTC), true
}
+const authVersion = "authv2"
+
func makeToken() string {
t := base64.RawURLEncoding.EncodeToString(marshalTime(time.Now()))
- return t + mac(t, "auth")
+ return t + mac(t, authVersion)
}
const authCookieName = "a"
@@ -763,7 +778,7 @@ func cookieAuth(r *http.Request) (time.Duration, bool) {
if err != nil {
return 0, false
}
- msg, ok := verify(cookie.Value, "auth")
+ msg, ok := verify(cookie.Value, authVersion)
if !ok {
return 0, false
}
diff --git a/roseh.moe_test.go b/roseh.moe_test.go
new file mode 100644
index 0000000..cf41cd0
--- /dev/null
+++ b/roseh.moe_test.go
@@ -0,0 +1,18 @@
+package main
+
+import (
+ "testing"
+ "time"
+)
+
+func TestMarshalTime(t *testing.T) {
+ now := time.Now().Truncate(time.Second)
+ b := marshalTime(now)
+ got, ok := unmarshalTime(b)
+ if !ok {
+ t.Fatalf("Failed round trip")
+ }
+ if !got.Equal(now) {
+ t.Errorf("Failed round trip. unmarshalTime(%v) = %v, want %v", b, got, now)
+ }
+}