1*35c0a8c4SKyle Evans /*-
2*35c0a8c4SKyle Evans * Copyright (c) 2024 Kyle Evans <kevans@FreeBSD.org>
3*35c0a8c4SKyle Evans *
4*35c0a8c4SKyle Evans * SPDX-License-Identifier: BSD-2-Clause
5*35c0a8c4SKyle Evans */
6*35c0a8c4SKyle Evans
7*35c0a8c4SKyle Evans #include <sys/param.h>
8*35c0a8c4SKyle Evans #include <sys/socket.h>
9*35c0a8c4SKyle Evans
10*35c0a8c4SKyle Evans #include <assert.h>
11*35c0a8c4SKyle Evans #include <signal.h>
12*35c0a8c4SKyle Evans #include <stdbool.h>
13*35c0a8c4SKyle Evans #include <stdio.h>
14*35c0a8c4SKyle Evans #include <stdlib.h>
15*35c0a8c4SKyle Evans #include <unistd.h>
16*35c0a8c4SKyle Evans
17*35c0a8c4SKyle Evans #include <libder.h>
18*35c0a8c4SKyle Evans
19*35c0a8c4SKyle Evans #include "fuzzers.h"
20*35c0a8c4SKyle Evans
21*35c0a8c4SKyle Evans int
LLVMFuzzerTestOneInput(const uint8_t * data,size_t sz)22*35c0a8c4SKyle Evans LLVMFuzzerTestOneInput(const uint8_t *data, size_t sz)
23*35c0a8c4SKyle Evans {
24*35c0a8c4SKyle Evans struct libder_ctx *ctx;
25*35c0a8c4SKyle Evans struct libder_object *obj;
26*35c0a8c4SKyle Evans size_t readsz;
27*35c0a8c4SKyle Evans int ret;
28*35c0a8c4SKyle Evans bool strict;
29*35c0a8c4SKyle Evans
30*35c0a8c4SKyle Evans if (sz < 2)
31*35c0a8c4SKyle Evans return (-1);
32*35c0a8c4SKyle Evans
33*35c0a8c4SKyle Evans /*
34*35c0a8c4SKyle Evans * I worked this in originally by just using the high bit of the first
35*35c0a8c4SKyle Evans * byte, but then I realized that encoding it that way would make it
36*35c0a8c4SKyle Evans * impossible to get strict validation of universal and application
37*35c0a8c4SKyle Evans * tags. The former is a bit more important than the latter.
38*35c0a8c4SKyle Evans */
39*35c0a8c4SKyle Evans strict = !!data[0];
40*35c0a8c4SKyle Evans data++;
41*35c0a8c4SKyle Evans sz--;
42*35c0a8c4SKyle Evans
43*35c0a8c4SKyle Evans ctx = libder_open();
44*35c0a8c4SKyle Evans libder_set_strict(ctx, strict);
45*35c0a8c4SKyle Evans ret = -1;
46*35c0a8c4SKyle Evans readsz = sz;
47*35c0a8c4SKyle Evans obj = libder_read(ctx, data, &readsz);
48*35c0a8c4SKyle Evans if (obj == NULL || readsz != sz)
49*35c0a8c4SKyle Evans goto out;
50*35c0a8c4SKyle Evans
51*35c0a8c4SKyle Evans if (obj != NULL) {
52*35c0a8c4SKyle Evans uint8_t *buf = NULL;
53*35c0a8c4SKyle Evans size_t bufsz = 0;
54*35c0a8c4SKyle Evans
55*35c0a8c4SKyle Evans /*
56*35c0a8c4SKyle Evans * If we successfully read it, then it shouldn't
57*35c0a8c4SKyle Evans * overflow. We're letting libder allocate the buffer,
58*35c0a8c4SKyle Evans * so we shouldn't be able to hit the 'too small' bit.
59*35c0a8c4SKyle Evans *
60*35c0a8c4SKyle Evans * I can't imagine what other errors might happen, so
61*35c0a8c4SKyle Evans * we'll just assert on it.
62*35c0a8c4SKyle Evans */
63*35c0a8c4SKyle Evans buf = libder_write(ctx, obj, buf, &bufsz);
64*35c0a8c4SKyle Evans if (buf == NULL)
65*35c0a8c4SKyle Evans goto out;
66*35c0a8c4SKyle Evans
67*35c0a8c4SKyle Evans assert(bufsz != 0);
68*35c0a8c4SKyle Evans
69*35c0a8c4SKyle Evans free(buf);
70*35c0a8c4SKyle Evans }
71*35c0a8c4SKyle Evans
72*35c0a8c4SKyle Evans ret = 0;
73*35c0a8c4SKyle Evans
74*35c0a8c4SKyle Evans out:
75*35c0a8c4SKyle Evans libder_obj_free(obj);
76*35c0a8c4SKyle Evans libder_close(ctx);
77*35c0a8c4SKyle Evans
78*35c0a8c4SKyle Evans return (ret);
79*35c0a8c4SKyle Evans }
80