1 /* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "test-lib.h"
4 #include "str.h"
5 #include "base32.h"
6 
7 
test_base32_encode(void)8 static void test_base32_encode(void)
9 {
10 	static const char *input[] = {
11 		"toedeledokie!!",
12 		"bye bye world",
13 		"hoeveel onzin kun je testen?????",
14 		"c'est pas vrai! ",
15 		"dit is het einde van deze test"
16 	};
17 	static const char *output[] = {
18 		"ORXWKZDFNRSWI33LNFSSCII=",
19 		"MJ4WKIDCPFSSA53POJWGI===",
20 		"NBXWK5TFMVWCA33OPJUW4IDLOVXCA2TFEB2GK43UMVXD6PZ7H47Q====",
21 		"MMTWK43UEBYGC4ZAOZZGC2JBEA======",
22 		"MRUXIIDJOMQGQZLUEBSWS3TEMUQHMYLOEBSGK6TFEB2GK43U"
23 	};
24 	string_t *str;
25 	unsigned int i;
26 
27 	test_begin("base32_encode() with padding");
28 	str = t_str_new(256);
29 	for (i = 0; i < N_ELEMENTS(input); i++) {
30 		str_truncate(str, 0);
31 		base32_encode(TRUE, input[i], strlen(input[i]), str);
32 		test_assert(strcmp(output[i], str_c(str)) == 0);
33 	}
34 	test_end();
35 
36 	test_begin("base32_encode() no padding");
37 	str = t_str_new(256);
38 	for (i = 0; i < N_ELEMENTS(input); i++) {
39 		const char *p = strchr(output[i], '=');
40 		size_t len;
41 
42 		if (p == NULL)
43 			len = strlen(output[i]);
44 		else
45 			len = (size_t)(p - output[i]);
46 		str_truncate(str, 0);
47 		base32_encode(FALSE, input[i], strlen(input[i]), str);
48 		test_assert(strncmp(output[i], str_c(str), len) == 0);
49 	}
50 	test_end();
51 }
52 
test_base32hex_encode(void)53 static void test_base32hex_encode(void)
54 {
55 	static const char *input[] = {
56 		"toedeledokie!!",
57 		"bye bye world",
58 		"hoeveel onzin kun je testen?????",
59 		"c'est pas vrai! ",
60 		"dit is het einde van deze test"
61 	};
62 	static const char *output[] = {
63 		"EHNMAP35DHIM8RRBD5II288=",
64 		"C9SMA832F5II0TRFE9M68===",
65 		"D1NMATJ5CLM20RREF9KMS83BELN20QJ541Q6ASRKCLN3UFPV7SVG====",
66 		"CCJMASRK41O62SP0EPP62Q9140======",
67 		"CHKN8839ECG6GPBK41IMIRJ4CKG7COBE41I6AUJ541Q6ASRK"
68 	};
69 	string_t *str;
70 	unsigned int i;
71 
72 	test_begin("base32hex_encode() with padding");
73 	str = t_str_new(256);
74 	for (i = 0; i < N_ELEMENTS(input); i++) {
75 		str_truncate(str, 0);
76 		base32hex_encode(TRUE, input[i], strlen(input[i]), str);
77 		test_assert(strcmp(output[i], str_c(str)) == 0);
78 	}
79 	test_end();
80 
81 	test_begin("base32hex_encode() no padding");
82 	str = t_str_new(256);
83 	for (i = 0; i < N_ELEMENTS(input); i++) {
84 		const char *p = strchr(output[i], '=');
85 		size_t len;
86 
87 		if (p == NULL)
88 			len = strlen(output[i]);
89 		else
90 			len = (size_t)(p - output[i]);
91 		str_truncate(str, 0);
92 		base32hex_encode(FALSE, input[i], strlen(input[i]), str);
93 		test_assert(strncmp(output[i], str_c(str), len) == 0);
94 	}
95 	test_end();
96 
97 }
98 
99 struct test_base32_decode_output {
100 	const char *text;
101 	int ret;
102 	unsigned int src_pos;
103 };
104 
test_base32_decode(void)105 static void test_base32_decode(void)
106 {
107 	static const char *input[] = {
108 		"ORXWKZDFNRSWI33LNFSSCII=",
109 		"MJ4WKIDCPFSSA53POJWGI===",
110 		"NBXWK5TFMVWCA33OPJUW4IDLOVXCA2TFEB2GK43UMVXD6PZ7H47Q====",
111 		"MMTWK43UEBYGC4ZAOZZGC2JBEA======",
112 		"MRUXIIDJOMQGQZLUEBSWS3TEMUQHMYLOEBSGK6TFEB2GK43U"
113 	};
114 	static const struct test_base32_decode_output output[] = {
115 		{ "toedeledokie!!", 0, 24 },
116 		{ "bye bye world", 0, 24 },
117 		{ "hoeveel onzin kun je testen?????", 0, 56 },
118 		{ "c'est pas vrai! ", 0, 32 },
119 		{ "dit is het einde van deze test", 1, 48 },
120 	};
121 	string_t *str;
122 	unsigned int i;
123 	size_t src_pos;
124 	int ret;
125 
126 	test_begin("base32_decode()");
127 	str = t_str_new(256);
128 	for (i = 0; i < N_ELEMENTS(input); i++) {
129 		str_truncate(str, 0);
130 
131 		src_pos = 0;
132 		ret = base32_decode(input[i], strlen(input[i]), &src_pos, str);
133 
134 		test_assert(output[i].ret == ret &&
135 			    strcmp(output[i].text, str_c(str)) == 0 &&
136 			    (src_pos == output[i].src_pos ||
137 			     (output[i].src_pos == UINT_MAX &&
138 			      src_pos == strlen(input[i]))));
139 	}
140 	test_end();
141 }
142 
test_base32_random(void)143 static void test_base32_random(void)
144 {
145 	string_t *str, *dest;
146 	unsigned char buf[10];
147 	unsigned int i, j, max;
148 
149 	str = t_str_new(256);
150 	dest = t_str_new(256);
151 
152 	test_begin("padded base32 encode/decode with random input");
153 	for (i = 0; i < 1000; i++) {
154 		max = i_rand_limit(sizeof(buf));
155 		for (j = 0; j < max; j++)
156 			buf[j] = i_rand_uchar();
157 
158 		str_truncate(str, 0);
159 		str_truncate(dest, 0);
160 		base32_encode(TRUE, buf, max, str);
161 		test_assert(base32_decode(str_data(str), str_len(str), NULL, dest) >= 0);
162 		test_assert(str_len(dest) == max &&
163 			    memcmp(buf, str_data(dest), max) == 0);
164 	}
165 	test_end();
166 
167 	test_begin("padded base32hex encode/decode with random input");
168 	for (i = 0; i < 1000; i++) {
169 		max = i_rand_limit(sizeof(buf));
170 		for (j = 0; j < max; j++)
171 			buf[j] = i_rand_uchar();
172 
173 		str_truncate(str, 0);
174 		str_truncate(dest, 0);
175 		base32hex_encode(TRUE, buf, max, str);
176 		test_assert(base32hex_decode(str_data(str), str_len(str), NULL, dest) >= 0);
177 		test_assert(str_len(dest) == max &&
178 			    memcmp(buf, str_data(dest), max) == 0);
179 	}
180 	test_end();
181 }
182 
test_base32(void)183 void test_base32(void)
184 {
185 	test_base32_encode();
186 	test_base32hex_encode();
187 	test_base32_decode();
188 	test_base32_random();
189 }
190