/*
 * 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/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
#define KRB5_OID_LEN  7
#define MSKRB5_OID_LEN  7
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 };
static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 };
static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 };

/*
 * 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--;
			}
		}
	}

	/* don't trust len bigger than ctx buffer */
	if (*len > ctx->end - ctx->pointer)
		return 0;

	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;

	/* primitive shall be definite, indefinite shall be constructed */
	if (*con == ASN1_PRI && !def)
		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;

	/* first subid actually encodes first two subids */
	if (size < 2 || size > ULONG_MAX/sizeof(unsigned long))
		return 0;

	*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;
	bool use_ntlmssp = false;
	bool use_kerberos = 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 decoding negTokenInit hdr exit2"));
				return 0;
			}
			if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
				if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) {

					cFYI(1,
					  ("OID len = %d oid = 0x%lx 0x%lx "
					   "0x%lx 0x%lx",
					   oidlen, *oid, *(oid + 1),
					   *(oid + 2), *(oid + 3)));

					if (compare_oid(oid, oidlen,
							MSKRB5_OID,
							MSKRB5_OID_LEN))
						use_kerberos = true;
					else if (compare_oid(oid, oidlen,
							     KRB5_OID,
							     KRB5_OID_LEN))
						use_kerberos = true;
					else if (compare_oid(oid, oidlen,
							     NTLMSSP_OID,
							     NTLMSSP_OID_LEN))
						use_ntlmssp = true;

					kfree(oid);
				}
			} else {
				cFYI(1, ("Should be an oid what is going on?"));
			}
		}

		if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
			cFYI(1,
			     ("Error decoding last part negTokenInit exit3"));
			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 negTokenInit exit5"));
			return 0;
		} else if ((cls != ASN1_UNI) || (con != ASN1_CON)
			   || (tag != ASN1_SEQ)) {
			cFYI(1, ("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 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 negTokenInit exit9"));
			return 0;
		} else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
			   || (tag != ASN1_GENSTR)) {
			cFYI(1,
			     ("Exit10 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 %s",
			 ctx.pointer));	/* is this UTF-8 or ASCII? */
	}

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

	return 1;
}
