auth/jwk/jwk.go
2025-01-17 01:30:05 +03:00

121 lines
2.2 KiB
Go

package jwk
import (
"encoding/json"
"errors"
"io"
"git.daebt.dev/golang/auth/algo"
"git.daebt.dev/golang/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
}