30 #define BASE64_TABLE_MAX 122
34 static const int b64table[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
35 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
36 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
38 -1, -1, -1, 62, -1, -1, -1, 63, 52, 53,
39 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
40 -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
41 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
42 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
43 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
44 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
45 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
55 static inline int GetBase64Value(uint8_t c)
61 val = b64table[(int) c];
76 if (GetBase64Value(encoded_byte) < 0 && encoded_byte !=
'=') {
92 ascii[0] = (uint8_t) (b64[0] << 2) | (b64[1] >> 4);
93 ascii[1] = (uint8_t) (b64[1] << 4) | (b64[2] >> 2);
94 ascii[2] = (uint8_t) (b64[2] << 6) | (b64[3]);
116 static inline Base64Ecode DecodeBase64RFC2045(uint8_t *dest, uint32_t dest_size,
const uint8_t *
src,
117 uint32_t
len, uint32_t *consumed_bytes, uint32_t *decoded_bytes)
120 uint32_t
padding = 0, bbidx = 0, non_b64_chars = 0;
121 uint8_t *dptr = dest;
124 for (uint32_t i = 0; i <
len; i++) {
125 val = GetBase64Value(
src[i]);
136 b64[bbidx++] = val > 0 ? (uint8_t)val : 0;
145 DecodeBase64Block(dptr, b64);
146 dptr += numDecoded_blk;
147 *decoded_bytes += numDecoded_blk;
151 *consumed_bytes +=
B64_BLOCK + non_b64_chars;
153 memset(&b64, 0,
sizeof(b64));
186 static inline Base64Ecode DecodeBase64RFC4648(uint8_t *dest, uint32_t dest_size,
const uint8_t *
src,
187 uint32_t
len, uint32_t *consumed_bytes, uint32_t *decoded_bytes,
bool strict)
190 uint32_t
padding = 0, bbidx = 0;
191 uint8_t *dptr = dest;
194 for (uint32_t i = 0; i <
len; i++) {
195 val = GetBase64Value(
src[i]);
207 b64[bbidx++] = (val > 0 ? (uint8_t)val : 0);
217 DecodeBase64Block(dptr, b64);
218 dptr += numDecoded_blk;
219 *decoded_bytes += numDecoded_blk;
224 memset(&b64, 0,
sizeof(b64));
251 DecodeBase64Block(dptr, b64);
252 *decoded_bytes += numDecoded_blk;
254 *consumed_bytes += bbidx;
256 if (*decoded_bytes == 0)
277 uint32_t *consumed_bytes, uint32_t *decoded_bytes, DetectBase64Mode mode)
282 case Base64ModeRFC4648:
283 ret = DecodeBase64RFC4648(
284 dest, dest_size,
src,
len, consumed_bytes, decoded_bytes,
false);
286 case Base64ModeRFC2045:
287 ret = DecodeBase64RFC2045(dest, dest_size,
src,
len, consumed_bytes, decoded_bytes);
289 case Base64ModeStrict:
290 ret = DecodeBase64RFC4648(
291 dest, dest_size,
src,
len, consumed_bytes, decoded_bytes,
true);
301 #define TEST_RFC2045(src, fin_str, dest_size, exp_decoded, exp_consumed, ecode) \
303 uint32_t consumed_bytes = 0, num_decoded = 0; \
304 uint8_t dst[dest_size]; \
305 Base64Ecode code = DecodeBase64(dst, dest_size, (const uint8_t *)src, strlen(src), \
306 &consumed_bytes, &num_decoded, Base64ModeRFC2045); \
307 FAIL_IF(code != ecode); \
308 FAIL_IF(memcmp(dst, fin_str, strlen(fin_str)) != 0); \
309 FAIL_IF(num_decoded != exp_decoded); \
310 FAIL_IF(consumed_bytes != exp_consumed); \
313 #define TEST_RFC4648(src, fin_str, dest_size, exp_decoded, exp_consumed, ecode) \
315 uint32_t consumed_bytes = 0, num_decoded = 0; \
316 uint8_t dst[dest_size]; \
317 Base64Ecode code = DecodeBase64(dst, dest_size, (const uint8_t *)src, strlen(src), \
318 &consumed_bytes, &num_decoded, Base64ModeRFC4648); \
319 FAIL_IF(code != ecode); \
320 FAIL_IF(memcmp(dst, fin_str, strlen(fin_str)) != 0); \
321 FAIL_IF(num_decoded != exp_decoded); \
322 FAIL_IF(consumed_bytes != exp_consumed); \
325 static int B64DecodeCompleteString(
void)
330 const char *
src =
"SGVsbG8gV29ybGR6";
331 const char *fin_str =
"Hello Worldz";
336 static int B64DecodeInCompleteString(
void)
341 const char *
src =
"SGVsbG8gV29ybGR";
342 const char *fin_str =
"Hello Wor";
347 static int B64DecodeCompleteStringWSp(
void)
353 const char *
src =
"SGVs bG8 gV29y bGQ=";
354 const char *fin_str =
"Hello World";
359 static int B64DecodeInCompleteStringWSp(
void)
366 const char *
src =
"SGVs bG8 gV29y bGQ";
367 const char *fin_str =
"Hello Wor";
372 static int B64DecodeStringBiggerThanBuffer(
void)
378 const char *
src =
"SGVs bG8 gV29y bGQ=";
379 const char *fin_str =
"Hello Wor";
384 static int B64DecodeStringEndingSpaces(
void)
386 const char *
src =
"0YPhA d H";
387 uint32_t consumed_bytes = 0, num_decoded = 0;
390 &num_decoded, Base64ModeRFC2045);
397 static int B64TestVectorsRFC2045(
void)
399 const char *src1 =
"";
400 const char *fin_str1 =
"";
402 const char *src2 =
"Zg==";
403 const char *fin_str2 =
"f";
405 const char *src3 =
"Zm8=";
406 const char *fin_str3 =
"fo";
408 const char *src4 =
"Zm9v";
409 const char *fin_str4 =
"foo";
411 const char *src5 =
"Zm9vYg==";
412 const char *fin_str5 =
"foob";
414 const char *src6 =
"Zm9vYmE=";
415 const char *fin_str6 =
"fooba";
417 const char *src7 =
"Zm9vYmFy";
418 const char *fin_str7 =
"foobar";
420 const char *src8 =
"Zm 9v Ym Fy";
421 const char *fin_str8 =
"foobar";
423 const char *src9 =
"Zm$9vYm.Fy";
424 const char *fin_str9 =
"foobar";
426 const char *src10 =
"Y21Wd2IzSjBaVzFoYVd4bWNtRjFaRUJoZEc4dVoyOTJMbUYxOmpqcHh4b3Rhb2w%5";
427 const char *fin_str10 =
"cmVwb3J0ZW1haWxmcmF1ZEBhdG8uZ292LmF1:jjpxxotaol9";
429 const char *src11 =
"Zm 9v Ym Fy 7fy";
430 const char *fin_str11 =
"foobar";
446 static int B64TestVectorsRFC4648(
void)
448 const char *src1 =
"";
449 const char *fin_str1 =
"";
451 const char *src2 =
"Zg==";
452 const char *fin_str2 =
"f";
454 const char *src3 =
"Zm8=";
455 const char *fin_str3 =
"fo";
457 const char *src4 =
"Zm9v";
458 const char *fin_str4 =
"foo";
460 const char *src5 =
"Zm9vYg==";
461 const char *fin_str5 =
"foob";
463 const char *src6 =
"Zm9vYmE=";
464 const char *fin_str6 =
"fooba";
466 const char *src7 =
"Zm9vYmFy";
467 const char *fin_str7 =
"foobar";
469 const char *src8 =
"Zm 9v Ym Fy";
470 const char *fin_str8 =
"f";
472 const char *src9 =
"Zm$9vYm.Fy";
473 const char *fin_str9 =
"f";
475 const char *src10 =
"Y21Wd2IzSjBaVzFoYVd4bWNtRjFaRUJoZEc4dVoyOTJMbUYxOmpqcHh4b3Rhb2w%3D";
476 const char *fin_str10 =
"cmVwb3J0ZW1haWxmcmF1ZEBhdG8uZ292LmF1:jjpxxotaol";
478 const char *src11 =
"Zm9vYg==";
479 const char *fin_str11 =
"foo";
497 UtRegisterTest(
"B64DecodeCompleteStringWSp", B64DecodeCompleteStringWSp);
498 UtRegisterTest(
"B64DecodeInCompleteStringWSp", B64DecodeInCompleteStringWSp);
499 UtRegisterTest(
"B64DecodeCompleteString", B64DecodeCompleteString);
500 UtRegisterTest(
"B64DecodeInCompleteString", B64DecodeInCompleteString);
501 UtRegisterTest(
"B64DecodeStringBiggerThanBuffer", B64DecodeStringBiggerThanBuffer);
502 UtRegisterTest(
"B64DecodeStringEndingSpaces", B64DecodeStringEndingSpaces);