Files
go-away/lib/challenge.go

69 lines
1.6 KiB
Go

package lib
import (
"crypto/sha256"
"encoding/binary"
"github.com/go-jose/go-jose/v4/jwt"
"net"
"net/http"
"strings"
"time"
)
type ChallengeInformation struct {
Name string `json:"name"`
Key []byte `json:"key"`
Result []byte `json:"result"`
Expiry *jwt.NumericDate `json:"exp,omitempty"`
NotBefore *jwt.NumericDate `json:"nbf,omitempty"`
IssuedAt *jwt.NumericDate `json:"iat,omitempty"`
}
func getRequestAddress(r *http.Request, clientHeader string) net.IP {
var ipStr string
if clientHeader != "" {
ipStr = r.Header.Get(clientHeader)
}
if ipStr != "" {
// handle X-Forwarded-For
ipStr = strings.Split(ipStr, ",")[0]
}
// fallback
if ipStr == "" {
parts := strings.Split(r.RemoteAddr, ":")
// drop port
ipStr = strings.Join(parts[:len(parts)-1], ":")
}
return net.ParseIP(ipStr)
}
func (state *State) GetChallengeKeyForRequest(challengeName string, until time.Time, r *http.Request) []byte {
hasher := sha256.New()
hasher.Write([]byte("challenge\x00"))
hasher.Write([]byte(challengeName))
hasher.Write([]byte{0})
hasher.Write(getRequestAddress(r, state.Settings.ClientIpHeader).To16())
hasher.Write([]byte{0})
// specific headers
for _, k := range []string{
"Accept-Language",
// General browser information
"User-Agent",
"Sec-Ch-Ua",
"Sec-Ch-Ua-Platform",
} {
hasher.Write([]byte(r.Header.Get(k)))
hasher.Write([]byte{0})
}
hasher.Write([]byte{0})
_ = binary.Write(hasher, binary.LittleEndian, until.UTC().Unix())
hasher.Write([]byte{0})
hasher.Write(state.publicKey)
hasher.Write([]byte{0})
return hasher.Sum(nil)
}