1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * lib/gssapi/krb5/ser_sctx.c 10 * 11 * Copyright 1995, 2004 by the Massachusetts Institute of Technology. 12 * All Rights Reserved. 13 * 14 * Export of this software from the United States of America may 15 * require a specific license from the United States Government. 16 * It is the responsibility of any person or organization contemplating 17 * export to obtain such a license before exporting. 18 * 19 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 20 * distribute this software and its documentation for any purpose and 21 * without fee is hereby granted, provided that the above copyright 22 * notice appear in all copies and that both that copyright notice and 23 * this permission notice appear in supporting documentation, and that 24 * the name of M.I.T. not be used in advertising or publicity pertaining 25 * to distribution of the software without specific, written prior 26 * permission. Furthermore if you modify this software you must label 27 * your software as modified software and not distribute it in such a 28 * fashion that it might be confused with the original M.I.T. software. 29 * M.I.T. makes no representations about the suitability of 30 * this software for any purpose. It is provided "as is" without express 31 * or implied warranty. 32 * 33 */ 34 35 /* 36 * ser_sctx.c - Handle [de]serialization of GSSAPI security context. 37 */ 38 /* Solaris Kerberos: order is important here. include gssapiP_krb5.h 39 * before all others, otherwise we get a LINT error from MALLOC macro 40 * being redefined in mechglueP.h */ 41 #include "gssapiP_krb5.h" 42 #include "k5-int.h" 43 44 /* 45 * This module contains routines to [de]serialize 46 * krb5_gss_enc_desc and krb5_gss_ctx_id_t. 47 * XXX This whole serialization abstraction is unnecessary in a 48 * non-messaging environment, which krb5 is. Someday, this should 49 * all get redone without the extra level of indirection. I've done 50 * some of this work here, since adding new serializers is an internal 51 * krb5 interface, and I won't use those. There is some more 52 * deobfuscation (no longer anonymizing pointers, mostly) which could 53 * still be done. --marc 54 */ 55 56 /*ARGSUSED*/ 57 static krb5_error_code 58 kg_oid_externalize(kcontext, arg, buffer, lenremain) 59 krb5_context kcontext; 60 krb5_pointer arg; 61 krb5_octet **buffer; 62 size_t *lenremain; 63 { 64 gss_OID oid = (gss_OID) arg; 65 krb5_error_code err; 66 67 err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain); 68 if (err) 69 return err; 70 err = krb5_ser_pack_int32((krb5_int32) oid->length, 71 buffer, lenremain); 72 if (err) 73 return err; 74 err = krb5_ser_pack_bytes((krb5_octet *) oid->elements, 75 oid->length, buffer, lenremain); 76 if (err) 77 return err; 78 err = krb5_ser_pack_int32(KV5M_GSS_OID, buffer, lenremain); 79 return err; 80 } 81 82 /*ARGSUSED*/ 83 static krb5_error_code 84 kg_oid_internalize(kcontext, argp, buffer, lenremain) 85 krb5_context kcontext; 86 krb5_pointer *argp; 87 krb5_octet **buffer; 88 size_t *lenremain; 89 { 90 gss_OID oid; 91 krb5_int32 ibuf; 92 krb5_octet *bp; 93 size_t remain; 94 95 bp = *buffer; 96 remain = *lenremain; 97 98 /* Read in and check our magic number */ 99 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) 100 return (EINVAL); 101 102 if (ibuf != KV5M_GSS_OID) 103 return (EINVAL); 104 105 oid = (gss_OID) MALLOC(sizeof(gss_OID_desc)); 106 if (oid == NULL) 107 return ENOMEM; 108 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) { 109 FREE(oid, sizeof(gss_OID_desc)); 110 return EINVAL; 111 } 112 oid->length = ibuf; 113 oid->elements = MALLOC(ibuf); 114 if (oid->elements == 0) { 115 FREE(oid, sizeof(gss_OID_desc)); 116 return ENOMEM; 117 } 118 if (krb5_ser_unpack_bytes((krb5_octet *) oid->elements, 119 oid->length, &bp, &remain)) { 120 FREE(oid->elements, oid->length); 121 FREE(oid, sizeof(gss_OID_desc)); 122 return EINVAL; 123 } 124 125 /* Read in and check our trailing magic number */ 126 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) { 127 FREE(oid->elements, oid->length); 128 FREE(oid, sizeof(gss_OID_desc)); 129 return (EINVAL); 130 } 131 132 if (ibuf != KV5M_GSS_OID) { 133 FREE(oid->elements, oid->length); 134 FREE(oid, sizeof(gss_OID_desc)); 135 return (EINVAL); 136 } 137 138 *buffer = bp; 139 *lenremain = remain; 140 *argp = (krb5_pointer) oid; 141 return 0; 142 } 143 144 /*ARGSUSED*/ 145 static krb5_error_code 146 kg_oid_size(kcontext, arg, sizep) 147 krb5_context kcontext; 148 krb5_pointer arg; 149 size_t *sizep; 150 { 151 krb5_error_code kret; 152 gss_OID oid; 153 size_t required; 154 155 kret = EINVAL; 156 /*LINTED*/ 157 if ((oid = (gss_OID) arg)) { 158 required = 2*sizeof(krb5_int32); /* For the header and trailer */ 159 required += sizeof(krb5_int32); 160 required += oid->length; 161 162 kret = 0; 163 164 *sizep += required; 165 } 166 167 return(kret); 168 } 169 170 /*ARGSUSED*/ 171 static krb5_error_code 172 kg_queue_externalize(kcontext, arg, buffer, lenremain) 173 krb5_context kcontext; 174 krb5_pointer arg; 175 krb5_octet **buffer; 176 size_t *lenremain; 177 { 178 krb5_error_code err; 179 err = krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain); 180 if (err == 0) 181 err = g_queue_externalize(arg, buffer, lenremain); 182 if (err == 0) 183 err = krb5_ser_pack_int32(KV5M_GSS_QUEUE, buffer, lenremain); 184 return err; 185 } 186 187 /*ARGSUSED*/ 188 static krb5_error_code 189 kg_queue_internalize(kcontext, argp, buffer, lenremain) 190 krb5_context kcontext; 191 krb5_pointer *argp; 192 krb5_octet **buffer; 193 size_t *lenremain; 194 { 195 krb5_int32 ibuf; 196 krb5_octet *bp; 197 size_t remain; 198 krb5_error_code err; 199 200 bp = *buffer; 201 remain = *lenremain; 202 203 /* Read in and check our magic number */ 204 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) 205 return (EINVAL); 206 207 if (ibuf != KV5M_GSS_QUEUE) 208 return (EINVAL); 209 210 err = g_queue_internalize(argp, &bp, &remain); 211 if (err) 212 return err; 213 214 /* Read in and check our trailing magic number */ 215 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) { 216 g_order_free(argp); 217 return (EINVAL); 218 } 219 220 if (ibuf != KV5M_GSS_QUEUE) { 221 g_order_free(argp); 222 return (EINVAL); 223 } 224 225 *buffer = bp; 226 *lenremain = remain; 227 return 0; 228 } 229 230 /*ARGSUSED*/ 231 static krb5_error_code 232 kg_queue_size(kcontext, arg, sizep) 233 krb5_context kcontext; 234 krb5_pointer arg; 235 size_t *sizep; 236 { 237 krb5_error_code kret; 238 size_t required; 239 240 kret = EINVAL; 241 if (arg) { 242 required = 2*sizeof(krb5_int32); /* For the header and trailer */ 243 (void) g_queue_size(arg, &required); 244 245 kret = 0; 246 *sizep += required; 247 } 248 return(kret); 249 } 250 251 /* 252 * Determine the size required for this krb5_gss_ctx_id_rec. 253 */ 254 krb5_error_code 255 kg_ctx_size(kcontext, arg, sizep) 256 krb5_context kcontext; 257 krb5_pointer arg; 258 size_t *sizep; 259 { 260 krb5_error_code kret; 261 krb5_gss_ctx_id_rec *ctx; 262 size_t required; 263 264 /* 265 * krb5_gss_ctx_id_rec requires: 266 * krb5_int32 for KG_CONTEXT 267 * krb5_int32 for initiate. 268 * krb5_int32 for established. 269 * krb5_int32 for big_endian. 270 * krb5_int32 for have_acceptor_subkey. 271 * krb5_int32 for seed_init. 272 * krb5_int32 for gss_flags. 273 * sizeof(seed) for seed 274 * ... for here 275 * ... for there 276 * ... for subkey 277 * krb5_int32 for signalg. 278 * krb5_int32 for cksum_size. 279 * krb5_int32 for sealalg. 280 * ... for enc 281 * ... for seq 282 * krb5_int32 for endtime. 283 * krb5_int32 for flags. 284 * krb5_int64 for seq_send. 285 * krb5_int64 for seq_recv. 286 * ... for seqstate 287 * ... for auth_context 288 * ... for mech_used 289 * krb5_int32 for proto 290 * krb5_int32 for cksumtype 291 * ... for acceptor_subkey 292 * krb5_int32 for acceptor_key_cksumtype 293 * krb5_int32 for cred_rcache 294 * krb5_int32 for trailer. 295 */ 296 kret = EINVAL; 297 /*LINTED*/ 298 if ((ctx = (krb5_gss_ctx_id_rec *) arg)) { 299 required = 17*sizeof(krb5_int32); 300 required += 2*sizeof(krb5_int64); 301 required += sizeof(ctx->seed); 302 303 kret = 0; 304 if (!kret && ctx->here) 305 kret = krb5_size_opaque(kcontext, 306 KV5M_PRINCIPAL, 307 (krb5_pointer) ctx->here, 308 &required); 309 310 if (!kret && ctx->there) 311 kret = krb5_size_opaque(kcontext, 312 KV5M_PRINCIPAL, 313 (krb5_pointer) ctx->there, 314 &required); 315 316 if (!kret && ctx->subkey) 317 kret = krb5_size_opaque(kcontext, 318 KV5M_KEYBLOCK, 319 (krb5_pointer) ctx->subkey, 320 &required); 321 322 if (!kret && ctx->enc) 323 kret = krb5_size_opaque(kcontext, 324 KV5M_KEYBLOCK, 325 (krb5_pointer) ctx->enc, 326 &required); 327 328 if (!kret && ctx->seq) 329 kret = krb5_size_opaque(kcontext, 330 KV5M_KEYBLOCK, 331 (krb5_pointer) ctx->seq, 332 &required); 333 334 if (!kret) 335 kret = kg_oid_size(kcontext, 336 (krb5_pointer) ctx->mech_used, 337 &required); 338 339 if (!kret && ctx->seqstate) 340 kret = kg_queue_size(kcontext, ctx->seqstate, &required); 341 342 #ifndef PROVIDE_KERNEL_IMPORT 343 if (!kret) 344 kret = krb5_size_opaque(kcontext, 345 KV5M_CONTEXT, 346 (krb5_pointer) ctx->k5_context, 347 &required); 348 if (!kret) 349 kret = krb5_size_opaque(kcontext, 350 KV5M_AUTH_CONTEXT, 351 (krb5_pointer) ctx->auth_context, 352 &required); 353 #endif 354 355 if (!kret && ctx->acceptor_subkey) 356 kret = krb5_size_opaque(kcontext, 357 KV5M_KEYBLOCK, 358 (krb5_pointer) ctx->acceptor_subkey, 359 &required); 360 if (!kret) 361 *sizep += required; 362 } 363 return(kret); 364 } 365 366 /* 367 * Externalize this krb5_gss_ctx_id_ret. 368 */ 369 krb5_error_code 370 kg_ctx_externalize(kcontext, arg, buffer, lenremain) 371 krb5_context kcontext; 372 krb5_pointer arg; 373 krb5_octet **buffer; 374 size_t *lenremain; 375 { 376 krb5_error_code kret; 377 krb5_gss_ctx_id_rec *ctx; 378 size_t required; 379 krb5_octet *bp; 380 size_t remain; 381 #ifndef _KERNEL 382 krb5int_access kaccess; 383 384 kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); 385 if (kret) 386 return(kret); 387 #endif 388 389 required = 0; 390 bp = *buffer; 391 remain = *lenremain; 392 kret = EINVAL; 393 /*LINTED*/ 394 if ((ctx = (krb5_gss_ctx_id_rec *) arg)) { 395 kret = ENOMEM; 396 if (!kg_ctx_size(kcontext, arg, &required) && 397 (required <= remain)) { 398 /* Our identifier */ 399 (void) krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain); 400 401 /* Now static data */ 402 (void) krb5_ser_pack_int32((krb5_int32) ctx->initiate, 403 &bp, &remain); 404 (void) krb5_ser_pack_int32((krb5_int32) ctx->established, 405 &bp, &remain); 406 (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian, 407 &bp, &remain); 408 (void) krb5_ser_pack_int32((krb5_int32) ctx->have_acceptor_subkey, 409 &bp, &remain); 410 (void) krb5_ser_pack_int32((krb5_int32) ctx->seed_init, 411 &bp, &remain); 412 (void) krb5_ser_pack_int32((krb5_int32) ctx->gss_flags, 413 &bp, &remain); 414 (void) krb5_ser_pack_bytes((krb5_octet *) ctx->seed, 415 sizeof(ctx->seed), 416 &bp, &remain); 417 (void) krb5_ser_pack_int32((krb5_int32) ctx->signalg, 418 &bp, &remain); 419 (void) krb5_ser_pack_int32((krb5_int32) ctx->cksum_size, 420 &bp, &remain); 421 (void) krb5_ser_pack_int32((krb5_int32) ctx->sealalg, 422 &bp, &remain); 423 (void) krb5_ser_pack_int32((krb5_int32) ctx->endtime, 424 &bp, &remain); 425 (void) krb5_ser_pack_int32((krb5_int32) ctx->krb_flags, 426 &bp, &remain); 427 #ifndef _KERNEL 428 (void) (*kaccess.krb5_ser_pack_int64)((krb5_int64) ctx->seq_send, 429 &bp, &remain); 430 (void) (*kaccess.krb5_ser_pack_int64)((krb5_int64) ctx->seq_recv, 431 &bp, &remain); 432 #else 433 (void) krb5_ser_pack_int64((krb5_int64) ctx->seq_send, 434 &bp, &remain); 435 (void) krb5_ser_pack_int64((krb5_int64) ctx->seq_recv, 436 &bp, &remain); 437 #endif 438 439 /* Now dynamic data */ 440 kret = 0; 441 442 if (!kret && ctx->mech_used) 443 kret = kg_oid_externalize(kcontext, ctx->mech_used, 444 &bp, &remain); 445 446 if (!kret && ctx->here) 447 kret = krb5_externalize_opaque(kcontext, 448 KV5M_PRINCIPAL, 449 (krb5_pointer) ctx->here, 450 &bp, &remain); 451 452 if (!kret && ctx->there) 453 kret = krb5_externalize_opaque(kcontext, 454 KV5M_PRINCIPAL, 455 (krb5_pointer) ctx->there, 456 &bp, &remain); 457 458 if (!kret && ctx->subkey) 459 kret = krb5_externalize_opaque(kcontext, 460 KV5M_KEYBLOCK, 461 (krb5_pointer) ctx->subkey, 462 &bp, &remain); 463 464 if (!kret && ctx->enc) 465 kret = krb5_externalize_opaque(kcontext, 466 KV5M_KEYBLOCK, 467 (krb5_pointer) ctx->enc, 468 &bp, &remain); 469 470 if (!kret && ctx->seq) 471 kret = krb5_externalize_opaque(kcontext, 472 KV5M_KEYBLOCK, 473 (krb5_pointer) ctx->seq, 474 &bp, &remain); 475 476 if (!kret && ctx->seqstate) 477 kret = kg_queue_externalize(kcontext, 478 ctx->seqstate, &bp, &remain); 479 480 #ifndef PROVIDE_KERNEL_IMPORT 481 if (!kret) 482 kret = krb5_externalize_opaque(kcontext, 483 KV5M_CONTEXT, 484 (krb5_pointer) ctx->k5_context, 485 &bp, &remain); 486 if (!kret) 487 kret = krb5_externalize_opaque(kcontext, 488 KV5M_AUTH_CONTEXT, 489 (krb5_pointer) ctx->auth_context, 490 &bp, &remain); 491 #endif 492 if (!kret) 493 kret = krb5_ser_pack_int32((krb5_int32) ctx->proto, 494 &bp, &remain); 495 if (!kret) 496 kret = krb5_ser_pack_int32((krb5_int32) ctx->cksumtype, 497 &bp, &remain); 498 if (!kret && ctx->acceptor_subkey) 499 kret = krb5_externalize_opaque(kcontext, 500 KV5M_KEYBLOCK, 501 (krb5_pointer) ctx->acceptor_subkey, 502 &bp, &remain); 503 if (!kret) 504 kret = krb5_ser_pack_int32((krb5_int32) ctx->acceptor_subkey_cksumtype, 505 &bp, &remain); 506 507 if (!kret) 508 kret = krb5_ser_pack_int32((krb5_int32) ctx->cred_rcache, 509 &bp, &remain); 510 /* trailer */ 511 if (!kret) 512 kret = krb5_ser_pack_int32(KG_CONTEXT, &bp, &remain); 513 if (!kret) { 514 *buffer = bp; 515 *lenremain = remain; 516 } 517 } 518 } 519 return(kret); 520 } 521 522 /* 523 * Internalize this krb5_gss_ctx_id_t. 524 */ 525 krb5_error_code 526 kg_ctx_internalize(kcontext, argp, buffer, lenremain) 527 krb5_context kcontext; 528 krb5_pointer *argp; 529 krb5_octet **buffer; 530 size_t *lenremain; 531 { 532 krb5_error_code kret; 533 krb5_gss_ctx_id_rec *ctx; 534 krb5_int32 ibuf; 535 krb5_octet *bp; 536 size_t remain; 537 #ifndef _KERNEL 538 krb5int_access kaccess; 539 540 kret = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION); 541 if (kret) 542 return(kret); 543 #endif 544 545 bp = *buffer; 546 remain = *lenremain; 547 kret = EINVAL; 548 /* Read our magic number */ 549 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) 550 ibuf = 0; 551 if (ibuf == KG_CONTEXT) { 552 kret = ENOMEM; 553 554 /* Get a context */ 555 if ((remain >= (17*sizeof(krb5_int32) 556 + 2*sizeof(krb5_int64) 557 + sizeof(ctx->seed))) && 558 (ctx = (krb5_gss_ctx_id_rec *) 559 xmalloc(sizeof(krb5_gss_ctx_id_rec)))) { 560 (void) memset(ctx, 0, sizeof(krb5_gss_ctx_id_rec)); 561 562 ctx->k5_context = kcontext; 563 564 /* Get static data */ 565 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 566 ctx->initiate = (int) ibuf; 567 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 568 ctx->established = (int) ibuf; 569 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 570 ctx->big_endian = (int) ibuf; 571 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 572 ctx->have_acceptor_subkey = (int) ibuf; 573 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 574 ctx->seed_init = (int) ibuf; 575 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 576 ctx->gss_flags = (int) ibuf; 577 (void) krb5_ser_unpack_bytes((krb5_octet *) ctx->seed, 578 sizeof(ctx->seed), 579 &bp, &remain); 580 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 581 ctx->signalg = (int) ibuf; 582 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 583 ctx->cksum_size = (int) ibuf; 584 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 585 ctx->sealalg = (int) ibuf; 586 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 587 ctx->endtime = (krb5_timestamp) ibuf; 588 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 589 ctx->krb_flags = (krb5_flags) ibuf; 590 #ifndef _KERNEL 591 (void) (*kaccess.krb5_ser_unpack_int64)((krb5_int64 *)&ctx->seq_send, &bp, &remain); 592 kret = (*kaccess.krb5_ser_unpack_int64)((krb5_int64 *)&ctx->seq_recv, &bp, &remain); 593 #else 594 (void) krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_send), 595 &bp, &remain); 596 kret = krb5_ser_unpack_int64((krb5_int64 *) (&ctx->seq_recv), 597 &bp, &remain); 598 #endif 599 if (kret) { 600 xfree_wrap(ctx, sizeof (krb5_gss_ctx_id_rec)); 601 return kret; 602 } 603 604 if ((kret = kg_oid_internalize(kcontext, 605 (krb5_pointer *) &ctx->mech_used, &bp, 606 &remain))) { 607 if (kret == EINVAL) 608 kret = 0; 609 } 610 /* Now get substructure data */ 611 if ((kret = krb5_internalize_opaque(kcontext, 612 KV5M_PRINCIPAL, 613 (krb5_pointer *) &ctx->here, 614 &bp, &remain))) { 615 if (kret == EINVAL) 616 kret = 0; 617 } 618 if (!kret && 619 (kret = krb5_internalize_opaque(kcontext, 620 KV5M_PRINCIPAL, 621 (krb5_pointer *) &ctx->there, 622 &bp, &remain))) { 623 if (kret == EINVAL) 624 kret = 0; 625 } 626 if (!kret && 627 (kret = krb5_internalize_opaque(kcontext, 628 KV5M_KEYBLOCK, 629 (krb5_pointer *) &ctx->subkey, 630 &bp, &remain))) { 631 if (kret == EINVAL) 632 kret = 0; 633 } 634 if (!kret && 635 (kret = krb5_internalize_opaque(kcontext, 636 KV5M_KEYBLOCK, 637 (krb5_pointer *) &ctx->enc, 638 &bp, &remain))) { 639 if (kret == EINVAL) 640 kret = 0; 641 } 642 if (!kret && 643 (kret = krb5_internalize_opaque(kcontext, 644 KV5M_KEYBLOCK, 645 (krb5_pointer *) &ctx->seq, 646 &bp, &remain))) { 647 if (kret == EINVAL) 648 kret = 0; 649 } 650 651 if (!kret) { 652 kret = kg_queue_internalize(kcontext, &ctx->seqstate, 653 &bp, &remain); 654 if (kret == EINVAL) 655 kret = 0; 656 } 657 658 #ifndef PROVIDE_KERNEL_IMPORT 659 if (!kret) 660 kret = krb5_internalize_opaque(kcontext, 661 KV5M_CONTEXT, 662 (krb5_pointer *) &ctx->k5_context, 663 &bp, &remain); 664 665 if (!kret) 666 kret = krb5_internalize_opaque(kcontext, 667 KV5M_AUTH_CONTEXT, 668 (krb5_pointer *) &ctx->auth_context, 669 &bp, &remain); 670 #endif 671 if (!kret) 672 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); 673 ctx->proto = ibuf; 674 if (!kret) 675 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); 676 ctx->cksumtype = ibuf; 677 if (!kret && 678 (kret = krb5_internalize_opaque(kcontext, 679 KV5M_KEYBLOCK, 680 (krb5_pointer *) &ctx->acceptor_subkey, 681 &bp, &remain))) { 682 if (kret == EINVAL) 683 kret = 0; 684 } 685 if (!kret) 686 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); 687 ctx->cred_rcache = ibuf; 688 if (!kret) 689 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); 690 ctx->acceptor_subkey_cksumtype = ibuf; 691 692 /* Get trailer */ 693 if (!kret) 694 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); 695 if (!kret && ibuf != KG_CONTEXT) 696 kret = EINVAL; 697 698 if (!kret) { 699 *buffer = bp; 700 *lenremain = remain; 701 *argp = (krb5_pointer) ctx; 702 } else { 703 if (ctx->seq) 704 krb5_free_keyblock(kcontext, ctx->seq); 705 if (ctx->enc) 706 krb5_free_keyblock(kcontext, ctx->enc); 707 if (ctx->subkey) 708 krb5_free_keyblock(kcontext, ctx->subkey); 709 if (ctx->there) 710 krb5_free_principal(kcontext, ctx->there); 711 if (ctx->here) 712 krb5_free_principal(kcontext, ctx->here); 713 xfree_wrap(ctx, sizeof (krb5_gss_ctx_id_rec)); 714 } 715 } 716 } 717 return(kret); 718 } 719