mirror of
https://github.com/therootcompany/golib.git
synced 2026-03-02 23:57:59 +00:00
63 lines
1.4 KiB
Go
63 lines
1.4 KiB
Go
package csvauth
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
)
|
|
|
|
// Provided for consistency. Often better to use Authenticate("", token)
|
|
func (a *Auth) LoadToken(secret string) (Credential, error) {
|
|
var credential Credential
|
|
c, err := a.loadAndVerifyToken(secret)
|
|
if c != nil {
|
|
credential = *c
|
|
}
|
|
return credential, err
|
|
}
|
|
|
|
// VerifyToken uses a shortened, but timing-safe HMAC to find the token,
|
|
// and then verifies it according to the chosen algorithm
|
|
func (a *Auth) VerifyToken(secret string) error {
|
|
_, err := a.loadAndVerifyToken(secret)
|
|
return err
|
|
}
|
|
|
|
func (a *Auth) loadAndVerifyToken(secret string) (*Credential, error) {
|
|
hashID := a.tokenCacheID(secret)
|
|
|
|
a.mux.Lock()
|
|
c, ok := a.tokens[hashID]
|
|
a.mux.Unlock()
|
|
|
|
if !ok {
|
|
return nil, ErrNotFound
|
|
}
|
|
|
|
if c.plain == "" {
|
|
var err error
|
|
if c.plain, err = a.maybeDecryptCredential(c); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if err := c.Verify("", secret); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &c, nil
|
|
}
|
|
|
|
func (a *Auth) tokenCacheID(secret string) string {
|
|
key := a.aes128key[:]
|
|
mac := hmac.New(sha256.New, key)
|
|
message := []byte(secret)
|
|
mac.Write(message)
|
|
// attack collisions are possible, but will still fail to pass HMAC
|
|
// practical collisions are not possible for the CSV use case
|
|
nameBytes := mac.Sum(nil)[:6]
|
|
|
|
name := base64.RawURLEncoding.EncodeToString(nameBytes)
|
|
return name
|
|
}
|