[BACK]Return to spnego_asn1.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / mpl / bind / dist / lib / dns

File: [cvs.NetBSD.org] / src / external / mpl / bind / dist / lib / dns / Attic / spnego_asn1.c (download)

Revision 1.8, Mon Apr 5 11:27:02 2021 UTC (2 years, 11 months ago) by rillig
Branch: MAIN
Changes since 1.7: +2 -2 lines

bind: remove unnecessary CONSTCOND comments

Since lint1/tree.c 1.202 from 2021-01-31, lint no longer needs the
/*CONSTCOND*/ for do-while-0 "loops".

No functional change.

/*	$NetBSD: spnego_asn1.c,v 1.8 2021/04/05 11:27:02 rillig Exp $	*/

/*
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
 *
 * See the COPYRIGHT file distributed with this work for additional
 * information regarding copyright ownership.
 */

/*! \file
 * \brief Method routines generated from SPNEGO ASN.1 module.
 * See spnego_asn1.pl for details.  Do not edit.
 */

/* Generated from spnego.asn1 */
/* Do not edit */

#ifndef __asn1_h__
#define __asn1_h__

#ifndef __asn1_common_definitions__
#define __asn1_common_definitions__

typedef struct octet_string {
	size_t length;
	void *data;
} octet_string;

typedef char *general_string;

typedef char *utf8_string;

typedef struct oid {
	size_t length;
	unsigned *components;
} oid;

#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R)                             \
	do {                                                              \
		(BL) = length_##T((S));                                   \
		(B) = malloc((BL));                                       \
		if ((B) == NULL) {                                        \
			(R) = ENOMEM;                                     \
		} else {                                                  \
			(R) = encode_##T(((unsigned char *)(B)) + (BL)-1, \
					 (BL), (S), (L));                 \
			if ((R) != 0) {                                   \
				free((B));                                \
				(B) = NULL;                               \
			}                                                 \
		}                                                         \
	} while (0)

#endif /* ifndef __asn1_common_definitions__ */

/*
 * MechType ::= OBJECT IDENTIFIER
 */

typedef oid MechType;

static int
encode_MechType(unsigned char *, size_t, const MechType *, size_t *);
static int
decode_MechType(const unsigned char *, size_t, MechType *, size_t *);
static void
free_MechType(MechType *);
/* unused declaration: length_MechType */
/* unused declaration: copy_MechType */

/*
 * MechTypeList ::= SEQUENCE OF MechType
 */

typedef struct MechTypeList {
	unsigned int len;
	MechType *val;
} MechTypeList;

static int
encode_MechTypeList(unsigned char *, size_t, const MechTypeList *, size_t *);
static int
decode_MechTypeList(const unsigned char *, size_t, MechTypeList *, size_t *);
static void
free_MechTypeList(MechTypeList *);
/* unused declaration: length_MechTypeList */
/* unused declaration: copy_MechTypeList */

/*
 * ContextFlags ::= BIT STRING { delegFlag(0), mutualFlag(1), replayFlag(2),
 * sequenceFlag(3), anonFlag(4), confFlag(5), integFlag(6) }
 */

typedef struct ContextFlags {
	unsigned int delegFlag	  : 1;
	unsigned int mutualFlag	  : 1;
	unsigned int replayFlag	  : 1;
	unsigned int sequenceFlag : 1;
	unsigned int anonFlag	  : 1;
	unsigned int confFlag	  : 1;
	unsigned int integFlag	  : 1;
} ContextFlags;

static int
encode_ContextFlags(unsigned char *, size_t, const ContextFlags *, size_t *);
static int
decode_ContextFlags(const unsigned char *, size_t, ContextFlags *, size_t *);
static void
free_ContextFlags(ContextFlags *);
/* unused declaration: length_ContextFlags */
/* unused declaration: copy_ContextFlags */
/* unused declaration: ContextFlags2int */
/* unused declaration: int2ContextFlags */
/* unused declaration: asn1_ContextFlags_units */

/*
 * NegTokenInit ::= SEQUENCE { mechTypes[0]    MechTypeList, reqFlags[1]
 * ContextFlags OPTIONAL, mechToken[2]    OCTET STRING OPTIONAL,
 * mechListMIC[3]  OCTET STRING OPTIONAL }
 */

typedef struct NegTokenInit {
	MechTypeList mechTypes;
	ContextFlags *reqFlags;
	octet_string *mechToken;
	octet_string *mechListMIC;
} NegTokenInit;

static int
encode_NegTokenInit(unsigned char *, size_t, const NegTokenInit *, size_t *);
static int
decode_NegTokenInit(const unsigned char *, size_t, NegTokenInit *, size_t *);
static void
free_NegTokenInit(NegTokenInit *);
/* unused declaration: length_NegTokenInit */
/* unused declaration: copy_NegTokenInit */

/*
 * NegTokenResp ::= SEQUENCE { negState[0]       ENUMERATED {
 * accept-completed(0), accept-incomplete(1), reject(2), request-mic(3) }
 * OPTIONAL, supportedMech[1]  MechType OPTIONAL, responseToken[2]  OCTET
 * STRING OPTIONAL, mechListMIC[3]    OCTET STRING OPTIONAL }
 */

typedef struct NegTokenResp {
	enum {
		accept_completed = 0,
		accept_incomplete = 1,
		reject = 2,
		request_mic = 3
	} *
		negState;

	MechType *supportedMech;
	octet_string *responseToken;
	octet_string *mechListMIC;
} NegTokenResp;

static int
encode_NegTokenResp(unsigned char *, size_t, const NegTokenResp *, size_t *);
static int
decode_NegTokenResp(const unsigned char *, size_t, NegTokenResp *, size_t *);
static void
free_NegTokenResp(NegTokenResp *);
/* unused declaration: length_NegTokenResp */
/* unused declaration: copy_NegTokenResp */

#endif /* __asn1_h__ */
/* Generated from spnego.asn1 */
/* Do not edit */

#define BACK                \
	if (e)              \
		return (e); \
	p -= l;             \
	len -= l;           \
	ret += l;           \
	POST(p);            \
	POST(len);          \
	POST(ret)

static int
encode_MechType(unsigned char *p, size_t len, const MechType *data,
		size_t *size) {
	size_t ret = 0;
	size_t l;
	int e;

	e = encode_oid(p, len, data, &l);
	BACK;
	*size = ret;
	return (0);
}

#define FORW               \
	if (e)             \
		goto fail; \
	p += l;            \
	len -= l;          \
	ret += l;          \
	POST(p);           \
	POST(len);         \
	POST(ret)

static int
decode_MechType(const unsigned char *p, size_t len, MechType *data,
		size_t *size) {
	size_t ret = 0;
	size_t l;
	int e;

	memset(data, 0, sizeof(*data));
	e = decode_oid(p, len, data, &l);
	FORW;
	if (size) {
		*size = ret;
	}
	return (0);
fail:
	free_MechType(data);
	return (e);
}

static void
free_MechType(MechType *data) {
	free_oid(data);
}

/* unused function: length_MechType */

/* unused function: copy_MechType */

/* Generated from spnego.asn1 */
/* Do not edit */

static int
encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList *data,
		    size_t *size) {
	size_t ret = 0;
	size_t l;
	int i, e;

	for (i = (data)->len - 1; i >= 0; --i) {
		size_t oldret = ret;
		ret = 0;
		e = encode_MechType(p, len, &(data)->val[i], &l);
		BACK;
		ret += oldret;
	}
	e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence,
				   &l);
	BACK;
	*size = ret;
	return (0);
}

static int
decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList *data,
		    size_t *size) {
	size_t ret = 0, reallen;
	size_t l;
	int e;

	memset(data, 0, sizeof(*data));
	reallen = 0;
	e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence,
				     &reallen, &l);
	FORW;
	if (len < reallen) {
		return (ASN1_OVERRUN);
	}
	len = reallen;
	{
		size_t origlen = len;
		size_t oldret = ret;
		ret = 0;
		(data)->len = 0;
		(data)->val = NULL;
		while (ret < origlen) {
			void *old = (data)->val;
			(data)->len++;
			(data)->val =
				realloc((data)->val,
					sizeof(*((data)->val)) * (data)->len);
			if ((data)->val == NULL) {
				(data)->val = old;
				(data)->len--;
				return (ENOMEM);
			}
			e = decode_MechType(p, len,
					    &(data)->val[(data)->len - 1], &l);
			FORW;
			len = origlen - ret;
		}
		ret += oldret;
	}
	if (size) {
		*size = ret;
	}
	return (0);
fail:
	free_MechTypeList(data);
	return (e);
}

static void
free_MechTypeList(MechTypeList *data) {
	while ((data)->len) {
		free_MechType(&(data)->val[(data)->len - 1]);
		(data)->len--;
	}
	free((data)->val);
	(data)->val = NULL;
}

/* unused function: length_MechTypeList */

/* unused function: copy_MechTypeList */

/* Generated from spnego.asn1 */
/* Do not edit */

static int
encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags *data,
		    size_t *size) {
	size_t ret = 0;
	size_t l;
	int e;

	{
		unsigned char c = 0;
		*p-- = c;
		len--;
		ret++;
		c = 0;
		*p-- = c;
		len--;
		ret++;
		c = 0;
		*p-- = c;
		len--;
		ret++;
		c = 0;
		if (data->integFlag) {
			c |= 1 << 1;
		}
		if (data->confFlag) {
			c |= 1 << 2;
		}
		if (data->anonFlag) {
			c |= 1 << 3;
		}
		if (data->sequenceFlag) {
			c |= 1 << 4;
		}
		if (data->replayFlag) {
			c |= 1 << 5;
		}
		if (data->mutualFlag) {
			c |= 1 << 6;
		}
		if (data->delegFlag) {
			c |= 1 << 7;
		}
		*p-- = c;
		*p-- = 0;
		len -= 2;
		ret += 2;
	}

	e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_BitString,
				   &l);
	BACK;
	*size = ret;
	return (0);
}

static int
decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags *data,
		    size_t *size) {
	size_t ret = 0, reallen;
	size_t l;
	int e;

	memset(data, 0, sizeof(*data));
	reallen = 0;
	e = der_match_tag_and_length(p, len, ASN1_C_UNIV, PRIM, UT_BitString,
				     &reallen, &l);
	FORW;
	if (len < reallen) {
		return (ASN1_OVERRUN);
	}
	p++;
	len--;
	POST(len);
	reallen--;
	ret++;
	data->delegFlag = (*p >> 7) & 1;
	data->mutualFlag = (*p >> 6) & 1;
	data->replayFlag = (*p >> 5) & 1;
	data->sequenceFlag = (*p >> 4) & 1;
	data->anonFlag = (*p >> 3) & 1;
	data->confFlag = (*p >> 2) & 1;
	data->integFlag = (*p >> 1) & 1;
	ret += reallen;
	if (size) {
		*size = ret;
	}
	return (0);
fail:
	free_ContextFlags(data);
	return (e);
}

static void
free_ContextFlags(ContextFlags *data) {
	(void)data;
}

/* unused function: length_ContextFlags */

/* unused function: copy_ContextFlags */

/* unused function: ContextFlags2int */

/* unused function: int2ContextFlags */

/* unused variable: ContextFlags_units */

/* unused function: asn1_ContextFlags_units */

/* Generated from spnego.asn1 */
/* Do not edit */

static int
encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit *data,
		    size_t *size) {
	size_t ret = 0;
	size_t l;
	int e;

	if ((data)->mechListMIC) {
		size_t oldret = ret;
		ret = 0;
		e = encode_octet_string(p, len, (data)->mechListMIC, &l);
		BACK;
		e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3,
					   &l);
		BACK;
		ret += oldret;
	}
	if ((data)->mechToken) {
		size_t oldret = ret;
		ret = 0;
		e = encode_octet_string(p, len, (data)->mechToken, &l);
		BACK;
		e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2,
					   &l);
		BACK;
		ret += oldret;
	}
	if ((data)->reqFlags) {
		size_t oldret = ret;
		ret = 0;
		e = encode_ContextFlags(p, len, (data)->reqFlags, &l);
		BACK;
		e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1,
					   &l);
		BACK;
		ret += oldret;
	}
	{
		size_t oldret = ret;
		ret = 0;
		e = encode_MechTypeList(p, len, &(data)->mechTypes, &l);
		BACK;
		e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0,
					   &l);
		BACK;
		ret += oldret;
	}
	e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence,
				   &l);
	BACK;
	*size = ret;
	return (0);
}

static int
decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit *data,
		    size_t *size) {
	size_t ret = 0, reallen;
	size_t l;
	int e;

	memset(data, 0, sizeof(*data));
	reallen = 0;
	e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence,
				     &reallen, &l);
	FORW;
	{
		int dce_fix;
		if ((dce_fix = fix_dce(reallen, &len)) < 0) {
			e = ASN1_BAD_FORMAT;
			goto fail;
		}
		{
			size_t newlen, oldlen;

			e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l);
			FORW;
			{
				e = der_get_length(p, len, &newlen, &l);
				FORW;
				{
					int mydce_fix;
					oldlen = len;
					if ((mydce_fix = fix_dce(newlen,
								 &len)) < 0) {
						e = ASN1_BAD_FORMAT;
						goto fail;
					}
					e = decode_MechTypeList(
						p, len, &(data)->mechTypes, &l);
					FORW;
					if (mydce_fix) {
						e = der_match_tag_and_length(
							p, len, (Der_class)0,
							(Der_type)0, 0,
							&reallen, &l);
						FORW;
					} else {
						len = oldlen - newlen;
					}
				}
			}
		}
		{
			size_t newlen, oldlen;

			e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l);
			if (e) {
				(data)->reqFlags = NULL;
			} else {
				p += l;
				len -= l;
				ret += l;
				e = der_get_length(p, len, &newlen, &l);
				FORW;
				{
					int mydce_fix;
					oldlen = len;
					if ((mydce_fix = fix_dce(newlen,
								 &len)) < 0) {
						e = ASN1_BAD_FORMAT;
						goto fail;
					}
					(data)->reqFlags = malloc(
						sizeof(*(data)->reqFlags));
					if ((data)->reqFlags == NULL) {
						e = ENOMEM;
						goto fail;
					}
					e = decode_ContextFlags(
						p, len, (data)->reqFlags, &l);
					FORW;
					if (mydce_fix) {
						e = der_match_tag_and_length(
							p, len, (Der_class)0,
							(Der_type)0, 0,
							&reallen, &l);
						FORW;
					} else {
						len = oldlen - newlen;
					}
				}
			}
		}
		{
			size_t newlen, oldlen;

			e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l);
			if (e) {
				(data)->mechToken = NULL;
			} else {
				p += l;
				len -= l;
				ret += l;
				e = der_get_length(p, len, &newlen, &l);
				FORW;
				{
					int mydce_fix;
					oldlen = len;
					if ((mydce_fix = fix_dce(newlen,
								 &len)) < 0) {
						e = ASN1_BAD_FORMAT;
						goto fail;
					}
					(data)->mechToken = malloc(
						sizeof(*(data)->mechToken));
					if ((data)->mechToken == NULL) {
						e = ENOMEM;
						goto fail;
					}
					e = decode_octet_string(
						p, len, (data)->mechToken, &l);
					FORW;
					if (mydce_fix) {
						e = der_match_tag_and_length(
							p, len, (Der_class)0,
							(Der_type)0, 0,
							&reallen, &l);
						FORW;
					} else {
						len = oldlen - newlen;
					}
				}
			}
		}
		{
			size_t newlen, oldlen;

			e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l);
			if (e) {
				(data)->mechListMIC = NULL;
			} else {
				p += l;
				len -= l;
				ret += l;
				e = der_get_length(p, len, &newlen, &l);
				FORW;
				{
					int mydce_fix;
					oldlen = len;
					if ((mydce_fix = fix_dce(newlen,
								 &len)) < 0) {
						e = ASN1_BAD_FORMAT;
						goto fail;
					}
					(data)->mechListMIC = malloc(
						sizeof(*(data)->mechListMIC));
					if ((data)->mechListMIC == NULL) {
						e = ENOMEM;
						goto fail;
					}
					e = decode_octet_string(
						p, len, (data)->mechListMIC,
						&l);
					FORW;
					if (mydce_fix) {
						e = der_match_tag_and_length(
							p, len, (Der_class)0,
							(Der_type)0, 0,
							&reallen, &l);
						FORW;
					} else {
						len = oldlen - newlen;
					}
				}
			}
		}
		if (dce_fix) {
			e = der_match_tag_and_length(p, len, (Der_class)0,
						     (Der_type)0, 0, &reallen,
						     &l);
			FORW;
		}
	}
	if (size) {
		*size = ret;
	}
	return (0);
fail:
	free_NegTokenInit(data);
	return (e);
}

static void
free_NegTokenInit(NegTokenInit *data) {
	free_MechTypeList(&(data)->mechTypes);
	if ((data)->reqFlags) {
		free_ContextFlags((data)->reqFlags);
		free((data)->reqFlags);
		(data)->reqFlags = NULL;
	}
	if ((data)->mechToken) {
		free_octet_string((data)->mechToken);
		free((data)->mechToken);
		(data)->mechToken = NULL;
	}
	if ((data)->mechListMIC) {
		free_octet_string((data)->mechListMIC);
		free((data)->mechListMIC);
		(data)->mechListMIC = NULL;
	}
}

/* unused function: length_NegTokenInit */

/* unused function: copy_NegTokenInit */

/* Generated from spnego.asn1 */
/* Do not edit */

static int
encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp *data,
		    size_t *size) {
	size_t ret = 0;
	size_t l;
	int e;

	if ((data)->mechListMIC) {
		size_t oldret = ret;
		ret = 0;
		e = encode_octet_string(p, len, (data)->mechListMIC, &l);
		BACK;
		e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 3,
					   &l);
		BACK;
		ret += oldret;
	}
	if ((data)->responseToken) {
		size_t oldret = ret;
		ret = 0;
		e = encode_octet_string(p, len, (data)->responseToken, &l);
		BACK;
		e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2,
					   &l);
		BACK;
		ret += oldret;
	}
	if ((data)->supportedMech) {
		size_t oldret = ret;
		ret = 0;
		e = encode_MechType(p, len, (data)->supportedMech, &l);
		BACK;
		e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1,
					   &l);
		BACK;
		ret += oldret;
	}
	if ((data)->negState) {
		size_t oldret = ret;
		ret = 0;
		e = encode_enumerated(p, len, (data)->negState, &l);
		BACK;
		e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0,
					   &l);
		BACK;
		ret += oldret;
	}
	e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence,
				   &l);
	BACK;
	*size = ret;
	return (0);
}

static int
decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp *data,
		    size_t *size) {
	size_t ret = 0, reallen;
	size_t l;
	int e;

	/* cppcheck-suppress uninitvar */
	memset(data, 0, sizeof(*data));
	reallen = 0;
	e = der_match_tag_and_length(p, len, ASN1_C_UNIV, CONS, UT_Sequence,
				     &reallen, &l);
	FORW;
	{
		int dce_fix;
		if ((dce_fix = fix_dce(reallen, &len)) < 0) {
			return (ASN1_BAD_FORMAT);
		}
		{
			size_t newlen, oldlen;

			e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, &l);
			if (e) {
				(data)->negState = NULL;
			} else {
				p += l;
				len -= l;
				ret += l;
				e = der_get_length(p, len, &newlen, &l);
				FORW;
				{
					int mydce_fix;
					oldlen = len;
					if ((mydce_fix = fix_dce(newlen,
								 &len)) < 0) {
						return (ASN1_BAD_FORMAT);
					}
					(data)->negState = malloc(
						sizeof(*(data)->negState));
					if ((data)->negState == NULL) {
						return (ENOMEM);
					}
					e = decode_enumerated(
						p, len, (data)->negState, &l);
					FORW;
					if (mydce_fix) {
						e = der_match_tag_and_length(
							p, len, (Der_class)0,
							(Der_type)0, 0,
							&reallen, &l);
						FORW;
					} else {
						len = oldlen - newlen;
					}
				}
			}
		}
		{
			size_t newlen, oldlen;

			e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, &l);
			if (e) {
				(data)->supportedMech = NULL;
			} else {
				p += l;
				len -= l;
				ret += l;
				e = der_get_length(p, len, &newlen, &l);
				FORW;
				{
					int mydce_fix;
					oldlen = len;
					if ((mydce_fix = fix_dce(newlen,
								 &len)) < 0) {
						return (ASN1_BAD_FORMAT);
					}
					(data)->supportedMech = malloc(
						sizeof(*(data)->supportedMech));
					if ((data)->supportedMech == NULL) {
						return (ENOMEM);
					}
					e = decode_MechType(
						p, len, (data)->supportedMech,
						&l);
					FORW;
					if (mydce_fix) {
						e = der_match_tag_and_length(
							p, len, (Der_class)0,
							(Der_type)0, 0,
							&reallen, &l);
						FORW;
					} else {
						len = oldlen - newlen;
					}
				}
			}
		}
		{
			size_t newlen, oldlen;

			e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, &l);
			if (e) {
				(data)->responseToken = NULL;
			} else {
				p += l;
				len -= l;
				ret += l;
				e = der_get_length(p, len, &newlen, &l);
				FORW;
				{
					int mydce_fix;
					oldlen = len;
					if ((mydce_fix = fix_dce(newlen,
								 &len)) < 0) {
						return (ASN1_BAD_FORMAT);
					}
					(data)->responseToken = malloc(
						sizeof(*(data)->responseToken));
					if ((data)->responseToken == NULL) {
						return (ENOMEM);
					}
					e = decode_octet_string(
						p, len, (data)->responseToken,
						&l);
					FORW;
					if (mydce_fix) {
						e = der_match_tag_and_length(
							p, len, (Der_class)0,
							(Der_type)0, 0,
							&reallen, &l);
						FORW;
					} else {
						len = oldlen - newlen;
					}
				}
			}
		}
		{
			size_t newlen, oldlen;

			e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 3, &l);
			if (e) {
				(data)->mechListMIC = NULL;
			} else {
				p += l;
				len -= l;
				ret += l;
				e = der_get_length(p, len, &newlen, &l);
				FORW;
				{
					int mydce_fix;
					oldlen = len;
					if ((mydce_fix = fix_dce(newlen,
								 &len)) < 0) {
						return (ASN1_BAD_FORMAT);
					}
					(data)->mechListMIC = malloc(
						sizeof(*(data)->mechListMIC));
					if ((data)->mechListMIC == NULL) {
						return (ENOMEM);
					}
					e = decode_octet_string(
						p, len, (data)->mechListMIC,
						&l);
					FORW;
					if (mydce_fix) {
						e = der_match_tag_and_length(
							p, len, (Der_class)0,
							(Der_type)0, 0,
							&reallen, &l);
						FORW;
					} else {
						len = oldlen - newlen;
					}
				}
			}
		}
		if (dce_fix) {
			e = der_match_tag_and_length(p, len, (Der_class)0,
						     (Der_type)0, 0, &reallen,
						     &l);
			FORW;
		}
	}
	if (size) {
		*size = ret;
	}
	return (0);
fail:
	free_NegTokenResp(data);
	return (e);
}

static void
free_NegTokenResp(NegTokenResp *data) {
	if ((data)->negState) {
		free((data)->negState);
		(data)->negState = NULL;
	}
	if ((data)->supportedMech) {
		free_MechType((data)->supportedMech);
		free((data)->supportedMech);
		(data)->supportedMech = NULL;
	}
	if ((data)->responseToken) {
		free_octet_string((data)->responseToken);
		free((data)->responseToken);
		(data)->responseToken = NULL;
	}
	if ((data)->mechListMIC) {
		free_octet_string((data)->mechListMIC);
		free((data)->mechListMIC);
		(data)->mechListMIC = NULL;
	}
}

/* unused function: length_NegTokenResp */

/* unused function: copy_NegTokenResp */

/* Generated from spnego.asn1 */
/* Do not edit */

/* CHOICE */
/* unused variable: asn1_NegotiationToken_dummy_holder */