00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef __asn1_h__
00028 #define __asn1_h__
00029
00030
00031 #ifndef __asn1_common_definitions__
00032 #define __asn1_common_definitions__
00033
00034 typedef struct octet_string {
00035 size_t length;
00036 void *data;
00037 } octet_string;
00038
00039 typedef char *general_string;
00040
00041 typedef char *utf8_string;
00042
00043 typedef struct oid {
00044 size_t length;
00045 unsigned *components;
00046 } oid;
00047
00048 #define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \
00049 do { \
00050 (BL) = length_##T((S)); \
00051 (B) = malloc((BL)); \
00052 if((B) == NULL) { \
00053 (R) = ENOMEM; \
00054 } else { \
00055 (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \
00056 (S), (L)); \
00057 if((R) != 0) { \
00058 free((B)); \
00059 (B) = NULL; \
00060 } \
00061 } \
00062 } while (0)
00063
00064 #endif
00065
00066
00067
00068
00069
00070 typedef oid MechType;
00071
00072 static int encode_MechType(unsigned char *, size_t, const MechType *, size_t *);
00073 static int decode_MechType(const unsigned char *, size_t, MechType *, size_t *);
00074 static void free_MechType(MechType *);
00075
00076
00077
00078
00079
00080
00081
00082
00083 typedef struct MechTypeList {
00084 unsigned int len;
00085 MechType *val;
00086 } MechTypeList;
00087
00088 static int encode_MechTypeList(unsigned char *, size_t, const MechTypeList *, size_t *);
00089 static int decode_MechTypeList(const unsigned char *, size_t, MechTypeList *, size_t *);
00090 static void free_MechTypeList(MechTypeList *);
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 typedef struct ContextFlags {
00101 unsigned int delegFlag:1;
00102 unsigned int mutualFlag:1;
00103 unsigned int replayFlag:1;
00104 unsigned int sequenceFlag:1;
00105 unsigned int anonFlag:1;
00106 unsigned int confFlag:1;
00107 unsigned int integFlag:1;
00108 } ContextFlags;
00109
00110
00111 static int encode_ContextFlags(unsigned char *, size_t, const ContextFlags *, size_t *);
00112 static int decode_ContextFlags(const unsigned char *, size_t, ContextFlags *, size_t *);
00113 static void free_ContextFlags(ContextFlags *);
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 typedef struct NegTokenInit {
00127 MechTypeList mechTypes;
00128 ContextFlags *reqFlags;
00129 octet_string *mechToken;
00130 octet_string *mechListMIC;
00131 } NegTokenInit;
00132
00133 static int encode_NegTokenInit(unsigned char *, size_t, const NegTokenInit *, size_t *);
00134 static int decode_NegTokenInit(const unsigned char *, size_t, NegTokenInit *, size_t *);
00135 static void free_NegTokenInit(NegTokenInit *);
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 typedef struct NegTokenResp {
00148 enum {
00149 accept_completed = 0,
00150 accept_incomplete = 1,
00151 reject = 2,
00152 request_mic = 3
00153 } *negState;
00154
00155 MechType *supportedMech;
00156 octet_string *responseToken;
00157 octet_string *mechListMIC;
00158 } NegTokenResp;
00159
00160 static int encode_NegTokenResp(unsigned char *, size_t, const NegTokenResp *, size_t *);
00161 static int decode_NegTokenResp(const unsigned char *, size_t, NegTokenResp *, size_t *);
00162 static void free_NegTokenResp(NegTokenResp *);
00163
00164
00165
00166
00167
00168
00169 #endif
00170
00171
00172
00173
00174 #define BACK if (e) return e; p -= l; len -= l; ret += l; POST(p); POST(len); POST(ret)
00175
00176 static int
00177 encode_MechType(unsigned char *p, size_t len, const MechType * data, size_t * size)
00178 {
00179 size_t ret = 0;
00180 size_t l;
00181 int e;
00182
00183 e = encode_oid(p, len, data, &l);
00184 BACK;
00185 *size = ret;
00186 return 0;
00187 }
00188
00189 #define FORW if(e) goto fail; p += l; len -= l; ret += l; POST(p); POST(len); POST(ret)
00190
00191 static int
00192 decode_MechType(const unsigned char *p, size_t len, MechType * data, size_t * size)
00193 {
00194 size_t ret = 0;
00195 size_t l;
00196 int e;
00197
00198 memset(data, 0, sizeof(*data));
00199 e = decode_oid(p, len, data, &l);
00200 FORW;
00201 if (size)
00202 *size = ret;
00203 return 0;
00204 fail:
00205 free_MechType(data);
00206 return e;
00207 }
00208
00209 static void
00210 free_MechType(MechType * data)
00211 {
00212 free_oid(data);
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 static int
00225 encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, size_t * size)
00226 {
00227 size_t ret = 0;
00228 size_t l;
00229 int i, e;
00230
00231 for (i = (data)->len - 1; i >= 0; --i) {
00232 size_t oldret = ret;
00233 ret = 0;
00234 e = encode_MechType(p, len, &(data)->val[i], &l);
00235 BACK;
00236 ret += oldret;
00237 }
00238 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
00239 BACK;
00240 *size = ret;
00241 return 0;
00242 }
00243
00244 static int
00245 decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, size_t * size)
00246 {
00247 size_t ret = 0, reallen;
00248 size_t l;
00249 int e;
00250
00251 memset(data, 0, sizeof(*data));
00252 reallen = 0;
00253 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
00254 FORW;
00255 if (len < reallen)
00256 return ASN1_OVERRUN;
00257 len = reallen;
00258 {
00259 size_t origlen = len;
00260 size_t oldret = ret;
00261 ret = 0;
00262 (data)->len = 0;
00263 (data)->val = NULL;
00264 while (ret < origlen) {
00265 void *old = (data)->val;
00266 (data)->len++;
00267 (data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len);
00268 if ((data)->val == NULL) {
00269 (data)->val = old;
00270 (data)->len--;
00271 return ENOMEM;
00272 }
00273 e = decode_MechType(p, len, &(data)->val[(data)->len - 1], &l);
00274 FORW;
00275 len = origlen - ret;
00276 }
00277 ret += oldret;
00278 }
00279 if (size)
00280 *size = ret;
00281 return 0;
00282 fail:
00283 free_MechTypeList(data);
00284 return e;
00285 }
00286
00287 static void
00288 free_MechTypeList(MechTypeList * data)
00289 {
00290 while ((data)->len) {
00291 free_MechType(&(data)->val[(data)->len - 1]);
00292 (data)->len--;
00293 }
00294 free((data)->val);
00295 (data)->val = NULL;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 static int
00308 encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, size_t * size)
00309 {
00310 size_t ret = 0;
00311 size_t l;
00312 int e;
00313
00314 {
00315 unsigned char c = 0;
00316 *p-- = c;
00317 len--;
00318 ret++;
00319 c = 0;
00320 *p-- = c;
00321 len--;
00322 ret++;
00323 c = 0;
00324 *p-- = c;
00325 len--;
00326 ret++;
00327 c = 0;
00328 if (data->integFlag)
00329 c |= 1 << 1;
00330 if (data->confFlag)
00331 c |= 1 << 2;
00332 if (data->anonFlag)
00333 c |= 1 << 3;
00334 if (data->sequenceFlag)
00335 c |= 1 << 4;
00336 if (data->replayFlag)
00337 c |= 1 << 5;
00338 if (data->mutualFlag)
00339 c |= 1 << 6;
00340 if (data->delegFlag)
00341 c |= 1 << 7;
00342 *p-- = c;
00343 *p-- = 0;
00344 len -= 2;
00345 ret += 2;
00346 }
00347
00348 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_BitString, &l);
00349 BACK;
00350 *size = ret;
00351 return 0;
00352 }
00353
00354 static int
00355 decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, size_t * size)
00356 {
00357 size_t ret = 0, reallen;
00358 size_t l;
00359 int e;
00360
00361 memset(data, 0, sizeof(*data));
00362 reallen = 0;
00363 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, PRIM, UT_BitString, &reallen, &l);
00364 FORW;
00365 if (len < reallen)
00366 return ASN1_OVERRUN;
00367 p++;
00368 len--;
00369 reallen--;
00370 ret++;
00371 data->delegFlag = (*p >> 7) & 1;
00372 data->mutualFlag = (*p >> 6) & 1;
00373 data->replayFlag = (*p >> 5) & 1;
00374 data->sequenceFlag = (*p >> 4) & 1;
00375 data->anonFlag = (*p >> 3) & 1;
00376 data->confFlag = (*p >> 2) & 1;
00377 data->integFlag = (*p >> 1) & 1;
00378 ret += reallen;
00379 if (size)
00380 *size = ret;
00381 return 0;
00382 fail:
00383 free_ContextFlags(data);
00384 return e;
00385 }
00386
00387 static void
00388 free_ContextFlags(ContextFlags * data)
00389 {
00390 (void)data;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 static int
00414 encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, size_t * size)
00415 {
00416 size_t ret = 0;
00417 size_t l;
00418 int e;
00419
00420 if ((data)->mechListMIC) {
00421 size_t oldret = ret;
00422 ret = 0;
00423 e = encode_octet_string(p, len, (data)->mechListMIC, &l);
00424 BACK;
00425 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l);
00426 BACK;
00427 ret += oldret;
00428 }
00429 if ((data)->mechToken) {
00430 size_t oldret = ret;
00431 ret = 0;
00432 e = encode_octet_string(p, len, (data)->mechToken, &l);
00433 BACK;
00434 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
00435 BACK;
00436 ret += oldret;
00437 }
00438 if ((data)->reqFlags) {
00439 size_t oldret = ret;
00440 ret = 0;
00441 e = encode_ContextFlags(p, len, (data)->reqFlags, &l);
00442 BACK;
00443 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
00444 BACK;
00445 ret += oldret;
00446 } {
00447 size_t oldret = ret;
00448 ret = 0;
00449 e = encode_MechTypeList(p, len, &(data)->mechTypes, &l);
00450 BACK;
00451 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
00452 BACK;
00453 ret += oldret;
00454 }
00455 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
00456 BACK;
00457 *size = ret;
00458 return 0;
00459 }
00460
00461 static int
00462 decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, size_t * size)
00463 {
00464 size_t ret = 0, reallen;
00465 size_t l;
00466 int e;
00467
00468 memset(data, 0, sizeof(*data));
00469 reallen = 0;
00470 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
00471 FORW;
00472 {
00473 int dce_fix;
00474 if ((dce_fix = fix_dce(reallen, &len)) < 0)
00475 return ASN1_BAD_FORMAT;
00476 {
00477 size_t newlen, oldlen;
00478
00479 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l);
00480 if (e)
00481 return e;
00482 else {
00483 p += l;
00484 len -= l;
00485 ret += l;
00486 e = der_get_length(p, len, &newlen, &l);
00487 FORW;
00488 {
00489 int mydce_fix;
00490 oldlen = len;
00491 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
00492 return ASN1_BAD_FORMAT;
00493 e = decode_MechTypeList(p, len, &(data)->mechTypes, &l);
00494 FORW;
00495 if (mydce_fix) {
00496 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
00497 FORW;
00498 } else
00499 len = oldlen - newlen;
00500 }
00501 }
00502 }
00503 {
00504 size_t newlen, oldlen;
00505
00506 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l);
00507 if (e)
00508 (data)->reqFlags = NULL;
00509 else {
00510 p += l;
00511 len -= l;
00512 ret += l;
00513 e = der_get_length(p, len, &newlen, &l);
00514 FORW;
00515 {
00516 int mydce_fix;
00517 oldlen = len;
00518 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
00519 return ASN1_BAD_FORMAT;
00520 (data)->reqFlags = malloc(sizeof(*(data)->reqFlags));
00521 if ((data)->reqFlags == NULL)
00522 return ENOMEM;
00523 e = decode_ContextFlags(p, len, (data)->reqFlags, &l);
00524 FORW;
00525 if (mydce_fix) {
00526 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
00527 FORW;
00528 } else
00529 len = oldlen - newlen;
00530 }
00531 }
00532 }
00533 {
00534 size_t newlen, oldlen;
00535
00536 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l);
00537 if (e)
00538 (data)->mechToken = NULL;
00539 else {
00540 p += l;
00541 len -= l;
00542 ret += l;
00543 e = der_get_length(p, len, &newlen, &l);
00544 FORW;
00545 {
00546 int mydce_fix;
00547 oldlen = len;
00548 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
00549 return ASN1_BAD_FORMAT;
00550 (data)->mechToken = malloc(sizeof(*(data)->mechToken));
00551 if ((data)->mechToken == NULL)
00552 return ENOMEM;
00553 e = decode_octet_string(p, len, (data)->mechToken, &l);
00554 FORW;
00555 if (mydce_fix) {
00556 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
00557 FORW;
00558 } else
00559 len = oldlen - newlen;
00560 }
00561 }
00562 }
00563 {
00564 size_t newlen, oldlen;
00565
00566 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l);
00567 if (e)
00568 (data)->mechListMIC = NULL;
00569 else {
00570 p += l;
00571 len -= l;
00572 ret += l;
00573 e = der_get_length(p, len, &newlen, &l);
00574 FORW;
00575 {
00576 int mydce_fix;
00577 oldlen = len;
00578 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
00579 return ASN1_BAD_FORMAT;
00580 (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC));
00581 if ((data)->mechListMIC == NULL)
00582 return ENOMEM;
00583 e = decode_octet_string(p, len, (data)->mechListMIC, &l);
00584 FORW;
00585 if (mydce_fix) {
00586 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
00587 FORW;
00588 } else
00589 len = oldlen - newlen;
00590 }
00591 }
00592 }
00593 if (dce_fix) {
00594 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
00595 FORW;
00596 }
00597 }
00598 if (size)
00599 *size = ret;
00600 return 0;
00601 fail:
00602 free_NegTokenInit(data);
00603 return e;
00604 }
00605
00606 static void
00607 free_NegTokenInit(NegTokenInit * data)
00608 {
00609 free_MechTypeList(&(data)->mechTypes);
00610 if ((data)->reqFlags) {
00611 free_ContextFlags((data)->reqFlags);
00612 free((data)->reqFlags);
00613 (data)->reqFlags = NULL;
00614 }
00615 if ((data)->mechToken) {
00616 free_octet_string((data)->mechToken);
00617 free((data)->mechToken);
00618 (data)->mechToken = NULL;
00619 }
00620 if ((data)->mechListMIC) {
00621 free_octet_string((data)->mechListMIC);
00622 free((data)->mechListMIC);
00623 (data)->mechListMIC = NULL;
00624 }
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 static int
00637 encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, size_t * size)
00638 {
00639 size_t ret = 0;
00640 size_t l;
00641 int e;
00642
00643 if ((data)->mechListMIC) {
00644 size_t oldret = ret;
00645 ret = 0;
00646 e = encode_octet_string(p, len, (data)->mechListMIC, &l);
00647 BACK;
00648 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l);
00649 BACK;
00650 ret += oldret;
00651 }
00652 if ((data)->responseToken) {
00653 size_t oldret = ret;
00654 ret = 0;
00655 e = encode_octet_string(p, len, (data)->responseToken, &l);
00656 BACK;
00657 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
00658 BACK;
00659 ret += oldret;
00660 }
00661 if ((data)->supportedMech) {
00662 size_t oldret = ret;
00663 ret = 0;
00664 e = encode_MechType(p, len, (data)->supportedMech, &l);
00665 BACK;
00666 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
00667 BACK;
00668 ret += oldret;
00669 }
00670 if ((data)->negState) {
00671 size_t oldret = ret;
00672 ret = 0;
00673 e = encode_enumerated(p, len, (data)->negState, &l);
00674 BACK;
00675 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
00676 BACK;
00677 ret += oldret;
00678 }
00679 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
00680 BACK;
00681 *size = ret;
00682 return 0;
00683 }
00684
00685 static int
00686 decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, size_t * size)
00687 {
00688 size_t ret = 0, reallen;
00689 size_t l;
00690 int e;
00691
00692 memset(data, 0, sizeof(*data));
00693 reallen = 0;
00694 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
00695 FORW;
00696 {
00697 int dce_fix;
00698 if ((dce_fix = fix_dce(reallen, &len)) < 0)
00699 return ASN1_BAD_FORMAT;
00700 {
00701 size_t newlen, oldlen;
00702
00703 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l);
00704 if (e)
00705 (data)->negState = NULL;
00706 else {
00707 p += l;
00708 len -= l;
00709 ret += l;
00710 e = der_get_length(p, len, &newlen, &l);
00711 FORW;
00712 {
00713 int mydce_fix;
00714 oldlen = len;
00715 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
00716 return ASN1_BAD_FORMAT;
00717 (data)->negState = malloc(sizeof(*(data)->negState));
00718 if ((data)->negState == NULL)
00719 return ENOMEM;
00720 e = decode_enumerated(p, len, (data)->negState, &l);
00721 FORW;
00722 if (mydce_fix) {
00723 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
00724 FORW;
00725 } else
00726 len = oldlen - newlen;
00727 }
00728 }
00729 }
00730 {
00731 size_t newlen, oldlen;
00732
00733 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l);
00734 if (e)
00735 (data)->supportedMech = NULL;
00736 else {
00737 p += l;
00738 len -= l;
00739 ret += l;
00740 e = der_get_length(p, len, &newlen, &l);
00741 FORW;
00742 {
00743 int mydce_fix;
00744 oldlen = len;
00745 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
00746 return ASN1_BAD_FORMAT;
00747 (data)->supportedMech = malloc(sizeof(*(data)->supportedMech));
00748 if ((data)->supportedMech == NULL)
00749 return ENOMEM;
00750 e = decode_MechType(p, len, (data)->supportedMech, &l);
00751 FORW;
00752 if (mydce_fix) {
00753 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
00754 FORW;
00755 } else
00756 len = oldlen - newlen;
00757 }
00758 }
00759 }
00760 {
00761 size_t newlen, oldlen;
00762
00763 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l);
00764 if (e)
00765 (data)->responseToken = NULL;
00766 else {
00767 p += l;
00768 len -= l;
00769 ret += l;
00770 e = der_get_length(p, len, &newlen, &l);
00771 FORW;
00772 {
00773 int mydce_fix;
00774 oldlen = len;
00775 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
00776 return ASN1_BAD_FORMAT;
00777 (data)->responseToken = malloc(sizeof(*(data)->responseToken));
00778 if ((data)->responseToken == NULL)
00779 return ENOMEM;
00780 e = decode_octet_string(p, len, (data)->responseToken, &l);
00781 FORW;
00782 if (mydce_fix) {
00783 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
00784 FORW;
00785 } else
00786 len = oldlen - newlen;
00787 }
00788 }
00789 }
00790 {
00791 size_t newlen, oldlen;
00792
00793 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l);
00794 if (e)
00795 (data)->mechListMIC = NULL;
00796 else {
00797 p += l;
00798 len -= l;
00799 ret += l;
00800 e = der_get_length(p, len, &newlen, &l);
00801 FORW;
00802 {
00803 int mydce_fix;
00804 oldlen = len;
00805 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
00806 return ASN1_BAD_FORMAT;
00807 (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC));
00808 if ((data)->mechListMIC == NULL)
00809 return ENOMEM;
00810 e = decode_octet_string(p, len, (data)->mechListMIC, &l);
00811 FORW;
00812 if (mydce_fix) {
00813 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
00814 FORW;
00815 } else
00816 len = oldlen - newlen;
00817 }
00818 }
00819 }
00820 if (dce_fix) {
00821 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
00822 FORW;
00823 }
00824 }
00825 if (size)
00826 *size = ret;
00827 return 0;
00828 fail:
00829 free_NegTokenResp(data);
00830 return e;
00831 }
00832
00833 static void
00834 free_NegTokenResp(NegTokenResp * data)
00835 {
00836 if ((data)->negState) {
00837 free((data)->negState);
00838 (data)->negState = NULL;
00839 }
00840 if ((data)->supportedMech) {
00841 free_MechType((data)->supportedMech);
00842 free((data)->supportedMech);
00843 (data)->supportedMech = NULL;
00844 }
00845 if ((data)->responseToken) {
00846 free_octet_string((data)->responseToken);
00847 free((data)->responseToken);
00848 (data)->responseToken = NULL;
00849 }
00850 if ((data)->mechListMIC) {
00851 free_octet_string((data)->mechListMIC);
00852 free((data)->mechListMIC);
00853 (data)->mechListMIC = NULL;
00854 }
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867