package jwk import ( "encoding/json" "errors" "io" "git.daebt.dev/auth/algo" "git.daebt.dev/auth/algo/rs" ) type Token interface { Algo() (algo.Algorithm, error) KeyId() []byte } type UseType string const ( UseSignature UseType = "sig" UseEncryption UseType = "enc" ) type Header struct { KeyId string `json:"kid,omitempty"` // KeyId уникальный идентификатор ключа KeyType algo.KeyType `json:"kty,omitempty"` // KeyType определяет криптографический алгоритм Use UseType `json:"use,omitempty"` // Use определяет использование ключа Algorithm algo.AlgorithmType `json:"alg,omitempty"` // Algorithm определяет алгоритм хеширования } type List struct { v []Token } func (l *List) SelectByKid(kid []byte) Token { val := string(kid) for _, v := range l.v { if string(v.KeyId()) == val { return v } } return nil } func (l *List) Range(f func(t Token) bool) { for _, v := range l.v { if !f(v) { return } } } func (l *List) Write(w io.Writer) error { return json.NewEncoder(w).Encode(&struct { Keys []Token `json:"keys"` }{l.v}) } func (l *List) WriteBytes() ([]byte, error) { return json.Marshal(&struct { Keys []Token `json:"keys"` }{l.v}) } func NewList(t ...Token) *List { return &List{ v: t, } } // ParseList func ParseList(buf []byte, parse func(json.RawMessage) Token) (*List, error) { rows := &struct { Keys []json.RawMessage `json:"keys"` }{} if err := json.Unmarshal(buf, rows); err != nil { return nil, err } l := &List{ v: []Token{}, } for _, v := range rows.Keys { if parse != nil { if val := parse(v); val != nil { l.v = append(l.v, val) continue } } var ( tkn Token info = &struct { KeyType algo.KeyType `json:"kty"` }{} ) if err := json.Unmarshal(v, info); err != nil { return l, err } switch info.KeyType { case rs.KeyRSA: tkn = new(TokenRSA) default: return l, errors.New("undefined key type") } if err := json.Unmarshal(v, tkn); err != nil { return l, err } l.v = append(l.v, tkn) } return l, nil }