-
Notifications
You must be signed in to change notification settings - Fork 28
/
Copy pathIJwt.hpp
284 lines (237 loc) · 6.36 KB
/
IJwt.hpp
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
/*
* Copyright (c) 2018-2019 Snowflake Computing, Inc. All rights reserved.
*/
#ifndef SNOWFLAKECLIENT_IJWT_HPP
#define SNOWFLAKECLIENT_IJWT_HPP
#include <string>
#include <openssl/ossl_typ.h>
#include <memory>
namespace Snowflake
{
namespace Client
{
namespace Jwt
{
/**
* Type of algorithms
*
* Note - Any updates to this
* enum should be reflected in
* jwtWrapper to maintain interoperability.
*/
enum class AlgorithmType
{
HS256, HS384, HS512,
RS256, RS384, RS512,
ES256, ES384, ES512,
UNKNOWN,
};
struct JwtException : public std::exception
{
JwtException(const std::string &message) : message_(message) {}
const char *what() const noexcept
{
return message_.c_str();
}
std::string message_;
};
/**
* This is the interface of a Claim Set that can be inserted to the JWT token
*/
class IClaimSet
{
public:
virtual ~IClaimSet() = default;
/**
* Constructor function for the claimset
* ALWAYS USE THIS FUNCTION TO INSTANTIATE A CLAIM SET!
*/
static IClaimSet *buildClaimSet();
/**
* Construct function for the claimset given the string of the
* JSON text
* @throw JWTException when the text is not valid
*/
static IClaimSet *parseClaimset(const std::string &text);
/**
* Check if the claim set contains a specific key
*/
virtual bool containsClaim(const std::string &key) = 0;
/**
* Add the key and a string value to the claim set
* Would replace the old one if the key exists
* @param key
* @param value
*/
virtual void addClaim(const std::string &key, const std::string &value) = 0;
/**
* Add the key and a long value to the claim set
* Would replace the old one if the key exists
* @param key
* @param value
*/
virtual void addClaim(const std::string &key, long number) = 0;
/**
* Get a claim from the claim set in string type
*/
virtual std::string getClaimInString(const std::string &key) = 0;
/**
* Get a claim from the claim set with internal buffer for c interface
* in jwtWrapper
*/
virtual const char* getClaimInStringConstBuf(const std::string &key)
{
m_claimString = getClaimInString(key);
return m_claimString.c_str();
}
/**
* Get a claim from the claim set in long type
*/
virtual long getClaimInLong(const std::string &key) = 0;
/**
* Get a claim from the claim set in double type
*/
virtual double getClaimInDouble(const std::string &key) = 0;
/**
* Serialize the claim set to base64url encoded format
*/
virtual std::string serialize(bool format=true) = 0;
/**
* Remove a claim from the claim set with specified key
*/
virtual void removeClaim(const std::string &key) = 0;
protected:
IClaimSet() = default;
private:
/**
* string buffer to hold string data returned from jwtWrapper
*/
std::string m_claimString;
};
/**
* This is a header of the JWT token
*/
class IHeader
{
public:
virtual ~IHeader() = default;
/**
* Construct function for JWT header
*/
static IHeader *buildHeader();
/**
* Construct function for JWT header given the JSON text for header
* @throw JWTException when the header is not valid
*/
static IHeader *parseHeader(const std::string &text);
/**
* Set the algorithm's type
* @param type
*/
virtual void setAlgorithm(AlgorithmType type) = 0;
/**
* Set custom header entry
* @param std::string header_type
* @param std::string header_value
*/
virtual void setCustomHeaderEntry(std::string header_type, std::string header_value) = 0;
/**
* Get the algorithm type of the header
* @return the algorithm type
*/
virtual AlgorithmType getAlgorithmType() = 0;
/**
* Get value corresponding to a custom field in
* the JWT Token Header
* @return std::string value corresponding to
* header_type
*/
virtual std::string getCustomHeaderEntry(const std::string header_type) = 0;
/**
* Get custom field in header with interal buffer for c interface in jwtWrapper
*/
virtual const char* getCustomHeaderEntryConstBuf(const std::string& header_type)
{
m_customHeaderEntry = getCustomHeaderEntry(header_type);
return m_customHeaderEntry.c_str();
}
/**
* Serialize the header
* @return serialized string in base64urlencoded
*/
virtual std::string serialize(bool format=true) = 0;
protected:
IHeader() = default;
private:
/**
* string buffer to hold string data returned from jwtWrapper
*/
std::string m_customHeaderEntry;
};
/**
* JWT interface class
* The general use case would be:
* For issuer:
* Use IClaimSet and IHeader to construct elements in the JWT.
* Set the claim set and header to the jwt token
* Serialize the token with the key and send the result of string to authenticator
*
* For authenticator
* Use buildJwt(std::string text to marshalize the JWT structure
* Verify the token using public key
*/
class IJwt
{
typedef std::shared_ptr<IClaimSet> ClaimSetPtr;
typedef std::shared_ptr<IHeader> HeaderPtr;
public:
/**
* Construct function for the JWT
*/
static IJwt *buildIJwt();
/**
* Construct function for the JWT with text of that token
* FORMAT: <base64url coded header>.<base64url coded claimset>.<secret>
* @throw JWTExcpetion if the text is not corrected serialized
*/
static IJwt *buildIJwt(const std::string &text);
virtual ~IJwt() {}
/**
* Serialize the JWT token with private key specified
* The algorithm of signing is specified in the IHeader
* @usedBy issuer
*/
virtual std::string serialize(EVP_PKEY *key) = 0;
/**
* Get serialize string with interal buffer for c interface in jwtWrapper
*/
virtual const char* serializeConstBuf(EVP_PKEY *key)
{
m_serializedString = serialize(key);
return m_serializedString.c_str();
}
/**
* Verify the JWT is valid using the public key
* @usedBy authenticator
*/
virtual bool verify(EVP_PKEY *key, bool format) = 0;
/**
* Setter and getter functions for header and claimset
* Generally used by issuer
*/
virtual void setClaimSet(ClaimSetPtr claim_set) = 0;
virtual ClaimSetPtr getClaimSet() = 0;
virtual void setHeader(HeaderPtr header) = 0;
virtual HeaderPtr getHeader() = 0;
protected:
IJwt() = default;
private:
/**
* string buffer to hold string data returned from jwtWrapper
*/
std::string m_serializedString;
};
} // namespace Jwt
} // namespace Client
} // namespace Snowflake
#endif //SNOWFLAKECLIENT_IJWT_HPP