/* Modify an AS-REP reply, change the msg_type to KRB5_TGS_REP. */ static krb5_error_code test_recv_modify_reply(krb5_context context, void *data, krb5_error_code code, const krb5_data *realm, const krb5_data *message, const krb5_data *reply, krb5_data **new_reply) { krb5_kdc_rep *as_rep; assert(code == 0); assert(krb5_is_as_rep(reply)); check(decode_krb5_as_rep(reply, &as_rep)); as_rep->msg_type = KRB5_TGS_REP; check(encode_krb5_as_rep(as_rep, new_reply)); krb5_free_kdc_rep(context, as_rep); return 0; }
/* due to argument promotion rules, we need to use the DECLARG/OLDDECLARG stuff... */ krb5_error_code krb5_encode_kdc_rep(krb5_context context, krb5_msgtype type, const krb5_enc_kdc_rep_part *encpart, int using_subkey, const krb5_keyblock *client_key, krb5_kdc_rep *dec_rep, krb5_data **enc_rep) { krb5_data *scratch; krb5_error_code retval; krb5_enc_kdc_rep_part tmp_encpart; krb5_keyusage usage; if (!krb5_c_valid_enctype(dec_rep->enc_part.enctype)) return KRB5_PROG_ETYPE_NOSUPP; switch (type) { case KRB5_AS_REP: usage = KRB5_KEYUSAGE_AS_REP_ENCPART; break; case KRB5_TGS_REP: if (using_subkey) usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY; else usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY; break; default: return KRB5_BADMSGTYPE; } /* * We don't want to modify encpart, but we need to be able to pass * in the message type to the encoder, so it can set the ASN.1 * type correct. * * Although note that it may be doing nothing with the message * type, to be compatible with old versions of Kerberos that always * encode this as a TGS_REP regardly of what it really should be; * also note that the reason why we are passing it in a structure * instead of as an argument to encode_krb5_enc_kdc_rep_part (the * way we should) is for compatibility with the ISODE version of * this fuction. Ah, compatibility.... */ tmp_encpart = *encpart; tmp_encpart.msg_type = type; retval = encode_krb5_enc_kdc_rep_part(&tmp_encpart, &scratch); if (retval) { return retval; } memset(&tmp_encpart, 0, sizeof(tmp_encpart)); #define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); \ krb5_free_data(context, scratch); } retval = krb5_encrypt_helper(context, client_key, usage, scratch, &dec_rep->enc_part); #define cleanup_encpart() { \ (void) memset(dec_rep->enc_part.ciphertext.data, 0, \ dec_rep->enc_part.ciphertext.length); \ free(dec_rep->enc_part.ciphertext.data); \ dec_rep->enc_part.ciphertext.length = 0; \ dec_rep->enc_part.ciphertext.data = 0;} cleanup_scratch(); if (retval) return(retval); /* now it's ready to be encoded for the wire! */ switch (type) { case KRB5_AS_REP: retval = encode_krb5_as_rep(dec_rep, enc_rep); break; case KRB5_TGS_REP: retval = encode_krb5_tgs_rep(dec_rep, enc_rep); break; } if (retval) cleanup_encpart(); return retval; }