xref: /minix3/crypto/external/bsd/heimdal/dist/lib/asn1/check-common.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: check-common.c,v 1.1.1.2 2014/04/24 12:45:28 pettai Exp $	*/
2ebfedea0SLionel Sambuc 
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc  * Copyright (c) 1999 - 2006 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc  * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc  * All rights reserved.
7ebfedea0SLionel Sambuc  *
8ebfedea0SLionel Sambuc  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
9ebfedea0SLionel Sambuc  *
10ebfedea0SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
11ebfedea0SLionel Sambuc  * modification, are permitted provided that the following conditions
12ebfedea0SLionel Sambuc  * are met:
13ebfedea0SLionel Sambuc  *
14ebfedea0SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
15ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
16ebfedea0SLionel Sambuc  *
17ebfedea0SLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
18ebfedea0SLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
19ebfedea0SLionel Sambuc  *    documentation and/or other materials provided with the distribution.
20ebfedea0SLionel Sambuc  *
21ebfedea0SLionel Sambuc  * 3. Neither the name of the Institute nor the names of its contributors
22ebfedea0SLionel Sambuc  *    may be used to endorse or promote products derived from this software
23ebfedea0SLionel Sambuc  *    without specific prior written permission.
24ebfedea0SLionel Sambuc  *
25ebfedea0SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
26ebfedea0SLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27ebfedea0SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28ebfedea0SLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
29ebfedea0SLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30ebfedea0SLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31ebfedea0SLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32ebfedea0SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33ebfedea0SLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34ebfedea0SLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35ebfedea0SLionel Sambuc  * SUCH DAMAGE.
36ebfedea0SLionel Sambuc  */
37ebfedea0SLionel Sambuc 
38ebfedea0SLionel Sambuc #ifdef HAVE_CONFIG_H
39ebfedea0SLionel Sambuc #include <config.h>
40ebfedea0SLionel Sambuc #endif
41ebfedea0SLionel Sambuc #ifdef HAVE_SYS_MMAN_H
42ebfedea0SLionel Sambuc #include <sys/mman.h>
43ebfedea0SLionel Sambuc #endif
44ebfedea0SLionel Sambuc #include <stdio.h>
45ebfedea0SLionel Sambuc #include <string.h>
46ebfedea0SLionel Sambuc #include <err.h>
47ebfedea0SLionel Sambuc #include <krb5/roken.h>
48ebfedea0SLionel Sambuc 
49ebfedea0SLionel Sambuc #include <krb5/asn1-common.h>
50ebfedea0SLionel Sambuc #include "check-common.h"
51ebfedea0SLionel Sambuc 
52*0a6a1f1dSLionel Sambuc __RCSID("NetBSD");
53ebfedea0SLionel Sambuc 
54ebfedea0SLionel Sambuc struct map_page {
55ebfedea0SLionel Sambuc     void *start;
56ebfedea0SLionel Sambuc     size_t size;
57ebfedea0SLionel Sambuc     void *data_start;
58ebfedea0SLionel Sambuc     size_t data_size;
59ebfedea0SLionel Sambuc     enum map_type type;
60ebfedea0SLionel Sambuc };
61ebfedea0SLionel Sambuc 
62ebfedea0SLionel Sambuc /* #undef HAVE_MMAP */
63ebfedea0SLionel Sambuc 
64ebfedea0SLionel Sambuc void *
map_alloc(enum map_type type,const void * buf,size_t size,struct map_page ** map)65ebfedea0SLionel Sambuc map_alloc(enum map_type type, const void *buf,
66ebfedea0SLionel Sambuc 	  size_t size, struct map_page **map)
67ebfedea0SLionel Sambuc {
68ebfedea0SLionel Sambuc #ifndef HAVE_MMAP
69ebfedea0SLionel Sambuc     unsigned char *p;
70ebfedea0SLionel Sambuc     size_t len = size + sizeof(long) * 2;
71ebfedea0SLionel Sambuc     int i;
72ebfedea0SLionel Sambuc 
73ebfedea0SLionel Sambuc     *map = ecalloc(1, sizeof(**map));
74ebfedea0SLionel Sambuc 
75ebfedea0SLionel Sambuc     p = emalloc(len);
76ebfedea0SLionel Sambuc     (*map)->type = type;
77ebfedea0SLionel Sambuc     (*map)->start = p;
78ebfedea0SLionel Sambuc     (*map)->size = len;
79ebfedea0SLionel Sambuc     (*map)->data_start = p + sizeof(long);
80ebfedea0SLionel Sambuc     for (i = sizeof(long); i > 0; i--)
81ebfedea0SLionel Sambuc 	p[sizeof(long) - i] = 0xff - i;
82ebfedea0SLionel Sambuc     for (i = sizeof(long); i > 0; i--)
83ebfedea0SLionel Sambuc 	p[len - i] = 0xff - i;
84ebfedea0SLionel Sambuc #else
85ebfedea0SLionel Sambuc     unsigned char *p;
86ebfedea0SLionel Sambuc     int flags, ret, fd;
87ebfedea0SLionel Sambuc     size_t pagesize = getpagesize();
88ebfedea0SLionel Sambuc 
89ebfedea0SLionel Sambuc     *map = ecalloc(1, sizeof(**map));
90ebfedea0SLionel Sambuc 
91ebfedea0SLionel Sambuc     (*map)->type = type;
92ebfedea0SLionel Sambuc 
93ebfedea0SLionel Sambuc #ifdef MAP_ANON
94ebfedea0SLionel Sambuc     flags = MAP_ANON;
95ebfedea0SLionel Sambuc     fd = -1;
96ebfedea0SLionel Sambuc #else
97ebfedea0SLionel Sambuc     flags = 0;
98ebfedea0SLionel Sambuc     fd = open ("/dev/zero", O_RDONLY);
99ebfedea0SLionel Sambuc     if(fd < 0)
100ebfedea0SLionel Sambuc 	err (1, "open /dev/zero");
101ebfedea0SLionel Sambuc #endif
102ebfedea0SLionel Sambuc     flags |= MAP_PRIVATE;
103ebfedea0SLionel Sambuc 
104ebfedea0SLionel Sambuc     (*map)->size = size + pagesize - (size % pagesize) + pagesize * 2;
105ebfedea0SLionel Sambuc 
106ebfedea0SLionel Sambuc     p = (unsigned char *)mmap(0, (*map)->size, PROT_READ | PROT_WRITE,
107ebfedea0SLionel Sambuc 			      flags, fd, 0);
108ebfedea0SLionel Sambuc     if (p == (unsigned char *)MAP_FAILED)
109ebfedea0SLionel Sambuc 	err (1, "mmap");
110ebfedea0SLionel Sambuc 
111ebfedea0SLionel Sambuc     (*map)->start = p;
112ebfedea0SLionel Sambuc 
113ebfedea0SLionel Sambuc     ret = mprotect (p, pagesize, 0);
114ebfedea0SLionel Sambuc     if (ret < 0)
115ebfedea0SLionel Sambuc 	err (1, "mprotect");
116ebfedea0SLionel Sambuc 
117ebfedea0SLionel Sambuc     ret = mprotect (p + (*map)->size - pagesize, pagesize, 0);
118ebfedea0SLionel Sambuc     if (ret < 0)
119ebfedea0SLionel Sambuc 	err (1, "mprotect");
120ebfedea0SLionel Sambuc 
121ebfedea0SLionel Sambuc     switch (type) {
122ebfedea0SLionel Sambuc     case OVERRUN:
123ebfedea0SLionel Sambuc 	(*map)->data_start = p + (*map)->size - pagesize - size;
124ebfedea0SLionel Sambuc 	break;
125ebfedea0SLionel Sambuc     case UNDERRUN:
126ebfedea0SLionel Sambuc 	(*map)->data_start = p + pagesize;
127ebfedea0SLionel Sambuc 	break;
128ebfedea0SLionel Sambuc    default:
129ebfedea0SLionel Sambuc 	abort();
130ebfedea0SLionel Sambuc     }
131ebfedea0SLionel Sambuc #endif
132ebfedea0SLionel Sambuc     (*map)->data_size = size;
133ebfedea0SLionel Sambuc     if (buf)
134ebfedea0SLionel Sambuc 	memcpy((*map)->data_start, buf, size);
135ebfedea0SLionel Sambuc     return (*map)->data_start;
136ebfedea0SLionel Sambuc }
137ebfedea0SLionel Sambuc 
138ebfedea0SLionel Sambuc void
map_free(struct map_page * map,const char * test_name,const char * map_name)139ebfedea0SLionel Sambuc map_free(struct map_page *map, const char *test_name, const char *map_name)
140ebfedea0SLionel Sambuc {
141ebfedea0SLionel Sambuc #ifndef HAVE_MMAP
142ebfedea0SLionel Sambuc     unsigned char *p = map->start;
143ebfedea0SLionel Sambuc     int i;
144ebfedea0SLionel Sambuc 
145ebfedea0SLionel Sambuc     for (i = sizeof(long); i > 0; i--)
146ebfedea0SLionel Sambuc 	if (p[sizeof(long) - i] != 0xff - i)
147ebfedea0SLionel Sambuc 	    errx(1, "%s: %s underrun %d\n", test_name, map_name, i);
148ebfedea0SLionel Sambuc     for (i = sizeof(long); i > 0; i--)
149ebfedea0SLionel Sambuc 	if (p[map->size - i] != 0xff - i)
150ebfedea0SLionel Sambuc 	    errx(1, "%s: %s overrun %lu\n", test_name, map_name,
151ebfedea0SLionel Sambuc 		 (unsigned long)map->size - i);
152ebfedea0SLionel Sambuc     free(map->start);
153ebfedea0SLionel Sambuc #else
154ebfedea0SLionel Sambuc     int ret;
155ebfedea0SLionel Sambuc 
156ebfedea0SLionel Sambuc     ret = munmap (map->start, map->size);
157ebfedea0SLionel Sambuc     if (ret < 0)
158ebfedea0SLionel Sambuc 	err (1, "munmap");
159ebfedea0SLionel Sambuc #endif
160ebfedea0SLionel Sambuc     free(map);
161ebfedea0SLionel Sambuc }
162ebfedea0SLionel Sambuc 
163ebfedea0SLionel Sambuc static void
print_bytes(unsigned const char * buf,size_t len)164ebfedea0SLionel Sambuc print_bytes (unsigned const char *buf, size_t len)
165ebfedea0SLionel Sambuc {
166ebfedea0SLionel Sambuc     int i;
167ebfedea0SLionel Sambuc 
168ebfedea0SLionel Sambuc     for (i = 0; i < len; ++i)
169ebfedea0SLionel Sambuc 	printf ("%02x ", buf[i]);
170ebfedea0SLionel Sambuc }
171ebfedea0SLionel Sambuc 
172ebfedea0SLionel Sambuc #ifndef MAP_FAILED
173ebfedea0SLionel Sambuc #define MAP_FAILED (-1)
174ebfedea0SLionel Sambuc #endif
175ebfedea0SLionel Sambuc 
176ebfedea0SLionel Sambuc static char *current_test = "<uninit>";
177ebfedea0SLionel Sambuc static char *current_state = "<uninit>";
178ebfedea0SLionel Sambuc 
179ebfedea0SLionel Sambuc static RETSIGTYPE
segv_handler(int sig)180ebfedea0SLionel Sambuc segv_handler(int sig)
181ebfedea0SLionel Sambuc {
182ebfedea0SLionel Sambuc     int fd;
183ebfedea0SLionel Sambuc     char msg[] = "SIGSEGV i current test: ";
184ebfedea0SLionel Sambuc 
185ebfedea0SLionel Sambuc     fd = open("/dev/stdout", O_WRONLY, 0600);
186ebfedea0SLionel Sambuc     if (fd >= 0) {
187ebfedea0SLionel Sambuc 	write(fd, msg, sizeof(msg));
188ebfedea0SLionel Sambuc 	write(fd, current_test, strlen(current_test));
189ebfedea0SLionel Sambuc 	write(fd, " ", 1);
190ebfedea0SLionel Sambuc 	write(fd, current_state, strlen(current_state));
191ebfedea0SLionel Sambuc 	write(fd, "\n", 1);
192ebfedea0SLionel Sambuc 	close(fd);
193ebfedea0SLionel Sambuc     }
194ebfedea0SLionel Sambuc     _exit(1);
195ebfedea0SLionel Sambuc }
196ebfedea0SLionel Sambuc 
197ebfedea0SLionel Sambuc int
generic_test(const struct test_case * tests,unsigned ntests,size_t data_size,int (ASN1CALL * encode)(unsigned char *,size_t,void *,size_t *),int (ASN1CALL * length)(void *),int (ASN1CALL * decode)(unsigned char *,size_t,void *,size_t *),int (ASN1CALL * free_data)(void *),int (* cmp)(void * a,void * b),int (ASN1CALL * copy)(const void * from,void * to))198ebfedea0SLionel Sambuc generic_test (const struct test_case *tests,
199ebfedea0SLionel Sambuc 	      unsigned ntests,
200ebfedea0SLionel Sambuc 	      size_t data_size,
201ebfedea0SLionel Sambuc 	      int (ASN1CALL *encode)(unsigned char *, size_t, void *, size_t *),
202ebfedea0SLionel Sambuc 	      int (ASN1CALL *length)(void *),
203ebfedea0SLionel Sambuc 	      int (ASN1CALL *decode)(unsigned char *, size_t, void *, size_t *),
204ebfedea0SLionel Sambuc 	      int (ASN1CALL *free_data)(void *),
205ebfedea0SLionel Sambuc 	      int (*cmp)(void *a, void *b),
206ebfedea0SLionel Sambuc 	      int (ASN1CALL *copy)(const void *from, void *to))
207ebfedea0SLionel Sambuc {
208ebfedea0SLionel Sambuc     unsigned char *buf, *buf2;
209ebfedea0SLionel Sambuc     int i;
210ebfedea0SLionel Sambuc     int failures = 0;
211ebfedea0SLionel Sambuc     void *data;
212ebfedea0SLionel Sambuc     struct map_page *data_map, *buf_map, *buf2_map;
213ebfedea0SLionel Sambuc 
214ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
215ebfedea0SLionel Sambuc     struct sigaction sa, osa;
216ebfedea0SLionel Sambuc #endif
217ebfedea0SLionel Sambuc 
218ebfedea0SLionel Sambuc     for (i = 0; i < ntests; ++i) {
219ebfedea0SLionel Sambuc 	int ret;
220ebfedea0SLionel Sambuc 	size_t sz, consumed_sz, length_sz, buf_sz;
221ebfedea0SLionel Sambuc 	void *to = NULL;
222ebfedea0SLionel Sambuc 
223ebfedea0SLionel Sambuc 	current_test = tests[i].name;
224ebfedea0SLionel Sambuc 
225ebfedea0SLionel Sambuc 	current_state = "init";
226ebfedea0SLionel Sambuc 
227ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
228ebfedea0SLionel Sambuc 	sigemptyset (&sa.sa_mask);
229ebfedea0SLionel Sambuc 	sa.sa_flags = 0;
230ebfedea0SLionel Sambuc #ifdef SA_RESETHAND
231ebfedea0SLionel Sambuc 	sa.sa_flags |= SA_RESETHAND;
232ebfedea0SLionel Sambuc #endif
233ebfedea0SLionel Sambuc 	sa.sa_handler = segv_handler;
234ebfedea0SLionel Sambuc 	sigaction (SIGSEGV, &sa, &osa);
235ebfedea0SLionel Sambuc #endif
236ebfedea0SLionel Sambuc 
237ebfedea0SLionel Sambuc 	data = map_alloc(OVERRUN, NULL, data_size, &data_map);
238ebfedea0SLionel Sambuc 
239ebfedea0SLionel Sambuc 	buf_sz = tests[i].byte_len;
240ebfedea0SLionel Sambuc 	buf = map_alloc(UNDERRUN, NULL, buf_sz, &buf_map);
241ebfedea0SLionel Sambuc 
242ebfedea0SLionel Sambuc 	current_state = "encode";
243ebfedea0SLionel Sambuc 	ret = (*encode) (buf + buf_sz - 1, buf_sz,
244ebfedea0SLionel Sambuc 			 tests[i].val, &sz);
245ebfedea0SLionel Sambuc 	if (ret != 0) {
246ebfedea0SLionel Sambuc 	    printf ("encoding of %s failed %d\n", tests[i].name, ret);
247ebfedea0SLionel Sambuc 	    ++failures;
248ebfedea0SLionel Sambuc 	    continue;
249ebfedea0SLionel Sambuc 	}
250ebfedea0SLionel Sambuc 	if (sz != tests[i].byte_len) {
251ebfedea0SLionel Sambuc  	    printf ("encoding of %s has wrong len (%lu != %lu)\n",
252ebfedea0SLionel Sambuc 		    tests[i].name,
253ebfedea0SLionel Sambuc 		    (unsigned long)sz, (unsigned long)tests[i].byte_len);
254ebfedea0SLionel Sambuc 	    ++failures;
255ebfedea0SLionel Sambuc 	    continue;
256ebfedea0SLionel Sambuc 	}
257ebfedea0SLionel Sambuc 
258ebfedea0SLionel Sambuc 	current_state = "length";
259ebfedea0SLionel Sambuc 	length_sz = (*length) (tests[i].val);
260ebfedea0SLionel Sambuc 	if (sz != length_sz) {
261ebfedea0SLionel Sambuc 	    printf ("length for %s is bad (%lu != %lu)\n",
262ebfedea0SLionel Sambuc 		    tests[i].name, (unsigned long)length_sz, (unsigned long)sz);
263ebfedea0SLionel Sambuc 	    ++failures;
264ebfedea0SLionel Sambuc 	    continue;
265ebfedea0SLionel Sambuc 	}
266ebfedea0SLionel Sambuc 
267ebfedea0SLionel Sambuc 	current_state = "memcmp";
268ebfedea0SLionel Sambuc 	if (memcmp (buf, tests[i].bytes, tests[i].byte_len) != 0) {
269ebfedea0SLionel Sambuc 	    printf ("encoding of %s has bad bytes:\n"
270ebfedea0SLionel Sambuc 		    "correct: ", tests[i].name);
271ebfedea0SLionel Sambuc 	    print_bytes ((unsigned char *)tests[i].bytes, tests[i].byte_len);
272ebfedea0SLionel Sambuc 	    printf ("\nactual:  ");
273ebfedea0SLionel Sambuc 	    print_bytes (buf, sz);
274ebfedea0SLionel Sambuc 	    printf ("\n");
275ebfedea0SLionel Sambuc #if 0
276ebfedea0SLionel Sambuc 	    rk_dumpdata("correct", tests[i].bytes, tests[i].byte_len);
277ebfedea0SLionel Sambuc 	    rk_dumpdata("actual", buf, sz);
278ebfedea0SLionel Sambuc 	    exit (1);
279ebfedea0SLionel Sambuc #endif
280ebfedea0SLionel Sambuc 	    ++failures;
281ebfedea0SLionel Sambuc 	    continue;
282ebfedea0SLionel Sambuc 	}
283ebfedea0SLionel Sambuc 
284ebfedea0SLionel Sambuc 	buf2 = map_alloc(OVERRUN, buf, sz, &buf2_map);
285ebfedea0SLionel Sambuc 
286ebfedea0SLionel Sambuc 	current_state = "decode";
287ebfedea0SLionel Sambuc 	ret = (*decode) (buf2, sz, data, &consumed_sz);
288ebfedea0SLionel Sambuc 	if (ret != 0) {
289ebfedea0SLionel Sambuc 	    printf ("decoding of %s failed %d\n", tests[i].name, ret);
290ebfedea0SLionel Sambuc 	    ++failures;
291ebfedea0SLionel Sambuc 	    continue;
292ebfedea0SLionel Sambuc 	}
293ebfedea0SLionel Sambuc 	if (sz != consumed_sz) {
294ebfedea0SLionel Sambuc 	    printf ("different length decoding %s (%ld != %ld)\n",
295ebfedea0SLionel Sambuc 		    tests[i].name,
296ebfedea0SLionel Sambuc 		    (unsigned long)sz, (unsigned long)consumed_sz);
297ebfedea0SLionel Sambuc 	    ++failures;
298ebfedea0SLionel Sambuc 	    continue;
299ebfedea0SLionel Sambuc 	}
300ebfedea0SLionel Sambuc 	current_state = "cmp";
301ebfedea0SLionel Sambuc 	if ((*cmp)(data, tests[i].val) != 0) {
302ebfedea0SLionel Sambuc 	    printf ("%s: comparison failed\n", tests[i].name);
303ebfedea0SLionel Sambuc 	    ++failures;
304ebfedea0SLionel Sambuc 	    continue;
305ebfedea0SLionel Sambuc 	}
306ebfedea0SLionel Sambuc 
307ebfedea0SLionel Sambuc 	current_state = "copy";
308ebfedea0SLionel Sambuc 	if (copy) {
309ebfedea0SLionel Sambuc 	    to = emalloc(data_size);
310ebfedea0SLionel Sambuc 	    ret = (*copy)(data, to);
311ebfedea0SLionel Sambuc 	    if (ret != 0) {
312ebfedea0SLionel Sambuc 		printf ("copy of %s failed %d\n", tests[i].name, ret);
313ebfedea0SLionel Sambuc 		++failures;
314ebfedea0SLionel Sambuc 		continue;
315ebfedea0SLionel Sambuc 	    }
316ebfedea0SLionel Sambuc 
317ebfedea0SLionel Sambuc 	    current_state = "cmp-copy";
318ebfedea0SLionel Sambuc 	    if ((*cmp)(data, to) != 0) {
319ebfedea0SLionel Sambuc 		printf ("%s: copy comparison failed\n", tests[i].name);
320ebfedea0SLionel Sambuc 		++failures;
321ebfedea0SLionel Sambuc 		continue;
322ebfedea0SLionel Sambuc 	    }
323ebfedea0SLionel Sambuc 	}
324ebfedea0SLionel Sambuc 
325ebfedea0SLionel Sambuc 	current_state = "free";
326ebfedea0SLionel Sambuc 	if (free_data) {
327ebfedea0SLionel Sambuc 	    (*free_data)(data);
328ebfedea0SLionel Sambuc 	    if (to) {
329ebfedea0SLionel Sambuc 		(*free_data)(to);
330ebfedea0SLionel Sambuc 		free(to);
331ebfedea0SLionel Sambuc 	    }
332ebfedea0SLionel Sambuc 	}
333ebfedea0SLionel Sambuc 
334ebfedea0SLionel Sambuc 	current_state = "free";
335ebfedea0SLionel Sambuc 	map_free(buf_map, tests[i].name, "encode");
336ebfedea0SLionel Sambuc 	map_free(buf2_map, tests[i].name, "decode");
337ebfedea0SLionel Sambuc 	map_free(data_map, tests[i].name, "data");
338ebfedea0SLionel Sambuc 
339ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
340ebfedea0SLionel Sambuc 	sigaction (SIGSEGV, &osa, NULL);
341ebfedea0SLionel Sambuc #endif
342ebfedea0SLionel Sambuc     }
343ebfedea0SLionel Sambuc     current_state = "done";
344ebfedea0SLionel Sambuc     return failures;
345ebfedea0SLionel Sambuc }
346ebfedea0SLionel Sambuc 
347ebfedea0SLionel Sambuc /*
348ebfedea0SLionel Sambuc  * check for failures
349ebfedea0SLionel Sambuc  *
350ebfedea0SLionel Sambuc  * a test size (byte_len) of -1 means that the test tries to trigger a
351ebfedea0SLionel Sambuc  * integer overflow (and later a malloc of to little memory), just
352ebfedea0SLionel Sambuc  * allocate some memory and hope that is enough for that test.
353ebfedea0SLionel Sambuc  */
354ebfedea0SLionel Sambuc 
355ebfedea0SLionel Sambuc int
generic_decode_fail(const struct test_case * tests,unsigned ntests,size_t data_size,int (ASN1CALL * decode)(unsigned char *,size_t,void *,size_t *))356ebfedea0SLionel Sambuc generic_decode_fail (const struct test_case *tests,
357ebfedea0SLionel Sambuc 		     unsigned ntests,
358ebfedea0SLionel Sambuc 		     size_t data_size,
359ebfedea0SLionel Sambuc 		     int (ASN1CALL *decode)(unsigned char *, size_t, void *, size_t *))
360ebfedea0SLionel Sambuc {
361ebfedea0SLionel Sambuc     unsigned char *buf;
362ebfedea0SLionel Sambuc     int i;
363ebfedea0SLionel Sambuc     int failures = 0;
364ebfedea0SLionel Sambuc     void *data;
365ebfedea0SLionel Sambuc     struct map_page *data_map, *buf_map;
366ebfedea0SLionel Sambuc 
367ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
368ebfedea0SLionel Sambuc     struct sigaction sa, osa;
369ebfedea0SLionel Sambuc #endif
370ebfedea0SLionel Sambuc 
371ebfedea0SLionel Sambuc     for (i = 0; i < ntests; ++i) {
372ebfedea0SLionel Sambuc 	int ret;
373ebfedea0SLionel Sambuc 	size_t sz;
374ebfedea0SLionel Sambuc 	const void *bytes;
375ebfedea0SLionel Sambuc 
376ebfedea0SLionel Sambuc 	current_test = tests[i].name;
377ebfedea0SLionel Sambuc 
378ebfedea0SLionel Sambuc 	current_state = "init";
379ebfedea0SLionel Sambuc 
380ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
381ebfedea0SLionel Sambuc 	sigemptyset (&sa.sa_mask);
382ebfedea0SLionel Sambuc 	sa.sa_flags = 0;
383ebfedea0SLionel Sambuc #ifdef SA_RESETHAND
384ebfedea0SLionel Sambuc 	sa.sa_flags |= SA_RESETHAND;
385ebfedea0SLionel Sambuc #endif
386ebfedea0SLionel Sambuc 	sa.sa_handler = segv_handler;
387ebfedea0SLionel Sambuc 	sigaction (SIGSEGV, &sa, &osa);
388ebfedea0SLionel Sambuc #endif
389ebfedea0SLionel Sambuc 
390ebfedea0SLionel Sambuc 	data = map_alloc(OVERRUN, NULL, data_size, &data_map);
391ebfedea0SLionel Sambuc 
392ebfedea0SLionel Sambuc 	if (tests[i].byte_len < 0xffffff && tests[i].byte_len >= 0) {
393ebfedea0SLionel Sambuc 	    sz = tests[i].byte_len;
394ebfedea0SLionel Sambuc 	    bytes = tests[i].bytes;
395ebfedea0SLionel Sambuc 	} else {
396ebfedea0SLionel Sambuc 	    sz = 4096;
397ebfedea0SLionel Sambuc 	    bytes = NULL;
398ebfedea0SLionel Sambuc 	}
399ebfedea0SLionel Sambuc 
400ebfedea0SLionel Sambuc 	buf = map_alloc(OVERRUN, bytes, sz, &buf_map);
401ebfedea0SLionel Sambuc 
402ebfedea0SLionel Sambuc 	if (tests[i].byte_len == -1)
403ebfedea0SLionel Sambuc 	    memset(buf, 0, sz);
404ebfedea0SLionel Sambuc 
405ebfedea0SLionel Sambuc 	current_state = "decode";
406ebfedea0SLionel Sambuc 	ret = (*decode) (buf, tests[i].byte_len, data, &sz);
407ebfedea0SLionel Sambuc 	if (ret == 0) {
408ebfedea0SLionel Sambuc 	    printf ("sucessfully decoded %s\n", tests[i].name);
409ebfedea0SLionel Sambuc 	    ++failures;
410ebfedea0SLionel Sambuc 	    continue;
411ebfedea0SLionel Sambuc 	}
412ebfedea0SLionel Sambuc 
413ebfedea0SLionel Sambuc 	current_state = "free";
414ebfedea0SLionel Sambuc 	if (buf)
415ebfedea0SLionel Sambuc 	    map_free(buf_map, tests[i].name, "encode");
416ebfedea0SLionel Sambuc 	map_free(data_map, tests[i].name, "data");
417ebfedea0SLionel Sambuc 
418ebfedea0SLionel Sambuc #ifdef HAVE_SIGACTION
419ebfedea0SLionel Sambuc 	sigaction (SIGSEGV, &osa, NULL);
420ebfedea0SLionel Sambuc #endif
421ebfedea0SLionel Sambuc     }
422ebfedea0SLionel Sambuc     current_state = "done";
423ebfedea0SLionel Sambuc     return failures;
424ebfedea0SLionel Sambuc }
425