1/*
2 * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in
3 * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich
4 *
5 * Copyright (c) 2000 RP Internet (www.rpi.net.au).
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 */
19
20#include <linux/module.h>
21#include <linux/types.h>
22#include <linux/kernel.h>
23#include <linux/mm.h>
24#include <linux/slab.h>
25#include "cifspdu.h"
26#include "cifsglob.h"
27#include "cifs_debug.h"
28#include "cifsproto.h"
29
30/*****************************************************************************
31 *
32 * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse)
33 *
34 *****************************************************************************/
35
36/* Class */
37#define ASN1_UNI	0	/* Universal */
38#define ASN1_APL	1	/* Application */
39#define ASN1_CTX	2	/* Context */
40#define ASN1_PRV	3	/* Private */
41
42/* Tag */
43#define ASN1_EOC	0	/* End Of Contents or N/A */
44#define ASN1_BOL	1	/* Boolean */
45#define ASN1_INT	2	/* Integer */
46#define ASN1_BTS	3	/* Bit String */
47#define ASN1_OTS	4	/* Octet String */
48#define ASN1_NUL	5	/* Null */
49#define ASN1_OJI	6	/* Object Identifier  */
50#define ASN1_OJD	7	/* Object Description */
51#define ASN1_EXT	8	/* External */
52#define ASN1_ENUM	10	/* Enumerated */
53#define ASN1_SEQ	16	/* Sequence */
54#define ASN1_SET	17	/* Set */
55#define ASN1_NUMSTR	18	/* Numerical String */
56#define ASN1_PRNSTR	19	/* Printable String */
57#define ASN1_TEXSTR	20	/* Teletext String */
58#define ASN1_VIDSTR	21	/* Video String */
59#define ASN1_IA5STR	22	/* IA5 String */
60#define ASN1_UNITIM	23	/* Universal Time */
61#define ASN1_GENTIM	24	/* General Time */
62#define ASN1_GRASTR	25	/* Graphical String */
63#define ASN1_VISSTR	26	/* Visible String */
64#define ASN1_GENSTR	27	/* General String */
65
66/* Primitive / Constructed methods*/
67#define ASN1_PRI	0	/* Primitive */
68#define ASN1_CON	1	/* Constructed */
69
70/*
71 * Error codes.
72 */
73#define ASN1_ERR_NOERROR		0
74#define ASN1_ERR_DEC_EMPTY		2
75#define ASN1_ERR_DEC_EOC_MISMATCH	3
76#define ASN1_ERR_DEC_LENGTH_MISMATCH	4
77#define ASN1_ERR_DEC_BADVALUE		5
78
79#define SPNEGO_OID_LEN 7
80#define NTLMSSP_OID_LEN  10
81#define KRB5_OID_LEN  7
82#define KRB5U2U_OID_LEN  8
83#define MSKRB5_OID_LEN  7
84static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
85static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
86static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 };
87static unsigned long KRB5U2U_OID[8] = { 1, 2, 840, 113554, 1, 2, 2, 3 };
88static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 };
89
90/*
91 * ASN.1 context.
92 */
93struct asn1_ctx {
94	int error;		/* Error condition */
95	unsigned char *pointer;	/* Octet just to be decoded */
96	unsigned char *begin;	/* First octet */
97	unsigned char *end;	/* Octet after last octet */
98};
99
100/*
101 * Octet string (not null terminated)
102 */
103struct asn1_octstr {
104	unsigned char *data;
105	unsigned int len;
106};
107
108static void
109asn1_open(struct asn1_ctx *ctx, unsigned char *buf, unsigned int len)
110{
111	ctx->begin = buf;
112	ctx->end = buf + len;
113	ctx->pointer = buf;
114	ctx->error = ASN1_ERR_NOERROR;
115}
116
117static unsigned char
118asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch)
119{
120	if (ctx->pointer >= ctx->end) {
121		ctx->error = ASN1_ERR_DEC_EMPTY;
122		return 0;
123	}
124	*ch = *(ctx->pointer)++;
125	return 1;
126}
127
128#if 0 /* will be needed later by spnego decoding/encoding of ntlmssp */
129static unsigned char
130asn1_enum_decode(struct asn1_ctx *ctx, __le32 *val)
131{
132	unsigned char ch;
133
134	if (ctx->pointer >= ctx->end) {
135		ctx->error = ASN1_ERR_DEC_EMPTY;
136		return 0;
137	}
138
139	ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to length octet */
140	if ((ch) == ASN1_ENUM)  /* if ch value is ENUM, 0xa */
141		*val = *(++(ctx->pointer)); /* value has enum value */
142	else
143		return 0;
144
145	ctx->pointer++;
146	return 1;
147}
148#endif
149
150static unsigned char
151asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
152{
153	unsigned char ch;
154
155	*tag = 0;
156
157	do {
158		if (!asn1_octet_decode(ctx, &ch))
159			return 0;
160		*tag <<= 7;
161		*tag |= ch & 0x7F;
162	} while ((ch & 0x80) == 0x80);
163	return 1;
164}
165
166static unsigned char
167asn1_id_decode(struct asn1_ctx *ctx,
168	       unsigned int *cls, unsigned int *con, unsigned int *tag)
169{
170	unsigned char ch;
171
172	if (!asn1_octet_decode(ctx, &ch))
173		return 0;
174
175	*cls = (ch & 0xC0) >> 6;
176	*con = (ch & 0x20) >> 5;
177	*tag = (ch & 0x1F);
178
179	if (*tag == 0x1F) {
180		if (!asn1_tag_decode(ctx, tag))
181			return 0;
182	}
183	return 1;
184}
185
186static unsigned char
187asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len)
188{
189	unsigned char ch, cnt;
190
191	if (!asn1_octet_decode(ctx, &ch))
192		return 0;
193
194	if (ch == 0x80)
195		*def = 0;
196	else {
197		*def = 1;
198
199		if (ch < 0x80)
200			*len = ch;
201		else {
202			cnt = (unsigned char) (ch & 0x7F);
203			*len = 0;
204
205			while (cnt > 0) {
206				if (!asn1_octet_decode(ctx, &ch))
207					return 0;
208				*len <<= 8;
209				*len |= ch;
210				cnt--;
211			}
212		}
213	}
214
215	/* don't trust len bigger than ctx buffer */
216	if (*len > ctx->end - ctx->pointer)
217		return 0;
218
219	return 1;
220}
221
222static unsigned char
223asn1_header_decode(struct asn1_ctx *ctx,
224		   unsigned char **eoc,
225		   unsigned int *cls, unsigned int *con, unsigned int *tag)
226{
227	unsigned int def = 0;
228	unsigned int len = 0;
229
230	if (!asn1_id_decode(ctx, cls, con, tag))
231		return 0;
232
233	if (!asn1_length_decode(ctx, &def, &len))
234		return 0;
235
236	/* primitive shall be definite, indefinite shall be constructed */
237	if (*con == ASN1_PRI && !def)
238		return 0;
239
240	if (def)
241		*eoc = ctx->pointer + len;
242	else
243		*eoc = NULL;
244	return 1;
245}
246
247static unsigned char
248asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
249{
250	unsigned char ch;
251
252	if (eoc == NULL) {
253		if (!asn1_octet_decode(ctx, &ch))
254			return 0;
255
256		if (ch != 0x00) {
257			ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
258			return 0;
259		}
260
261		if (!asn1_octet_decode(ctx, &ch))
262			return 0;
263
264		if (ch != 0x00) {
265			ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
266			return 0;
267		}
268		return 1;
269	} else {
270		if (ctx->pointer != eoc) {
271			ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;
272			return 0;
273		}
274		return 1;
275	}
276}
277
278/* static unsigned char asn1_null_decode(struct asn1_ctx *ctx,
279				      unsigned char *eoc)
280{
281	ctx->pointer = eoc;
282	return 1;
283}
284
285static unsigned char asn1_long_decode(struct asn1_ctx *ctx,
286				      unsigned char *eoc, long *integer)
287{
288	unsigned char ch;
289	unsigned int len;
290
291	if (!asn1_octet_decode(ctx, &ch))
292		return 0;
293
294	*integer = (signed char) ch;
295	len = 1;
296
297	while (ctx->pointer < eoc) {
298		if (++len > sizeof(long)) {
299			ctx->error = ASN1_ERR_DEC_BADVALUE;
300			return 0;
301		}
302
303		if (!asn1_octet_decode(ctx, &ch))
304			return 0;
305
306		*integer <<= 8;
307		*integer |= ch;
308	}
309	return 1;
310}
311
312static unsigned char asn1_uint_decode(struct asn1_ctx *ctx,
313				      unsigned char *eoc,
314				      unsigned int *integer)
315{
316	unsigned char ch;
317	unsigned int len;
318
319	if (!asn1_octet_decode(ctx, &ch))
320		return 0;
321
322	*integer = ch;
323	if (ch == 0)
324		len = 0;
325	else
326		len = 1;
327
328	while (ctx->pointer < eoc) {
329		if (++len > sizeof(unsigned int)) {
330			ctx->error = ASN1_ERR_DEC_BADVALUE;
331			return 0;
332		}
333
334		if (!asn1_octet_decode(ctx, &ch))
335			return 0;
336
337		*integer <<= 8;
338		*integer |= ch;
339	}
340	return 1;
341}
342
343static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
344				       unsigned char *eoc,
345				       unsigned long *integer)
346{
347	unsigned char ch;
348	unsigned int len;
349
350	if (!asn1_octet_decode(ctx, &ch))
351		return 0;
352
353	*integer = ch;
354	if (ch == 0)
355		len = 0;
356	else
357		len = 1;
358
359	while (ctx->pointer < eoc) {
360		if (++len > sizeof(unsigned long)) {
361			ctx->error = ASN1_ERR_DEC_BADVALUE;
362			return 0;
363		}
364
365		if (!asn1_octet_decode(ctx, &ch))
366			return 0;
367
368		*integer <<= 8;
369		*integer |= ch;
370	}
371	return 1;
372}
373
374static unsigned char
375asn1_octets_decode(struct asn1_ctx *ctx,
376		   unsigned char *eoc,
377		   unsigned char **octets, unsigned int *len)
378{
379	unsigned char *ptr;
380
381	*len = 0;
382
383	*octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
384	if (*octets == NULL) {
385		return 0;
386	}
387
388	ptr = *octets;
389	while (ctx->pointer < eoc) {
390		if (!asn1_octet_decode(ctx, (unsigned char *) ptr++)) {
391			kfree(*octets);
392			*octets = NULL;
393			return 0;
394		}
395		(*len)++;
396	}
397	return 1;
398} */
399
400static unsigned char
401asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid)
402{
403	unsigned char ch;
404
405	*subid = 0;
406
407	do {
408		if (!asn1_octet_decode(ctx, &ch))
409			return 0;
410
411		*subid <<= 7;
412		*subid |= ch & 0x7F;
413	} while ((ch & 0x80) == 0x80);
414	return 1;
415}
416
417static int
418asn1_oid_decode(struct asn1_ctx *ctx,
419		unsigned char *eoc, unsigned long **oid, unsigned int *len)
420{
421	unsigned long subid;
422	unsigned int size;
423	unsigned long *optr;
424
425	size = eoc - ctx->pointer + 1;
426
427	/* first subid actually encodes first two subids */
428	if (size < 2 || size > UINT_MAX/sizeof(unsigned long))
429		return 0;
430
431	*oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
432	if (*oid == NULL)
433		return 0;
434
435	optr = *oid;
436
437	if (!asn1_subid_decode(ctx, &subid)) {
438		kfree(*oid);
439		*oid = NULL;
440		return 0;
441	}
442
443	if (subid < 40) {
444		optr[0] = 0;
445		optr[1] = subid;
446	} else if (subid < 80) {
447		optr[0] = 1;
448		optr[1] = subid - 40;
449	} else {
450		optr[0] = 2;
451		optr[1] = subid - 80;
452	}
453
454	*len = 2;
455	optr += 2;
456
457	while (ctx->pointer < eoc) {
458		if (++(*len) > size) {
459			ctx->error = ASN1_ERR_DEC_BADVALUE;
460			kfree(*oid);
461			*oid = NULL;
462			return 0;
463		}
464
465		if (!asn1_subid_decode(ctx, optr++)) {
466			kfree(*oid);
467			*oid = NULL;
468			return 0;
469		}
470	}
471	return 1;
472}
473
474static int
475compare_oid(unsigned long *oid1, unsigned int oid1len,
476	    unsigned long *oid2, unsigned int oid2len)
477{
478	unsigned int i;
479
480	if (oid1len != oid2len)
481		return 0;
482	else {
483		for (i = 0; i < oid1len; i++) {
484			if (oid1[i] != oid2[i])
485				return 0;
486		}
487		return 1;
488	}
489}
490
491	/* BB check for endian conversion issues here */
492
493int
494decode_negTokenInit(unsigned char *security_blob, int length,
495		    struct TCP_Server_Info *server)
496{
497	struct asn1_ctx ctx;
498	unsigned char *end;
499	unsigned char *sequence_end;
500	unsigned long *oid = NULL;
501	unsigned int cls, con, tag, oidlen, rc;
502
503	/* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
504
505	asn1_open(&ctx, security_blob, length);
506
507	/* GSSAPI header */
508	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
509		cifs_dbg(FYI, "Error decoding negTokenInit header\n");
510		return 0;
511	} else if ((cls != ASN1_APL) || (con != ASN1_CON)
512		   || (tag != ASN1_EOC)) {
513		cifs_dbg(FYI, "cls = %d con = %d tag = %d\n", cls, con, tag);
514		return 0;
515	}
516
517	/* Check for SPNEGO OID -- remember to free obj->oid */
518	rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
519	if (rc) {
520		if ((tag == ASN1_OJI) && (con == ASN1_PRI) &&
521		    (cls == ASN1_UNI)) {
522			rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
523			if (rc) {
524				rc = compare_oid(oid, oidlen, SPNEGO_OID,
525						 SPNEGO_OID_LEN);
526				kfree(oid);
527			}
528		} else
529			rc = 0;
530	}
531
532	/* SPNEGO OID not present or garbled -- bail out */
533	if (!rc) {
534		cifs_dbg(FYI, "Error decoding negTokenInit header\n");
535		return 0;
536	}
537
538	/* SPNEGO */
539	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
540		cifs_dbg(FYI, "Error decoding negTokenInit\n");
541		return 0;
542	} else if ((cls != ASN1_CTX) || (con != ASN1_CON)
543		   || (tag != ASN1_EOC)) {
544		cifs_dbg(FYI, "cls = %d con = %d tag = %d end = %p (%d) exit 0\n",
545			 cls, con, tag, end, *end);
546		return 0;
547	}
548
549	/* negTokenInit */
550	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
551		cifs_dbg(FYI, "Error decoding negTokenInit\n");
552		return 0;
553	} else if ((cls != ASN1_UNI) || (con != ASN1_CON)
554		   || (tag != ASN1_SEQ)) {
555		cifs_dbg(FYI, "cls = %d con = %d tag = %d end = %p (%d) exit 1\n",
556			 cls, con, tag, end, *end);
557		return 0;
558	}
559
560	/* sequence */
561	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
562		cifs_dbg(FYI, "Error decoding 2nd part of negTokenInit\n");
563		return 0;
564	} else if ((cls != ASN1_CTX) || (con != ASN1_CON)
565		   || (tag != ASN1_EOC)) {
566		cifs_dbg(FYI, "cls = %d con = %d tag = %d end = %p (%d) exit 0\n",
567			 cls, con, tag, end, *end);
568		return 0;
569	}
570
571	/* sequence of */
572	if (asn1_header_decode
573	    (&ctx, &sequence_end, &cls, &con, &tag) == 0) {
574		cifs_dbg(FYI, "Error decoding 2nd part of negTokenInit\n");
575		return 0;
576	} else if ((cls != ASN1_UNI) || (con != ASN1_CON)
577		   || (tag != ASN1_SEQ)) {
578		cifs_dbg(FYI, "cls = %d con = %d tag = %d end = %p (%d) exit 1\n",
579			 cls, con, tag, end, *end);
580		return 0;
581	}
582
583	/* list of security mechanisms */
584	while (!asn1_eoc_decode(&ctx, sequence_end)) {
585		rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
586		if (!rc) {
587			cifs_dbg(FYI, "Error decoding negTokenInit hdr exit2\n");
588			return 0;
589		}
590		if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
591			if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) {
592
593				cifs_dbg(FYI, "OID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx\n",
594					 oidlen, *oid, *(oid + 1), *(oid + 2),
595					 *(oid + 3));
596
597				if (compare_oid(oid, oidlen, MSKRB5_OID,
598						MSKRB5_OID_LEN))
599					server->sec_mskerberos = true;
600				else if (compare_oid(oid, oidlen, KRB5U2U_OID,
601						     KRB5U2U_OID_LEN))
602					server->sec_kerberosu2u = true;
603				else if (compare_oid(oid, oidlen, KRB5_OID,
604						     KRB5_OID_LEN))
605					server->sec_kerberos = true;
606				else if (compare_oid(oid, oidlen, NTLMSSP_OID,
607						     NTLMSSP_OID_LEN))
608					server->sec_ntlmssp = true;
609
610				kfree(oid);
611			}
612		} else {
613			cifs_dbg(FYI, "Should be an oid what is going on?\n");
614		}
615	}
616
617	/*
618	 * We currently ignore anything at the end of the SPNEGO blob after
619	 * the mechTypes have been parsed, since none of that info is
620	 * used at the moment.
621	 */
622	return 1;
623}
624