xref: /freebsd/crypto/krb5/src/tests/fuzzing/fuzz_asn.c (revision f1c4c3daccbaf3820f0e2224de53df12fc952fcc)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* tests/fuzzing/fuzz_asn.c - fuzzing harness for ASN.1 encoding/decoding */
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-spake.h>
34 
35 #define kMinInputLength 2
36 #define kMaxInputLength 2048
37 
38 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
39 
40 static void
free_cred_enc_part_whole(krb5_context ctx,krb5_cred_enc_part * val)41 free_cred_enc_part_whole(krb5_context ctx, krb5_cred_enc_part *val)
42 {
43     krb5_free_cred_enc_part(ctx, val);
44     free(val);
45 }
46 
47 static void
free_kkdcp_message(krb5_context context,krb5_kkdcp_message * val)48 free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val)
49 {
50     if (val == NULL)
51         return;
52     free(val->kerb_message.data);
53     free(val->target_domain.data);
54     free(val);
55 }
56 
57 #define FUZZ_ASAN(type, encoder, decoder, freefn) do {   \
58         type *v;                                         \
59         krb5_data *data_out = NULL;                      \
60                                                          \
61         if ((*decoder)(&data_in, &v) != 0)               \
62             break;                                       \
63                                                          \
64         (*encoder)(v, &data_out);                        \
65         krb5_free_data(context, data_out);               \
66         (*freefn)(context, v);                           \
67     } while (0)
68 
69 int
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)70 LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
71 {
72     krb5_context context;
73     krb5_data data_in;
74 
75     if (size < kMinInputLength || size > kMaxInputLength)
76         return 0;
77 
78     if (krb5_init_context(&context))
79         return 0;
80 
81     data_in = make_data((void *)data, size);
82 
83     /* Adapted from krb5_decode_leak.c */
84     FUZZ_ASAN(krb5_authenticator, encode_krb5_authenticator,
85               decode_krb5_authenticator, krb5_free_authenticator);
86     FUZZ_ASAN(krb5_ticket, encode_krb5_ticket, decode_krb5_ticket,
87               krb5_free_ticket);
88     FUZZ_ASAN(krb5_keyblock, encode_krb5_encryption_key,
89               decode_krb5_encryption_key, krb5_free_keyblock);
90     FUZZ_ASAN(krb5_enc_tkt_part, encode_krb5_enc_tkt_part,
91               decode_krb5_enc_tkt_part, krb5_free_enc_tkt_part);
92     FUZZ_ASAN(krb5_enc_kdc_rep_part, encode_krb5_enc_kdc_rep_part,
93               decode_krb5_enc_kdc_rep_part, krb5_free_enc_kdc_rep_part);
94     FUZZ_ASAN(krb5_kdc_rep, encode_krb5_as_rep, decode_krb5_as_rep,
95               krb5_free_kdc_rep);
96     FUZZ_ASAN(krb5_kdc_rep, encode_krb5_tgs_rep, decode_krb5_tgs_rep,
97               krb5_free_kdc_rep);
98     FUZZ_ASAN(krb5_ap_req, encode_krb5_ap_req, decode_krb5_ap_req,
99               krb5_free_ap_req);
100     FUZZ_ASAN(krb5_ap_rep, encode_krb5_ap_rep, decode_krb5_ap_rep,
101               krb5_free_ap_rep);
102     FUZZ_ASAN(krb5_ap_rep_enc_part, encode_krb5_ap_rep_enc_part,
103               decode_krb5_ap_rep_enc_part, krb5_free_ap_rep_enc_part);
104     FUZZ_ASAN(krb5_kdc_req, encode_krb5_as_req, decode_krb5_as_req,
105               krb5_free_kdc_req);
106     FUZZ_ASAN(krb5_kdc_req, encode_krb5_tgs_req, decode_krb5_tgs_req,
107               krb5_free_kdc_req);
108     FUZZ_ASAN(krb5_kdc_req, encode_krb5_kdc_req_body, decode_krb5_kdc_req_body,
109               krb5_free_kdc_req);
110     FUZZ_ASAN(krb5_safe, encode_krb5_safe, decode_krb5_safe, krb5_free_safe);
111     FUZZ_ASAN(krb5_priv, encode_krb5_priv, decode_krb5_priv, krb5_free_priv);
112     FUZZ_ASAN(krb5_priv_enc_part, encode_krb5_enc_priv_part,
113               decode_krb5_enc_priv_part, krb5_free_priv_enc_part);
114     FUZZ_ASAN(krb5_cred, encode_krb5_cred, decode_krb5_cred, krb5_free_cred);
115     FUZZ_ASAN(krb5_cred_enc_part, encode_krb5_enc_cred_part,
116               decode_krb5_enc_cred_part, free_cred_enc_part_whole);
117     FUZZ_ASAN(krb5_error, encode_krb5_error, decode_krb5_error,
118               krb5_free_error);
119     FUZZ_ASAN(krb5_authdata *, encode_krb5_authdata, decode_krb5_authdata,
120               krb5_free_authdata);
121     FUZZ_ASAN(krb5_pa_data *, encode_krb5_padata_sequence,
122               decode_krb5_padata_sequence, krb5_free_pa_data);
123     FUZZ_ASAN(krb5_pa_data *, encode_krb5_typed_data,
124               decode_krb5_typed_data, krb5_free_pa_data);
125     FUZZ_ASAN(krb5_etype_info_entry *, encode_krb5_etype_info,
126               decode_krb5_etype_info, krb5_free_etype_info);
127     FUZZ_ASAN(krb5_etype_info_entry *, encode_krb5_etype_info2,
128               decode_krb5_etype_info2, krb5_free_etype_info);
129     FUZZ_ASAN(krb5_pa_enc_ts, encode_krb5_pa_enc_ts, decode_krb5_pa_enc_ts,
130               krb5_free_pa_enc_ts);
131     FUZZ_ASAN(krb5_enc_data, encode_krb5_enc_data, decode_krb5_enc_data,
132               krb5_free_enc_data);
133     FUZZ_ASAN(krb5_sam_challenge_2, encode_krb5_sam_challenge_2,
134               decode_krb5_sam_challenge_2, krb5_free_sam_challenge_2);
135     FUZZ_ASAN(krb5_sam_challenge_2_body, encode_krb5_sam_challenge_2_body,
136               decode_krb5_sam_challenge_2_body,
137               krb5_free_sam_challenge_2_body);
138     FUZZ_ASAN(krb5_sam_response_2, encode_krb5_sam_response_2,
139               decode_krb5_sam_response_2, krb5_free_sam_response_2);
140     FUZZ_ASAN(krb5_enc_sam_response_enc_2, encode_krb5_enc_sam_response_enc_2,
141               decode_krb5_enc_sam_response_enc_2,
142               krb5_free_enc_sam_response_enc_2);
143     FUZZ_ASAN(krb5_pa_for_user, encode_krb5_pa_for_user,
144               decode_krb5_pa_for_user, krb5_free_pa_for_user);
145     FUZZ_ASAN(krb5_pa_s4u_x509_user, encode_krb5_pa_s4u_x509_user,
146               decode_krb5_pa_s4u_x509_user, krb5_free_pa_s4u_x509_user);
147     FUZZ_ASAN(krb5_ad_kdcissued, encode_krb5_ad_kdcissued,
148               decode_krb5_ad_kdcissued, krb5_free_ad_kdcissued);
149     FUZZ_ASAN(krb5_iakerb_header, encode_krb5_iakerb_header,
150               decode_krb5_iakerb_header, krb5_free_iakerb_header);
151     FUZZ_ASAN(krb5_iakerb_finished, encode_krb5_iakerb_finished,
152               decode_krb5_iakerb_finished, krb5_free_iakerb_finished);
153     FUZZ_ASAN(krb5_fast_response, encode_krb5_fast_response,
154               decode_krb5_fast_response, krb5_free_fast_response);
155     FUZZ_ASAN(krb5_enc_data, encode_krb5_pa_fx_fast_reply,
156               decode_krb5_pa_fx_fast_reply, krb5_free_enc_data);
157 
158     /* Adapted from krb5_encode_test.c */
159     FUZZ_ASAN(krb5_otp_tokeninfo, encode_krb5_otp_tokeninfo,
160               decode_krb5_otp_tokeninfo, k5_free_otp_tokeninfo);
161     FUZZ_ASAN(krb5_pa_otp_challenge, encode_krb5_pa_otp_challenge,
162               decode_krb5_pa_otp_challenge, k5_free_pa_otp_challenge);
163     FUZZ_ASAN(krb5_pa_otp_req, encode_krb5_pa_otp_req, decode_krb5_pa_otp_req,
164               k5_free_pa_otp_req);
165     FUZZ_ASAN(krb5_data, encode_krb5_pa_otp_enc_req,
166               decode_krb5_pa_otp_enc_req, krb5_free_data);
167     FUZZ_ASAN(krb5_kkdcp_message, encode_krb5_kkdcp_message,
168               decode_krb5_kkdcp_message, free_kkdcp_message);
169     FUZZ_ASAN(krb5_cammac, encode_krb5_cammac, decode_krb5_cammac,
170               k5_free_cammac);
171     FUZZ_ASAN(krb5_secure_cookie, encode_krb5_secure_cookie,
172               decode_krb5_secure_cookie, k5_free_secure_cookie);
173     FUZZ_ASAN(krb5_spake_factor, encode_krb5_spake_factor,
174               decode_krb5_spake_factor, k5_free_spake_factor);
175     FUZZ_ASAN(krb5_pa_spake, encode_krb5_pa_spake, decode_krb5_pa_spake,
176               k5_free_pa_spake);
177 
178     /* Adapted from krb5_decode_test.c */
179     {
180         krb5_pa_pac_req *pa_pac_req = NULL;
181 
182         if (decode_krb5_pa_pac_req(&data_in, &pa_pac_req) == 0)
183             free(pa_pac_req);
184     }
185 
186     krb5_free_context(context);
187     return 0;
188 }
189