1 /*
2 * Copyright (C) 2006, 2007, 2012, 2013, 2015 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
34 typedef struct octet_string {
35 size_t length;
36 void *data;
37 } octet_string;
38
39 typedef char *general_string;
40
41 typedef char *utf8_string;
42
43 typedef 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
70 typedef oid MechType;
71
72 static int encode_MechType(unsigned char *, size_t, const MechType *, size_t *);
73 static int decode_MechType(const unsigned char *, size_t, MechType *, size_t *);
74 static void free_MechType(MechType *);
75 /* unused declaration: length_MechType */
76 /* unused declaration: copy_MechType */
77
78
79 /*
80 * MechTypeList ::= SEQUENCE OF MechType
81 */
82
83 typedef struct MechTypeList {
84 unsigned int len;
85 MechType *val;
86 } MechTypeList;
87
88 static int encode_MechTypeList(unsigned char *, size_t, const MechTypeList *, size_t *);
89 static int decode_MechTypeList(const unsigned char *, size_t, MechTypeList *, size_t *);
90 static 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
100 typedef 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
111 static int encode_ContextFlags(unsigned char *, size_t, const ContextFlags *, size_t *);
112 static int decode_ContextFlags(const unsigned char *, size_t, ContextFlags *, size_t *);
113 static 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
126 typedef struct NegTokenInit {
127 MechTypeList mechTypes;
128 ContextFlags *reqFlags;
129 octet_string *mechToken;
130 octet_string *mechListMIC;
131 } NegTokenInit;
132
133 static int encode_NegTokenInit(unsigned char *, size_t, const NegTokenInit *, size_t *);
134 static int decode_NegTokenInit(const unsigned char *, size_t, NegTokenInit *, size_t *);
135 static 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
147 typedef 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
160 static int encode_NegTokenResp(unsigned char *, size_t, const NegTokenResp *, size_t *);
161 static int decode_NegTokenResp(const unsigned char *, size_t, NegTokenResp *, size_t *);
162 static 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; POST(p); POST(len); POST(ret)
175
176 static int
encode_MechType(unsigned char * p,size_t len,const MechType * data,size_t * size)177 encode_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 e;
182
183 e = encode_oid(p, len, data, &l);
184 BACK;
185 *size = ret;
186 return 0;
187 }
188
189 #define FORW if(e) goto fail; p += l; len -= l; ret += l; POST(p); POST(len); POST(ret)
190
191 static int
decode_MechType(const unsigned char * p,size_t len,MechType * data,size_t * size)192 decode_MechType(const unsigned char *p, size_t len, MechType * data, size_t * size)
193 {
194 size_t ret = 0;
195 size_t l;
196 int e;
197
198 memset(data, 0, sizeof(*data));
199 e = decode_oid(p, len, data, &l);
200 FORW;
201 if (size)
202 *size = ret;
203 return 0;
204 fail:
205 free_MechType(data);
206 return e;
207 }
208
209 static void
free_MechType(MechType * data)210 free_MechType(MechType * data)
211 {
212 free_oid(data);
213 }
214
215 /* unused function: length_MechType */
216
217
218 /* unused function: copy_MechType */
219
220 /* Generated from spnego.asn1 */
221 /* Do not edit */
222
223
224 static int
encode_MechTypeList(unsigned char * p,size_t len,const MechTypeList * data,size_t * size)225 encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, size_t * size)
226 {
227 size_t ret = 0;
228 size_t l;
229 int i, e;
230
231 for (i = (data)->len - 1; i >= 0; --i) {
232 size_t oldret = ret;
233 ret = 0;
234 e = encode_MechType(p, len, &(data)->val[i], &l);
235 BACK;
236 ret += oldret;
237 }
238 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
239 BACK;
240 *size = ret;
241 return 0;
242 }
243
244 static int
decode_MechTypeList(const unsigned char * p,size_t len,MechTypeList * data,size_t * size)245 decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, size_t * size)
246 {
247 size_t ret = 0, reallen;
248 size_t l;
249 int e;
250
251 memset(data, 0, sizeof(*data));
252 reallen = 0;
253 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
254 FORW;
255 if (len < reallen)
256 return ASN1_OVERRUN;
257 len = reallen;
258 {
259 size_t origlen = len;
260 size_t oldret = ret;
261 ret = 0;
262 (data)->len = 0;
263 (data)->val = NULL;
264 while (ret < origlen) {
265 void *old = (data)->val;
266 (data)->len++;
267 (data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len);
268 if ((data)->val == NULL) {
269 (data)->val = old;
270 (data)->len--;
271 return ENOMEM;
272 }
273 e = decode_MechType(p, len, &(data)->val[(data)->len - 1], &l);
274 FORW;
275 len = origlen - ret;
276 }
277 ret += oldret;
278 }
279 if (size)
280 *size = ret;
281 return 0;
282 fail:
283 free_MechTypeList(data);
284 return e;
285 }
286
287 static void
free_MechTypeList(MechTypeList * data)288 free_MechTypeList(MechTypeList * data)
289 {
290 while ((data)->len) {
291 free_MechType(&(data)->val[(data)->len - 1]);
292 (data)->len--;
293 }
294 free((data)->val);
295 (data)->val = NULL;
296 }
297
298 /* unused function: length_MechTypeList */
299
300
301 /* unused function: copy_MechTypeList */
302
303 /* Generated from spnego.asn1 */
304 /* Do not edit */
305
306
307 static int
encode_ContextFlags(unsigned char * p,size_t len,const ContextFlags * data,size_t * size)308 encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, size_t * size)
309 {
310 size_t ret = 0;
311 size_t l;
312 int e;
313
314 {
315 unsigned char c = 0;
316 *p-- = c;
317 len--;
318 ret++;
319 c = 0;
320 *p-- = c;
321 len--;
322 ret++;
323 c = 0;
324 *p-- = c;
325 len--;
326 ret++;
327 c = 0;
328 if (data->integFlag)
329 c |= 1 << 1;
330 if (data->confFlag)
331 c |= 1 << 2;
332 if (data->anonFlag)
333 c |= 1 << 3;
334 if (data->sequenceFlag)
335 c |= 1 << 4;
336 if (data->replayFlag)
337 c |= 1 << 5;
338 if (data->mutualFlag)
339 c |= 1 << 6;
340 if (data->delegFlag)
341 c |= 1 << 7;
342 *p-- = c;
343 *p-- = 0;
344 len -= 2;
345 ret += 2;
346 }
347
348 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_BitString, &l);
349 BACK;
350 *size = ret;
351 return 0;
352 }
353
354 static int
decode_ContextFlags(const unsigned char * p,size_t len,ContextFlags * data,size_t * size)355 decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, size_t * size)
356 {
357 size_t ret = 0, reallen;
358 size_t l;
359 int e;
360
361 memset(data, 0, sizeof(*data));
362 reallen = 0;
363 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, PRIM, UT_BitString, &reallen, &l);
364 FORW;
365 if (len < reallen)
366 return ASN1_OVERRUN;
367 p++;
368 len--;
369 reallen--;
370 ret++;
371 data->delegFlag = (*p >> 7) & 1;
372 data->mutualFlag = (*p >> 6) & 1;
373 data->replayFlag = (*p >> 5) & 1;
374 data->sequenceFlag = (*p >> 4) & 1;
375 data->anonFlag = (*p >> 3) & 1;
376 data->confFlag = (*p >> 2) & 1;
377 data->integFlag = (*p >> 1) & 1;
378 ret += reallen;
379 if (size)
380 *size = ret;
381 return 0;
382 fail:
383 free_ContextFlags(data);
384 return e;
385 }
386
387 static void
free_ContextFlags(ContextFlags * data)388 free_ContextFlags(ContextFlags * data)
389 {
390 (void)data;
391 }
392
393 /* unused function: length_ContextFlags */
394
395
396 /* unused function: copy_ContextFlags */
397
398
399 /* unused function: ContextFlags2int */
400
401
402 /* unused function: int2ContextFlags */
403
404
405 /* unused variable: ContextFlags_units */
406
407 /* unused function: asn1_ContextFlags_units */
408
409 /* Generated from spnego.asn1 */
410 /* Do not edit */
411
412
413 static int
encode_NegTokenInit(unsigned char * p,size_t len,const NegTokenInit * data,size_t * size)414 encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, size_t * size)
415 {
416 size_t ret = 0;
417 size_t l;
418 int e;
419
420 if ((data)->mechListMIC) {
421 size_t oldret = ret;
422 ret = 0;
423 e = encode_octet_string(p, len, (data)->mechListMIC, &l);
424 BACK;
425 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l);
426 BACK;
427 ret += oldret;
428 }
429 if ((data)->mechToken) {
430 size_t oldret = ret;
431 ret = 0;
432 e = encode_octet_string(p, len, (data)->mechToken, &l);
433 BACK;
434 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
435 BACK;
436 ret += oldret;
437 }
438 if ((data)->reqFlags) {
439 size_t oldret = ret;
440 ret = 0;
441 e = encode_ContextFlags(p, len, (data)->reqFlags, &l);
442 BACK;
443 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
444 BACK;
445 ret += oldret;
446 } {
447 size_t oldret = ret;
448 ret = 0;
449 e = encode_MechTypeList(p, len, &(data)->mechTypes, &l);
450 BACK;
451 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
452 BACK;
453 ret += oldret;
454 }
455 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
456 BACK;
457 *size = ret;
458 return 0;
459 }
460
461 static int
decode_NegTokenInit(const unsigned char * p,size_t len,NegTokenInit * data,size_t * size)462 decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, size_t * size)
463 {
464 size_t ret = 0, reallen;
465 size_t l;
466 int e;
467
468 memset(data, 0, sizeof(*data));
469 reallen = 0;
470 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
471 FORW;
472 {
473 int dce_fix;
474 if ((dce_fix = fix_dce(reallen, &len)) < 0)
475 return ASN1_BAD_FORMAT;
476 {
477 size_t newlen, oldlen;
478
479 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l);
480 if (e)
481 return e;
482 else {
483 p += l;
484 len -= l;
485 ret += l;
486 e = der_get_length(p, len, &newlen, &l);
487 FORW;
488 {
489 int mydce_fix;
490 oldlen = len;
491 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
492 return ASN1_BAD_FORMAT;
493 e = decode_MechTypeList(p, len, &(data)->mechTypes, &l);
494 FORW;
495 if (mydce_fix) {
496 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
497 FORW;
498 } else
499 len = oldlen - newlen;
500 }
501 }
502 }
503 {
504 size_t newlen, oldlen;
505
506 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l);
507 if (e)
508 (data)->reqFlags = NULL;
509 else {
510 p += l;
511 len -= l;
512 ret += l;
513 e = der_get_length(p, len, &newlen, &l);
514 FORW;
515 {
516 int mydce_fix;
517 oldlen = len;
518 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
519 return ASN1_BAD_FORMAT;
520 (data)->reqFlags = malloc(sizeof(*(data)->reqFlags));
521 if ((data)->reqFlags == NULL)
522 return ENOMEM;
523 e = decode_ContextFlags(p, len, (data)->reqFlags, &l);
524 FORW;
525 if (mydce_fix) {
526 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
527 FORW;
528 } else
529 len = oldlen - newlen;
530 }
531 }
532 }
533 {
534 size_t newlen, oldlen;
535
536 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l);
537 if (e)
538 (data)->mechToken = NULL;
539 else {
540 p += l;
541 len -= l;
542 ret += l;
543 e = der_get_length(p, len, &newlen, &l);
544 FORW;
545 {
546 int mydce_fix;
547 oldlen = len;
548 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
549 return ASN1_BAD_FORMAT;
550 (data)->mechToken = malloc(sizeof(*(data)->mechToken));
551 if ((data)->mechToken == NULL)
552 return ENOMEM;
553 e = decode_octet_string(p, len, (data)->mechToken, &l);
554 FORW;
555 if (mydce_fix) {
556 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
557 FORW;
558 } else
559 len = oldlen - newlen;
560 }
561 }
562 }
563 {
564 size_t newlen, oldlen;
565
566 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l);
567 if (e)
568 (data)->mechListMIC = NULL;
569 else {
570 p += l;
571 len -= l;
572 ret += l;
573 e = der_get_length(p, len, &newlen, &l);
574 FORW;
575 {
576 int mydce_fix;
577 oldlen = len;
578 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
579 return ASN1_BAD_FORMAT;
580 (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC));
581 if ((data)->mechListMIC == NULL)
582 return ENOMEM;
583 e = decode_octet_string(p, len, (data)->mechListMIC, &l);
584 FORW;
585 if (mydce_fix) {
586 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
587 FORW;
588 } else
589 len = oldlen - newlen;
590 }
591 }
592 }
593 if (dce_fix) {
594 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
595 FORW;
596 }
597 }
598 if (size)
599 *size = ret;
600 return 0;
601 fail:
602 free_NegTokenInit(data);
603 return e;
604 }
605
606 static void
free_NegTokenInit(NegTokenInit * data)607 free_NegTokenInit(NegTokenInit * data)
608 {
609 free_MechTypeList(&(data)->mechTypes);
610 if ((data)->reqFlags) {
611 free_ContextFlags((data)->reqFlags);
612 free((data)->reqFlags);
613 (data)->reqFlags = NULL;
614 }
615 if ((data)->mechToken) {
616 free_octet_string((data)->mechToken);
617 free((data)->mechToken);
618 (data)->mechToken = NULL;
619 }
620 if ((data)->mechListMIC) {
621 free_octet_string((data)->mechListMIC);
622 free((data)->mechListMIC);
623 (data)->mechListMIC = NULL;
624 }
625 }
626
627 /* unused function: length_NegTokenInit */
628
629
630 /* unused function: copy_NegTokenInit */
631
632 /* Generated from spnego.asn1 */
633 /* Do not edit */
634
635
636 static int
encode_NegTokenResp(unsigned char * p,size_t len,const NegTokenResp * data,size_t * size)637 encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, size_t * size)
638 {
639 size_t ret = 0;
640 size_t l;
641 int e;
642
643 if ((data)->mechListMIC) {
644 size_t oldret = ret;
645 ret = 0;
646 e = encode_octet_string(p, len, (data)->mechListMIC, &l);
647 BACK;
648 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3, &l);
649 BACK;
650 ret += oldret;
651 }
652 if ((data)->responseToken) {
653 size_t oldret = ret;
654 ret = 0;
655 e = encode_octet_string(p, len, (data)->responseToken, &l);
656 BACK;
657 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
658 BACK;
659 ret += oldret;
660 }
661 if ((data)->supportedMech) {
662 size_t oldret = ret;
663 ret = 0;
664 e = encode_MechType(p, len, (data)->supportedMech, &l);
665 BACK;
666 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
667 BACK;
668 ret += oldret;
669 }
670 if ((data)->negState) {
671 size_t oldret = ret;
672 ret = 0;
673 e = encode_enumerated(p, len, (data)->negState, &l);
674 BACK;
675 e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
676 BACK;
677 ret += oldret;
678 }
679 e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
680 BACK;
681 *size = ret;
682 return 0;
683 }
684
685 static int
decode_NegTokenResp(const unsigned char * p,size_t len,NegTokenResp * data,size_t * size)686 decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, size_t * size)
687 {
688 size_t ret = 0, reallen;
689 size_t l;
690 int e;
691
692 memset(data, 0, sizeof(*data));
693 reallen = 0;
694 e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence, &reallen, &l);
695 FORW;
696 {
697 int dce_fix;
698 if ((dce_fix = fix_dce(reallen, &len)) < 0)
699 return ASN1_BAD_FORMAT;
700 {
701 size_t newlen, oldlen;
702
703 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l);
704 if (e)
705 (data)->negState = NULL;
706 else {
707 p += l;
708 len -= l;
709 ret += l;
710 e = der_get_length(p, len, &newlen, &l);
711 FORW;
712 {
713 int mydce_fix;
714 oldlen = len;
715 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
716 return ASN1_BAD_FORMAT;
717 (data)->negState = malloc(sizeof(*(data)->negState));
718 if ((data)->negState == NULL)
719 return ENOMEM;
720 e = decode_enumerated(p, len, (data)->negState, &l);
721 FORW;
722 if (mydce_fix) {
723 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
724 FORW;
725 } else
726 len = oldlen - newlen;
727 }
728 }
729 }
730 {
731 size_t newlen, oldlen;
732
733 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l);
734 if (e)
735 (data)->supportedMech = NULL;
736 else {
737 p += l;
738 len -= l;
739 ret += l;
740 e = der_get_length(p, len, &newlen, &l);
741 FORW;
742 {
743 int mydce_fix;
744 oldlen = len;
745 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
746 return ASN1_BAD_FORMAT;
747 (data)->supportedMech = malloc(sizeof(*(data)->supportedMech));
748 if ((data)->supportedMech == NULL)
749 return ENOMEM;
750 e = decode_MechType(p, len, (data)->supportedMech, &l);
751 FORW;
752 if (mydce_fix) {
753 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
754 FORW;
755 } else
756 len = oldlen - newlen;
757 }
758 }
759 }
760 {
761 size_t newlen, oldlen;
762
763 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l);
764 if (e)
765 (data)->responseToken = NULL;
766 else {
767 p += l;
768 len -= l;
769 ret += l;
770 e = der_get_length(p, len, &newlen, &l);
771 FORW;
772 {
773 int mydce_fix;
774 oldlen = len;
775 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
776 return ASN1_BAD_FORMAT;
777 (data)->responseToken = malloc(sizeof(*(data)->responseToken));
778 if ((data)->responseToken == NULL)
779 return ENOMEM;
780 e = decode_octet_string(p, len, (data)->responseToken, &l);
781 FORW;
782 if (mydce_fix) {
783 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
784 FORW;
785 } else
786 len = oldlen - newlen;
787 }
788 }
789 }
790 {
791 size_t newlen, oldlen;
792
793 e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l);
794 if (e)
795 (data)->mechListMIC = NULL;
796 else {
797 p += l;
798 len -= l;
799 ret += l;
800 e = der_get_length(p, len, &newlen, &l);
801 FORW;
802 {
803 int mydce_fix;
804 oldlen = len;
805 if ((mydce_fix = fix_dce(newlen, &len)) < 0)
806 return ASN1_BAD_FORMAT;
807 (data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC));
808 if ((data)->mechListMIC == NULL)
809 return ENOMEM;
810 e = decode_octet_string(p, len, (data)->mechListMIC, &l);
811 FORW;
812 if (mydce_fix) {
813 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
814 FORW;
815 } else
816 len = oldlen - newlen;
817 }
818 }
819 }
820 if (dce_fix) {
821 e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
822 FORW;
823 }
824 }
825 if (size)
826 *size = ret;
827 return 0;
828 fail:
829 free_NegTokenResp(data);
830 return e;
831 }
832
833 static void
free_NegTokenResp(NegTokenResp * data)834 free_NegTokenResp(NegTokenResp * data)
835 {
836 if ((data)->negState) {
837 free((data)->negState);
838 (data)->negState = NULL;
839 }
840 if ((data)->supportedMech) {
841 free_MechType((data)->supportedMech);
842 free((data)->supportedMech);
843 (data)->supportedMech = NULL;
844 }
845 if ((data)->responseToken) {
846 free_octet_string((data)->responseToken);
847 free((data)->responseToken);
848 (data)->responseToken = NULL;
849 }
850 if ((data)->mechListMIC) {
851 free_octet_string((data)->mechListMIC);
852 free((data)->mechListMIC);
853 (data)->mechListMIC = NULL;
854 }
855 }
856
857 /* unused function: length_NegTokenResp */
858
859
860 /* unused function: copy_NegTokenResp */
861
862 /* Generated from spnego.asn1 */
863 /* Do not edit */
864
865
866 /* CHOICE */
867 /* unused variable: asn1_NegotiationToken_dummy_holder */
868