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