Initial QSfera import

This commit is contained in:
Курнат Андрей
2026-06-07 10:20:04 +03:00
commit 2315f25754
16485 changed files with 4826827 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
load("@rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "jwa",
srcs = [
"compression_gen.go",
"content_encryption_gen.go",
"elliptic_gen.go",
"jwa.go",
"key_encryption_gen.go",
"key_type_gen.go",
"options_gen.go",
"signature_gen.go",
],
importpath = "github.com/lestrrat-go/jwx/v3/jwa",
visibility = ["//visibility:public"],
deps = [
"//internal/tokens",
"@com_github_lestrrat_go_option_v2//:option",
],
)
go_test(
name = "jwa_test",
srcs = [
"compression_gen_test.go",
"content_encryption_gen_test.go",
"elliptic_gen_test.go",
"jwa_test.go",
"key_encryption_gen_test.go",
"key_type_gen_test.go",
"signature_gen_test.go",
],
deps = [
":jwa",
"@com_github_stretchr_testify//require",
"@com_github_lestrrat_go_option_v2//:option",
],
)
alias(
name = "go_default_library",
actual = ":jwa",
visibility = ["//visibility:public"],
)
+3
View File
@@ -0,0 +1,3 @@
# JWA [![Go Reference](https://pkg.go.dev/badge/github.com/lestrrat-go/jwx/v3/jwa.svg)](https://pkg.go.dev/github.com/lestrrat-go/jwx/v3/jwa)
Package [github.com/lestrrat-go/jwx/v3/jwa](./jwa) defines the various algorithm described in [RFC7518](https://tools.ietf.org/html/rfc7518)
+153
View File
@@ -0,0 +1,153 @@
// Code generated by tools/cmd/genjwa/main.go. DO NOT EDIT.
package jwa
import (
"encoding/json"
"fmt"
"sort"
"sync"
)
var muAllCompressionAlgorithm sync.RWMutex
var allCompressionAlgorithm = map[string]CompressionAlgorithm{}
var muListCompressionAlgorithm sync.RWMutex
var listCompressionAlgorithm []CompressionAlgorithm
var builtinCompressionAlgorithm = map[string]struct{}{}
func init() {
// builtin values for CompressionAlgorithm
algorithms := make([]CompressionAlgorithm, 2)
algorithms[0] = NewCompressionAlgorithm("DEF")
algorithms[1] = NewCompressionAlgorithm("")
RegisterCompressionAlgorithm(algorithms...)
}
// Deflate returns an object representing the "DEF" content compression algorithm value. Using this value specifies that the content should be compressed using DEFLATE (RFC 1951).
func Deflate() CompressionAlgorithm {
return lookupBuiltinCompressionAlgorithm("DEF")
}
// NoCompress returns an object representing an empty compression algorithm value. Using this value specifies that the content should not be compressed.
func NoCompress() CompressionAlgorithm {
return lookupBuiltinCompressionAlgorithm("")
}
func lookupBuiltinCompressionAlgorithm(name string) CompressionAlgorithm {
muAllCompressionAlgorithm.RLock()
v, ok := allCompressionAlgorithm[name]
muAllCompressionAlgorithm.RUnlock()
if !ok {
panic(fmt.Sprintf(`jwa: CompressionAlgorithm %q not registered`, name))
}
return v
}
// CompressionAlgorithm represents the compression algorithms as described in https://tools.ietf.org/html/rfc7518#section-7.3
type CompressionAlgorithm struct {
name string
deprecated bool
}
func (s CompressionAlgorithm) String() string {
return s.name
}
// IsDeprecated returns true if the CompressionAlgorithm object is deprecated.
func (s CompressionAlgorithm) IsDeprecated() bool {
return s.deprecated
}
// EmptyCompressionAlgorithm returns an empty CompressionAlgorithm object, used as a zero value.
func EmptyCompressionAlgorithm() CompressionAlgorithm {
return CompressionAlgorithm{}
}
// NewCompressionAlgorithm creates a new CompressionAlgorithm object with the given name.
func NewCompressionAlgorithm(name string, options ...NewAlgorithmOption) CompressionAlgorithm {
var deprecated bool
for _, option := range options {
switch option.Ident() {
case identDeprecated{}:
if err := option.Value(&deprecated); err != nil {
panic("jwa.NewCompressionAlgorithm: WithDeprecated option must be a boolean")
}
}
}
return CompressionAlgorithm{name: name, deprecated: deprecated}
}
// LookupCompressionAlgorithm returns the CompressionAlgorithm object for the given name.
func LookupCompressionAlgorithm(name string) (CompressionAlgorithm, bool) {
muAllCompressionAlgorithm.RLock()
v, ok := allCompressionAlgorithm[name]
muAllCompressionAlgorithm.RUnlock()
return v, ok
}
// RegisterCompressionAlgorithm registers a new CompressionAlgorithm. The signature value must be immutable
// and safe to be used by multiple goroutines, as it is going to be shared with all other users of this library.
func RegisterCompressionAlgorithm(algorithms ...CompressionAlgorithm) {
muAllCompressionAlgorithm.Lock()
for _, alg := range algorithms {
allCompressionAlgorithm[alg.String()] = alg
}
muAllCompressionAlgorithm.Unlock()
rebuildCompressionAlgorithm()
}
// UnregisterCompressionAlgorithm unregisters a CompressionAlgorithm from its known database.
// Non-existent entries, as well as built-in algorithms will silently be ignored.
func UnregisterCompressionAlgorithm(algorithms ...CompressionAlgorithm) {
muAllCompressionAlgorithm.Lock()
for _, alg := range algorithms {
if _, ok := builtinCompressionAlgorithm[alg.String()]; ok {
continue
}
delete(allCompressionAlgorithm, alg.String())
}
muAllCompressionAlgorithm.Unlock()
rebuildCompressionAlgorithm()
}
func rebuildCompressionAlgorithm() {
list := make([]CompressionAlgorithm, 0, len(allCompressionAlgorithm))
muAllCompressionAlgorithm.RLock()
for _, v := range allCompressionAlgorithm {
list = append(list, v)
}
muAllCompressionAlgorithm.RUnlock()
sort.Slice(list, func(i, j int) bool {
return list[i].String() < list[j].String()
})
muListCompressionAlgorithm.Lock()
listCompressionAlgorithm = list
muListCompressionAlgorithm.Unlock()
}
// CompressionAlgorithms returns a list of all available values for CompressionAlgorithm.
func CompressionAlgorithms() []CompressionAlgorithm {
muListCompressionAlgorithm.RLock()
defer muListCompressionAlgorithm.RUnlock()
return listCompressionAlgorithm
}
// MarshalJSON serializes the CompressionAlgorithm object to a JSON string.
func (s CompressionAlgorithm) MarshalJSON() ([]byte, error) {
return json.Marshal(s.String())
}
// UnmarshalJSON deserializes the JSON string to a CompressionAlgorithm object.
func (s *CompressionAlgorithm) UnmarshalJSON(data []byte) error {
var name string
if err := json.Unmarshal(data, &name); err != nil {
return fmt.Errorf(`failed to unmarshal CompressionAlgorithm: %w`, err)
}
v, ok := LookupCompressionAlgorithm(name)
if !ok {
return fmt.Errorf(`unknown CompressionAlgorithm: %q`, name)
}
*s = v
return nil
}
@@ -0,0 +1,179 @@
// Code generated by tools/cmd/genjwa/main.go. DO NOT EDIT.
package jwa
import (
"encoding/json"
"fmt"
"sort"
"sync"
"github.com/lestrrat-go/jwx/v3/internal/tokens"
)
var muAllContentEncryptionAlgorithm sync.RWMutex
var allContentEncryptionAlgorithm = map[string]ContentEncryptionAlgorithm{}
var muListContentEncryptionAlgorithm sync.RWMutex
var listContentEncryptionAlgorithm []ContentEncryptionAlgorithm
var builtinContentEncryptionAlgorithm = map[string]struct{}{}
func init() {
// builtin values for ContentEncryptionAlgorithm
algorithms := make([]ContentEncryptionAlgorithm, 6)
algorithms[0] = NewContentEncryptionAlgorithm(tokens.A128CBC_HS256)
algorithms[1] = NewContentEncryptionAlgorithm(tokens.A128GCM)
algorithms[2] = NewContentEncryptionAlgorithm(tokens.A192CBC_HS384)
algorithms[3] = NewContentEncryptionAlgorithm(tokens.A192GCM)
algorithms[4] = NewContentEncryptionAlgorithm(tokens.A256CBC_HS512)
algorithms[5] = NewContentEncryptionAlgorithm(tokens.A256GCM)
RegisterContentEncryptionAlgorithm(algorithms...)
}
// A128CBC_HS256 returns an object representing A128CBC-HS256. Using this value specifies that the content should be encrypted using AES-CBC + HMAC-SHA256 (128).
func A128CBC_HS256() ContentEncryptionAlgorithm {
return lookupBuiltinContentEncryptionAlgorithm(tokens.A128CBC_HS256)
}
// A128GCM returns an object representing A128GCM. Using this value specifies that the content should be encrypted using AES-GCM (128).
func A128GCM() ContentEncryptionAlgorithm {
return lookupBuiltinContentEncryptionAlgorithm(tokens.A128GCM)
}
// A192CBC_HS384 returns an object representing A192CBC-HS384. Using this value specifies that the content should be encrypted using AES-CBC + HMAC-SHA384 (192).
func A192CBC_HS384() ContentEncryptionAlgorithm {
return lookupBuiltinContentEncryptionAlgorithm(tokens.A192CBC_HS384)
}
// A192GCM returns an object representing A192GCM. Using this value specifies that the content should be encrypted using AES-GCM (192).
func A192GCM() ContentEncryptionAlgorithm {
return lookupBuiltinContentEncryptionAlgorithm(tokens.A192GCM)
}
// A256CBC_HS512 returns an object representing A256CBC-HS512. Using this value specifies that the content should be encrypted using AES-CBC + HMAC-SHA512 (256).
func A256CBC_HS512() ContentEncryptionAlgorithm {
return lookupBuiltinContentEncryptionAlgorithm(tokens.A256CBC_HS512)
}
// A256GCM returns an object representing A256GCM. Using this value specifies that the content should be encrypted using AES-GCM (256).
func A256GCM() ContentEncryptionAlgorithm {
return lookupBuiltinContentEncryptionAlgorithm(tokens.A256GCM)
}
func lookupBuiltinContentEncryptionAlgorithm(name string) ContentEncryptionAlgorithm {
muAllContentEncryptionAlgorithm.RLock()
v, ok := allContentEncryptionAlgorithm[name]
muAllContentEncryptionAlgorithm.RUnlock()
if !ok {
panic(fmt.Sprintf(`jwa: ContentEncryptionAlgorithm %q not registered`, name))
}
return v
}
// ContentEncryptionAlgorithm represents the various encryption algorithms as described in https://tools.ietf.org/html/rfc7518#section-5
type ContentEncryptionAlgorithm struct {
name string
deprecated bool
}
func (s ContentEncryptionAlgorithm) String() string {
return s.name
}
// IsDeprecated returns true if the ContentEncryptionAlgorithm object is deprecated.
func (s ContentEncryptionAlgorithm) IsDeprecated() bool {
return s.deprecated
}
// EmptyContentEncryptionAlgorithm returns an empty ContentEncryptionAlgorithm object, used as a zero value.
func EmptyContentEncryptionAlgorithm() ContentEncryptionAlgorithm {
return ContentEncryptionAlgorithm{}
}
// NewContentEncryptionAlgorithm creates a new ContentEncryptionAlgorithm object with the given name.
func NewContentEncryptionAlgorithm(name string, options ...NewAlgorithmOption) ContentEncryptionAlgorithm {
var deprecated bool
for _, option := range options {
switch option.Ident() {
case identDeprecated{}:
if err := option.Value(&deprecated); err != nil {
panic("jwa.NewContentEncryptionAlgorithm: WithDeprecated option must be a boolean")
}
}
}
return ContentEncryptionAlgorithm{name: name, deprecated: deprecated}
}
// LookupContentEncryptionAlgorithm returns the ContentEncryptionAlgorithm object for the given name.
func LookupContentEncryptionAlgorithm(name string) (ContentEncryptionAlgorithm, bool) {
muAllContentEncryptionAlgorithm.RLock()
v, ok := allContentEncryptionAlgorithm[name]
muAllContentEncryptionAlgorithm.RUnlock()
return v, ok
}
// RegisterContentEncryptionAlgorithm registers a new ContentEncryptionAlgorithm. The signature value must be immutable
// and safe to be used by multiple goroutines, as it is going to be shared with all other users of this library.
func RegisterContentEncryptionAlgorithm(algorithms ...ContentEncryptionAlgorithm) {
muAllContentEncryptionAlgorithm.Lock()
for _, alg := range algorithms {
allContentEncryptionAlgorithm[alg.String()] = alg
}
muAllContentEncryptionAlgorithm.Unlock()
rebuildContentEncryptionAlgorithm()
}
// UnregisterContentEncryptionAlgorithm unregisters a ContentEncryptionAlgorithm from its known database.
// Non-existent entries, as well as built-in algorithms will silently be ignored.
func UnregisterContentEncryptionAlgorithm(algorithms ...ContentEncryptionAlgorithm) {
muAllContentEncryptionAlgorithm.Lock()
for _, alg := range algorithms {
if _, ok := builtinContentEncryptionAlgorithm[alg.String()]; ok {
continue
}
delete(allContentEncryptionAlgorithm, alg.String())
}
muAllContentEncryptionAlgorithm.Unlock()
rebuildContentEncryptionAlgorithm()
}
func rebuildContentEncryptionAlgorithm() {
list := make([]ContentEncryptionAlgorithm, 0, len(allContentEncryptionAlgorithm))
muAllContentEncryptionAlgorithm.RLock()
for _, v := range allContentEncryptionAlgorithm {
list = append(list, v)
}
muAllContentEncryptionAlgorithm.RUnlock()
sort.Slice(list, func(i, j int) bool {
return list[i].String() < list[j].String()
})
muListContentEncryptionAlgorithm.Lock()
listContentEncryptionAlgorithm = list
muListContentEncryptionAlgorithm.Unlock()
}
// ContentEncryptionAlgorithms returns a list of all available values for ContentEncryptionAlgorithm.
func ContentEncryptionAlgorithms() []ContentEncryptionAlgorithm {
muListContentEncryptionAlgorithm.RLock()
defer muListContentEncryptionAlgorithm.RUnlock()
return listContentEncryptionAlgorithm
}
// MarshalJSON serializes the ContentEncryptionAlgorithm object to a JSON string.
func (s ContentEncryptionAlgorithm) MarshalJSON() ([]byte, error) {
return json.Marshal(s.String())
}
// UnmarshalJSON deserializes the JSON string to a ContentEncryptionAlgorithm object.
func (s *ContentEncryptionAlgorithm) UnmarshalJSON(data []byte) error {
var name string
if err := json.Unmarshal(data, &name); err != nil {
return fmt.Errorf(`failed to unmarshal ContentEncryptionAlgorithm: %w`, err)
}
v, ok := LookupContentEncryptionAlgorithm(name)
if !ok {
return fmt.Errorf(`unknown ContentEncryptionAlgorithm: %q`, name)
}
*s = v
return nil
}
+190
View File
@@ -0,0 +1,190 @@
// Code generated by tools/cmd/genjwa/main.go. DO NOT EDIT.
package jwa
import (
"encoding/json"
"fmt"
"sort"
"sync"
)
var muAllEllipticCurveAlgorithm sync.RWMutex
var allEllipticCurveAlgorithm = map[string]EllipticCurveAlgorithm{}
var muListEllipticCurveAlgorithm sync.RWMutex
var listEllipticCurveAlgorithm []EllipticCurveAlgorithm
var builtinEllipticCurveAlgorithm = map[string]struct{}{}
func init() {
// builtin values for EllipticCurveAlgorithm
algorithms := make([]EllipticCurveAlgorithm, 7)
algorithms[0] = NewEllipticCurveAlgorithm("Ed25519")
algorithms[1] = NewEllipticCurveAlgorithm("Ed448")
algorithms[2] = NewEllipticCurveAlgorithm("P-256")
algorithms[3] = NewEllipticCurveAlgorithm("P-384")
algorithms[4] = NewEllipticCurveAlgorithm("P-521")
algorithms[5] = NewEllipticCurveAlgorithm("X25519")
algorithms[6] = NewEllipticCurveAlgorithm("X448")
RegisterEllipticCurveAlgorithm(algorithms...)
}
// Ed25519 returns an object representing Ed25519 algorithm for EdDSA operations.
func Ed25519() EllipticCurveAlgorithm {
return lookupBuiltinEllipticCurveAlgorithm("Ed25519")
}
// Ed448 returns an object representing Ed448 algorithm for EdDSA operations.
func Ed448() EllipticCurveAlgorithm {
return lookupBuiltinEllipticCurveAlgorithm("Ed448")
}
var invalidEllipticCurve = NewEllipticCurveAlgorithm("P-invalid")
// InvalidEllipticCurve returns an object representing an invalid elliptic curve.
func InvalidEllipticCurve() EllipticCurveAlgorithm {
return invalidEllipticCurve
}
// P256 returns an object representing P-256 algorithm for ECDSA operations.
func P256() EllipticCurveAlgorithm {
return lookupBuiltinEllipticCurveAlgorithm("P-256")
}
// P384 returns an object representing P-384 algorithm for ECDSA operations.
func P384() EllipticCurveAlgorithm {
return lookupBuiltinEllipticCurveAlgorithm("P-384")
}
// P521 returns an object representing P-521 algorithm for ECDSA operations.
func P521() EllipticCurveAlgorithm {
return lookupBuiltinEllipticCurveAlgorithm("P-521")
}
// X25519 returns an object representing X25519 algorithm for ECDH operations.
func X25519() EllipticCurveAlgorithm {
return lookupBuiltinEllipticCurveAlgorithm("X25519")
}
// X448 returns an object representing X448 algorithm for ECDH operations.
func X448() EllipticCurveAlgorithm {
return lookupBuiltinEllipticCurveAlgorithm("X448")
}
func lookupBuiltinEllipticCurveAlgorithm(name string) EllipticCurveAlgorithm {
muAllEllipticCurveAlgorithm.RLock()
v, ok := allEllipticCurveAlgorithm[name]
muAllEllipticCurveAlgorithm.RUnlock()
if !ok {
panic(fmt.Sprintf(`jwa: EllipticCurveAlgorithm %q not registered`, name))
}
return v
}
// EllipticCurveAlgorithm represents the algorithms used for EC keys
type EllipticCurveAlgorithm struct {
name string
deprecated bool
}
func (s EllipticCurveAlgorithm) String() string {
return s.name
}
// IsDeprecated returns true if the EllipticCurveAlgorithm object is deprecated.
func (s EllipticCurveAlgorithm) IsDeprecated() bool {
return s.deprecated
}
// EmptyEllipticCurveAlgorithm returns an empty EllipticCurveAlgorithm object, used as a zero value.
func EmptyEllipticCurveAlgorithm() EllipticCurveAlgorithm {
return EllipticCurveAlgorithm{}
}
// NewEllipticCurveAlgorithm creates a new EllipticCurveAlgorithm object with the given name.
func NewEllipticCurveAlgorithm(name string, options ...NewAlgorithmOption) EllipticCurveAlgorithm {
var deprecated bool
for _, option := range options {
switch option.Ident() {
case identDeprecated{}:
if err := option.Value(&deprecated); err != nil {
panic("jwa.NewEllipticCurveAlgorithm: WithDeprecated option must be a boolean")
}
}
}
return EllipticCurveAlgorithm{name: name, deprecated: deprecated}
}
// LookupEllipticCurveAlgorithm returns the EllipticCurveAlgorithm object for the given name.
func LookupEllipticCurveAlgorithm(name string) (EllipticCurveAlgorithm, bool) {
muAllEllipticCurveAlgorithm.RLock()
v, ok := allEllipticCurveAlgorithm[name]
muAllEllipticCurveAlgorithm.RUnlock()
return v, ok
}
// RegisterEllipticCurveAlgorithm registers a new EllipticCurveAlgorithm. The signature value must be immutable
// and safe to be used by multiple goroutines, as it is going to be shared with all other users of this library.
func RegisterEllipticCurveAlgorithm(algorithms ...EllipticCurveAlgorithm) {
muAllEllipticCurveAlgorithm.Lock()
for _, alg := range algorithms {
allEllipticCurveAlgorithm[alg.String()] = alg
}
muAllEllipticCurveAlgorithm.Unlock()
rebuildEllipticCurveAlgorithm()
}
// UnregisterEllipticCurveAlgorithm unregisters a EllipticCurveAlgorithm from its known database.
// Non-existent entries, as well as built-in algorithms will silently be ignored.
func UnregisterEllipticCurveAlgorithm(algorithms ...EllipticCurveAlgorithm) {
muAllEllipticCurveAlgorithm.Lock()
for _, alg := range algorithms {
if _, ok := builtinEllipticCurveAlgorithm[alg.String()]; ok {
continue
}
delete(allEllipticCurveAlgorithm, alg.String())
}
muAllEllipticCurveAlgorithm.Unlock()
rebuildEllipticCurveAlgorithm()
}
func rebuildEllipticCurveAlgorithm() {
list := make([]EllipticCurveAlgorithm, 0, len(allEllipticCurveAlgorithm))
muAllEllipticCurveAlgorithm.RLock()
for _, v := range allEllipticCurveAlgorithm {
list = append(list, v)
}
muAllEllipticCurveAlgorithm.RUnlock()
sort.Slice(list, func(i, j int) bool {
return list[i].String() < list[j].String()
})
muListEllipticCurveAlgorithm.Lock()
listEllipticCurveAlgorithm = list
muListEllipticCurveAlgorithm.Unlock()
}
// EllipticCurveAlgorithms returns a list of all available values for EllipticCurveAlgorithm.
func EllipticCurveAlgorithms() []EllipticCurveAlgorithm {
muListEllipticCurveAlgorithm.RLock()
defer muListEllipticCurveAlgorithm.RUnlock()
return listEllipticCurveAlgorithm
}
// MarshalJSON serializes the EllipticCurveAlgorithm object to a JSON string.
func (s EllipticCurveAlgorithm) MarshalJSON() ([]byte, error) {
return json.Marshal(s.String())
}
// UnmarshalJSON deserializes the JSON string to a EllipticCurveAlgorithm object.
func (s *EllipticCurveAlgorithm) UnmarshalJSON(data []byte) error {
var name string
if err := json.Unmarshal(data, &name); err != nil {
return fmt.Errorf(`failed to unmarshal EllipticCurveAlgorithm: %w`, err)
}
v, ok := LookupEllipticCurveAlgorithm(name)
if !ok {
return fmt.Errorf(`unknown EllipticCurveAlgorithm: %q`, name)
}
*s = v
return nil
}
+68
View File
@@ -0,0 +1,68 @@
//go:generate ../tools/cmd/genjwa.sh
// Package jwa defines the various algorithm described in https://tools.ietf.org/html/rfc7518
package jwa
import (
"errors"
"fmt"
)
// KeyAlgorithm is a workaround for jwk.Key being able to contain different
// types of algorithms in its `alg` field.
//
// Previously the storage for the `alg` field was represented as a string,
// but this caused some users to wonder why the field was not typed appropriately
// like other fields.
//
// Ideally we would like to keep track of Signature Algorithms and
// Key Encryption Algorithms separately, and force the APIs to
// type-check at compile time, but this allows users to pass a value from a
// jwk.Key directly
type KeyAlgorithm interface {
String() string
IsDeprecated() bool
}
var errInvalidKeyAlgorithm = errors.New(`invalid key algorithm`)
func ErrInvalidKeyAlgorithm() error {
return errInvalidKeyAlgorithm
}
// KeyAlgorithmFrom takes either a string, `jwa.SignatureAlgorithm`,
// `jwa.KeyEncryptionAlgorithm`, or `jwa.ContentEncryptionAlgorithm`.
// and returns a `jwa.KeyAlgorithm`.
//
// If the value cannot be handled, it returns an `jwa.InvalidKeyAlgorithm`
// object instead of returning an error. This design choice was made to allow
// users to directly pass the return value to functions such as `jws.Sign()`
func KeyAlgorithmFrom(v any) (KeyAlgorithm, error) {
switch v := v.(type) {
case SignatureAlgorithm:
return v, nil
case KeyEncryptionAlgorithm:
return v, nil
case ContentEncryptionAlgorithm:
return v, nil
case string:
salg, ok := LookupSignatureAlgorithm(v)
if ok {
return salg, nil
}
kalg, ok := LookupKeyEncryptionAlgorithm(v)
if ok {
return kalg, nil
}
calg, ok := LookupContentEncryptionAlgorithm(v)
if ok {
return calg, nil
}
return nil, fmt.Errorf(`invalid key value: %q: %w`, v, errInvalidKeyAlgorithm)
default:
return nil, fmt.Errorf(`invalid key type: %T: %w`, v, errInvalidKeyAlgorithm)
}
}
+268
View File
@@ -0,0 +1,268 @@
// Code generated by tools/cmd/genjwa/main.go. DO NOT EDIT.
package jwa
import (
"encoding/json"
"fmt"
"sort"
"sync"
"github.com/lestrrat-go/jwx/v3/internal/tokens"
)
var muAllKeyEncryptionAlgorithm sync.RWMutex
var allKeyEncryptionAlgorithm = map[string]KeyEncryptionAlgorithm{}
var muListKeyEncryptionAlgorithm sync.RWMutex
var listKeyEncryptionAlgorithm []KeyEncryptionAlgorithm
var builtinKeyEncryptionAlgorithm = map[string]struct{}{}
func init() {
// builtin values for KeyEncryptionAlgorithm
algorithms := make([]KeyEncryptionAlgorithm, 19)
algorithms[0] = NewKeyEncryptionAlgorithm(tokens.A128GCMKW, WithIsSymmetric(true))
algorithms[1] = NewKeyEncryptionAlgorithm(tokens.A128KW, WithIsSymmetric(true))
algorithms[2] = NewKeyEncryptionAlgorithm(tokens.A192GCMKW, WithIsSymmetric(true))
algorithms[3] = NewKeyEncryptionAlgorithm(tokens.A192KW, WithIsSymmetric(true))
algorithms[4] = NewKeyEncryptionAlgorithm(tokens.A256GCMKW, WithIsSymmetric(true))
algorithms[5] = NewKeyEncryptionAlgorithm(tokens.A256KW, WithIsSymmetric(true))
algorithms[6] = NewKeyEncryptionAlgorithm(tokens.DIRECT, WithIsSymmetric(true))
algorithms[7] = NewKeyEncryptionAlgorithm(tokens.ECDH_ES)
algorithms[8] = NewKeyEncryptionAlgorithm(tokens.ECDH_ES_A128KW)
algorithms[9] = NewKeyEncryptionAlgorithm(tokens.ECDH_ES_A192KW)
algorithms[10] = NewKeyEncryptionAlgorithm(tokens.ECDH_ES_A256KW)
algorithms[11] = NewKeyEncryptionAlgorithm(tokens.PBES2_HS256_A128KW, WithIsSymmetric(true))
algorithms[12] = NewKeyEncryptionAlgorithm(tokens.PBES2_HS384_A192KW, WithIsSymmetric(true))
algorithms[13] = NewKeyEncryptionAlgorithm(tokens.PBES2_HS512_A256KW, WithIsSymmetric(true))
algorithms[14] = NewKeyEncryptionAlgorithm(tokens.RSA1_5, WithDeprecated(true))
algorithms[15] = NewKeyEncryptionAlgorithm(tokens.RSA_OAEP)
algorithms[16] = NewKeyEncryptionAlgorithm(tokens.RSA_OAEP_256)
algorithms[17] = NewKeyEncryptionAlgorithm(tokens.RSA_OAEP_384)
algorithms[18] = NewKeyEncryptionAlgorithm(tokens.RSA_OAEP_512)
RegisterKeyEncryptionAlgorithm(algorithms...)
}
// A128GCMKW returns an object representing AES-GCM key wrap (128) key encryption algorithm.
func A128GCMKW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.A128GCMKW)
}
// A128KW returns an object representing AES key wrap (128) key encryption algorithm.
func A128KW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.A128KW)
}
// A192GCMKW returns an object representing AES-GCM key wrap (192) key encryption algorithm.
func A192GCMKW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.A192GCMKW)
}
// A192KW returns an object representing AES key wrap (192) key encryption algorithm.
func A192KW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.A192KW)
}
// A256GCMKW returns an object representing AES-GCM key wrap (256) key encryption algorithm.
func A256GCMKW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.A256GCMKW)
}
// A256KW returns an object representing AES key wrap (256) key encryption algorithm.
func A256KW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.A256KW)
}
// DIRECT returns an object representing Direct key encryption algorithm.
func DIRECT() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.DIRECT)
}
// ECDH_ES returns an object representing ECDH-ES key encryption algorithm.
func ECDH_ES() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.ECDH_ES)
}
// ECDH_ES_A128KW returns an object representing ECDH-ES + AES key wrap (128) key encryption algorithm.
func ECDH_ES_A128KW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.ECDH_ES_A128KW)
}
// ECDH_ES_A192KW returns an object representing ECDH-ES + AES key wrap (192) key encryption algorithm.
func ECDH_ES_A192KW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.ECDH_ES_A192KW)
}
// ECDH_ES_A256KW returns an object representing ECDH-ES + AES key wrap (256) key encryption algorithm.
func ECDH_ES_A256KW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.ECDH_ES_A256KW)
}
// PBES2_HS256_A128KW returns an object representing PBES2 + HMAC-SHA256 + AES key wrap (128) key encryption algorithm.
func PBES2_HS256_A128KW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.PBES2_HS256_A128KW)
}
// PBES2_HS384_A192KW returns an object representing PBES2 + HMAC-SHA384 + AES key wrap (192) key encryption algorithm.
func PBES2_HS384_A192KW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.PBES2_HS384_A192KW)
}
// PBES2_HS512_A256KW returns an object representing PBES2 + HMAC-SHA512 + AES key wrap (256) key encryption algorithm.
func PBES2_HS512_A256KW() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.PBES2_HS512_A256KW)
}
// RSA1_5 returns an object representing RSA-PKCS1v1.5 key encryption algorithm.
func RSA1_5() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.RSA1_5)
}
// RSA_OAEP returns an object representing RSA-OAEP-SHA1 key encryption algorithm.
func RSA_OAEP() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.RSA_OAEP)
}
// RSA_OAEP_256 returns an object representing RSA-OAEP-SHA256 key encryption algorithm.
func RSA_OAEP_256() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.RSA_OAEP_256)
}
// RSA_OAEP_384 returns an object representing RSA-OAEP-SHA384 key encryption algorithm.
func RSA_OAEP_384() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.RSA_OAEP_384)
}
// RSA_OAEP_512 returns an object representing RSA-OAEP-SHA512 key encryption algorithm.
func RSA_OAEP_512() KeyEncryptionAlgorithm {
return lookupBuiltinKeyEncryptionAlgorithm(tokens.RSA_OAEP_512)
}
func lookupBuiltinKeyEncryptionAlgorithm(name string) KeyEncryptionAlgorithm {
muAllKeyEncryptionAlgorithm.RLock()
v, ok := allKeyEncryptionAlgorithm[name]
muAllKeyEncryptionAlgorithm.RUnlock()
if !ok {
panic(fmt.Sprintf(`jwa: KeyEncryptionAlgorithm %q not registered`, name))
}
return v
}
// KeyEncryptionAlgorithm represents the various encryption algorithms as described in https://tools.ietf.org/html/rfc7518#section-4.1
type KeyEncryptionAlgorithm struct {
name string
deprecated bool
isSymmetric bool
}
func (s KeyEncryptionAlgorithm) String() string {
return s.name
}
// IsDeprecated returns true if the KeyEncryptionAlgorithm object is deprecated.
func (s KeyEncryptionAlgorithm) IsDeprecated() bool {
return s.deprecated
}
// IsSymmetric returns true if the KeyEncryptionAlgorithm object is symmetric. Symmetric algorithms use the same key for both encryption and decryption.
func (s KeyEncryptionAlgorithm) IsSymmetric() bool {
return s.isSymmetric
}
// EmptyKeyEncryptionAlgorithm returns an empty KeyEncryptionAlgorithm object, used as a zero value.
func EmptyKeyEncryptionAlgorithm() KeyEncryptionAlgorithm {
return KeyEncryptionAlgorithm{}
}
// NewKeyEncryptionAlgorithm creates a new KeyEncryptionAlgorithm object with the given name.
func NewKeyEncryptionAlgorithm(name string, options ...NewKeyEncryptionAlgorithmOption) KeyEncryptionAlgorithm {
var deprecated bool
var isSymmetric bool
for _, option := range options {
switch option.Ident() {
case identIsSymmetric{}:
if err := option.Value(&isSymmetric); err != nil {
panic("jwa.NewKeyEncryptionAlgorithm: WithIsSymmetric option must be a boolean")
}
case identDeprecated{}:
if err := option.Value(&deprecated); err != nil {
panic("jwa.NewKeyEncryptionAlgorithm: WithDeprecated option must be a boolean")
}
}
}
return KeyEncryptionAlgorithm{name: name, deprecated: deprecated, isSymmetric: isSymmetric}
}
// LookupKeyEncryptionAlgorithm returns the KeyEncryptionAlgorithm object for the given name.
func LookupKeyEncryptionAlgorithm(name string) (KeyEncryptionAlgorithm, bool) {
muAllKeyEncryptionAlgorithm.RLock()
v, ok := allKeyEncryptionAlgorithm[name]
muAllKeyEncryptionAlgorithm.RUnlock()
return v, ok
}
// RegisterKeyEncryptionAlgorithm registers a new KeyEncryptionAlgorithm. The signature value must be immutable
// and safe to be used by multiple goroutines, as it is going to be shared with all other users of this library.
func RegisterKeyEncryptionAlgorithm(algorithms ...KeyEncryptionAlgorithm) {
muAllKeyEncryptionAlgorithm.Lock()
for _, alg := range algorithms {
allKeyEncryptionAlgorithm[alg.String()] = alg
}
muAllKeyEncryptionAlgorithm.Unlock()
rebuildKeyEncryptionAlgorithm()
}
// UnregisterKeyEncryptionAlgorithm unregisters a KeyEncryptionAlgorithm from its known database.
// Non-existent entries, as well as built-in algorithms will silently be ignored.
func UnregisterKeyEncryptionAlgorithm(algorithms ...KeyEncryptionAlgorithm) {
muAllKeyEncryptionAlgorithm.Lock()
for _, alg := range algorithms {
if _, ok := builtinKeyEncryptionAlgorithm[alg.String()]; ok {
continue
}
delete(allKeyEncryptionAlgorithm, alg.String())
}
muAllKeyEncryptionAlgorithm.Unlock()
rebuildKeyEncryptionAlgorithm()
}
func rebuildKeyEncryptionAlgorithm() {
list := make([]KeyEncryptionAlgorithm, 0, len(allKeyEncryptionAlgorithm))
muAllKeyEncryptionAlgorithm.RLock()
for _, v := range allKeyEncryptionAlgorithm {
list = append(list, v)
}
muAllKeyEncryptionAlgorithm.RUnlock()
sort.Slice(list, func(i, j int) bool {
return list[i].String() < list[j].String()
})
muListKeyEncryptionAlgorithm.Lock()
listKeyEncryptionAlgorithm = list
muListKeyEncryptionAlgorithm.Unlock()
}
// KeyEncryptionAlgorithms returns a list of all available values for KeyEncryptionAlgorithm.
func KeyEncryptionAlgorithms() []KeyEncryptionAlgorithm {
muListKeyEncryptionAlgorithm.RLock()
defer muListKeyEncryptionAlgorithm.RUnlock()
return listKeyEncryptionAlgorithm
}
// MarshalJSON serializes the KeyEncryptionAlgorithm object to a JSON string.
func (s KeyEncryptionAlgorithm) MarshalJSON() ([]byte, error) {
return json.Marshal(s.String())
}
// UnmarshalJSON deserializes the JSON string to a KeyEncryptionAlgorithm object.
func (s *KeyEncryptionAlgorithm) UnmarshalJSON(data []byte) error {
var name string
if err := json.Unmarshal(data, &name); err != nil {
return fmt.Errorf(`failed to unmarshal KeyEncryptionAlgorithm: %w`, err)
}
v, ok := LookupKeyEncryptionAlgorithm(name)
if !ok {
return fmt.Errorf(`unknown KeyEncryptionAlgorithm: %q`, name)
}
*s = v
return nil
}
+172
View File
@@ -0,0 +1,172 @@
// Code generated by tools/cmd/genjwa/main.go. DO NOT EDIT.
package jwa
import (
"encoding/json"
"fmt"
"sort"
"sync"
)
var muAllKeyType sync.RWMutex
var allKeyType = map[string]KeyType{}
var muListKeyType sync.RWMutex
var listKeyType []KeyType
var builtinKeyType = map[string]struct{}{}
func init() {
// builtin values for KeyType
algorithms := make([]KeyType, 4)
algorithms[0] = NewKeyType("EC")
algorithms[1] = NewKeyType("OKP")
algorithms[2] = NewKeyType("oct")
algorithms[3] = NewKeyType("RSA")
RegisterKeyType(algorithms...)
}
// EC returns an object representing EC. Elliptic Curve
func EC() KeyType {
return lookupBuiltinKeyType("EC")
}
var invalidKeyType = NewKeyType("")
// InvalidKeyType returns an object representing invalid key type. Invalid KeyType
func InvalidKeyType() KeyType {
return invalidKeyType
}
// OKP returns an object representing OKP. Octet string key pairs
func OKP() KeyType {
return lookupBuiltinKeyType("OKP")
}
// OctetSeq returns an object representing oct. Octet sequence (used to represent symmetric keys)
func OctetSeq() KeyType {
return lookupBuiltinKeyType("oct")
}
// RSA returns an object representing RSA. RSA
func RSA() KeyType {
return lookupBuiltinKeyType("RSA")
}
func lookupBuiltinKeyType(name string) KeyType {
muAllKeyType.RLock()
v, ok := allKeyType[name]
muAllKeyType.RUnlock()
if !ok {
panic(fmt.Sprintf(`jwa: KeyType %q not registered`, name))
}
return v
}
// KeyType represents the key type ("kty") that are supported
type KeyType struct {
name string
deprecated bool
}
func (s KeyType) String() string {
return s.name
}
// IsDeprecated returns true if the KeyType object is deprecated.
func (s KeyType) IsDeprecated() bool {
return s.deprecated
}
// EmptyKeyType returns an empty KeyType object, used as a zero value.
func EmptyKeyType() KeyType {
return KeyType{}
}
// NewKeyType creates a new KeyType object with the given name.
func NewKeyType(name string, options ...NewAlgorithmOption) KeyType {
var deprecated bool
for _, option := range options {
switch option.Ident() {
case identDeprecated{}:
if err := option.Value(&deprecated); err != nil {
panic("jwa.NewKeyType: WithDeprecated option must be a boolean")
}
}
}
return KeyType{name: name, deprecated: deprecated}
}
// LookupKeyType returns the KeyType object for the given name.
func LookupKeyType(name string) (KeyType, bool) {
muAllKeyType.RLock()
v, ok := allKeyType[name]
muAllKeyType.RUnlock()
return v, ok
}
// RegisterKeyType registers a new KeyType. The signature value must be immutable
// and safe to be used by multiple goroutines, as it is going to be shared with all other users of this library.
func RegisterKeyType(algorithms ...KeyType) {
muAllKeyType.Lock()
for _, alg := range algorithms {
allKeyType[alg.String()] = alg
}
muAllKeyType.Unlock()
rebuildKeyType()
}
// UnregisterKeyType unregisters a KeyType from its known database.
// Non-existent entries, as well as built-in algorithms will silently be ignored.
func UnregisterKeyType(algorithms ...KeyType) {
muAllKeyType.Lock()
for _, alg := range algorithms {
if _, ok := builtinKeyType[alg.String()]; ok {
continue
}
delete(allKeyType, alg.String())
}
muAllKeyType.Unlock()
rebuildKeyType()
}
func rebuildKeyType() {
list := make([]KeyType, 0, len(allKeyType))
muAllKeyType.RLock()
for _, v := range allKeyType {
list = append(list, v)
}
muAllKeyType.RUnlock()
sort.Slice(list, func(i, j int) bool {
return list[i].String() < list[j].String()
})
muListKeyType.Lock()
listKeyType = list
muListKeyType.Unlock()
}
// KeyTypes returns a list of all available values for KeyType.
func KeyTypes() []KeyType {
muListKeyType.RLock()
defer muListKeyType.RUnlock()
return listKeyType
}
// MarshalJSON serializes the KeyType object to a JSON string.
func (s KeyType) MarshalJSON() ([]byte, error) {
return json.Marshal(s.String())
}
// UnmarshalJSON deserializes the JSON string to a KeyType object.
func (s *KeyType) UnmarshalJSON(data []byte) error {
var name string
if err := json.Unmarshal(data, &name); err != nil {
return fmt.Errorf(`failed to unmarshal KeyType: %w`, err)
}
v, ok := LookupKeyType(name)
if !ok {
return fmt.Errorf(`unknown KeyType: %q`, name)
}
*s = v
return nil
}
+41
View File
@@ -0,0 +1,41 @@
package_name: jwa
output: jwa/options_gen.go
interfaces:
- name: NewAlgorithmOption
methods:
- newSignatureAlgorithmOption
- newKeyEncryptionAlgorithmOption
- newSignatureKeyEncryptionAlgorithmOption
comment: |
NewAlgorithmOption represents an option that can be passed to any of the constructor functions
- name: NewSignatureAlgorithmOption
methods:
- newSignatureAlgorithmOption
comment: |
NewSignatureAlgorithmOption represents an option that can be passed to the NewSignatureAlgorithm
- name: NewKeyEncryptionAlgorithmOption
methods:
- newKeyEncryptionAlgorithmOption
comment: |
NewKeyEncryptionAlgorithmOption represents an option that can be passed to the NewKeyEncryptionAlgorithm
- name: NewSignatureKeyEncryptionAlgorithmOption
comment: |
NewSignatureKeyEncryptionAlgorithmOption represents an option that can be passed to both
NewSignatureAlgorithm and NewKeyEncryptionAlgorithm
methods:
- newSignatureAlgorithmOption
- newKeyEncryptionAlgorithmOption
options:
- ident: IsSymmetric
interface: NewSignatureKeyEncryptionAlgorithmOption
argument_type: bool
comment: |
IsSymmetric specifies that the algorithm is symmetric
- ident: Deprecated
interface: NewAlgorithmOption
argument_type: bool
comment: |
WithDeprecated specifies that the algorithm is deprecated. In order to
un-deprecate an algorithm, you will have to create a new algorithm
with the same values but with the Deprecated option set to false, and
then call RegisterXXXXAlgorithm with the new algorithm.
+91
View File
@@ -0,0 +1,91 @@
// Code generated by tools/cmd/genoptions/main.go. DO NOT EDIT.
package jwa
import (
"github.com/lestrrat-go/option/v2"
)
type Option = option.Interface
// NewAlgorithmOption represents an option that can be passed to any of the constructor functions
type NewAlgorithmOption interface {
Option
newSignatureAlgorithmOption()
newKeyEncryptionAlgorithmOption()
newSignatureKeyEncryptionAlgorithmOption()
}
type newAlgorithmOption struct {
Option
}
func (*newAlgorithmOption) newSignatureAlgorithmOption() {}
func (*newAlgorithmOption) newKeyEncryptionAlgorithmOption() {}
func (*newAlgorithmOption) newSignatureKeyEncryptionAlgorithmOption() {}
// NewKeyEncryptionAlgorithmOption represents an option that can be passed to the NewKeyEncryptionAlgorithm
type NewKeyEncryptionAlgorithmOption interface {
Option
newKeyEncryptionAlgorithmOption()
}
type newKeyEncryptionAlgorithmOption struct {
Option
}
func (*newKeyEncryptionAlgorithmOption) newKeyEncryptionAlgorithmOption() {}
// NewSignatureAlgorithmOption represents an option that can be passed to the NewSignatureAlgorithm
type NewSignatureAlgorithmOption interface {
Option
newSignatureAlgorithmOption()
}
type newSignatureAlgorithmOption struct {
Option
}
func (*newSignatureAlgorithmOption) newSignatureAlgorithmOption() {}
// NewSignatureKeyEncryptionAlgorithmOption represents an option that can be passed to both
// NewSignatureAlgorithm and NewKeyEncryptionAlgorithm
type NewSignatureKeyEncryptionAlgorithmOption interface {
Option
newSignatureAlgorithmOption()
newKeyEncryptionAlgorithmOption()
}
type newSignatureKeyEncryptionAlgorithmOption struct {
Option
}
func (*newSignatureKeyEncryptionAlgorithmOption) newSignatureAlgorithmOption() {}
func (*newSignatureKeyEncryptionAlgorithmOption) newKeyEncryptionAlgorithmOption() {}
type identDeprecated struct{}
type identIsSymmetric struct{}
func (identDeprecated) String() string {
return "WithDeprecated"
}
func (identIsSymmetric) String() string {
return "WithIsSymmetric"
}
// WithDeprecated specifies that the algorithm is deprecated. In order to
// un-deprecate an algorithm, you will have to create a new algorithm
// with the same values but with the Deprecated option set to false, and
// then call RegisterXXXXAlgorithm with the new algorithm.
func WithDeprecated(v bool) NewAlgorithmOption {
return &newAlgorithmOption{option.New(identDeprecated{}, v)}
}
// IsSymmetric specifies that the algorithm is symmetric
func WithIsSymmetric(v bool) NewSignatureKeyEncryptionAlgorithmOption {
return &newSignatureKeyEncryptionAlgorithmOption{option.New(identIsSymmetric{}, v)}
}
+14
View File
@@ -0,0 +1,14 @@
//go:build jwx_es256k
package jwa
var secp256k1Algorithm = NewEllipticCurveAlgorithm("secp256k1")
// This constant is only available if compiled with jwx_es256k build tag
func Secp256k1() EllipticCurveAlgorithm {
return secp256k1Algorithm
}
func init() {
RegisterEllipticCurveAlgorithm(secp256k1Algorithm)
}
+242
View File
@@ -0,0 +1,242 @@
// Code generated by tools/cmd/genjwa/main.go. DO NOT EDIT.
package jwa
import (
"encoding/json"
"fmt"
"sort"
"sync"
)
var muAllSignatureAlgorithm sync.RWMutex
var allSignatureAlgorithm = map[string]SignatureAlgorithm{}
var muListSignatureAlgorithm sync.RWMutex
var listSignatureAlgorithm []SignatureAlgorithm
var builtinSignatureAlgorithm = map[string]struct{}{}
func init() {
// builtin values for SignatureAlgorithm
algorithms := make([]SignatureAlgorithm, 15)
algorithms[0] = NewSignatureAlgorithm("ES256")
algorithms[1] = NewSignatureAlgorithm("ES256K")
algorithms[2] = NewSignatureAlgorithm("ES384")
algorithms[3] = NewSignatureAlgorithm("ES512")
algorithms[4] = NewSignatureAlgorithm("EdDSA")
algorithms[5] = NewSignatureAlgorithm("HS256", WithIsSymmetric(true))
algorithms[6] = NewSignatureAlgorithm("HS384", WithIsSymmetric(true))
algorithms[7] = NewSignatureAlgorithm("HS512", WithIsSymmetric(true))
algorithms[8] = NewSignatureAlgorithm("none")
algorithms[9] = NewSignatureAlgorithm("PS256")
algorithms[10] = NewSignatureAlgorithm("PS384")
algorithms[11] = NewSignatureAlgorithm("PS512")
algorithms[12] = NewSignatureAlgorithm("RS256")
algorithms[13] = NewSignatureAlgorithm("RS384")
algorithms[14] = NewSignatureAlgorithm("RS512")
RegisterSignatureAlgorithm(algorithms...)
}
// ES256 returns an object representing ECDSA signature algorithm using P-256 curve and SHA-256.
func ES256() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("ES256")
}
// ES256K returns an object representing ECDSA signature algorithm using secp256k1 curve and SHA-256.
func ES256K() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("ES256K")
}
// ES384 returns an object representing ECDSA signature algorithm using P-384 curve and SHA-384.
func ES384() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("ES384")
}
// ES512 returns an object representing ECDSA signature algorithm using P-521 curve and SHA-512.
func ES512() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("ES512")
}
// EdDSA returns an object representing EdDSA signature algorithms.
func EdDSA() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("EdDSA")
}
// HS256 returns an object representing HMAC signature algorithm using SHA-256.
func HS256() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("HS256")
}
// HS384 returns an object representing HMAC signature algorithm using SHA-384.
func HS384() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("HS384")
}
// HS512 returns an object representing HMAC signature algorithm using SHA-512.
func HS512() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("HS512")
}
// NoSignature returns an object representing the lack of a signature algorithm. Using this value specifies that the content should not be signed, which you should avoid doing.
func NoSignature() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("none")
}
// PS256 returns an object representing RSASSA-PSS signature algorithm using SHA-256 and MGF1-SHA256.
func PS256() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("PS256")
}
// PS384 returns an object representing RSASSA-PSS signature algorithm using SHA-384 and MGF1-SHA384.
func PS384() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("PS384")
}
// PS512 returns an object representing RSASSA-PSS signature algorithm using SHA-512 and MGF1-SHA512.
func PS512() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("PS512")
}
// RS256 returns an object representing RSASSA-PKCS-v1.5 signature algorithm using SHA-256.
func RS256() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("RS256")
}
// RS384 returns an object representing RSASSA-PKCS-v1.5 signature algorithm using SHA-384.
func RS384() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("RS384")
}
// RS512 returns an object representing RSASSA-PKCS-v1.5 signature algorithm using SHA-512.
func RS512() SignatureAlgorithm {
return lookupBuiltinSignatureAlgorithm("RS512")
}
func lookupBuiltinSignatureAlgorithm(name string) SignatureAlgorithm {
muAllSignatureAlgorithm.RLock()
v, ok := allSignatureAlgorithm[name]
muAllSignatureAlgorithm.RUnlock()
if !ok {
panic(fmt.Sprintf(`jwa: SignatureAlgorithm %q not registered`, name))
}
return v
}
// SignatureAlgorithm represents the various signature algorithms as described in https://tools.ietf.org/html/rfc7518#section-3.1
type SignatureAlgorithm struct {
name string
deprecated bool
isSymmetric bool
}
func (s SignatureAlgorithm) String() string {
return s.name
}
// IsDeprecated returns true if the SignatureAlgorithm object is deprecated.
func (s SignatureAlgorithm) IsDeprecated() bool {
return s.deprecated
}
// IsSymmetric returns true if the SignatureAlgorithm object is symmetric. Symmetric algorithms use the same key for both encryption and decryption.
func (s SignatureAlgorithm) IsSymmetric() bool {
return s.isSymmetric
}
// EmptySignatureAlgorithm returns an empty SignatureAlgorithm object, used as a zero value.
func EmptySignatureAlgorithm() SignatureAlgorithm {
return SignatureAlgorithm{}
}
// NewSignatureAlgorithm creates a new SignatureAlgorithm object with the given name.
func NewSignatureAlgorithm(name string, options ...NewSignatureAlgorithmOption) SignatureAlgorithm {
var deprecated bool
var isSymmetric bool
for _, option := range options {
switch option.Ident() {
case identIsSymmetric{}:
if err := option.Value(&isSymmetric); err != nil {
panic("jwa.NewSignatureAlgorithm: WithIsSymmetric option must be a boolean")
}
case identDeprecated{}:
if err := option.Value(&deprecated); err != nil {
panic("jwa.NewSignatureAlgorithm: WithDeprecated option must be a boolean")
}
}
}
return SignatureAlgorithm{name: name, deprecated: deprecated, isSymmetric: isSymmetric}
}
// LookupSignatureAlgorithm returns the SignatureAlgorithm object for the given name.
func LookupSignatureAlgorithm(name string) (SignatureAlgorithm, bool) {
muAllSignatureAlgorithm.RLock()
v, ok := allSignatureAlgorithm[name]
muAllSignatureAlgorithm.RUnlock()
return v, ok
}
// RegisterSignatureAlgorithm registers a new SignatureAlgorithm. The signature value must be immutable
// and safe to be used by multiple goroutines, as it is going to be shared with all other users of this library.
func RegisterSignatureAlgorithm(algorithms ...SignatureAlgorithm) {
muAllSignatureAlgorithm.Lock()
for _, alg := range algorithms {
allSignatureAlgorithm[alg.String()] = alg
}
muAllSignatureAlgorithm.Unlock()
rebuildSignatureAlgorithm()
}
// UnregisterSignatureAlgorithm unregisters a SignatureAlgorithm from its known database.
// Non-existent entries, as well as built-in algorithms will silently be ignored.
func UnregisterSignatureAlgorithm(algorithms ...SignatureAlgorithm) {
muAllSignatureAlgorithm.Lock()
for _, alg := range algorithms {
if _, ok := builtinSignatureAlgorithm[alg.String()]; ok {
continue
}
delete(allSignatureAlgorithm, alg.String())
}
muAllSignatureAlgorithm.Unlock()
rebuildSignatureAlgorithm()
}
func rebuildSignatureAlgorithm() {
list := make([]SignatureAlgorithm, 0, len(allSignatureAlgorithm))
muAllSignatureAlgorithm.RLock()
for _, v := range allSignatureAlgorithm {
list = append(list, v)
}
muAllSignatureAlgorithm.RUnlock()
sort.Slice(list, func(i, j int) bool {
return list[i].String() < list[j].String()
})
muListSignatureAlgorithm.Lock()
listSignatureAlgorithm = list
muListSignatureAlgorithm.Unlock()
}
// SignatureAlgorithms returns a list of all available values for SignatureAlgorithm.
func SignatureAlgorithms() []SignatureAlgorithm {
muListSignatureAlgorithm.RLock()
defer muListSignatureAlgorithm.RUnlock()
return listSignatureAlgorithm
}
// MarshalJSON serializes the SignatureAlgorithm object to a JSON string.
func (s SignatureAlgorithm) MarshalJSON() ([]byte, error) {
return json.Marshal(s.String())
}
// UnmarshalJSON deserializes the JSON string to a SignatureAlgorithm object.
func (s *SignatureAlgorithm) UnmarshalJSON(data []byte) error {
var name string
if err := json.Unmarshal(data, &name); err != nil {
return fmt.Errorf(`failed to unmarshal SignatureAlgorithm: %w`, err)
}
v, ok := LookupSignatureAlgorithm(name)
if !ok {
return fmt.Errorf(`unknown SignatureAlgorithm: %q`, name)
}
*s = v
return nil
}