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
krb5_keyblock_size(krb5_context kcontext,krb5_pointer arg,size_t * sizep)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
krb5_keyblock_externalize(krb5_context kcontext,krb5_pointer arg,krb5_octet ** buffer,size_t * lenremain)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
krb5_keyblock_internalize(krb5_context kcontext,krb5_pointer * argp,krb5_octet ** buffer,size_t * lenremain)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
krb5_ser_keyblock_init(krb5_context kcontext)203 krb5_ser_keyblock_init(krb5_context kcontext)
204 {
205 return(krb5_register_serializer(kcontext, &krb5_keyblock_ser_entry));
206 }
207