xref: /freebsd/crypto/krb5/src/kdc/t_ndr.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* kdc/t_ndr.c - tests for ndr.c */
3 /*
4  * Copyright (C) 2021 by Red Hat, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  *
14  * * Redistributions in binary form must reproduce the above copyright
15  *   notice, this list of conditions and the following disclaimer in
16  *   the documentation and/or other materials provided with the
17  *   distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30  * OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Unit tests for the NDR marshalling/unmarshalling in ndr.c
35  */
36 
37 #include "k5-int.h"
38 #include "kdc_util.h"
39 
40 /*
41  * Three S4U_DELEGATION_INFO buffers decoded from communication with AD 2019:
42  *
43  * - svc1/adserver.ad.test@AD.TEST to svc2/adserver.ad.test@AD.TEST
44  * - svc1/adserver.ad.test@AD.TEST to longsvc/adserver.ad.test@AD.TEST
45  * - svc1/adserver.ad.test@AD.TEST to svc2/adserver.ad.test@AD.TEST then
46  *                                 to longsvc/adserver.ad.test@AD.TEST
47  */
48 static uint8_t s4u_di_short[] = {
49     0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xa0, 0x00, 0x00, 0x00,
50     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x2a, 0x00, 0x2c, 0x00,
51     0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
52     0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
53     0x73, 0x00, 0x76, 0x00, 0x63, 0x00, 0x32, 0x00, 0x2f, 0x00, 0x61, 0x00,
54     0x64, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00,
55     0x72, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00,
56     0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
57     0x3a, 0x00, 0x3c, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x00,
58     0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x73, 0x00, 0x76, 0x00,
59     0x63, 0x00, 0x31, 0x00, 0x2f, 0x00, 0x61, 0x00, 0x64, 0x00, 0x73, 0x00,
60     0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x2e, 0x00,
61     0x61, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00,
62     0x74, 0x00, 0x40, 0x00, 0x41, 0x00, 0x44, 0x00, 0x2e, 0x00, 0x54, 0x00,
63     0x45, 0x00, 0x53, 0x00, 0x54, 0x00, 0x00, 0x00,
64 };
65 
66 static uint8_t s4u_di_long[] = {
67     0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xa8, 0x00, 0x00, 0x00,
68     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x32, 0x00,
69     0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
70     0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
71     0x6c, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x73, 0x00, 0x76, 0x00,
72     0x63, 0x00, 0x2f, 0x00, 0x61, 0x00, 0x64, 0x00, 0x73, 0x00, 0x65, 0x00,
73     0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x2e, 0x00, 0x61, 0x00,
74     0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
75     0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x3c, 0x00, 0x0c, 0x00, 0x02, 0x00,
76     0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
77     0x73, 0x00, 0x76, 0x00, 0x63, 0x00, 0x31, 0x00, 0x2f, 0x00, 0x61, 0x00,
78     0x64, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00,
79     0x72, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00,
80     0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x40, 0x00, 0x41, 0x00, 0x44, 0x00,
81     0x2e, 0x00, 0x54, 0x00, 0x45, 0x00, 0x53, 0x00, 0x54, 0x00, 0x00, 0x00,
82     0x00, 0x00, 0x00, 0x00,
83 };
84 
85 static uint8_t s4u_di_double[] = {
86     0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xf8, 0x00, 0x00, 0x00,
87     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x32, 0x00,
88     0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00,
89     0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
90     0x6c, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x73, 0x00, 0x76, 0x00,
91     0x63, 0x00, 0x2f, 0x00, 0x61, 0x00, 0x64, 0x00, 0x73, 0x00, 0x65, 0x00,
92     0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x2e, 0x00, 0x61, 0x00,
93     0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
94     0x02, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x3c, 0x00, 0x0c, 0x00, 0x02, 0x00,
95     0x3a, 0x00, 0x3c, 0x00, 0x10, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x00,
96     0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x73, 0x00, 0x76, 0x00,
97     0x63, 0x00, 0x31, 0x00, 0x2f, 0x00, 0x61, 0x00, 0x64, 0x00, 0x73, 0x00,
98     0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x2e, 0x00,
99     0x61, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00,
100     0x74, 0x00, 0x40, 0x00, 0x41, 0x00, 0x44, 0x00, 0x2e, 0x00, 0x54, 0x00,
101     0x45, 0x00, 0x53, 0x00, 0x54, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
102     0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x73, 0x00, 0x76, 0x00,
103     0x63, 0x00, 0x32, 0x00, 0x2f, 0x00, 0x61, 0x00, 0x64, 0x00, 0x73, 0x00,
104     0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x2e, 0x00,
105     0x61, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00,
106     0x74, 0x00, 0x40, 0x00, 0x41, 0x00, 0x44, 0x00, 0x2e, 0x00, 0x54, 0x00,
107     0x45, 0x00, 0x53, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 };
109 
110 static uint8_t fuzz1[] = {
111     0x01, 0x10, 0x08, 0x20, 0x20, 0x20, 0x20, 0x20, 0x24, 0x00, 0x00, 0x00,
112     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
113     0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0xff, 0xff,
114     0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
115     0x20, 0x20, 0x20, 0x20
116 };
117 
118 static uint8_t fuzz2[] = {
119     0x01, 0x10, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0x24, 0x00, 0x00, 0x00,
120     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121     0x00, 0x1e, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x16, 0x00, 0x00,
122     0x1e, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123     0x00, 0x00, 0x00, 0x1e
124 };
125 
126 static void
test_dec_enc(uint8_t * blob,size_t len,char * name,int fail)127 test_dec_enc(uint8_t *blob, size_t len, char *name, int fail)
128 {
129     krb5_data data_in, data_out;
130     struct pac_s4u_delegation_info *di = NULL;
131     krb5_error_code ret;
132     int eq;
133     size_t i;
134 
135     printf("Checking blob %s...\n", name);
136 
137     data_in = make_data(blob, len);
138     ret = ndr_dec_delegation_info(&data_in, &di);
139     if (fail) {
140         if (!ret) {
141             printf("%s: unexpected decode success\n", name);
142             exit(1);
143         }
144         printf("%s: failed as expected\n", name);
145         return;
146     } else if (ret) {
147         printf("%s: bad decode (%d): %s\n", name, ret, strerror(ret));
148         exit(1);
149     }
150 
151     printf("%s, %d\n", di->proxy_target, di->transited_services_length);
152     for (i = 0; i < di->transited_services_length; i++)
153         printf("    %s\n", di->transited_services[i]);
154 
155     ret = ndr_enc_delegation_info(di, &data_out);
156     ndr_free_delegation_info(di);
157     if (ret) {
158         printf("%s: bad encode (%d): %s\n", name, ret, strerror(ret));
159         exit(1);
160     }
161 
162     eq = data_eq(data_in, data_out);
163     krb5_free_data_contents(NULL, &data_out);
164     if (!eq) {
165         printf("%s: re-encoding did not produce the same result\n", name);
166         exit(1);
167     }
168 
169     printf("%s matched\n\n", name);
170 }
171 
172 #define RUN_TEST(blob) test_dec_enc(blob, sizeof(blob), #blob, 0)
173 #define RUN_TEST_FAIL(blob) test_dec_enc(blob, sizeof(blob), #blob, 1)
174 
175 int
main()176 main()
177 {
178     printf("Running NDR tests...\n");
179 
180     RUN_TEST(s4u_di_short);
181     RUN_TEST(s4u_di_long);
182     RUN_TEST(s4u_di_double);
183     RUN_TEST_FAIL(fuzz1);
184     RUN_TEST_FAIL(fuzz2);
185 
186     printf("Passed NDR tests\n");
187     return 0;
188 }
189