1/* 2 * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17/* $Id: spnego_asn1.c,v 1.4 2007/06/19 23:47:16 tbox Exp $ */ 18 19/*! \file 20 * \brief Method routines generated from SPNEGO ASN.1 module. 21 * See spnego_asn1.pl for details. Do not edit. 22 */ 23 24/* Generated from spnego.asn1 */ 25/* Do not edit */ 26 27#ifndef __asn1_h__ 28#define __asn1_h__ 29 30 31#ifndef __asn1_common_definitions__ 32#define __asn1_common_definitions__ 33 34typedef struct octet_string { 35 size_t length; 36 void *data; 37} octet_string; 38 39typedef char *general_string; 40 41typedef char *utf8_string; 42 43typedef struct oid { 44 size_t length; 45 unsigned *components; 46} oid; 47 48#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \ 49 do { \ 50 (BL) = length_##T((S)); \ 51 (B) = malloc((BL)); \ 52 if((B) == NULL) { \ 53 (R) = ENOMEM; \ 54 } else { \ 55 (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \ 56 (S), (L)); \ 57 if((R) != 0) { \ 58 free((B)); \ 59 (B) = NULL; \ 60 } \ 61 } \ 62 } while (0) 63 64#endif 65 66/* 67 * MechType ::= OBJECT IDENTIFIER 68 */ 69 70typedef oid MechType; 71 72static int encode_MechType(unsigned char *, size_t, const MechType *, size_t *); 73static int decode_MechType(const unsigned char *, size_t, MechType *, size_t *); 74static void free_MechType(MechType *); 75/* unused declaration: length_MechType */ 76/* unused declaration: copy_MechType */ 77 78 79/* 80 * MechTypeList ::= SEQUENCE OF MechType 81 */ 82 83typedef struct MechTypeList { 84 unsigned int len; 85 MechType *val; 86} MechTypeList; 87 88static int encode_MechTypeList(unsigned char *, size_t, const MechTypeList *, size_t *); 89static int decode_MechTypeList(const unsigned char *, size_t, MechTypeList *, size_t *); 90static void free_MechTypeList(MechTypeList *); 91/* unused declaration: length_MechTypeList */ 92/* unused declaration: copy_MechTypeList */ 93 94 95/* 96 * ContextFlags ::= BIT STRING { delegFlag(0), mutualFlag(1), replayFlag(2), 97 * sequenceFlag(3), anonFlag(4), confFlag(5), integFlag(6) } 98 */ 99 100typedef struct ContextFlags { 101 unsigned int delegFlag:1; 102 unsigned int mutualFlag:1; 103 unsigned int replayFlag:1; 104 unsigned int sequenceFlag:1; 105 unsigned int anonFlag:1; 106 unsigned int confFlag:1; 107 unsigned int integFlag:1; 108} ContextFlags; 109 110 111static int encode_ContextFlags(unsigned char *, size_t, const ContextFlags *, size_t *); 112static int decode_ContextFlags(const unsigned char *, size_t, ContextFlags *, size_t *); 113static void free_ContextFlags(ContextFlags *); 114/* unused declaration: length_ContextFlags */ 115/* unused declaration: copy_ContextFlags */ 116/* unused declaration: ContextFlags2int */ 117/* unused declaration: int2ContextFlags */ 118/* unused declaration: asn1_ContextFlags_units */ 119 120/* 121 * NegTokenInit ::= SEQUENCE { mechTypes[0] MechTypeList, reqFlags[1] 122 * ContextFlags OPTIONAL, mechToken[2] OCTET STRING OPTIONAL, 123 * mechListMIC[3] OCTET STRING OPTIONAL } 124 */ 125 126typedef struct NegTokenInit { 127 MechTypeList mechTypes; 128 ContextFlags *reqFlags; 129 octet_string *mechToken; 130 octet_string *mechListMIC; 131} NegTokenInit; 132 133static int encode_NegTokenInit(unsigned char *, size_t, const NegTokenInit *, size_t *); 134static int decode_NegTokenInit(const unsigned char *, size_t, NegTokenInit *, size_t *); 135static void free_NegTokenInit(NegTokenInit *); 136/* unused declaration: length_NegTokenInit */ 137/* unused declaration: copy_NegTokenInit */ 138 139 140/* 141 * NegTokenResp ::= SEQUENCE { negState[0] ENUMERATED { 142 * accept-completed(0), accept-incomplete(1), reject(2), request-mic(3) } 143 * OPTIONAL, supportedMech[1] MechType OPTIONAL, responseToken[2] OCTET 144 * STRING OPTIONAL, mechListMIC[3] OCTET STRING OPTIONAL } 145 */ 146 147typedef struct NegTokenResp { 148 enum { 149 accept_completed = 0, 150 accept_incomplete = 1, 151 reject = 2, 152 request_mic = 3 153 } *negState; 154 155 MechType *supportedMech; 156 octet_string *responseToken; 157 octet_string *mechListMIC; 158} NegTokenResp; 159 160static int encode_NegTokenResp(unsigned char *, size_t, const NegTokenResp *, size_t *); 161static int decode_NegTokenResp(const unsigned char *, size_t, NegTokenResp *, size_t *); 162static void free_NegTokenResp(NegTokenResp *); 163/* unused declaration: length_NegTokenResp */ 164/* unused declaration: copy_NegTokenResp */ 165 166 167 168 169#endif /* __asn1_h__ */ 170/* Generated from spnego.asn1 */ 171/* Do not edit */ 172 173 174#define BACK if (e) return e; p -= l; len -= l; ret += l 175 176static int 177encode_MechType(unsigned char *p, size_t len, const MechType * data, size_t * size) 178{ 179 size_t ret = 0; 180 size_t l; 181 int i, e; 182 183 i = 0; 184 e = encode_oid(p, len, data, &l); 185 BACK; 186 *size = ret; 187 return 0; 188} 189 190#define FORW if(e) goto fail; p += l; len -= l; ret += l 191 192static int 193decode_MechType(const unsigned char *p, size_t len, MechType * data, size_t * size) 194{ 195 size_t ret = 0, reallen; 196 size_t l; 197 int e; 198 199 memset(data, 0, sizeof(*data)); 200 reallen = 0; 201 e = decode_oid(p, len, data, &l); 202 FORW; 203 if (size) 204 *size = ret; 205 return 0; 206fail: 207 free_MechType(data); 208 return e; 209} 210 211static void 212free_MechType(MechType * data) 213{ 214 free_oid(data); 215} 216 217/* unused function: length_MechType */ 218 219 220/* unused function: copy_MechType */ 221 222/* Generated from spnego.asn1 */ 223/* Do not edit */ 224 225 226#define BACK if (e) return e; p -= l; len -= l; ret += l 227 228static int 229encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, size_t * size) 230{ 231 size_t ret = 0; 232 size_t l; 233 int i, e; 234 235 i = 0; 236 for (i = (data)->len - 1; i >= 0; --i) { 237 int oldret = ret; 238 ret = 0; 239 e = encode_MechType(p, len, &(data)->val[i], &l); 240 BACK; 241 ret += oldret; 242 } 243 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l); 244 BACK; 245 *size = ret; 246 return 0; 247} 248 249#define FORW if(e) goto fail; p += l; len -= l; ret += l 250 251static int 252decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, size_t * size) 253{ 254 size_t ret = 0, reallen; 255 size_t l; 256 int e; 257 258 memset(data, 0, sizeof(*data)); 259 reallen = 0; 260 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l); 261 FORW; 262 if (len < reallen) 263 return ASN1_OVERRUN; 264 len = reallen; 265 { 266 size_t origlen = len; 267 int oldret = ret; 268 ret = 0; 269 (data)->len = 0; 270 (data)->val = NULL; 271 while (ret < origlen) { 272 (data)->len++; 273 (data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len); 274 e = decode_MechType(p, len, &(data)->val[(data)->len - 1], &l); 275 FORW; 276 len = origlen - ret; 277 } 278 ret += oldret; 279 } 280 if (size) 281 *size = ret; 282 return 0; 283fail: 284 free_MechTypeList(data); 285 return e; 286} 287 288static void 289free_MechTypeList(MechTypeList * data) 290{ 291 while ((data)->len) { 292 free_MechType(&(data)->val[(data)->len - 1]); 293 (data)->len--; 294 } 295 free((data)->val); 296 (data)->val = NULL; 297} 298 299/* unused function: length_MechTypeList */ 300 301 302/* unused function: copy_MechTypeList */ 303 304/* Generated from spnego.asn1 */ 305/* Do not edit */ 306 307 308#define BACK if (e) return e; p -= l; len -= l; ret += l 309 310static int 311encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, size_t * size) 312{ 313 size_t ret = 0; 314 size_t l; 315 int i, e; 316 317 i = 0; 318 { 319 unsigned char c = 0; 320 *p-- = c; 321 len--; 322 ret++; 323 c = 0; 324 *p-- = c; 325 len--; 326 ret++; 327 c = 0; 328 *p-- = c; 329 len--; 330 ret++; 331 c = 0; 332 if (data->integFlag) 333 c |= 1 << 1; 334 if (data->confFlag) 335 c |= 1 << 2; 336 if (data->anonFlag) 337 c |= 1 << 3; 338 if (data->sequenceFlag) 339 c |= 1 << 4; 340 if (data->replayFlag) 341 c |= 1 << 5; 342 if (data->mutualFlag) 343 c |= 1 << 6; 344 if (data->delegFlag) 345 c |= 1 << 7; 346 *p-- = c; 347 *p-- = 0; 348 len -= 2; 349 ret += 2; 350 } 351 352 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_BitString, &l); 353 BACK; 354 *size = ret; 355 return 0; 356} 357 358#define FORW if(e) goto fail; p += l; len -= l; ret += l 359 360static int 361decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, size_t * size) 362{ 363 size_t ret = 0, reallen; 364 size_t l; 365 int e; 366 367 memset(data, 0, sizeof(*data)); 368 reallen = 0; 369 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, PRIM, UT_BitString, &reallen, &l); 370 FORW; 371 if (len < reallen) 372 return ASN1_OVERRUN; 373 p++; 374 len--; 375 reallen--; 376 ret++; 377 data->delegFlag = (*p >> 7) & 1; 378 data->mutualFlag = (*p >> 6) & 1; 379 data->replayFlag = (*p >> 5) & 1; 380 data->sequenceFlag = (*p >> 4) & 1; 381 data->anonFlag = (*p >> 3) & 1; 382 data->confFlag = (*p >> 2) & 1; 383 data->integFlag = (*p >> 1) & 1; 384 p += reallen; 385 len -= reallen; 386 ret += reallen; 387 if (size) 388 *size = ret; 389 return 0; 390fail: 391 free_ContextFlags(data); 392 return e; 393} 394 395static void 396free_ContextFlags(ContextFlags * data) 397{ 398 (void)data; 399} 400 401/* unused function: length_ContextFlags */ 402 403 404/* unused function: copy_ContextFlags */ 405 406 407/* unused function: ContextFlags2int */ 408 409 410/* unused function: int2ContextFlags */ 411 412 413/* unused variable: ContextFlags_units */ 414 415/* unused function: asn1_ContextFlags_units */ 416 417/* Generated from spnego.asn1 */ 418/* Do not edit */ 419 420 421#define BACK if (e) return e; p -= l; len -= l; ret += l 422 423static int 424encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, size_t * size) 425{ 426 size_t ret = 0; 427 size_t l; 428 int i, e; 429 430 i = 0; 431 if ((data)->mechListMIC) { 432 int oldret = ret; 433 ret = 0; 434 e = encode_octet_string(p, len, (data)->mechListMIC, &l); 435 BACK; 436 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l); 437 BACK; 438 ret += oldret; 439 } 440 if ((data)->mechToken) { 441 int oldret = ret; 442 ret = 0; 443 e = encode_octet_string(p, len, (data)->mechToken, &l); 444 BACK; 445 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l); 446 BACK; 447 ret += oldret; 448 } 449 if ((data)->reqFlags) { 450 int oldret = ret; 451 ret = 0; 452 e = encode_ContextFlags(p, len, (data)->reqFlags, &l); 453 BACK; 454 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l); 455 BACK; 456 ret += oldret; 457 } { 458 int oldret = ret; 459 ret = 0; 460 e = encode_MechTypeList(p, len, &(data)->mechTypes, &l); 461 BACK; 462 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l); 463 BACK; 464 ret += oldret; 465 } 466 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l); 467 BACK; 468 *size = ret; 469 return 0; 470} 471 472#define FORW if(e) goto fail; p += l; len -= l; ret += l 473 474static int 475decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, size_t * size) 476{ 477 size_t ret = 0, reallen; 478 size_t l; 479 int e; 480 481 memset(data, 0, sizeof(*data)); 482 reallen = 0; 483 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l); 484 FORW; 485 { 486 int dce_fix; 487 if ((dce_fix = fix_dce(reallen, &len)) < 0) 488 return ASN1_BAD_FORMAT; 489 { 490 size_t newlen, oldlen; 491 492 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l); 493 if (e) 494 return e; 495 else { 496 p += l; 497 len -= l; 498 ret += l; 499 e = der_get_length(p, len, &newlen, &l); 500 FORW; 501 { 502 int dce_fix; 503 oldlen = len; 504 if ((dce_fix = fix_dce(newlen, &len)) < 0) 505 return ASN1_BAD_FORMAT; 506 e = decode_MechTypeList(p, len, &(data)->mechTypes, &l); 507 FORW; 508 if (dce_fix) { 509 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); 510 FORW; 511 } else 512 len = oldlen - newlen; 513 } 514 } 515 } 516 { 517 size_t newlen, oldlen; 518 519 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l); 520 if (e) 521 (data)->reqFlags = NULL; 522 else { 523 p += l; 524 len -= l; 525 ret += l; 526 e = der_get_length(p, len, &newlen, &l); 527 FORW; 528 { 529 int dce_fix; 530 oldlen = len; 531 if ((dce_fix = fix_dce(newlen, &len)) < 0) 532 return ASN1_BAD_FORMAT; 533 (data)->reqFlags = malloc(sizeof(*(data)->reqFlags)); 534 if ((data)->reqFlags == NULL) 535 return ENOMEM; 536 e = decode_ContextFlags(p, len, (data)->reqFlags, &l); 537 FORW; 538 if (dce_fix) { 539 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); 540 FORW; 541 } else 542 len = oldlen - newlen; 543 } 544 } 545 } 546 { 547 size_t newlen, oldlen; 548 549 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l); 550 if (e) 551 (data)->mechToken = NULL; 552 else { 553 p += l; 554 len -= l; 555 ret += l; 556 e = der_get_length(p, len, &newlen, &l); 557 FORW; 558 { 559 int dce_fix; 560 oldlen = len; 561 if ((dce_fix = fix_dce(newlen, &len)) < 0) 562 return ASN1_BAD_FORMAT; 563 (data)->mechToken = malloc(sizeof(*(data)->mechToken)); 564 if ((data)->mechToken == NULL) 565 return ENOMEM; 566 e = decode_octet_string(p, len, (data)->mechToken, &l); 567 FORW; 568 if (dce_fix) { 569 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); 570 FORW; 571 } else 572 len = oldlen - newlen; 573 } 574 } 575 } 576 { 577 size_t newlen, oldlen; 578 579 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l); 580 if (e) 581 (data)->mechListMIC = NULL; 582 else { 583 p += l; 584 len -= l; 585 ret += l; 586 e = der_get_length(p, len, &newlen, &l); 587 FORW; 588 { 589 int dce_fix; 590 oldlen = len; 591 if ((dce_fix = fix_dce(newlen, &len)) < 0) 592 return ASN1_BAD_FORMAT; 593 (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC)); 594 if ((data)->mechListMIC == NULL) 595 return ENOMEM; 596 e = decode_octet_string(p, len, (data)->mechListMIC, &l); 597 FORW; 598 if (dce_fix) { 599 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); 600 FORW; 601 } else 602 len = oldlen - newlen; 603 } 604 } 605 } 606 if (dce_fix) { 607 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); 608 FORW; 609 } 610 } 611 if (size) 612 *size = ret; 613 return 0; 614fail: 615 free_NegTokenInit(data); 616 return e; 617} 618 619static void 620free_NegTokenInit(NegTokenInit * data) 621{ 622 free_MechTypeList(&(data)->mechTypes); 623 if ((data)->reqFlags) { 624 free_ContextFlags((data)->reqFlags); 625 free((data)->reqFlags); 626 (data)->reqFlags = NULL; 627 } 628 if ((data)->mechToken) { 629 free_octet_string((data)->mechToken); 630 free((data)->mechToken); 631 (data)->mechToken = NULL; 632 } 633 if ((data)->mechListMIC) { 634 free_octet_string((data)->mechListMIC); 635 free((data)->mechListMIC); 636 (data)->mechListMIC = NULL; 637 } 638} 639 640/* unused function: length_NegTokenInit */ 641 642 643/* unused function: copy_NegTokenInit */ 644 645/* Generated from spnego.asn1 */ 646/* Do not edit */ 647 648 649#define BACK if (e) return e; p -= l; len -= l; ret += l 650 651static int 652encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, size_t * size) 653{ 654 size_t ret = 0; 655 size_t l; 656 int i, e; 657 658 i = 0; 659 if ((data)->mechListMIC) { 660 int oldret = ret; 661 ret = 0; 662 e = encode_octet_string(p, len, (data)->mechListMIC, &l); 663 BACK; 664 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l); 665 BACK; 666 ret += oldret; 667 } 668 if ((data)->responseToken) { 669 int oldret = ret; 670 ret = 0; 671 e = encode_octet_string(p, len, (data)->responseToken, &l); 672 BACK; 673 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l); 674 BACK; 675 ret += oldret; 676 } 677 if ((data)->supportedMech) { 678 int oldret = ret; 679 ret = 0; 680 e = encode_MechType(p, len, (data)->supportedMech, &l); 681 BACK; 682 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l); 683 BACK; 684 ret += oldret; 685 } 686 if ((data)->negState) { 687 int oldret = ret; 688 ret = 0; 689 e = encode_enumerated(p, len, (data)->negState, &l); 690 BACK; 691 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l); 692 BACK; 693 ret += oldret; 694 } 695 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l); 696 BACK; 697 *size = ret; 698 return 0; 699} 700 701#define FORW if(e) goto fail; p += l; len -= l; ret += l 702 703static int 704decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, size_t * size) 705{ 706 size_t ret = 0, reallen; 707 size_t l; 708 int e; 709 710 memset(data, 0, sizeof(*data)); 711 reallen = 0; 712 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l); 713 FORW; 714 { 715 int dce_fix; 716 if ((dce_fix = fix_dce(reallen, &len)) < 0) 717 return ASN1_BAD_FORMAT; 718 { 719 size_t newlen, oldlen; 720 721 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l); 722 if (e) 723 (data)->negState = NULL; 724 else { 725 p += l; 726 len -= l; 727 ret += l; 728 e = der_get_length(p, len, &newlen, &l); 729 FORW; 730 { 731 int dce_fix; 732 oldlen = len; 733 if ((dce_fix = fix_dce(newlen, &len)) < 0) 734 return ASN1_BAD_FORMAT; 735 (data)->negState = malloc(sizeof(*(data)->negState)); 736 if ((data)->negState == NULL) 737 return ENOMEM; 738 e = decode_enumerated(p, len, (data)->negState, &l); 739 FORW; 740 if (dce_fix) { 741 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); 742 FORW; 743 } else 744 len = oldlen - newlen; 745 } 746 } 747 } 748 { 749 size_t newlen, oldlen; 750 751 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l); 752 if (e) 753 (data)->supportedMech = NULL; 754 else { 755 p += l; 756 len -= l; 757 ret += l; 758 e = der_get_length(p, len, &newlen, &l); 759 FORW; 760 { 761 int dce_fix; 762 oldlen = len; 763 if ((dce_fix = fix_dce(newlen, &len)) < 0) 764 return ASN1_BAD_FORMAT; 765 (data)->supportedMech = malloc(sizeof(*(data)->supportedMech)); 766 if ((data)->supportedMech == NULL) 767 return ENOMEM; 768 e = decode_MechType(p, len, (data)->supportedMech, &l); 769 FORW; 770 if (dce_fix) { 771 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); 772 FORW; 773 } else 774 len = oldlen - newlen; 775 } 776 } 777 } 778 { 779 size_t newlen, oldlen; 780 781 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l); 782 if (e) 783 (data)->responseToken = NULL; 784 else { 785 p += l; 786 len -= l; 787 ret += l; 788 e = der_get_length(p, len, &newlen, &l); 789 FORW; 790 { 791 int dce_fix; 792 oldlen = len; 793 if ((dce_fix = fix_dce(newlen, &len)) < 0) 794 return ASN1_BAD_FORMAT; 795 (data)->responseToken = malloc(sizeof(*(data)->responseToken)); 796 if ((data)->responseToken == NULL) 797 return ENOMEM; 798 e = decode_octet_string(p, len, (data)->responseToken, &l); 799 FORW; 800 if (dce_fix) { 801 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); 802 FORW; 803 } else 804 len = oldlen - newlen; 805 } 806 } 807 } 808 { 809 size_t newlen, oldlen; 810 811 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l); 812 if (e) 813 (data)->mechListMIC = NULL; 814 else { 815 p += l; 816 len -= l; 817 ret += l; 818 e = der_get_length(p, len, &newlen, &l); 819 FORW; 820 { 821 int dce_fix; 822 oldlen = len; 823 if ((dce_fix = fix_dce(newlen, &len)) < 0) 824 return ASN1_BAD_FORMAT; 825 (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC)); 826 if ((data)->mechListMIC == NULL) 827 return ENOMEM; 828 e = decode_octet_string(p, len, (data)->mechListMIC, &l); 829 FORW; 830 if (dce_fix) { 831 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); 832 FORW; 833 } else 834 len = oldlen - newlen; 835 } 836 } 837 } 838 if (dce_fix) { 839 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l); 840 FORW; 841 } 842 } 843 if (size) 844 *size = ret; 845 return 0; 846fail: 847 free_NegTokenResp(data); 848 return e; 849} 850 851static void 852free_NegTokenResp(NegTokenResp * data) 853{ 854 if ((data)->negState) { 855 free((data)->negState); 856 (data)->negState = NULL; 857 } 858 if ((data)->supportedMech) { 859 free_MechType((data)->supportedMech); 860 free((data)->supportedMech); 861 (data)->supportedMech = NULL; 862 } 863 if ((data)->responseToken) { 864 free_octet_string((data)->responseToken); 865 free((data)->responseToken); 866 (data)->responseToken = NULL; 867 } 868 if ((data)->mechListMIC) { 869 free_octet_string((data)->mechListMIC); 870 free((data)->mechListMIC); 871 (data)->mechListMIC = NULL; 872 } 873} 874 875/* unused function: length_NegTokenResp */ 876 877 878/* unused function: copy_NegTokenResp */ 879 880/* Generated from spnego.asn1 */ 881/* Do not edit */ 882 883 884/* CHOICE */ 885/* unused variable: asn1_NegotiationToken_dummy_holder */ 886