diff options
author | jsing <> | 2014-05-03 15:07:46 +0000 |
---|---|---|
committer | jsing <> | 2014-05-03 15:07:46 +0000 |
commit | c068ce427d4525ce31189b2feb96a7ef18568758 (patch) | |
tree | 35196a9a223fc61156e97a24a8c23c377cbbef1e | |
parent | d59b1705859c0c622e7eb86fafb20cf0097c6d82 (diff) | |
download | openbsd-c068ce427d4525ce31189b2feb96a7ef18568758.tar.gz openbsd-c068ce427d4525ce31189b2feb96a7ef18568758.tar.bz2 openbsd-c068ce427d4525ce31189b2feb96a7ef18568758.zip |
Initial version of a base64 regress.
-rw-r--r-- | src/regress/lib/libcrypto/Makefile | 3 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/base64/Makefile | 7 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/base64/base64test.c | 373 |
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 | ||
3 | SUBDIR= \ | 3 | SUBDIR= \ |
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 | |||
3 | PROG= base64test | ||
4 | LDADD= -lcrypto | ||
5 | DPADD= ${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 | |||
25 | struct 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 | */ | ||
36 | struct 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 | |||
85 | struct 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 | |||
126 | struct 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 | |||
172 | int | ||
173 | base64_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 | |||
245 | done: | ||
246 | BIO_free_all(bio_mem); | ||
247 | free(buf); | ||
248 | |||
249 | return failure; | ||
250 | } | ||
251 | |||
252 | int | ||
253 | base64_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 | |||
320 | done: | ||
321 | BIO_free_all(bio_mem); | ||
322 | free(buf); | ||
323 | if (test_nl) | ||
324 | free(input); | ||
325 | |||
326 | return failure; | ||
327 | } | ||
328 | |||
329 | int | ||
330 | main(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 | } | ||