1 /* 2 * lib/krb5/krb/ser_key.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. M.I.T. makes no representations about the suitability of 20 * this software for any purpose. It is provided "as is" without express 21 * or implied warranty. 22 * 23 */ 24 25 /* 26 * ser_key.c - Serialize a krb5_keyblock structure. 27 */ 28 #include "k5-int.h" 29 #include "int-proto.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_context, krb5_pointer, size_t *); 39 static krb5_error_code krb5_keyblock_externalize 40 (krb5_context, krb5_pointer, krb5_octet **, size_t *); 41 static krb5_error_code krb5_keyblock_internalize 42 (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(krb5_context kcontext, krb5_pointer arg, size_t *sizep) 59 { 60 krb5_error_code kret; 61 krb5_keyblock *keyblock; 62 63 /* 64 * krb5_keyblock requires: 65 * krb5_int32 for KV5M_KEYBLOCK 66 * krb5_int32 for enctype 67 * krb5_int32 for length 68 * keyblock->length for contents 69 * krb5_int32 for KV5M_KEYBLOCK 70 */ 71 kret = EINVAL; 72 /* Solaris Kerberos */ 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 /* Solaris Kerberos */ 103 keyblock = (krb5_keyblock *) arg; 104 if (keyblock) { 105 kret = ENOMEM; 106 if (!krb5_keyblock_size(kcontext, arg, &required) && 107 (required <= remain)) { 108 /* Our identifier */ 109 (void) krb5_ser_pack_int32(KV5M_KEYBLOCK, &bp, &remain); 110 111 /* Our enctype */ 112 (void) krb5_ser_pack_int32((krb5_int32) keyblock->enctype, 113 &bp, &remain); 114 115 /* Our length */ 116 (void) krb5_ser_pack_int32((krb5_int32) keyblock->length, 117 &bp, &remain); 118 119 /* Our contents */ 120 (void) krb5_ser_pack_bytes(keyblock->contents, 121 (size_t) keyblock->length, 122 &bp, &remain); 123 124 /* Finally, our trailer */ 125 (void) krb5_ser_pack_int32(KV5M_KEYBLOCK, &bp, &remain); 126 127 kret = 0; 128 *buffer = bp; 129 *lenremain = remain; 130 } 131 } 132 return(kret); 133 } 134 135 /* 136 * krb5_keyblock_internalize() - Internalize the krb5_keyblock. 137 */ 138 139 /*ARGSUSED*/ 140 static krb5_error_code 141 krb5_keyblock_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain) 142 { 143 krb5_error_code kret; 144 krb5_keyblock *keyblock; 145 krb5_int32 ibuf; 146 krb5_octet *bp; 147 size_t remain; 148 149 bp = *buffer; 150 remain = *lenremain; 151 kret = EINVAL; 152 /* Read our magic number */ 153 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) 154 ibuf = 0; 155 if (ibuf == KV5M_KEYBLOCK) { 156 kret = ENOMEM; 157 158 /* Get a keyblock */ 159 if ((remain >= (3*sizeof(krb5_int32))) && 160 (keyblock = (krb5_keyblock *) MALLOC(sizeof(krb5_keyblock)))) { 161 (void) memset(keyblock, 0, sizeof(krb5_keyblock)); 162 163 /* Get the enctype */ 164 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 165 keyblock->enctype = (krb5_enctype) ibuf; 166 167 /* Get the length */ 168 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 169 keyblock->length = (int) ibuf; 170 171 /* Get the string */ 172 /* Solaris Kerberos */ 173 keyblock->contents = (krb5_octet *) MALLOC((size_t) (ibuf)); 174 if ((keyblock->contents)&& 175 !(kret = krb5_ser_unpack_bytes(keyblock->contents, 176 (size_t) ibuf, 177 &bp, &remain))) { 178 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); 179 if (!kret && (ibuf == KV5M_KEYBLOCK)) { 180 kret = 0; 181 *buffer = bp; 182 *lenremain = remain; 183 keyblock->magic = KV5M_KEYBLOCK; 184 *argp = (krb5_pointer) keyblock; 185 } 186 else 187 kret = EINVAL; 188 } 189 if (kret) { 190 if (keyblock->contents) 191 FREE(keyblock->contents, keyblock->length); 192 FREE(keyblock, sizeof(krb5_keyblock)); 193 } 194 } 195 } 196 return(kret); 197 } 198 199 /* 200 * Register the keyblock serializer. 201 */ 202 krb5_error_code 203 krb5_ser_keyblock_init(krb5_context kcontext) 204 { 205 return(krb5_register_serializer(kcontext, &krb5_keyblock_ser_entry)); 206 } 207