1/*	$NetBSD: test_pac.c,v 1.2 2017/01/28 21:31:49 christos Exp $	*/
2
3/*
4 * Copyright (c) 2006 Kungliga Tekniska H��gskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Institute nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include "krb5_locl.h"
37
38/*
39 * This PAC and keys are copied (with permission) from Samba torture
40 * regression test suite, they where created by Andrew Bartlet.
41 */
42
43static const unsigned char saved_pac[] = {
44	0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00,
45	0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
46	0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
47	0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
48	0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
49	0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb,
50	0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff,
51	0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
52	0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
53	0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
54	0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
55	0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00,
56	0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
57	0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58	0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
59	0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60	0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62	0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63	0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
64	0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
65	0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
70	0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
71	0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
72	0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
73	0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
74	0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
75	0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
76	0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
77	0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78	0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
79	0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
80	0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
81	0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
82	0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
83};
84
85static int type_1_length = 472;
86
87static const krb5_keyblock kdc_keyblock = {
88    ETYPE_ARCFOUR_HMAC_MD5,
89    { 16, "\xB2\x86\x75\x71\x48\xAF\x7F\xD2\x52\xC5\x36\x03\xA1\x50\xB7\xE7" }
90};
91
92static const krb5_keyblock member_keyblock = {
93    ETYPE_ARCFOUR_HMAC_MD5,
94    { 16, "\xD2\x17\xFA\xEA\xE5\xE6\xB5\xF9\x5C\xCC\x94\x07\x7A\xB8\xA5\xFC" }
95};
96
97static time_t authtime = 1120440609;
98static const char *user = "w2003final$";
99
100/*
101 * This pac from Christan Krause
102 */
103
104static const unsigned char saved_pac2[] =
105    "\x05\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\xc8\x01\x00\x00"
106    "\x58\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x18\x00\x00\x00"
107    "\x20\x02\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x70\x00\x00\x00"
108    "\x38\x02\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x14\x00\x00\x00"
109    "\xa8\x02\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x14\x00\x00\x00"
110    "\xc0\x02\x00\x00\x00\x00\x00\x00\x01\x10\x08\x00\xcc\xcc\xcc\xcc"
111    "\xb8\x01\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x7d\xee\x09\x76"
112    "\xf2\x39\xc9\x01\xff\xff\xff\xff\xff\xff\xff\x7f\xff\xff\xff\xff"
113    "\xff\xff\xff\x7f\x6d\x49\x38\x62\xf2\x39\xc9\x01\x6d\x09\xa2\x8c"
114    "\xbb\x3a\xc9\x01\xff\xff\xff\xff\xff\xff\xff\x7f\x0e\x00\x0e\x00"
115    "\x04\x00\x02\x00\x10\x00\x10\x00\x08\x00\x02\x00\x00\x00\x00\x00"
116    "\x0c\x00\x02\x00\x00\x00\x00\x00\x10\x00\x02\x00\x00\x00\x00\x00"
117    "\x14\x00\x02\x00\x00\x00\x00\x00\x18\x00\x02\x00\x02\x01\x00\x00"
118    "\x52\x04\x00\x00\x01\x02\x00\x00\x03\x00\x00\x00\x1c\x00\x02\x00"
119    "\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
120    "\x00\x00\x00\x00\x10\x00\x12\x00\x20\x00\x02\x00\x0e\x00\x10\x00"
121    "\x24\x00\x02\x00\x28\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00"
122    "\x10\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
123    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
124    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
125    "\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00"
126    "\x6f\x00\x70\x00\x65\x00\x6e\x00\x6d\x00\x73\x00\x70\x00\x00\x00"
127    "\x08\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x6f\x00\x70\x00"
128    "\x65\x00\x6e\x00\x20\x00\x6d\x00\x73\x00\x70\x00\x00\x00\x00\x00"
129    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
130    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
131    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00"
132    "\x60\x04\x00\x00\x07\x00\x00\x00\x01\x02\x00\x00\x07\x00\x00\x00"
133    "\x5e\x04\x00\x00\x07\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00"
134    "\x08\x00\x00\x00\x43\x00\x48\x00\x4b\x00\x52\x00\x2d\x00\x41\x00"
135    "\x44\x00\x53\x00\x08\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00"
136    "\x4d\x00\x53\x00\x50\x00\x2d\x00\x41\x00\x44\x00\x53\x00\x00\x00"
137    "\x04\x00\x00\x00\x01\x04\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00"
138    "\x91\xad\xdc\x4c\x63\xb8\xb5\x48\xd5\x53\xd2\xd1\x00\x00\x00\x00"
139    "\x00\x66\xeb\x75\xf2\x39\xc9\x01\x0e\x00\x6f\x00\x70\x00\x65\x00"
140    "\x6e\x00\x6d\x00\x73\x00\x70\x00\x38\x00\x10\x00\x28\x00\x48\x00"
141    "\x00\x00\x00\x00\x00\x00\x00\x00\x6f\x00\x70\x00\x65\x00\x6e\x00"
142    "\x6d\x00\x73\x00\x70\x00\x40\x00\x6d\x00\x73\x00\x70\x00\x2d\x00"
143    "\x61\x00\x64\x00\x73\x00\x2e\x00\x70\x00\x65\x00\x70\x00\x70\x00"
144    "\x65\x00\x72\x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x64\x00\x65\x00"
145    "\x4d\x00\x53\x00\x50\x00\x2d\x00\x41\x00\x44\x00\x53\x00\x2e\x00"
146    "\x50\x00\x45\x00\x50\x00\x50\x00\x45\x00\x52\x00\x43\x00\x4f\x00"
147    "\x4e\x00\x2e\x00\x44\x00\x45\x00\x76\xff\xff\xff\xb3\x56\x15\x29"
148    "\x37\xc6\x5c\xf7\x97\x35\xfa\xec\x59\xe8\x96\xa0\x00\x00\x00\x00"
149    "\x76\xff\xff\xff\x50\x71\xa2\xb1\xa3\x64\x82\x5c\xfd\x23\xea\x3b"
150    "\xb0\x19\x12\xd4\x00\x00\x00\x00";
151
152
153static const krb5_keyblock member_keyblock2 = {
154    ETYPE_DES_CBC_MD5,
155    { 8, "\x9e\x37\x83\x25\x4a\x7f\xf2\xf8" }
156};
157
158static time_t authtime2 = 1225304188;
159static const char *user2 = "openmsp";
160
161
162
163int
164main(int argc, char **argv)
165{
166    krb5_error_code ret;
167    krb5_context context;
168    krb5_pac pac;
169    krb5_data data;
170    krb5_principal p, p2;
171
172    ret = krb5_init_context(&context);
173    if (ret)
174	errx(1, "krb5_init_contex");
175
176    krb5_enctype_enable(context, ETYPE_DES_CBC_MD5);
177
178    ret = krb5_parse_name_flags(context, user,
179				KRB5_PRINCIPAL_PARSE_NO_REALM, &p);
180    if (ret)
181	krb5_err(context, 1, ret, "krb5_parse_name");
182
183    ret = krb5_pac_parse(context, saved_pac, sizeof(saved_pac), &pac);
184    if (ret)
185	krb5_err(context, 1, ret, "krb5_pac_parse");
186
187    ret = krb5_pac_verify(context, pac, authtime, p,
188			   &member_keyblock, &kdc_keyblock);
189    if (ret)
190	krb5_err(context, 1, ret, "krb5_pac_verify");
191
192    ret = _krb5_pac_sign(context, pac, authtime, p,
193			 &member_keyblock, &kdc_keyblock, &data);
194    if (ret)
195	krb5_err(context, 1, ret, "_krb5_pac_sign");
196
197    krb5_pac_free(context, pac);
198
199    ret = krb5_pac_parse(context, data.data, data.length, &pac);
200    krb5_data_free(&data);
201    if (ret)
202	krb5_err(context, 1, ret, "krb5_pac_parse 2");
203
204    ret = krb5_pac_verify(context, pac, authtime, p,
205			   &member_keyblock, &kdc_keyblock);
206    if (ret)
207	krb5_err(context, 1, ret, "krb5_pac_verify 2");
208
209    /* make a copy and try to reproduce it */
210    {
211	uint32_t *list;
212	size_t len, i;
213	krb5_pac pac2;
214
215	ret = krb5_pac_init(context, &pac2);
216	if (ret)
217	    krb5_err(context, 1, ret, "krb5_pac_init");
218
219	/* our two user buffer plus the three "system" buffers */
220	ret = krb5_pac_get_types(context, pac, &len, &list);
221	if (ret)
222	    krb5_err(context, 1, ret, "krb5_pac_get_types");
223
224	for (i = 0; i < len; i++) {
225	    /* skip server_cksum, privsvr_cksum, and logon_name */
226	    if (list[i] == 6 || list[i] == 7 || list[i] == 10)
227		continue;
228
229	    ret = krb5_pac_get_buffer(context, pac, list[i], &data);
230	    if (ret)
231		krb5_err(context, 1, ret, "krb5_pac_get_buffer");
232
233	    if (list[i] == 1) {
234		if (type_1_length != data.length)
235		    krb5_errx(context, 1, "type 1 have wrong length: %lu",
236			      (unsigned long)data.length);
237	    } else
238		krb5_errx(context, 1, "unknown type %lu",
239			  (unsigned long)list[i]);
240
241	    ret = krb5_pac_add_buffer(context, pac2, list[i], &data);
242	    if (ret)
243		krb5_err(context, 1, ret, "krb5_pac_add_buffer");
244	    krb5_data_free(&data);
245	}
246	free(list);
247
248	ret = _krb5_pac_sign(context, pac2, authtime, p,
249			     &member_keyblock, &kdc_keyblock, &data);
250	if (ret)
251	    krb5_err(context, 1, ret, "_krb5_pac_sign 4");
252
253	krb5_pac_free(context, pac2);
254
255	ret = krb5_pac_parse(context, data.data, data.length, &pac2);
256	krb5_data_free(&data);
257	if (ret)
258	    krb5_err(context, 1, ret, "krb5_pac_parse 4");
259
260	ret = krb5_pac_verify(context, pac2, authtime, p,
261			      &member_keyblock, &kdc_keyblock);
262	if (ret)
263	    krb5_err(context, 1, ret, "krb5_pac_verify 4");
264
265	krb5_pac_free(context, pac2);
266    }
267
268    krb5_pac_free(context, pac);
269
270    /*
271     * check pac from Christian
272     */
273
274    ret = krb5_parse_name_flags(context, user2,
275				KRB5_PRINCIPAL_PARSE_NO_REALM, &p2);
276    if (ret)
277	krb5_err(context, 1, ret, "krb5_parse_name");
278
279    ret = krb5_pac_parse(context, saved_pac2, sizeof(saved_pac2) -1, &pac);
280    if (ret)
281	krb5_err(context, 1, ret, "krb5_pac_parse");
282
283    ret = krb5_pac_verify(context, pac, authtime2, p2,
284			   &member_keyblock2, NULL);
285    if (ret)
286	krb5_err(context, 1, ret, "krb5_pac_verify c1");
287
288    krb5_pac_free(context, pac);
289    krb5_free_principal(context, p2);
290
291    /*
292     * Test empty free
293     */
294
295    ret = krb5_pac_init(context, &pac);
296    if (ret)
297	krb5_err(context, 1, ret, "krb5_pac_init");
298    krb5_pac_free(context, pac);
299
300    /*
301     * Test add remove buffer
302     */
303
304    ret = krb5_pac_init(context, &pac);
305    if (ret)
306	krb5_err(context, 1, ret, "krb5_pac_init");
307
308    {
309	const krb5_data cdata = { 2, "\x00\x01" } ;
310
311	ret = krb5_pac_add_buffer(context, pac, 1, &cdata);
312	if (ret)
313	    krb5_err(context, 1, ret, "krb5_pac_add_buffer");
314    }
315    {
316	ret = krb5_pac_get_buffer(context, pac, 1, &data);
317	if (ret)
318	    krb5_err(context, 1, ret, "krb5_pac_get_buffer");
319	if (data.length != 2 || memcmp(data.data, "\x00\x01", 2) != 0)
320	    krb5_errx(context, 1, "krb5_pac_get_buffer data not the same");
321	krb5_data_free(&data);
322    }
323
324    {
325	const krb5_data cdata = { 2, "\x02\x00" } ;
326
327	ret = krb5_pac_add_buffer(context, pac, 2, &cdata);
328	if (ret)
329	    krb5_err(context, 1, ret, "krb5_pac_add_buffer");
330    }
331    {
332	ret = krb5_pac_get_buffer(context, pac, 1, &data);
333	if (ret)
334	    krb5_err(context, 1, ret, "krb5_pac_get_buffer");
335	if (data.length != 2 || memcmp(data.data, "\x00\x01", 2) != 0)
336	    krb5_errx(context, 1, "krb5_pac_get_buffer data not the same");
337	krb5_data_free(&data);
338	/* */
339	ret = krb5_pac_get_buffer(context, pac, 2, &data);
340	if (ret)
341	    krb5_err(context, 1, ret, "krb5_pac_get_buffer");
342	if (data.length != 2 || memcmp(data.data, "\x02\x00", 2) != 0)
343	    krb5_errx(context, 1, "krb5_pac_get_buffer data not the same");
344	krb5_data_free(&data);
345    }
346
347    ret = _krb5_pac_sign(context, pac, authtime, p,
348			 &member_keyblock, &kdc_keyblock, &data);
349    if (ret)
350	krb5_err(context, 1, ret, "_krb5_pac_sign");
351
352    krb5_pac_free(context, pac);
353
354    ret = krb5_pac_parse(context, data.data, data.length, &pac);
355    krb5_data_free(&data);
356    if (ret)
357	krb5_err(context, 1, ret, "krb5_pac_parse 3");
358
359    ret = krb5_pac_verify(context, pac, authtime, p,
360			   &member_keyblock, &kdc_keyblock);
361    if (ret)
362	krb5_err(context, 1, ret, "krb5_pac_verify 3");
363
364    {
365	uint32_t *list;
366	size_t len;
367
368	/* our two user buffer plus the three "system" buffers */
369	ret = krb5_pac_get_types(context, pac, &len, &list);
370	if (ret)
371	    krb5_err(context, 1, ret, "krb5_pac_get_types");
372	if (len != 5)
373	    krb5_errx(context, 1, "list wrong length");
374	free(list);
375    }
376
377    krb5_pac_free(context, pac);
378
379    krb5_free_principal(context, p);
380    krb5_free_context(context);
381
382    return 0;
383}
384