...
1
17
18 package jwt
19
20 import (
21 "fmt"
22 "strings"
23
24 jose "gopkg.in/square/go-jose.v2"
25 "gopkg.in/square/go-jose.v2/json"
26 )
27
28
29 type JSONWebToken struct {
30 payload func(k interface{}) ([]byte, error)
31 unverifiedPayload func() []byte
32 Headers []jose.Header
33 }
34
35 type NestedJSONWebToken struct {
36 enc *jose.JSONWebEncryption
37 Headers []jose.Header
38 }
39
40
41 func (t *JSONWebToken) Claims(key interface{}, dest ...interface{}) error {
42 payloadKey := tryJWKS(t.Headers, key)
43
44 b, err := t.payload(payloadKey)
45 if err != nil {
46 return err
47 }
48
49 for _, d := range dest {
50 if err := json.Unmarshal(b, d); err != nil {
51 return err
52 }
53 }
54
55 return nil
56 }
57
58
59
60
61 func (t *JSONWebToken) UnsafeClaimsWithoutVerification(dest ...interface{}) error {
62 if t.unverifiedPayload == nil {
63 return fmt.Errorf("square/go-jose: Cannot get unverified claims")
64 }
65 claims := t.unverifiedPayload()
66 for _, d := range dest {
67 if err := json.Unmarshal(claims, d); err != nil {
68 return err
69 }
70 }
71 return nil
72 }
73
74 func (t *NestedJSONWebToken) Decrypt(decryptionKey interface{}) (*JSONWebToken, error) {
75 key := tryJWKS(t.Headers, decryptionKey)
76
77 b, err := t.enc.Decrypt(key)
78 if err != nil {
79 return nil, err
80 }
81
82 sig, err := ParseSigned(string(b))
83 if err != nil {
84 return nil, err
85 }
86
87 return sig, nil
88 }
89
90
91 func ParseSigned(s string) (*JSONWebToken, error) {
92 sig, err := jose.ParseSigned(s)
93 if err != nil {
94 return nil, err
95 }
96 headers := make([]jose.Header, len(sig.Signatures))
97 for i, signature := range sig.Signatures {
98 headers[i] = signature.Header
99 }
100
101 return &JSONWebToken{
102 payload: sig.Verify,
103 unverifiedPayload: sig.UnsafePayloadWithoutVerification,
104 Headers: headers,
105 }, nil
106 }
107
108
109 func ParseEncrypted(s string) (*JSONWebToken, error) {
110 enc, err := jose.ParseEncrypted(s)
111 if err != nil {
112 return nil, err
113 }
114
115 return &JSONWebToken{
116 payload: enc.Decrypt,
117 Headers: []jose.Header{enc.Header},
118 }, nil
119 }
120
121
122 func ParseSignedAndEncrypted(s string) (*NestedJSONWebToken, error) {
123 enc, err := jose.ParseEncrypted(s)
124 if err != nil {
125 return nil, err
126 }
127
128 contentType, _ := enc.Header.ExtraHeaders[jose.HeaderContentType].(string)
129 if strings.ToUpper(contentType) != "JWT" {
130 return nil, ErrInvalidContentType
131 }
132
133 return &NestedJSONWebToken{
134 enc: enc,
135 Headers: []jose.Header{enc.Header},
136 }, nil
137 }
138
139 func tryJWKS(headers []jose.Header, key interface{}) interface{} {
140 var jwks jose.JSONWebKeySet
141
142 switch jwksType := key.(type) {
143 case *jose.JSONWebKeySet:
144 jwks = *jwksType
145 case jose.JSONWebKeySet:
146 jwks = jwksType
147 default:
148 return key
149 }
150
151 var kid string
152 for _, header := range headers {
153 if header.KeyID != "" {
154 kid = header.KeyID
155 break
156 }
157 }
158
159 if kid == "" {
160 return key
161 }
162
163 keys := jwks.Key(kid)
164 if len(keys) == 0 {
165 return key
166 }
167
168 return keys[0].Key
169 }
170
View as plain text