summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--roseh.moe.go43
1 files changed, 18 insertions, 25 deletions
diff --git a/roseh.moe.go b/roseh.moe.go
index ffca9d5..a2e7ed2 100644
--- a/roseh.moe.go
+++ b/roseh.moe.go
@@ -209,7 +209,7 @@ func makeHole() string {
func newWormhole(w http.ResponseWriter, r *http.Request) {
hole := makeHole()
- http.Redirect(w, r, "/wormhole/"+hole+"/upload?s="+base64.RawURLEncoding.EncodeToString(mac([]byte(hole))), http.StatusSeeOther)
+ http.Redirect(w, r, "/wormhole/"+hole+"/upload?s="+base64.RawURLEncoding.EncodeToString(mac([]byte(hole), "hole")), http.StatusSeeOther)
}
func wormhole(w http.ResponseWriter, r *http.Request) {
@@ -309,8 +309,7 @@ func wormholeQR(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprintf("Bad signature: %s", err), http.StatusBadRequest)
return
}
- expectedMAC := mac([]byte(r.PathValue("hole")))
- if !hmac.Equal(sig, expectedMAC) {
+ if !verify([]byte(r.PathValue("hole")), sig, "hole") {
http.Error(w, "Bad signature", http.StatusBadRequest)
return
}
@@ -325,26 +324,17 @@ func wormholeQR(w http.ResponseWriter, r *http.Request) {
const macSize = targetSecurityLevel
-func mac(msg []byte) []byte {
+func mac(msg []byte, purpose string) []byte {
mac := hmac.New(sha256.New, secretKey)
+ io.WriteString(mac, purpose)
+ io.WriteString(mac, ":")
mac.Write(msg)
return mac.Sum(nil)[:macSize]
}
-func sign(msg []byte) []byte {
- return append(msg, mac(msg)...)
-}
-
-func verify(msg []byte) ([]byte, bool) {
- if len(msg) < macSize {
- return nil, false
- }
- msg, messageMAC := msg[:len(msg)-macSize], msg[len(msg)-macSize:]
- expectedMAC := mac(msg)
- if !hmac.Equal(messageMAC, expectedMAC) {
- return nil, false
- }
- return msg, true
+func verify(msg, messageMAC []byte, purpose string) bool {
+ expectedMAC := mac(msg, purpose)
+ return hmac.Equal(messageMAC, expectedMAC)
}
func marshalInt(x int64) []byte {
@@ -390,7 +380,8 @@ func unmarshalTime(b []byte) (time.Time, bool) {
}
func makeToken() string {
- return base64.RawURLEncoding.EncodeToString(sign(marshalTime(time.Now())))
+ t := marshalTime(time.Now())
+ return base64.RawURLEncoding.EncodeToString(append(t, mac(t, "auth")...))
}
const cookieExpiration = 7 * 24 * time.Hour
@@ -419,8 +410,11 @@ func cookieAuth(w http.ResponseWriter, r *http.Request) bool {
if err != nil {
return false
}
- msg, ok := verify(authCookie)
- if !ok {
+ if len(authCookie) < macSize {
+ return false
+ }
+ msg, mac := authCookie[:len(authCookie)-macSize], authCookie[len(authCookie)-macSize:]
+ if !verify(msg, mac, "auth") {
return false
}
t, ok := unmarshalTime(msg)
@@ -491,7 +485,7 @@ type loginTemplateArgs struct {
}
func redirectLogin(w http.ResponseWriter, r *http.Request, redirect string) {
- redirect += base64.RawURLEncoding.EncodeToString(mac([]byte(redirect)))
+ redirect += base64.RawURLEncoding.EncodeToString(mac([]byte(redirect), "redirect"))
http.Redirect(w, r, *selfURL+"/login?redirect="+url.QueryEscape(redirect), http.StatusFound)
}
@@ -507,12 +501,11 @@ func verifyRedirect(redirect string) (string, bool) {
return "", false
}
redirect, macBase64 := redirect[:len(redirect)-base64MacSize], redirect[len(redirect)-base64MacSize:]
- messageMAC, err := base64.RawURLEncoding.DecodeString(macBase64)
+ mac, err := base64.RawURLEncoding.DecodeString(macBase64)
if err != nil {
return "", false
}
- expectedMAC := mac([]byte(redirect))
- if !hmac.Equal(messageMAC, expectedMAC) {
+ if !verify([]byte(redirect), mac, "redirect") {
return "", false
}
return redirect, true