1 /* 2 * lib/krb5/krb/ser_cksum.c 3 * 4 * Copyright 1995 by the Massachusetts Institute of Technology. 5 * All Rights Reserved. 6 * 7 * Export of this software from the United States of America may 8 * require a specific license from the United States Government. 9 * It is the responsibility of any person or organization contemplating 10 * export to obtain such a license before exporting. 11 * 12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 13 * distribute this software and its documentation for any purpose and 14 * without fee is hereby granted, provided that the above copyright 15 * notice appear in all copies and that both that copyright notice and 16 * this permission notice appear in supporting documentation, and that 17 * the name of M.I.T. not be used in advertising or publicity pertaining 18 * to distribution of the software without specific, written prior 19 * permission. Furthermore if you modify this software you must label 20 * your software as modified software and not distribute it in such a 21 * fashion that it might be confused with the original M.I.T. software. 22 * M.I.T. makes no representations about the suitability of 23 * this software for any purpose. It is provided "as is" without express 24 * or implied warranty. 25 * 26 */ 27 28 /* 29 * ser_cksum.c - Serialize a krb5_checksum structure. 30 */ 31 #include "k5-int.h" 32 #include "int-proto.h" 33 34 /* 35 * Routines to deal with externalizing the krb5_checksum: 36 * krb5_checksum_esize(); 37 * krb5_checksum_externalize(); 38 * krb5_checksum_internalize(); 39 */ 40 static krb5_error_code krb5_checksum_esize 41 (krb5_context, krb5_pointer, size_t *); 42 static krb5_error_code krb5_checksum_externalize 43 (krb5_context, krb5_pointer, krb5_octet **, size_t *); 44 static krb5_error_code krb5_checksum_internalize 45 (krb5_context,krb5_pointer *, krb5_octet **, size_t *); 46 47 /* Local data */ 48 static const krb5_ser_entry krb5_checksum_ser_entry = { 49 KV5M_CHECKSUM, /* Type */ 50 krb5_checksum_esize, /* Sizer routine */ 51 krb5_checksum_externalize, /* Externalize routine */ 52 krb5_checksum_internalize /* Internalize routine */ 53 }; 54 55 /* 56 * krb5_checksum_esize() - Determine the size required to externalize 57 * the krb5_checksum. 58 */ 59 /*ARGSUSED*/ 60 static krb5_error_code 61 krb5_checksum_esize(krb5_context kcontext, krb5_pointer arg, size_t *sizep) 62 { 63 krb5_error_code kret; 64 krb5_checksum *checksum; 65 66 /* 67 * krb5_checksum requires: 68 * krb5_int32 for KV5M_CHECKSUM 69 * krb5_int32 for checksum_type 70 * krb5_int32 for length 71 * krb5_int32 for KV5M_CHECKSUM 72 * checksum->length for contents 73 */ 74 kret = EINVAL; 75 /* Solaris Kerberos */ 76 checksum = (krb5_checksum *) arg; 77 if (checksum) { 78 *sizep += (sizeof(krb5_int32) + 79 sizeof(krb5_int32) + 80 sizeof(krb5_int32) + 81 sizeof(krb5_int32) + 82 (size_t) checksum->length); 83 kret = 0; 84 } 85 return(kret); 86 } 87 88 /* 89 * krb5_checksum_externalize() - Externalize the krb5_checksum. 90 */ 91 static krb5_error_code 92 krb5_checksum_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **buffer, size_t *lenremain) 93 { 94 krb5_error_code kret; 95 krb5_checksum *checksum; 96 size_t required; 97 krb5_octet *bp; 98 size_t remain; 99 100 required = 0; 101 bp = *buffer; 102 remain = *lenremain; 103 kret = EINVAL; 104 /* Solaris Kerberos */ 105 checksum = (krb5_checksum *) arg; 106 if (checksum) { 107 kret = ENOMEM; 108 if (!krb5_checksum_esize(kcontext, arg, &required) && 109 (required <= remain)) { 110 /* Our identifier */ 111 (void) krb5_ser_pack_int32(KV5M_CHECKSUM, &bp, &remain); 112 113 /* Our checksum_type */ 114 (void) krb5_ser_pack_int32((krb5_int32) checksum->checksum_type, 115 &bp, &remain); 116 117 /* Our length */ 118 (void) krb5_ser_pack_int32((krb5_int32) checksum->length, 119 &bp, &remain); 120 121 /* Our contents */ 122 (void) krb5_ser_pack_bytes(checksum->contents, 123 (size_t) checksum->length, 124 &bp, &remain); 125 126 /* Finally, our trailer */ 127 (void) krb5_ser_pack_int32(KV5M_CHECKSUM, &bp, &remain); 128 129 kret = 0; 130 *buffer = bp; 131 *lenremain = remain; 132 } 133 } 134 return(kret); 135 } 136 137 /* 138 * krb5_checksum_internalize() - Internalize the krb5_checksum. 139 */ 140 /*ARGSUSED*/ 141 static krb5_error_code 142 krb5_checksum_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) 143 { 144 krb5_error_code kret; 145 krb5_checksum *checksum; 146 krb5_int32 ibuf; 147 krb5_octet *bp; 148 size_t remain; 149 150 bp = *buffer; 151 remain = *lenremain; 152 kret = EINVAL; 153 /* Read our magic number */ 154 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) 155 ibuf = 0; 156 if (ibuf == KV5M_CHECKSUM) { 157 kret = ENOMEM; 158 159 /* Get a checksum */ 160 if ((remain >= (2*sizeof(krb5_int32))) && 161 (checksum = (krb5_checksum *) MALLOC(sizeof(krb5_checksum)))) { 162 (void) memset(checksum, 0, sizeof(krb5_checksum)); 163 164 /* Get the checksum_type */ 165 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 166 checksum->checksum_type = (krb5_cksumtype) ibuf; 167 168 /* Get the length */ 169 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 170 checksum->length = (int) ibuf; 171 172 /* Get the string */ 173 /* Solaris Kerberos */ 174 if (ibuf) 175 checksum->contents = (krb5_octet *) 176 MALLOC((size_t) (ibuf)); 177 178 if (!ibuf || 179 ((checksum->contents) && 180 !(kret = krb5_ser_unpack_bytes(checksum->contents, 181 (size_t) ibuf, 182 &bp, &remain)))) { 183 184 /* Get the trailer */ 185 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); 186 if (!kret && (ibuf == KV5M_CHECKSUM)) { 187 checksum->magic = KV5M_CHECKSUM; 188 *buffer = bp; 189 *lenremain = remain; 190 *argp = (krb5_pointer) checksum; 191 } 192 else 193 kret = EINVAL; 194 } 195 if (kret) { 196 if (checksum->contents) 197 FREE(checksum->contents, checksum->length); 198 FREE(checksum, sizeof (krb5_checksum)); 199 } 200 } 201 } 202 return(kret); 203 } 204 205 /* 206 * Register the checksum serializer. 207 */ 208 krb5_error_code 209 krb5_ser_checksum_init(krb5_context kcontext) 210 { 211 return(krb5_register_serializer(kcontext, &krb5_checksum_ser_entry)); 212 } 213