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