From 858cbaa9a2f3ed02aa09feebeb9d8d9550bc3fa3 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sat, 7 Oct 2023 16:25:58 +0200 Subject: [PATCH] Make JWT code C++ compatible Must be C++ as we will be replacing jasmin json with rapidjson. --- src/thirdparty/jwt/CMakeLists.txt | 4 + src/thirdparty/jwt/base64.cpp | 4 +- src/thirdparty/jwt/claim.cpp | 21 +- src/thirdparty/jwt/decode.cpp | 60 ++-- src/thirdparty/jwt/encode.cpp | 49 +-- src/thirdparty/jwt/include/base64.h | 12 +- src/thirdparty/jwt/include/checknum.h | 141 ++++++++ src/thirdparty/jwt/include/claim.h | 12 +- src/thirdparty/jwt/include/decode.h | 12 +- src/thirdparty/jwt/include/encode.h | 12 +- src/thirdparty/jwt/include/jsmn.h | 471 ++++++++++++++++++++++++++ src/thirdparty/jwt/include/retcodes.h | 12 +- src/thirdparty/jwt/include/util.h | 12 +- src/thirdparty/jwt/include/version.h | 12 +- src/thirdparty/jwt/util.cpp | 12 +- src/thirdparty/jwt/version.cpp | 16 +- 16 files changed, 749 insertions(+), 113 deletions(-) create mode 100644 src/thirdparty/jwt/include/checknum.h create mode 100644 src/thirdparty/jwt/include/jsmn.h diff --git a/src/thirdparty/jwt/CMakeLists.txt b/src/thirdparty/jwt/CMakeLists.txt index 0477cbab..ea61d451 100644 --- a/src/thirdparty/jwt/CMakeLists.txt +++ b/src/thirdparty/jwt/CMakeLists.txt @@ -25,3 +25,7 @@ add_sources( SOURCE_GROUP "Include" end_sources() thirdparty_suppress_warnings() + +target_include_directories( ${PROJECT_NAME} PRIVATE + "${THIRDPARTY_SOURCE_DIR}/mbedtls/include/" +) diff --git a/src/thirdparty/jwt/base64.cpp b/src/thirdparty/jwt/base64.cpp index ea27386a..2d7fe85b 100644 --- a/src/thirdparty/jwt/base64.cpp +++ b/src/thirdparty/jwt/base64.cpp @@ -133,7 +133,7 @@ int l8w8jwt_base64_encode(const int url, const uint8_t* data, const size_t data_ return L8W8JWT_OVERFLOW; } - *out = malloc(olen); + *out = (char*)malloc(olen); if (*out == NULL) { return L8W8JWT_OUT_OF_MEM; @@ -249,7 +249,7 @@ int l8w8jwt_base64_decode(const int url, const char* data, const size_t data_len if (r == 3) r = 1; - *out = calloc(count / 4 * 3 + 16, sizeof(uint8_t)); + *out = (uint8_t*)calloc(count / 4 * 3 + 16, sizeof(uint8_t)); if (*out == NULL) { return L8W8JWT_OUT_OF_MEM; diff --git a/src/thirdparty/jwt/claim.cpp b/src/thirdparty/jwt/claim.cpp index 089baff1..a8edab49 100644 --- a/src/thirdparty/jwt/claim.cpp +++ b/src/thirdparty/jwt/claim.cpp @@ -14,9 +14,9 @@ limitations under the License. */ -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif #include "include/claim.h" #include "include/version.h" @@ -24,8 +24,13 @@ extern "C" { #include "include/chillbuff.h" #include - -#include // SChannel??? +#ifdef __cplusplus +extern "C" { +#endif +#include +#ifdef __cplusplus +} +#endif void l8w8jwt_free_claims(struct l8w8jwt_claim* claims, const size_t claims_count) { @@ -142,6 +147,6 @@ struct l8w8jwt_claim* l8w8jwt_get_claim(struct l8w8jwt_claim* claims, const size return NULL; } -#ifdef __cplusplus -} // extern "C" -#endif +//#ifdef __cplusplus +//} // extern "C" +//#endif diff --git a/src/thirdparty/jwt/decode.cpp b/src/thirdparty/jwt/decode.cpp index 65ecfa25..e1c68542 100644 --- a/src/thirdparty/jwt/decode.cpp +++ b/src/thirdparty/jwt/decode.cpp @@ -14,9 +14,9 @@ limitations under the License. */ -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif #define JSMN_STATIC @@ -24,11 +24,15 @@ extern "C" { #include "include/decode.h" #include "include/base64.h" #include "include/chillbuff.h" +#include "include/jsmn.h" +#include "include/checknum.h" -#include // RapidJSON? #include #include -#include + +//#ifdef __cplusplus +//extern "C" { +//#endif #include #include #include @@ -36,6 +40,9 @@ extern "C" { #include #include #include +//#ifdef __cplusplus +//} +//#endif #if L8W8JWT_ENABLE_EDDSA #include @@ -82,14 +89,14 @@ static inline void md_info_from_alg(const int alg, mbedtls_md_info_t** md_info, static int l8w8jwt_unescape_claim(struct l8w8jwt_claim* claim, const char* key, const size_t key_length, const char* value, const size_t value_length) { claim->key_length = 0; - claim->key = calloc(sizeof(char), key_length + 1); + claim->key = (char*)calloc(sizeof(char), key_length + 1); claim->value_length = 0; - claim->value = calloc(sizeof(char), value_length + 1); + claim->value = (char*)calloc(sizeof(char), value_length + 1); if (claim->key == NULL || claim->value == NULL) { - free(claim->key); + free((void*)claim->key); free(claim->value); return L8W8JWT_OUT_OF_MEM; } @@ -165,7 +172,7 @@ static int l8w8jwt_parse_claims(chillbuff* buffer, char* json, const size_t json } jsmntok_t _tokens[64]; - jsmntok_t* tokens = r <= (sizeof(_tokens) / sizeof(_tokens[0])) ? _tokens : malloc(r * sizeof(jsmntok_t)); + jsmntok_t* tokens = r <= (sizeof(_tokens) / sizeof(_tokens[0])) ? _tokens : (jsmntok_t*)malloc(r * sizeof(jsmntok_t)); if (tokens == NULL) { @@ -315,7 +322,7 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati } const int alg = params->alg; - enum l8w8jwt_validation_result validation_res = L8W8JWT_VALID; + unsigned validation_res = L8W8JWT_VALID; int r = l8w8jwt_validate_decoding_params(params); if (r != L8W8JWT_SUCCESS) @@ -328,7 +335,7 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati return L8W8JWT_NULL_ARG; } - *out_validation_result = ~L8W8JWT_VALID; + *out_validation_result = (l8w8jwt_validation_result)~L8W8JWT_VALID; char* header = NULL; size_t header_length = 0; @@ -342,6 +349,9 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati char* current = params->jwt; char* next = strchr(params->jwt, '.'); + size_t current_length; + time_t ct; + if (next == NULL) /* No payload. */ { return L8W8JWT_DECODE_FAILED_INVALID_TOKEN_FORMAT; @@ -385,7 +395,7 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati goto exit; } - size_t current_length = next - current; + current_length = next - current; r = l8w8jwt_base64_decode(true, current, current_length, (uint8_t**)&header, &header_length); if (r != L8W8JWT_SUCCESS) @@ -651,7 +661,7 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati if (params->validate_sub != NULL) { - struct l8w8jwt_claim* c = l8w8jwt_get_claim(claims.array, claims.length, "sub", 3); + struct l8w8jwt_claim* c = l8w8jwt_get_claim((l8w8jwt_claim*)claims.array, claims.length, "sub", 3); if (c == NULL || strncmp(c->value, params->validate_sub, params->validate_sub_length ? params->validate_sub_length : strlen(params->validate_sub)) != 0) { validation_res |= (unsigned)L8W8JWT_SUB_FAILURE; @@ -660,7 +670,7 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati if (params->validate_aud != NULL) { - struct l8w8jwt_claim* c = l8w8jwt_get_claim(claims.array, claims.length, "aud", 3); + struct l8w8jwt_claim* c = l8w8jwt_get_claim((l8w8jwt_claim*)claims.array, claims.length, "aud", 3); if (c == NULL || strncmp(c->value, params->validate_aud, params->validate_aud_length ? params->validate_aud_length : strlen(params->validate_aud)) != 0) { validation_res |= (unsigned)L8W8JWT_AUD_FAILURE; @@ -669,7 +679,7 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati if (params->validate_iss != NULL) { - struct l8w8jwt_claim* c = l8w8jwt_get_claim(claims.array, claims.length, "iss", 3); + struct l8w8jwt_claim* c = l8w8jwt_get_claim((l8w8jwt_claim*)claims.array, claims.length, "iss", 3); if (c == NULL || strncmp(c->value, params->validate_iss, params->validate_iss_length ? params->validate_iss_length : strlen(params->validate_iss)) != 0) { validation_res |= (unsigned)L8W8JWT_ISS_FAILURE; @@ -678,18 +688,18 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati if (params->validate_jti != NULL) { - struct l8w8jwt_claim* c = l8w8jwt_get_claim(claims.array, claims.length, "jti", 3); + struct l8w8jwt_claim* c = l8w8jwt_get_claim((l8w8jwt_claim*)claims.array, claims.length, "jti", 3); if (c == NULL || strncmp(c->value, params->validate_jti, params->validate_jti_length ? params->validate_jti_length : strlen(params->validate_jti)) != 0) { validation_res |= (unsigned)L8W8JWT_JTI_FAILURE; } } - const time_t ct = time(NULL); + ct = time(NULL); if (params->validate_exp) { - struct l8w8jwt_claim* c = l8w8jwt_get_claim(claims.array, claims.length, "exp", 3); + struct l8w8jwt_claim* c = l8w8jwt_get_claim((l8w8jwt_claim*)claims.array, claims.length, "exp", 3); if (c == NULL || ct - params->exp_tolerance_seconds > strtoll(c->value, NULL, 10)) { validation_res |= (unsigned)L8W8JWT_EXP_FAILURE; @@ -698,7 +708,7 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati if (params->validate_nbf) { - struct l8w8jwt_claim* c = l8w8jwt_get_claim(claims.array, claims.length, "nbf", 3); + struct l8w8jwt_claim* c = l8w8jwt_get_claim((l8w8jwt_claim*)claims.array, claims.length, "nbf", 3); if (c == NULL || ct + params->nbf_tolerance_seconds < strtoll(c->value, NULL, 10)) { validation_res |= (unsigned)L8W8JWT_NBF_FAILURE; @@ -707,7 +717,7 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati if (params->validate_iat) { - struct l8w8jwt_claim* c = l8w8jwt_get_claim(claims.array, claims.length, "iat", 3); + struct l8w8jwt_claim* c = l8w8jwt_get_claim((l8w8jwt_claim*)claims.array, claims.length, "iat", 3); if (c == NULL || ct + params->iat_tolerance_seconds < strtoll(c->value, NULL, 10)) { validation_res |= (unsigned)L8W8JWT_IAT_FAILURE; @@ -716,7 +726,7 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati if (params->validate_typ) { - struct l8w8jwt_claim* c = l8w8jwt_get_claim(claims.array, claims.length, "typ", 3); + struct l8w8jwt_claim* c = l8w8jwt_get_claim((l8w8jwt_claim*)claims.array, claims.length, "typ", 3); if (c == NULL || l8w8jwt_strncmpic(c->value, params->validate_typ, params->validate_typ_length) != 0) { validation_res |= (unsigned)L8W8JWT_TYP_FAILURE; @@ -724,7 +734,7 @@ int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validati } r = L8W8JWT_SUCCESS; - *out_validation_result = validation_res; + *out_validation_result = (l8w8jwt_validation_result)validation_res; if (out_claims != NULL && out_claims_length != NULL) { @@ -764,6 +774,6 @@ exit: #undef JSMN_STATIC -#ifdef __cplusplus -} // extern "C" -#endif +//#ifdef __cplusplus +//} // extern "C" +//#endif diff --git a/src/thirdparty/jwt/encode.cpp b/src/thirdparty/jwt/encode.cpp index 081901e2..d3caca39 100644 --- a/src/thirdparty/jwt/encode.cpp +++ b/src/thirdparty/jwt/encode.cpp @@ -14,9 +14,9 @@ limitations under the License. */ -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif #include "include/util.h" #include "include/encode.h" @@ -24,6 +24,7 @@ extern "C" { #include "include/chillbuff.h" #include + #include #include #include @@ -143,7 +144,7 @@ static int write_header_and_payload(chillbuff* stringbuilder, struct l8w8jwt_enc char* segment; size_t segment_length; - r = l8w8jwt_base64_encode(1, buff.array, buff.length, &segment, &segment_length); + r = l8w8jwt_base64_encode(1, (const uint8_t*)buff.array, buff.length, &segment, &segment_length); if (r != L8W8JWT_SUCCESS) { chillbuff_free(&buff); @@ -176,13 +177,13 @@ static int write_header_and_payload(chillbuff* stringbuilder, struct l8w8jwt_enc struct l8w8jwt_claim claims[] = { // Setting l8w8jwt_claim::value_length to 0 makes the encoder use strlen, which in this case is fine. - { .key = *(iatnbfexp + 00) ? "iat" : NULL, .key_length = 3, .value = iatnbfexp + 00, .value_length = 0, .type = L8W8JWT_CLAIM_TYPE_INTEGER }, - { .key = *(iatnbfexp + 21) ? "nbf" : NULL, .key_length = 3, .value = iatnbfexp + 21, .value_length = 0, .type = L8W8JWT_CLAIM_TYPE_INTEGER }, - { .key = *(iatnbfexp + 42) ? "exp" : NULL, .key_length = 3, .value = iatnbfexp + 42, .value_length = 0, .type = L8W8JWT_CLAIM_TYPE_INTEGER }, - { .key = params->sub ? "sub" : NULL, .key_length = 3, .value = params->sub, .value_length = params->sub_length, .type = L8W8JWT_CLAIM_TYPE_STRING }, - { .key = params->iss ? "iss" : NULL, .key_length = 3, .value = params->iss, .value_length = params->iss_length, .type = L8W8JWT_CLAIM_TYPE_STRING }, - { .key = params->aud ? "aud" : NULL, .key_length = 3, .value = params->aud, .value_length = params->aud_length, .type = L8W8JWT_CLAIM_TYPE_STRING }, - { .key = params->jti ? "jti" : NULL, .key_length = 3, .value = params->jti, .value_length = params->jti_length, .type = L8W8JWT_CLAIM_TYPE_STRING }, + { *(iatnbfexp + 00) ? (char*)"iat" : NULL, 3, iatnbfexp + 00, 0, L8W8JWT_CLAIM_TYPE_INTEGER }, + { *(iatnbfexp + 21) ? (char*)"nbf" : NULL, 3, iatnbfexp + 21, 0, L8W8JWT_CLAIM_TYPE_INTEGER }, + { *(iatnbfexp + 42) ? (char*)"exp" : NULL, 3, iatnbfexp + 42, 0, L8W8JWT_CLAIM_TYPE_INTEGER }, + { params->sub ? (char*)"sub" : NULL, 3, params->sub, params->sub_length, L8W8JWT_CLAIM_TYPE_STRING }, + { params->iss ? (char*)"iss" : NULL, 3, params->iss, params->iss_length, L8W8JWT_CLAIM_TYPE_STRING }, + { params->aud ? (char*)"aud" : NULL, 3, params->aud, params->aud_length, L8W8JWT_CLAIM_TYPE_STRING }, + { params->jti ? (char*)"jti" : NULL, 3, params->jti, params->jti_length, L8W8JWT_CLAIM_TYPE_STRING }, }; chillbuff_push_back(&buff, "{", 1); @@ -199,7 +200,7 @@ static int write_header_and_payload(chillbuff* stringbuilder, struct l8w8jwt_enc chillbuff_push_back(&buff, "}", 1); - r = l8w8jwt_base64_encode(1, buff.array, buff.length, &segment, &segment_length); + r = l8w8jwt_base64_encode(1, (const uint8_t*)buff.array, buff.length, &segment, &segment_length); if (r != L8W8JWT_SUCCESS) { chillbuff_free(&buff); @@ -221,6 +222,8 @@ static int write_signature(chillbuff* stringbuilder, struct l8w8jwt_encoding_par int r; const int alg = params->alg; + unsigned char hash[64] = { 0x00 }; + char* signature = NULL; size_t signature_length = 0, signature_bytes_length = 0, key_length = 0; @@ -228,6 +231,12 @@ static int write_signature(chillbuff* stringbuilder, struct l8w8jwt_encoding_par mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; + size_t md_length; + mbedtls_md_type_t md_type; + mbedtls_md_info_t* md_info; + + size_t half_signature_bytes_length; + mbedtls_pk_init(&pk); mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&ctr_drbg); @@ -263,14 +272,8 @@ static int write_signature(chillbuff* stringbuilder, struct l8w8jwt_encoding_par goto exit; } - size_t md_length; - mbedtls_md_type_t md_type; - mbedtls_md_info_t* md_info; - md_info_from_alg(alg, &md_info, &md_type, &md_length); - unsigned char hash[64] = { 0x00 }; - switch (alg) { case L8W8JWT_ALG_HS256: @@ -492,7 +495,7 @@ static int write_signature(chillbuff* stringbuilder, struct l8w8jwt_encoding_par goto ecdsa_exit; } - const size_t half_signature_bytes_length = signature_bytes_length / 2; + half_signature_bytes_length = signature_bytes_length / 2; r = mbedtls_mpi_write_binary(&sig_r, signature_bytes, half_signature_bytes_length); if (r != 0) @@ -589,7 +592,7 @@ exit: /* Step 3: finalize the token by writing it into the "out" string defined in the l8w8jwt_encoding_params argument. */ static int write_token(chillbuff* stringbuilder, struct l8w8jwt_encoding_params* params) { - *(params->out) = malloc(stringbuilder->length + 1); + *(params->out) = (char*)malloc(stringbuilder->length + 1); if (*(params->out) == NULL) { return L8W8JWT_OUT_OF_MEM; @@ -680,6 +683,6 @@ exit: return r; } -#ifdef __cplusplus -} // extern "C" -#endif +//#ifdef __cplusplus +//} // extern "C" +//#endif diff --git a/src/thirdparty/jwt/include/base64.h b/src/thirdparty/jwt/include/base64.h index f3124fc8..f6211f60 100644 --- a/src/thirdparty/jwt/include/base64.h +++ b/src/thirdparty/jwt/include/base64.h @@ -26,9 +26,9 @@ #ifndef L8W8JWT_BASE64_H #define L8W8JWT_BASE64_H -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif #include "version.h" #include @@ -70,8 +70,8 @@ L8W8JWT_API int l8w8jwt_base64_encode(int url, const uint8_t* data, size_t data_ */ L8W8JWT_API int l8w8jwt_base64_decode(int url, const char* data, size_t data_length, uint8_t** out, size_t* out_length); -#ifdef __cplusplus -} // extern "C" -#endif +//#ifdef __cplusplus +//} // extern "C" +//#endif #endif // L8W8JWT_BASE64_H diff --git a/src/thirdparty/jwt/include/checknum.h b/src/thirdparty/jwt/include/checknum.h new file mode 100644 index 00000000..c84a32fa --- /dev/null +++ b/src/thirdparty/jwt/include/checknum.h @@ -0,0 +1,141 @@ +/* + Copyright 2020 Raphael Beck + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file checknum.h + * @author Raphael Beck + * @brief Check whether a given string contains an integer or floating point number. + */ + +/* https://github.com/GlitchedPolygons/checknum */ + +#ifndef CHECKNUM_H +#define CHECKNUM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CHECKNUM_STATIC + #define CHECKNUM_API static +#else + #define CHECKNUM_API extern +#endif + +#include +#include +#include +#include + +/** + * Checks whether a given string contains a valid integer or floating point number.

+ * If it's an integer, 1 is returned.

+ * If it's a float or a double, 2 is returned.

+ * If the string doesn't contain a valid number at all, 0 is returned. + */ +CHECKNUM_API int checknum(char* string, size_t string_length) +{ + if (string == NULL) + return 0; + + if (string_length == 0) + string_length = strlen(string); + + char* c = string; + + while (*c == ' ' && c < string + string_length) + c++; + + while (*(string + string_length - 1) == ' ' && c < string + string_length) + string_length--; + + switch (*c) + { + case '+': + case '-': + if (++c >= string + string_length) + return 0; + default: + break; + } + + unsigned int type = 0; + + if (*c == '0') + { + type |= 1 << 0; + if (*++c != '.' && c < string + string_length) + return 0; + } + + for (; c < string + string_length; c++) + { + switch (*c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + type |= 1 << 0; + continue; + case '-': + if (type & 1 << 1 || (*(c - 1) != 'E' && *(c - 1) != 'e')) + return 0; + type |= 1 << 1; + continue; + case '.': + if (type & 1 << 2 || type & 1 << 3) + return 0; + type |= 1 << 2; + continue; + case 'E': + case 'e': + if (!(type & 1 << 0) || type & 1 << 3 || c + 1 >= string + string_length) + return 0; + type |= 1 << 3; + continue; + case '+': + if (type & 1 << 4 || (*(c - 1) != 'E' && *(c - 1) != 'e')) + return 0; + type |= 1 << 4; + continue; + default: + return 0; + } + } + + switch (type) + { + case 0: + return 0; + case 1 << 0: + return 1; + default: + return type & 1 << 0 ? 2 : 0; + } +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // CHECKNUM_H diff --git a/src/thirdparty/jwt/include/claim.h b/src/thirdparty/jwt/include/claim.h index 0b55acad..a6cc1aa8 100644 --- a/src/thirdparty/jwt/include/claim.h +++ b/src/thirdparty/jwt/include/claim.h @@ -23,9 +23,9 @@ #ifndef L8W8JWT_CLAIM_H #define L8W8JWT_CLAIM_H -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif #include "version.h" #include @@ -139,8 +139,8 @@ L8W8JWT_API int l8w8jwt_write_claims(struct chillbuff* stringbuilder, struct l8w */ L8W8JWT_API struct l8w8jwt_claim* l8w8jwt_get_claim(struct l8w8jwt_claim* claims, size_t claims_count, const char* key, size_t key_length); -#ifdef __cplusplus -} // extern "C" -#endif +//#ifdef __cplusplus +//} // extern "C" +//#endif #endif // L8W8JWT_CLAIM_H diff --git a/src/thirdparty/jwt/include/decode.h b/src/thirdparty/jwt/include/decode.h index a8a31cb4..42ee2a78 100644 --- a/src/thirdparty/jwt/include/decode.h +++ b/src/thirdparty/jwt/include/decode.h @@ -23,9 +23,9 @@ #ifndef L8W8JWT_DECODE_H #define L8W8JWT_DECODE_H -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif #include "algs.h" #include "claim.h" @@ -267,8 +267,8 @@ L8W8JWT_API int l8w8jwt_validate_decoding_params(struct l8w8jwt_decoding_params* */ L8W8JWT_API int l8w8jwt_decode(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validation_result* out_validation_result, struct l8w8jwt_claim** out_claims, size_t* out_claims_length); -#ifdef __cplusplus -} // extern "C" -#endif +//#ifdef __cplusplus +//} // extern "C" +//#endif #endif // L8W8JWT_DECODE_H diff --git a/src/thirdparty/jwt/include/encode.h b/src/thirdparty/jwt/include/encode.h index a1b8e1c9..963b0f1c 100644 --- a/src/thirdparty/jwt/include/encode.h +++ b/src/thirdparty/jwt/include/encode.h @@ -23,9 +23,9 @@ #ifndef L8W8JWT_ENCODE_H #define L8W8JWT_ENCODE_H -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif #include "algs.h" #include "claim.h" @@ -199,8 +199,8 @@ L8W8JWT_API int l8w8jwt_validate_encoding_params(struct l8w8jwt_encoding_params* */ L8W8JWT_API int l8w8jwt_encode(struct l8w8jwt_encoding_params* params); -#ifdef __cplusplus -} // extern "C" -#endif +//#ifdef __cplusplus +//} // extern "C" +//#endif #endif // L8W8JWT_ENCODE_H diff --git a/src/thirdparty/jwt/include/jsmn.h b/src/thirdparty/jwt/include/jsmn.h new file mode 100644 index 00000000..8ac14c1b --- /dev/null +++ b/src/thirdparty/jwt/include/jsmn.h @@ -0,0 +1,471 @@ +/* + * MIT License + * + * Copyright (c) 2010 Serge Zaitsev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef JSMN_H +#define JSMN_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef JSMN_STATIC +#define JSMN_API static +#else +#define JSMN_API extern +#endif + +/** + * JSON type identifier. Basic types are: + * o Object + * o Array + * o String + * o Other primitive: number, boolean (true/false) or null + */ +typedef enum { + JSMN_UNDEFINED = 0, + JSMN_OBJECT = 1 << 0, + JSMN_ARRAY = 1 << 1, + JSMN_STRING = 1 << 2, + JSMN_PRIMITIVE = 1 << 3 +} jsmntype_t; + +enum jsmnerr { + /* Not enough tokens were provided */ + JSMN_ERROR_NOMEM = -1, + /* Invalid character inside JSON string */ + JSMN_ERROR_INVAL = -2, + /* The string is not a full JSON packet, more bytes expected */ + JSMN_ERROR_PART = -3 +}; + +/** + * JSON token description. + * type type (object, array, string etc.) + * start start position in JSON data string + * end end position in JSON data string + */ +typedef struct jsmntok { + jsmntype_t type; + int start; + int end; + int size; +#ifdef JSMN_PARENT_LINKS + int parent; +#endif +} jsmntok_t; + +/** + * JSON parser. Contains an array of token blocks available. Also stores + * the string being parsed now and current position in that string. + */ +typedef struct jsmn_parser { + unsigned int pos; /* offset in the JSON string */ + unsigned int toknext; /* next token to allocate */ + int toksuper; /* superior token node, e.g. parent object or array */ +} jsmn_parser; + +/** + * Create JSON parser over an array of tokens + */ +JSMN_API void jsmn_init(jsmn_parser *parser); + +/** + * Run JSON parser. It parses a JSON data string into and array of tokens, each + * describing + * a single JSON object. + */ +JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, + jsmntok_t *tokens, const unsigned int num_tokens); + +#ifndef JSMN_HEADER +/** + * Allocates a fresh unused token from the token pool. + */ +static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *tok; + if (parser->toknext >= num_tokens) { + return NULL; + } + tok = &tokens[parser->toknext++]; + tok->start = tok->end = -1; + tok->size = 0; +#ifdef JSMN_PARENT_LINKS + tok->parent = -1; +#endif + return tok; +} + +/** + * Fills token type and boundaries. + */ +static void jsmn_fill_token(jsmntok_t *token, const jsmntype_t type, + const int start, const int end) { + token->type = type; + token->start = start; + token->end = end; + token->size = 0; +} + +/** + * Fills next available token with JSON primitive. + */ +static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, + const size_t len, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *token; + int start; + + start = parser->pos; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + switch (js[parser->pos]) { +#ifndef JSMN_STRICT + /* In strict mode primitive must be followed by "," or "}" or "]" */ + case ':': +#endif + case '\t': + case '\r': + case '\n': + case ' ': + case ',': + case ']': + case '}': + goto found; + default: + /* to quiet a warning from gcc*/ + break; + } + if (js[parser->pos] < 32 || js[parser->pos] >= 127) { + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } +#ifdef JSMN_STRICT + /* In strict mode primitive must be followed by a comma/object/array */ + parser->pos = start; + return JSMN_ERROR_PART; +#endif + +found: + if (tokens == NULL) { + parser->pos--; + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + parser->pos--; + return 0; +} + +/** + * Fills next token with JSON string. + */ +static int jsmn_parse_string(jsmn_parser *parser, const char *js, + const size_t len, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *token; + + int start = parser->pos; + + /* Skip starting quote */ + parser->pos++; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c = js[parser->pos]; + + /* Quote: end of string */ + if (c == '\"') { + if (tokens == NULL) { + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_STRING, start + 1, parser->pos); +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + return 0; + } + + /* Backslash: Quoted symbol expected */ + if (c == '\\' && parser->pos + 1 < len) { + int i; + parser->pos++; + switch (js[parser->pos]) { + /* Allowed escaped symbols */ + case '\"': + case '/': + case '\\': + case 'b': + case 'f': + case 'r': + case 'n': + case 't': + break; + /* Allows escaped symbol \uXXXX */ + case 'u': + parser->pos++; + for (i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; + i++) { + /* If it isn't a hex character we have an error */ + if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ + (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ + (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ + parser->pos = start; + return JSMN_ERROR_INVAL; + } + parser->pos++; + } + parser->pos--; + break; + /* Unexpected symbol */ + default: + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } + } + parser->pos = start; + return JSMN_ERROR_PART; +} + +/** + * Parse JSON string and fill tokens. + */ +JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, + jsmntok_t *tokens, const unsigned int num_tokens) { + int r; + int i; + jsmntok_t *token; + int count = parser->toknext; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c; + jsmntype_t type; + + c = js[parser->pos]; + switch (c) { + case '{': + case '[': + count++; + if (tokens == NULL) { + break; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + return JSMN_ERROR_NOMEM; + } + if (parser->toksuper != -1) { + jsmntok_t *t = &tokens[parser->toksuper]; +#ifdef JSMN_STRICT + /* In strict mode an object or array can't become a key */ + if (t->type == JSMN_OBJECT) { + return JSMN_ERROR_INVAL; + } +#endif + t->size++; +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + } + token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); + token->start = parser->pos; + parser->toksuper = parser->toknext - 1; + break; + case '}': + case ']': + if (tokens == NULL) { + break; + } + type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); +#ifdef JSMN_PARENT_LINKS + if (parser->toknext < 1) { + return JSMN_ERROR_INVAL; + } + token = &tokens[parser->toknext - 1]; + for (;;) { + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + token->end = parser->pos + 1; + parser->toksuper = token->parent; + break; + } + if (token->parent == -1) { + if (token->type != type || parser->toksuper == -1) { + return JSMN_ERROR_INVAL; + } + break; + } + token = &tokens[token->parent]; + } +#else + for (i = parser->toknext - 1; i >= 0; i--) { + token = &tokens[i]; + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + parser->toksuper = -1; + token->end = parser->pos + 1; + break; + } + } + /* Error if unmatched closing bracket */ + if (i == -1) { + return JSMN_ERROR_INVAL; + } + for (; i >= 0; i--) { + token = &tokens[i]; + if (token->start != -1 && token->end == -1) { + parser->toksuper = i; + break; + } + } +#endif + break; + case '\"': + r = jsmn_parse_string(parser, js, len, tokens, num_tokens); + if (r < 0) { + return r; + } + count++; + if (parser->toksuper != -1 && tokens != NULL) { + tokens[parser->toksuper].size++; + } + break; + case '\t': + case '\r': + case '\n': + case ' ': + break; + case ':': + parser->toksuper = parser->toknext - 1; + break; + case ',': + if (tokens != NULL && parser->toksuper != -1 && + tokens[parser->toksuper].type != JSMN_ARRAY && + tokens[parser->toksuper].type != JSMN_OBJECT) { +#ifdef JSMN_PARENT_LINKS + parser->toksuper = tokens[parser->toksuper].parent; +#else + for (i = parser->toknext - 1; i >= 0; i--) { + if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { + if (tokens[i].start != -1 && tokens[i].end == -1) { + parser->toksuper = i; + break; + } + } + } +#endif + } + break; +#ifdef JSMN_STRICT + /* In strict mode primitives are: numbers and booleans */ + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 't': + case 'f': + case 'n': + /* And they must not be keys of the object */ + if (tokens != NULL && parser->toksuper != -1) { + const jsmntok_t *t = &tokens[parser->toksuper]; + if (t->type == JSMN_OBJECT || + (t->type == JSMN_STRING && t->size != 0)) { + return JSMN_ERROR_INVAL; + } + } +#else + /* In non-strict mode every unquoted value is a primitive */ + default: +#endif + r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); + if (r < 0) { + return r; + } + count++; + if (parser->toksuper != -1 && tokens != NULL) { + tokens[parser->toksuper].size++; + } + break; + +#ifdef JSMN_STRICT + /* Unexpected char in strict mode */ + default: + return JSMN_ERROR_INVAL; +#endif + } + } + + if (tokens != NULL) { + for (i = parser->toknext - 1; i >= 0; i--) { + /* Unmatched opened object or array */ + if (tokens[i].start != -1 && tokens[i].end == -1) { + return JSMN_ERROR_PART; + } + } + } + + return count; +} + +/** + * Creates a new parser based over a given buffer with an array of tokens + * available. + */ +JSMN_API void jsmn_init(jsmn_parser *parser) { + parser->pos = 0; + parser->toknext = 0; + parser->toksuper = -1; +} + +#endif /* JSMN_HEADER */ + +#ifdef __cplusplus +} +#endif + +#endif /* JSMN_H */ diff --git a/src/thirdparty/jwt/include/retcodes.h b/src/thirdparty/jwt/include/retcodes.h index fe3bef71..653e5303 100644 --- a/src/thirdparty/jwt/include/retcodes.h +++ b/src/thirdparty/jwt/include/retcodes.h @@ -23,9 +23,9 @@ #ifndef L8W8JWT_RETCODES_H #define L8W8JWT_RETCODES_H -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif /** * Returned from a l8w8jwt function when everything went smooth 'n' chill. Time to get Schwifty, Morteyy! @@ -100,8 +100,8 @@ extern "C" { */ #define L8W8JWT_UNSUPPORTED_ALG 800 -#ifdef __cplusplus -} // extern "C" -#endif +//#ifdef __cplusplus +//} // extern "C" +//#endif #endif // L8W8JWT_RETCODES_H diff --git a/src/thirdparty/jwt/include/util.h b/src/thirdparty/jwt/include/util.h index 7bd4d479..9df8f292 100644 --- a/src/thirdparty/jwt/include/util.h +++ b/src/thirdparty/jwt/include/util.h @@ -23,9 +23,9 @@ #ifndef L8W8JWT_UTIL_H #define L8W8JWT_UTIL_H -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif #include #include "version.h" @@ -51,8 +51,8 @@ L8W8JWT_API int l8w8jwt_hexstr2bin(const char* hexstr, size_t hexstr_length, uns */ L8W8JWT_API int l8w8jwt_strncmpic(const char* str1, const char* str2, size_t n); -#ifdef __cplusplus -} // extern "C" -#endif +//#ifdef __cplusplus +//} // extern "C" +//#endif #endif // L8W8JWT_UTIL_H \ No newline at end of file diff --git a/src/thirdparty/jwt/include/version.h b/src/thirdparty/jwt/include/version.h index 9fce28a0..4f196d2c 100644 --- a/src/thirdparty/jwt/include/version.h +++ b/src/thirdparty/jwt/include/version.h @@ -23,9 +23,9 @@ #ifndef L8W8JWT_VERSION_H #define L8W8JWT_VERSION_H -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif /** * Current l8w8jwt version number. @@ -80,8 +80,8 @@ L8W8JWT_API int l8w8jwt_get_version_number(void); */ L8W8JWT_API void l8w8jwt_get_version_string(char out[32]); -#ifdef __cplusplus -} // extern "C" -#endif +//#ifdef __cplusplus +//} // extern "C" +//#endif #endif // L8W8JWT_VERSION_H diff --git a/src/thirdparty/jwt/util.cpp b/src/thirdparty/jwt/util.cpp index 686659e9..2a827fcc 100644 --- a/src/thirdparty/jwt/util.cpp +++ b/src/thirdparty/jwt/util.cpp @@ -17,9 +17,9 @@ #include "include/util.h" #include -#ifdef __cplusplus -extern "C" { -#endif +//#ifdef __cplusplus +//extern "C" { +//#endif int l8w8jwt_hexstr2bin(const char* hexstr, const size_t hexstr_length, unsigned char* output, const size_t output_size, size_t* output_length) { @@ -82,6 +82,6 @@ int l8w8jwt_strncmpic(const char* str1, const char* str2, size_t n) return ret; } -#ifdef __cplusplus -} // extern "C" -#endif \ No newline at end of file +//#ifdef __cplusplus +//} // extern "C" +//#endif \ No newline at end of file diff --git a/src/thirdparty/jwt/version.cpp b/src/thirdparty/jwt/version.cpp index 2484b772..f8b94b82 100644 --- a/src/thirdparty/jwt/version.cpp +++ b/src/thirdparty/jwt/version.cpp @@ -18,10 +18,14 @@ #include #include -#ifdef __cplusplus -extern "C" { +#if defined(_WIN32) +#include #endif +//#ifdef __cplusplus +//extern "C" { +//#endif + void l8w8jwt_free(void* mem) { free(mem); @@ -29,8 +33,6 @@ void l8w8jwt_free(void* mem) void l8w8jwt_zero(void* buf, size_t len) { - MBEDTLS_INTERNAL_VALIDATE(len == 0 || buf != NULL); - if (len > 0) { #if defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO) @@ -68,6 +70,6 @@ void l8w8jwt_get_version_string(char out[32]) out[version_string_length] = '\0'; } -#ifdef __cplusplus -} // extern "C" -#endif \ No newline at end of file +//#ifdef __cplusplus +//} // extern "C" +//#endif \ No newline at end of file