base64-test.c 4.11 KB
Newer Older
Niels Möller's avatar
Niels Möller committed
1
2
#include "testutils.h"
#include "base64.h"
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "knuth-lfib.h"

static void
test_fuzz_once(struct base64_encode_ctx *encode,
	       struct base64_decode_ctx *decode,
	       size_t size, const uint8_t *input)
{
  size_t base64_len = BASE64_ENCODE_RAW_LENGTH (size);
  size_t out_len;
  uint8_t *base64 = xalloc (base64_len + 2);
  uint8_t *decoded = xalloc (size + 2);

  *base64++ = 0x12;
  base64[base64_len] = 0x34;

  *decoded++ = 0x56;
  decoded[size] = 0x78;

  out_len = base64_encode_update(encode, base64, size, input);
  ASSERT (out_len <= base64_len);
  out_len += base64_encode_final(encode, base64 + out_len);
  ASSERT (out_len == base64_len);
  ASSERT (base64[-1] == 0x12);
  ASSERT (base64[base64_len] == 0x34);

  ASSERT(base64_decode_update(decode, &out_len, decoded,
			      base64_len, base64));
  ASSERT(base64_decode_final(decode));
  ASSERT (out_len == size);
  ASSERT (decoded[-1] == 0x56);
  ASSERT (decoded[size] == 0x78);
  
  ASSERT(MEMEQ(size, input, decoded));
  free (base64 - 1);
  free (decoded - 1);
}

static void
test_fuzz(void)
{
  /* Fuzz a round-trip through both encoder and decoder */
  struct base64_encode_ctx encode;
  struct base64_decode_ctx decode;
  unsigned i;
  size_t length;
  uint8_t input[1024];

  struct knuth_lfib_ctx rand_ctx;
  knuth_lfib_init(&rand_ctx, 39854);

  for (i = 0; i < 10000; i++)
    {
      length = i % sizeof(input);
      /* length could be 0, which is fine we need to test that case too */
      knuth_lfib_random(&rand_ctx, length, input);

      base64_encode_init(&encode);
      base64_decode_init(&decode);
      test_fuzz_once(&encode, &decode, length, input);
62
63
64
65

      base64url_encode_init(&encode);
      base64url_decode_init(&decode);
      test_fuzz_once(&encode, &decode, length, input);
66
67
    }
}
Niels Möller's avatar
Niels Möller committed
68

69
void
Niels Möller's avatar
Niels Möller committed
70
71
test_main(void)
{
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  ASSERT(BASE64_ENCODE_LENGTH(0) == 0);   /* At most   4 bits */
  ASSERT(BASE64_ENCODE_LENGTH(1) == 2);   /* At most  12 bits */
  ASSERT(BASE64_ENCODE_LENGTH(2) == 3);   /* At most  20 bits */
  ASSERT(BASE64_ENCODE_LENGTH(3) == 4);   /* At most  28 bits */
  ASSERT(BASE64_ENCODE_LENGTH(4) == 6);   /* At most  36 bits */
  ASSERT(BASE64_ENCODE_LENGTH(5) == 7);   /* At most  44 bits */
  ASSERT(BASE64_ENCODE_LENGTH(12) == 16); /* At most 100 bits */
  ASSERT(BASE64_ENCODE_LENGTH(13) == 18); /* At most 108 bits */

  ASSERT(BASE64_DECODE_LENGTH(0) == 0); /* At most  6 bits */
  ASSERT(BASE64_DECODE_LENGTH(1) == 1); /* At most 12 bits */
  ASSERT(BASE64_DECODE_LENGTH(2) == 2); /* At most 18 bits */
  ASSERT(BASE64_DECODE_LENGTH(3) == 3); /* At most 24 bits */
  ASSERT(BASE64_DECODE_LENGTH(4) == 3); /* At most 30 bits */
  
87
88
89
90
91
92
93
94
95
  test_armor(&nettle_base64, LDATA(""), "");
  test_armor(&nettle_base64, LDATA("H"), "SA==");
  test_armor(&nettle_base64, LDATA("He"), "SGU=");
  test_armor(&nettle_base64, LDATA("Hel"), "SGVs");
  test_armor(&nettle_base64, LDATA("Hell"), "SGVsbA==");
  test_armor(&nettle_base64, LDATA("Hello"), "SGVsbG8=");
  test_armor(&nettle_base64, LDATA("Hello\0"), "SGVsbG8A");
  test_armor(&nettle_base64, LDATA("Hello?>>>"), "SGVsbG8/Pj4+");
  test_armor(&nettle_base64, LDATA("\xff\xff\xff\xff"), "/////w==");
Niels Möller's avatar
Niels Möller committed
96

97
98
99
100
101
102
103
104
105
  test_armor(&nettle_base64url, LDATA(""), "");
  test_armor(&nettle_base64url, LDATA("H"), "SA==");
  test_armor(&nettle_base64url, LDATA("He"), "SGU=");
  test_armor(&nettle_base64url, LDATA("Hel"), "SGVs");
  test_armor(&nettle_base64url, LDATA("Hell"), "SGVsbA==");
  test_armor(&nettle_base64url, LDATA("Hello"), "SGVsbG8=");
  test_armor(&nettle_base64url, LDATA("Hello\0"), "SGVsbG8A");
  test_armor(&nettle_base64url, LDATA("Hello?>>>"), "SGVsbG8_Pj4-");
  test_armor(&nettle_base64url, LDATA("\xff\xff\xff\xff"), "_____w==");
106

107
108
109
  {
    /* Test overlapping areas */
    uint8_t buffer[] = "Helloxxxx";
110
    struct base64_decode_ctx ctx;
111
    size_t dst_length;
112
    
113
114
    ASSERT(BASE64_ENCODE_RAW_LENGTH(5) == 8);
    base64_encode_raw(buffer, 5, buffer);
115
116
117
    ASSERT(MEMEQ(9, buffer, "SGVsbG8=x"));

    base64_decode_init(&ctx);
Niels Möller's avatar
Niels Möller committed
118
    dst_length = 0; /* Output parameter only. */
119
120
    ASSERT(base64_decode_update(&ctx, &dst_length, buffer, 8, buffer));
    ASSERT(dst_length == 5);
121
    
122
123
    ASSERT(MEMEQ(9, buffer, "HelloG8=x"));
  }
124
  test_fuzz ();
Niels Möller's avatar
Niels Möller committed
125
}