windows-nt/Source/XPSP1/NT/ds/security/base/lsa/server/spnego.c
2020-09-26 16:20:57 +08:00

738 lines
21 KiB
C

#include <windows.h>
#include "spnego.h"
ASN1module_t SPNEGO_Module = NULL;
static int ASN1CALL ASN1Enc_SavedMechTypeList(ASN1encoding_t enc, ASN1uint32_t tag, SavedMechTypeList *val);
static int ASN1CALL ASN1Enc_MechTypeList(ASN1encoding_t enc, ASN1uint32_t tag, PMechTypeList *val);
static int ASN1CALL ASN1Enc_NegHints(ASN1encoding_t enc, ASN1uint32_t tag, NegHints *val);
static int ASN1CALL ASN1Enc_NegTokenInit(ASN1encoding_t enc, ASN1uint32_t tag, NegTokenInit *val);
static int ASN1CALL ASN1Enc_NegTokenInit2(ASN1encoding_t enc, ASN1uint32_t tag, NegTokenInit2 *val);
static int ASN1CALL ASN1Enc_NegTokenTarg(ASN1encoding_t enc, ASN1uint32_t tag, NegTokenTarg *val);
static int ASN1CALL ASN1Enc_NegotiationToken(ASN1encoding_t enc, ASN1uint32_t tag, NegotiationToken *val);
static int ASN1CALL ASN1Enc_InitialNegToken(ASN1encoding_t enc, ASN1uint32_t tag, InitialNegToken *val);
static int ASN1CALL ASN1Dec_SavedMechTypeList(ASN1decoding_t dec, ASN1uint32_t tag, SavedMechTypeList *val);
static int ASN1CALL ASN1Dec_MechTypeList(ASN1decoding_t dec, ASN1uint32_t tag, PMechTypeList *val);
static int ASN1CALL ASN1Dec_NegHints(ASN1decoding_t dec, ASN1uint32_t tag, NegHints *val);
static int ASN1CALL ASN1Dec_NegTokenInit(ASN1decoding_t dec, ASN1uint32_t tag, NegTokenInit *val);
static int ASN1CALL ASN1Dec_NegTokenInit2(ASN1decoding_t dec, ASN1uint32_t tag, NegTokenInit2 *val);
static int ASN1CALL ASN1Dec_NegTokenTarg(ASN1decoding_t dec, ASN1uint32_t tag, NegTokenTarg *val);
static int ASN1CALL ASN1Dec_NegotiationToken(ASN1decoding_t dec, ASN1uint32_t tag, NegotiationToken *val);
static int ASN1CALL ASN1Dec_InitialNegToken(ASN1decoding_t dec, ASN1uint32_t tag, InitialNegToken *val);
static void ASN1CALL ASN1Free_SavedMechTypeList(SavedMechTypeList *val);
static void ASN1CALL ASN1Free_MechTypeList(PMechTypeList *val);
static void ASN1CALL ASN1Free_NegHints(NegHints *val);
static void ASN1CALL ASN1Free_NegTokenInit(NegTokenInit *val);
static void ASN1CALL ASN1Free_NegTokenInit2(NegTokenInit2 *val);
static void ASN1CALL ASN1Free_NegTokenTarg(NegTokenTarg *val);
static void ASN1CALL ASN1Free_NegotiationToken(NegotiationToken *val);
static void ASN1CALL ASN1Free_InitialNegToken(InitialNegToken *val);
typedef ASN1BerEncFun_t ASN1EncFun_t;
static const ASN1EncFun_t encfntab[3] = {
(ASN1EncFun_t) ASN1Enc_SavedMechTypeList,
(ASN1EncFun_t) ASN1Enc_NegotiationToken,
(ASN1EncFun_t) ASN1Enc_InitialNegToken,
};
typedef ASN1BerDecFun_t ASN1DecFun_t;
static const ASN1DecFun_t decfntab[3] = {
(ASN1DecFun_t) ASN1Dec_SavedMechTypeList,
(ASN1DecFun_t) ASN1Dec_NegotiationToken,
(ASN1DecFun_t) ASN1Dec_InitialNegToken,
};
static const ASN1FreeFun_t freefntab[3] = {
(ASN1FreeFun_t) ASN1Free_SavedMechTypeList,
(ASN1FreeFun_t) ASN1Free_NegotiationToken,
(ASN1FreeFun_t) ASN1Free_InitialNegToken,
};
static const ULONG sizetab[3] = {
SIZE_SPNEGO_Module_PDU_0,
SIZE_SPNEGO_Module_PDU_1,
SIZE_SPNEGO_Module_PDU_2,
};
/* forward declarations of values: */
/* definitions of value components: */
/* definitions of values: */
void ASN1CALL SPNEGO_Module_Startup(void)
{
SPNEGO_Module = ASN1_CreateModule(0x10000, ASN1_BER_RULE_DER, ASN1FLAGS_NONE, 3, (const ASN1GenericFun_t *) encfntab, (const ASN1GenericFun_t *) decfntab, freefntab, sizetab, 0x656e7073);
}
void ASN1CALL SPNEGO_Module_Cleanup(void)
{
ASN1_CloseModule(SPNEGO_Module);
SPNEGO_Module = NULL;
}
static int ASN1CALL ASN1Enc_SavedMechTypeList(ASN1encoding_t enc, ASN1uint32_t tag, SavedMechTypeList *val)
{
if (!ASN1Enc_MechTypeList(enc, tag, val))
return 0;
return 1;
}
static int ASN1CALL ASN1Dec_SavedMechTypeList(ASN1decoding_t dec, ASN1uint32_t tag, SavedMechTypeList *val)
{
if (!ASN1Dec_MechTypeList(dec, tag, val))
return 0;
return 1;
}
static void ASN1CALL ASN1Free_SavedMechTypeList(SavedMechTypeList *val)
{
if (val) {
ASN1Free_MechTypeList(val);
}
}
static int ASN1CALL ASN1Enc_MechTypeList(ASN1encoding_t enc, ASN1uint32_t tag, PMechTypeList *val)
{
PMechTypeList f;
ASN1uint32_t nLenOff;
if (!ASN1BEREncExplicitTag(enc, tag ? tag : 0x10, &nLenOff))
return 0;
for (f = *val; f; f = f->next) {
if (!ASN1BEREncObjectIdentifier(enc, 0x6, &f->value))
return 0;
}
if (!ASN1BEREncEndOfContents(enc, nLenOff))
return 0;
return 1;
}
static int ASN1CALL ASN1Dec_MechTypeList(ASN1decoding_t dec, ASN1uint32_t tag, PMechTypeList *val)
{
PMechTypeList *f;
ASN1decoding_t dd;
ASN1octet_t *di;
ASN1uint32_t t;
if (!ASN1BERDecExplicitTag(dec, tag ? tag : 0x10, &dd, &di))
return 0;
f = val;
while (ASN1BERDecNotEndOfContents(dd, di)) {
if (!ASN1BERDecPeekTag(dd, &t))
return 0;
if (!(*f = (PMechTypeList)ASN1DecAlloc(dd, sizeof(**f))))
return 0;
if (!ASN1BERDecObjectIdentifier(dd, 0x6, &(*f)->value))
return 0;
f = &(*f)->next;
}
*f = NULL;
if (!ASN1BERDecEndOfContents(dec, dd, di))
return 0;
return 1;
}
static void ASN1CALL ASN1Free_MechTypeList(PMechTypeList *val)
{
PMechTypeList f, ff;
if (val) {
for (f = *val; f; f = ff) {
ASN1objectidentifier_free(&f->value);
ff = f->next;
ASN1Free(f);
}
}
}
static int ASN1CALL ASN1Enc_NegHints(ASN1encoding_t enc, ASN1uint32_t tag, NegHints *val)
{
ASN1uint32_t nLenOff;
ASN1uint32_t t;
ASN1uint32_t nLenOff0;
if (!ASN1BEREncExplicitTag(enc, tag ? tag : 0x10, &nLenOff))
return 0;
if ((val)->o[0] & 0x80) {
t = lstrlenA((val)->hintName);
if (!ASN1BEREncExplicitTag(enc, 0x80000000, &nLenOff0))
return 0;
if (!ASN1DEREncCharString(enc, 0x1b, t, (val)->hintName))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x40) {
if (!ASN1BEREncExplicitTag(enc, 0x80000001, &nLenOff0))
return 0;
if (!ASN1DEREncOctetString(enc, 0x4, ((val)->hintAddress).length, ((val)->hintAddress).value))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if (!ASN1BEREncEndOfContents(enc, nLenOff))
return 0;
return 1;
}
static int ASN1CALL ASN1Dec_NegHints(ASN1decoding_t dec, ASN1uint32_t tag, NegHints *val)
{
ASN1decoding_t dd;
ASN1octet_t *di;
ASN1uint32_t t;
ASN1decoding_t dd0;
ASN1octet_t *di0;
if (!ASN1BERDecExplicitTag(dec, tag ? tag : 0x10, &dd, &di))
return 0;
ZeroMemory((val)->o, 1);
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000000) {
(val)->o[0] |= 0x80;
if (!ASN1BERDecExplicitTag(dd, 0x80000000, &dd0, &di0))
return 0;
if (!ASN1BERDecZeroCharString(dd0, 0x1b, &(val)->hintName))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000001) {
(val)->o[0] |= 0x40;
if (!ASN1BERDecExplicitTag(dd, 0x80000001, &dd0, &di0))
return 0;
if (!ASN1BERDecOctetString(dd0, 0x4, &(val)->hintAddress))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
if (!ASN1BERDecEndOfContents(dec, dd, di))
return 0;
return 1;
}
static void ASN1CALL ASN1Free_NegHints(NegHints *val)
{
if (val) {
if ((val)->o[0] & 0x80) {
ASN1ztcharstring_free((val)->hintName);
}
if ((val)->o[0] & 0x40) {
ASN1octetstring_free(&(val)->hintAddress);
}
}
}
static int ASN1CALL ASN1Enc_NegTokenInit(ASN1encoding_t enc, ASN1uint32_t tag, NegTokenInit *val)
{
ASN1uint32_t nLenOff;
ASN1uint32_t nLenOff0;
ASN1uint32_t r;
if (!ASN1BEREncExplicitTag(enc, tag ? tag : 0x10, &nLenOff))
return 0;
if ((val)->o[0] & 0x80) {
if (!ASN1BEREncExplicitTag(enc, 0x80000000, &nLenOff0))
return 0;
if (!ASN1Enc_MechTypeList(enc, 0, &(val)->mechTypes))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x40) {
r = ((val)->reqFlags).length;
ASN1BEREncRemoveZeroBits(&r, ((val)->reqFlags).value);
if (!ASN1BEREncExplicitTag(enc, 0x80000001, &nLenOff0))
return 0;
if (!ASN1DEREncBitString(enc, 0x3, r, ((val)->reqFlags).value))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x20) {
if (!ASN1BEREncExplicitTag(enc, 0x80000002, &nLenOff0))
return 0;
if (!ASN1DEREncOctetString(enc, 0x4, ((val)->mechToken).length, ((val)->mechToken).value))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x10) {
if (!ASN1BEREncExplicitTag(enc, 0x80000003, &nLenOff0))
return 0;
if (!ASN1Enc_NegHints(enc, 0, &(val)->negHints))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x8) {
if (!ASN1BEREncExplicitTag(enc, 0x80000004, &nLenOff0))
return 0;
if (!ASN1DEREncOctetString(enc, 0x4, ((val)->mechListMIC).length, ((val)->mechListMIC).value))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if (!ASN1BEREncEndOfContents(enc, nLenOff))
return 0;
return 1;
}
static int ASN1CALL ASN1Dec_NegTokenInit(ASN1decoding_t dec, ASN1uint32_t tag, NegTokenInit *val)
{
ASN1decoding_t dd;
ASN1octet_t *di;
ASN1uint32_t t;
ASN1decoding_t dd0;
ASN1octet_t *di0;
if (!ASN1BERDecExplicitTag(dec, tag ? tag : 0x10, &dd, &di))
return 0;
ZeroMemory((val)->o, 1);
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000000) {
(val)->o[0] |= 0x80;
if (!ASN1BERDecExplicitTag(dd, 0x80000000, &dd0, &di0))
return 0;
if (!ASN1Dec_MechTypeList(dd0, 0, &(val)->mechTypes))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000001) {
(val)->o[0] |= 0x40;
if (!ASN1BERDecExplicitTag(dd, 0x80000001, &dd0, &di0))
return 0;
if (!ASN1BERDecBitString(dd0, 0x3, &(val)->reqFlags))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000002) {
(val)->o[0] |= 0x20;
if (!ASN1BERDecExplicitTag(dd, 0x80000002, &dd0, &di0))
return 0;
if (!ASN1BERDecOctetString(dd0, 0x4, &(val)->mechToken))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000003) {
(val)->o[0] |= 0x10;
if (!ASN1BERDecExplicitTag(dd, 0x80000003, &dd0, &di0))
return 0;
if (!ASN1Dec_NegHints(dd0, 0, &(val)->negHints))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000004) {
(val)->o[0] |= 0x8;
if (!ASN1BERDecExplicitTag(dd, 0x80000004, &dd0, &di0))
return 0;
if (!ASN1BERDecOctetString(dd0, 0x4, &(val)->mechListMIC))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
if (!ASN1BERDecEndOfContents(dec, dd, di))
return 0;
return 1;
}
static void ASN1CALL ASN1Free_NegTokenInit(NegTokenInit *val)
{
if (val) {
if ((val)->o[0] & 0x80) {
ASN1Free_MechTypeList(&(val)->mechTypes);
}
if ((val)->o[0] & 0x40) {
ASN1bitstring_free(&(val)->reqFlags);
}
if ((val)->o[0] & 0x20) {
ASN1octetstring_free(&(val)->mechToken);
}
if ((val)->o[0] & 0x10) {
ASN1Free_NegHints(&(val)->negHints);
}
if ((val)->o[0] & 0x8) {
ASN1octetstring_free(&(val)->mechListMIC);
}
}
}
static int ASN1CALL ASN1Enc_NegTokenInit2(ASN1encoding_t enc, ASN1uint32_t tag, NegTokenInit2 *val)
{
ASN1uint32_t nLenOff;
ASN1uint32_t nLenOff0;
ASN1uint32_t r;
if (!ASN1BEREncExplicitTag(enc, tag ? tag : 0x10, &nLenOff))
return 0;
if ((val)->o[0] & 0x80) {
if (!ASN1BEREncExplicitTag(enc, 0x80000000, &nLenOff0))
return 0;
if (!ASN1Enc_MechTypeList(enc, 0, &(val)->mechTypes))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x40) {
r = ((val)->reqFlags).length;
ASN1BEREncRemoveZeroBits(&r, ((val)->reqFlags).value);
if (!ASN1BEREncExplicitTag(enc, 0x80000001, &nLenOff0))
return 0;
if (!ASN1DEREncBitString(enc, 0x3, r, ((val)->reqFlags).value))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x20) {
if (!ASN1BEREncExplicitTag(enc, 0x80000002, &nLenOff0))
return 0;
if (!ASN1DEREncOctetString(enc, 0x4, ((val)->mechToken).length, ((val)->mechToken).value))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x10) {
if (!ASN1BEREncExplicitTag(enc, 0x80000003, &nLenOff0))
return 0;
if (!ASN1DEREncOctetString(enc, 0x4, ((val)->mechListMIC).length, ((val)->mechListMIC).value))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x8) {
if (!ASN1BEREncExplicitTag(enc, 0x80000004, &nLenOff0))
return 0;
if (!ASN1Enc_NegHints(enc, 0, &(val)->negHints))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if (!ASN1BEREncEndOfContents(enc, nLenOff))
return 0;
return 1;
}
static int ASN1CALL ASN1Dec_NegTokenInit2(ASN1decoding_t dec, ASN1uint32_t tag, NegTokenInit2 *val)
{
ASN1decoding_t dd;
ASN1octet_t *di;
ASN1uint32_t t;
ASN1decoding_t dd0;
ASN1octet_t *di0;
if (!ASN1BERDecExplicitTag(dec, tag ? tag : 0x10, &dd, &di))
return 0;
ZeroMemory((val)->o, 1);
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000000) {
(val)->o[0] |= 0x80;
if (!ASN1BERDecExplicitTag(dd, 0x80000000, &dd0, &di0))
return 0;
if (!ASN1Dec_MechTypeList(dd0, 0, &(val)->mechTypes))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000001) {
(val)->o[0] |= 0x40;
if (!ASN1BERDecExplicitTag(dd, 0x80000001, &dd0, &di0))
return 0;
if (!ASN1BERDecBitString(dd0, 0x3, &(val)->reqFlags))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000002) {
(val)->o[0] |= 0x20;
if (!ASN1BERDecExplicitTag(dd, 0x80000002, &dd0, &di0))
return 0;
if (!ASN1BERDecOctetString(dd0, 0x4, &(val)->mechToken))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000003) {
(val)->o[0] |= 0x10;
if (!ASN1BERDecExplicitTag(dd, 0x80000003, &dd0, &di0))
return 0;
if (!ASN1BERDecOctetString(dd0, 0x4, &(val)->mechListMIC))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000004) {
(val)->o[0] |= 0x8;
if (!ASN1BERDecExplicitTag(dd, 0x80000004, &dd0, &di0))
return 0;
if (!ASN1Dec_NegHints(dd0, 0, &(val)->negHints))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
if (!ASN1BERDecEndOfContents(dec, dd, di))
return 0;
return 1;
}
static void ASN1CALL ASN1Free_NegTokenInit2(NegTokenInit2 *val)
{
if (val) {
if ((val)->o[0] & 0x80) {
ASN1Free_MechTypeList(&(val)->mechTypes);
}
if ((val)->o[0] & 0x40) {
ASN1bitstring_free(&(val)->reqFlags);
}
if ((val)->o[0] & 0x20) {
ASN1octetstring_free(&(val)->mechToken);
}
if ((val)->o[0] & 0x10) {
ASN1octetstring_free(&(val)->mechListMIC);
}
if ((val)->o[0] & 0x8) {
ASN1Free_NegHints(&(val)->negHints);
}
}
}
static int ASN1CALL ASN1Enc_NegTokenTarg(ASN1encoding_t enc, ASN1uint32_t tag, NegTokenTarg *val)
{
ASN1uint32_t nLenOff;
ASN1uint32_t nLenOff0;
if (!ASN1BEREncExplicitTag(enc, tag ? tag : 0x10, &nLenOff))
return 0;
if ((val)->o[0] & 0x80) {
if (!ASN1BEREncExplicitTag(enc, 0x80000000, &nLenOff0))
return 0;
if (!ASN1BEREncU32(enc, 0xa, (val)->negResult))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x40) {
if (!ASN1BEREncExplicitTag(enc, 0x80000001, &nLenOff0))
return 0;
if (!ASN1BEREncObjectIdentifier(enc, 0x6, &(val)->supportedMech))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x20) {
if (!ASN1BEREncExplicitTag(enc, 0x80000002, &nLenOff0))
return 0;
if (!ASN1DEREncOctetString(enc, 0x4, ((val)->responseToken).length, ((val)->responseToken).value))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if ((val)->o[0] & 0x10) {
if (!ASN1BEREncExplicitTag(enc, 0x80000003, &nLenOff0))
return 0;
if (!ASN1DEREncOctetString(enc, 0x4, ((val)->mechListMIC).length, ((val)->mechListMIC).value))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
}
if (!ASN1BEREncEndOfContents(enc, nLenOff))
return 0;
return 1;
}
static int ASN1CALL ASN1Dec_NegTokenTarg(ASN1decoding_t dec, ASN1uint32_t tag, NegTokenTarg *val)
{
ASN1decoding_t dd;
ASN1octet_t *di;
ASN1uint32_t t;
ASN1decoding_t dd0;
ASN1octet_t *di0;
if (!ASN1BERDecExplicitTag(dec, tag ? tag : 0x10, &dd, &di))
return 0;
ZeroMemory((val)->o, 1);
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000000) {
(val)->o[0] |= 0x80;
if (!ASN1BERDecExplicitTag(dd, 0x80000000, &dd0, &di0))
return 0;
if (!ASN1BERDecU32Val(dd0, 0xa, (ASN1uint32_t *) &(val)->negResult))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000001) {
(val)->o[0] |= 0x40;
if (!ASN1BERDecExplicitTag(dd, 0x80000001, &dd0, &di0))
return 0;
if (!ASN1BERDecObjectIdentifier(dd0, 0x6, &(val)->supportedMech))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000002) {
(val)->o[0] |= 0x20;
if (!ASN1BERDecExplicitTag(dd, 0x80000002, &dd0, &di0))
return 0;
if (!ASN1BERDecOctetString(dd0, 0x4, &(val)->responseToken))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
ASN1BERDecPeekTag(dd, &t);
if (t == 0x80000003) {
(val)->o[0] |= 0x10;
if (!ASN1BERDecExplicitTag(dd, 0x80000003, &dd0, &di0))
return 0;
if (!ASN1BERDecOctetString(dd0, 0x4, &(val)->mechListMIC))
return 0;
if (!ASN1BERDecEndOfContents(dd, dd0, di0))
return 0;
}
if (!ASN1BERDecEndOfContents(dec, dd, di))
return 0;
return 1;
}
static void ASN1CALL ASN1Free_NegTokenTarg(NegTokenTarg *val)
{
if (val) {
if ((val)->o[0] & 0x40) {
ASN1objectidentifier_free(&(val)->supportedMech);
}
if ((val)->o[0] & 0x20) {
ASN1octetstring_free(&(val)->responseToken);
}
if ((val)->o[0] & 0x10) {
ASN1octetstring_free(&(val)->mechListMIC);
}
}
}
static int ASN1CALL ASN1Enc_NegotiationToken(ASN1encoding_t enc, ASN1uint32_t tag, NegotiationToken *val)
{
ASN1uint32_t nLenOff0;
switch ((val)->choice) {
case 1:
if (!ASN1BEREncExplicitTag(enc, 0x80000000, &nLenOff0))
return 0;
if (!ASN1Enc_NegTokenInit(enc, 0, &(val)->u.negTokenInit))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
break;
case 2:
if (!ASN1BEREncExplicitTag(enc, 0x80000001, &nLenOff0))
return 0;
if (!ASN1Enc_NegTokenTarg(enc, 0, &(val)->u.negTokenTarg))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
break;
case 3:
if (!ASN1BEREncExplicitTag(enc, 0x80000002, &nLenOff0))
return 0;
if (!ASN1Enc_NegTokenInit2(enc, 0, &(val)->u.negTokenInit2))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff0))
return 0;
break;
}
return 1;
}
static int ASN1CALL ASN1Dec_NegotiationToken(ASN1decoding_t dec, ASN1uint32_t tag, NegotiationToken *val)
{
ASN1uint32_t t;
ASN1decoding_t dd0;
ASN1octet_t *di0;
if (!ASN1BERDecPeekTag(dec, &t))
return 0;
switch (t) {
case 0x80000000:
(val)->choice = 1;
if (!ASN1BERDecExplicitTag(dec, 0x80000000, &dd0, &di0))
return 0;
if (!ASN1Dec_NegTokenInit(dd0, 0, &(val)->u.negTokenInit))
return 0;
if (!ASN1BERDecEndOfContents(dec, dd0, di0))
return 0;
break;
case 0x80000001:
(val)->choice = 2;
if (!ASN1BERDecExplicitTag(dec, 0x80000001, &dd0, &di0))
return 0;
if (!ASN1Dec_NegTokenTarg(dd0, 0, &(val)->u.negTokenTarg))
return 0;
if (!ASN1BERDecEndOfContents(dec, dd0, di0))
return 0;
break;
case 0x80000002:
(val)->choice = 3;
if (!ASN1BERDecExplicitTag(dec, 0x80000002, &dd0, &di0))
return 0;
if (!ASN1Dec_NegTokenInit2(dd0, 0, &(val)->u.negTokenInit2))
return 0;
if (!ASN1BERDecEndOfContents(dec, dd0, di0))
return 0;
break;
default:
ASN1DecSetError(dec, ASN1_ERR_CORRUPT);
return 0;
}
return 1;
}
static void ASN1CALL ASN1Free_NegotiationToken(NegotiationToken *val)
{
if (val) {
switch ((val)->choice) {
case 1:
ASN1Free_NegTokenInit(&(val)->u.negTokenInit);
break;
case 2:
ASN1Free_NegTokenTarg(&(val)->u.negTokenTarg);
break;
case 3:
ASN1Free_NegTokenInit2(&(val)->u.negTokenInit2);
break;
}
}
}
static int ASN1CALL ASN1Enc_InitialNegToken(ASN1encoding_t enc, ASN1uint32_t tag, InitialNegToken *val)
{
ASN1uint32_t nLenOff;
if (!ASN1BEREncExplicitTag(enc, tag ? tag : 0x40000000, &nLenOff))
return 0;
if (!ASN1BEREncObjectIdentifier(enc, 0x6, &(val)->spnegoMech))
return 0;
if (!ASN1Enc_NegotiationToken(enc, 0, &(val)->negToken))
return 0;
if (!ASN1BEREncEndOfContents(enc, nLenOff))
return 0;
return 1;
}
static int ASN1CALL ASN1Dec_InitialNegToken(ASN1decoding_t dec, ASN1uint32_t tag, InitialNegToken *val)
{
ASN1decoding_t dd;
ASN1octet_t *di;
if (!ASN1BERDecExplicitTag(dec, tag ? tag : 0x40000000, &dd, &di))
return 0;
if (!ASN1BERDecObjectIdentifier(dd, 0x6, &(val)->spnegoMech))
return 0;
if (!ASN1Dec_NegotiationToken(dd, 0, &(val)->negToken))
return 0;
if (!ASN1BERDecEndOfContents(dec, dd, di))
return 0;
return 1;
}
static void ASN1CALL ASN1Free_InitialNegToken(InitialNegToken *val)
{
if (val) {
ASN1objectidentifier_free(&(val)->spnegoMech);
ASN1Free_NegotiationToken(&(val)->negToken);
}
}