/* 
 * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in
 * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich
 *      
 * Copyright (c) 2000 RP Internet (www.rpi.net.au).
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifs_debug.h"
#include "cifsproto.h"

/*****************************************************************************
 *
 * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse)
 *
 *****************************************************************************/

/* Class */
#define ASN1_UNI	0	/* Universal */
#define ASN1_APL	1	/* Application */
#define ASN1_CTX	2	/* Context */
#define ASN1_PRV	3	/* Private */

/* Tag */
#define ASN1_EOC	0	/* End Of Contents or N/A */
#define ASN1_BOL	1	/* Boolean */
#define ASN1_INT	2	/* Integer */
#define ASN1_BTS	3	/* Bit String */
#define ASN1_OTS	4	/* Octet String */
#define ASN1_NUL	5	/* Null */
#define ASN1_OJI	6	/* Object Identifier  */
#define ASN1_OJD	7	/* Object Description */
#define ASN1_EXT	8	/* External */
#define ASN1_SEQ	16	/* Sequence */
#define ASN1_SET	17	/* Set */
#define ASN1_NUMSTR	18	/* Numerical String */
#define ASN1_PRNSTR	19	/* Printable String */
#define ASN1_TEXSTR	20	/* Teletext String */
#define ASN1_VIDSTR	21	/* Video String */
#define ASN1_IA5STR	22	/* IA5 String */
#define ASN1_UNITIM	23	/* Universal Time */
#define ASN1_GENTIM	24	/* General Time */
#define ASN1_GRASTR	25	/* Graphical String */
#define ASN1_VISSTR	26	/* Visible String */
#define ASN1_GENSTR	27	/* General String */

/* Primitive / Constructed methods*/
#define ASN1_PRI	0	/* Primitive */
#define ASN1_CON	1	/* Constructed */

/*
 * Error codes.
 */
#define ASN1_ERR_NOERROR		0
#define ASN1_ERR_DEC_EMPTY		2
#define ASN1_ERR_DEC_EOC_MISMATCH	3
#define ASN1_ERR_DEC_LENGTH_MISMATCH	4
#define ASN1_ERR_DEC_BADVALUE		5

#define SPNEGO_OID_LEN 7
#define NTLMSSP_OID_LEN  10
static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };

/* 
 * ASN.1 context.
 */
struct asn1_ctx {
	int error;		/* Error condition */
	unsigned char *pointer;	/* Octet just to be decoded */
	unsigned char *begin;	/* First octet */
	unsigned char *end;	/* Octet after last octet */
};

/*
 * Octet string (not null terminated)
 */
struct asn1_octstr {
	unsigned char *data;
	unsigned int len;
};

static void
asn1_open(struct asn1_ctx *ctx, unsigned char *buf, unsigned int len)
{
	ctx->begin = buf;
	ctx->end = buf + len;
	ctx->pointer = buf;
	ctx->error = ASN1_ERR_NOERROR;
}

static unsigned char
asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch)
{
	if (ctx->pointer >= ctx->end) {
		ctx->error = ASN1_ERR_DEC_EMPTY;
		return 0;
	}
	*ch = *(ctx->pointer)++;
	return 1;
}

static unsigned char
asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
{
	unsigned char ch;

	*tag = 0;

	do {
		if (!asn1_octet_decode(ctx, &ch))
			return 0;
		*tag <<= 7;
		*tag |= ch & 0x7F;
	} while ((ch & 0x80) == 0x80);
	return 1;
}

static unsigned char
asn1_id_decode(struct asn1_ctx *ctx,
	       unsigned int *cls, unsigned int *con, unsigned int *tag)
{
	unsigned char ch;

	if (!asn1_octet_decode(ctx, &ch))
		return 0;

	*cls = (ch & 0xC0) >> 6;
	*con = (ch & 0x20) >> 5;
	*tag = (ch & 0x1F);

	if (*tag == 0x1F) {
		if (!asn1_tag_decode(ctx, tag))
			return 0;
	}
	return 1;
}

static unsigned char
asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len)
{
	unsigned char ch, cnt;

	if (!asn1_octet_decode(ctx, &ch))
		return 0;

	if (ch == 0x80)
		*def = 0;
	else {
		*def = 1;

		if (ch < 0x80)
			*len = ch;
		else {
			cnt = (unsigned char) (ch & 0x7F);
			*len = 0;

			while (cnt > 0) {
				if (!asn1_octet_decode(ctx, &ch))
					return 0;
				*len <<= 8;
				*len |= ch;
				cnt--;
			}
		}
	}
	return 1;
}

static unsigned char
asn1_header_decode(struct asn1_ctx *ctx,
		   unsigned char **eoc,
		   unsigned int *cls, unsigned int *con, unsigned int *tag)
{
	unsigned int def, len;

	if (!asn1_id_decode(ctx, cls, con, tag))
		return 0;

	if (!asn1_length_decode(ctx, &def, &len))
		return 0;

	if (def)
		*eoc = ctx->pointer + len;
	else
		*eoc = NULL;
	return 1;
}

static unsigned char
asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
{
	unsigned char ch;

	if (eoc == NULL) {
		if (!asn1_octet_decode(ctx, &ch))
			return 0;

		if (ch != 0x00) {
			ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
			return 0;
		}

		if (!asn1_octet_decode(ctx, &ch))
			return 0;

		if (ch != 0x00) {
			ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
			return 0;
		}
		return 1;
	} else {
		if (ctx->pointer != eoc) {
			ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;
			return 0;
		}
		return 1;
	}
}

/* static unsigned char asn1_null_decode(struct asn1_ctx *ctx,
				      unsigned char *eoc)
{
	ctx->pointer = eoc;
	return 1;
}

static unsigned char asn1_long_decode(struct asn1_ctx *ctx,
				      unsigned char *eoc, long *integer)
{
	unsigned char ch;
	unsigned int len;

	if (!asn1_octet_decode(ctx, &ch))
		return 0;

	*integer = (signed char) ch;
	len = 1;

	while (ctx->pointer < eoc) {
		if (++len > sizeof(long)) {
			ctx->error = ASN1_ERR_DEC_BADVALUE;
			return 0;
		}

		if (!asn1_octet_decode(ctx, &ch))
			return 0;

		*integer <<= 8;
		*integer |= ch;
	}
	return 1;
}

static unsigned char asn1_uint_decode(struct asn1_ctx *ctx,
				      unsigned char *eoc,
				      unsigned int *integer)
{
	unsigned char ch;
	unsigned int len;

	if (!asn1_octet_decode(ctx, &ch))
		return 0;

	*integer = ch;
	if (ch == 0)
		len = 0;
	else
		len = 1;

	while (ctx->pointer < eoc) {
		if (++len > sizeof(unsigned int)) {
			ctx->error = ASN1_ERR_DEC_BADVALUE;
			return 0;
		}

		if (!asn1_octet_decode(ctx, &ch))
			return 0;

		*integer <<= 8;
		*integer |= ch;
	}
	return 1;
}

static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
				       unsigned char *eoc,
				       unsigned long *integer)
{
	unsigned char ch;
	unsigned int len;

	if (!asn1_octet_decode(ctx, &ch))
		return 0;

	*integer = ch;
	if (ch == 0)
		len = 0;
	else
		len = 1;

	while (ctx->pointer < eoc) {
		if (++len > sizeof(unsigned long)) {
			ctx->error = ASN1_ERR_DEC_BADVALUE;
			return 0;
		}

		if (!asn1_octet_decode(ctx, &ch))
			return 0;

		*integer <<= 8;
		*integer |= ch;
	}
	return 1;
} 

static unsigned char
asn1_octets_decode(struct asn1_ctx *ctx,
		   unsigned char *eoc,
		   unsigned char **octets, unsigned int *len)
{
	unsigned char *ptr;

	*len = 0;

	*octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
	if (*octets == NULL) {
		return 0;
	}

	ptr = *octets;
	while (ctx->pointer < eoc) {
		if (!asn1_octet_decode(ctx, (unsigned char *) ptr++)) {
			kfree(*octets);
			*octets = NULL;
			return 0;
		}
		(*len)++;
	}
	return 1;
} */

static unsigned char
asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid)
{
	unsigned char ch;

	*subid = 0;

	do {
		if (!asn1_octet_decode(ctx, &ch))
			return 0;

		*subid <<= 7;
		*subid |= ch & 0x7F;
	} while ((ch & 0x80) == 0x80);
	return 1;
}

static int 
asn1_oid_decode(struct asn1_ctx *ctx,
		unsigned char *eoc, unsigned long **oid, unsigned int *len)
{
	unsigned long subid;
	unsigned int size;
	unsigned long *optr;

	size = eoc - ctx->pointer + 1;
	*oid = kmalloc(size * sizeof (unsigned long), GFP_ATOMIC);
	if (*oid == NULL) {
		return 0;
	}

	optr = *oid;

	if (!asn1_subid_decode(ctx, &subid)) {
		kfree(*oid);
		*oid = NULL;
		return 0;
	}

	if (subid < 40) {
		optr[0] = 0;
		optr[1] = subid;
	} else if (subid < 80) {
		optr[0] = 1;
		optr[1] = subid - 40;
	} else {
		optr[0] = 2;
		optr[1] = subid - 80;
	}

	*len = 2;
	optr += 2;

	while (ctx->pointer < eoc) {
		if (++(*len) > size) {
			ctx->error = ASN1_ERR_DEC_BADVALUE;
			kfree(*oid);
			*oid = NULL;
			return 0;
		}

		if (!asn1_subid_decode(ctx, optr++)) {
			kfree(*oid);
			*oid = NULL;
			return 0;
		}
	}
	return 1;
}

static int
compare_oid(unsigned long *oid1, unsigned int oid1len,
	    unsigned long *oid2, unsigned int oid2len)
{
	unsigned int i;

	if (oid1len != oid2len)
		return 0;
	else {
		for (i = 0; i < oid1len; i++) {
			if (oid1[i] != oid2[i])
				return 0;
		}
		return 1;
	}
}

	/* BB check for endian conversion issues here */

int
decode_negTokenInit(unsigned char *security_blob, int length,
		    enum securityEnum *secType)
{
	struct asn1_ctx ctx;
	unsigned char *end;
	unsigned char *sequence_end;
	unsigned long *oid = NULL;
	unsigned int cls, con, tag, oidlen, rc;
	int use_ntlmssp = FALSE;

	*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default */

	/* cifs_dump_mem(" Received SecBlob ", security_blob, length); */

	asn1_open(&ctx, security_blob, length);

	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
		cFYI(1, ("Error decoding negTokenInit header "));
		return 0;
	} else if ((cls != ASN1_APL) || (con != ASN1_CON)
		   || (tag != ASN1_EOC)) {
		cFYI(1, ("cls = %d con = %d tag = %d", cls, con, tag));
		return 0;
	} else {
		/*      remember to free obj->oid */
		rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
		if (rc) {
			if ((tag == ASN1_OJI) && (cls == ASN1_PRI)) {
				rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
				if (rc) {
					rc = compare_oid(oid, oidlen,
							 SPNEGO_OID,
							 SPNEGO_OID_LEN);
					kfree(oid);
				}
			} else
				rc = 0;
		}

		if (!rc) {
			cFYI(1, ("Error decoding negTokenInit header"));
			return 0;
		}

		if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
			cFYI(1, ("Error decoding negTokenInit "));
			return 0;
		} else if ((cls != ASN1_CTX) || (con != ASN1_CON)
			   || (tag != ASN1_EOC)) {
			cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 0",
			      cls, con, tag, end, *end));
			return 0;
		}

		if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
			cFYI(1, ("Error decoding negTokenInit "));
			return 0;
		} else if ((cls != ASN1_UNI) || (con != ASN1_CON)
			   || (tag != ASN1_SEQ)) {
			cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 1",
			      cls, con, tag, end, *end));
			return 0;
		}

		if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
			cFYI(1, ("Error decoding 2nd part of negTokenInit "));
			return 0;
		} else if ((cls != ASN1_CTX) || (con != ASN1_CON)
			   || (tag != ASN1_EOC)) {
			cFYI(1,
			     ("cls = %d con = %d tag = %d end = %p (%d) exit 0",
			      cls, con, tag, end, *end));
			return 0;
		}

		if (asn1_header_decode
		    (&ctx, &sequence_end, &cls, &con, &tag) == 0) {
			cFYI(1, ("Error decoding 2nd part of negTokenInit "));
			return 0;
		} else if ((cls != ASN1_UNI) || (con != ASN1_CON)
			   || (tag != ASN1_SEQ)) {
			cFYI(1,
			     ("cls = %d con = %d tag = %d end = %p (%d) exit 1",
			      cls, con, tag, end, *end));
			return 0;
		}

		while (!asn1_eoc_decode(&ctx, sequence_end)) {
			rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
			if (!rc) {
				cFYI(1,
				     ("Error 1 decoding negTokenInit header exit 2"));
				return 0;
			}
			if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
				rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
				if(rc) {		
					cFYI(1,
					  ("OID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx",
					   oidlen, *oid, *(oid + 1), *(oid + 2),
					   *(oid + 3)));
					rc = compare_oid(oid, oidlen, NTLMSSP_OID,
						 NTLMSSP_OID_LEN);
					if(oid)
						kfree(oid);
					if (rc)
						use_ntlmssp = TRUE;
				}
			} else {
				cFYI(1,("This should be an oid what is going on? "));
			}
		}

		if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
			cFYI(1,
			     ("Error decoding last part of negTokenInit exit 3"));
			return 0;
		} else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {	/* tag = 3 indicating mechListMIC */
			cFYI(1,
			     ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
			      cls, con, tag, end, *end));
			return 0;
		}
		if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
			cFYI(1,
			     ("Error decoding last part of negTokenInit exit 5"));
			return 0;
		} else if ((cls != ASN1_UNI) || (con != ASN1_CON)
			   || (tag != ASN1_SEQ)) {
			cFYI(1,
			     ("Exit 6 cls = %d con = %d tag = %d end = %p (%d)",
			      cls, con, tag, end, *end));
		}

		if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
			cFYI(1,
			     ("Error decoding last part of negTokenInit exit 7"));
			return 0;
		} else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
			cFYI(1,
			     ("Exit 8 cls = %d con = %d tag = %d end = %p (%d)",
			      cls, con, tag, end, *end));
			return 0;
		}
		if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
			cFYI(1,
			     ("Error decoding last part of negTokenInit exit 9"));
			return 0;
		} else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
			   || (tag != ASN1_GENSTR)) {
			cFYI(1,
			     ("Exit 10 cls = %d con = %d tag = %d end = %p (%d)",
			      cls, con, tag, end, *end));
			return 0;
		}
		cFYI(1, ("Need to call asn1_octets_decode() function for this %s", ctx.pointer));	/* is this UTF-8 or ASCII? */
	}

	/* if (use_kerberos) 
	   *secType = Kerberos 
	   else */
	if (use_ntlmssp) {
		*secType = NTLMSSP;
	}

	return 1;
}
