docstore/pkg/server/xsrf.go
2022-09-19 22:52:40 +02:00

48 lines
898 B
Go

// Copyright (C) 2021 Marius Schellenberger
package server
import (
"crypto/rand"
"crypto/subtle"
"encoding/base64"
"git.giftfish.de/ston1th/jwt/v3"
)
const keySize = jwt.KeySize / 2
func genKey(size int) (b []byte, err error) {
b = make([]byte, size)
_, err = rand.Reader.Read(b)
return
}
func newXsrf(secret []byte) (s string, err error) {
rnd, err := genKey(keySize)
s = base64.RawURLEncoding.EncodeToString(append(rnd, xor(rnd, secret)...))
return
}
func checkXsrf(xsrf string, secret []byte) bool {
t, err := base64.RawURLEncoding.DecodeString(xsrf)
if err != nil {
return false
}
if len(t) != jwt.KeySize {
return false
}
return subtle.ConstantTimeCompare(secret, xor(t[keySize:], t[:keySize])) == 1
}
func xor(a, b []byte) (c []byte) {
n := len(a)
if len(b) < n {
return nil
}
c = make([]byte, n)
for i := 0; i < n; i++ {
c[i] = a[i] ^ b[i]
}
return
}