]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - contrib/bind9/lib/dns/spnego_asn1.c
Fix BIND remote Denial of Service vulnerability. [SA-16:34]
[FreeBSD/releng/9.3.git] / contrib / bind9 / lib / dns / spnego_asn1.c
1 /*
2  * Copyright (C) 2006, 2007, 2012, 2013  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
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
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
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
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
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
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
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
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
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
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
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 dce_fix;
490                                         oldlen = len;
491                                         if ((dce_fix = fix_dce(newlen, &len)) < 0)
492                                                 return ASN1_BAD_FORMAT;
493                                         e = decode_MechTypeList(p, len, &(data)->mechTypes, &l);
494                                         FORW;
495                                         if (dce_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 dce_fix;
517                                         oldlen = len;
518                                         if ((dce_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 (dce_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 dce_fix;
547                                         oldlen = len;
548                                         if ((dce_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 (dce_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 dce_fix;
577                                         oldlen = len;
578                                         if ((dce_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 (dce_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
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
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
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 dce_fix;
714                                         oldlen = len;
715                                         if ((dce_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 (dce_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 dce_fix;
744                                         oldlen = len;
745                                         if ((dce_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 (dce_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 dce_fix;
774                                         oldlen = len;
775                                         if ((dce_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 (dce_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 dce_fix;
804                                         oldlen = len;
805                                         if ((dce_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 (dce_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
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 */