/* 
 * 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 = 0; 
	unsigned int len = 0;

	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);
					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;
}
