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