17c478bd9Sstevel@tonic-gate /*
2*159d09a2SMark Phalan  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate 
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate  * lib/gssapi/krb5/ser_sctx.c
97c478bd9Sstevel@tonic-gate  *
10ab9b2e15Sgtb  * Copyright 1995, 2004 by the Massachusetts Institute of Technology.
117c478bd9Sstevel@tonic-gate  * All Rights Reserved.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may
147c478bd9Sstevel@tonic-gate  *   require a specific license from the United States Government.
157c478bd9Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
167c478bd9Sstevel@tonic-gate  *   export to obtain such a license before exporting.
177c478bd9Sstevel@tonic-gate  *
187c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
197c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
207c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
217c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
227c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
237c478bd9Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
247c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
257c478bd9Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
267c478bd9Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
277c478bd9Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
287c478bd9Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
297c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
307c478bd9Sstevel@tonic-gate  * or implied warranty.
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  * ser_sctx.c - Handle [de]serialization of GSSAPI security context.
367c478bd9Sstevel@tonic-gate  */
37ab9b2e15Sgtb  /* Solaris Kerberos:  order is important here.  include gssapiP_krb5.h
38ab9b2e15Sgtb   * before all others, otherwise we get a LINT error from MALLOC macro
39ab9b2e15Sgtb   * being redefined in mechglueP.h */
40ab9b2e15Sgtb #include "gssapiP_krb5.h"
41ab9b2e15Sgtb #include "k5-int.h"
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate /*
447c478bd9Sstevel@tonic-gate  * This module contains routines to [de]serialize
457c478bd9Sstevel@tonic-gate  *	krb5_gss_enc_desc and krb5_gss_ctx_id_t.
467c478bd9Sstevel@tonic-gate  * XXX This whole serialization abstraction is unnecessary in a
477c478bd9Sstevel@tonic-gate  * non-messaging environment, which krb5 is.  Someday, this should
487c478bd9Sstevel@tonic-gate  * all get redone without the extra level of indirection. I've done
497c478bd9Sstevel@tonic-gate  * some of this work here, since adding new serializers is an internal
507c478bd9Sstevel@tonic-gate  * krb5 interface, and I won't use those.  There is some more
517c478bd9Sstevel@tonic-gate  * deobfuscation (no longer anonymizing pointers, mostly) which could
527c478bd9Sstevel@tonic-gate  * still be done. --marc
537c478bd9Sstevel@tonic-gate  */
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate /*ARGSUSED*/
567c478bd9Sstevel@tonic-gate static krb5_error_code
kg_oid_externalize(kcontext,arg,buffer,lenremain)577c478bd9Sstevel@tonic-gate kg_oid_externalize(kcontext, arg, buffer, lenremain)
587c478bd9Sstevel@tonic-gate     krb5_context	kcontext;
597c478bd9Sstevel@tonic-gate     krb5_pointer	arg;
607c478bd9Sstevel@tonic-gate     krb5_octet		**buffer;
617c478bd9Sstevel@tonic-gate     size_t		*lenremain;
627c478bd9Sstevel@tonic-gate {
637c478bd9Sstevel@tonic-gate      gss_OID oid = (gss_OID) arg;
647c478bd9Sstevel@tonic-gate      krb5_error_code err;
65ab9b2e15Sgtb 
667c478bd9Sstevel@tonic-gate      err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain);
677c478bd9Sstevel@tonic-gate      if (err)
68ab9b2e15Sgtb 	 return err;
697c478bd9Sstevel@tonic-gate      err = krb5_ser_pack_int32((krb5_int32) oid->length,
70ab9b2e15Sgtb 			       buffer, lenremain);
717c478bd9Sstevel@tonic-gate      if (err)
72ab9b2e15Sgtb 	 return err;
737c478bd9Sstevel@tonic-gate      err = krb5_ser_pack_bytes((krb5_octet *) oid->elements,
74ab9b2e15Sgtb 			       oid->length, buffer, lenremain);
757c478bd9Sstevel@tonic-gate      if (err)
76ab9b2e15Sgtb 	 return err;
777c478bd9Sstevel@tonic-gate      err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain);
787c478bd9Sstevel@tonic-gate      return err;
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate /*ARGSUSED*/
827c478bd9Sstevel@tonic-gate static krb5_error_code
kg_oid_internalize(kcontext,argp,buffer,lenremain)837c478bd9Sstevel@tonic-gate kg_oid_internalize(kcontext, argp, buffer, lenremain)
847c478bd9Sstevel@tonic-gate     krb5_context	kcontext;
857c478bd9Sstevel@tonic-gate     krb5_pointer	*argp;
867c478bd9Sstevel@tonic-gate     krb5_octet		**buffer;
877c478bd9Sstevel@tonic-gate     size_t		*lenremain;
887c478bd9Sstevel@tonic-gate {
89ab9b2e15Sgtb      gss_OID oid;
907c478bd9Sstevel@tonic-gate      krb5_int32 ibuf;
917c478bd9Sstevel@tonic-gate      krb5_octet		*bp;
927c478bd9Sstevel@tonic-gate      size_t		remain;
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate      bp = *buffer;
957c478bd9Sstevel@tonic-gate      remain = *lenremain;
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate      /* Read in and check our magic number */
987c478bd9Sstevel@tonic-gate      if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
997c478bd9Sstevel@tonic-gate 	return (EINVAL);
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate      if (ibuf != KV5M_GSS_OID)
1027c478bd9Sstevel@tonic-gate 	 return (EINVAL);
103ab9b2e15Sgtb 
104ab9b2e15Sgtb      oid = (gss_OID) MALLOC(sizeof(gss_OID_desc));
1057c478bd9Sstevel@tonic-gate      if (oid == NULL)
1067c478bd9Sstevel@tonic-gate 	  return ENOMEM;
1077c478bd9Sstevel@tonic-gate      if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) {
108ab9b2e15Sgtb          FREE(oid, sizeof(gss_OID_desc));
109ab9b2e15Sgtb 	 return EINVAL;
1107c478bd9Sstevel@tonic-gate      }
1117c478bd9Sstevel@tonic-gate      oid->length = ibuf;
1127c478bd9Sstevel@tonic-gate      oid->elements = MALLOC(ibuf);
113ab9b2e15Sgtb      if (oid->elements == 0) {
114ab9b2e15Sgtb              FREE(oid, sizeof(gss_OID_desc));
115ab9b2e15Sgtb 	     return ENOMEM;
1167c478bd9Sstevel@tonic-gate      }
1177c478bd9Sstevel@tonic-gate      if (krb5_ser_unpack_bytes((krb5_octet *) oid->elements,
118ab9b2e15Sgtb 			       oid->length, &bp, &remain)) {
1197c478bd9Sstevel@tonic-gate          FREE(oid->elements, oid->length);
120ab9b2e15Sgtb          FREE(oid, sizeof(gss_OID_desc));
121ab9b2e15Sgtb 	 return EINVAL;
1227c478bd9Sstevel@tonic-gate      }
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate      /* Read in and check our trailing magic number */
1257c478bd9Sstevel@tonic-gate      if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) {
126ab9b2e15Sgtb          FREE(oid->elements, oid->length);
127ab9b2e15Sgtb          FREE(oid, sizeof(gss_OID_desc));
128ab9b2e15Sgtb 	 return (EINVAL);
1297c478bd9Sstevel@tonic-gate      }
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate      if (ibuf != KV5M_GSS_OID) {
132ab9b2e15Sgtb          FREE(oid->elements, oid->length);
133ab9b2e15Sgtb          FREE(oid, sizeof(gss_OID_desc));
134ab9b2e15Sgtb 	 return (EINVAL);
1357c478bd9Sstevel@tonic-gate      }
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate      *buffer = bp;
1387c478bd9Sstevel@tonic-gate      *lenremain = remain;
139ab9b2e15Sgtb      *argp = (krb5_pointer) oid;
1407c478bd9Sstevel@tonic-gate      return 0;
1417c478bd9Sstevel@tonic-gate }
142ab9b2e15Sgtb 
1437c478bd9Sstevel@tonic-gate /*ARGSUSED*/
144ab9b2e15Sgtb static krb5_error_code
kg_oid_size(kcontext,arg,sizep)1457c478bd9Sstevel@tonic-gate kg_oid_size(kcontext, arg, sizep)
1467c478bd9Sstevel@tonic-gate     krb5_context	kcontext;
1477c478bd9Sstevel@tonic-gate     krb5_pointer	arg;
1487c478bd9Sstevel@tonic-gate     size_t		*sizep;
1497c478bd9Sstevel@tonic-gate {
1507c478bd9Sstevel@tonic-gate    krb5_error_code kret;
1517c478bd9Sstevel@tonic-gate    gss_OID oid;
1527c478bd9Sstevel@tonic-gate    size_t required;
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate    kret = EINVAL;
155ab9b2e15Sgtb    /*LINTED*/
156ab9b2e15Sgtb    if ((oid = (gss_OID) arg)) {
1577c478bd9Sstevel@tonic-gate       required = 2*sizeof(krb5_int32); /* For the header and trailer */
1587c478bd9Sstevel@tonic-gate       required += sizeof(krb5_int32);
1597c478bd9Sstevel@tonic-gate       required += oid->length;
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate       kret = 0;
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate       *sizep += required;
1647c478bd9Sstevel@tonic-gate    }
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate    return(kret);
1677c478bd9Sstevel@tonic-gate }
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1707c478bd9Sstevel@tonic-gate static krb5_error_code
kg_queue_externalize(kcontext,arg,buffer,lenremain)1717c478bd9Sstevel@tonic-gate kg_queue_externalize(kcontext, arg, buffer, lenremain)
1727c478bd9Sstevel@tonic-gate     krb5_context	kcontext;
1737c478bd9Sstevel@tonic-gate     krb5_pointer	arg;
1747c478bd9Sstevel@tonic-gate     krb5_octet		**buffer;
1757c478bd9Sstevel@tonic-gate     size_t		*lenremain;
1767c478bd9Sstevel@tonic-gate {
1777c478bd9Sstevel@tonic-gate     krb5_error_code err;
1787c478bd9Sstevel@tonic-gate     err = krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain);
1797c478bd9Sstevel@tonic-gate     if (err == 0)
1807c478bd9Sstevel@tonic-gate 	err = g_queue_externalize(arg, buffer, lenremain);
1817c478bd9Sstevel@tonic-gate     if (err == 0)
1827c478bd9Sstevel@tonic-gate 	err = krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain);
1837c478bd9Sstevel@tonic-gate     return err;
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1877c478bd9Sstevel@tonic-gate static krb5_error_code
kg_queue_internalize(kcontext,argp,buffer,lenremain)1887c478bd9Sstevel@tonic-gate kg_queue_internalize(kcontext, argp, buffer, lenremain)
1897c478bd9Sstevel@tonic-gate     krb5_context	kcontext;
1907c478bd9Sstevel@tonic-gate     krb5_pointer	*argp;
1917c478bd9Sstevel@tonic-gate     krb5_octet		**buffer;
1927c478bd9Sstevel@tonic-gate     size_t		*lenremain;
1937c478bd9Sstevel@tonic-gate {
1947c478bd9Sstevel@tonic-gate      krb5_int32 ibuf;
1957c478bd9Sstevel@tonic-gate      krb5_octet		*bp;
1967c478bd9Sstevel@tonic-gate      size_t		remain;
197ab9b2e15Sgtb      krb5_error_code	err;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate      bp = *buffer;
2007c478bd9Sstevel@tonic-gate      remain = *lenremain;
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate      /* Read in and check our magic number */
2037c478bd9Sstevel@tonic-gate      if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
2047c478bd9Sstevel@tonic-gate 	return (EINVAL);
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate      if (ibuf != KV5M_GSS_QUEUE)
2077c478bd9Sstevel@tonic-gate 	 return (EINVAL);
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate      err = g_queue_internalize(argp, &bp, &remain);
2107c478bd9Sstevel@tonic-gate      if (err)
211ab9b2e15Sgtb 	  return err;
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate      /* Read in and check our trailing magic number */
214ab9b2e15Sgtb      if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) {
215ab9b2e15Sgtb 	 g_order_free(argp);
216ab9b2e15Sgtb 	 return (EINVAL);
217ab9b2e15Sgtb      }
2187c478bd9Sstevel@tonic-gate 
219ab9b2e15Sgtb      if (ibuf != KV5M_GSS_QUEUE) {
220ab9b2e15Sgtb 	 g_order_free(argp);
2217c478bd9Sstevel@tonic-gate 	 return (EINVAL);
222ab9b2e15Sgtb      }
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate      *buffer = bp;
2257c478bd9Sstevel@tonic-gate      *lenremain = remain;
2267c478bd9Sstevel@tonic-gate      return 0;
2277c478bd9Sstevel@tonic-gate }
228ab9b2e15Sgtb 
2297c478bd9Sstevel@tonic-gate /*ARGSUSED*/
230ab9b2e15Sgtb static krb5_error_code
kg_queue_size(kcontext,arg,sizep)2317c478bd9Sstevel@tonic-gate kg_queue_size(kcontext, arg, sizep)
2327c478bd9Sstevel@tonic-gate     krb5_context	kcontext;
2337c478bd9Sstevel@tonic-gate     krb5_pointer	arg;
2347c478bd9Sstevel@tonic-gate     size_t		*sizep;
2357c478bd9Sstevel@tonic-gate {
2367c478bd9Sstevel@tonic-gate    krb5_error_code kret;
2377c478bd9Sstevel@tonic-gate    size_t required;
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate    kret = EINVAL;
2407c478bd9Sstevel@tonic-gate    if (arg) {
2417c478bd9Sstevel@tonic-gate       required = 2*sizeof(krb5_int32); /* For the header and trailer */
2427c478bd9Sstevel@tonic-gate       (void) g_queue_size(arg, &required);
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate       kret = 0;
2457c478bd9Sstevel@tonic-gate       *sizep += required;
2467c478bd9Sstevel@tonic-gate    }
2477c478bd9Sstevel@tonic-gate    return(kret);
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate /*
2517c478bd9Sstevel@tonic-gate  * Determine the size required for this krb5_gss_ctx_id_rec.
2527c478bd9Sstevel@tonic-gate  */
2537c478bd9Sstevel@tonic-gate krb5_error_code
kg_ctx_size(kcontext,arg,sizep)2547c478bd9Sstevel@tonic-gate kg_ctx_size(kcontext, arg, sizep)
2557c478bd9Sstevel@tonic-gate     krb5_context	kcontext;
2567c478bd9Sstevel@tonic-gate     krb5_pointer	arg;
2577c478bd9Sstevel@tonic-gate     size_t		*sizep;
2587c478bd9Sstevel@tonic-gate {
2597c478bd9Sstevel@tonic-gate     krb5_error_code	kret;
2607c478bd9Sstevel@tonic-gate     krb5_gss_ctx_id_rec	*ctx;
2617c478bd9Sstevel@tonic-gate     size_t		required;
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate     /*
2647c478bd9Sstevel@tonic-gate      * krb5_gss_ctx_id_rec requires:
265ab9b2e15Sgtb      *	krb5_int32	for KG_CONTEXT
266ab9b2e15Sgtb      *	krb5_int32	for initiate.
267ab9b2e15Sgtb      *	krb5_int32	for established.
268ab9b2e15Sgtb      *	krb5_int32	for big_endian.
269ab9b2e15Sgtb      *	krb5_int32	for have_acceptor_subkey.
270ab9b2e15Sgtb      *	krb5_int32	for seed_init.
271ab9b2e15Sgtb      *	krb5_int32	for gss_flags.
272ab9b2e15Sgtb      *	sizeof(seed)	for seed
273ab9b2e15Sgtb      *	...		for here
274ab9b2e15Sgtb      *	...		for there
275ab9b2e15Sgtb      *	...		for subkey
276ab9b2e15Sgtb      *  krb5_int32	for signalg.
277ab9b2e15Sgtb      *  krb5_int32	for cksum_size.
278ab9b2e15Sgtb      *  krb5_int32	for sealalg.
279ab9b2e15Sgtb      *	...		for enc
280ab9b2e15Sgtb      *	...		for seq
281ab9b2e15Sgtb      *	krb5_int32	for endtime.
282ab9b2e15Sgtb      *	krb5_int32	for flags.
283ab9b2e15Sgtb      *	krb5_int64	for seq_send.
284ab9b2e15Sgtb      *	krb5_int64	for seq_recv.
285ab9b2e15Sgtb      *	...		for seqstate
286ab9b2e15Sgtb      *	...		for auth_context
287ab9b2e15Sgtb      *	...		for mech_used
288ab9b2e15Sgtb      *	krb5_int32	for proto
289ab9b2e15Sgtb      *	krb5_int32	for cksumtype
290ab9b2e15Sgtb      *	...		for acceptor_subkey
291ab9b2e15Sgtb      *	krb5_int32	for acceptor_key_cksumtype
292ab9b2e15Sgtb      *	krb5_int32	for cred_rcache
293ab9b2e15Sgtb      *	krb5_int32	for trailer.
2947c478bd9Sstevel@tonic-gate      */
2957c478bd9Sstevel@tonic-gate     kret = EINVAL;
296ab9b2e15Sgtb     /*LINTED*/
297ab9b2e15Sgtb     if ((ctx = (krb5_gss_ctx_id_rec *) arg)) {
298ab9b2e15Sgtb 	required = 17*sizeof(krb5_int32);
2997c478bd9Sstevel@tonic-gate 	required += 2*sizeof(krb5_int64);
3007c478bd9Sstevel@tonic-gate 	required += sizeof(ctx->seed);
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	kret = 0;
3037c478bd9Sstevel@tonic-gate 	if (!kret && ctx->here)
3047c478bd9Sstevel@tonic-gate 	    kret = krb5_size_opaque(kcontext,
3057c478bd9Sstevel@tonic-gate 				    KV5M_PRINCIPAL,
3067c478bd9Sstevel@tonic-gate 				    (krb5_pointer) ctx->here,
3077c478bd9Sstevel@tonic-gate 				    &required);
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate 	if (!kret && ctx->there)
3107c478bd9Sstevel@tonic-gate 	    kret = krb5_size_opaque(kcontext,
3117c478bd9Sstevel@tonic-gate 				    KV5M_PRINCIPAL,
3127c478bd9Sstevel@tonic-gate 				    (krb5_pointer) ctx->there,
3137c478bd9Sstevel@tonic-gate 				    &required);
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	if (!kret && ctx->subkey)
3167c478bd9Sstevel@tonic-gate 	    kret = krb5_size_opaque(kcontext,
3177c478bd9Sstevel@tonic-gate 				    KV5M_KEYBLOCK,
3187c478bd9Sstevel@tonic-gate 				    (krb5_pointer) ctx->subkey,
3197c478bd9Sstevel@tonic-gate 				    &required);
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	if (!kret && ctx->enc)
3227c478bd9Sstevel@tonic-gate 	    kret = krb5_size_opaque(kcontext,
3237c478bd9Sstevel@tonic-gate 				    KV5M_KEYBLOCK,
3247c478bd9Sstevel@tonic-gate 				    (krb5_pointer) ctx->enc,
3257c478bd9Sstevel@tonic-gate 				    &required);
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate 	if (!kret && ctx->seq)
3287c478bd9Sstevel@tonic-gate 	    kret = krb5_size_opaque(kcontext,
3297c478bd9Sstevel@tonic-gate 				    KV5M_KEYBLOCK,
3307c478bd9Sstevel@tonic-gate 				    (krb5_pointer) ctx->seq,
3317c478bd9Sstevel@tonic-gate 				    &required);
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 	if (!kret)
3347c478bd9Sstevel@tonic-gate 	    kret = kg_oid_size(kcontext,
335ab9b2e15Sgtb 			       (krb5_pointer) ctx->mech_used,
3367c478bd9Sstevel@tonic-gate 			       &required);
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate 	if (!kret && ctx->seqstate)
3397c478bd9Sstevel@tonic-gate 	    kret = kg_queue_size(kcontext, ctx->seqstate, &required);
340ab9b2e15Sgtb 
3417c478bd9Sstevel@tonic-gate #ifndef PROVIDE_KERNEL_IMPORT
342ab9b2e15Sgtb 	if (!kret)
343ab9b2e15Sgtb 	    kret = krb5_size_opaque(kcontext,
344ab9b2e15Sgtb 				    KV5M_CONTEXT,
345ab9b2e15Sgtb 				    (krb5_pointer) ctx->k5_context,
346ab9b2e15Sgtb 				    &required);
3477c478bd9Sstevel@tonic-gate 	if (!kret)
3487c478bd9Sstevel@tonic-gate 	    kret = krb5_size_opaque(kcontext,
3497c478bd9Sstevel@tonic-gate 				    KV5M_AUTH_CONTEXT,
3507c478bd9Sstevel@tonic-gate 				    (krb5_pointer) ctx->auth_context,
3517c478bd9Sstevel@tonic-gate 				    &required);
3527c478bd9Sstevel@tonic-gate #endif
3537c478bd9Sstevel@tonic-gate 
354ab9b2e15Sgtb 	if (!kret && ctx->acceptor_subkey)
355ab9b2e15Sgtb 	    kret = krb5_size_opaque(kcontext,
356ab9b2e15Sgtb 				    KV5M_KEYBLOCK,
357ab9b2e15Sgtb 				    (krb5_pointer) ctx->acceptor_subkey,
358ab9b2e15Sgtb 				    &required);
3597c478bd9Sstevel@tonic-gate 	if (!kret)
3607c478bd9Sstevel@tonic-gate 	    *sizep += required;
3617c478bd9Sstevel@tonic-gate     }
3627c478bd9Sstevel@tonic-gate     return(kret);
3637c478bd9Sstevel@tonic-gate }
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate /*
3667c478bd9Sstevel@tonic-gate  * Externalize this krb5_gss_ctx_id_ret.
3677c478bd9Sstevel@tonic-gate  */
3687c478bd9Sstevel@tonic-gate krb5_error_code
kg_ctx_externalize(kcontext,arg,buffer,lenremain)3697c478bd9Sstevel@tonic-gate kg_ctx_externalize(kcontext, arg, buffer, lenremain)
3707c478bd9Sstevel@tonic-gate     krb5_context	kcontext;
3717c478bd9Sstevel@tonic-gate     krb5_pointer	arg;
3727c478bd9Sstevel@tonic-gate     krb5_octet		**buffer;
3737c478bd9Sstevel@tonic-gate     size_t		*lenremain;
3747c478bd9Sstevel@tonic-gate {
3757c478bd9Sstevel@tonic-gate     krb5_error_code	kret;
3767c478bd9Sstevel@tonic-gate     krb5_gss_ctx_id_rec	*ctx;
3777c478bd9Sstevel@tonic-gate     size_t		required;
3787c478bd9Sstevel@tonic-gate     krb5_octet		*bp;
3797c478bd9Sstevel@tonic-gate     size_t		remain;
380ab9b2e15Sgtb #ifndef _KERNEL
381ab9b2e15Sgtb     krb5int_access kaccess;
3827c478bd9Sstevel@tonic-gate 
383ab9b2e15Sgtb     kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
384ab9b2e15Sgtb     if (kret)
385ab9b2e15Sgtb         return(kret);
386ab9b2e15Sgtb #endif
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate     required = 0;
3897c478bd9Sstevel@tonic-gate     bp = *buffer;
3907c478bd9Sstevel@tonic-gate     remain = *lenremain;
3917c478bd9Sstevel@tonic-gate     kret = EINVAL;
392ab9b2e15Sgtb     /*LINTED*/
393ab9b2e15Sgtb     if ((ctx = (krb5_gss_ctx_id_rec *) arg)) {
3947c478bd9Sstevel@tonic-gate 	kret = ENOMEM;
3957c478bd9Sstevel@tonic-gate 	if (!kg_ctx_size(kcontext, arg, &required) &&
3967c478bd9Sstevel@tonic-gate 	    (required <= remain)) {
3977c478bd9Sstevel@tonic-gate 	    /* Our identifier */
3987c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain);
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	    /* Now static data */
401ab9b2e15Sgtb 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->initiate,
402ab9b2e15Sgtb 				       &bp, &remain);
403ab9b2e15Sgtb 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->established,
404ab9b2e15Sgtb 				       &bp, &remain);
405ab9b2e15Sgtb 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian,
406ab9b2e15Sgtb 				       &bp, &remain);
407ab9b2e15Sgtb 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->have_acceptor_subkey,
408ab9b2e15Sgtb 				       &bp, &remain);
409ab9b2e15Sgtb 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->seed_init,
410ab9b2e15Sgtb 				       &bp, &remain);
411ab9b2e15Sgtb 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->gss_flags,
412ab9b2e15Sgtb 				       &bp, &remain);
413ab9b2e15Sgtb 	    (void) krb5_ser_pack_bytes((krb5_octet *) ctx->seed,
414ab9b2e15Sgtb 				       sizeof(ctx->seed),
415ab9b2e15Sgtb 				       &bp, &remain);
4167c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->signalg,
4177c478bd9Sstevel@tonic-gate 				       &bp, &remain);
4187c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->cksum_size,
4197c478bd9Sstevel@tonic-gate 				       &bp, &remain);
4207c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->sealalg,
4217c478bd9Sstevel@tonic-gate 				       &bp, &remain);
4227c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->endtime,
4237c478bd9Sstevel@tonic-gate 				       &bp, &remain);
4247c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_pack_int32((krb5_int32) ctx->krb_flags,
4257c478bd9Sstevel@tonic-gate 				       &bp, &remain);
426ab9b2e15Sgtb #ifndef _KERNEL
427ab9b2e15Sgtb 	    (void) (*kaccess.krb5_ser_pack_int64)((krb5_int64) ctx->seq_send,
428ab9b2e15Sgtb 				       &bp, &remain);
429ab9b2e15Sgtb 	    (void) (*kaccess.krb5_ser_pack_int64)((krb5_int64) ctx->seq_recv,
430ab9b2e15Sgtb 				       &bp, &remain);
431ab9b2e15Sgtb #else
4327c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_pack_int64((krb5_int64) ctx->seq_send,
4337c478bd9Sstevel@tonic-gate 				       &bp, &remain);
4347c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_pack_int64((krb5_int64) ctx->seq_recv,
4357c478bd9Sstevel@tonic-gate 				       &bp, &remain);
436ab9b2e15Sgtb #endif
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 	    /* Now dynamic data */
4397c478bd9Sstevel@tonic-gate 	    kret = 0;
4407c478bd9Sstevel@tonic-gate 
441ab9b2e15Sgtb 	    if (!kret && ctx->mech_used)
442ab9b2e15Sgtb 		 kret = kg_oid_externalize(kcontext, ctx->mech_used,
4437c478bd9Sstevel@tonic-gate 					   &bp, &remain);
4447c478bd9Sstevel@tonic-gate 
4457c478bd9Sstevel@tonic-gate 	    if (!kret && ctx->here)
4467c478bd9Sstevel@tonic-gate 		kret = krb5_externalize_opaque(kcontext,
4477c478bd9Sstevel@tonic-gate 					       KV5M_PRINCIPAL,
4487c478bd9Sstevel@tonic-gate 					       (krb5_pointer) ctx->here,
4497c478bd9Sstevel@tonic-gate 					       &bp, &remain);
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	    if (!kret && ctx->there)
4527c478bd9Sstevel@tonic-gate 		kret = krb5_externalize_opaque(kcontext,
4537c478bd9Sstevel@tonic-gate 					       KV5M_PRINCIPAL,
4547c478bd9Sstevel@tonic-gate 					       (krb5_pointer) ctx->there,
4557c478bd9Sstevel@tonic-gate 					       &bp, &remain);
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate 	    if (!kret && ctx->subkey)
4587c478bd9Sstevel@tonic-gate 		kret = krb5_externalize_opaque(kcontext,
4597c478bd9Sstevel@tonic-gate 					       KV5M_KEYBLOCK,
4607c478bd9Sstevel@tonic-gate 					       (krb5_pointer) ctx->subkey,
4617c478bd9Sstevel@tonic-gate 					       &bp, &remain);
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate 	    if (!kret && ctx->enc)
4647c478bd9Sstevel@tonic-gate 		kret = krb5_externalize_opaque(kcontext,
4657c478bd9Sstevel@tonic-gate 					       KV5M_KEYBLOCK,
4667c478bd9Sstevel@tonic-gate 					       (krb5_pointer) ctx->enc,
4677c478bd9Sstevel@tonic-gate 					       &bp, &remain);
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 	    if (!kret && ctx->seq)
4707c478bd9Sstevel@tonic-gate 		kret = krb5_externalize_opaque(kcontext,
4717c478bd9Sstevel@tonic-gate 					       KV5M_KEYBLOCK,
4727c478bd9Sstevel@tonic-gate 					       (krb5_pointer) ctx->seq,
4737c478bd9Sstevel@tonic-gate 					       &bp, &remain);
4747c478bd9Sstevel@tonic-gate 
4757c478bd9Sstevel@tonic-gate 	    if (!kret && ctx->seqstate)
4767c478bd9Sstevel@tonic-gate 		kret = kg_queue_externalize(kcontext,
4777c478bd9Sstevel@tonic-gate 					    ctx->seqstate, &bp, &remain);
4787c478bd9Sstevel@tonic-gate 
4797c478bd9Sstevel@tonic-gate #ifndef PROVIDE_KERNEL_IMPORT
480ab9b2e15Sgtb 	    if (!kret)
481ab9b2e15Sgtb 		kret = krb5_externalize_opaque(kcontext,
482ab9b2e15Sgtb 					       KV5M_CONTEXT,
483ab9b2e15Sgtb 					       (krb5_pointer) ctx->k5_context,
484ab9b2e15Sgtb 					       &bp, &remain);
4857c478bd9Sstevel@tonic-gate 	    if (!kret)
4867c478bd9Sstevel@tonic-gate 		kret = krb5_externalize_opaque(kcontext,
4877c478bd9Sstevel@tonic-gate 					       KV5M_AUTH_CONTEXT,
4887c478bd9Sstevel@tonic-gate 					       (krb5_pointer) ctx->auth_context,
4897c478bd9Sstevel@tonic-gate 					       &bp, &remain);
4907c478bd9Sstevel@tonic-gate #endif
491ab9b2e15Sgtb 	    if (!kret)
4927c478bd9Sstevel@tonic-gate 		kret = krb5_ser_pack_int32((krb5_int32) ctx->proto,
493ab9b2e15Sgtb 					   &bp, &remain);
494ab9b2e15Sgtb 	    if (!kret)
4957c478bd9Sstevel@tonic-gate 		kret = krb5_ser_pack_int32((krb5_int32) ctx->cksumtype,
496ab9b2e15Sgtb 					   &bp, &remain);
497ab9b2e15Sgtb 	    if (!kret && ctx->acceptor_subkey)
4987c478bd9Sstevel@tonic-gate 		kret = krb5_externalize_opaque(kcontext,
499ab9b2e15Sgtb 					       KV5M_KEYBLOCK,
500ab9b2e15Sgtb 					       (krb5_pointer) ctx->acceptor_subkey,
501ab9b2e15Sgtb 					       &bp, &remain);
502ab9b2e15Sgtb 	    if (!kret)
5037c478bd9Sstevel@tonic-gate 		kret = krb5_ser_pack_int32((krb5_int32) ctx->acceptor_subkey_cksumtype,
504ab9b2e15Sgtb 					   &bp, &remain);
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate 	    if (!kret)
507ab9b2e15Sgtb 		kret = krb5_ser_pack_int32((krb5_int32) ctx->cred_rcache,
508ab9b2e15Sgtb 					   &bp, &remain);
509ab9b2e15Sgtb 	    /* trailer */
510ab9b2e15Sgtb 	    if (!kret)
511ab9b2e15Sgtb 		kret = krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain);
5127c478bd9Sstevel@tonic-gate 	    if (!kret) {
5137c478bd9Sstevel@tonic-gate 		*buffer = bp;
5147c478bd9Sstevel@tonic-gate 		*lenremain = remain;
5157c478bd9Sstevel@tonic-gate 	    }
5167c478bd9Sstevel@tonic-gate 	}
5177c478bd9Sstevel@tonic-gate     }
5187c478bd9Sstevel@tonic-gate     return(kret);
5197c478bd9Sstevel@tonic-gate }
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate /*
5227c478bd9Sstevel@tonic-gate  * Internalize this krb5_gss_ctx_id_t.
5237c478bd9Sstevel@tonic-gate  */
5247c478bd9Sstevel@tonic-gate krb5_error_code
kg_ctx_internalize(kcontext,argp,buffer,lenremain)5257c478bd9Sstevel@tonic-gate kg_ctx_internalize(kcontext, argp, buffer, lenremain)
5267c478bd9Sstevel@tonic-gate     krb5_context	kcontext;
5277c478bd9Sstevel@tonic-gate     krb5_pointer	*argp;
5287c478bd9Sstevel@tonic-gate     krb5_octet		**buffer;
5297c478bd9Sstevel@tonic-gate     size_t		*lenremain;
5307c478bd9Sstevel@tonic-gate {
5317c478bd9Sstevel@tonic-gate     krb5_error_code	kret;
5327c478bd9Sstevel@tonic-gate     krb5_gss_ctx_id_rec	*ctx;
5337c478bd9Sstevel@tonic-gate     krb5_int32		ibuf;
5347c478bd9Sstevel@tonic-gate     krb5_octet		*bp;
5357c478bd9Sstevel@tonic-gate     size_t		remain;
536ab9b2e15Sgtb #ifndef _KERNEL
537ab9b2e15Sgtb     krb5int_access kaccess;
5387c478bd9Sstevel@tonic-gate 
539ab9b2e15Sgtb     kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
540ab9b2e15Sgtb     if (kret)
541ab9b2e15Sgtb         return(kret);
542ab9b2e15Sgtb #endif
5437c478bd9Sstevel@tonic-gate 
5447c478bd9Sstevel@tonic-gate     bp = *buffer;
5457c478bd9Sstevel@tonic-gate     remain = *lenremain;
5467c478bd9Sstevel@tonic-gate     kret = EINVAL;
5477c478bd9Sstevel@tonic-gate     /* Read our magic number */
5487c478bd9Sstevel@tonic-gate     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
5497c478bd9Sstevel@tonic-gate 	ibuf = 0;
5507c478bd9Sstevel@tonic-gate     if (ibuf == KG_CONTEXT) {
5517c478bd9Sstevel@tonic-gate 	kret = ENOMEM;
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	/* Get a context */
554ab9b2e15Sgtb 	if ((remain >= (17*sizeof(krb5_int32)
5557c478bd9Sstevel@tonic-gate 			+ 2*sizeof(krb5_int64)
5567c478bd9Sstevel@tonic-gate 			+ sizeof(ctx->seed))) &&
5577c478bd9Sstevel@tonic-gate 	    (ctx = (krb5_gss_ctx_id_rec *)
5587c478bd9Sstevel@tonic-gate 	     xmalloc(sizeof(krb5_gss_ctx_id_rec)))) {
5597c478bd9Sstevel@tonic-gate 	    (void) memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec));
5607c478bd9Sstevel@tonic-gate 
561ab9b2e15Sgtb 	    ctx->k5_context = kcontext;
562ab9b2e15Sgtb 
5637c478bd9Sstevel@tonic-gate 	    /* Get static data */
564ab9b2e15Sgtb 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
565ab9b2e15Sgtb 	    ctx->initiate = (int) ibuf;
566ab9b2e15Sgtb 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
567ab9b2e15Sgtb 	    ctx->established = (int) ibuf;
568ab9b2e15Sgtb 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
569ab9b2e15Sgtb 	    ctx->big_endian = (int) ibuf;
570ab9b2e15Sgtb 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
571ab9b2e15Sgtb 	    ctx->have_acceptor_subkey = (int) ibuf;
572ab9b2e15Sgtb 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
573ab9b2e15Sgtb 	    ctx->seed_init = (int) ibuf;
574ab9b2e15Sgtb 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
575ab9b2e15Sgtb 	    ctx->gss_flags = (int) ibuf;
5767c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_unpack_bytes((krb5_octet *) ctx->seed,
5777c478bd9Sstevel@tonic-gate 					 sizeof(ctx->seed),
5787c478bd9Sstevel@tonic-gate 					 &bp, &remain);
5797c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
5807c478bd9Sstevel@tonic-gate 	    ctx->signalg = (int) ibuf;
5817c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
5827c478bd9Sstevel@tonic-gate 	    ctx->cksum_size = (int) ibuf;
5837c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
5847c478bd9Sstevel@tonic-gate 	    ctx->sealalg = (int) ibuf;
5857c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
5867c478bd9Sstevel@tonic-gate 	    ctx->endtime = (krb5_timestamp) ibuf;
5877c478bd9Sstevel@tonic-gate 	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
5887c478bd9Sstevel@tonic-gate 	    ctx->krb_flags = (krb5_flags) ibuf;
589ab9b2e15Sgtb #ifndef _KERNEL
590ab9b2e15Sgtb 	    (void) (*kaccess.krb5_ser_unpack_int64)((krb5_int64 *)&ctx->seq_send, &bp, &remain);
591ab9b2e15Sgtb 	    kret = (*kaccess.krb5_ser_unpack_int64)((krb5_int64 *)&ctx->seq_recv, &bp, &remain);
592ab9b2e15Sgtb #else
593ab9b2e15Sgtb 	    (void) krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_send),
594ab9b2e15Sgtb 					&bp, &remain);
595ab9b2e15Sgtb 	    kret = krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_recv),
596ab9b2e15Sgtb 					&bp, &remain);
597ab9b2e15Sgtb #endif
598ab9b2e15Sgtb 	    if (kret) {
599ab9b2e15Sgtb 		xfree_wrap(ctx, sizeof (krb5_gss_ctx_id_rec));
600ab9b2e15Sgtb 		return kret;
601ab9b2e15Sgtb 	    }
602ab9b2e15Sgtb 
6037c478bd9Sstevel@tonic-gate 	    if ((kret = kg_oid_internalize(kcontext,
604ab9b2e15Sgtb 					(krb5_pointer *) &ctx->mech_used, &bp,
605ab9b2e15Sgtb 					   &remain))) {
6067c478bd9Sstevel@tonic-gate 		 if (kret == EINVAL)
6077c478bd9Sstevel@tonic-gate 		      kret = 0;
6087c478bd9Sstevel@tonic-gate 	    }
6097c478bd9Sstevel@tonic-gate 	    /* Now get substructure data */
6107c478bd9Sstevel@tonic-gate 	    if ((kret = krb5_internalize_opaque(kcontext,
6117c478bd9Sstevel@tonic-gate 						KV5M_PRINCIPAL,
6127c478bd9Sstevel@tonic-gate 						(krb5_pointer *) &ctx->here,
6137c478bd9Sstevel@tonic-gate 						&bp, &remain))) {
6147c478bd9Sstevel@tonic-gate 		if (kret == EINVAL)
6157c478bd9Sstevel@tonic-gate 		    kret = 0;
6167c478bd9Sstevel@tonic-gate 	    }
6177c478bd9Sstevel@tonic-gate 	    if (!kret &&
6187c478bd9Sstevel@tonic-gate 		(kret = krb5_internalize_opaque(kcontext,
6197c478bd9Sstevel@tonic-gate 						KV5M_PRINCIPAL,
6207c478bd9Sstevel@tonic-gate 						(krb5_pointer *) &ctx->there,
6217c478bd9Sstevel@tonic-gate 						&bp, &remain))) {
6227c478bd9Sstevel@tonic-gate 		if (kret == EINVAL)
6237c478bd9Sstevel@tonic-gate 		    kret = 0;
6247c478bd9Sstevel@tonic-gate 	    }
6257c478bd9Sstevel@tonic-gate 	    if (!kret &&
6267c478bd9Sstevel@tonic-gate 		(kret = krb5_internalize_opaque(kcontext,
6277c478bd9Sstevel@tonic-gate 						KV5M_KEYBLOCK,
6287c478bd9Sstevel@tonic-gate 						(krb5_pointer *) &ctx->subkey,
6297c478bd9Sstevel@tonic-gate 						&bp, &remain))) {
6307c478bd9Sstevel@tonic-gate 		if (kret == EINVAL)
6317c478bd9Sstevel@tonic-gate 		    kret = 0;
6327c478bd9Sstevel@tonic-gate 	    }
6337c478bd9Sstevel@tonic-gate 	    if (!kret &&
6347c478bd9Sstevel@tonic-gate 		(kret = krb5_internalize_opaque(kcontext,
6357c478bd9Sstevel@tonic-gate 						KV5M_KEYBLOCK,
6367c478bd9Sstevel@tonic-gate 						(krb5_pointer *) &ctx->enc,
6377c478bd9Sstevel@tonic-gate 						&bp, &remain))) {
6387c478bd9Sstevel@tonic-gate 		if (kret == EINVAL)
6397c478bd9Sstevel@tonic-gate 		    kret = 0;
6407c478bd9Sstevel@tonic-gate 	    }
6417c478bd9Sstevel@tonic-gate 	    if (!kret &&
6427c478bd9Sstevel@tonic-gate 		(kret = krb5_internalize_opaque(kcontext,
6437c478bd9Sstevel@tonic-gate 						KV5M_KEYBLOCK,
6447c478bd9Sstevel@tonic-gate 						(krb5_pointer *) &ctx->seq,
6457c478bd9Sstevel@tonic-gate 						&bp, &remain))) {
6467c478bd9Sstevel@tonic-gate 		if (kret == EINVAL)
6477c478bd9Sstevel@tonic-gate 		    kret = 0;
6487c478bd9Sstevel@tonic-gate 	    }
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate 	    if (!kret) {
6517c478bd9Sstevel@tonic-gate 		kret = kg_queue_internalize(kcontext, &ctx->seqstate,
6527c478bd9Sstevel@tonic-gate 					    &bp, &remain);
6537c478bd9Sstevel@tonic-gate 		if (kret == EINVAL)
6547c478bd9Sstevel@tonic-gate 		    kret = 0;
6557c478bd9Sstevel@tonic-gate 	    }
656*159d09a2SMark Phalan 
6577c478bd9Sstevel@tonic-gate #ifndef PROVIDE_KERNEL_IMPORT
658ab9b2e15Sgtb 	    if (!kret)
659ab9b2e15Sgtb 		kret = krb5_internalize_opaque(kcontext,
660ab9b2e15Sgtb 					       KV5M_CONTEXT,
661*159d09a2SMark Phalan 					       (krb5_pointer *) &ctx->k5_context,
662*159d09a2SMark Phalan 					       &bp, &remain);
663ab9b2e15Sgtb 
664ab9b2e15Sgtb 	    if (!kret)
6657c478bd9Sstevel@tonic-gate 		kret = krb5_internalize_opaque(kcontext,
6667c478bd9Sstevel@tonic-gate 					       KV5M_AUTH_CONTEXT,
6677c478bd9Sstevel@tonic-gate 				       (krb5_pointer *) &ctx->auth_context,
6687c478bd9Sstevel@tonic-gate 					       &bp, &remain);
6697c478bd9Sstevel@tonic-gate #endif
6707c478bd9Sstevel@tonic-gate 	    if (!kret)
6717c478bd9Sstevel@tonic-gate 		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
6727c478bd9Sstevel@tonic-gate 	    ctx->proto = ibuf;
6737c478bd9Sstevel@tonic-gate 	    if (!kret)
6747c478bd9Sstevel@tonic-gate 		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
6757c478bd9Sstevel@tonic-gate 	    ctx->cksumtype = ibuf;
6767c478bd9Sstevel@tonic-gate 	    if (!kret &&
6777c478bd9Sstevel@tonic-gate 		(kret = krb5_internalize_opaque(kcontext,
6787c478bd9Sstevel@tonic-gate 						KV5M_KEYBLOCK,
6797c478bd9Sstevel@tonic-gate 						(krb5_pointer *) &ctx->acceptor_subkey,
6807c478bd9Sstevel@tonic-gate 						&bp, &remain))) {
6817c478bd9Sstevel@tonic-gate 		if (kret == EINVAL)
682ab9b2e15Sgtb 		    kret = 0;
683ab9b2e15Sgtb 	    }
684ab9b2e15Sgtb 	    if (!kret)
6857c478bd9Sstevel@tonic-gate 		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
686ab9b2e15Sgtb 	    ctx->cred_rcache = ibuf;
687ab9b2e15Sgtb 	    if (!kret)
6887c478bd9Sstevel@tonic-gate 		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
689ab9b2e15Sgtb 	    ctx->acceptor_subkey_cksumtype = ibuf;
6907c478bd9Sstevel@tonic-gate 
691ab9b2e15Sgtb 	    /* Get trailer */
692ab9b2e15Sgtb 	    if (!kret)
693ab9b2e15Sgtb 		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
694ab9b2e15Sgtb 	    if (!kret && ibuf != KG_CONTEXT)
6957c478bd9Sstevel@tonic-gate 		kret = EINVAL;
6967c478bd9Sstevel@tonic-gate 
697ab9b2e15Sgtb 	    if (!kret) {
6987c478bd9Sstevel@tonic-gate 		*buffer = bp;
6997c478bd9Sstevel@tonic-gate 		*lenremain = remain;
7007c478bd9Sstevel@tonic-gate 		*argp = (krb5_pointer) ctx;
7017c478bd9Sstevel@tonic-gate 	    } else {
7027c478bd9Sstevel@tonic-gate 		if (ctx->seq)
7037c478bd9Sstevel@tonic-gate 		    krb5_free_keyblock(kcontext, ctx->seq);
7047c478bd9Sstevel@tonic-gate 		if (ctx->enc)
7057c478bd9Sstevel@tonic-gate 		    krb5_free_keyblock(kcontext, ctx->enc);
7067c478bd9Sstevel@tonic-gate 		if (ctx->subkey)
7077c478bd9Sstevel@tonic-gate 		    krb5_free_keyblock(kcontext, ctx->subkey);
7087c478bd9Sstevel@tonic-gate 		if (ctx->there)
7097c478bd9Sstevel@tonic-gate 		    krb5_free_principal(kcontext, ctx->there);
7107c478bd9Sstevel@tonic-gate 		if (ctx->here)
7117c478bd9Sstevel@tonic-gate 		    krb5_free_principal(kcontext, ctx->here);
7127c478bd9Sstevel@tonic-gate 		xfree_wrap(ctx, sizeof (krb5_gss_ctx_id_rec));
7137c478bd9Sstevel@tonic-gate 	    }
7147c478bd9Sstevel@tonic-gate 	}
7157c478bd9Sstevel@tonic-gate     }
7167c478bd9Sstevel@tonic-gate     return(kret);
7177c478bd9Sstevel@tonic-gate }
718