summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2014-05-03 15:07:46 +0000
committerjsing <>2014-05-03 15:07:46 +0000
commitc068ce427d4525ce31189b2feb96a7ef18568758 (patch)
tree35196a9a223fc61156e97a24a8c23c377cbbef1e
parentd59b1705859c0c622e7eb86fafb20cf0097c6d82 (diff)
downloadopenbsd-c068ce427d4525ce31189b2feb96a7ef18568758.tar.gz
openbsd-c068ce427d4525ce31189b2feb96a7ef18568758.tar.bz2
openbsd-c068ce427d4525ce31189b2feb96a7ef18568758.zip
Initial version of a base64 regress.
-rw-r--r--src/regress/lib/libcrypto/Makefile3
-rw-r--r--src/regress/lib/libcrypto/base64/Makefile7
-rw-r--r--src/regress/lib/libcrypto/base64/base64test.c373
3 files changed, 382 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/Makefile b/src/regress/lib/libcrypto/Makefile
index 327eb5b12d..345077c20c 100644
--- a/src/regress/lib/libcrypto/Makefile
+++ b/src/regress/lib/libcrypto/Makefile
@@ -1,7 +1,8 @@
1# $OpenBSD: Makefile,v 1.6 2014/05/02 19:27:04 miod Exp $ 1# $OpenBSD: Makefile,v 1.7 2014/05/03 15:07:46 jsing Exp $
2 2
3SUBDIR= \ 3SUBDIR= \
4 aeswrap \ 4 aeswrap \
5 base64 \
5 bf \ 6 bf \
6 bn \ 7 bn \
7 cast \ 8 cast \
diff --git a/src/regress/lib/libcrypto/base64/Makefile b/src/regress/lib/libcrypto/base64/Makefile
new file mode 100644
index 0000000000..d16badf297
--- /dev/null
+++ b/src/regress/lib/libcrypto/base64/Makefile
@@ -0,0 +1,7 @@
1# $OpenBSD: Makefile,v 1.1 2014/05/03 15:07:46 jsing Exp $
2
3PROG= base64test
4LDADD= -lcrypto
5DPADD= ${LIBCRYPTO}
6
7.include <bsd.regress.mk>
diff --git a/src/regress/lib/libcrypto/base64/base64test.c b/src/regress/lib/libcrypto/base64/base64test.c
new file mode 100644
index 0000000000..2db10f6007
--- /dev/null
+++ b/src/regress/lib/libcrypto/base64/base64test.c
@@ -0,0 +1,373 @@
1/*
2 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <openssl/bio.h>
18#include <openssl/evp.h>
19
20#include <err.h>
21#include <stdio.h>
22
23#define BUF_SIZE 128
24
25struct base64_test {
26 const unsigned char in[BUF_SIZE];
27 const size_t in_len;
28 const unsigned char out[BUF_SIZE];
29 const size_t out_len;
30 const size_t valid_len;
31};
32
33/*
34 * Many of these tests are based on those found in Go's encoding/base64 tests.
35 */
36struct base64_test base64_tests[] = {
37
38 /* RFC3548 examples. */
39 { "\x14\xfb\x9c\x03\xd9\x7e", 6, "FPucA9l+", 8, 6, },
40 { "\x14\xfb\x9c\x03\xd9", 5, "FPucA9k=", 8, 5, },
41 { "\x14\xfb\x9c\x03", 4, "FPucAw==", 8, 4, },
42
43 /* RFC4648 examples. */
44 { "", 0, "", 0, 0, },
45 { "f", 1, "Zg==", 4, 1, },
46 { "fo", 2, "Zm8=", 4, 2, },
47 { "foo", 3, "Zm9v", 4, 3, },
48 { "foob", 4, "Zm9vYg==", 8, 4, },
49 { "fooba", 5, "Zm9vYmE=", 8, 5, },
50 { "foobar", 6, "Zm9vYmFy", 8, 6, },
51
52 /* Wikipedia examples. */
53 { "sure.", 5, "c3VyZS4=", 8, 5, },
54 { "sure", 4, "c3VyZQ==", 8, 4, },
55 { "sur", 3, "c3Vy", 4, 3, },
56 { "su", 2, "c3U=", 4, 2, },
57 { "leasure.", 8, "bGVhc3VyZS4=", 12, 8, },
58 { "easure.", 7, "ZWFzdXJlLg==", 12, 7, },
59 { "asure.", 6, "YXN1cmUu", 8, 6, },
60
61 { "abcd", 4, "YWJjZA==", 8, 4, },
62
63 {
64 "Twas brillig, and the slithy toves",
65 34,
66 "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==",
67 48,
68 34,
69 },
70
71#ifdef crash
72 {
73 "",
74 -1,
75 "YWJjZA======================================================"
76 "============",
77 74,
78 0,
79 },
80#endif
81};
82
83#define N_TESTS (sizeof(base64_tests) / sizeof(*base64_tests))
84
85struct base64_test base64_nl_tests[] = {
86
87 /* Corrupt/invalid encodings. */
88 { "", -1, "", 0, 0, },
89 { "", -1, "!!!!", 4, 0, }, /* 20 */
90 { "", -1, "====", 4, 1, }, /* XXX - output ix 0x0. */
91 { "", -1, "x===", 4, 1, },
92 { "", -1, "=AAA", 4, 3, },
93 { "", -1, "A=AA", 4, 3, },
94 { "", -1, "AA=A", 4, 2, },
95 { "", -1, "AA==A", 5, 0, },
96 { "", -1, "AAA=AAAA", 8, 6, },
97 { "", -1, "AAAAA", 5, 0, },
98 { "", -1, "AAAAAA", 6, 0, },
99 { "", -1, "A=", 2, 0, },
100 { "", -1, "A==", 3, 0, },
101 { "", -1, "AA=", 3, 0, },
102 { "", -1, "AA==", 4, 1, }, /* XXX - output ix 0x0. */
103 { "", -1, "AAA=", 4, 2, }, /* XXX - output ix 2x 0x0. */
104 { "", -1, "AAAA", 4, 3, }, /* XXX - output ix 3x 0x0. */
105 { "", -1, "AAAAAA=", 7, 0, },
106 { "", -1, "YWJjZA=====", 11, 0, },
107
108
109 /* Encodings with embedded CR/LF. */
110 { "sure", 4, "c3VyZQ==", 8, 4, },
111 { "sure", 4, "c3VyZQ==\r", 9, 4, },
112 { "sure", 4, "c3VyZQ==\n", 9, 4, },
113 { "sure", 4, "c3VyZQ==\r\n", 10, 4, },
114 { "sure", 4, "c3VyZ\r\nQ==", 10, 4, },
115 { "sure", 4, "c3V\ryZ\nQ==", 10, 4, },
116 { "sure", 4, "c3V\nyZ\rQ==", 10, 4, },
117 { "sure", 4, "c3VyZ\nQ==", 9, 4, },
118 { "sure", 4, "c3VyZQ\n==", 9, 4, },
119 { "sure", 4, "c3VyZQ=\n=", 9, 4, },
120 { "sure", 4, "c3VyZQ=\r\n\r\n=", 12, 4, },
121
122};
123
124#define N_NL_TESTS (sizeof(base64_nl_tests) / sizeof(*base64_nl_tests))
125
126struct base64_test base64_no_nl_tests[] = {
127
128 /*
129 * In non-newline mode, the output resulting from corrupt/invalid
130 * encodings is completely crazy. A number of zero bytes is returned
131 * rather than nothing.
132 */
133
134 /* Corrupt/invalid encodings. */
135 { "", -1, "", 0, 0, },
136 { "", -1, "!!!!", 4, 0, }, /* 20 */
137 { "", -1, "====", 4, 1, },
138 { "", -1, "x===", 4, 1, },
139 { "", -1, "=AAA", 4, 3, },
140 { "", -1, "A=AA", 4, 3, },
141 { "", -1, "AA=A", 4, 3, },
142 { "", -1, "AA==A", 5, 1, },
143 { "", -1, "AAA=AAAA", 8, 6, },
144 { "", -1, "AAAAA", 5, 3, },
145 { "", -1, "AAAAAA", 6, 3, },
146 { "", -1, "A=", 2, 0, },
147 { "", -1, "A==", 3, 0, },
148 { "", -1, "AA=", 3, 0, },
149 { "", -1, "AA==", 4, 1, },
150 { "", -1, "AAA=", 4, 2, },
151 { "", -1, "AAAA", 4, 3, },
152 { "", -1, "AAAAAA=", 7, 3, },
153 { "", -1, "YWJjZA=====", 11, 4, },
154
155 /* Encodings with embedded CR/LF. */
156 { "sure", 4, "c3VyZQ==", 8, 4, },
157 { "sure", 4, "c3VyZQ==\r", 9, 4, },
158 { "sure", 4, "c3VyZQ==\n", 9, 4, },
159 { "sure", 4, "c3VyZQ==\r\n", 10, 4, },
160 { "sure", -1, "c3VyZ\r\nQ==", 10, 0, },
161 { "sure", -1, "c3V\ryZ\nQ==", 10, 0, },
162 { "sure", -1, "c3V\nyZ\rQ==", 10, 0, },
163 { "sure", -1, "c3VyZ\nQ==", 9, 0, },
164 { "sure", -1, "c3VyZQ\n==", 9, 0, },
165 { "sure", -1, "c3VyZQ=\n=", 9, 0, },
166 { "sure", -1, "c3VyZQ=\r\n\r\n=", 12, 0, },
167
168};
169
170#define N_NO_NL_TESTS (sizeof(base64_no_nl_tests) / sizeof(*base64_no_nl_tests))
171
172int
173base64_encoding_test(int test_no, struct base64_test *bt, int test_nl)
174{
175 BIO *bio_b64, *bio_mem;
176 unsigned char *buf, *out;
177 int i, len, b64len;
178 int failure = 0;
179
180 buf = malloc(BUF_SIZE);
181 if (buf == NULL)
182 errx(1, "malloc");
183
184 bio_b64 = BIO_new(BIO_f_base64());
185 if (bio_b64 == NULL)
186 errx(1, "BIO_new failed for BIO_f_base64");
187
188 bio_mem = BIO_new(BIO_s_mem());
189 if (bio_mem == NULL)
190 errx(1, "BIO_new failed for BIO_s_mem");
191
192 bio_mem = BIO_push(bio_b64, bio_mem);
193
194 if (!test_nl)
195 BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
196
197 len = BIO_write(bio_mem, bt->in, bt->in_len);
198 if (len != bt->in_len) {
199 fprintf(stderr, "FAIL: test %i - only wrote %i out of %i "
200 "characters\n", test_no, len, bt->in_len);
201 failure = 1;
202 goto done;
203 }
204 if (BIO_flush(bio_mem) < 0) {
205 fprintf(stderr, "FAIL: test %i - flush failed\n", test_no);
206 failure = 1;
207 goto done;
208 }
209
210 b64len = 0;
211 for (i = 0; i < bt->out_len; i++) {
212 if (bt->out[i] == '\r' || bt->out[i] == '\n')
213 continue;
214 buf[b64len++] = bt->out[i];
215 }
216 if (test_nl)
217 buf[b64len++] = '\n';
218
219 len = BIO_get_mem_data(bio_mem, &out);
220
221 /* An empty string with NL results in no output, rather than '\n'. */
222 if (test_nl && b64len == 1 && len == 0)
223 goto done;
224
225 if (len != b64len) {
226 fprintf(stderr, "FAIL: test %i - encoding resulted in %i "
227 "characters instead of %i\n", test_no, len, b64len);
228 failure = 1;
229 goto done;
230 }
231
232 if (memcmp(buf, out, b64len) != 0) {
233 fprintf(stderr, "FAIL: test %i - encoding differs:\n", test_no);
234 fprintf(stderr, " encoding: ");
235 for (i = 0; i < len; i++)
236 fprintf(stderr, "%c", out[i]);
237 fprintf(stderr, "\n");
238 fprintf(stderr, " test data: ");
239 for (i = 0; i < bt->out_len; i++)
240 fprintf(stderr, "%c", buf[i]);
241 fprintf(stderr, "\n");
242 failure = 1;
243 }
244
245done:
246 BIO_free_all(bio_mem);
247 free(buf);
248
249 return failure;
250}
251
252int
253base64_decoding_test(int test_no, struct base64_test *bt, int test_nl)
254{
255 BIO *bio_b64, *bio_mem;
256 char *buf, *input;
257 int failure = 0;
258 int i, inlen, len;
259
260 buf = malloc(BUF_SIZE);
261 if (buf == NULL)
262 errx(1, "malloc");
263
264 input = (char *)bt->out;
265 inlen = bt->out_len;
266
267 if (test_nl)
268 inlen = asprintf(&input, "%s\r\n", bt->out);
269
270 bio_mem = BIO_new_mem_buf(input, inlen);
271 if (bio_mem == NULL)
272 errx(1, "BIO_new_mem_buf failed");
273
274 bio_b64 = BIO_new(BIO_f_base64());
275 if (bio_b64 == NULL)
276 errx(1, "BIO_new failed for BIO_f_base64");
277
278 if (!test_nl)
279 BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
280
281 bio_mem = BIO_push(bio_b64, bio_mem);
282
283 /*
284 * If we wrote zero characters then a BIO_read will result in a return
285 * value of -1, hence we need to handle this case.
286 */
287 len = BIO_read(bio_mem, buf, BUF_SIZE);
288 if (len != bt->valid_len && (bt->in_len != 0 || len != -1)) {
289 fprintf(stderr, "FAIL: test %i - decoding resulted in %i "
290 "characters instead of %i\n", test_no, len, bt->valid_len);
291 fprintf(stderr, " input: ");
292 for (i = 0; i < inlen; i++)
293 fprintf(stderr, "%c", input[i]);
294 fprintf(stderr, "\n");
295 fprintf(stderr, " decoding: ");
296 for (i = 0; i < len; i++)
297 fprintf(stderr, "0x%x ", buf[i]);
298 fprintf(stderr, "\n");
299 failure = 1;
300 goto done;
301 }
302
303 /* See if we expect this to fail decoding. */
304 if (bt->in_len == -1)
305 goto done;
306
307 if (memcmp(bt->in, buf, bt->in_len) != 0) {
308 fprintf(stderr, "FAIL: test %i - decoding differs:\n", test_no);
309 fprintf(stderr, " decoding: ");
310 for (i = 0; i < len; i++)
311 fprintf(stderr, "0x%x ", buf[i]);
312 fprintf(stderr, "\n");
313 fprintf(stderr, " test data: ");
314 for (i = 0; i < inlen; i++)
315 fprintf(stderr, "0x%x ", input[i]);
316 fprintf(stderr, "\n");
317 failure = 1;
318 }
319
320done:
321 BIO_free_all(bio_mem);
322 free(buf);
323 if (test_nl)
324 free(input);
325
326 return failure;
327}
328
329int
330main(int argc, char **argv)
331{
332 struct base64_test *bt;
333 int failed = 0;
334 int i;
335
336 fprintf(stderr, "Starting combined tests...\n");
337
338 for (i = 0; i < N_TESTS; i++) {
339 bt = &base64_tests[i];
340 if (bt->in_len != -1)
341 failed += base64_encoding_test(i, bt, 0);
342 if (bt->out_len != -1)
343 failed += base64_decoding_test(i, bt, 0);
344 if (bt->in_len != -1)
345 failed += base64_encoding_test(i, bt, 1);
346 if (bt->out_len != -1)
347 failed += base64_decoding_test(i, bt, 1);
348 }
349
350 fprintf(stderr, "Starting NL tests...\n");
351
352 for (i = 0; i < N_NL_TESTS; i++) {
353 bt = &base64_nl_tests[i];
354
355 if (bt->in_len != -1)
356 failed += base64_encoding_test(i, bt, 1);
357 if (bt->out_len != -1)
358 failed += base64_decoding_test(i, bt, 1);
359 }
360
361 fprintf(stderr, "Starting NO NL tests...\n");
362
363 for (i = 0; i < N_NO_NL_TESTS; i++) {
364 bt = &base64_no_nl_tests[i];
365
366 if (bt->in_len != -1)
367 failed += base64_encoding_test(i, bt, 0);
368 if (bt->out_len != -1)
369 failed += base64_decoding_test(i, bt, 0);
370 }
371
372 return failed;
373}