1 #pragma ident "%Z%%M% %I% %E% SMI" 2 /* 3 * lib/krb5/krb/ser_adata.c 4 * 5 * Copyright 1995 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. M.I.T. makes no representations about the suitability of 21 * this software for any purpose. It is provided "as is" without express 22 * or implied warranty. 23 * 24 */ 25 26 /* 27 * ser_adata.c - Serialize a krb5_authdata structure. 28 */ 29 #include <k5-int.h> 30 #include <int-proto.h> 31 32 /* 33 * Routines to deal with externalizing the krb5_authdata: 34 * krb5_authdata_size(); 35 * krb5_authdata_externalize(); 36 * krb5_authdata_internalize(); 37 */ 38 static krb5_error_code krb5_authdata_size 39 (krb5_context, krb5_pointer, size_t *); 40 static krb5_error_code krb5_authdata_externalize 41 (krb5_context, krb5_pointer, krb5_octet **, size_t *); 42 static krb5_error_code krb5_authdata_internalize 43 (krb5_context, krb5_pointer *, krb5_octet **, size_t *); 44 45 /* Local data */ 46 static const krb5_ser_entry krb5_authdata_ser_entry = { 47 KV5M_AUTHDATA, /* Type */ 48 krb5_authdata_size, /* Sizer routine */ 49 krb5_authdata_externalize, /* Externalize routine */ 50 krb5_authdata_internalize /* Internalize routine */ 51 }; 52 53 /* 54 * krb5_authdata_esize() - Determine the size required to externalize 55 * the krb5_authdata. 56 */ 57 /*ARGSUSED*/ 58 static krb5_error_code 59 krb5_authdata_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep) 60 { 61 krb5_error_code kret; 62 krb5_authdata *authdata; 63 64 /* 65 * krb5_authdata requires: 66 * krb5_int32 for KV5M_AUTHDATA 67 * krb5_int32 for ad_type 68 * krb5_int32 for length 69 * authdata->length for contents 70 * krb5_int32 for KV5M_AUTHDATA 71 */ 72 kret = EINVAL; 73 authdata = (krb5_authdata *) arg; 74 if (authdata) { 75 *sizep += (sizeof(krb5_int32) + 76 sizeof(krb5_int32) + 77 sizeof(krb5_int32) + 78 sizeof(krb5_int32) + 79 (size_t) authdata->length); 80 kret = 0; 81 } 82 return(kret); 83 } 84 85 /* 86 * krb5_authdata_externalize() - Externalize the krb5_authdata. 87 */ 88 static krb5_error_code 89 krb5_authdata_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **buffer, size_t *lenremain) 90 { 91 krb5_error_code kret; 92 krb5_authdata *authdata; 93 size_t required; 94 krb5_octet *bp; 95 size_t remain; 96 97 required = 0; 98 bp = *buffer; 99 remain = *lenremain; 100 kret = EINVAL; 101 authdata = (krb5_authdata *) arg; 102 if (authdata) { 103 kret = ENOMEM; 104 if (!krb5_authdata_size(kcontext, arg, &required) && 105 (required <= remain)) { 106 /* Our identifier */ 107 (void) krb5_ser_pack_int32(KV5M_AUTHDATA, &bp, &remain); 108 109 /* Our ad_type */ 110 (void) krb5_ser_pack_int32((krb5_int32) authdata->ad_type, 111 &bp, &remain); 112 113 /* Our length */ 114 (void) krb5_ser_pack_int32((krb5_int32) authdata->length, 115 &bp, &remain); 116 117 /* Our contents */ 118 (void) krb5_ser_pack_bytes(authdata->contents, 119 (size_t) authdata->length, 120 &bp, &remain); 121 122 /* Finally, our trailer */ 123 (void) krb5_ser_pack_int32(KV5M_AUTHDATA, &bp, &remain); 124 kret = 0; 125 *buffer = bp; 126 *lenremain = remain; 127 } 128 } 129 return(kret); 130 } 131 132 /* 133 * krb5_authdata_internalize() - Internalize the krb5_authdata. 134 */ 135 /*ARGSUSED*/ 136 static krb5_error_code 137 krb5_authdata_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) 138 { 139 krb5_error_code kret; 140 krb5_authdata *authdata; 141 krb5_int32 ibuf; 142 krb5_octet *bp; 143 size_t remain; 144 145 bp = *buffer; 146 remain = *lenremain; 147 kret = EINVAL; 148 /* Read our magic number */ 149 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) 150 ibuf = 0; 151 if (ibuf == KV5M_AUTHDATA) { 152 kret = ENOMEM; 153 154 /* Get a authdata */ 155 if ((remain >= (2*sizeof(krb5_int32))) && 156 (authdata = (krb5_authdata *) MALLOC(sizeof(krb5_authdata)))) { 157 (void) memset(authdata, 0, sizeof(krb5_authdata)); 158 159 /* Get the ad_type */ 160 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 161 authdata->ad_type = (krb5_authdatatype) ibuf; 162 163 /* Get the length */ 164 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 165 authdata->length = (int) ibuf; 166 167 /* Get the string */ 168 authdata->contents = (krb5_octet *) 169 MALLOC((size_t) (ibuf)); 170 if ((authdata->contents) && 171 !(kret = krb5_ser_unpack_bytes(authdata->contents, 172 (size_t) ibuf, 173 &bp, &remain))) { 174 if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) 175 ibuf = 0; 176 if (ibuf == KV5M_AUTHDATA) { 177 authdata->magic = KV5M_AUTHDATA; 178 *buffer = bp; 179 *lenremain = remain; 180 *argp = (krb5_pointer) authdata; 181 } 182 else 183 kret = EINVAL; 184 } 185 if (kret) { 186 if (authdata->contents) 187 FREE(authdata->contents, authdata->length); 188 FREE(authdata, sizeof (krb5_authdata)); 189 } 190 } 191 } 192 return(kret); 193 } 194 195 /* 196 * Register the authdata serializer. 197 */ 198 krb5_error_code 199 krb5_ser_authdata_init(krb5_context kcontext) 200 { 201 return(krb5_register_serializer(kcontext, &krb5_authdata_ser_entry)); 202 } 203