xref: /freebsd/crypto/krb5/src/tests/fuzzing/fuzz_krb.c (revision f1c4c3daccbaf3820f0e2224de53df12fc952fcc)
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, &timestamp);
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