re-work strict/relaxed base64 decoding implementation
Instead of one API function with an option parameter, provide two API functions. Instead of defaulting to strict decoding, default to relaxed decoding.
This commit is contained in:
parent
53359ccfc6
commit
c1dd1cbe30
@ -476,11 +476,6 @@
|
||||
#define LTC_PKCS_1
|
||||
#endif
|
||||
|
||||
#if (defined(LTC_BASE64) || defined(LTC_BASE64_URL)) && !defined(LTC_BASE64_STRICT)
|
||||
/* By default we're doing strict decoding now */
|
||||
#define LTC_BASE64_STRICT 1
|
||||
#endif
|
||||
|
||||
#if defined(TFM_DESC) && defined(LTC_RSA_BLINDING)
|
||||
#warning RSA blinding currently not supported in combination with TFM
|
||||
#undef LTC_RSA_BLINDING
|
||||
|
@ -3,18 +3,20 @@
|
||||
int base64_encode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
#define base64_decode(i, il, o, ol) base64_decode_ex(i, il, o, ol, LTC_BASE64_STRICT)
|
||||
int base64_decode_ex(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen, int strict);
|
||||
int base64_decode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int base64_strict_decode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_BASE64_URL
|
||||
int base64url_encode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
#define base64url_decode(i, il, o, ol) base64url_decode_ex(i, il, o, ol, LTC_BASE64_STRICT)
|
||||
int base64url_decode_ex(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen, int strict);
|
||||
int base64url_decode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
int base64url_strict_decode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
#endif
|
||||
|
||||
/* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */
|
||||
|
@ -71,9 +71,14 @@ static const unsigned char map_base64url[256] = {
|
||||
255, 255, 255, 255 };
|
||||
#endif /* LTC_BASE64_URL */
|
||||
|
||||
enum {
|
||||
relaxed = 0,
|
||||
strict = 1
|
||||
};
|
||||
|
||||
static int _base64_decode_internal(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *map, int strict)
|
||||
const unsigned char *map, int is_strict)
|
||||
{
|
||||
unsigned long t, x, y, z;
|
||||
unsigned char c;
|
||||
@ -87,7 +92,7 @@ static int _base64_decode_internal(const unsigned char *in, unsigned long inlen
|
||||
for (x = y = z = t = 0; x < inlen; x++) {
|
||||
c = map[in[x]&0xFF];
|
||||
if (c == 255) {
|
||||
if (strict)
|
||||
if (is_strict)
|
||||
return CRYPT_INVALID_PACKET;
|
||||
else
|
||||
continue;
|
||||
@ -117,7 +122,7 @@ static int _base64_decode_internal(const unsigned char *in, unsigned long inlen
|
||||
}
|
||||
}
|
||||
if (y != 0) {
|
||||
if (y == 1 || map != map_base64url || strict == 1) return CRYPT_INVALID_PACKET;
|
||||
if (y == 1 || map != map_base64url || is_strict == 1) return CRYPT_INVALID_PACKET;
|
||||
t = t << (6 * (4 - y));
|
||||
if (z + y - 1 > *outlen) return CRYPT_BUFFER_OVERFLOW;
|
||||
if (y >= 2) out[z++] = (unsigned char) ((t >> 16) & 255);
|
||||
@ -129,18 +134,31 @@ static int _base64_decode_internal(const unsigned char *in, unsigned long inlen
|
||||
|
||||
#if defined(LTC_BASE64)
|
||||
/**
|
||||
base64 decode a block of memory
|
||||
Relaxed base64 decode a block of memory
|
||||
@param in The base64 data to decode
|
||||
@param inlen The length of the base64 data
|
||||
@param out [out] The destination of the binary decoded data
|
||||
@param outlen [in/out] The max size and resulting size of the decoded data
|
||||
@param strict Strict[1] or relaxed[0] decoding of the input
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int base64_decode_ex(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int strict)
|
||||
int base64_decode(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
return _base64_decode_internal(in, inlen, out, outlen, map_base64, strict);
|
||||
return _base64_decode_internal(in, inlen, out, outlen, map_base64, relaxed);
|
||||
}
|
||||
|
||||
/**
|
||||
Strict base64 decode a block of memory
|
||||
@param in The base64 data to decode
|
||||
@param inlen The length of the base64 data
|
||||
@param out [out] The destination of the binary decoded data
|
||||
@param outlen [in/out] The max size and resulting size of the decoded data
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int base64_strict_decode(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
return _base64_decode_internal(in, inlen, out, outlen, map_base64, strict);
|
||||
}
|
||||
#endif /* LTC_BASE64 */
|
||||
|
||||
@ -151,11 +169,16 @@ int base64_decode_ex(const unsigned char *in, unsigned long inlen,
|
||||
@param inlen The length of the base64 data
|
||||
@param out [out] The destination of the binary decoded data
|
||||
@param outlen [in/out] The max size and resulting size of the decoded data
|
||||
@param strict Strict[1] or relaxed[0] decoding of the input
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int base64url_decode_ex(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int strict)
|
||||
int base64url_decode(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
return _base64_decode_internal(in, inlen, out, outlen, map_base64url, relaxed);
|
||||
}
|
||||
|
||||
int base64url_strict_decode(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
return _base64_decode_internal(in, inlen, out, outlen, map_base64url, strict);
|
||||
}
|
||||
|
@ -337,9 +337,6 @@ const char *crypt_build_settings =
|
||||
#if defined(LTC_BASE64_URL)
|
||||
" BASE64-URL-SAFE "
|
||||
#endif
|
||||
#if defined(LTC_BASE64) || defined(LTC_BASE64_URL)
|
||||
" "NAME_VALUE(LTC_BASE64_STRICT)" "
|
||||
#endif
|
||||
#if defined(LTC_CRC32)
|
||||
" CRC32 "
|
||||
#endif
|
||||
|
@ -89,10 +89,6 @@ static const crypt_constant _crypt_constants[] = {
|
||||
{"LTC_CTR_MODE", 0},
|
||||
#endif
|
||||
|
||||
#if defined(LTC_BASE64) || defined(LTC_BASE64_URL)
|
||||
_C_STRINGIFY(LTC_BASE64_STRICT),
|
||||
#endif
|
||||
|
||||
_C_STRINGIFY(MAXBLOCKSIZE),
|
||||
_C_STRINGIFY(TAB_SIZE),
|
||||
_C_STRINGIFY(ARGTYPE),
|
||||
|
@ -34,7 +34,7 @@ int base64_test(void)
|
||||
|
||||
const struct {
|
||||
const char* s;
|
||||
int mode;
|
||||
int is_strict;
|
||||
} url_cases[] = {
|
||||
{"vuiSPKIl8PiR5O-rC4z9_xTQKZ0", 0},
|
||||
{"vuiSPKIl8PiR5O-rC4z9_xTQKZ0=", 1},
|
||||
@ -63,7 +63,10 @@ int base64_test(void)
|
||||
for (x = 0; x < sizeof(url_cases)/sizeof(url_cases[0]); ++x) {
|
||||
slen1 = strlen(url_cases[x].s);
|
||||
l1 = sizeof(out);
|
||||
DO(base64url_decode_ex((unsigned char*)url_cases[x].s, slen1, out, &l1, url_cases[x].mode));
|
||||
if(url_cases[x].is_strict)
|
||||
DO(base64url_strict_decode((unsigned char*)url_cases[x].s, slen1, out, &l1));
|
||||
else
|
||||
DO(base64url_decode((unsigned char*)url_cases[x].s, slen1, out, &l1));
|
||||
if (l1 != strlen(special_case) || memcmp(out, special_case, l1)) {
|
||||
fprintf(stderr, "\nbase64url failed case %lu: %s", x, url_cases[x].s);
|
||||
print_hex("\nbase64url should", special_case, strlen(special_case));
|
||||
@ -91,16 +94,16 @@ int base64_test(void)
|
||||
out[10] = '\0';
|
||||
l1++;
|
||||
l2 = sizeof(tmp);
|
||||
DO(base64_decode_ex(out, l1, tmp, &l2, 0));
|
||||
DO(base64_decode(out, l1, tmp, &l2));
|
||||
if (l2 != x || memcmp(tmp, in, x)) {
|
||||
fprintf(stderr, "loose base64 decoding failed %lu %lu %lu", x, l1, l2);
|
||||
fprintf(stderr, "relaxed base64 decoding failed %lu %lu %lu", x, l1, l2);
|
||||
print_hex("is ", tmp, l2);
|
||||
print_hex("should", in, x);
|
||||
print_hex("input ", out, l1);
|
||||
return 1;
|
||||
}
|
||||
l2 = sizeof(tmp);
|
||||
DO(base64_decode_ex(out, l1, tmp, &l2, 1) == CRYPT_INVALID_PACKET ? CRYPT_OK : CRYPT_INVALID_PACKET);
|
||||
DO(base64_strict_decode(out, l1, tmp, &l2) == CRYPT_INVALID_PACKET ? CRYPT_OK : CRYPT_INVALID_PACKET);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -392,7 +392,7 @@ static void der_cacert_test(void)
|
||||
|
||||
ltc_asn1_list *decoded_list, *l, *l1, *l2;
|
||||
|
||||
DO(base64_decode_ex(_der_tests_cacert_root_cert, sizeof(_der_tests_cacert_root_cert), buf, &len1, 0));
|
||||
DO(base64_decode(_der_tests_cacert_root_cert, sizeof(_der_tests_cacert_root_cert), buf, &len1));
|
||||
len2 = len1;
|
||||
DO(der_decode_sequence_flexi(buf, &len2, &decoded_list));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user