forked from MicahParks/jwkset
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjwk.go
74 lines (63 loc) · 1.92 KB
/
jwk.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package jwkset
import (
"context"
"encoding/json"
"errors"
"fmt"
)
// KeyWithMeta is holds a Key and its metadata.
type KeyWithMeta[CustomKeyMeta any] struct {
ALG ALG
Custom CustomKeyMeta
Key interface{}
KeyID string
}
// NewKey creates a new KeyWithMeta.
func NewKey[CustomKeyMeta any](key interface{}, keyID string) KeyWithMeta[CustomKeyMeta] {
return KeyWithMeta[CustomKeyMeta]{
Key: key,
KeyID: keyID,
}
}
// JWKSet is a set of JSON Web Keys.
type JWKSet[CustomKeyMeta any] struct {
Store Storage[CustomKeyMeta]
}
// NewMemory creates a new in-memory JWKSet.
func NewMemory[CustomKeyMeta any]() JWKSet[CustomKeyMeta] {
return JWKSet[CustomKeyMeta]{
Store: NewMemoryStorage[CustomKeyMeta](),
}
}
// JSONPublic creates the JSON representation of the public keys in JWKSet.
func (j JWKSet[CustomKeyMeta]) JSONPublic(ctx context.Context) (json.RawMessage, error) {
return j.JSONWithOptions(ctx, KeyMarshalOptions{})
}
// JSONPrivate creates the JSON representation of the JWKSet public and private key material.
func (j JWKSet[CustomKeyMeta]) JSONPrivate(ctx context.Context) (json.RawMessage, error) {
options := KeyMarshalOptions{
AsymmetricPrivate: true,
Symmetric: true,
}
return j.JSONWithOptions(ctx, options)
}
// JSONWithOptions creates the JSON representation of the JWKSet with the given options.
func (j JWKSet[CustomKeyMeta]) JSONWithOptions(ctx context.Context, options KeyMarshalOptions) (json.RawMessage, error) {
jwks := JWKSMarshal{}
keys, err := j.Store.SnapshotKeys(ctx)
if err != nil {
return nil, fmt.Errorf("failed to read snapshot of all keys from storage: %w", err)
}
for _, meta := range keys {
jwk, err := KeyMarshal(meta, options)
if err != nil {
if errors.Is(err, ErrUnsupportedKeyType) {
// Ignore the key.
continue
}
return nil, fmt.Errorf("failed to marshal key: %w", err)
}
jwks.Keys = append(jwks.Keys, jwk)
}
return json.Marshal(jwks)
}