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