/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/auth/token.go
221 строка
5 KB
zoom-ua
gofumpt (#28710)
17 дек 2025, 17:16
Не верифицирован
17 дек 2025, 17:16
cda510b
Код
Авторство
О чём код?
// Copyright 2015 Keybase, Inc. All rights reserved. Use of // this source code is governed by the included BSD license. // Code used to support authentication tokens for arbitrary purposes. package auth import ( "bytes" "crypto/rand" "encoding/hex" "encoding/json" "math" "time" "github.com/keybase/client/go/kbcrypto" libkb "github.com/keybase/client/go/libkb" keybase1 "github.com/keybase/client/go/protocol/keybase1" ) const ( TokenType = "auth" CurrentTokenVersion = 2 ChallengeLengthBytes = 32 ChallengeLengthString = ChallengeLengthBytes * 2 // we use hex encoding ) type TokenAuth struct { Server string `json:"server"` Challenge string `json:"session"` } type TokenKey struct { UID keybase1.UID `json:"uid"` Username libkb.NormalizedUsername `json:"username"` KID keybase1.KID `json:"kid"` } type TokenBody struct { Auth TokenAuth `json:"auth"` Key TokenKey `json:"key"` Type string `json:"type"` Version int `json:"version"` } type TokenClient struct { Name string `json:"name"` Version string `json:"version"` } type Token struct { Body TokenBody `json:"body"` Client TokenClient `json:"client"` CreationTime int64 `json:"ctime"` ExpireIn int `json:"expire_in"` Tag string `json:"tag"` } func NewToken(uid keybase1.UID, username libkb.NormalizedUsername, kid keybase1.KID, server, challenge string, now int64, expireIn int, clientName, clientVersion string, ) *Token { return &Token{ Body: TokenBody{ Auth: TokenAuth{ Server: server, Challenge: challenge, }, Key: TokenKey{ UID: uid, Username: username, KID: kid, }, Type: TokenType, Version: CurrentTokenVersion, }, Client: TokenClient{ Name: clientName, Version: clientVersion, }, CreationTime: now, ExpireIn: expireIn, Tag: "signature", } } func (t Token) Bytes() []byte { bytes, err := json.Marshal(&t) if err != nil { return []byte{} } return bytes } func (t Token) String() string { return string(t.Bytes()) } func VerifyToken(signature, server, challenge string, maxExpireIn int) (*Token, error) { var t *Token key, token, _, err := kbcrypto.NaclVerifyAndExtract(signature) if err != nil { return nil, err } if t, err = parseToken(token); err != nil { return nil, err } if key.GetKID() != t.KID() { return nil, InvalidTokenKeyError{ expected: key.GetKID().String(), received: t.KID().String(), } } if TokenType != t.Type() { return nil, InvalidTokenTypeError{ expected: TokenType, received: t.Type(), } } if server != t.Server() { return nil, InvalidTokenServerError{ expected: server, received: t.Server(), } } if challenge != t.Challenge() { return nil, InvalidTokenChallengeError{ expected: challenge, received: t.Challenge(), } } remaining := t.TimeRemaining() if remaining > maxExpireIn { return nil, MaxTokenExpiresError{ creationTime: t.CreationTime, expireIn: t.ExpireIn, now: time.Now().Unix(), maxExpireIn: maxExpireIn, remaining: remaining, } } if remaining <= 0 { return nil, TokenExpiredError{ creationTime: t.CreationTime, expireIn: t.ExpireIn, now: time.Now().Unix(), } } return t, nil } func (t Token) TimeRemaining() int { ctime := time.Unix(t.CreationTime, 0) expires := ctime.Add(time.Duration(t.ExpireIn) * time.Second) return int(math.Ceil(time.Until(expires).Seconds())) } func (t Token) Server() string { return t.Body.Auth.Server } func (t Token) Challenge() string { return t.Body.Auth.Challenge } func (t Token) UID() keybase1.UID { return t.Body.Key.UID } func (t Token) KID() keybase1.KID { return t.Body.Key.KID } func (t Token) Username() libkb.NormalizedUsername { return t.Body.Key.Username } func (t Token) Type() string { return t.Body.Type } func (t Token) Version() int { return t.Body.Version } func (t Token) ClientName() string { return t.Client.Name } func (t Token) ClientVersion() string { return t.Client.Version } func parseToken(token []byte) (*Token, error) { decoder := json.NewDecoder(bytes.NewReader(token)) decoder.UseNumber() var t Token if err := decoder.Decode(&t); err != nil { return nil, err } return &t, nil } // GenerateChallenge returns a cryptographically secure random challenge string. func GenerateChallenge() (string, error) { buf := make([]byte, ChallengeLengthBytes) if _, err := rand.Read(buf); err != nil { return "", err } return hex.EncodeToString(buf), nil } // IsValidChallenge returns true if the passed challenge is validly formed. func IsValidChallenge(challenge string) bool { if len(challenge) != ChallengeLengthString { return false } if _, err := hex.DecodeString(challenge); err != nil { return false } return true }