1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* tests/fuzzing/krb.c - fuzzing harness for miscellaneous libkrb5 functions */
3 /*
4 * Copyright (C) 2024 by Arjun. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29 * OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "autoconf.h"
33 #include <k5-int.h>
34
35 #define kMinInputLength 2
36 #define kMaxInputLength 512
37
38 #define ANAME_SZ 40
39 #define INST_SZ 40
40 #define REALM_SZ 40
41
42 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
43
44 static void
fuzz_deltat(char * data_in)45 fuzz_deltat(char *data_in)
46 {
47 krb5_deltat result;
48 krb5_string_to_deltat(data_in, &result);
49 }
50
51 static void
fuzz_host_string(char * data_in)52 fuzz_host_string(char *data_in)
53 {
54 krb5_error_code ret;
55 char *host;
56 int port = -1;
57
58 ret = k5_parse_host_string(data_in, 0, &host, &port);
59 if (!ret)
60 free(host);
61 }
62
63 static void
fuzz_princ(krb5_context context,char * data_in)64 fuzz_princ(krb5_context context, char *data_in)
65 {
66 krb5_error_code ret;
67 krb5_principal p;
68 char *princ;
69
70 ret = krb5_parse_name(context, data_in, &p);
71 if (ret)
72 return;
73
74 ret = krb5_unparse_name(context, p, &princ);
75 if (!ret)
76 free(princ);
77
78 krb5_free_principal(context, p);
79 }
80
81 static void
fuzz_principal_425(krb5_context context,char * data_in)82 fuzz_principal_425(krb5_context context, char *data_in)
83 {
84 krb5_principal princ;
85 krb5_425_conv_principal(context, data_in, data_in, data_in, &princ);
86 krb5_free_principal(context, princ);
87 }
88
89 static void
fuzz_principal_524(krb5_context context,char * data_in)90 fuzz_principal_524(krb5_context context, char *data_in)
91 {
92 krb5_error_code ret;
93 krb5_principal princ = 0;
94 char aname[ANAME_SZ + 1], inst[INST_SZ + 1], realm[REALM_SZ + 1];
95
96 aname[ANAME_SZ] = inst[INST_SZ] = realm[REALM_SZ] = 0;
97
98 ret = krb5_parse_name(context, data_in, &princ);
99 if (ret)
100 return;
101
102 krb5_524_conv_principal(context, princ, aname, inst, realm);
103 krb5_free_principal(context, princ);
104 }
105
106 static void
fuzz_timestamp(char * data_in)107 fuzz_timestamp(char *data_in)
108 {
109 krb5_error_code ret;
110 krb5_timestamp timestamp;
111
112 ret = krb5_string_to_timestamp(data_in, ×tamp);
113 if (!ret)
114 ts2tt(timestamp);
115 }
116
117 /*
118 * data_in is going to be modified during parsing.
119 */
120 static void
fuzz_enctype_list(char * data_in)121 fuzz_enctype_list(char *data_in)
122 {
123 krb5_error_code ret;
124 krb5_context context;
125 krb5_enctype *ienc, zero = 0;
126
127 ret = krb5_init_context(&context);
128 if (ret)
129 return;
130
131 ret = krb5int_parse_enctype_list(context, "", data_in, &zero, &ienc);
132 if (!ret)
133 free(ienc);
134
135 krb5_free_context(context);
136 }
137
138 extern int
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)139 LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
140 {
141 krb5_error_code ret;
142 krb5_context context = NULL;
143 char *data_in;
144
145 if (size < kMinInputLength || size > kMaxInputLength)
146 return 0;
147
148 ret = krb5_init_context(&context);
149 if (ret)
150 return 0;
151
152 data_in = k5memdup0(data, size, &ret);
153 if (ret)
154 goto cleanup;
155
156 fuzz_deltat(data_in);
157 fuzz_host_string(data_in);
158 fuzz_princ(context, data_in);
159 fuzz_principal_425(context, data_in);
160 fuzz_principal_524(context, data_in);
161 fuzz_timestamp(data_in);
162 fuzz_enctype_list(data_in);
163
164 free(data_in);
165
166 cleanup:
167 krb5_free_context(context);
168
169 return 0;
170 }
171