1
#pragma once
2

            
3
// Copyright 2018 Google LLC
4
// Copyright Envoy Project Authors
5
// SPDX-License-Identifier: Apache-2.0
6

            
7
#pragma once
8

            
9
#include <string>
10

            
11
namespace Envoy {
12
namespace JwtVerify {
13

            
14
/**
15
 * Define the Jwt verification error status.
16
 */
17
enum class Status {
18
  Ok = 0,
19

            
20
  // Jwt errors:
21

            
22
  // Jwt missing.
23
  JwtMissed,
24

            
25
  // Jwt not valid yet.
26
  JwtNotYetValid,
27

            
28
  // Jwt expired.
29
  JwtExpired,
30

            
31
  // JWT is not in the form of Header.Payload.Signature
32
  JwtBadFormat,
33

            
34
  // Jwt header is an invalid Base64url encoded.
35
  JwtHeaderParseErrorBadBase64,
36

            
37
  // Jwt header is an invalid JSON.
38
  JwtHeaderParseErrorBadJson,
39

            
40
  // "alg" in the header is not a string.
41
  JwtHeaderBadAlg,
42

            
43
  // Value of "alg" in the header is invalid.
44
  JwtHeaderNotImplementedAlg,
45

            
46
  // "kid" in the header is not a string.
47
  JwtHeaderBadKid,
48

            
49
  // Jwt payload is an invalid Base64url encoded.
50
  JwtPayloadParseErrorBadBase64,
51

            
52
  // Jwt payload is an invalid JSON.
53
  JwtPayloadParseErrorBadJson,
54

            
55
  // Jwt payload field [iss] must be string.
56
  JwtPayloadParseErrorIssNotString,
57

            
58
  // Jwt payload field [sub] must be string.
59
  JwtPayloadParseErrorSubNotString,
60

            
61
  // Jwt payload field [iat] must be integer.
62
  JwtPayloadParseErrorIatNotInteger,
63

            
64
  // Jwt payload field [iat] must be within a 64 bit positive integer range.
65
  JwtPayloadParseErrorIatOutOfRange,
66

            
67
  // Jwt payload field [nbf] must be integer.
68
  JwtPayloadParseErrorNbfNotInteger,
69

            
70
  // Jwt payload field [nbf] must be within a 64 bit positive integer range.
71
  JwtPayloadParseErrorNbfOutOfRange,
72

            
73
  // Jwt payload field [exp] must be integer.
74
  JwtPayloadParseErrorExpNotInteger,
75

            
76
  // Jwt payload field [exp] must be within a 64 bit positive integer range.
77
  JwtPayloadParseErrorExpOutOfRange,
78

            
79
  // Jwt payload field [jti] must be string.
80
  JwtPayloadParseErrorJtiNotString,
81

            
82
  // Jwt payload field [aud] must be string or string list.
83
  JwtPayloadParseErrorAudNotString,
84

            
85
  // Jwt signature is an invalid Base64url input.
86
  JwtSignatureParseErrorBadBase64,
87

            
88
  // Jwt ED25519 signature is wrong length
89
  JwtEd25519SignatureWrongLength,
90

            
91
  // Issuer is not configured.
92
  JwtUnknownIssuer,
93

            
94
  // Audience is not allowed.
95
  JwtAudienceNotAllowed,
96

            
97
  // Jwt verification fails.
98
  JwtVerificationFail,
99

            
100
  // Found multiple Jwt tokens.
101
  JwtMultipleTokens,
102

            
103
  // Jwks errors
104

            
105
  // Jwks is an invalid JSON.
106
  JwksParseError,
107

            
108
  // Jwks does not have "keys".
109
  JwksNoKeys,
110

            
111
  // "keys" in Jwks is not an array.
112
  JwksBadKeys,
113

            
114
  // Jwks doesn't have any valid public key.
115
  JwksNoValidKeys,
116

            
117
  // Jwks doesn't have key to match kid or alg from Jwt.
118
  JwksKidAlgMismatch,
119

            
120
  // "n" or "e" field of a Jwk RSA is missing or has a parse error.
121
  JwksRsaParseError,
122

            
123
  // Failed to create a EC_KEY object.
124
  JwksEcCreateKeyFail,
125

            
126
  // "x" or "y" field is an invalid Base64
127
  JwksEcXorYBadBase64,
128

            
129
  // "x" or "y" field of a Jwk EC is missing or has a parse error.
130
  JwksEcParseError,
131

            
132
  // Jwks Oct key is an invalid Base64.
133
  JwksOctBadBase64,
134

            
135
  // "x" field is invalid Base64
136
  JwksOKPXBadBase64,
137
  // "x" field is wrong length
138
  JwksOKPXWrongLength,
139

            
140
  // Failed to fetch public key
141
  JwksFetchFail,
142

            
143
  // "kty" is missing in "keys".
144
  JwksMissingKty,
145
  // "kty" is not string type in "keys".
146
  JwksBadKty,
147
  // "kty" is not supported in "keys".
148
  JwksNotImplementedKty,
149

            
150
  // "alg" is not started with "RS" for a RSA key
151
  JwksRSAKeyBadAlg,
152
  // "n" field is missing for a RSA key
153
  JwksRSAKeyMissingN,
154
  // "n" field is not string for a RSA key
155
  JwksRSAKeyBadN,
156
  // "e" field is missing for a RSA key
157
  JwksRSAKeyMissingE,
158
  // "e" field is not string for a RSA key
159
  JwksRSAKeyBadE,
160

            
161
  // "alg" is not "ES256", "ES384" or "ES512" for an EC key
162
  JwksECKeyBadAlg,
163
  // "crv" field is not string for an EC key
164
  JwksECKeyBadCrv,
165
  // "crv" or "alg" is not supported for an EC key
166
  JwksECKeyAlgOrCrvUnsupported,
167
  // "crv" is not compatible with "alg" for an EC key
168
  JwksECKeyAlgNotCompatibleWithCrv,
169
  // "x" field is missing for an EC key
170
  JwksECKeyMissingX,
171
  // "x" field is not string for an EC key
172
  JwksECKeyBadX,
173
  // "y" field is missing for an EC key
174
  JwksECKeyMissingY,
175
  // "y" field is not string for an EC key
176
  JwksECKeyBadY,
177

            
178
  // "alg" is not "HS256", "HS384" or "HS512" for an HMAC key
179
  JwksHMACKeyBadAlg,
180
  // "k" field is missing for an HMAC key
181
  JwksHMACKeyMissingK,
182
  // "k" field is not string for an HMAC key
183
  JwksHMACKeyBadK,
184

            
185
  // "alg" is not "EdDSA" for an OKP key
186
  JwksOKPKeyBadAlg,
187
  // "crv" field is missing for an OKP key
188
  JwksOKPKeyMissingCrv,
189
  // "crv" field is not string for an OKP key
190
  JwksOKPKeyBadCrv,
191
  // "crv" is not supported for an OKP key
192
  JwksOKPKeyCrvUnsupported,
193
  // "x" field is missing for an OKP key
194
  JwksOKPKeyMissingX,
195
  // "x" field is not string for an OKP key
196
  JwksOKPKeyBadX,
197

            
198
  // X509 BIO_Write function fails
199
  JwksX509BioWriteError,
200
  // X509 parse pubkey fails
201
  JwksX509ParseError,
202
  // X509 get pubkey fails
203
  JwksX509GetPubkeyError,
204

            
205
  // Key type is not supported.
206
  JwksPemNotImplementedKty,
207
  // Unable to parse public key
208
  JwksPemBadBase64,
209
  // Failed to get raw ED25519 key from PEM
210
  JwksPemGetRawEd25519Error,
211

            
212
  // Failed to create BIO
213
  JwksBioAllocError,
214
};
215

            
216
/**
217
 * Convert enum status to string.
218
 * @param status is the enum status.
219
 * @return the string status.
220
 */
221
std::string getStatusString(Status status);
222

            
223
/**
224
 * Base class to keep the status that represents "OK" or the first failure.
225
 */
226
class WithStatus {
227
public:
228
2123
  WithStatus() : status_(Status::Ok) {}
229

            
230
  /**
231
   * Get the current status.
232
   * @return the enum status.
233
   */
234
2156
  Status getStatus() const { return status_; }
235

            
236
protected:
237
148
  void updateStatus(Status status) {
238
    // Only keep the first failure
239
148
    if (status_ == Status::Ok) {
240
111
      status_ = status;
241
111
    }
242
148
  }
243

            
244
2029
  void resetStatus(Status status) { status_ = status; }
245

            
246
private:
247
  // The internal status.
248
  Status status_;
249
};
250

            
251
} // namespace JwtVerify
252
} // namespace Envoy