Imported Upstream version 1.20.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 "k5-spake.h"
55 #include <assert.h>
56
57 void KRB5_CALLCONV
58 krb5_free_address(krb5_context context, krb5_address *val)
59 {
60     if (val == NULL)
61         return;
62     free(val->contents);
63     free(val);
64 }
65
66 void KRB5_CALLCONV
67 krb5_free_addresses(krb5_context context, krb5_address **val)
68 {
69     krb5_address **temp;
70
71     if (val == NULL)
72         return;
73     for (temp = val; *temp; temp++) {
74         free((*temp)->contents);
75         free(*temp);
76     }
77     free(val);
78 }
79
80 void KRB5_CALLCONV
81 krb5_free_ap_rep(krb5_context context, krb5_ap_rep *val)
82 {
83     if (val == NULL)
84         return;
85     free(val->enc_part.ciphertext.data);
86     free(val);
87 }
88
89 void KRB5_CALLCONV
90 krb5_free_ap_req(krb5_context context, krb5_ap_req *val)
91 {
92     if (val == NULL)
93         return;
94     krb5_free_ticket(context, val->ticket);
95     free(val->authenticator.ciphertext.data);
96     free(val);
97 }
98
99 void KRB5_CALLCONV
100 krb5_free_ap_rep_enc_part(krb5_context context, krb5_ap_rep_enc_part *val)
101 {
102     if (val == NULL)
103         return;
104     krb5_free_keyblock(context, val->subkey);
105     free(val);
106 }
107
108 void KRB5_CALLCONV
109 krb5_free_authenticator_contents(krb5_context context, krb5_authenticator *val)
110 {
111     if (val == NULL)
112         return;
113     krb5_free_checksum(context, val->checksum);
114     val->checksum = 0;
115     krb5_free_principal(context, val->client);
116     val->client = 0;
117     krb5_free_keyblock(context, val->subkey);
118     val->subkey = 0;
119     krb5_free_authdata(context, val->authorization_data);
120     val->authorization_data = 0;
121 }
122
123 void KRB5_CALLCONV
124 krb5_free_authenticator(krb5_context context, krb5_authenticator *val)
125 {
126     if (val == NULL)
127         return;
128     krb5_free_authenticator_contents(context, val);
129     free(val);
130 }
131
132 void KRB5_CALLCONV
133 krb5_free_checksum(krb5_context context, krb5_checksum *val)
134 {
135     if (val == NULL)
136         return;
137     krb5_free_checksum_contents(context, val);
138     free(val);
139 }
140
141 void KRB5_CALLCONV
142 krb5_free_checksum_contents(krb5_context context, krb5_checksum *val)
143 {
144     if (val == NULL)
145         return;
146     free(val->contents);
147     val->contents = NULL;
148     val->length = 0;
149 }
150
151 void KRB5_CALLCONV
152 krb5_free_cred(krb5_context context, krb5_cred *val)
153 {
154     if (val == NULL)
155         return;
156     krb5_free_tickets(context, val->tickets);
157     free(val->enc_part.ciphertext.data);
158     free(val);
159 }
160
161 /*
162  * krb5_free_cred_contents zeros out the session key, and then frees
163  * the credentials structures
164  */
165
166 void KRB5_CALLCONV
167 krb5_free_cred_contents(krb5_context context, krb5_creds *val)
168 {
169     if (val == NULL)
170         return;
171     krb5_free_principal(context, val->client);
172     val->client = 0;
173     krb5_free_principal(context, val->server);
174     val->server = 0;
175     krb5_free_keyblock_contents(context, &val->keyblock);
176     free(val->ticket.data);
177     val->ticket.data = 0;
178     free(val->second_ticket.data);
179     val->second_ticket.data = 0;
180     krb5_free_addresses(context, val->addresses);
181     val->addresses = 0;
182     krb5_free_authdata(context, val->authdata);
183     val->authdata = 0;
184 }
185
186 void KRB5_CALLCONV
187 krb5_free_cred_enc_part(krb5_context context, krb5_cred_enc_part *val)
188 {
189     krb5_cred_info **temp;
190
191     if (val == NULL)
192         return;
193     krb5_free_address(context, val->r_address);
194     val->r_address = 0;
195     krb5_free_address(context, val->s_address);
196     val->s_address = 0;
197
198     if (val->ticket_info) {
199         for (temp = val->ticket_info; *temp; temp++) {
200             krb5_free_keyblock(context, (*temp)->session);
201             krb5_free_principal(context, (*temp)->client);
202             krb5_free_principal(context, (*temp)->server);
203             krb5_free_addresses(context, (*temp)->caddrs);
204             free(*temp);
205         }
206         free(val->ticket_info);
207         val->ticket_info = 0;
208     }
209 }
210
211
212 void KRB5_CALLCONV
213 krb5_free_creds(krb5_context context, krb5_creds *val)
214 {
215     if (val == NULL)
216         return;
217     krb5_free_cred_contents(context, val);
218     free(val);
219 }
220
221
222 void KRB5_CALLCONV
223 krb5_free_data(krb5_context context, krb5_data *val)
224 {
225     if (val == NULL)
226         return;
227     free(val->data);
228     free(val);
229 }
230
231
232 void KRB5_CALLCONV
233 krb5_free_octet_data(krb5_context context, krb5_octet_data *val)
234 {
235     if (val == NULL)
236         return;
237     free(val->data);
238     free(val);
239 }
240
241 void KRB5_CALLCONV
242 krb5_free_data_contents(krb5_context context, krb5_data *val)
243 {
244     if (val == NULL)
245         return;
246     free(val->data);
247     val->data = NULL;
248     val->length = 0;
249 }
250
251 void KRB5_CALLCONV
252 krb5_free_enc_data(krb5_context context, krb5_enc_data *val)
253 {
254     if (val == NULL)
255         return;
256     krb5_free_data_contents(context, &val->ciphertext);
257     free(val);
258 }
259
260 void krb5_free_etype_info(krb5_context context, krb5_etype_info info)
261 {
262     int i;
263
264     if (info == NULL)
265         return;
266     for (i=0; info[i] != NULL; i++) {
267         free(info[i]->salt);
268         krb5_free_data_contents(context, &info[i]->s2kparams);
269         free(info[i]);
270     }
271     free(info);
272 }
273
274
275 void KRB5_CALLCONV
276 krb5_free_enc_kdc_rep_part(krb5_context context, krb5_enc_kdc_rep_part *val)
277 {
278     if (val == NULL)
279         return;
280     krb5_free_keyblock(context, val->session);
281     krb5_free_last_req(context, val->last_req);
282     krb5_free_principal(context, val->server);
283     krb5_free_addresses(context, val->caddrs);
284     krb5_free_pa_data(context, val->enc_padata);
285     free(val);
286 }
287
288 void KRB5_CALLCONV
289 krb5_free_enc_tkt_part(krb5_context context, krb5_enc_tkt_part *val)
290 {
291     if (val == NULL)
292         return;
293     krb5_free_keyblock(context, val->session);
294     krb5_free_principal(context, val->client);
295     free(val->transited.tr_contents.data);
296     krb5_free_addresses(context, val->caddrs);
297     krb5_free_authdata(context, val->authorization_data);
298     free(val);
299 }
300
301
302 void KRB5_CALLCONV
303 krb5_free_error(krb5_context context, krb5_error *val)
304 {
305     if (val == NULL)
306         return;
307     krb5_free_principal(context, val->client);
308     krb5_free_principal(context, val->server);
309     free(val->text.data);
310     free(val->e_data.data);
311     free(val);
312 }
313
314 void KRB5_CALLCONV
315 krb5_free_kdc_rep(krb5_context context, krb5_kdc_rep *val)
316 {
317     if (val == NULL)
318         return;
319     krb5_free_pa_data(context, val->padata);
320     krb5_free_principal(context, val->client);
321     krb5_free_ticket(context, val->ticket);
322     free(val->enc_part.ciphertext.data);
323     krb5_free_enc_kdc_rep_part(context, val->enc_part2);
324     free(val);
325 }
326
327
328 void KRB5_CALLCONV
329 krb5_free_kdc_req(krb5_context context, krb5_kdc_req *val)
330 {
331     if (val == NULL)
332         return;
333     krb5_free_pa_data(context, val->padata);
334     krb5_free_principal(context, val->client);
335     krb5_free_principal(context, val->server);
336     free(val->ktype);
337     krb5_free_addresses(context, val->addresses);
338     free(val->authorization_data.ciphertext.data);
339     krb5_free_authdata(context, val->unenc_authdata);
340     krb5_free_tickets(context, val->second_ticket);
341     free(val);
342 }
343
344 void KRB5_CALLCONV
345 krb5_free_keyblock_contents(krb5_context context, krb5_keyblock *key)
346 {
347     krb5int_c_free_keyblock_contents (context, key);
348 }
349
350 void KRB5_CALLCONV
351 krb5_free_keyblock(krb5_context context, krb5_keyblock *val)
352 {
353     krb5int_c_free_keyblock (context, val);
354 }
355
356
357
358 void KRB5_CALLCONV
359 krb5_free_last_req(krb5_context context, krb5_last_req_entry **val)
360 {
361     krb5_last_req_entry **temp;
362
363     if (val == NULL)
364         return;
365     for (temp = val; *temp; temp++)
366         free(*temp);
367     free(val);
368 }
369
370 void
371 k5_zapfree_pa_data(krb5_pa_data **val)
372 {
373     krb5_pa_data **pa;
374
375     if (val == NULL)
376         return;
377     for (pa = val; *pa != NULL; pa++) {
378         zapfree((*pa)->contents, (*pa)->length);
379         zapfree(*pa, sizeof(**pa));
380     }
381     free(val);
382 }
383
384 void KRB5_CALLCONV
385 krb5_free_pa_data(krb5_context context, krb5_pa_data **val)
386 {
387     krb5_pa_data **temp;
388
389     if (val == NULL)
390         return;
391     for (temp = val; *temp; temp++) {
392         free((*temp)->contents);
393         free(*temp);
394     }
395     free(val);
396 }
397
398 void KRB5_CALLCONV
399 krb5_free_principal(krb5_context context, krb5_principal val)
400 {
401     krb5_int32 i;
402
403     if (!val)
404         return;
405
406     if (val->data) {
407         i = val->length;
408         while(--i >= 0)
409             free(val->data[i].data);
410         free(val->data);
411     }
412     free(val->realm.data);
413     free(val);
414 }
415
416 void KRB5_CALLCONV
417 krb5_free_priv(krb5_context context, krb5_priv *val)
418 {
419     if (val == NULL)
420         return;
421     free(val->enc_part.ciphertext.data);
422     free(val);
423 }
424
425 void KRB5_CALLCONV
426 krb5_free_priv_enc_part(krb5_context context, krb5_priv_enc_part *val)
427 {
428     if (val == NULL)
429         return;
430     free(val->user_data.data);
431     krb5_free_address(context, val->r_address);
432     krb5_free_address(context, val->s_address);
433     free(val);
434 }
435
436 void KRB5_CALLCONV
437 krb5_free_safe(krb5_context context, krb5_safe *val)
438 {
439     if (val == NULL)
440         return;
441     free(val->user_data.data);
442     krb5_free_address(context, val->r_address);
443     krb5_free_address(context, val->s_address);
444     krb5_free_checksum(context, val->checksum);
445     free(val);
446 }
447
448
449 void KRB5_CALLCONV
450 krb5_free_ticket(krb5_context context, krb5_ticket *val)
451 {
452     if (val == NULL)
453         return;
454     krb5_free_principal(context, val->server);
455     free(val->enc_part.ciphertext.data);
456     krb5_free_enc_tkt_part(context, val->enc_part2);
457     free(val);
458 }
459
460 void KRB5_CALLCONV
461 krb5_free_tickets(krb5_context context, krb5_ticket **val)
462 {
463     krb5_ticket **temp;
464
465     if (val == NULL)
466         return;
467     for (temp = val; *temp; temp++)
468         krb5_free_ticket(context, *temp);
469     free(val);
470 }
471
472
473 void KRB5_CALLCONV
474 krb5_free_tgt_creds(krb5_context context, krb5_creds **tgts)
475 {
476     krb5_creds **tgtpp;
477     if (tgts == NULL)
478         return;
479     for (tgtpp = tgts; *tgtpp; tgtpp++)
480         krb5_free_creds(context, *tgtpp);
481     free(tgts);
482 }
483
484 void KRB5_CALLCONV
485 krb5_free_tkt_authent(krb5_context context, krb5_tkt_authent *val)
486 {
487     if (val == NULL)
488         return;
489     krb5_free_ticket(context, val->ticket);
490     krb5_free_authenticator(context, val->authenticator);
491     free(val);
492 }
493
494 void KRB5_CALLCONV
495 krb5_free_unparsed_name(krb5_context context, char *val)
496 {
497     if (val != NULL)
498         free(val);
499 }
500
501 void KRB5_CALLCONV
502 krb5_free_string(krb5_context context, char *val)
503 {
504     free(val);
505 }
506
507 void KRB5_CALLCONV
508 krb5_free_sam_challenge_2(krb5_context ctx, krb5_sam_challenge_2 *sc2)
509 {
510     if (!sc2)
511         return;
512     krb5_free_sam_challenge_2_contents(ctx, sc2);
513     free(sc2);
514 }
515
516 void KRB5_CALLCONV
517 krb5_free_sam_challenge_2_contents(krb5_context ctx,
518                                    krb5_sam_challenge_2 *sc2)
519 {
520     krb5_checksum **cksump;
521
522     if (!sc2)
523         return;
524     if (sc2->sam_challenge_2_body.data)
525         krb5_free_data_contents(ctx, &sc2->sam_challenge_2_body);
526     if (sc2->sam_cksum) {
527         cksump = sc2->sam_cksum;
528         while (*cksump) {
529             krb5_free_checksum(ctx, *cksump);
530             cksump++;
531         }
532         free(sc2->sam_cksum);
533         sc2->sam_cksum = 0;
534     }
535 }
536
537 void KRB5_CALLCONV
538 krb5_free_sam_challenge_2_body(krb5_context ctx,
539                                krb5_sam_challenge_2_body *sc2)
540 {
541     if (!sc2)
542         return;
543     krb5_free_sam_challenge_2_body_contents(ctx, sc2);
544     free(sc2);
545 }
546
547 void KRB5_CALLCONV
548 krb5_free_sam_challenge_2_body_contents(krb5_context ctx,
549                                         krb5_sam_challenge_2_body *sc2)
550 {
551     if (!sc2)
552         return;
553     if (sc2->sam_type_name.data)
554         krb5_free_data_contents(ctx, &sc2->sam_type_name);
555     if (sc2->sam_track_id.data)
556         krb5_free_data_contents(ctx, &sc2->sam_track_id);
557     if (sc2->sam_challenge_label.data)
558         krb5_free_data_contents(ctx, &sc2->sam_challenge_label);
559     if (sc2->sam_challenge.data)
560         krb5_free_data_contents(ctx, &sc2->sam_challenge);
561     if (sc2->sam_response_prompt.data)
562         krb5_free_data_contents(ctx, &sc2->sam_response_prompt);
563     if (sc2->sam_pk_for_sad.data)
564         krb5_free_data_contents(ctx, &sc2->sam_pk_for_sad);
565 }
566
567 void KRB5_CALLCONV
568 krb5_free_sam_response_2(krb5_context ctx, krb5_sam_response_2 *sr2)
569 {
570     if (!sr2)
571         return;
572     krb5_free_sam_response_2_contents(ctx, sr2);
573     free(sr2);
574 }
575
576 void KRB5_CALLCONV
577 krb5_free_sam_response_2_contents(krb5_context ctx, krb5_sam_response_2 *sr2)
578 {
579     if (!sr2)
580         return;
581     if (sr2->sam_track_id.data)
582         krb5_free_data_contents(ctx, &sr2->sam_track_id);
583     if (sr2->sam_enc_nonce_or_sad.ciphertext.data)
584         krb5_free_data_contents(ctx, &sr2->sam_enc_nonce_or_sad.ciphertext);
585 }
586
587 void KRB5_CALLCONV
588 krb5_free_enc_sam_response_enc_2(krb5_context ctx,
589                                  krb5_enc_sam_response_enc_2 *esre2)
590 {
591     if (!esre2)
592         return;
593     krb5_free_enc_sam_response_enc_2_contents(ctx, esre2);
594     free(esre2);
595 }
596
597 void KRB5_CALLCONV
598 krb5_free_enc_sam_response_enc_2_contents(krb5_context ctx,
599                                           krb5_enc_sam_response_enc_2 *esre2)
600 {
601     if (!esre2)
602         return;
603     if (esre2->sam_sad.data)
604         krb5_free_data_contents(ctx, &esre2->sam_sad);
605 }
606
607 void KRB5_CALLCONV
608 krb5_free_pa_enc_ts(krb5_context ctx, krb5_pa_enc_ts *pa_enc_ts)
609 {
610     if (!pa_enc_ts)
611         return;
612     free(pa_enc_ts);
613 }
614
615 void KRB5_CALLCONV
616 krb5_free_pa_for_user(krb5_context context, krb5_pa_for_user *req)
617 {
618     if (req == NULL)
619         return;
620     krb5_free_principal(context, req->user);
621     req->user = NULL;
622     krb5_free_checksum_contents(context, &req->cksum);
623     krb5_free_data_contents(context, &req->auth_package);
624     free(req);
625 }
626
627 void KRB5_CALLCONV
628 krb5_free_s4u_userid_contents(krb5_context context, krb5_s4u_userid *user_id)
629 {
630     if (user_id == NULL)
631         return;
632     user_id->nonce = 0;
633     krb5_free_principal(context, user_id->user);
634     user_id->user = NULL;
635     krb5_free_data_contents(context, &user_id->subject_cert);
636     user_id->subject_cert.length = 0;
637     user_id->subject_cert.data = NULL;
638     user_id->options = 0;
639 }
640
641 void KRB5_CALLCONV
642 krb5_free_pa_s4u_x509_user(krb5_context context, krb5_pa_s4u_x509_user *req)
643 {
644     if (req == NULL)
645         return;
646     krb5_free_s4u_userid_contents(context, &req->user_id);
647     krb5_free_checksum_contents(context, &req->cksum);
648     free(req);
649 }
650
651 void KRB5_CALLCONV
652 krb5_free_pa_pac_req(krb5_context context,
653                      krb5_pa_pac_req *req)
654 {
655     free(req);
656 }
657
658 void KRB5_CALLCONV
659 krb5_free_fast_req(krb5_context context, krb5_fast_req *val)
660 {
661     if (val == NULL)
662         return;
663     krb5_free_kdc_req(context, val->req_body);
664     free(val);
665 }
666
667 void KRB5_CALLCONV
668 krb5_free_fast_armor(krb5_context context, krb5_fast_armor *val)
669 {
670     if (val == NULL)
671         return;
672     krb5_free_data_contents(context, &val->armor_value);
673     free(val);
674 }
675
676 void KRB5_CALLCONV
677 krb5_free_fast_response(krb5_context context, krb5_fast_response *val)
678 {
679     if (!val)
680         return;
681     krb5_free_pa_data(context, val->padata);
682     krb5_free_fast_finished(context, val->finished);
683     krb5_free_keyblock(context, val->strengthen_key);
684     free(val);
685 }
686
687 void KRB5_CALLCONV
688 krb5_free_fast_finished(krb5_context context, krb5_fast_finished *val)
689 {
690     if (!val)
691         return;
692     krb5_free_principal(context, val->client);
693     krb5_free_checksum_contents(context, &val->ticket_checksum);
694     free(val);
695 }
696
697 void KRB5_CALLCONV
698 krb5_free_fast_armored_req(krb5_context context, krb5_fast_armored_req *val)
699 {
700     if (val == NULL)
701         return;
702     if (val->armor)
703         krb5_free_fast_armor(context, val->armor);
704     krb5_free_data_contents(context, &val->enc_part.ciphertext);
705     if (val->req_checksum.contents)
706         krb5_free_checksum_contents(context, &val->req_checksum);
707     free(val);
708 }
709
710 void
711 k5_free_data_ptr_list(krb5_data **list)
712 {
713     int i;
714
715     for (i = 0; list != NULL && list[i] != NULL; i++)
716         krb5_free_data(NULL, list[i]);
717     free(list);
718 }
719
720 void KRB5_CALLCONV
721 krb5int_free_data_list(krb5_context context, krb5_data *data)
722 {
723     int i;
724
725     if (data == NULL)
726         return;
727
728     for (i = 0; data[i].data != NULL; i++)
729         free(data[i].data);
730
731     free(data);
732 }
733
734 void KRB5_CALLCONV
735 krb5_free_ad_kdcissued(krb5_context context, krb5_ad_kdcissued *val)
736 {
737     if (val == NULL)
738         return;
739
740     krb5_free_checksum_contents(context, &val->ad_checksum);
741     krb5_free_principal(context, val->i_principal);
742     krb5_free_authdata(context, val->elements);
743     free(val);
744 }
745
746 void KRB5_CALLCONV
747 krb5_free_iakerb_header(krb5_context context, krb5_iakerb_header *val)
748 {
749     if (val == NULL)
750         return ;
751
752     krb5_free_data_contents(context, &val->target_realm);
753     krb5_free_data(context, val->cookie);
754     free(val);
755 }
756
757 void KRB5_CALLCONV
758 krb5_free_iakerb_finished(krb5_context context, krb5_iakerb_finished *val)
759 {
760     if (val == NULL)
761         return ;
762
763     krb5_free_checksum_contents(context, &val->checksum);
764     free(val);
765 }
766
767 void
768 k5_free_algorithm_identifier(krb5_context context,
769                              krb5_algorithm_identifier *val)
770 {
771     if (val == NULL)
772         return;
773     free(val->algorithm.data);
774     free(val->parameters.data);
775     free(val);
776 }
777
778 void
779 k5_free_otp_tokeninfo(krb5_context context, krb5_otp_tokeninfo *val)
780 {
781     krb5_algorithm_identifier **alg;
782
783     if (val == NULL)
784         return;
785     free(val->vendor.data);
786     free(val->challenge.data);
787     free(val->token_id.data);
788     free(val->alg_id.data);
789     for (alg = val->supported_hash_alg; alg != NULL && *alg != NULL; alg++)
790         k5_free_algorithm_identifier(context, *alg);
791     free(val->supported_hash_alg);
792     free(val);
793 }
794
795 void
796 k5_free_pa_otp_challenge(krb5_context context, krb5_pa_otp_challenge *val)
797 {
798     krb5_otp_tokeninfo **ti;
799
800     if (val == NULL)
801         return;
802     free(val->nonce.data);
803     free(val->service.data);
804     for (ti = val->tokeninfo; *ti != NULL; ti++)
805         k5_free_otp_tokeninfo(context, *ti);
806     free(val->tokeninfo);
807     free(val->salt.data);
808     free(val->s2kparams.data);
809     free(val);
810 }
811
812 void
813 k5_free_pa_otp_req(krb5_context context, krb5_pa_otp_req *val)
814 {
815     if (val == NULL)
816         return;
817     val->flags = 0;
818     free(val->nonce.data);
819     free(val->enc_data.ciphertext.data);
820     if (val->hash_alg != NULL)
821         k5_free_algorithm_identifier(context, val->hash_alg);
822     free(val->otp_value.data);
823     free(val->pin.data);
824     free(val->challenge.data);
825     free(val->counter.data);
826     free(val->token_id.data);
827     free(val->alg_id.data);
828     free(val->vendor.data);
829     free(val);
830 }
831
832 void
833 k5_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val)
834 {
835     if (val == NULL)
836         return;
837     free(val->target_domain.data);
838     free(val->kerb_message.data);
839     free(val);
840 }
841
842 static void
843 free_vmac(krb5_context context, krb5_verifier_mac *val)
844 {
845     if (val == NULL)
846         return;
847     krb5_free_principal(context, val->princ);
848     krb5_free_checksum_contents(context, &val->checksum);
849     free(val);
850 }
851
852 void
853 k5_free_cammac(krb5_context context, krb5_cammac *val)
854 {
855     krb5_verifier_mac **vp;
856
857     if (val == NULL)
858         return;
859     krb5_free_authdata(context, val->elements);
860     free_vmac(context, val->kdc_verifier);
861     free_vmac(context, val->svc_verifier);
862     for (vp = val->other_verifiers; vp != NULL && *vp != NULL; vp++)
863         free_vmac(context, *vp);
864     free(val->other_verifiers);
865     free(val);
866 }
867
868 void
869 k5_free_secure_cookie(krb5_context context, krb5_secure_cookie *val)
870 {
871     if (val == NULL)
872         return;
873     k5_zapfree_pa_data(val->data);
874     free(val);
875 }
876
877 void
878 k5_free_spake_factor(krb5_context context, krb5_spake_factor *val)
879 {
880     if (val == NULL)
881         return;
882     if (val->data != NULL)
883         zapfree(val->data->data, val->data->length);
884     free(val->data);
885     free(val);
886 }
887
888 void
889 k5_free_pa_spake(krb5_context context, krb5_pa_spake *val)
890 {
891     krb5_spake_factor **f;
892
893     if (val == NULL)
894         return;
895     switch (val->choice) {
896     case SPAKE_MSGTYPE_SUPPORT:
897         free(val->u.support.groups);
898         break;
899     case SPAKE_MSGTYPE_CHALLENGE:
900         krb5_free_data_contents(context, &val->u.challenge.pubkey);
901         for (f = val->u.challenge.factors; f != NULL && *f != NULL; f++)
902             k5_free_spake_factor(context, *f);
903         free(val->u.challenge.factors);
904         break;
905     case SPAKE_MSGTYPE_RESPONSE:
906         krb5_free_data_contents(context, &val->u.response.pubkey);
907         krb5_free_data_contents(context, &val->u.response.factor.ciphertext);
908         break;
909     case SPAKE_MSGTYPE_ENCDATA:
910         krb5_free_data_contents(context, &val->u.encdata.ciphertext);
911         break;
912     default:
913         break;
914     }
915     free(val);
916 }