mirror of https://git.sr.ht/~sircmpwn/gql.sr.ht
Add auth/token.go & support code in crypto.go
This commit is contained in:
parent
f5f498ec5a
commit
6d5b4f7606
|
@ -0,0 +1,68 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"time"
|
||||
|
||||
"git.sr.ht/~sircmpwn/go-bare"
|
||||
|
||||
"git.sr.ht/~sircmpwn/gql.sr.ht/crypto"
|
||||
)
|
||||
|
||||
const TokenVersion uint = 0
|
||||
|
||||
type Timestamp int64
|
||||
|
||||
func (t Timestamp) Time() time.Time {
|
||||
return time.Unix(int64(t), 0)
|
||||
}
|
||||
|
||||
func ToTimestamp(t time.Time) Timestamp {
|
||||
return Timestamp(t.Unix())
|
||||
}
|
||||
|
||||
type OAuth2Token struct {
|
||||
Version uint
|
||||
Expires Timestamp
|
||||
Scopes string
|
||||
ClientID string
|
||||
Username string
|
||||
}
|
||||
|
||||
func (ot *OAuth2Token) Encode() string {
|
||||
plain, err := bare.Marshal(ot)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mac := crypto.HMAC(plain)
|
||||
return base64.RawStdEncoding.EncodeToString(append(plain, mac...))
|
||||
}
|
||||
|
||||
func DecodeToken(token string) *OAuth2Token {
|
||||
payload, err := base64.RawStdEncoding.DecodeString(token)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if len(payload) <= 32 {
|
||||
return nil
|
||||
}
|
||||
|
||||
mac := payload[32:]
|
||||
payload = payload[:32]
|
||||
if crypto.HMACVerify(payload, mac) == false {
|
||||
return nil
|
||||
}
|
||||
|
||||
ot := &OAuth2Token{}
|
||||
err = bare.Unmarshal(payload, &ot)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if ot.Version != TokenVersion {
|
||||
return nil
|
||||
}
|
||||
if time.Now().UTC().After(ot.Expires.Time()) {
|
||||
return nil
|
||||
}
|
||||
return ot
|
||||
}
|
|
@ -2,6 +2,8 @@ package crypto
|
|||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"log"
|
||||
"time"
|
||||
|
@ -13,6 +15,7 @@ import (
|
|||
var (
|
||||
privateKey ed25519.PrivateKey
|
||||
publicKey ed25519.PublicKey
|
||||
macKey []byte
|
||||
fernetKey *fernet.Key
|
||||
)
|
||||
|
||||
|
@ -36,6 +39,9 @@ func InitCrypto(config ini.File) {
|
|||
if err != nil {
|
||||
log.Fatalf("Load Fernet network encryption key: %v", err)
|
||||
}
|
||||
mac := hmac.New(sha256.New, privateKey)
|
||||
mac.Write([]byte("sr.ht HMAC key"))
|
||||
macKey = mac.Sum(nil)
|
||||
}
|
||||
|
||||
func Sign(payload []byte) []byte {
|
||||
|
@ -62,3 +68,16 @@ func Decrypt(payload []byte) []byte {
|
|||
func DecryptWithExpiration(payload []byte, expiry time.Duration) []byte {
|
||||
return fernet.VerifyAndDecrypt(payload, expiry, []*fernet.Key{fernetKey})
|
||||
}
|
||||
|
||||
func HMAC(payload []byte) []byte {
|
||||
mac := hmac.New(sha256.New, macKey)
|
||||
mac.Write(payload)
|
||||
return mac.Sum(nil)
|
||||
}
|
||||
|
||||
func HMACVerify(payload []byte, signature []byte) bool {
|
||||
mac := hmac.New(sha256.New, macKey)
|
||||
mac.Write(payload)
|
||||
expected := mac.Sum(nil)
|
||||
return hmac.Equal(expected, signature)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue