1*7f2fe78bSCy Schubert /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2*7f2fe78bSCy Schubert /* lib/krb5/krb/ser_actx.c - Serialize krb5_auth_context structure */
3*7f2fe78bSCy Schubert /*
4*7f2fe78bSCy Schubert * Copyright 1995, 2008 by the Massachusetts Institute of Technology.
5*7f2fe78bSCy Schubert * All Rights Reserved.
6*7f2fe78bSCy Schubert *
7*7f2fe78bSCy Schubert * Export of this software from the United States of America may
8*7f2fe78bSCy Schubert * require a specific license from the United States Government.
9*7f2fe78bSCy Schubert * It is the responsibility of any person or organization contemplating
10*7f2fe78bSCy Schubert * export to obtain such a license before exporting.
11*7f2fe78bSCy Schubert *
12*7f2fe78bSCy Schubert * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13*7f2fe78bSCy Schubert * distribute this software and its documentation for any purpose and
14*7f2fe78bSCy Schubert * without fee is hereby granted, provided that the above copyright
15*7f2fe78bSCy Schubert * notice appear in all copies and that both that copyright notice and
16*7f2fe78bSCy Schubert * this permission notice appear in supporting documentation, and that
17*7f2fe78bSCy Schubert * the name of M.I.T. not be used in advertising or publicity pertaining
18*7f2fe78bSCy Schubert * to distribution of the software without specific, written prior
19*7f2fe78bSCy Schubert * permission. Furthermore if you modify this software you must label
20*7f2fe78bSCy Schubert * your software as modified software and not distribute it in such a
21*7f2fe78bSCy Schubert * fashion that it might be confused with the original M.I.T. software.
22*7f2fe78bSCy Schubert * M.I.T. makes no representations about the suitability of
23*7f2fe78bSCy Schubert * this software for any purpose. It is provided "as is" without express
24*7f2fe78bSCy Schubert * or implied warranty.
25*7f2fe78bSCy Schubert */
26*7f2fe78bSCy Schubert
27*7f2fe78bSCy Schubert #include "k5-int.h"
28*7f2fe78bSCy Schubert #include "int-proto.h"
29*7f2fe78bSCy Schubert #include "auth_con.h"
30*7f2fe78bSCy Schubert
31*7f2fe78bSCy Schubert #define TOKEN_RADDR 950916
32*7f2fe78bSCy Schubert #define TOKEN_RPORT 950917
33*7f2fe78bSCy Schubert #define TOKEN_LADDR 950918
34*7f2fe78bSCy Schubert #define TOKEN_LPORT 950919
35*7f2fe78bSCy Schubert #define TOKEN_KEYBLOCK 950920
36*7f2fe78bSCy Schubert #define TOKEN_LSKBLOCK 950921
37*7f2fe78bSCy Schubert #define TOKEN_RSKBLOCK 950922
38*7f2fe78bSCy Schubert
39*7f2fe78bSCy Schubert krb5_error_code
k5_size_auth_context(krb5_auth_context auth_context,size_t * sizep)40*7f2fe78bSCy Schubert k5_size_auth_context(krb5_auth_context auth_context, size_t *sizep)
41*7f2fe78bSCy Schubert {
42*7f2fe78bSCy Schubert krb5_error_code kret;
43*7f2fe78bSCy Schubert size_t required;
44*7f2fe78bSCy Schubert
45*7f2fe78bSCy Schubert /*
46*7f2fe78bSCy Schubert * krb5_auth_context requires at minimum:
47*7f2fe78bSCy Schubert * krb5_int32 for KV5M_AUTH_CONTEXT
48*7f2fe78bSCy Schubert * krb5_int32 for auth_context_flags
49*7f2fe78bSCy Schubert * krb5_int32 for remote_seq_number
50*7f2fe78bSCy Schubert * krb5_int32 for local_seq_number
51*7f2fe78bSCy Schubert * krb5_int32 for req_cksumtype
52*7f2fe78bSCy Schubert * krb5_int32 for safe_cksumtype
53*7f2fe78bSCy Schubert * krb5_int32 for size of i_vector
54*7f2fe78bSCy Schubert * krb5_int32 for KV5M_AUTH_CONTEXT
55*7f2fe78bSCy Schubert */
56*7f2fe78bSCy Schubert kret = EINVAL;
57*7f2fe78bSCy Schubert if (auth_context != NULL) {
58*7f2fe78bSCy Schubert kret = 0;
59*7f2fe78bSCy Schubert
60*7f2fe78bSCy Schubert required = auth_context->cstate.length;
61*7f2fe78bSCy Schubert required += sizeof(krb5_int32)*8;
62*7f2fe78bSCy Schubert
63*7f2fe78bSCy Schubert /* Calculate size required by remote_addr, if appropriate */
64*7f2fe78bSCy Schubert if (!kret && auth_context->remote_addr) {
65*7f2fe78bSCy Schubert kret = k5_size_address(auth_context->remote_addr, &required);
66*7f2fe78bSCy Schubert if (!kret)
67*7f2fe78bSCy Schubert required += sizeof(krb5_int32);
68*7f2fe78bSCy Schubert }
69*7f2fe78bSCy Schubert
70*7f2fe78bSCy Schubert /* Calculate size required by remote_port, if appropriate */
71*7f2fe78bSCy Schubert if (!kret && auth_context->remote_port) {
72*7f2fe78bSCy Schubert kret = k5_size_address(auth_context->remote_port, &required);
73*7f2fe78bSCy Schubert if (!kret)
74*7f2fe78bSCy Schubert required += sizeof(krb5_int32);
75*7f2fe78bSCy Schubert }
76*7f2fe78bSCy Schubert
77*7f2fe78bSCy Schubert /* Calculate size required by local_addr, if appropriate */
78*7f2fe78bSCy Schubert if (!kret && auth_context->local_addr) {
79*7f2fe78bSCy Schubert kret = k5_size_address(auth_context->local_addr, &required);
80*7f2fe78bSCy Schubert if (!kret)
81*7f2fe78bSCy Schubert required += sizeof(krb5_int32);
82*7f2fe78bSCy Schubert }
83*7f2fe78bSCy Schubert
84*7f2fe78bSCy Schubert /* Calculate size required by local_port, if appropriate */
85*7f2fe78bSCy Schubert if (!kret && auth_context->local_port) {
86*7f2fe78bSCy Schubert kret = k5_size_address(auth_context->local_port, &required);
87*7f2fe78bSCy Schubert if (!kret)
88*7f2fe78bSCy Schubert required += sizeof(krb5_int32);
89*7f2fe78bSCy Schubert }
90*7f2fe78bSCy Schubert
91*7f2fe78bSCy Schubert /* Calculate size required by key, if appropriate */
92*7f2fe78bSCy Schubert if (!kret && auth_context->key) {
93*7f2fe78bSCy Schubert kret = k5_size_keyblock(&auth_context->key->keyblock, &required);
94*7f2fe78bSCy Schubert if (!kret)
95*7f2fe78bSCy Schubert required += sizeof(krb5_int32);
96*7f2fe78bSCy Schubert }
97*7f2fe78bSCy Schubert
98*7f2fe78bSCy Schubert /* Calculate size required by send_subkey, if appropriate */
99*7f2fe78bSCy Schubert if (!kret && auth_context->send_subkey) {
100*7f2fe78bSCy Schubert kret = k5_size_keyblock(&auth_context->send_subkey->keyblock,
101*7f2fe78bSCy Schubert &required);
102*7f2fe78bSCy Schubert if (!kret)
103*7f2fe78bSCy Schubert required += sizeof(krb5_int32);
104*7f2fe78bSCy Schubert }
105*7f2fe78bSCy Schubert
106*7f2fe78bSCy Schubert /* Calculate size required by recv_subkey, if appropriate */
107*7f2fe78bSCy Schubert if (!kret && auth_context->recv_subkey) {
108*7f2fe78bSCy Schubert kret = k5_size_keyblock(&auth_context->recv_subkey->keyblock,
109*7f2fe78bSCy Schubert &required);
110*7f2fe78bSCy Schubert if (!kret)
111*7f2fe78bSCy Schubert required += sizeof(krb5_int32);
112*7f2fe78bSCy Schubert }
113*7f2fe78bSCy Schubert
114*7f2fe78bSCy Schubert /* Calculate size required by authentp, if appropriate */
115*7f2fe78bSCy Schubert if (!kret && auth_context->authentp)
116*7f2fe78bSCy Schubert kret = k5_size_authenticator(auth_context->authentp, &required);
117*7f2fe78bSCy Schubert
118*7f2fe78bSCy Schubert }
119*7f2fe78bSCy Schubert if (!kret)
120*7f2fe78bSCy Schubert *sizep += required;
121*7f2fe78bSCy Schubert return(kret);
122*7f2fe78bSCy Schubert }
123*7f2fe78bSCy Schubert
124*7f2fe78bSCy Schubert krb5_error_code
k5_externalize_auth_context(krb5_auth_context auth_context,krb5_octet ** buffer,size_t * lenremain)125*7f2fe78bSCy Schubert k5_externalize_auth_context(krb5_auth_context auth_context,
126*7f2fe78bSCy Schubert krb5_octet **buffer, size_t *lenremain)
127*7f2fe78bSCy Schubert {
128*7f2fe78bSCy Schubert krb5_error_code kret;
129*7f2fe78bSCy Schubert size_t required;
130*7f2fe78bSCy Schubert krb5_octet *bp;
131*7f2fe78bSCy Schubert size_t remain;
132*7f2fe78bSCy Schubert
133*7f2fe78bSCy Schubert required = 0;
134*7f2fe78bSCy Schubert bp = *buffer;
135*7f2fe78bSCy Schubert remain = *lenremain;
136*7f2fe78bSCy Schubert kret = EINVAL;
137*7f2fe78bSCy Schubert if (auth_context != NULL) {
138*7f2fe78bSCy Schubert kret = ENOMEM;
139*7f2fe78bSCy Schubert if (!k5_size_auth_context(auth_context, &required) &&
140*7f2fe78bSCy Schubert required <= remain) {
141*7f2fe78bSCy Schubert
142*7f2fe78bSCy Schubert /* Write fixed portion */
143*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(KV5M_AUTH_CONTEXT, &bp, &remain);
144*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(auth_context->auth_context_flags,
145*7f2fe78bSCy Schubert &bp, &remain);
146*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(auth_context->remote_seq_number,
147*7f2fe78bSCy Schubert &bp, &remain);
148*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(auth_context->local_seq_number,
149*7f2fe78bSCy Schubert &bp, &remain);
150*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32((krb5_int32) auth_context->req_cksumtype,
151*7f2fe78bSCy Schubert &bp, &remain);
152*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32((krb5_int32) auth_context->safe_cksumtype,
153*7f2fe78bSCy Schubert &bp, &remain);
154*7f2fe78bSCy Schubert
155*7f2fe78bSCy Schubert /* Write the cipher state */
156*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(auth_context->cstate.length, &bp,
157*7f2fe78bSCy Schubert &remain);
158*7f2fe78bSCy Schubert (void) krb5_ser_pack_bytes((krb5_octet *)auth_context->cstate.data,
159*7f2fe78bSCy Schubert auth_context->cstate.length,
160*7f2fe78bSCy Schubert &bp, &remain);
161*7f2fe78bSCy Schubert
162*7f2fe78bSCy Schubert kret = 0;
163*7f2fe78bSCy Schubert
164*7f2fe78bSCy Schubert /* Now handle remote_addr, if appropriate */
165*7f2fe78bSCy Schubert if (!kret && auth_context->remote_addr) {
166*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(TOKEN_RADDR, &bp, &remain);
167*7f2fe78bSCy Schubert kret = k5_externalize_address(auth_context->remote_addr,
168*7f2fe78bSCy Schubert &bp, &remain);
169*7f2fe78bSCy Schubert }
170*7f2fe78bSCy Schubert
171*7f2fe78bSCy Schubert /* Now handle remote_port, if appropriate */
172*7f2fe78bSCy Schubert if (!kret && auth_context->remote_port) {
173*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(TOKEN_RPORT, &bp, &remain);
174*7f2fe78bSCy Schubert kret = k5_externalize_address(auth_context->remote_addr,
175*7f2fe78bSCy Schubert &bp, &remain);
176*7f2fe78bSCy Schubert }
177*7f2fe78bSCy Schubert
178*7f2fe78bSCy Schubert /* Now handle local_addr, if appropriate */
179*7f2fe78bSCy Schubert if (!kret && auth_context->local_addr) {
180*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(TOKEN_LADDR, &bp, &remain);
181*7f2fe78bSCy Schubert kret = k5_externalize_address(auth_context->local_addr,
182*7f2fe78bSCy Schubert &bp, &remain);
183*7f2fe78bSCy Schubert }
184*7f2fe78bSCy Schubert
185*7f2fe78bSCy Schubert /* Now handle local_port, if appropriate */
186*7f2fe78bSCy Schubert if (!kret && auth_context->local_port) {
187*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(TOKEN_LPORT, &bp, &remain);
188*7f2fe78bSCy Schubert kret = k5_externalize_address(auth_context->local_addr,
189*7f2fe78bSCy Schubert &bp, &remain);
190*7f2fe78bSCy Schubert }
191*7f2fe78bSCy Schubert
192*7f2fe78bSCy Schubert /* Now handle keyblock, if appropriate */
193*7f2fe78bSCy Schubert if (!kret && auth_context->key) {
194*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(TOKEN_KEYBLOCK, &bp, &remain);
195*7f2fe78bSCy Schubert kret = k5_externalize_keyblock(&auth_context->key->keyblock,
196*7f2fe78bSCy Schubert &bp, &remain);
197*7f2fe78bSCy Schubert }
198*7f2fe78bSCy Schubert
199*7f2fe78bSCy Schubert /* Now handle subkey, if appropriate */
200*7f2fe78bSCy Schubert if (!kret && auth_context->send_subkey) {
201*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(TOKEN_LSKBLOCK, &bp, &remain);
202*7f2fe78bSCy Schubert kret = k5_externalize_keyblock(&auth_context->
203*7f2fe78bSCy Schubert send_subkey->keyblock,
204*7f2fe78bSCy Schubert &bp, &remain);
205*7f2fe78bSCy Schubert }
206*7f2fe78bSCy Schubert
207*7f2fe78bSCy Schubert /* Now handle subkey, if appropriate */
208*7f2fe78bSCy Schubert if (!kret && auth_context->recv_subkey) {
209*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(TOKEN_RSKBLOCK, &bp, &remain);
210*7f2fe78bSCy Schubert kret = k5_externalize_keyblock(&auth_context->
211*7f2fe78bSCy Schubert recv_subkey->keyblock,
212*7f2fe78bSCy Schubert &bp, &remain);
213*7f2fe78bSCy Schubert }
214*7f2fe78bSCy Schubert
215*7f2fe78bSCy Schubert /* Now handle authentp, if appropriate */
216*7f2fe78bSCy Schubert if (!kret && auth_context->authentp)
217*7f2fe78bSCy Schubert kret = k5_externalize_authenticator(auth_context->authentp,
218*7f2fe78bSCy Schubert &bp, &remain);
219*7f2fe78bSCy Schubert
220*7f2fe78bSCy Schubert /*
221*7f2fe78bSCy Schubert * If we were successful, write trailer then update the pointer and
222*7f2fe78bSCy Schubert * remaining length;
223*7f2fe78bSCy Schubert */
224*7f2fe78bSCy Schubert if (!kret) {
225*7f2fe78bSCy Schubert /* Write our trailer */
226*7f2fe78bSCy Schubert (void) krb5_ser_pack_int32(KV5M_AUTH_CONTEXT, &bp, &remain);
227*7f2fe78bSCy Schubert *buffer = bp;
228*7f2fe78bSCy Schubert *lenremain = remain;
229*7f2fe78bSCy Schubert }
230*7f2fe78bSCy Schubert }
231*7f2fe78bSCy Schubert }
232*7f2fe78bSCy Schubert return(kret);
233*7f2fe78bSCy Schubert }
234*7f2fe78bSCy Schubert
235*7f2fe78bSCy Schubert /* Internalize a keyblock and convert it to a key. */
236*7f2fe78bSCy Schubert static krb5_error_code
intern_key(krb5_key * key,krb5_octet ** bp,size_t * sp)237*7f2fe78bSCy Schubert intern_key(krb5_key *key, krb5_octet **bp, size_t *sp)
238*7f2fe78bSCy Schubert {
239*7f2fe78bSCy Schubert krb5_keyblock *keyblock;
240*7f2fe78bSCy Schubert krb5_error_code ret;
241*7f2fe78bSCy Schubert
242*7f2fe78bSCy Schubert ret = k5_internalize_keyblock(&keyblock, bp, sp);
243*7f2fe78bSCy Schubert if (ret != 0)
244*7f2fe78bSCy Schubert return ret;
245*7f2fe78bSCy Schubert ret = krb5_k_create_key(NULL, keyblock, key);
246*7f2fe78bSCy Schubert krb5_free_keyblock(NULL, keyblock);
247*7f2fe78bSCy Schubert return ret;
248*7f2fe78bSCy Schubert }
249*7f2fe78bSCy Schubert
250*7f2fe78bSCy Schubert krb5_error_code
k5_internalize_auth_context(krb5_auth_context * argp,krb5_octet ** buffer,size_t * lenremain)251*7f2fe78bSCy Schubert k5_internalize_auth_context(krb5_auth_context *argp,
252*7f2fe78bSCy Schubert krb5_octet **buffer, size_t *lenremain)
253*7f2fe78bSCy Schubert {
254*7f2fe78bSCy Schubert krb5_error_code kret;
255*7f2fe78bSCy Schubert krb5_auth_context auth_context;
256*7f2fe78bSCy Schubert krb5_int32 ibuf;
257*7f2fe78bSCy Schubert krb5_octet *bp;
258*7f2fe78bSCy Schubert size_t remain;
259*7f2fe78bSCy Schubert krb5_int32 cstate_len;
260*7f2fe78bSCy Schubert krb5_int32 tag;
261*7f2fe78bSCy Schubert
262*7f2fe78bSCy Schubert bp = *buffer;
263*7f2fe78bSCy Schubert remain = *lenremain;
264*7f2fe78bSCy Schubert kret = EINVAL;
265*7f2fe78bSCy Schubert /* Read our magic number */
266*7f2fe78bSCy Schubert if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
267*7f2fe78bSCy Schubert ibuf = 0;
268*7f2fe78bSCy Schubert if (ibuf == KV5M_AUTH_CONTEXT) {
269*7f2fe78bSCy Schubert kret = ENOMEM;
270*7f2fe78bSCy Schubert
271*7f2fe78bSCy Schubert /* Get memory for the auth_context */
272*7f2fe78bSCy Schubert if ((remain >= (5*sizeof(krb5_int32))) &&
273*7f2fe78bSCy Schubert (auth_context = (krb5_auth_context)
274*7f2fe78bSCy Schubert calloc(1, sizeof(struct _krb5_auth_context)))) {
275*7f2fe78bSCy Schubert
276*7f2fe78bSCy Schubert /* Get auth_context_flags */
277*7f2fe78bSCy Schubert (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
278*7f2fe78bSCy Schubert auth_context->auth_context_flags = ibuf;
279*7f2fe78bSCy Schubert
280*7f2fe78bSCy Schubert /* Get remote_seq_number */
281*7f2fe78bSCy Schubert (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
282*7f2fe78bSCy Schubert auth_context->remote_seq_number = ibuf;
283*7f2fe78bSCy Schubert
284*7f2fe78bSCy Schubert /* Get local_seq_number */
285*7f2fe78bSCy Schubert (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
286*7f2fe78bSCy Schubert auth_context->local_seq_number = ibuf;
287*7f2fe78bSCy Schubert
288*7f2fe78bSCy Schubert /* Get req_cksumtype */
289*7f2fe78bSCy Schubert (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
290*7f2fe78bSCy Schubert auth_context->req_cksumtype = (krb5_cksumtype) ibuf;
291*7f2fe78bSCy Schubert
292*7f2fe78bSCy Schubert /* Get safe_cksumtype */
293*7f2fe78bSCy Schubert (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
294*7f2fe78bSCy Schubert auth_context->safe_cksumtype = (krb5_cksumtype) ibuf;
295*7f2fe78bSCy Schubert
296*7f2fe78bSCy Schubert /* Get length of cstate */
297*7f2fe78bSCy Schubert (void) krb5_ser_unpack_int32(&cstate_len, &bp, &remain);
298*7f2fe78bSCy Schubert
299*7f2fe78bSCy Schubert if (cstate_len) {
300*7f2fe78bSCy Schubert kret = alloc_data(&auth_context->cstate, cstate_len);
301*7f2fe78bSCy Schubert if (!kret) {
302*7f2fe78bSCy Schubert kret = krb5_ser_unpack_bytes((krb5_octet *)
303*7f2fe78bSCy Schubert auth_context->cstate.data,
304*7f2fe78bSCy Schubert cstate_len, &bp, &remain);
305*7f2fe78bSCy Schubert }
306*7f2fe78bSCy Schubert }
307*7f2fe78bSCy Schubert else
308*7f2fe78bSCy Schubert kret = 0;
309*7f2fe78bSCy Schubert
310*7f2fe78bSCy Schubert /* Peek at next token */
311*7f2fe78bSCy Schubert tag = 0;
312*7f2fe78bSCy Schubert if (!kret)
313*7f2fe78bSCy Schubert kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
314*7f2fe78bSCy Schubert
315*7f2fe78bSCy Schubert /* This is the remote_addr */
316*7f2fe78bSCy Schubert if (!kret && (tag == TOKEN_RADDR)) {
317*7f2fe78bSCy Schubert if (!(kret = k5_internalize_address(&auth_context->remote_addr,
318*7f2fe78bSCy Schubert &bp, &remain)))
319*7f2fe78bSCy Schubert kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
320*7f2fe78bSCy Schubert }
321*7f2fe78bSCy Schubert
322*7f2fe78bSCy Schubert /* This is the remote_port */
323*7f2fe78bSCy Schubert if (!kret && (tag == TOKEN_RPORT)) {
324*7f2fe78bSCy Schubert if (!(kret = k5_internalize_address(&auth_context->remote_port,
325*7f2fe78bSCy Schubert &bp, &remain)))
326*7f2fe78bSCy Schubert kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
327*7f2fe78bSCy Schubert }
328*7f2fe78bSCy Schubert
329*7f2fe78bSCy Schubert /* This is the local_addr */
330*7f2fe78bSCy Schubert if (!kret && (tag == TOKEN_LADDR)) {
331*7f2fe78bSCy Schubert if (!(kret = k5_internalize_address(&auth_context->local_addr,
332*7f2fe78bSCy Schubert &bp, &remain)))
333*7f2fe78bSCy Schubert kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
334*7f2fe78bSCy Schubert }
335*7f2fe78bSCy Schubert
336*7f2fe78bSCy Schubert /* This is the local_port */
337*7f2fe78bSCy Schubert if (!kret && (tag == TOKEN_LPORT)) {
338*7f2fe78bSCy Schubert if (!(kret = k5_internalize_address(&auth_context->local_port,
339*7f2fe78bSCy Schubert &bp, &remain)))
340*7f2fe78bSCy Schubert kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
341*7f2fe78bSCy Schubert }
342*7f2fe78bSCy Schubert
343*7f2fe78bSCy Schubert /* This is the keyblock */
344*7f2fe78bSCy Schubert if (!kret && (tag == TOKEN_KEYBLOCK)) {
345*7f2fe78bSCy Schubert if (!(kret = intern_key(&auth_context->key, &bp, &remain)))
346*7f2fe78bSCy Schubert kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
347*7f2fe78bSCy Schubert }
348*7f2fe78bSCy Schubert
349*7f2fe78bSCy Schubert /* This is the send_subkey */
350*7f2fe78bSCy Schubert if (!kret && (tag == TOKEN_LSKBLOCK)) {
351*7f2fe78bSCy Schubert if (!(kret = intern_key(&auth_context->send_subkey,
352*7f2fe78bSCy Schubert &bp, &remain)))
353*7f2fe78bSCy Schubert kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
354*7f2fe78bSCy Schubert }
355*7f2fe78bSCy Schubert
356*7f2fe78bSCy Schubert /* This is the recv_subkey */
357*7f2fe78bSCy Schubert if (!kret) {
358*7f2fe78bSCy Schubert if (tag == TOKEN_RSKBLOCK) {
359*7f2fe78bSCy Schubert kret = intern_key(&auth_context->recv_subkey,
360*7f2fe78bSCy Schubert &bp, &remain);
361*7f2fe78bSCy Schubert }
362*7f2fe78bSCy Schubert else {
363*7f2fe78bSCy Schubert /*
364*7f2fe78bSCy Schubert * We read the next tag, but it's not of any use here, so
365*7f2fe78bSCy Schubert * we effectively 'unget' it here.
366*7f2fe78bSCy Schubert */
367*7f2fe78bSCy Schubert bp -= sizeof(krb5_int32);
368*7f2fe78bSCy Schubert remain += sizeof(krb5_int32);
369*7f2fe78bSCy Schubert }
370*7f2fe78bSCy Schubert }
371*7f2fe78bSCy Schubert
372*7f2fe78bSCy Schubert /* Now find the authentp */
373*7f2fe78bSCy Schubert if (!kret) {
374*7f2fe78bSCy Schubert kret = k5_internalize_authenticator(&auth_context->authentp,
375*7f2fe78bSCy Schubert &bp, &remain);
376*7f2fe78bSCy Schubert if (kret == EINVAL)
377*7f2fe78bSCy Schubert kret = 0;
378*7f2fe78bSCy Schubert }
379*7f2fe78bSCy Schubert
380*7f2fe78bSCy Schubert /* Finally, find the trailer */
381*7f2fe78bSCy Schubert if (!kret) {
382*7f2fe78bSCy Schubert kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
383*7f2fe78bSCy Schubert if (!kret && (ibuf != KV5M_AUTH_CONTEXT))
384*7f2fe78bSCy Schubert kret = EINVAL;
385*7f2fe78bSCy Schubert }
386*7f2fe78bSCy Schubert if (!kret) {
387*7f2fe78bSCy Schubert *buffer = bp;
388*7f2fe78bSCy Schubert *lenremain = remain;
389*7f2fe78bSCy Schubert auth_context->magic = KV5M_AUTH_CONTEXT;
390*7f2fe78bSCy Schubert *argp = auth_context;
391*7f2fe78bSCy Schubert }
392*7f2fe78bSCy Schubert else
393*7f2fe78bSCy Schubert krb5_auth_con_free(NULL, auth_context);
394*7f2fe78bSCy Schubert }
395*7f2fe78bSCy Schubert }
396*7f2fe78bSCy Schubert return(kret);
397*7f2fe78bSCy Schubert }
398