2N/A/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2N/A/*
2N/A * src/lib/krb5/asn.1/krb5_decode.c
2N/A *
2N/A * Copyright 1994, 2008 by the Massachusetts Institute of Technology.
2N/A * All Rights Reserved.
2N/A *
2N/A * Export of this software from the United States of America may
2N/A * require a specific license from the United States Government.
2N/A * It is the responsibility of any person or organization contemplating
2N/A * export to obtain such a license before exporting.
2N/A *
2N/A * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
2N/A * distribute this software and its documentation for any purpose and
2N/A * without fee is hereby granted, provided that the above copyright
2N/A * notice appear in all copies and that both that copyright notice and
2N/A * this permission notice appear in supporting documentation, and that
2N/A * the name of M.I.T. not be used in advertising or publicity pertaining
2N/A * to distribution of the software without specific, written prior
2N/A * permission. Furthermore if you modify this software you must label
2N/A * your software as modified software and not distribute it in such a
2N/A * fashion that it might be confused with the original M.I.T. software.
2N/A * M.I.T. makes no representations about the suitability of
2N/A * this software for any purpose. It is provided "as is" without express
2N/A * or implied warranty.
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include "k5-int.h"
2N/A#include "krbasn1.h"
2N/A#include "asn1_k_decode.h"
2N/A#include "asn1_decode.h"
2N/A#include "asn1_get.h"
2N/A
2N/A/* Solaris Kerberos */
2N/A#include "kerberos_dtrace.h"
2N/A
2N/A/* setup *********************************************************/
2N/A/* set up variables */
2N/A/*
2N/A * the setup* macros can return, but are always used at function start
2N/A * and thus need no malloc cleanup
2N/A */
2N/A#define setup_buf_only(type) \
2N/A asn1_error_code retval; \
2N/A asn1buf buf; \
2N/A type rep = NULL; \
2N/A \
2N/A *repptr = NULL; \
2N/A retval = asn1buf_wrap_data(&buf,code); \
2N/A if (retval) return retval
2N/A
2N/A#define setup_no_tagnum(type) \
2N/A asn1_class asn1class; \
2N/A asn1_construction construction; \
2N/A setup_buf_only(type)
2N/A
2N/A#define setup_no_length(type) \
2N/A asn1_tagnum tagnum; \
2N/A setup_no_tagnum(type)
2N/A
2N/A#define setup(type) \
2N/A unsigned int length; \
2N/A setup_no_length(type)
2N/A
2N/A/* helper macros for cleanup */
2N/A#define clean_return(val) { retval = val; goto error_out; }
2N/A
2N/A/* alloc_field is the first thing to allocate storage that may need cleanup */
2N/A#define alloc_field(var) \
2N/A var = calloc(1,sizeof(*var)); \
2N/A if ((var) == NULL) clean_return(ENOMEM)
2N/A
2N/A/*
2N/A * Allocate a principal and initialize enough fields for
2N/A * krb5_free_principal to have defined behavior.
2N/A */
2N/A#define alloc_principal(var) \
2N/A alloc_field(var); \
2N/A var->realm.data = NULL; \
2N/A var->data = NULL
2N/A
2N/A/* process encoding header ***************************************/
2N/A/* decode tag and check that it == [APPLICATION tagnum] */
2N/A#define check_apptag(tagexpect) \
2N/A { \
2N/A taginfo t1; \
2N/A retval = asn1_get_tag_2(&buf, &t1); \
2N/A if (retval) clean_return (retval); \
2N/A if (t1.asn1class != APPLICATION || t1.construction != CONSTRUCTED) \
2N/A clean_return(ASN1_BAD_ID); \
2N/A if (t1.tagnum != (tagexpect)) clean_return(KRB5_BADMSGTYPE); \
2N/A asn1class = t1.asn1class; \
2N/A construction = t1.construction; \
2N/A tagnum = t1.tagnum; \
2N/A }
2N/A
2N/A
2N/A
2N/A/* process a structure *******************************************/
2N/A
2N/A/* decode an explicit tag and place the number in tagnum */
2N/A#define next_tag_from_buf(buf) \
2N/A { taginfo t2; \
2N/A retval = asn1_get_tag_2(&(buf), &t2); \
2N/A if (retval) clean_return(retval); \
2N/A asn1class = t2.asn1class; \
2N/A construction = t2.construction; \
2N/A tagnum = t2.tagnum; \
2N/A indef = t2.indef; \
2N/A taglen = t2.length; \
2N/A }
2N/A#define next_tag() next_tag_from_buf(subbuf)
2N/A
2N/A
2N/Astatic asn1_error_code
2N/Aasn1_get_eoc_tag (asn1buf *buf)
2N/A{
2N/A asn1_error_code retval;
2N/A taginfo t;
2N/A
2N/A retval = asn1_get_tag_2(buf, &t);
2N/A if (retval)
2N/A return retval;
2N/A if (t.asn1class != UNIVERSAL || t.tagnum || t.indef)
2N/A return ASN1_MISSING_EOC;
2N/A return 0;
2N/A}
2N/A
2N/A#define get_eoc() \
2N/A { \
2N/A retval = asn1_get_eoc_tag(&subbuf); \
2N/A if (retval) clean_return(retval); \
2N/A }
2N/A
2N/A/* decode sequence header and initialize tagnum with the first field */
2N/A#define begin_structure() \
2N/A unsigned int taglen; \
2N/A asn1buf subbuf; \
2N/A int seqindef; \
2N/A int indef; \
2N/A retval = asn1_get_sequence(&buf,&length,&seqindef); \
2N/A if (retval) clean_return(retval); \
2N/A retval = asn1buf_imbed(&subbuf,&buf,length,seqindef); \
2N/A if (retval) clean_return(retval); \
2N/A next_tag()
2N/A
2N/A#define end_structure() \
2N/A retval = asn1buf_sync(&buf,&subbuf,asn1class, \
2N/A tagnum,length,indef,seqindef); \
2N/A if (retval) clean_return(retval)
2N/A
2N/A/* process fields *******************************************/
2N/A/* normal fields ************************/
2N/A#define get_field_body(var,decoder) \
2N/A retval = decoder(&subbuf,&(var)); \
2N/A if (retval) clean_return(retval); \
2N/A if (indef) { get_eoc(); } \
2N/A next_tag()
2N/A
2N/A/*
2N/A * error_if_bad_tag
2N/A *
2N/A * Checks that the next tag is the expected one; returns with an error
2N/A * if not.
2N/A */
2N/A#define error_if_bad_tag(tagexpect) \
2N/A if (tagnum != (tagexpect)) { clean_return ((tagnum < (tagexpect)) ? ASN1_MISPLACED_FIELD : ASN1_MISSING_FIELD); }
2N/A
2N/A/*
2N/A * decode a field (<[UNIVERSAL id]> <length> <contents>)
2N/A * check that the id number == tagexpect then
2N/A * decode into var
2N/A * get the next tag
2N/A */
2N/A#define get_field(var,tagexpect,decoder) \
2N/A error_if_bad_tag(tagexpect); \
2N/A if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \
2N/A clean_return(ASN1_BAD_ID); \
2N/A get_field_body(var,decoder)
2N/A
2N/A/* decode (or skip, if not present) an optional field */
2N/A#define opt_field(var,tagexpect,decoder) \
2N/A if (asn1buf_remains(&subbuf, seqindef)) { \
2N/A if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \
2N/A clean_return(ASN1_BAD_ID); \
2N/A if (tagnum == (tagexpect)) { \
2N/A get_field_body(var,decoder); \
2N/A } \
2N/A }
2N/A
2N/A/* field w/ accompanying length *********/
2N/A#define get_lenfield_body(len,var,decoder) \
2N/A retval = decoder(&subbuf,&(len),&(var)); \
2N/A if (retval) clean_return(retval); \
2N/A if (indef) { get_eoc(); } \
2N/A next_tag()
2N/A
2N/A/* decode a field w/ its length (for string types) */
2N/A#define get_lenfield(len,var,tagexpect,decoder) \
2N/A error_if_bad_tag(tagexpect); \
2N/A if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \
2N/A clean_return(ASN1_BAD_ID); \
2N/A get_lenfield_body(len,var,decoder)
2N/A
2N/A/* decode an optional field w/ length */
2N/A#define opt_lenfield(len,var,tagexpect,decoder) \
2N/A if (asn1buf_remains(&subbuf, seqindef)) { \
2N/A if (asn1class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) \
2N/A clean_return(ASN1_BAD_ID); \
2N/A if (tagnum == (tagexpect)) { \
2N/A get_lenfield_body(len,var,decoder); \
2N/A } \
2N/A }
2N/A
2N/A
2N/A/* clean up ******************************************************/
2N/A/* finish up */
2N/A/* to make things less painful, assume the cleanup is passed rep */
2N/A#define cleanup(cleanup_routine) \
2N/A *repptr = rep; \
2N/A return 0; \
2N/Aerror_out: \
2N/Aif (rep) \
2N/A cleanup_routine(rep); \
2N/Areturn retval;
2N/A
2N/A#define cleanup_none() \
2N/A *repptr = rep; \
2N/A return 0; \
2N/Aerror_out: \
2N/Areturn retval;
2N/A
2N/A#define cleanup_manual() \
2N/A *repptr = rep; \
2N/A return 0;
2N/A
2N/A#define free_field(rep,f) free((rep)->f)
2N/A#define clear_field(rep,f) (rep)->f = 0
2N/A
2N/A#ifndef LEAN_CLIENT
2N/Akrb5_error_code
2N/Adecode_krb5_authenticator(const krb5_data *code, krb5_authenticator **repptr)
2N/A{
2N/A setup(krb5_authenticator *);
2N/A alloc_field(rep);
2N/A clear_field(rep,subkey);
2N/A clear_field(rep,checksum);
2N/A clear_field(rep,client);
2N/A clear_field(rep,authorization_data);
2N/A
2N/A check_apptag(2);
2N/A { begin_structure();
2N/A { krb5_kvno kvno;
2N/A get_field(kvno,0,asn1_decode_kvno);
2N/A if (kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); }
2N/A alloc_principal(rep->client);
2N/A get_field(rep->client,1,asn1_decode_realm);
2N/A get_field(rep->client,2,asn1_decode_principal_name);
2N/A opt_field(rep->checksum,3,asn1_decode_checksum_ptr);
2N/A get_field(rep->cusec,4,asn1_decode_int32);
2N/A get_field(rep->ctime,5,asn1_decode_kerberos_time);
2N/A opt_field(rep->subkey,6,asn1_decode_encryption_key_ptr);
2N/A opt_field(rep->seq_number,7,asn1_decode_seqnum);
2N/A opt_field(rep->authorization_data,8,asn1_decode_authorization_data);
2N/A rep->magic = KV5M_AUTHENTICATOR;
2N/A end_structure();
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_authenticator(NULL, rep);
2N/A return retval;
2N/A}
2N/A#endif
2N/A
2N/Akrb5_error_code KRB5_CALLCONV
2N/Akrb5_decode_ticket(const krb5_data *code, krb5_ticket **repptr)
2N/A{
2N/A return decode_krb5_ticket(code, repptr);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_ticket(const krb5_data *code, krb5_ticket **repptr)
2N/A{
2N/A setup(krb5_ticket *);
2N/A alloc_field(rep);
2N/A clear_field(rep,server);
2N/A clear_field(rep,enc_part.ciphertext.data);
2N/A clear_field(rep,enc_part2);
2N/A
2N/A check_apptag(1);
2N/A { begin_structure();
2N/A { krb5_kvno kvno;
2N/A get_field(kvno,0,asn1_decode_kvno);
2N/A if (kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO);
2N/A }
2N/A alloc_principal(rep->server);
2N/A get_field(rep->server,1,asn1_decode_realm);
2N/A get_field(rep->server,2,asn1_decode_principal_name);
2N/A get_field(rep->enc_part,3,asn1_decode_encrypted_data);
2N/A rep->magic = KV5M_TICKET;
2N/A end_structure();
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_ticket(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_encryption_key(const krb5_data *code, krb5_keyblock **repptr)
2N/A{
2N/A setup(krb5_keyblock *);
2N/A alloc_field(rep);
2N/A clear_field(rep,contents);
2N/A
2N/A { begin_structure();
2N/A get_field(rep->enctype,0,asn1_decode_enctype);
2N/A get_lenfield(rep->length,rep->contents,1,asn1_decode_octetstring);
2N/A end_structure();
2N/A rep->magic = KV5M_KEYBLOCK;
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_keyblock(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_enc_tkt_part(const krb5_data *code, krb5_enc_tkt_part **repptr)
2N/A{
2N/A setup(krb5_enc_tkt_part *);
2N/A alloc_field(rep);
2N/A clear_field(rep,session);
2N/A clear_field(rep,client);
2N/A clear_field(rep,transited.tr_contents.data);
2N/A clear_field(rep,caddrs);
2N/A clear_field(rep,authorization_data);
2N/A
2N/A check_apptag(3);
2N/A { begin_structure();
2N/A get_field(rep->flags,0,asn1_decode_ticket_flags);
2N/A get_field(rep->session,1,asn1_decode_encryption_key_ptr);
2N/A alloc_principal(rep->client);
2N/A get_field(rep->client,2,asn1_decode_realm);
2N/A get_field(rep->client,3,asn1_decode_principal_name);
2N/A get_field(rep->transited,4,asn1_decode_transited_encoding);
2N/A get_field(rep->times.authtime,5,asn1_decode_kerberos_time);
2N/A if (tagnum == 6)
2N/A { get_field(rep->times.starttime,6,asn1_decode_kerberos_time); }
2N/A else
2N/A rep->times.starttime=rep->times.authtime;
2N/A get_field(rep->times.endtime,7,asn1_decode_kerberos_time);
2N/A opt_field(rep->times.renew_till,8,asn1_decode_kerberos_time);
2N/A opt_field(rep->caddrs,9,asn1_decode_host_addresses);
2N/A opt_field(rep->authorization_data,10,asn1_decode_authorization_data);
2N/A rep->magic = KV5M_ENC_TKT_PART;
2N/A end_structure();
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_enc_tkt_part(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_enc_kdc_rep_part(const krb5_data *code,
2N/A krb5_enc_kdc_rep_part **repptr)
2N/A{
2N/A taginfo t4;
2N/A setup_buf_only(krb5_enc_kdc_rep_part *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_get_tag_2(&buf, &t4);
2N/A if (retval) clean_return(retval);
2N/A if (t4.asn1class != APPLICATION || t4.construction != CONSTRUCTED) clean_return(ASN1_BAD_ID);
2N/A if (t4.tagnum == 25) rep->msg_type = KRB5_AS_REP;
2N/A else if (t4.tagnum == 26) rep->msg_type = KRB5_TGS_REP;
2N/A else clean_return(KRB5_BADMSGTYPE);
2N/A
2N/A retval = asn1_decode_enc_kdc_rep_part(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_as_rep(const krb5_data *code, krb5_kdc_rep **repptr)
2N/A{
2N/A setup_no_length(krb5_kdc_rep *);
2N/A alloc_field(rep);
2N/A clear_field(rep,padata);
2N/A clear_field(rep,client);
2N/A clear_field(rep,ticket);
2N/A clear_field(rep,enc_part.ciphertext.data);
2N/A clear_field(rep,enc_part2);
2N/A
2N/A check_apptag(11);
2N/A retval = asn1_decode_kdc_rep(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A#ifdef KRB5_MSGTYPE_STRICT
2N/A if (rep->msg_type != KRB5_AS_REP)
2N/A clean_return(KRB5_BADMSGTYPE);
2N/A#endif
2N/A
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_kdc_rep(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_tgs_rep(const krb5_data *code, krb5_kdc_rep **repptr)
2N/A{
2N/A setup_no_length(krb5_kdc_rep *);
2N/A alloc_field(rep);
2N/A clear_field(rep,padata);
2N/A clear_field(rep,client);
2N/A clear_field(rep,ticket);
2N/A clear_field(rep,enc_part.ciphertext.data);
2N/A clear_field(rep,enc_part2);
2N/A
2N/A check_apptag(13);
2N/A retval = asn1_decode_kdc_rep(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A#ifdef KRB5_MSGTYPE_STRICT
2N/A if (rep->msg_type != KRB5_TGS_REP) clean_return(KRB5_BADMSGTYPE);
2N/A#endif
2N/A
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_kdc_rep(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_ap_req(const krb5_data *code, krb5_ap_req **repptr)
2N/A{
2N/A setup(krb5_ap_req *);
2N/A alloc_field(rep);
2N/A clear_field(rep,ticket);
2N/A clear_field(rep,authenticator.ciphertext.data);
2N/A
2N/A check_apptag(14);
2N/A { begin_structure();
2N/A { krb5_kvno kvno;
2N/A get_field(kvno,0,asn1_decode_kvno);
2N/A if (kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); }
2N/A { krb5_msgtype msg_type;
2N/A get_field(msg_type,1,asn1_decode_msgtype);
2N/A#ifdef KRB5_MSGTYPE_STRICT
2N/A if (msg_type != KRB5_AP_REQ) clean_return(KRB5_BADMSGTYPE);
2N/A#endif
2N/A }
2N/A get_field(rep->ap_options,2,asn1_decode_ap_options);
2N/A get_field(rep->ticket,3,asn1_decode_ticket_ptr);
2N/A get_field(rep->authenticator,4,asn1_decode_encrypted_data);
2N/A end_structure();
2N/A rep->magic = KV5M_AP_REQ;
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_ap_req(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_ap_rep(const krb5_data *code, krb5_ap_rep **repptr)
2N/A{
2N/A setup(krb5_ap_rep *);
2N/A alloc_field(rep);
2N/A clear_field(rep,enc_part.ciphertext.data);
2N/A
2N/A check_apptag(15);
2N/A { begin_structure();
2N/A { krb5_kvno kvno;
2N/A get_field(kvno,0,asn1_decode_kvno);
2N/A if (kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); }
2N/A { krb5_msgtype msg_type;
2N/A get_field(msg_type,1,asn1_decode_msgtype);
2N/A#ifdef KRB5_MSGTYPE_STRICT
2N/A if (msg_type != KRB5_AP_REP) clean_return(KRB5_BADMSGTYPE);
2N/A#endif
2N/A }
2N/A get_field(rep->enc_part,2,asn1_decode_encrypted_data);
2N/A end_structure();
2N/A rep->magic = KV5M_AP_REP;
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_ap_rep(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_ap_rep_enc_part(const krb5_data *code,
2N/A krb5_ap_rep_enc_part **repptr)
2N/A{
2N/A setup(krb5_ap_rep_enc_part *);
2N/A alloc_field(rep);
2N/A clear_field(rep,subkey);
2N/A
2N/A check_apptag(27);
2N/A { begin_structure();
2N/A get_field(rep->ctime,0,asn1_decode_kerberos_time);
2N/A get_field(rep->cusec,1,asn1_decode_int32);
2N/A opt_field(rep->subkey,2,asn1_decode_encryption_key_ptr);
2N/A opt_field(rep->seq_number,3,asn1_decode_seqnum);
2N/A end_structure();
2N/A rep->magic = KV5M_AP_REP_ENC_PART;
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_ap_rep_enc_part(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_as_req(const krb5_data *code, krb5_kdc_req **repptr)
2N/A{
2N/A setup_no_length(krb5_kdc_req *);
2N/A alloc_field(rep);
2N/A clear_field(rep,padata);
2N/A clear_field(rep,client);
2N/A clear_field(rep,server);
2N/A clear_field(rep,ktype);
2N/A clear_field(rep,addresses);
2N/A clear_field(rep,authorization_data.ciphertext.data);
2N/A clear_field(rep,unenc_authdata);
2N/A clear_field(rep,second_ticket);
2N/A clear_field(rep, kdc_state);
2N/A
2N/A check_apptag(10);
2N/A retval = asn1_decode_kdc_req(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A#ifdef KRB5_MSGTYPE_STRICT
2N/A if (rep->msg_type != KRB5_AS_REQ) clean_return(KRB5_BADMSGTYPE);
2N/A#endif
2N/A
2N/A /* Solaris Kerberos */
2N/A k5_trace_kdc_req_read(code, rep);
2N/A
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_kdc_req(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_tgs_req(const krb5_data *code, krb5_kdc_req **repptr)
2N/A{
2N/A setup_no_length(krb5_kdc_req *);
2N/A alloc_field(rep);
2N/A clear_field(rep,padata);
2N/A clear_field(rep,client);
2N/A clear_field(rep,server);
2N/A clear_field(rep,ktype);
2N/A clear_field(rep,addresses);
2N/A clear_field(rep,authorization_data.ciphertext.data);
2N/A clear_field(rep,unenc_authdata);
2N/A clear_field(rep,second_ticket);
2N/A clear_field(rep, kdc_state);
2N/A
2N/A check_apptag(12);
2N/A retval = asn1_decode_kdc_req(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A#ifdef KRB5_MSGTYPE_STRICT
2N/A if (rep->msg_type != KRB5_TGS_REQ) clean_return(KRB5_BADMSGTYPE);
2N/A#endif
2N/A
2N/A /* Solaris Kerberos */
2N/A k5_trace_kdc_req_read(code, rep);
2N/A
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_kdc_req(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_kdc_req_body(const krb5_data *code, krb5_kdc_req **repptr)
2N/A{
2N/A setup_buf_only(krb5_kdc_req *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_kdc_req_body(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/A/*
2N/A * decode_krb5_safe_with_body
2N/A *
2N/A * Like decode_krb5_safe(), but grabs the encoding of the
2N/A * KRB-SAFE-BODY as well, in case re-encoding would produce a
2N/A * different encoding. (Yes, we're using DER, but there's this
2N/A * annoying problem with pre-1.3.x code using signed sequence numbers,
2N/A * which we permissively decode and cram into unsigned 32-bit numbers.
2N/A * When they're re-encoded, they're no longer negative if they started
2N/A * out negative, so checksum verification fails.)
2N/A *
2N/A * This does *not* perform any copying; the returned pointer to the
2N/A * encoded KRB-SAFE-BODY points into the input buffer.
2N/A */
2N/Akrb5_error_code
2N/Adecode_krb5_safe_with_body(const krb5_data *code, krb5_safe **repptr,
2N/A krb5_data *body)
2N/A{
2N/A krb5_data tmpbody;
2N/A setup(krb5_safe *);
2N/A alloc_field(rep);
2N/A clear_field(rep,user_data.data);
2N/A clear_field(rep,r_address);
2N/A clear_field(rep,s_address);
2N/A clear_field(rep,checksum);
2N/A tmpbody.magic = 0;
2N/A
2N/A check_apptag(20);
2N/A { begin_structure();
2N/A { krb5_kvno kvno;
2N/A get_field(kvno,0,asn1_decode_kvno);
2N/A if (kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); }
2N/A { krb5_msgtype msg_type;
2N/A get_field(msg_type,1,asn1_decode_msgtype);
2N/A#ifdef KRB5_MSGTYPE_STRICT
2N/A if (msg_type != KRB5_SAFE) clean_return(KRB5_BADMSGTYPE);
2N/A#endif
2N/A }
2N/A /*
2N/A * Gross kludge to extract pointer to encoded safe-body. Relies
2N/A * on tag prefetch done by next_tag(). Don't handle indefinite
2N/A * encoding, as it's too much work.
2N/A */
2N/A if (!indef) {
2N/A tmpbody.length = taglen;
2N/A tmpbody.data = subbuf.next;
2N/A } else {
2N/A tmpbody.length = 0;
2N/A tmpbody.data = NULL;
2N/A }
2N/A get_field(*rep,2,asn1_decode_krb_safe_body);
2N/A get_field(rep->checksum,3,asn1_decode_checksum_ptr);
2N/A rep->magic = KV5M_SAFE;
2N/A end_structure();
2N/A }
2N/A if (body != NULL)
2N/A *body = tmpbody;
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_safe(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_safe(const krb5_data *code, krb5_safe **repptr)
2N/A{
2N/A return decode_krb5_safe_with_body(code, repptr, NULL);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_priv(const krb5_data *code, krb5_priv **repptr)
2N/A{
2N/A setup(krb5_priv *);
2N/A alloc_field(rep);
2N/A clear_field(rep,enc_part.ciphertext.data);
2N/A
2N/A check_apptag(21);
2N/A { begin_structure();
2N/A { krb5_kvno kvno;
2N/A get_field(kvno,0,asn1_decode_kvno);
2N/A if (kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); }
2N/A { krb5_msgtype msg_type;
2N/A get_field(msg_type,1,asn1_decode_msgtype);
2N/A#ifdef KRB5_MSGTYPE_STRICT
2N/A if (msg_type != KRB5_PRIV) clean_return(KRB5_BADMSGTYPE);
2N/A#endif
2N/A }
2N/A get_field(rep->enc_part,3,asn1_decode_encrypted_data);
2N/A rep->magic = KV5M_PRIV;
2N/A end_structure();
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_priv(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_enc_priv_part(const krb5_data *code, krb5_priv_enc_part **repptr)
2N/A{
2N/A setup(krb5_priv_enc_part *);
2N/A alloc_field(rep);
2N/A clear_field(rep,user_data.data);
2N/A clear_field(rep,r_address);
2N/A clear_field(rep,s_address);
2N/A
2N/A check_apptag(28);
2N/A { begin_structure();
2N/A get_lenfield(rep->user_data.length,rep->user_data.data,0,asn1_decode_charstring);
2N/A opt_field(rep->timestamp,1,asn1_decode_kerberos_time);
2N/A opt_field(rep->usec,2,asn1_decode_int32);
2N/A opt_field(rep->seq_number,3,asn1_decode_seqnum);
2N/A get_field(rep->s_address,4,asn1_decode_host_address_ptr);
2N/A opt_field(rep->r_address,5,asn1_decode_host_address_ptr);
2N/A rep->magic = KV5M_PRIV_ENC_PART;
2N/A end_structure();
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_priv_enc_part(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_checksum(const krb5_data *code, krb5_checksum **repptr)
2N/A{
2N/A setup_buf_only(krb5_checksum *);
2N/A alloc_field(rep);
2N/A retval = asn1_decode_checksum(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_cred(const krb5_data *code, krb5_cred **repptr)
2N/A{
2N/A setup(krb5_cred *);
2N/A alloc_field(rep);
2N/A clear_field(rep,tickets);
2N/A clear_field(rep,enc_part.ciphertext.data);
2N/A
2N/A check_apptag(22);
2N/A { begin_structure();
2N/A { krb5_kvno kvno;
2N/A get_field(kvno,0,asn1_decode_kvno);
2N/A if (kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); }
2N/A { krb5_msgtype msg_type;
2N/A get_field(msg_type,1,asn1_decode_msgtype);
2N/A#ifdef KRB5_MSGTYPE_STRICT
2N/A if (msg_type != KRB5_CRED) clean_return(KRB5_BADMSGTYPE);
2N/A#endif
2N/A }
2N/A get_field(rep->tickets,2,asn1_decode_sequence_of_ticket);
2N/A get_field(rep->enc_part,3,asn1_decode_encrypted_data);
2N/A rep->magic = KV5M_CRED;
2N/A end_structure();
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_cred(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_enc_cred_part(const krb5_data *code, krb5_cred_enc_part **repptr)
2N/A{
2N/A setup(krb5_cred_enc_part *);
2N/A alloc_field(rep);
2N/A clear_field(rep,r_address);
2N/A clear_field(rep,s_address);
2N/A clear_field(rep,ticket_info);
2N/A
2N/A check_apptag(29);
2N/A { begin_structure();
2N/A get_field(rep->ticket_info,0,asn1_decode_sequence_of_krb_cred_info);
2N/A opt_field(rep->nonce,1,asn1_decode_int32);
2N/A opt_field(rep->timestamp,2,asn1_decode_kerberos_time);
2N/A opt_field(rep->usec,3,asn1_decode_int32);
2N/A opt_field(rep->s_address,4,asn1_decode_host_address_ptr);
2N/A opt_field(rep->r_address,5,asn1_decode_host_address_ptr);
2N/A rep->magic = KV5M_CRED_ENC_PART;
2N/A end_structure();
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A /* Despite the name, krb5_free_cred_enc_part is contents only. */
2N/A krb5_free_cred_enc_part(NULL, rep);
2N/A free(rep);
2N/A return retval;
2N/A}
2N/A
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_error(const krb5_data *code, krb5_error **repptr)
2N/A{
2N/A setup(krb5_error *);
2N/A alloc_field(rep);
2N/A clear_field(rep,server);
2N/A clear_field(rep,client);
2N/A clear_field(rep,text.data);
2N/A clear_field(rep,e_data.data);
2N/A
2N/A check_apptag(30);
2N/A { begin_structure();
2N/A { krb5_kvno kvno;
2N/A get_field(kvno,0,asn1_decode_kvno);
2N/A if (kvno != KVNO) clean_return(KRB5KDC_ERR_BAD_PVNO); }
2N/A { krb5_msgtype msg_type;
2N/A get_field(msg_type,1,asn1_decode_msgtype);
2N/A#ifdef KRB5_MSGTYPE_STRICT
2N/A if (msg_type != KRB5_ERROR) clean_return(KRB5_BADMSGTYPE);
2N/A#endif
2N/A }
2N/A opt_field(rep->ctime,2,asn1_decode_kerberos_time);
2N/A opt_field(rep->cusec,3,asn1_decode_int32);
2N/A get_field(rep->stime,4,asn1_decode_kerberos_time);
2N/A get_field(rep->susec,5,asn1_decode_int32);
2N/A get_field(rep->error,6,asn1_decode_ui_4);
2N/A if (tagnum == 7) { alloc_principal(rep->client); }
2N/A opt_field(rep->client,7,asn1_decode_realm);
2N/A opt_field(rep->client,8,asn1_decode_principal_name);
2N/A alloc_principal(rep->server);
2N/A get_field(rep->server,9,asn1_decode_realm);
2N/A get_field(rep->server,10,asn1_decode_principal_name);
2N/A opt_lenfield(rep->text.length,rep->text.data,11,asn1_decode_generalstring);
2N/A opt_lenfield(rep->e_data.length,rep->e_data.data,12,asn1_decode_charstring);
2N/A rep->magic = KV5M_ERROR;
2N/A end_structure();
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_error(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_authdata(const krb5_data *code, krb5_authdata ***repptr)
2N/A{
2N/A setup_buf_only(krb5_authdata **);
2N/A retval = asn1_decode_authorization_data(&buf,&rep);
2N/A if (retval) clean_return(retval);
2N/A cleanup_none(); /* we're not allocating anything here... */
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_pwd_sequence(const krb5_data *code, passwd_phrase_element **repptr)
2N/A{
2N/A setup_buf_only(passwd_phrase_element *);
2N/A alloc_field(rep);
2N/A retval = asn1_decode_passwdsequence(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_pwd_data(const krb5_data *code, krb5_pwd_data **repptr)
2N/A{
2N/A setup(krb5_pwd_data *);
2N/A alloc_field(rep);
2N/A clear_field(rep,element);
2N/A { begin_structure();
2N/A get_field(rep->sequence_count,0,asn1_decode_int);
2N/A get_field(rep->element,1,asn1_decode_sequence_of_passwdsequence);
2N/A rep->magic = KV5M_PWD_DATA;
2N/A end_structure (); }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_pwd_data(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_padata_sequence(const krb5_data *code, krb5_pa_data ***repptr)
2N/A{
2N/A setup_buf_only(krb5_pa_data **);
2N/A retval = asn1_decode_sequence_of_pa_data(&buf,&rep);
2N/A if (retval) clean_return(retval);
2N/A cleanup_none(); /* we're not allocating anything here */
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_alt_method(const krb5_data *code, krb5_alt_method **repptr)
2N/A{
2N/A setup(krb5_alt_method *);
2N/A alloc_field(rep);
2N/A clear_field(rep,data);
2N/A { begin_structure();
2N/A get_field(rep->method,0,asn1_decode_int32);
2N/A if (tagnum == 1) {
2N/A get_lenfield(rep->length,rep->data,1,asn1_decode_octetstring);
2N/A } else {
2N/A rep->length = 0;
2N/A rep->data = 0;
2N/A }
2N/A rep->magic = KV5M_ALT_METHOD;
2N/A end_structure();
2N/A }
2N/A cleanup_manual();
2N/Aerror_out:
2N/A krb5_free_alt_method(NULL, rep);
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_etype_info(const krb5_data *code, krb5_etype_info_entry ***repptr)
2N/A{
2N/A setup_buf_only(krb5_etype_info_entry **);
2N/A retval = asn1_decode_etype_info(&buf,&rep);
2N/A if (retval) clean_return(retval);
2N/A cleanup_none(); /* we're not allocating anything here */
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_etype_info2(const krb5_data *code, krb5_etype_info_entry ***repptr)
2N/A{
2N/A setup_buf_only(krb5_etype_info_entry **);
2N/A retval = asn1_decode_etype_info2(&buf,&rep, 0);
2N/A if (retval == ASN1_BAD_ID) {
2N/A retval = asn1buf_wrap_data(&buf,code);
2N/A if (retval) clean_return(retval);
2N/A retval = asn1_decode_etype_info2(&buf, &rep, 1);
2N/A }
2N/A if (retval) clean_return(retval);
2N/A cleanup_none(); /* we're not allocating anything here */
2N/A}
2N/A
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_enc_data(const krb5_data *code, krb5_enc_data **repptr)
2N/A{
2N/A setup_buf_only(krb5_enc_data *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_encrypted_data(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_pa_enc_ts(const krb5_data *code, krb5_pa_enc_ts **repptr)
2N/A{
2N/A setup(krb5_pa_enc_ts *);
2N/A alloc_field(rep);
2N/A { begin_structure();
2N/A get_field(rep->patimestamp,0,asn1_decode_kerberos_time);
2N/A if (tagnum == 1) {
2N/A get_field(rep->pausec,1,asn1_decode_int32);
2N/A } else
2N/A rep->pausec = 0;
2N/A end_structure (); }
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_sam_challenge(const krb5_data *code, krb5_sam_challenge **repptr)
2N/A{
2N/A setup_buf_only(krb5_sam_challenge *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_sam_challenge(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_sam_challenge_2(const krb5_data *code,
2N/A krb5_sam_challenge_2 **repptr)
2N/A{
2N/A setup_buf_only(krb5_sam_challenge_2 *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_sam_challenge_2(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_sam_challenge_2_body(const krb5_data *code,
2N/A krb5_sam_challenge_2_body **repptr)
2N/A{
2N/A setup_buf_only(krb5_sam_challenge_2_body *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_sam_challenge_2_body(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_enc_sam_key(const krb5_data *code, krb5_sam_key **repptr)
2N/A{
2N/A setup_buf_only(krb5_sam_key *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_enc_sam_key(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_enc_sam_response_enc(const krb5_data *code,
2N/A krb5_enc_sam_response_enc **repptr)
2N/A{
2N/A setup_buf_only(krb5_enc_sam_response_enc *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_enc_sam_response_enc(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_enc_sam_response_enc_2(const krb5_data *code,
2N/A krb5_enc_sam_response_enc_2 **repptr)
2N/A{
2N/A setup_buf_only(krb5_enc_sam_response_enc_2 *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_enc_sam_response_enc_2(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_sam_response(const krb5_data *code,
2N/A krb5_sam_response **repptr)
2N/A{
2N/A setup_buf_only(krb5_sam_response *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_sam_response(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_sam_response_2(const krb5_data *code,
2N/A krb5_sam_response_2 **repptr)
2N/A{
2N/A setup_buf_only(krb5_sam_response_2 *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_sam_response_2(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_predicted_sam_response(const krb5_data *code,
2N/A krb5_predicted_sam_response **repptr)
2N/A{
2N/A setup_buf_only(krb5_predicted_sam_response *); /* preallocated */
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_predicted_sam_response(&buf,rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_setpw_req(const krb5_data *code, krb5_data **repptr,
2N/A krb5_principal *principal)
2N/A{
2N/A setup_buf_only(krb5_data *);
2N/A alloc_field(rep);
2N/A *principal = NULL;
2N/A
2N/A retval = asn1_decode_setpw_req(&buf, rep, principal);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_pa_for_user(const krb5_data *code, krb5_pa_for_user **repptr)
2N/A{
2N/A setup_buf_only(krb5_pa_for_user *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_pa_for_user(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_pa_s4u_x509_user(const krb5_data *code, krb5_pa_s4u_x509_user **repptr)
2N/A{
2N/A setup_buf_only(krb5_pa_s4u_x509_user *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_pa_s4u_x509_user(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_pa_pac_req(const krb5_data *code, krb5_pa_pac_req **repptr)
2N/A{
2N/A setup_buf_only(krb5_pa_pac_req *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_pa_pac_req(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_etype_list(const krb5_data *code, krb5_etype_list **repptr)
2N/A{
2N/A setup_buf_only(krb5_etype_list *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_sequence_of_enctype(&buf, &rep->length, &rep->etypes);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code decode_krb5_pa_fx_fast_request
2N/A(const krb5_data *code, krb5_fast_armored_req **repptr)
2N/A{
2N/A setup(krb5_fast_armored_req *);
2N/A alloc_field(rep);
2N/A clear_field(rep, armor);
2N/A {
2N/A int indef;
2N/A unsigned int taglen;
2N/A next_tag_from_buf(buf);
2N/A if (tagnum != 0)
2N/A clean_return(ASN1_BAD_ID);
2N/A }
2N/A {begin_structure();
2N/A opt_field(rep->armor, 0, asn1_decode_fast_armor_ptr);
2N/A get_field(rep->req_checksum, 1, asn1_decode_checksum);
2N/A get_field(rep->enc_part, 2, asn1_decode_encrypted_data);
2N/A end_structure();}
2N/A rep->magic = KV5M_FAST_ARMORED_REQ;
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code decode_krb5_fast_req
2N/A(const krb5_data *code, krb5_fast_req **repptr)
2N/A{
2N/A setup(krb5_fast_req *);
2N/A alloc_field(rep);
2N/A alloc_field(rep->req_body);
2N/A clear_field(rep, req_body->padata);
2N/A {begin_structure();
2N/A get_field(rep->fast_options, 0, asn1_decode_krb5_flags);
2N/A opt_field(rep->req_body->padata, 1, asn1_decode_sequence_of_pa_data);
2N/A get_field(*(rep->req_body), 2, asn1_decode_kdc_req_body);
2N/A end_structure(); }
2N/A rep->magic = KV5M_FAST_REQ;
2N/A cleanup_manual();
2N/Aerror_out:
2N/A if (rep) {
2N/A if (rep->req_body)
2N/A krb5_free_kdc_req(0, rep->req_body);
2N/A free(rep);
2N/A }
2N/A return retval;
2N/A}
2N/A
2N/Akrb5_error_code decode_krb5_fast_response
2N/A(const krb5_data *code, krb5_fast_response **repptr)
2N/A{
2N/A setup(krb5_fast_response *);
2N/A
2N/A alloc_field(rep);
2N/A clear_field(rep, finished);
2N/A clear_field(rep, padata);
2N/A clear_field(rep,strengthen_key);
2N/A {begin_structure();
2N/A get_field(rep->padata, 0, asn1_decode_sequence_of_pa_data);
2N/A opt_field(rep->strengthen_key, 1, asn1_decode_encryption_key_ptr);
2N/A opt_field(rep->finished, 2, asn1_decode_fast_finished_ptr);
2N/A get_field(rep->nonce, 3, asn1_decode_int32);
2N/A end_structure(); }
2N/A rep->magic = KV5M_FAST_RESPONSE;
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code decode_krb5_pa_fx_fast_reply
2N/A(const krb5_data *code, krb5_enc_data **repptr)
2N/A{
2N/A setup(krb5_enc_data *);
2N/A alloc_field(rep);
2N/A {
2N/A int indef;
2N/A unsigned int taglen;
2N/A next_tag_from_buf(buf);
2N/A if (tagnum != 0)
2N/A clean_return(ASN1_BAD_ID);
2N/A }
2N/A {begin_structure();
2N/A get_field(*rep, 0, asn1_decode_encrypted_data);
2N/A end_structure();
2N/A }
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_ad_kdcissued(const krb5_data *code, krb5_ad_kdcissued **repptr)
2N/A{
2N/A setup_buf_only(krb5_ad_kdcissued *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_ad_kdcissued(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_ad_signedpath(const krb5_data *code, krb5_ad_signedpath **repptr)
2N/A{
2N/A setup_buf_only(krb5_ad_signedpath *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_ad_signedpath(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Akrb5int_get_authdata_containee_types(krb5_context context,
2N/A const krb5_authdata *authdata,
2N/A unsigned int *num,
2N/A krb5_authdatatype **repptr)
2N/A{
2N/A krb5_data data, *code = &data;
2N/A
2N/A data.data = (char *)authdata->contents;
2N/A data.length = authdata->length;
2N/A
2N/A *num = 0;
2N/A
2N/A {
2N/A setup_buf_only(krb5_authdatatype *);
2N/A
2N/A retval = asn1_peek_authorization_data(&buf, num, &rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup_none();
2N/A }
2N/A assert(0); /* NOTREACHED */
2N/A}
2N/A
2N/A#ifndef DISABLE_PKINIT
2N/Akrb5_error_code
2N/Adecode_krb5_pa_pk_as_req(const krb5_data *code, krb5_pa_pk_as_req **repptr)
2N/A{
2N/A setup_buf_only(krb5_pa_pk_as_req *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_pa_pk_as_req(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_pa_pk_as_req_draft9(const krb5_data *code,
2N/A krb5_pa_pk_as_req_draft9 **repptr)
2N/A{
2N/A setup_buf_only(krb5_pa_pk_as_req_draft9 *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_pa_pk_as_req_draft9(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_pa_pk_as_rep(const krb5_data *code, krb5_pa_pk_as_rep **repptr)
2N/A{
2N/A setup_buf_only(krb5_pa_pk_as_rep *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_pa_pk_as_rep(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_pa_pk_as_rep_draft9(const krb5_data *code,
2N/A krb5_pa_pk_as_rep_draft9 **repptr)
2N/A{
2N/A setup_buf_only(krb5_pa_pk_as_rep_draft9 *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_pa_pk_as_rep_draft9(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_auth_pack(const krb5_data *code, krb5_auth_pack **repptr)
2N/A{
2N/A setup_buf_only(krb5_auth_pack *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_auth_pack(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_auth_pack_draft9(const krb5_data *code,
2N/A krb5_auth_pack_draft9 **repptr)
2N/A{
2N/A setup_buf_only(krb5_auth_pack_draft9 *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_auth_pack_draft9(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_kdc_dh_key_info(const krb5_data *code,
2N/A krb5_kdc_dh_key_info **repptr)
2N/A{
2N/A setup_buf_only(krb5_kdc_dh_key_info *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_kdc_dh_key_info(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_principal_name(const krb5_data *code, krb5_principal_data **repptr)
2N/A{
2N/A setup_buf_only(krb5_principal_data *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_krb5_principal_name(&buf, &rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_reply_key_pack(const krb5_data *code, krb5_reply_key_pack **repptr)
2N/A{
2N/A setup_buf_only(krb5_reply_key_pack *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_reply_key_pack(&buf, rep);
2N/A if (retval)
2N/A goto error_out;
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_reply_key_pack_draft9(const krb5_data *code,
2N/A krb5_reply_key_pack_draft9 **repptr)
2N/A{
2N/A setup_buf_only(krb5_reply_key_pack_draft9 *);
2N/A alloc_field(rep);
2N/A
2N/A retval = asn1_decode_reply_key_pack_draft9(&buf, rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_td_trusted_certifiers(const krb5_data *code,
2N/A krb5_external_principal_identifier ***repptr)
2N/A{
2N/A setup_buf_only(krb5_external_principal_identifier **);
2N/A retval = asn1_decode_sequence_of_external_principal_identifier(&buf, &rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_td_dh_parameters(const krb5_data *code,
2N/A krb5_algorithm_identifier ***repptr)
2N/A{
2N/A setup_buf_only(krb5_algorithm_identifier **);
2N/A retval = asn1_decode_sequence_of_algorithm_identifier(&buf, &rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}
2N/A#endif /* DISABLE_PKINIT */
2N/A
2N/Akrb5_error_code
2N/Adecode_krb5_typed_data(const krb5_data *code, krb5_typed_data ***repptr)
2N/A{
2N/A setup_buf_only(krb5_typed_data **);
2N/A retval = asn1_decode_sequence_of_typed_data(&buf, &rep);
2N/A if (retval) clean_return(retval);
2N/A
2N/A cleanup(free);
2N/A}