diff options
Diffstat (limited to 'vendor/github.com/golang-jwt/jwt/v5/parser.go')
-rw-r--r-- | vendor/github.com/golang-jwt/jwt/v5/parser.go | 238 |
1 files changed, 0 insertions, 238 deletions
diff --git a/vendor/github.com/golang-jwt/jwt/v5/parser.go b/vendor/github.com/golang-jwt/jwt/v5/parser.go deleted file mode 100644 index ecf99af..0000000 --- a/vendor/github.com/golang-jwt/jwt/v5/parser.go +++ /dev/null | |||
@@ -1,238 +0,0 @@ | |||
1 | package jwt | ||
2 | |||
3 | import ( | ||
4 | "bytes" | ||
5 | "encoding/base64" | ||
6 | "encoding/json" | ||
7 | "fmt" | ||
8 | "strings" | ||
9 | ) | ||
10 | |||
11 | type Parser struct { | ||
12 | // If populated, only these methods will be considered valid. | ||
13 | validMethods []string | ||
14 | |||
15 | // Use JSON Number format in JSON decoder. | ||
16 | useJSONNumber bool | ||
17 | |||
18 | // Skip claims validation during token parsing. | ||
19 | skipClaimsValidation bool | ||
20 | |||
21 | validator *Validator | ||
22 | |||
23 | decodeStrict bool | ||
24 | |||
25 | decodePaddingAllowed bool | ||
26 | } | ||
27 | |||
28 | // NewParser creates a new Parser with the specified options | ||
29 | func NewParser(options ...ParserOption) *Parser { | ||
30 | p := &Parser{ | ||
31 | validator: &Validator{}, | ||
32 | } | ||
33 | |||
34 | // Loop through our parsing options and apply them | ||
35 | for _, option := range options { | ||
36 | option(p) | ||
37 | } | ||
38 | |||
39 | return p | ||
40 | } | ||
41 | |||
42 | // Parse parses, validates, verifies the signature and returns the parsed token. | ||
43 | // keyFunc will receive the parsed token and should return the key for validating. | ||
44 | func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) { | ||
45 | return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc) | ||
46 | } | ||
47 | |||
48 | // ParseWithClaims parses, validates, and verifies like Parse, but supplies a default object implementing the Claims | ||
49 | // interface. This provides default values which can be overridden and allows a caller to use their own type, rather | ||
50 | // than the default MapClaims implementation of Claims. | ||
51 | // | ||
52 | // Note: If you provide a custom claim implementation that embeds one of the standard claims (such as RegisteredClaims), | ||
53 | // make sure that a) you either embed a non-pointer version of the claims or b) if you are using a pointer, allocate the | ||
54 | // proper memory for it before passing in the overall claims, otherwise you might run into a panic. | ||
55 | func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) { | ||
56 | token, parts, err := p.ParseUnverified(tokenString, claims) | ||
57 | if err != nil { | ||
58 | return token, err | ||
59 | } | ||
60 | |||
61 | // Verify signing method is in the required set | ||
62 | if p.validMethods != nil { | ||
63 | var signingMethodValid = false | ||
64 | var alg = token.Method.Alg() | ||
65 | for _, m := range p.validMethods { | ||
66 | if m == alg { | ||
67 | signingMethodValid = true | ||
68 | break | ||
69 | } | ||
70 | } | ||
71 | if !signingMethodValid { | ||
72 | // signing method is not in the listed set | ||
73 | return token, newError(fmt.Sprintf("signing method %v is invalid", alg), ErrTokenSignatureInvalid) | ||
74 | } | ||
75 | } | ||
76 | |||
77 | // Decode signature | ||
78 | token.Signature, err = p.DecodeSegment(parts[2]) | ||
79 | if err != nil { | ||
80 | return token, newError("could not base64 decode signature", ErrTokenMalformed, err) | ||
81 | } | ||
82 | text := strings.Join(parts[0:2], ".") | ||
83 | |||
84 | // Lookup key(s) | ||
85 | if keyFunc == nil { | ||
86 | // keyFunc was not provided. short circuiting validation | ||
87 | return token, newError("no keyfunc was provided", ErrTokenUnverifiable) | ||
88 | } | ||
89 | |||
90 | got, err := keyFunc(token) | ||
91 | if err != nil { | ||
92 | return token, newError("error while executing keyfunc", ErrTokenUnverifiable, err) | ||
93 | } | ||
94 | |||
95 | switch have := got.(type) { | ||
96 | case VerificationKeySet: | ||
97 | if len(have.Keys) == 0 { | ||
98 | return token, newError("keyfunc returned empty verification key set", ErrTokenUnverifiable) | ||
99 | } | ||
100 | // Iterate through keys and verify signature, skipping the rest when a match is found. | ||
101 | // Return the last error if no match is found. | ||
102 | for _, key := range have.Keys { | ||
103 | if err = token.Method.Verify(text, token.Signature, key); err == nil { | ||
104 | break | ||
105 | } | ||
106 | } | ||
107 | default: | ||
108 | err = token.Method.Verify(text, token.Signature, have) | ||
109 | } | ||
110 | if err != nil { | ||
111 | return token, newError("", ErrTokenSignatureInvalid, err) | ||
112 | } | ||
113 | |||
114 | // Validate Claims | ||
115 | if !p.skipClaimsValidation { | ||
116 | // Make sure we have at least a default validator | ||
117 | if p.validator == nil { | ||
118 | p.validator = NewValidator() | ||
119 | } | ||
120 | |||
121 | if err := p.validator.Validate(claims); err != nil { | ||
122 | return token, newError("", ErrTokenInvalidClaims, err) | ||
123 | } | ||
124 | } | ||
125 | |||
126 | // No errors so far, token is valid. | ||
127 | token.Valid = true | ||
128 | |||
129 | return token, nil | ||
130 | } | ||
131 | |||
132 | // ParseUnverified parses the token but doesn't validate the signature. | ||
133 | // | ||
134 | // WARNING: Don't use this method unless you know what you're doing. | ||
135 | // | ||
136 | // It's only ever useful in cases where you know the signature is valid (since it has already | ||
137 | // been or will be checked elsewhere in the stack) and you want to extract values from it. | ||
138 | func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) { | ||
139 | parts = strings.Split(tokenString, ".") | ||
140 | if len(parts) != 3 { | ||
141 | return nil, parts, newError("token contains an invalid number of segments", ErrTokenMalformed) | ||
142 | } | ||
143 | |||
144 | token = &Token{Raw: tokenString} | ||
145 | |||
146 | // parse Header | ||
147 | var headerBytes []byte | ||
148 | if headerBytes, err = p.DecodeSegment(parts[0]); err != nil { | ||
149 | return token, parts, newError("could not base64 decode header", ErrTokenMalformed, err) | ||
150 | } | ||
151 | if err = json.Unmarshal(headerBytes, &token.Header); err != nil { | ||
152 | return token, parts, newError("could not JSON decode header", ErrTokenMalformed, err) | ||
153 | } | ||
154 | |||
155 | // parse Claims | ||
156 | token.Claims = claims | ||
157 | |||
158 | claimBytes, err := p.DecodeSegment(parts[1]) | ||
159 | if err != nil { | ||
160 | return token, parts, newError("could not base64 decode claim", ErrTokenMalformed, err) | ||
161 | } | ||
162 | |||
163 | // If `useJSONNumber` is enabled then we must use *json.Decoder to decode | ||
164 | // the claims. However, this comes with a performance penalty so only use | ||
165 | // it if we must and, otherwise, simple use json.Unmarshal. | ||
166 | if !p.useJSONNumber { | ||
167 | // JSON Unmarshal. Special case for map type to avoid weird pointer behavior. | ||
168 | if c, ok := token.Claims.(MapClaims); ok { | ||
169 | err = json.Unmarshal(claimBytes, &c) | ||
170 | } else { | ||
171 | err = json.Unmarshal(claimBytes, &claims) | ||
172 | } | ||
173 | } else { | ||
174 | dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) | ||
175 | dec.UseNumber() | ||
176 | // JSON Decode. Special case for map type to avoid weird pointer behavior. | ||
177 | if c, ok := token.Claims.(MapClaims); ok { | ||
178 | err = dec.Decode(&c) | ||
179 | } else { | ||
180 | err = dec.Decode(&claims) | ||
181 | } | ||
182 | } | ||
183 | if err != nil { | ||
184 | return token, parts, newError("could not JSON decode claim", ErrTokenMalformed, err) | ||
185 | } | ||
186 | |||
187 | // Lookup signature method | ||
188 | if method, ok := token.Header["alg"].(string); ok { | ||
189 | if token.Method = GetSigningMethod(method); token.Method == nil { | ||
190 | return token, parts, newError("signing method (alg) is unavailable", ErrTokenUnverifiable) | ||
191 | } | ||
192 | } else { | ||
193 | return token, parts, newError("signing method (alg) is unspecified", ErrTokenUnverifiable) | ||
194 | } | ||
195 | |||
196 | return token, parts, nil | ||
197 | } | ||
198 | |||
199 | // DecodeSegment decodes a JWT specific base64url encoding. This function will | ||
200 | // take into account whether the [Parser] is configured with additional options, | ||
201 | // such as [WithStrictDecoding] or [WithPaddingAllowed]. | ||
202 | func (p *Parser) DecodeSegment(seg string) ([]byte, error) { | ||
203 | encoding := base64.RawURLEncoding | ||
204 | |||
205 | if p.decodePaddingAllowed { | ||
206 | if l := len(seg) % 4; l > 0 { | ||
207 | seg += strings.Repeat("=", 4-l) | ||
208 | } | ||
209 | encoding = base64.URLEncoding | ||
210 | } | ||
211 | |||
212 | if p.decodeStrict { | ||
213 | encoding = encoding.Strict() | ||
214 | } | ||
215 | return encoding.DecodeString(seg) | ||
216 | } | ||
217 | |||
218 | // Parse parses, validates, verifies the signature and returns the parsed token. | ||
219 | // keyFunc will receive the parsed token and should return the cryptographic key | ||
220 | // for verifying the signature. The caller is strongly encouraged to set the | ||
221 | // WithValidMethods option to validate the 'alg' claim in the token matches the | ||
222 | // expected algorithm. For more details about the importance of validating the | ||
223 | // 'alg' claim, see | ||
224 | // https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ | ||
225 | func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { | ||
226 | return NewParser(options...).Parse(tokenString, keyFunc) | ||
227 | } | ||
228 | |||
229 | // ParseWithClaims is a shortcut for NewParser().ParseWithClaims(). | ||
230 | // | ||
231 | // Note: If you provide a custom claim implementation that embeds one of the | ||
232 | // standard claims (such as RegisteredClaims), make sure that a) you either | ||
233 | // embed a non-pointer version of the claims or b) if you are using a pointer, | ||
234 | // allocate the proper memory for it before passing in the overall claims, | ||
235 | // otherwise you might run into a panic. | ||
236 | func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) { | ||
237 | return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc) | ||
238 | } | ||