Skip to content

Commit 0e00e46

Browse files
committed
Update JWT interface and fix all the unit tests.
- Unit tests are all green. - Fixed all the layout issues.
1 parent 04aac6d commit 0e00e46

File tree

15 files changed

+588
-564
lines changed

15 files changed

+588
-564
lines changed

src/base64/base64.cpp

+34-31
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,21 @@
2121
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2222
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2323
#include "private/base64.h"
24-
#include <string>
2524
#include "jwt/allocators.h"
25+
#include <string>
2626

2727
#define WHITESPACE 64
28-
#define EQUALS 65
29-
#define INVALID 66
28+
#define EQUALS 65
29+
#define INVALID 66
3030

3131
inline char Base64Encode::EncodeChar(uint8_t in) {
32-
const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
32+
const char table[] =
33+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
3334
return table[in];
3435
}
3536

36-
int Base64Encode::DecodeUrl(const char *decode, size_t num_decode, char *out, size_t *num_out) {
37+
int Base64Encode::DecodeUrl(const char *decode, size_t num_decode, char *out,
38+
size_t *num_out) {
3739
// No integer overflows please.
3840
if ((decode + num_decode) < decode || (out + *num_out) < out)
3941
return 1;
@@ -51,19 +53,19 @@ int Base64Encode::DecodeUrl(const char *decode, size_t num_decode, char *out, si
5153
char c = DecodeChar(ch);
5254

5355
switch (c) {
54-
case INVALID:
55-
return 1; // invalid input, return error
56-
default:
57-
buf = buf << 6 | c;
58-
iter++; // increment the number of iteration
59-
// If the buffer is full, split it into bytes
60-
if (iter == 4) {
61-
*(out++) = (buf >> 16) & 0xff;
62-
*(out++) = (buf >> 8) & 0xff;
63-
*(out++) = buf & 0xff;
64-
buf = 0;
65-
iter = 0;
66-
}
56+
case INVALID:
57+
return 1; // invalid input, return error
58+
default:
59+
buf = buf << 6 | c;
60+
iter++; // increment the number of iteration
61+
// If the buffer is full, split it into bytes
62+
if (iter == 4) {
63+
*(out++) = (buf >> 16) & 0xff;
64+
*(out++) = (buf >> 8) & 0xff;
65+
*(out++) = buf & 0xff;
66+
buf = 0;
67+
iter = 0;
68+
}
6769
}
6870
}
6971

@@ -76,12 +78,12 @@ int Base64Encode::DecodeUrl(const char *decode, size_t num_decode, char *out, si
7678
}
7779
}
7880

79-
*num_out = (out - out_start); // modify to reflect the actual output size
81+
*num_out = (out - out_start); // modify to reflect the actual output size
8082
return 0;
8183
}
8284

83-
int Base64Encode::EncodeUrl(const char* encode, size_t num_encode,
84-
char* result, size_t* num_result) {
85+
int Base64Encode::EncodeUrl(const char *encode, size_t num_encode, char *result,
86+
size_t *num_result) {
8587
// No integer overflows please.
8688
if ((encode + num_encode) < encode || (result + *num_result) < result)
8789
return 1;
@@ -94,25 +96,26 @@ int Base64Encode::EncodeUrl(const char* encode, size_t num_encode,
9496
return 0;
9597
}
9698

97-
const char* start = result;
98-
size_t eLen = (num_encode / 3) * 3; // Length of even 24-bits.
99+
const char *start = result;
100+
size_t eLen = (num_encode / 3) * 3; // Length of even 24-bits.
99101

100102
// Encode even 24-bits
101103
for (size_t s = 0; s < eLen; s += 3) {
102-
// Copy next three bytes into lower 24 bits of int, paying attension to sign.
104+
// Copy next three bytes into lower 24 bits of int, paying attension to
105+
// sign.
103106
uint32_t i = (*encode++ & 0xff) << 16;
104107
i = i | (*encode++ & 0xff) << 8;
105108
i = i | (*encode++ & 0xff);
106109

107110
// Encode the int into four chars
108-
*result++ = EncodeChar((i >> 18) & 0x3f);
109-
*result++ = EncodeChar((i >> 12) & 0x3f);
110-
*result++ = EncodeChar((i >> 6) & 0x3f);
111-
*result++ = EncodeChar(i & 0x3f);
111+
*result++ = EncodeChar((i >> 18) & 0x3f);
112+
*result++ = EncodeChar((i >> 12) & 0x3f);
113+
*result++ = EncodeChar((i >> 6) & 0x3f);
114+
*result++ = EncodeChar(i & 0x3f);
112115
}
113116

114117
// Pad and encode last bits if source isn't an even 24 bits.
115-
size_t left = num_encode - eLen; // 0 - 2.
118+
size_t left = num_encode - eLen; // 0 - 2.
116119
if (left > 0) {
117120
// Prepare the int
118121
uint32_t i = ((*encode++ & 0xff) << 10);
@@ -131,11 +134,11 @@ int Base64Encode::EncodeUrl(const char* encode, size_t num_encode,
131134
}
132135

133136
std::string Base64Encode::EncodeUrl(const std::string &input) {
134-
size_t num_encoded = EncodeBytesNeeded(input.size());
137+
size_t num_encoded = EncodeBytesNeeded(input.size());
135138
str_ptr encoded(new char[num_encoded]);
136139
// Impossible to get a buffer overlow
137140
EncodeUrl(input.c_str(), input.size(), encoded.get(), &num_encoded);
138-
return std::string(encoded.get(), num_encoded-1);
141+
return std::string(encoded.get(), num_encoded - 1);
139142
}
140143

141144
std::string Base64Encode::DecodeUrl(const std::string &input) {

src/include/jwt/allocators.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,10 @@
2626
#include <stdlib.h>
2727

2828
class json_str_delete {
29-
public:
30-
inline void operator() (char* ptr) const {
31-
free(ptr);
32-
}
29+
public:
30+
inline void operator()(char *ptr) const { free(ptr); }
3331
};
3432

3533
typedef std::unique_ptr<char, json_str_delete> json_str;
3634
typedef std::unique_ptr<char[]> str_ptr;
37-
#endif // SRC_INCLUDE_JWT_ALLOCATORS_H_
35+
#endif // SRC_INCLUDE_JWT_ALLOCATORS_H_

src/include/jwt/jwt.h

+59-77
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@
2323
#ifndef SRC_INCLUDE_JWT_JWT_H_
2424
#define SRC_INCLUDE_JWT_JWT_H_
2525

26-
#include "jwt/claimvalidator.h"
27-
#include "jwt/json.hpp"
28-
#include "jwt/messagevalidator.h"
29-
#include <memory>
3026
#include <stddef.h>
27+
#include <memory>
3128
#include <string>
3229
#include <utility>
30+
#include <tuple>
31+
#include "jwt/claimvalidator.h"
32+
#include "jwt/json.hpp"
33+
#include "jwt/messagevalidator.h"
3334

3435
// Stack allocated signature.
3536
#define MAX_SIGNATURE_LENGTH 256
@@ -48,82 +49,63 @@
4849
* more details.
4950
*/
5051
class JWT {
51-
using json = nlohmann::json;
52-
53-
public:
54-
~JWT();
55-
56-
/**
57-
* Parses an encoded web token and validates it.
58-
*
59-
* @param jwsToken String containing a valid webtoken
60-
* @param verifier Optional verifier used to validate the signature. If this
61-
* parameter is null the signature will not be verified.
62-
* @param validator Optional validator to validate the claims in this token.
63-
* The payload will not be validated if this parameter is null
64-
* @throw TokenFormatError in case the token cannot be parsed
65-
* @throw InvalidSignatureError in case the token is not signed
66-
* @throw InvalidClaimError in case the payload cannot be validated
67-
*/
68-
static JWT *Decode(std::string jwsToken, MessageValidator *verifier = nullptr,
69-
ClaimValidator *validator = nullptr);
52+
using json = nlohmann::json;
7053

71-
/**
72-
* Decodes and validates a JSON Web Token.
73-
*
74-
* @param jws_token String containing a valid webtoken
75-
* @param num_jws_token The number of bytes in the jws_token string
76-
* @param verifier Optional verifier used to validate the JOSE header. No
77-
* verification will be done if this parameter is null .
78-
* @param validator Optional validator to validate the claims in this token.
79-
* The payload will not be validated if this parameter is null
80-
* @throw TokenFormatError in case the token cannot be parsed
81-
* @throw InvalidSignatureError in case the token is not signed
82-
* @throw InvalidClaimError in case the payload cannot be validated
83-
*/
84-
static JWT *Decode(const char *jws_token, size_t num_jws_token,
85-
MessageValidator *verifier = nullptr,
86-
ClaimValidator *validator = nullptr);
54+
public:
8755

88-
/**
89-
* Encodes the given json payload and optional header with the given signer.
90-
*
91-
* @param signer The MessageSigner used to sign the resulting token.
92-
* @param payload The payload for this token.
93-
* @param header The optional header. Note the "jwt" and "alg" fields will be
94-
* set
95-
* @return a char[] with a signed token. To be cleared up with calling
96-
* delete[]
97-
*/
98-
static std::string Encode(MessageSigner *signer, json payload,
99-
json header = nullptr);
56+
/**
57+
* Parses an encoded web token and validates it.
58+
*
59+
* @param jwsToken String containing a valid webtoken
60+
* @param verifier Optional verifier used to validate the signature. If this
61+
* parameter is null the signature will not be verified.
62+
* @param validator Optional validator to validate the claims in this token.
63+
* The payload will not be validated if this parameter is null
64+
* @throw TokenFormatError in case the token cannot be parsed
65+
* @throw InvalidSignatureError in case the token is not signed
66+
* @throw InvalidClaimError in case the payload cannot be validated
67+
*/
68+
static std::tuple<json, json> Decode(std::string jwsToken,
69+
MessageValidator *verifier = nullptr,
70+
ClaimValidator *validator = nullptr);
10071

101-
/**
102-
* The contents of the JOSE Header describe the cryptographic operations
103-
* applied to the JWT Claims Set. Callers do not own the reference returned
104-
* and should not free it.
105-
*/
106-
inline const json header() { return header_; }
72+
/**
73+
* Decodes and validates a JSON Web Token.
74+
*
75+
* @param jws_token String containing a valid webtoken
76+
* @param num_jws_token The number of bytes in the jws_token string
77+
* @param verifier Optional verifier used to validate the JOSE header. No
78+
* verification will be done if this parameter is null .
79+
* @param validator Optional validator to validate the claims in this token.
80+
* The payload will not be validated if this parameter is null
81+
* @return A tuple containing the json header and the payload.
82+
* @throw TokenFormatError in case the token cannot be parsed
83+
* @throw InvalidSignatureError in case the token is not signed
84+
* @throw InvalidClaimError in case the payload cannot be validated
85+
*/
86+
static std::tuple<json, json> Decode(const char *jws_token,
87+
size_t num_jws_token,
88+
MessageValidator *verifier = nullptr,
89+
ClaimValidator *validator = nullptr);
10790

108-
/**
109-
* A JSON object that contains the claims conveyed by the JWT. Callers do not
110-
* own the reference returned and should not free it.
111-
*/
112-
inline const json payload() { return payload_; }
91+
/**
92+
* Encodes the given json payload and optional header with the given signer.
93+
*
94+
* @param signer The MessageSigner used to sign the resulting token.
95+
* @param payload The payload for this token.
96+
* @param header The optional header. Note the "jwt" and "alg" fields will
97+
* be set
98+
* @return a char[] with a signed token. To be cleared up with calling
99+
* delete[]
100+
*/
101+
static std::string Encode(MessageSigner *signer, json payload,
102+
json header = nullptr);
113103

114-
private:
115-
JWT(json header, json payload);
116-
117-
static json ExtractPayload(const char *payload, size_t num_payload);
118-
static bool VerifySignature(json header_claims_, const char *header,
119-
size_t num_header_and_payload,
120-
const char *signature, size_t num_signature,
121-
MessageValidator *verifier);
122-
123-
json header_;
124-
json payload_;
104+
private:
105+
static json ExtractPayload(const char *payload, size_t num_payload);
106+
static bool VerifySignature(json header_claims_, const char *header,
107+
size_t num_header_and_payload,
108+
const char *signature, size_t num_signature,
109+
MessageValidator *verifier);
125110
};
126-
127-
/** Auto pointer that will release the token when it goes out of scope */
128-
typedef std::unique_ptr<JWT> jwt_ptr;
129-
#endif // SRC_INCLUDE_JWT_JWT_H_
111+
#endif // SRC_INCLUDE_JWT_JWT_H_

src/include/jwt/jwt_all.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@
2222
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2323
#ifndef SRC_INCLUDE_JWT_JWT_ALL_H_
2424
#define SRC_INCLUDE_JWT_JWT_ALL_H_
25-
#include "jwt/jwt.h"
2625
#include "jwt/allocators.h"
26+
#include "jwt/jwt.h"
2727

2828
// Validators
29+
#include "jwt/hmacvalidator.h"
2930
#include "jwt/messagevalidatorfactory.h"
3031
#include "jwt/nonevalidator.h"
3132
#include "jwt/rsavalidator.h"
32-
#include "jwt/hmacvalidator.h"
3333

3434
// Claims
3535
#include "jwt/claimvalidatorfactory.h"
3636
#include "jwt/listclaimvalidator.h"
3737
#include "jwt/timevalidator.h"
38-
#endif // SRC_INCLUDE_JWT_JWT_ALL_H_
38+
#endif // SRC_INCLUDE_JWT_JWT_ALL_H_

src/include/jwt/jwt_error.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
/**
3131
* Indicates that we failed to validate and parse the token.
3232
*/
33-
class InvalidTokenError :public std::runtime_error {
34-
public:
35-
explicit InvalidTokenError(std::string msg) : std::runtime_error(msg) { }
33+
class InvalidTokenError : public std::runtime_error {
34+
public:
35+
explicit InvalidTokenError(std::string msg) : std::runtime_error(msg) {}
3636
};
3737

3838
/**
@@ -41,16 +41,16 @@ class InvalidTokenError :public std::runtime_error {
4141
* from this set of bytes.
4242
*/
4343
class TokenFormatError : public InvalidTokenError {
44-
public:
45-
explicit TokenFormatError(std::string msg) : InvalidTokenError(msg) { }
44+
public:
45+
explicit TokenFormatError(std::string msg) : InvalidTokenError(msg) {}
4646
};
4747

4848
/**
4949
* The token is not properly signed.
5050
*/
5151
class InvalidSignatureError : public InvalidTokenError {
52-
public:
53-
explicit InvalidSignatureError(std::string msg) : InvalidTokenError(msg) { }
52+
public:
53+
explicit InvalidSignatureError(std::string msg) : InvalidTokenError(msg) {}
5454
};
5555

56-
#endif // SRC_INCLUDE_JWT_JWT_ERROR_H_
56+
#endif // SRC_INCLUDE_JWT_JWT_ERROR_H_

0 commit comments

Comments
 (0)