2 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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.
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.
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
36 #include "krb5_locl.h"
39 * Free ticket and content
41 * @param context a Kerberos 5 context
42 * @param ticket ticket to free
44 * @return Returns 0 to indicate success. Otherwise an kerberos et
45 * error code is returned, see krb5_get_error_message().
50 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
51 krb5_free_ticket(krb5_context context
,
54 free_EncTicketPart(&ticket
->ticket
);
55 krb5_free_principal(context
, ticket
->client
);
56 krb5_free_principal(context
, ticket
->server
);
62 * Copy ticket and content
64 * @param context a Kerberos 5 context
65 * @param from ticket to copy
66 * @param to new copy of ticket, free with krb5_free_ticket()
68 * @return Returns 0 to indicate success. Otherwise an kerberos et
69 * error code is returned, see krb5_get_error_message().
74 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
75 krb5_copy_ticket(krb5_context context
,
76 const krb5_ticket
*from
,
83 tmp
= malloc(sizeof(*tmp
));
85 return krb5_enomem(context
);
86 if((ret
= copy_EncTicketPart(&from
->ticket
, &tmp
->ticket
))){
90 ret
= krb5_copy_principal(context
, from
->client
, &tmp
->client
);
92 free_EncTicketPart(&tmp
->ticket
);
96 ret
= krb5_copy_principal(context
, from
->server
, &tmp
->server
);
98 krb5_free_principal(context
, tmp
->client
);
99 free_EncTicketPart(&tmp
->ticket
);
108 * Return client principal in ticket
110 * @param context a Kerberos 5 context
111 * @param ticket ticket to copy
112 * @param client client principal, free with krb5_free_principal()
114 * @return Returns 0 to indicate success. Otherwise an kerberos et
115 * error code is returned, see krb5_get_error_message().
120 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
121 krb5_ticket_get_client(krb5_context context
,
122 const krb5_ticket
*ticket
,
123 krb5_principal
*client
)
125 return krb5_copy_principal(context
, ticket
->client
, client
);
129 * Return server principal in ticket
131 * @param context a Kerberos 5 context
132 * @param ticket ticket to copy
133 * @param server server principal, free with krb5_free_principal()
135 * @return Returns 0 to indicate success. Otherwise an kerberos et
136 * error code is returned, see krb5_get_error_message().
141 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
142 krb5_ticket_get_server(krb5_context context
,
143 const krb5_ticket
*ticket
,
144 krb5_principal
*server
)
146 return krb5_copy_principal(context
, ticket
->server
, server
);
150 * Return end time of ticket
152 * @param context a Kerberos 5 context
153 * @param ticket ticket to copy
155 * @return end time of ticket
160 KRB5_LIB_FUNCTION
time_t KRB5_LIB_CALL
161 krb5_ticket_get_endtime(krb5_context context
,
162 const krb5_ticket
*ticket
)
164 return ticket
->ticket
.endtime
;
168 * Get the flags from the Kerberos ticket
170 * @param context Kerberos context
171 * @param ticket Kerberos ticket
173 * @return ticket flags
175 * @ingroup krb5_ticket
177 KRB5_LIB_FUNCTION
unsigned long KRB5_LIB_CALL
178 krb5_ticket_get_flags(krb5_context context
,
179 const krb5_ticket
*ticket
)
181 return TicketFlags2int(ticket
->ticket
.flags
);
185 find_type_in_ad(krb5_context context
,
190 krb5_keyblock
*sessionkey
,
191 const AuthorizationData
*ad
,
194 krb5_error_code ret
= 0;
198 ret
= ENOENT
; /* XXX */
199 krb5_set_error_message(context
, ret
,
200 N_("Authorization data nested deeper "
201 "then %d levels, stop searching", ""),
207 * Only copy out the element the first time we get to it, we need
208 * to run over the whole authorization data fields to check if
209 * there are any container clases we need to care about.
211 for (i
= 0; i
< ad
->len
; i
++) {
212 if (!*found
&& ad
->val
[i
].ad_type
== type
) {
213 ret
= der_copy_octet_string(&ad
->val
[i
].ad_data
, data
);
215 krb5_set_error_message(context
, ret
,
216 N_("malloc: out of memory", ""));
222 switch (ad
->val
[i
].ad_type
) {
223 case KRB5_AUTHDATA_IF_RELEVANT
: {
224 AuthorizationData child
;
225 ret
= decode_AuthorizationData(ad
->val
[i
].ad_data
.data
,
226 ad
->val
[i
].ad_data
.length
,
230 krb5_set_error_message(context
, ret
,
231 N_("Failed to decode "
232 "IF_RELEVANT with %d", ""),
236 ret
= find_type_in_ad(context
, type
, data
, found
, FALSE
,
237 sessionkey
, &child
, level
+ 1);
238 free_AuthorizationData(&child
);
244 case KRB5_AUTHDATA_KDC_ISSUED
: {
247 ret
= decode_AD_KDCIssued(ad
->val
[i
].ad_data
.data
,
248 ad
->val
[i
].ad_data
.length
,
252 krb5_set_error_message(context
, ret
,
253 N_("Failed to decode "
254 "AD_KDCIssued with %d", ""),
263 ASN1_MALLOC_ENCODE(AuthorizationData
, buf
.data
, buf
.length
,
264 &child
.elements
, &len
, ret
);
266 free_AD_KDCIssued(&child
);
267 krb5_clear_error_message(context
);
270 if(buf
.length
!= len
)
271 krb5_abortx(context
, "internal error in ASN.1 encoder");
273 ret
= krb5_c_verify_checksum(context
, sessionkey
, 19, &buf
,
274 &child
.ad_checksum
, &valid
);
275 krb5_data_free(&buf
);
277 free_AD_KDCIssued(&child
);
281 krb5_clear_error_message(context
);
283 free_AD_KDCIssued(&child
);
287 ret
= find_type_in_ad(context
, type
, data
, found
, failp
, sessionkey
,
288 &child
.elements
, level
+ 1);
289 free_AD_KDCIssued(&child
);
295 case KRB5_AUTHDATA_AND_OR
:
298 ret
= ENOENT
; /* XXX */
299 krb5_set_error_message(context
, ret
,
300 N_("Authorization data contains "
301 "AND-OR element that is unknown to the "
307 ret
= ENOENT
; /* XXX */
308 krb5_set_error_message(context
, ret
,
309 N_("Authorization data contains "
310 "unknown type (%d) ", ""),
318 krb5_data_free(data
);
325 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
326 _krb5_get_ad(krb5_context context
,
327 const AuthorizationData
*ad
,
328 krb5_keyblock
*sessionkey
,
332 krb5_boolean found
= FALSE
;
335 krb5_data_zero(data
);
338 krb5_set_error_message(context
, ENOENT
,
339 N_("No authorization data", ""));
340 return ENOENT
; /* XXX */
343 ret
= find_type_in_ad(context
, type
, data
, &found
, TRUE
, sessionkey
, ad
, 0);
347 krb5_set_error_message(context
, ENOENT
,
348 N_("Have no authorization data of type %d", ""),
350 return ENOENT
; /* XXX */
357 * Extract the authorization data type of type from the ticket. Store
358 * the field in data. This function is to use for kerberos
361 * @param context a Kerberos 5 context
362 * @param ticket Kerberos ticket
363 * @param type type to fetch
364 * @param data returned data, free with krb5_data_free()
369 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
370 krb5_ticket_get_authorization_data_type(krb5_context context
,
375 AuthorizationData
*ad
;
377 krb5_boolean found
= FALSE
;
379 krb5_data_zero(data
);
381 ad
= ticket
->ticket
.authorization_data
;
382 if (ticket
->ticket
.authorization_data
== NULL
) {
383 krb5_set_error_message(context
, ENOENT
,
384 N_("Ticket have not authorization data", ""));
385 return ENOENT
; /* XXX */
388 ret
= find_type_in_ad(context
, type
, data
, &found
, TRUE
,
389 &ticket
->ticket
.key
, ad
, 0);
393 krb5_set_error_message(context
, ENOENT
,
394 N_("Ticket have not "
395 "authorization data of type %d", ""),
397 return ENOENT
; /* XXX */
402 static krb5_error_code
403 check_server_referral(krb5_context context
,
406 krb5_const_principal requested
,
407 krb5_const_principal returned
,
411 PA_ServerReferralData ref
;
419 if (rep
->kdc_rep
.padata
== NULL
)
422 pa
= krb5_find_padata(rep
->kdc_rep
.padata
->val
,
423 rep
->kdc_rep
.padata
->len
,
424 KRB5_PADATA_SERVER_REFERRAL
, &i
);
428 memset(&ed
, 0, sizeof(ed
));
429 memset(&ref
, 0, sizeof(ref
));
431 ret
= decode_EncryptedData(pa
->padata_value
.data
,
432 pa
->padata_value
.length
,
436 if (len
!= pa
->padata_value
.length
) {
437 free_EncryptedData(&ed
);
438 krb5_set_error_message(context
, KRB5KRB_AP_ERR_MODIFIED
,
439 N_("Referral EncryptedData wrong for realm %s",
440 "realm"), requested
->realm
);
441 return KRB5KRB_AP_ERR_MODIFIED
;
444 ret
= krb5_crypto_init(context
, key
, 0, &session
);
446 free_EncryptedData(&ed
);
450 ret
= krb5_decrypt_EncryptedData(context
, session
,
451 KRB5_KU_PA_SERVER_REFERRAL
,
453 free_EncryptedData(&ed
);
454 krb5_crypto_destroy(context
, session
);
458 ret
= decode_PA_ServerReferralData(data
.data
, data
.length
, &ref
, &len
);
460 krb5_data_free(&data
);
463 krb5_data_free(&data
);
465 if (strcmp(requested
->realm
, returned
->realm
) != 0) {
466 free_PA_ServerReferralData(&ref
);
467 krb5_set_error_message(context
, KRB5KRB_AP_ERR_MODIFIED
,
468 N_("server ref realm mismatch, "
469 "requested realm %s got back %s", ""),
470 requested
->realm
, returned
->realm
);
471 return KRB5KRB_AP_ERR_MODIFIED
;
474 if (krb5_principal_is_krbtgt(context
, returned
)) {
475 const char *realm
= returned
->name
.name_string
.val
[1];
477 if (ref
.referred_realm
== NULL
478 || strcmp(*ref
.referred_realm
, realm
) != 0)
480 free_PA_ServerReferralData(&ref
);
481 krb5_set_error_message(context
, KRB5KRB_AP_ERR_MODIFIED
,
482 N_("tgt returned with wrong ref", ""));
483 return KRB5KRB_AP_ERR_MODIFIED
;
485 } else if (krb5_principal_compare(context
, returned
, requested
) == 0) {
486 free_PA_ServerReferralData(&ref
);
487 krb5_set_error_message(context
, KRB5KRB_AP_ERR_MODIFIED
,
488 N_("req princ no same as returned", ""));
489 return KRB5KRB_AP_ERR_MODIFIED
;
492 if (ref
.requested_principal_name
) {
493 cmp
= _krb5_principal_compare_PrincipalName(context
,
495 ref
.requested_principal_name
);
497 free_PA_ServerReferralData(&ref
);
498 krb5_set_error_message(context
, KRB5KRB_AP_ERR_MODIFIED
,
499 N_("referred principal not same "
500 "as requested", ""));
501 return KRB5KRB_AP_ERR_MODIFIED
;
503 } else if (flags
& EXTRACT_TICKET_AS_REQ
) {
504 free_PA_ServerReferralData(&ref
);
505 krb5_set_error_message(context
, KRB5KRB_AP_ERR_MODIFIED
,
506 N_("Requested principal missing on AS-REQ", ""));
507 return KRB5KRB_AP_ERR_MODIFIED
;
510 free_PA_ServerReferralData(&ref
);
515 * Expect excact match or that we got a krbtgt
517 if (krb5_principal_compare(context
, requested
, returned
) != TRUE
&&
518 (krb5_realm_compare(context
, requested
, returned
) != TRUE
&&
519 krb5_principal_is_krbtgt(context
, returned
) != TRUE
))
521 krb5_set_error_message(context
, KRB5KRB_AP_ERR_MODIFIED
,
522 N_("Not same server principal returned "
523 "as requested", ""));
524 return KRB5KRB_AP_ERR_MODIFIED
;
531 * Verify referral data
535 static krb5_error_code
536 check_client_referral(krb5_context context
,
538 krb5_const_principal requested
,
539 krb5_const_principal mapped
,
540 krb5_keyblock
const * key
)
543 PA_ClientCanonicalized canon
;
550 if (rep
->kdc_rep
.padata
== NULL
)
553 pa
= krb5_find_padata(rep
->kdc_rep
.padata
->val
,
554 rep
->kdc_rep
.padata
->len
,
555 KRB5_PADATA_CLIENT_CANONICALIZED
, &i
);
559 ret
= decode_PA_ClientCanonicalized(pa
->padata_value
.data
,
560 pa
->padata_value
.length
,
563 krb5_set_error_message(context
, ret
,
564 N_("Failed to decode ClientCanonicalized "
565 "from realm %s", ""), requested
->realm
);
569 ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames
, data
.data
, data
.length
,
570 &canon
.names
, &len
, ret
);
572 free_PA_ClientCanonicalized(&canon
);
575 if (data
.length
!= len
)
576 krb5_abortx(context
, "internal asn.1 error");
578 ret
= krb5_crypto_init(context
, key
, 0, &crypto
);
581 free_PA_ClientCanonicalized(&canon
);
585 ret
= krb5_verify_checksum(context
, crypto
, KRB5_KU_CANONICALIZED_NAMES
,
586 data
.data
, data
.length
,
587 &canon
.canon_checksum
);
588 krb5_crypto_destroy(context
, crypto
);
591 krb5_set_error_message(context
, ret
,
592 N_("Failed to verify client canonicalized "
593 "data from realm %s", ""),
595 free_PA_ClientCanonicalized(&canon
);
599 if (!_krb5_principal_compare_PrincipalName(context
,
601 &canon
.names
.requested_name
))
603 free_PA_ClientCanonicalized(&canon
);
604 krb5_set_error_message(context
, KRB5_PRINC_NOMATCH
,
605 N_("Requested name doesn't match"
606 " in client referral", ""));
607 return KRB5_PRINC_NOMATCH
;
609 if (!_krb5_principal_compare_PrincipalName(context
,
611 &canon
.names
.mapped_name
))
613 free_PA_ClientCanonicalized(&canon
);
614 krb5_set_error_message(context
, KRB5_PRINC_NOMATCH
,
615 N_("Mapped name doesn't match"
616 " in client referral", ""));
617 return KRB5_PRINC_NOMATCH
;
623 if (krb5_principal_compare(context
, requested
, mapped
) == FALSE
&&
624 !rep
->enc_part
.flags
.enc_pa_rep
)
626 krb5_set_error_message(context
, KRB5KRB_AP_ERR_MODIFIED
,
627 N_("Not same client principal returned "
628 "as requested", ""));
629 return KRB5KRB_AP_ERR_MODIFIED
;
635 static krb5_error_code KRB5_CALLCONV
636 decrypt_tkt (krb5_context context
,
638 krb5_key_usage usage
,
639 krb5_const_pointer decrypt_arg
,
640 krb5_kdc_rep
*dec_rep
)
647 ret
= krb5_crypto_init(context
, key
, 0, &crypto
);
651 ret
= krb5_decrypt_EncryptedData (context
,
654 &dec_rep
->kdc_rep
.enc_part
,
656 krb5_crypto_destroy(context
, crypto
);
661 ret
= decode_EncASRepPart(data
.data
,
666 ret
= decode_EncTGSRepPart(data
.data
,
670 krb5_data_free (&data
);
672 krb5_set_error_message(context
, ret
,
673 N_("Failed to decode encpart in ticket", ""));
679 KRB5_LIB_FUNCTION
int KRB5_LIB_CALL
680 _krb5_extract_ticket(krb5_context context
,
684 krb5_const_pointer keyseed
,
685 krb5_key_usage key_usage
,
686 krb5_addresses
*addrs
,
690 krb5_decrypt_proc decrypt_proc
,
691 krb5_const_pointer decryptarg
)
694 krb5_principal tmp_principal
;
697 krb5_timestamp sec_now
;
701 if (decrypt_proc
== NULL
)
702 decrypt_proc
= decrypt_tkt
;
704 ret
= (*decrypt_proc
)(context
, key
, key_usage
, decryptarg
, rep
);
708 if (rep
->enc_part
.flags
.enc_pa_rep
&& request
) {
709 krb5_crypto crypto
= NULL
;
714 _krb5_debug(context
, 5, "processing enc-ap-rep");
716 if (rep
->enc_part
.encrypted_pa_data
== NULL
||
717 (pa
= krb5_find_padata(rep
->enc_part
.encrypted_pa_data
->val
,
718 rep
->enc_part
.encrypted_pa_data
->len
,
719 KRB5_PADATA_REQ_ENC_PA_REP
,
722 _krb5_debug(context
, 5, "KRB5_PADATA_REQ_ENC_PA_REP missing");
723 ret
= KRB5KRB_AP_ERR_MODIFIED
;
727 ret
= krb5_crypto_init(context
, key
, 0, &crypto
);
731 ret
= decode_Checksum(pa
->padata_value
.data
,
732 pa
->padata_value
.length
,
735 krb5_crypto_destroy(context
, crypto
);
739 ret
= krb5_verify_checksum(context
, crypto
,
741 request
->data
, request
->length
,
743 krb5_crypto_destroy(context
, crypto
);
744 free_Checksum(&cksum
);
745 _krb5_debug(context
, 5, "enc-ap-rep: %svalid", (ret
== 0) ? "" : "in");
750 /* save session key */
752 creds
->session
.keyvalue
.length
= 0;
753 creds
->session
.keyvalue
.data
= NULL
;
754 creds
->session
.keytype
= rep
->enc_part
.key
.keytype
;
755 ret
= krb5_data_copy (&creds
->session
.keyvalue
,
756 rep
->enc_part
.key
.keyvalue
.data
,
757 rep
->enc_part
.key
.keyvalue
.length
);
759 krb5_clear_error_message(context
);
763 /* compare client and save */
764 ret
= _krb5_principalname2krb5_principal(context
,
767 rep
->kdc_rep
.crealm
);
771 /* check client referral and save principal */
772 /* anonymous here ? */
773 if((flags
& EXTRACT_TICKET_ALLOW_CNAME_MISMATCH
) == 0) {
774 ret
= check_client_referral(context
, rep
,
779 krb5_free_principal (context
, tmp_principal
);
783 krb5_free_principal (context
, creds
->client
);
784 creds
->client
= tmp_principal
;
786 /* check server referral and save principal */
787 ret
= _krb5_principalname2krb5_principal (context
,
789 rep
->kdc_rep
.ticket
.sname
,
790 rep
->kdc_rep
.ticket
.realm
);
793 if((flags
& EXTRACT_TICKET_ALLOW_SERVER_MISMATCH
) == 0){
794 ret
= check_server_referral(context
,
801 krb5_free_principal (context
, tmp_principal
);
805 krb5_free_principal(context
, creds
->server
);
806 creds
->server
= tmp_principal
;
809 if(flags
& EXTRACT_TICKET_MATCH_REALM
){
810 const char *srealm
= krb5_principal_get_realm(context
, creds
->server
);
811 const char *crealm
= krb5_principal_get_realm(context
, creds
->client
);
813 if (strcmp(rep
->enc_part
.srealm
, srealm
) != 0 ||
814 strcmp(rep
->enc_part
.srealm
, crealm
) != 0)
816 ret
= KRB5KRB_AP_ERR_MODIFIED
;
817 krb5_clear_error_message(context
);
824 if (nonce
!= (unsigned)rep
->enc_part
.nonce
) {
825 ret
= KRB5KRB_AP_ERR_MODIFIED
;
826 krb5_set_error_message(context
, ret
, N_("malloc: out of memory", ""));
832 krb5_timeofday (context
, &sec_now
);
833 if (rep
->enc_part
.flags
.initial
834 && (flags
& EXTRACT_TICKET_TIMESYNC
)
835 && context
->kdc_sec_offset
== 0
836 && krb5_config_get_bool (context
, NULL
,
840 context
->kdc_sec_offset
= rep
->enc_part
.authtime
- sec_now
;
841 krb5_timeofday (context
, &sec_now
);
844 /* check all times */
846 if (rep
->enc_part
.starttime
) {
847 tmp_time
= *rep
->enc_part
.starttime
;
849 tmp_time
= rep
->enc_part
.authtime
;
851 if (creds
->times
.starttime
== 0
852 && abs(tmp_time
- sec_now
) > context
->max_skew
) {
853 ret
= KRB5KRB_AP_ERR_SKEW
;
854 krb5_set_error_message (context
, ret
,
855 N_("time skew (%d) larger than max (%d)", ""),
856 abs(tmp_time
- sec_now
),
857 (int)context
->max_skew
);
861 if (creds
->times
.starttime
!= 0
862 && tmp_time
!= creds
->times
.starttime
) {
863 krb5_clear_error_message (context
);
864 ret
= KRB5KRB_AP_ERR_MODIFIED
;
868 creds
->times
.starttime
= tmp_time
;
870 if (rep
->enc_part
.renew_till
) {
871 tmp_time
= *rep
->enc_part
.renew_till
;
875 if (creds
->times
.renew_till
!= 0
876 && tmp_time
> creds
->times
.renew_till
) {
877 krb5_clear_error_message (context
);
878 ret
= KRB5KRB_AP_ERR_MODIFIED
;
882 creds
->times
.renew_till
= tmp_time
;
884 creds
->times
.authtime
= rep
->enc_part
.authtime
;
886 if (creds
->times
.endtime
!= 0
887 && rep
->enc_part
.endtime
> creds
->times
.endtime
) {
888 krb5_clear_error_message (context
);
889 ret
= KRB5KRB_AP_ERR_MODIFIED
;
893 creds
->times
.endtime
= rep
->enc_part
.endtime
;
895 if(rep
->enc_part
.caddr
)
896 krb5_copy_addresses (context
, rep
->enc_part
.caddr
, &creds
->addresses
);
898 krb5_copy_addresses (context
, addrs
, &creds
->addresses
);
900 creds
->addresses
.len
= 0;
901 creds
->addresses
.val
= NULL
;
903 creds
->flags
.b
= rep
->enc_part
.flags
;
905 creds
->authdata
.len
= 0;
906 creds
->authdata
.val
= NULL
;
909 ASN1_MALLOC_ENCODE(Ticket
, creds
->ticket
.data
, creds
->ticket
.length
,
910 &rep
->kdc_rep
.ticket
, &len
, ret
);
913 if (creds
->ticket
.length
!= len
)
914 krb5_abortx(context
, "internal error in ASN.1 encoder");
915 creds
->second_ticket
.length
= 0;
916 creds
->second_ticket
.data
= NULL
;
920 memset (rep
->enc_part
.key
.keyvalue
.data
, 0,
921 rep
->enc_part
.key
.keyvalue
.length
);