Documentation
ΒΆ
Overview ΒΆ
Package incorruptible provides a safer, shorter, faster secret token for session cookie and Authorization HTTP header.
Index ΒΆ
- Constants
- func AppendIP(buf []byte, ip net.IP) []byte
- func BytesToUint64(buf []byte) (uint64, error)
- func DecodeExpiry(buf []byte) ([]byte, int64)
- func Decrypt(aead cipher.AEAD, all []byte) (plaintext []byte, err error)
- func Encrypt(aead cipher.AEAD, plaintext []byte) []byte
- func MagicCode(buf []byte) uint8
- func Marshal(tv TValues, magic uint8) ([]byte, error)
- func NewAESCipher(secretKey []byte) cipher.AEAD
- func NewChaCipher(secretKey []byte) cipher.AEAD
- func NewCipher(secretKey []byte) cipher.AEAD
- func PutExpiry(buf []byte, unix int64) error
- func Uint64ToBytes(v uint64) []byte
- type Incorruptible
- func (incorr *Incorruptible) BearerToken(r *http.Request) (string, error)
- func (incorr *Incorruptible) Chk(next http.Handler) http.Handler
- func (incorr *Incorruptible) Cookie(_ int) *http.Cookie
- func (incorr *Incorruptible) CookieName() string
- func (incorr *Incorruptible) CookieToken(r *http.Request) (string, error)
- func (incorr *Incorruptible) DeadCookie() *http.Cookie
- func (incorr *Incorruptible) Decode(base91 string) (TValues, error)
- func (incorr *Incorruptible) DecodeBearerToken(r *http.Request) (TValues, error)
- func (incorr *Incorruptible) DecodeCookieToken(r *http.Request) (TValues, error)
- func (incorr *Incorruptible) DecodeToken(r *http.Request) (TValues, []any)
- func (incorr *Incorruptible) Encode(tv TValues) (string, error)
- func (incorr *Incorruptible) NewCookie(r *http.Request, keyValues ...KVal) (*http.Cookie, TValues, error)
- func (incorr *Incorruptible) NewCookieFromToken(token string, maxAge int) *http.Cookie
- func (incorr *Incorruptible) NewCookieFromValues(tv TValues) (*http.Cookie, error)
- func (incorr *Incorruptible) NewTValues(r *http.Request, keyValues ...KVal) (TValues, error)
- func (incorr *Incorruptible) Set(next http.Handler) http.Handler
- func (incorr *Incorruptible) Vet(next http.Handler) http.Handler
- type KBool
- type KInt64
- type KString
- type KUint64
- type KVal
- type Metadata
- type Serializer
- type TValues
- func (tv TValues) Bool(key int) (bool, error)
- func (tv TValues) BoolIfAny(key int, defaultValue ...bool) bool
- func (tv TValues) CompareExpiry() int
- func (tv *TValues) EmptyIP()
- func (tv TValues) ExpiryTime() time.Time
- func (tv *TValues) Get(keyValues ...KVal) ([]KVal, error)
- func (tv TValues) Int64(key int) (int64, error)
- func (tv TValues) Int64IfAny(key int, defaultValue ...int64) int64
- func (tv TValues) KBool(k int, v ...bool) KBool
- func (tv TValues) KInt64(k int, v ...int64) KInt64
- func (tv TValues) KString(k int, v ...string) KString
- func (tv TValues) KUint64(k int, v ...uint64) KUint64
- func (tv TValues) MaxAge() int
- func (tv TValues) NoIP() bool
- func (tv *TValues) Set(keyValues ...KVal) error
- func (tv *TValues) SetBool(key int, val bool) error
- func (tv *TValues) SetExpiry(maxAge int)
- func (tv *TValues) SetExpiryDuration(d time.Duration)
- func (tv *TValues) SetExpiryTime(t time.Time)
- func (tv *TValues) SetInt64(key int, val int64) error
- func (tv *TValues) SetRemoteIP(r *http.Request) error
- func (tv *TValues) SetString(key int, val string) error
- func (tv *TValues) SetUint64(key int, val uint64) error
- func (tv *TValues) ShortenIP4Length()
- func (tv TValues) String(key int) (string, error)
- func (tv TValues) StringIfAny(key int, defaultValue ...string) string
- func (tv TValues) ToCtx(r *http.Request) *http.Request
- func (tv TValues) Uint64(key int) (uint64, error)
- func (tv TValues) Uint64IfAny(key int, defaultValue ...uint64) uint64
- func (tv TValues) Valid(r *http.Request) error
- func (tv TValues) ValidExpiry() bool
- func (tv TValues) ValidIP(r *http.Request) error
- type WriteErr
Constants ΒΆ
const ( HeaderSize = magicCodeSize + saltSize + metadataSize MaxValues int = maskNValues )
const ( // The expiry is stored in 3 bytes, with a 30 seconds precision, starting from 2022. ExpiryStartYear = 2022 ExpiryMaxYear = ExpiryStartYear + rangeInYears ExpirySize = 3 // 24 bits = 10 years with 20-second precision PrecisionInSeconds = 20 )
const ( HTTP = "http" HTTPS = "https" )
URL schemes.
const ( // Base91MinSize and ciphertextMinSize need to be adapted according // on any change about expiry encoding size, padding size... Base91MinSize = 42 )
const (
EnablePadding = false
)
Variables ΒΆ
This section is empty.
Functions ΒΆ
func BytesToUint64 ΒΆ
func DecodeExpiry ΒΆ
func Decrypt ΒΆ
Decrypt decrypts the ciphertext using any AEAD cipher. The parameter "all" contains the nonce + the ciphertext + the potential GCM tag. in the format "nonce|ciphertext|tag" where '|' indicates concatenation.
func Encrypt ΒΆ
Encrypt encrypts data using the given cipher. Output takes the form "nonce|ciphertext|tag" where '|' indicates concatenation.
"math/rand" is 40 times faster than "crypto/rand" see: https://github.com/SimonWaldherr/golang-benchmarks#random
func Marshal ΒΆ
Marshal serializes a TValues in a short way. The format starts with a magic code (2 bytes), followed by the expiry time, the client IP, the user-defined values, and ends with random salt as padding for a final size aligned on 32 bits.
func NewAESCipher ΒΆ
NewAESCipher creates a cipher with Encrypt() and Decrypt() functions for AEAD (Authenticated Encryption with Associated Data).
Implementation is based on: - https://en.wikipedia.org/wiki/Authenticated_encryption - https://go.dev/blog/tls-cipher-suites - https://github.com/gtank/cryptopasta
The underlying algorithm is AES-128 GCM: - AES is a symmetric encryption, faster than asymmetric (e.g. RSA) - 128-bit key is sufficient for most usages (256-bits is much slower)
Assumption design: This function should be used on AES-supported hardware like AMD/Intel processors providing optimized AES instructions set. If this is not your case, please use NewChaChaCipher().
GCM (Galois Counter Mode) is preferred over CBC (Cipher Block Chaining) because of CBC-specific attacks and configuration difficulties. But, CBC is faster and does not have any weakness in our server-side use case. If requested, this implementation may change to use CBC. Your feedback or suggestions are welcome, please contact us.
This package follows the Golang Cryptography Principles: https://golang.org/design/cryptography-principles Secure implementation, faultlessly configurable, performant and state-of-the-art updated.
func NewChaCipher ΒΆ
NewChaCipher creates a cipher for ChaCha20-Poly1305. with Encrypt() and Decrypt() functions.
func Uint64ToBytes ΒΆ
Uint64ToBytes works on the byte-level encoding of the Incorruptible token.
Types ΒΆ
type Incorruptible ΒΆ
type Incorruptible struct { SetIP bool // If true => put the remote IP in the token. // contains filtered or unexported fields }
func New ΒΆ
func New(writeErr WriteErr, urls []*url.URL, secretKey []byte, cookieName string, maxAge int, setIP bool) *Incorruptible
New creates a new Incorruptible. The order of the parameters are consistent with garcon.NewJWTChecker (see Teal-Finance/Garcon). The Garcon middleware constructors use a garcon.Writer as first parameter. Please share your thoughts/feedback, we can still change that.
func (*Incorruptible) BearerToken ΒΆ
func (incorr *Incorruptible) BearerToken(r *http.Request) (string, error)
BearerToken returns the token (in base91 format) from the HTTP Authorization header.
func (*Incorruptible) Chk ΒΆ
func (incorr *Incorruptible) Chk(next http.Handler) http.Handler
Chk is a middleware accepting requests only if it has a valid Incorruptible cookie, Chk does not consider the "Authorization" header (only the token within the cookie). Use instead the Vet() middleware to also verify the "Authorization" header. Chk finally stores the decoded token in the request context. In dev. mode, Chk accepts requests without valid cookie but does not store invalid tokens.
func (*Incorruptible) Cookie ΒΆ
func (incorr *Incorruptible) Cookie(_ int) *http.Cookie
Cookie returns a pointer to the default cookie values. This can be used to customize some cookie values (may break), and also to facilitate testing.
func (*Incorruptible) CookieName ΒΆ
func (incorr *Incorruptible) CookieName() string
func (*Incorruptible) CookieToken ΒΆ
func (incorr *Incorruptible) CookieToken(r *http.Request) (string, error)
CookieToken returns the token (in base91 format) from the cookie.
func (*Incorruptible) DeadCookie ΒΆ
func (incorr *Incorruptible) DeadCookie() *http.Cookie
DeadCookie returns an Incorruptible cookie without Value and with "Max-Age=0" in order to delete the Incorruptible cookie in the current HTTP session.
Example:
func logout(w http.ResponseWriter, r *http.Request) { http.SetCookie(w, Incorruptible.DeadCookie()) }
func (*Incorruptible) DecodeBearerToken ΒΆ
func (incorr *Incorruptible) DecodeBearerToken(r *http.Request) (TValues, error)
func (*Incorruptible) DecodeCookieToken ΒΆ
func (incorr *Incorruptible) DecodeCookieToken(r *http.Request) (TValues, error)
func (*Incorruptible) DecodeToken ΒΆ
func (incorr *Incorruptible) DecodeToken(r *http.Request) (TValues, []any)
func (*Incorruptible) NewCookie ΒΆ
func (incorr *Incorruptible) NewCookie(r *http.Request, keyValues ...KVal) (*http.Cookie, TValues, error)
NewCookie creates a new cookie based on default values. the HTTP request parameter is used to get the remote IP (only when incorr.SetIP is true).
func (*Incorruptible) NewCookieFromToken ΒΆ
func (incorr *Incorruptible) NewCookieFromToken(token string, maxAge int) *http.Cookie
func (*Incorruptible) NewCookieFromValues ΒΆ
func (incorr *Incorruptible) NewCookieFromValues(tv TValues) (*http.Cookie, error)
func (*Incorruptible) NewTValues ΒΆ
func (*Incorruptible) Set ΒΆ
func (incorr *Incorruptible) Set(next http.Handler) http.Handler
Set is a middleware putting a "session" cookie when the request has no valid "incorruptible" token. The token is searched in the "session" cookie and in the first "Authorization" header. The "session" cookie (that is added in the response) contains a minimalist "incorruptible" token. Finally, Set stores the decoded token in the request context.
func (*Incorruptible) Vet ΒΆ
func (incorr *Incorruptible) Vet(next http.Handler) http.Handler
Vet is a middleware accepting requests having a valid Incorruptible token either in the cookie or in the first "Authorization" header. Vet finally stores the decoded token in the request context. In dev. mode, Vet accepts requests without a valid token but does not store invalid tokens.
type Metadata ΒΆ
type Metadata byte
func GetMetadata ΒΆ
func NewMetadata ΒΆ
NewMetadata sets the metadata bits within the token.
func (Metadata) IsCompressed ΒΆ
func (Metadata) PayloadMinSize ΒΆ
type Serializer ΒΆ
type Serializer struct {
// contains filtered or unexported fields
}
type TValues ΒΆ
type TValues struct { Expires int64 // Unix time UTC (seconds since 1970) IP net.IP // TOTO: use netip.Addr Values [][]byte }
TValues (Token Values) represents the decoded form of an Incorruptible token.
func EmptyTValues ΒΆ
func EmptyTValues() TValues
EmptyTValues returns an empty TValues that can be used to generate a minimalist token.
func NewTValues ΒΆ
NewTValues returns an empty TValues that can be used to generate a minimalist token.
func (TValues) CompareExpiry ΒΆ
func (TValues) ExpiryTime ΒΆ
func (TValues) NoIP ΒΆ
NoIP returns true when no IP is set within the TValues. NoIP returns false when an IP is present.
func (*TValues) SetExpiryDuration ΒΆ
func (*TValues) SetExpiryTime ΒΆ
func (*TValues) ShortenIP4Length ΒΆ
func (tv *TValues) ShortenIP4Length()