Imported Upstream version 1.15.1
[platform/upstream/krb5.git] / src / lib / krb5 / krb / kfree.c
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/kfree.c */
3 /*
4  * Copyright 1990-1998, 2009 by the Massachusetts Institute of Technology.
5  *
6  * Export of this software from the United States of America may
7  *   require a specific license from the United States Government.
8  *   It is the responsibility of any person or organization contemplating
9  *   export to obtain such a license before exporting.
10  *
11  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12  * distribute this software and its documentation for any purpose and
13  * without fee is hereby granted, provided that the above copyright
14  * notice appear in all copies and that both that copyright notice and
15  * this permission notice appear in supporting documentation, and that
16  * the name of M.I.T. not be used in advertising or publicity pertaining
17  * to distribution of the software without specific, written prior
18  * permission.  Furthermore if you modify this software you must label
19  * your software as modified software and not distribute it in such a
20  * fashion that it might be confused with the original M.I.T. software.
21  * M.I.T. makes no representations about the suitability of
22  * this software for any purpose.  It is provided "as is" without express
23  * or implied warranty.
24  */
25 /*
26  * Copyright (c) 2006-2008, Novell, Inc.
27  * All rights reserved.
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions are met:
31  *
32  *   * Redistributions of source code must retain the above copyright notice,
33  *       this list of conditions and the following disclaimer.
34  *   * Redistributions in binary form must reproduce the above copyright
35  *       notice, this list of conditions and the following disclaimer in the
36  *       documentation and/or other materials provided with the distribution.
37  *   * The copyright holder's name is not used to endorse or promote products
38  *       derived from this software without specific prior written permission.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
44  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
45  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
46  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
47  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
48  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
50  * POSSIBILITY OF SUCH DAMAGE.
51  */
52
53 #include "k5-int.h"
54 #include <assert.h>
55
56 void KRB5_CALLCONV
57 krb5_free_address(krb5_context context, krb5_address *val)
58 {
59     if (val == NULL)
60         return;
61     free(val->contents);
62     free(val);
63 }
64
65 void KRB5_CALLCONV
66 krb5_free_addresses(krb5_context context, krb5_address **val)
67 {
68     register krb5_address **temp;
69
70     if (val == NULL)
71         return;
72     for (temp = val; *temp; temp++) {
73         free((*temp)->contents);
74         free(*temp);
75     }
76     free(val);
77 }
78
79 void KRB5_CALLCONV
80 krb5_free_ap_rep(krb5_context context, register krb5_ap_rep *val)
81 {
82     if (val == NULL)
83         return;
84     free(val->enc_part.ciphertext.data);
85     free(val);
86 }
87
88 void KRB5_CALLCONV
89 krb5_free_ap_req(krb5_context context, register krb5_ap_req *val)
90 {
91     if (val == NULL)
92         return;
93     krb5_free_ticket(context, val->ticket);
94     free(val->authenticator.ciphertext.data);
95     free(val);
96 }
97
98 void KRB5_CALLCONV
99 krb5_free_ap_rep_enc_part(krb5_context context, krb5_ap_rep_enc_part *val)
100 {
101     if (val == NULL)
102         return;
103     krb5_free_keyblock(context, val->subkey);
104     free(val);
105 }
106
107 void KRB5_CALLCONV
108 krb5_free_authenticator_contents(krb5_context context, krb5_authenticator *val)
109 {
110     if (val == NULL)
111         return;
112     krb5_free_checksum(context, val->checksum);
113     val->checksum = 0;
114     krb5_free_principal(context, val->client);
115     val->client = 0;
116     krb5_free_keyblock(context, val->subkey);
117     val->subkey = 0;
118     krb5_free_authdata(context, val->authorization_data);
119     val->authorization_data = 0;
120 }
121
122 void KRB5_CALLCONV
123 krb5_free_authenticator(krb5_context context, krb5_authenticator *val)
124 {
125     if (val == NULL)
126         return;
127     krb5_free_authenticator_contents(context, val);
128     free(val);
129 }
130
131 void KRB5_CALLCONV
132 krb5_free_checksum(krb5_context context, register krb5_checksum *val)
133 {
134     if (val == NULL)
135         return;
136     krb5_free_checksum_contents(context, val);
137     free(val);
138 }
139
140 void KRB5_CALLCONV
141 krb5_free_checksum_contents(krb5_context context, register krb5_checksum *val)
142 {
143     if (val == NULL)
144         return;
145     free(val->contents);
146     val->contents = NULL;
147 }
148
149 void KRB5_CALLCONV
150 krb5_free_cred(krb5_context context, register krb5_cred *val)
151 {
152     if (val == NULL)
153         return;
154     krb5_free_tickets(context, val->tickets);
155     free(val->enc_part.ciphertext.data);
156     free(val);
157 }
158
159 /*
160  * krb5_free_cred_contents zeros out the session key, and then frees
161  * the credentials structures
162  */
163
164 void KRB5_CALLCONV
165 krb5_free_cred_contents(krb5_context context, krb5_creds *val)
166 {
167     if (val == NULL)
168         return;
169     krb5_free_principal(context, val->client);
170     val->client = 0;
171     krb5_free_principal(context, val->server);
172     val->server = 0;
173     krb5_free_keyblock_contents(context, &val->keyblock);
174     free(val->ticket.data);
175     val->ticket.data = 0;
176     free(val->second_ticket.data);
177     val->second_ticket.data = 0;
178     krb5_free_addresses(context, val->addresses);
179     val->addresses = 0;
180     krb5_free_authdata(context, val->authdata);
181     val->authdata = 0;
182 }
183
184 void KRB5_CALLCONV
185 krb5_free_cred_enc_part(krb5_context context, register krb5_cred_enc_part *val)
186 {
187     register krb5_cred_info **temp;
188
189     if (val == NULL)
190         return;
191     krb5_free_address(context, val->r_address);
192     val->r_address = 0;
193     krb5_free_address(context, val->s_address);
194     val->s_address = 0;
195
196     if (val->ticket_info) {
197         for (temp = val->ticket_info; *temp; temp++) {
198             krb5_free_keyblock(context, (*temp)->session);
199             krb5_free_principal(context, (*temp)->client);
200             krb5_free_principal(context, (*temp)->server);
201             krb5_free_addresses(context, (*temp)->caddrs);
202             free(*temp);
203         }
204         free(val->ticket_info);
205         val->ticket_info = 0;
206     }
207 }
208
209
210 void KRB5_CALLCONV
211 krb5_free_creds(krb5_context context, krb5_creds *val)
212 {
213     if (val == NULL)
214         return;
215     krb5_free_cred_contents(context, val);
216     free(val);
217 }
218
219
220 void KRB5_CALLCONV
221 krb5_free_data(krb5_context context, krb5_data *val)
222 {
223     if (val == NULL)
224         return;
225     free(val->data);
226     free(val);
227 }
228
229
230 void KRB5_CALLCONV
231 krb5_free_octet_data(krb5_context context, krb5_octet_data *val)
232 {
233     if (val == NULL)
234         return;
235     free(val->data);
236     free(val);
237 }
238
239 void KRB5_CALLCONV
240 krb5_free_data_contents(krb5_context context, krb5_data *val)
241 {
242     if (val == NULL)
243         return;
244     if (val->data) {
245         free(val->data);
246         val->data = 0;
247     }
248 }
249
250 void KRB5_CALLCONV
251 krb5_free_enc_data(krb5_context context, krb5_enc_data *val)
252 {
253     if (val == NULL)
254         return;
255     krb5_free_data_contents(context, &val->ciphertext);
256     free(val);
257 }
258
259 void krb5_free_etype_info(krb5_context context, krb5_etype_info info)
260 {
261     int i;
262
263     if (info == NULL)
264         return;
265     for (i=0; info[i] != NULL; i++) {
266         free(info[i]->salt);
267         krb5_free_data_contents(context, &info[i]->s2kparams);
268         free(info[i]);
269     }
270     free(info);
271 }
272
273
274 void KRB5_CALLCONV
275 krb5_free_enc_kdc_rep_part(krb5_context context, register krb5_enc_kdc_rep_part *val)
276 {
277     if (val == NULL)
278         return;
279     krb5_free_keyblock(context, val->session);
280     krb5_free_last_req(context, val->last_req);
281     krb5_free_principal(context, val->server);
282     krb5_free_addresses(context, val->caddrs);
283     krb5_free_pa_data(context, val->enc_padata);
284     free(val);
285 }
286
287 void KRB5_CALLCONV
288 krb5_free_enc_tkt_part(krb5_context context, krb5_enc_tkt_part *val)
289 {
290     if (val == NULL)
291         return;
292     krb5_free_keyblock(context, val->session);
293     krb5_free_principal(context, val->client);
294     free(val->transited.tr_contents.data);
295     krb5_free_addresses(context, val->caddrs);
296     krb5_free_authdata(context, val->authorization_data);
297     free(val);
298 }
299
300
301 void KRB5_CALLCONV
302 krb5_free_error(krb5_context context, register krb5_error *val)
303 {
304     if (val == NULL)
305         return;
306     krb5_free_principal(context, val->client);
307     krb5_free_principal(context, val->server);
308     free(val->text.data);
309     free(val->e_data.data);
310     free(val);
311 }
312
313 void KRB5_CALLCONV
314 krb5_free_kdc_rep(krb5_context context, krb5_kdc_rep *val)
315 {
316     if (val == NULL)
317         return;
318     krb5_free_pa_data(context, val->padata);
319     krb5_free_principal(context, val->client);
320     krb5_free_ticket(context, val->ticket);
321     free(val->enc_part.ciphertext.data);
322     krb5_free_enc_kdc_rep_part(context, val->enc_part2);
323     free(val);
324 }
325
326
327 void KRB5_CALLCONV
328 krb5_free_kdc_req(krb5_context context, krb5_kdc_req *val)
329 {
330     if (val == NULL)
331         return;
332     krb5_free_pa_data(context, val->padata);
333     krb5_free_principal(context, val->client);
334     krb5_free_principal(context, val->server);
335     free(val->ktype);
336     krb5_free_addresses(context, val->addresses);
337     free(val->authorization_data.ciphertext.data);
338     krb5_free_authdata(context, val->unenc_authdata);
339     krb5_free_tickets(context, val->second_ticket);
340     free(val);
341 }
342
343 void KRB5_CALLCONV
344 krb5_free_keyblock_contents(krb5_context context, register krb5_keyblock *key)
345 {
346     krb5int_c_free_keyblock_contents (context, key);
347 }
348
349 void KRB5_CALLCONV
350 krb5_free_keyblock(krb5_context context, register krb5_keyblock *val)
351 {
352     krb5int_c_free_keyblock (context, val);
353 }
354
355
356
357 void KRB5_CALLCONV
358 krb5_free_last_req(krb5_context context, krb5_last_req_entry **val)
359 {
360     register krb5_last_req_entry **temp;
361
362     if (val == NULL)
363         return;
364     for (temp = val; *temp; temp++)
365         free(*temp);
366     free(val);
367 }
368
369 void
370 k5_zapfree_pa_data(krb5_pa_data **val)
371 {
372     krb5_pa_data **pa;
373
374     if (val == NULL)
375         return;
376     for (pa = val; *pa != NULL; pa++) {
377         zapfree((*pa)->contents, (*pa)->length);
378         zapfree(*pa, sizeof(**pa));
379     }
380     free(val);
381 }
382
383 void KRB5_CALLCONV
384 krb5_free_pa_data(krb5_context context, krb5_pa_data **val)
385 {
386     register krb5_pa_data **temp;
387
388     if (val == NULL)
389         return;
390     for (temp = val; *temp; temp++) {
391         free((*temp)->contents);
392         free(*temp);
393     }
394     free(val);
395 }
396
397 void KRB5_CALLCONV
398 krb5_free_principal(krb5_context context, krb5_principal val)
399 {
400     register krb5_int32 i;
401
402     if (!val)
403         return;
404
405     if (val->data) {
406         i = val->length;
407         while(--i >= 0)
408             free(val->data[i].data);
409         free(val->data);
410     }
411     free(val->realm.data);
412     free(val);
413 }
414
415 void KRB5_CALLCONV
416 krb5_free_priv(krb5_context context, register krb5_priv *val)
417 {
418     if (val == NULL)
419         return;
420     free(val->enc_part.ciphertext.data);
421     free(val);
422 }
423
424 void KRB5_CALLCONV
425 krb5_free_priv_enc_part(krb5_context context, register krb5_priv_enc_part *val)
426 {
427     if (val == NULL)
428         return;
429     free(val->user_data.data);
430     krb5_free_address(context, val->r_address);
431     krb5_free_address(context, val->s_address);
432     free(val);
433 }
434
435 void KRB5_CALLCONV
436 krb5_free_safe(krb5_context context, register krb5_safe *val)
437 {
438     if (val == NULL)
439         return;
440     free(val->user_data.data);
441     krb5_free_address(context, val->r_address);
442     krb5_free_address(context, val->s_address);
443     krb5_free_checksum(context, val->checksum);
444     free(val);
445 }
446
447
448 void KRB5_CALLCONV
449 krb5_free_ticket(krb5_context context, krb5_ticket *val)
450 {
451     if (val == NULL)
452         return;
453     krb5_free_principal(context, val->server);
454     free(val->enc_part.ciphertext.data);
455     krb5_free_enc_tkt_part(context, val->enc_part2);
456     free(val);
457 }
458
459 void KRB5_CALLCONV
460 krb5_free_tickets(krb5_context context, krb5_ticket **val)
461 {
462     register krb5_ticket **temp;
463
464     if (val == NULL)
465         return;
466     for (temp = val; *temp; temp++)
467         krb5_free_ticket(context, *temp);
468     free(val);
469 }
470
471
472 void KRB5_CALLCONV
473 krb5_free_tgt_creds(krb5_context context, krb5_creds **tgts)
474 {
475     register krb5_creds **tgtpp;
476     if (tgts == NULL)
477         return;
478     for (tgtpp = tgts; *tgtpp; tgtpp++)
479         krb5_free_creds(context, *tgtpp);
480     free(tgts);
481 }
482
483 void KRB5_CALLCONV
484 krb5_free_tkt_authent(krb5_context context, krb5_tkt_authent *val)
485 {
486     if (val == NULL)
487         return;
488     krb5_free_ticket(context, val->ticket);
489     krb5_free_authenticator(context, val->authenticator);
490     free(val);
491 }
492
493 void KRB5_CALLCONV
494 krb5_free_unparsed_name(krb5_context context, char *val)
495 {
496     if (val != NULL)
497         free(val);
498 }
499
500 void KRB5_CALLCONV
501 krb5_free_string(krb5_context context, char *val)
502 {
503     free(val);
504 }
505
506 void KRB5_CALLCONV
507 krb5_free_sam_challenge_2(krb5_context ctx, krb5_sam_challenge_2 *sc2)
508 {
509     if (!sc2)
510         return;
511     krb5_free_sam_challenge_2_contents(ctx, sc2);
512     free(sc2);
513 }
514
515 void KRB5_CALLCONV
516 krb5_free_sam_challenge_2_contents(krb5_context ctx,
517                                    krb5_sam_challenge_2 *sc2)
518 {
519     krb5_checksum **cksump;
520
521     if (!sc2)
522         return;
523     if (sc2->sam_challenge_2_body.data)
524         krb5_free_data_contents(ctx, &sc2->sam_challenge_2_body);
525     if (sc2->sam_cksum) {
526         cksump = sc2->sam_cksum;
527         while (*cksump) {
528             krb5_free_checksum(ctx, *cksump);
529             cksump++;
530         }
531         free(sc2->sam_cksum);
532         sc2->sam_cksum = 0;
533     }
534 }
535
536 void KRB5_CALLCONV
537 krb5_free_sam_challenge_2_body(krb5_context ctx,
538                                krb5_sam_challenge_2_body *sc2)
539 {
540     if (!sc2)
541         return;
542     krb5_free_sam_challenge_2_body_contents(ctx, sc2);
543     free(sc2);
544 }
545
546 void KRB5_CALLCONV
547 krb5_free_sam_challenge_2_body_contents(krb5_context ctx,
548                                         krb5_sam_challenge_2_body *sc2)
549 {
550     if (!sc2)
551         return;
552     if (sc2->sam_type_name.data)
553         krb5_free_data_contents(ctx, &sc2->sam_type_name);
554     if (sc2->sam_track_id.data)
555         krb5_free_data_contents(ctx, &sc2->sam_track_id);
556     if (sc2->sam_challenge_label.data)
557         krb5_free_data_contents(ctx, &sc2->sam_challenge_label);
558     if (sc2->sam_challenge.data)
559         krb5_free_data_contents(ctx, &sc2->sam_challenge);
560     if (sc2->sam_response_prompt.data)
561         krb5_free_data_contents(ctx, &sc2->sam_response_prompt);
562     if (sc2->sam_pk_for_sad.data)
563         krb5_free_data_contents(ctx, &sc2->sam_pk_for_sad);
564 }
565
566 void KRB5_CALLCONV
567 krb5_free_sam_response_2(krb5_context ctx, krb5_sam_response_2 *sr2)
568 {
569     if (!sr2)
570         return;
571     krb5_free_sam_response_2_contents(ctx, sr2);
572     free(sr2);
573 }
574
575 void KRB5_CALLCONV
576 krb5_free_sam_response_2_contents(krb5_context ctx, krb5_sam_response_2 *sr2)
577 {
578     if (!sr2)
579         return;
580     if (sr2->sam_track_id.data)
581         krb5_free_data_contents(ctx, &sr2->sam_track_id);
582     if (sr2->sam_enc_nonce_or_sad.ciphertext.data)
583         krb5_free_data_contents(ctx, &sr2->sam_enc_nonce_or_sad.ciphertext);
584 }
585
586 void KRB5_CALLCONV
587 krb5_free_enc_sam_response_enc_2(krb5_context ctx,
588                                  krb5_enc_sam_response_enc_2 *esre2)
589 {
590     if (!esre2)
591         return;
592     krb5_free_enc_sam_response_enc_2_contents(ctx, esre2);
593     free(esre2);
594 }
595
596 void KRB5_CALLCONV
597 krb5_free_enc_sam_response_enc_2_contents(krb5_context ctx,
598                                           krb5_enc_sam_response_enc_2 *esre2)
599 {
600     if (!esre2)
601         return;
602     if (esre2->sam_sad.data)
603         krb5_free_data_contents(ctx, &esre2->sam_sad);
604 }
605
606 void KRB5_CALLCONV
607 krb5_free_pa_enc_ts(krb5_context ctx, krb5_pa_enc_ts *pa_enc_ts)
608 {
609     if (!pa_enc_ts)
610         return;
611     free(pa_enc_ts);
612 }
613
614 void KRB5_CALLCONV
615 krb5_free_pa_for_user(krb5_context context, krb5_pa_for_user *req)
616 {
617     if (req == NULL)
618         return;
619     krb5_free_principal(context, req->user);
620     req->user = NULL;
621     krb5_free_checksum_contents(context, &req->cksum);
622     krb5_free_data_contents(context, &req->auth_package);
623     free(req);
624 }
625
626 void KRB5_CALLCONV
627 krb5_free_s4u_userid_contents(krb5_context context, krb5_s4u_userid *user_id)
628 {
629     if (user_id == NULL)
630         return;
631     user_id->nonce = 0;
632     krb5_free_principal(context, user_id->user);
633     user_id->user = NULL;
634     krb5_free_data_contents(context, &user_id->subject_cert);
635     user_id->subject_cert.length = 0;
636     user_id->subject_cert.data = NULL;
637     user_id->options = 0;
638 }
639
640 void KRB5_CALLCONV
641 krb5_free_pa_s4u_x509_user(krb5_context context, krb5_pa_s4u_x509_user *req)
642 {
643     if (req == NULL)
644         return;
645     krb5_free_s4u_userid_contents(context, &req->user_id);
646     krb5_free_checksum_contents(context, &req->cksum);
647     free(req);
648 }
649
650 void KRB5_CALLCONV
651 krb5_free_pa_pac_req(krb5_context context,
652                      krb5_pa_pac_req *req)
653 {
654     free(req);
655 }
656
657 void KRB5_CALLCONV
658 krb5_free_fast_req(krb5_context context, krb5_fast_req *val)
659 {
660     if (val == NULL)
661         return;
662     krb5_free_kdc_req(context, val->req_body);
663     free(val);
664 }
665
666 void KRB5_CALLCONV
667 krb5_free_fast_armor(krb5_context context, krb5_fast_armor *val)
668 {
669     if (val == NULL)
670         return;
671     krb5_free_data_contents(context, &val->armor_value);
672     free(val);
673 }
674
675 void KRB5_CALLCONV
676 krb5_free_fast_response(krb5_context context, krb5_fast_response *val)
677 {
678     if (!val)
679         return;
680     krb5_free_pa_data(context, val->padata);
681     krb5_free_fast_finished(context, val->finished);
682     krb5_free_keyblock(context, val->strengthen_key);
683     free(val);
684 }
685
686 void KRB5_CALLCONV
687 krb5_free_fast_finished(krb5_context context, krb5_fast_finished *val)
688 {
689     if (!val)
690         return;
691     krb5_free_principal(context, val->client);
692     krb5_free_checksum_contents(context, &val->ticket_checksum);
693     free(val);
694 }
695
696 void KRB5_CALLCONV
697 krb5_free_fast_armored_req(krb5_context context, krb5_fast_armored_req *val)
698 {
699     if (val == NULL)
700         return;
701     if (val->armor)
702         krb5_free_fast_armor(context, val->armor);
703     krb5_free_data_contents(context, &val->enc_part.ciphertext);
704     if (val->req_checksum.contents)
705         krb5_free_checksum_contents(context, &val->req_checksum);
706     free(val);
707 }
708
709 void
710 k5_free_data_ptr_list(krb5_data **list)
711 {
712     int i;
713
714     for (i = 0; list != NULL && list[i] != NULL; i++)
715         krb5_free_data(NULL, list[i]);
716     free(list);
717 }
718
719 void KRB5_CALLCONV
720 krb5int_free_data_list(krb5_context context, krb5_data *data)
721 {
722     int i;
723
724     if (data == NULL)
725         return;
726
727     for (i = 0; data[i].data != NULL; i++)
728         free(data[i].data);
729
730     free(data);
731 }
732
733 void KRB5_CALLCONV
734 krb5_free_ad_kdcissued(krb5_context context, krb5_ad_kdcissued *val)
735 {
736     if (val == NULL)
737         return;
738
739     krb5_free_checksum_contents(context, &val->ad_checksum);
740     krb5_free_principal(context, val->i_principal);
741     krb5_free_authdata(context, val->elements);
742     free(val);
743 }
744
745 void KRB5_CALLCONV
746 krb5_free_ad_signedpath(krb5_context context, krb5_ad_signedpath *val)
747 {
748     int i;
749
750     if (val == NULL)
751         return;
752
753     krb5_free_checksum_contents(context, &val->checksum);
754     if (val->delegated != NULL) {
755         for (i = 0; val->delegated[i] != NULL; i++)
756             krb5_free_principal(context, val->delegated[i]);
757         free(val->delegated);
758     }
759     krb5_free_pa_data(context, val->method_data);
760     free(val);
761 }
762
763 void KRB5_CALLCONV
764 krb5_free_iakerb_header(krb5_context context, krb5_iakerb_header *val)
765 {
766     if (val == NULL)
767         return ;
768
769     krb5_free_data_contents(context, &val->target_realm);
770     krb5_free_data(context, val->cookie);
771     free(val);
772 }
773
774 void KRB5_CALLCONV
775 krb5_free_iakerb_finished(krb5_context context, krb5_iakerb_finished *val)
776 {
777     if (val == NULL)
778         return ;
779
780     krb5_free_checksum_contents(context, &val->checksum);
781     free(val);
782 }
783
784 void
785 k5_free_algorithm_identifier(krb5_context context,
786                              krb5_algorithm_identifier *val)
787 {
788     if (val == NULL)
789         return;
790     free(val->algorithm.data);
791     free(val->parameters.data);
792     free(val);
793 }
794
795 void
796 k5_free_otp_tokeninfo(krb5_context context, krb5_otp_tokeninfo *val)
797 {
798     krb5_algorithm_identifier **alg;
799
800     if (val == NULL)
801         return;
802     free(val->vendor.data);
803     free(val->challenge.data);
804     free(val->token_id.data);
805     free(val->alg_id.data);
806     for (alg = val->supported_hash_alg; alg != NULL && *alg != NULL; alg++)
807         k5_free_algorithm_identifier(context, *alg);
808     free(val->supported_hash_alg);
809     free(val);
810 }
811
812 void
813 k5_free_pa_otp_challenge(krb5_context context, krb5_pa_otp_challenge *val)
814 {
815     krb5_otp_tokeninfo **ti;
816
817     if (val == NULL)
818         return;
819     free(val->nonce.data);
820     free(val->service.data);
821     for (ti = val->tokeninfo; *ti != NULL; ti++)
822         k5_free_otp_tokeninfo(context, *ti);
823     free(val->tokeninfo);
824     free(val->salt.data);
825     free(val->s2kparams.data);
826     free(val);
827 }
828
829 void
830 k5_free_pa_otp_req(krb5_context context, krb5_pa_otp_req *val)
831 {
832     if (val == NULL)
833         return;
834     val->flags = 0;
835     free(val->nonce.data);
836     free(val->enc_data.ciphertext.data);
837     if (val->hash_alg != NULL)
838         k5_free_algorithm_identifier(context, val->hash_alg);
839     free(val->otp_value.data);
840     free(val->pin.data);
841     free(val->challenge.data);
842     free(val->counter.data);
843     free(val->token_id.data);
844     free(val->alg_id.data);
845     free(val->vendor.data);
846     free(val);
847 }
848
849 void
850 k5_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val)
851 {
852     if (val == NULL)
853         return;
854     free(val->target_domain.data);
855     free(val->kerb_message.data);
856     free(val);
857 }
858
859 static void
860 free_vmac(krb5_context context, krb5_verifier_mac *val)
861 {
862     if (val == NULL)
863         return;
864     krb5_free_principal(context, val->princ);
865     krb5_free_checksum_contents(context, &val->checksum);
866     free(val);
867 }
868
869 void
870 k5_free_cammac(krb5_context context, krb5_cammac *val)
871 {
872     krb5_verifier_mac **vp;
873
874     if (val == NULL)
875         return;
876     krb5_free_authdata(context, val->elements);
877     free_vmac(context, val->kdc_verifier);
878     free_vmac(context, val->svc_verifier);
879     for (vp = val->other_verifiers; vp != NULL && *vp != NULL; vp++)
880         free_vmac(context, *vp);
881     free(val->other_verifiers);
882     free(val);
883 }
884
885 void
886 k5_free_secure_cookie(krb5_context context, krb5_secure_cookie *val)
887 {
888     if (val == NULL)
889         return;
890     k5_zapfree_pa_data(val->data);
891     free(val);
892 }