1 #pragma ident "%Z%%M% %I% %E% SMI" 2 /* 3 * lib/krb5/krb/encode_kdc.c 4 * 5 * Copyright 1990 by the Massachusetts Institute of Technology. 6 * All Rights Reserved. 7 * 8 * Export of this software from the United States of America may 9 * require a specific license from the United States Government. 10 * It is the responsibility of any person or organization contemplating 11 * export to obtain such a license before exporting. 12 * 13 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 14 * distribute this software and its documentation for any purpose and 15 * without fee is hereby granted, provided that the above copyright 16 * notice appear in all copies and that both that copyright notice and 17 * this permission notice appear in supporting documentation, and that 18 * the name of M.I.T. not be used in advertising or publicity pertaining 19 * to distribution of the software without specific, written prior 20 * permission. Furthermore if you modify this software you must label 21 * your software as modified software and not distribute it in such a 22 * fashion that it might be confused with the original M.I.T. software. 23 * M.I.T. makes no representations about the suitability of 24 * this software for any purpose. It is provided "as is" without express 25 * or implied warranty. 26 * 27 * 28 * krb5_encode_kdc_rep() function. 29 */ 30 31 #include <k5-int.h> 32 33 /* 34 Takes KDC rep parts in *rep and *encpart, and formats it into *enc_rep, 35 using message type type and encryption key client_key and encryption type 36 etype. 37 38 The string *enc_rep will be allocated before formatting; the caller should 39 free when finished. 40 41 returns system errors 42 43 dec_rep->enc_part.ciphertext is allocated and filled in. 44 */ 45 /* due to argument promotion rules, we need to use the DECLARG/OLDDECLARG 46 stuff... */ 47 krb5_error_code 48 krb5_encode_kdc_rep(krb5_context context, krb5_msgtype type, 49 const krb5_enc_kdc_rep_part *encpart, 50 int using_subkey, const krb5_keyblock *client_key, 51 krb5_kdc_rep *dec_rep, krb5_data **enc_rep) 52 { 53 krb5_data *scratch; 54 krb5_error_code retval; 55 krb5_enc_kdc_rep_part tmp_encpart; 56 krb5_keyusage usage; 57 58 if (!valid_enctype(dec_rep->enc_part.enctype)) 59 return KRB5_PROG_ETYPE_NOSUPP; 60 61 switch (type) { 62 case KRB5_AS_REP: 63 usage = KRB5_KEYUSAGE_AS_REP_ENCPART; 64 break; 65 case KRB5_TGS_REP: 66 if (using_subkey) 67 usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY; 68 else 69 usage = KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY; 70 break; 71 default: 72 return KRB5_BADMSGTYPE; 73 } 74 75 /* 76 * We don't want to modify encpart, but we need to be able to pass 77 * in the message type to the encoder, so it can set the ASN.1 78 * type correct. 79 * 80 * Although note that it may be doing nothing with the message 81 * type, to be compatible with old versions of Kerberos that always 82 * encode this as a TGS_REP regardly of what it really should be; 83 * also note that the reason why we are passing it in a structure 84 * instead of as an argument to encode_krb5_enc_kdc_rep_part (the 85 * way we should) is for compatibility with the ISODE version of 86 * this fuction. Ah, compatibility.... 87 */ 88 tmp_encpart = *encpart; 89 tmp_encpart.msg_type = type; 90 retval = encode_krb5_enc_kdc_rep_part(&tmp_encpart, &scratch); 91 if (retval) { 92 return retval; 93 } 94 memset(&tmp_encpart, 0, sizeof(tmp_encpart)); 95 96 #define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); \ 97 krb5_free_data(context, scratch); } 98 99 retval = krb5_encrypt_helper(context, client_key, usage, scratch, 100 &dec_rep->enc_part); 101 102 #define cleanup_encpart() { \ 103 (void) memset(dec_rep->enc_part.ciphertext.data, 0, \ 104 dec_rep->enc_part.ciphertext.length); \ 105 free(dec_rep->enc_part.ciphertext.data); \ 106 dec_rep->enc_part.ciphertext.length = 0; \ 107 dec_rep->enc_part.ciphertext.data = 0;} 108 109 cleanup_scratch(); 110 111 if (retval) 112 return(retval); 113 114 /* now it's ready to be encoded for the wire! */ 115 116 switch (type) { 117 case KRB5_AS_REP: 118 retval = encode_krb5_as_rep(dec_rep, enc_rep); 119 break; 120 case KRB5_TGS_REP: 121 retval = encode_krb5_tgs_rep(dec_rep, enc_rep); 122 break; 123 } 124 125 if (retval) 126 cleanup_encpart(); 127 128 return retval; 129 } 130