ThirdParty: upgrade l8w8jwt library to 2.4.0

Security fixes.
This commit is contained in:
Kawe Mazidjatari 2024-11-12 00:10:46 +01:00
parent e5d7644d19
commit 24e731e4ee
12 changed files with 964 additions and 539 deletions

View File

@ -19,6 +19,7 @@ add_sources( SOURCE_GROUP "Include"
"include/decode.h"
"include/encode.h"
"include/retcodes.h"
"include/timehelper.h"
"include/util.h"
"include/version.h"
)

View File

@ -104,6 +104,7 @@ after February 11, 2012 is no longer under the GPL v2 option.
#include <stdio.h>
#include <stdlib.h>
#include "include/util.h"
#include "include/base64.h"
#include "include/version.h"
#include "include/retcodes.h"
@ -133,7 +134,7 @@ int l8w8jwt_base64_encode(const int url, const uint8_t* data, const size_t data_
return L8W8JWT_OVERFLOW;
}
*out = (char*)malloc(olen);
*out = l8w8jwt_malloc(olen);
if (*out == NULL)
{
return L8W8JWT_OUT_OF_MEM;
@ -228,14 +229,14 @@ int l8w8jwt_base64_decode(const int url, const char* data, const size_t data_len
memset(dtable, 0x80, 256);
for (i = 0; i < 64; i++)
for (i = 0; i < 64; ++i)
{
dtable[table[i]] = (uint8_t)i;
}
dtable['='] = 0;
for (i = 0; i < in_length; i++)
for (i = 0; i < in_length; ++i)
{
if (dtable[(unsigned char)data[i]] != 0x80)
count++;
@ -249,7 +250,7 @@ int l8w8jwt_base64_decode(const int url, const char* data, const size_t data_len
if (r == 3)
r = 1;
*out = (uint8_t*)calloc(count / 4 * 3 + 16, sizeof(uint8_t));
*out = l8w8jwt_calloc(count / 4 * 3 + 16, sizeof(uint8_t));
if (*out == NULL)
{
return L8W8JWT_OUT_OF_MEM;
@ -261,7 +262,7 @@ int l8w8jwt_base64_decode(const int url, const char* data, const size_t data_len
uint8_t block[4];
uint8_t* pos = *out;
for (i = 0; i < in_length + r; i++)
for (i = 0; i < in_length + r; ++i)
{
const unsigned char c = i < in_length ? data[i] : '=';

View File

@ -25,45 +25,86 @@ extern "C" {
#include <string.h>
#include <mbedtls/md.h>
#include <mbedtls/platform_util.h>
void l8w8jwt_free_claims(struct l8w8jwt_claim* claims, const size_t claims_count)
{
if (claims != NULL && claims_count > 0)
if (claims == NULL)
{
for (struct l8w8jwt_claim* claim = claims; claim < claims + claims_count; ++claim)
return;
}
for (struct l8w8jwt_claim* claim = claims; claim < claims + claims_count; ++claim)
{
if (claim == NULL)
{
if (claim == NULL)
continue;
l8w8jwt_zero(claim->key, claim->key_length);
l8w8jwt_zero(claim->value, claim->value_length);
l8w8jwt_free(claim->key);
l8w8jwt_free(claim->value);
continue;
}
l8w8jwt_zero(claims, claims_count * sizeof(struct l8w8jwt_claim));
l8w8jwt_free(claims);
mbedtls_platform_zeroize(claim->key, claim->key_length);
mbedtls_platform_zeroize(claim->value, claim->value_length);
l8w8jwt_free(claim->key);
l8w8jwt_free(claim->value);
}
if (claims_count != 0)
{
mbedtls_platform_zeroize(claims, claims_count * sizeof(struct l8w8jwt_claim));
}
l8w8jwt_free(claims);
}
static inline void l8w8jwt_escape_claim_string(struct chillbuff* stringbuilder, const char* string, const size_t string_length)
{
static const char* escape_table[] = {
"\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007",
"\\b", "\\t", "\\n", "\\u000b", "\\f", "\\r", "\\u000e", "\\u000f",
"\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017",
"\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f",
NULL, NULL, "\\\"", NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\/",
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, "\\\\", NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, "\\u007f",
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
for (size_t i = 0; i < string_length; ++i)
{
const char c = string[i];
const char* e = escape_table[c];
switch (c)
if (e)
{
case '\\':
chillbuff_push_back(stringbuilder, "\\\\", 2);
break;
case '\"':
chillbuff_push_back(stringbuilder, "\\\"", 2);
break;
default:
chillbuff_push_back(stringbuilder, &c, 1);
break;
chillbuff_push_back(stringbuilder, e, strlen(e));
}
else
{
chillbuff_push_back(stringbuilder, &c, 1);
}
}
}
@ -110,15 +151,20 @@ int l8w8jwt_write_claims(struct chillbuff* stringbuilder, struct l8w8jwt_claim*
chillbuff_push_back(stringbuilder, "\":", 2);
if (claim->type == L8W8JWT_CLAIM_TYPE_STRING)
{
chillbuff_push_back(stringbuilder, "\"", 1);
chillbuff_clear(&escape_buffer);
l8w8jwt_escape_claim_string(&escape_buffer, claim->value, value_length);
chillbuff_clear(&escape_buffer);
l8w8jwt_escape_claim_string(&escape_buffer, claim->value, value_length);
chillbuff_push_back(stringbuilder, escape_buffer.array,escape_buffer.length);
chillbuff_push_back(stringbuilder, escape_buffer.array, escape_buffer.length);
if (claim->type == L8W8JWT_CLAIM_TYPE_STRING)
chillbuff_push_back(stringbuilder, "\"", 1);
}
else
{
chillbuff_push_back(stringbuilder, claim->value, value_length);
}
first = 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,6 @@ extern "C" {
#include "include/chillbuff.h"
#include <inttypes.h>
#include <mbedtls/pk.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
@ -144,7 +143,7 @@ static int write_header_and_payload(chillbuff* stringbuilder, struct l8w8jwt_enc
char* segment;
size_t segment_length;
r = l8w8jwt_base64_encode(1, (const uint8_t*)buff.array, buff.length, &segment, &segment_length);
r = l8w8jwt_base64_encode(1, buff.array, buff.length, &segment, &segment_length);
if (r != L8W8JWT_SUCCESS)
{
chillbuff_free(&buff);
@ -177,13 +176,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.
{ *(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 },
{ .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 },
};
chillbuff_push_back(&buff, "{", 1);
@ -200,7 +199,7 @@ static int write_header_and_payload(chillbuff* stringbuilder, struct l8w8jwt_enc
chillbuff_push_back(&buff, "}", 1);
r = l8w8jwt_base64_encode(1, (const uint8_t*)buff.array, buff.length, &segment, &segment_length);
r = l8w8jwt_base64_encode(1, buff.array, buff.length, &segment, &segment_length);
if (r != L8W8JWT_SUCCESS)
{
chillbuff_free(&buff);
@ -222,8 +221,6 @@ 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;
@ -231,19 +228,13 @@ 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);
#if L8W8JWT_SMALL_STACK
unsigned char* signature_bytes = calloc(sizeof(unsigned char), 4096);
unsigned char* key = calloc(sizeof(unsigned char), L8W8JWT_MAX_KEY_SIZE);
unsigned char* signature_bytes = l8w8jwt_calloc(sizeof(unsigned char), 4096);
unsigned char* key = l8w8jwt_calloc(sizeof(unsigned char), L8W8JWT_MAX_KEY_SIZE);
if (signature_bytes == NULL || key == NULL)
{
@ -272,8 +263,14 @@ static int write_signature(chillbuff* stringbuilder, struct l8w8jwt_encoding_par
goto exit;
}
size_t md_length = 0;
mbedtls_md_type_t md_type = MBEDTLS_MD_NONE;
mbedtls_md_info_t* md_info = NULL;
md_info_from_alg(alg, &md_info, &md_type, &md_length);
unsigned char hash[64] = { 0x00 };
switch (alg)
{
case L8W8JWT_ALG_HS256:
@ -495,7 +492,7 @@ static int write_signature(chillbuff* stringbuilder, struct l8w8jwt_encoding_par
goto ecdsa_exit;
}
half_signature_bytes_length = signature_bytes_length / 2;
const size_t half_signature_bytes_length = signature_bytes_length / 2;
r = mbedtls_mpi_write_binary(&sig_r, signature_bytes, half_signature_bytes_length);
if (r != 0)
@ -543,7 +540,7 @@ static int write_signature(chillbuff* stringbuilder, struct l8w8jwt_encoding_par
ed25519_sign_ref10(signature_bytes, (const unsigned char*)stringbuilder->array, stringbuilder->length, private_key_ref10);
signature_bytes_length = 64;
l8w8jwt_zero(private_key_ref10, sizeof(private_key_ref10));
mbedtls_platform_zeroize(private_key_ref10, sizeof(private_key_ref10));
break;
#else
r = L8W8JWT_UNSUPPORTED_ALG;
@ -563,7 +560,7 @@ static int write_signature(chillbuff* stringbuilder, struct l8w8jwt_encoding_par
}
/*
* If this succeeds, it mallocs "signature" and assigns the resulting string length to "signature_length".
* If this succeeds, it mallocs "signature" (using l8w8jwt_malloc) and assigns the resulting string length to "signature_length".
*/
r = l8w8jwt_base64_encode(1, (uint8_t*)signature_bytes, signature_bytes_length, &signature, &signature_length);
if (r != L8W8JWT_SUCCESS)
@ -576,7 +573,7 @@ static int write_signature(chillbuff* stringbuilder, struct l8w8jwt_encoding_par
chillbuff_push_back(stringbuilder, signature, signature_length);
exit:
l8w8jwt_zero(key, L8W8JWT_MAX_KEY_SIZE);
mbedtls_platform_zeroize(key, L8W8JWT_MAX_KEY_SIZE);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
mbedtls_pk_free(&pk);
@ -592,7 +589,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) = (char*)malloc(stringbuilder->length + 1);
*(params->out) = l8w8jwt_malloc(stringbuilder->length + 1);
if (*(params->out) == NULL)
{
return L8W8JWT_OUT_OF_MEM;

View File

@ -31,7 +31,7 @@ extern "C" {
#include "claim.h"
#include "version.h"
#include "retcodes.h"
#include <time.h>
#include "timehelper.h"
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@ -95,7 +95,7 @@ enum l8w8jwt_validation_result {
L8W8JWT_TYP_FAILURE = (unsigned)1 << (unsigned)8
};
static void l8w8jwt_get_validation_result_desc(enum l8w8jwt_validation_result res, char* out_buffer, size_t buffer_size)
static void l8w8jwt_get_validation_result_desc(enum l8w8jwt_validation_result res, char* out_buffer, const size_t buffer_size)
{
#define JWT_OUTPUT_MSG(msg) snprintf(out_buffer, buffer_size, "%s", msg)
#define JWT_FLAG_STATUS(flag, msg) if(res & flag) { JWT_OUTPUT_MSG(msg); return; }
@ -109,7 +109,7 @@ static void l8w8jwt_get_validation_result_desc(enum l8w8jwt_validation_result re
JWT_FLAG_STATUS(L8W8JWT_ISS_FAILURE, "Issuer claim is invalid");
JWT_FLAG_STATUS(L8W8JWT_SUB_FAILURE, "Subject claim is invalid");
JWT_FLAG_STATUS(L8W8JWT_AUD_FAILURE, "Audience claim is invalid");
JWT_FLAG_STATUS(L8W8JWT_JTI_FAILURE, "JWT ID claim is invalid");
JWT_FLAG_STATUS(L8W8JWT_JTI_FAILURE, "JTI claim is invalid");
JWT_FLAG_STATUS(L8W8JWT_EXP_FAILURE, "Token has expired");
JWT_FLAG_STATUS(L8W8JWT_NBF_FAILURE, "Token is not yet valid");
JWT_FLAG_STATUS(L8W8JWT_IAT_FAILURE, "Token has not been issued yet");
@ -271,8 +271,11 @@ L8W8JWT_API int l8w8jwt_validate_decoding_params(struct l8w8jwt_decoding_params*
* Decode (and validate) a JWT using specific parameters. <p>
* The resulting {@link #l8w8jwt_validation_result} written into the passed "out_validation_result" pointer
* contains validation failure flags (see the {@link #l8w8jwt_validation_result} enum docs for more details). <p>
*
* This only happens if decoding also succeeded: if the token is malformed, nothing will be written into "out_validation_result". <p>
*
* If validation succeeds, the {@link #l8w8jwt_validation_result} receives the value 0 (enum value <code>L8W8JWT_VALID</code>). <p>
*
* The same applies to the "out_claims" argument: it is only allocated and written to if it (obviously) isn't <code>NULL</code> and if the decoding was also successful!
*
* @param params The parameters to use for decoding and validating the token.
@ -293,6 +296,63 @@ 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);
/**
* Decode (and validate) a JWT using specific parameters,
* but instead of writing the collection of claims contained in the payload into an array of <code>l8w8jwt_validation_result</code>
* like in the standard {@link l8w8jwt_decode} function,
* the raw JWT payload's JSON string is written into the {@link #out_payload_json} string, such that it can be parsed externally. <p>
*
* The resulting {@link #l8w8jwt_validation_result} written into the passed "out_validation_result" pointer
* contains validation failure flags (see the {@link #l8w8jwt_validation_result} enum docs for more details). <p>
*
* This only happens if decoding also succeeded: if the token is malformed, nothing will be written into "out_validation_result". <p>
*
* If validation succeeds, the {@link #l8w8jwt_validation_result} receives the value 0 (enum value <code>L8W8JWT_VALID</code>). <p>
*
* The same applies to the "out_payload_json" argument:
* it is only allocated and written to if it (obviously) isn't <code>NULL</code> and if the decoding procedure was also successful!
*
* @param params The parameters to use for decoding and validating the token.
*
* @param out_validation_result Where to write the validation result flags into (0 means success). In case of a decoding failure this is set to -1 (or <code>~L8W8JWT_VALID</code>)!
*
* @param out_header Where to write the decoded JWT header JSON string into.
*
* @param out_header_length Where to write the length of {@link out_header} into.
*
* @param out_payload Where to write the decoded JWT's payload JSON string into, so that it can be parsed externally instead of by l8w8jwt directly.
*
* @param out_payload_length Where to write the length of {@link out_payload} into.
*
* @param out_signature Where to write the JWT's signature into.
*
* @param out_signature_length Where to write the length of {@link out_signature} into.
*
* @return Return code as defined in retcodes.h (this is NOT the validation result that's written into the {@link out_validation_result} argument; the returned int describes whether the actual parsing/decoding part failed).
*/
L8W8JWT_API int l8w8jwt_decode_raw(struct l8w8jwt_decoding_params* params, enum l8w8jwt_validation_result* out_validation_result, char** out_header, size_t* out_header_length, char** out_payload, size_t* out_payload_length, uint8_t** out_signature, size_t* out_signature_length);
/**
* Decodes a JWT without validating anything: neither claims nor signature. Just raw decoding, no validation!
*
* @param params The parameters to use for decoding and validating the token.
*
* @param out_header Where to write the decoded JWT header JSON string into.
*
* @param out_header_length Where to write the length of {@link out_header} into.
*
* @param out_payload Where to write the decoded JWT's payload JSON string into, so that it can be parsed externally instead of by l8w8jwt directly.
*
* @param out_payload_length Where to write the length of {@link out_payload} into.
*
* @param out_signature Where to write the JWT's signature into.
*
* @param out_signature_length Where to write the length of {@link out_signature} into.
*
* @return Return code as defined in retcodes.h
*/
L8W8JWT_API int l8w8jwt_decode_raw_no_validation(struct l8w8jwt_decoding_params* params, char** out_header, size_t* out_header_length, char** out_payload, size_t* out_payload_length, uint8_t** out_signature, size_t* out_signature_length);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -31,7 +31,7 @@ extern "C" {
#include "claim.h"
#include "version.h"
#include "retcodes.h"
#include <time.h>
#include "timehelper.h"
#include <stddef.h>
#ifndef L8W8JWT_MAX_KEY_SIZE
@ -100,7 +100,7 @@ L8W8JWT_API struct l8w8jwt_encoding_params
* otherwise it will be set to whatever random value was in the memory where this variable resides.
* @see https://tools.ietf.org/html/rfc7519#section-4.1.4
*/
time_t exp;
l8w8jwt_time_t exp;
/**
* "Not before" time claim; specifies when this token should start being valid (in seconds since Unix epoch). <p>
@ -108,7 +108,7 @@ L8W8JWT_API struct l8w8jwt_encoding_params
* otherwise it will be set to whatever random value was in the memory where this variable resides.
* @see https://tools.ietf.org/html/rfc7519#section-4.1.5
*/
time_t nbf;
l8w8jwt_time_t nbf;
/**
* "Issued at" timestamp claim; specifies when this token was emitted (in seconds since Unix epoch). <p>
@ -116,7 +116,7 @@ L8W8JWT_API struct l8w8jwt_encoding_params
* otherwise it will be set to whatever random value was in the memory where this variable resides.
* @see https://tools.ietf.org/html/rfc7519#section-4.1.6
*/
time_t iat;
l8w8jwt_time_t iat;
/**
* [OPTIONAL] Array of additional claims to include in the JWT's header like for example "kid" or "cty"; pass <code>NULL</code> if you don't wish to add any! <p>

17
src/thirdparty/jwt/include/timehelper.h vendored Normal file
View File

@ -0,0 +1,17 @@
#include "version.h"
#include <time.h>
/**
* For now use the standard type for l8w8jwt_time_t.
* Support for adding alternate types could be added in the future, if needed.
*/
typedef time_t l8w8jwt_time_t;
/**
* Define alternate implementation of system `time` API
*/
#if L8W8JWT_PLATFORM_TIME_ALT
extern l8w8jwt_time_t (*l8w8jwt_time)(l8w8jwt_time_t *time);
#else
#define l8w8jwt_time time
#endif

View File

@ -27,6 +27,7 @@
extern "C" {
#endif
#include <stdlib.h>
#include <stddef.h>
#include "version.h"
@ -51,6 +52,48 @@ L8W8JWT_API int l8w8jwt_hexstr2bin(const char* hexstr, const size_t hexstr_lengt
*/
L8W8JWT_API int l8w8jwt_strncmpic(const char* str1, const char* str2, size_t n);
#ifndef L8W8JWT_PLATFORM_MALLOC_ALT
/**
* Set this pre-processor definition to \c 1 if you need to
* provide custom implementation of malloc
*/
#define L8W8JWT_PLATFORM_MALLOC_ALT 0
#endif
#ifndef L8W8JWT_PLATFORM_CALLOC_ALT
/**
* Set this pre-processor definition to \c 1 if you need to
* provide custom implementation of calloc
*/
#define L8W8JWT_PLATFORM_CALLOC_ALT 0
#endif
#ifndef L8W8JWT_PLATFORM_REALLOC_ALT
/**
* Set this pre-processor definition to \c 1 if you need to
* provide custom implementation of realloc
*/
#define L8W8JWT_PLATFORM_REALLOC_ALT 0
#endif
#if L8W8JWT_PLATFORM_MALLOC_ALT
extern void *(*l8w8jwt_malloc) (size_t size);
#else
#define l8w8jwt_malloc malloc
#endif
#if L8W8JWT_PLATFORM_CALLOC_ALT
extern void *(*l8w8jwt_calloc) (size_t nmemb, size_t size);
#else
#define l8w8jwt_calloc calloc
#endif
#if L8W8JWT_PLATFORM_REALLOC_ALT
extern void *(*l8w8jwt_realloc) (void *ptr, size_t size);
#else
#define l8w8jwt_realloc realloc
#endif
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -30,12 +30,12 @@ extern "C" {
/**
* Current l8w8jwt version number.
*/
#define L8W8JWT_VERSION 220
#define L8W8JWT_VERSION 240
/**
* Current l8w8jwt version number (as a human-readable string).
*/
#define L8W8JWT_VERSION_STR "2.2.0"
#define L8W8JWT_VERSION_STR "2.4.0"
#if defined(_WIN32) && defined(L8W8JWT_DLL)
#ifdef L8W8JWT_BUILD_DLL
@ -55,19 +55,20 @@ extern "C" {
#define L8W8JWT_SMALL_STACK 0
#endif
#ifndef L8W8JWT_PLATFORM_TIME_ALT
/**
* Set this pre-processor definition to \c 1 if you need to
* provide custom implementation of system time API.
*/
#define L8W8JWT_PLATFORM_TIME_ALT 0
#endif
/**
* Free memory that was allocated by L8W8JWT.
* @param mem The memory to free.
*/
L8W8JWT_API void l8w8jwt_free(void* mem);
/**
* Zero memory securely.
* @param mem The memory to zero.
* @param len The length to zero.
*/
L8W8JWT_API void l8w8jwt_zero(void* buf, size_t len);
/**
* Gets the l8w8jwt version number as an integer.
* @return Version number (e.g. "2.1.4" => 214)

View File

@ -42,7 +42,7 @@ int l8w8jwt_hexstr2bin(const char* hexstr, const size_t hexstr_length, unsigned
return 3;
}
for (size_t i = 0, ii = 0; ii < final_length; i += 2, ii++)
for (size_t i = 0, ii = 0; ii < final_length; i += 2, ++ii)
{
output[ii] = (hexstr[i] % 32 + 9) % 25 * 16 + (hexstr[i + 1] % 32 + 9) % 25;
}

View File

@ -18,10 +18,6 @@
#include <stdlib.h>
#include <string.h>
#if defined(_WIN32)
#include <windows.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -31,31 +27,6 @@ void l8w8jwt_free(void* mem)
free(mem);
}
void l8w8jwt_zero(void* buf, size_t len)
{
if (len > 0)
{
#if defined(MBEDTLS_PLATFORM_HAS_EXPLICIT_BZERO)
explicit_bzero(buf, len);
#if defined(HAVE_MEMORY_SANITIZER)
/* You'd think that Msan would recognize explicit_bzero() as
* equivalent to bzero(), but it actually doesn't on several
* platforms, including Linux (Ubuntu 20.04).
* https://github.com/google/sanitizers/issues/1507
* https://github.com/openssh/openssh-portable/commit/74433a19bb6f4cef607680fa4d1d7d81ca3826aa
*/
__msan_unpoison(buf, len);
#endif
#elif defined(__STDC_LIB_EXT1__)
memset_s(buf, len, 0, len);
#elif defined(_WIN32)
RtlSecureZeroMemory(buf, len);
#else
memset_func(buf, 0, len);
#endif
}
}
int l8w8jwt_get_version_number()
{
return (int)L8W8JWT_VERSION;