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