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