This source file includes following definitions.
- asn1_open
- asn1_octet_decode
- asn1_enum_decode
- asn1_tag_decode
- asn1_id_decode
- asn1_length_decode
- asn1_header_decode
- asn1_eoc_decode
- asn1_subid_decode
- asn1_oid_decode
- compare_oid
- decode_negTokenInit
1
2
3
4
5
6
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
22
23
24
25
26 #define ASN1_UNI 0
27 #define ASN1_APL 1
28 #define ASN1_CTX 2
29 #define ASN1_PRV 3
30
31
32 #define ASN1_EOC 0
33 #define ASN1_BOL 1
34 #define ASN1_INT 2
35 #define ASN1_BTS 3
36 #define ASN1_OTS 4
37 #define ASN1_NUL 5
38 #define ASN1_OJI 6
39 #define ASN1_OJD 7
40 #define ASN1_EXT 8
41 #define ASN1_ENUM 10
42 #define ASN1_SEQ 16
43 #define ASN1_SET 17
44 #define ASN1_NUMSTR 18
45 #define ASN1_PRNSTR 19
46 #define ASN1_TEXSTR 20
47 #define ASN1_VIDSTR 21
48 #define ASN1_IA5STR 22
49 #define ASN1_UNITIM 23
50 #define ASN1_GENTIM 24
51 #define ASN1_GRASTR 25
52 #define ASN1_VISSTR 26
53 #define ASN1_GENSTR 27
54
55
56 #define ASN1_PRI 0
57 #define ASN1_CON 1
58
59
60
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
81
82 struct asn1_ctx {
83 int error;
84 unsigned char *pointer;
85 unsigned char *begin;
86 unsigned char *end;
87 };
88
89
90
91
92 struct asn1_octstr {
93 unsigned char *data;
94 unsigned int len;
95 };
96
97 static void
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
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
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)++;
129 if ((ch) == ASN1_ENUM)
130 *val = *(++(ctx->pointer));
131 else
132 return 0;
133
134 ctx->pointer++;
135 return 1;
136 }
137 #endif
138
139 static unsigned char
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
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
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
205 if (*len > ctx->end - ctx->pointer)
206 return 0;
207
208 return 1;
209 }
210
211 static unsigned char
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
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
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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389 static unsigned char
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
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
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
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
481
482 int
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
493
494 asn1_open(&ctx, security_blob, length);
495
496
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
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
522 if (!rc) {
523 cifs_dbg(FYI, "Error decoding negTokenInit header\n");
524 return 0;
525 }
526
527
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 (%d) exit 0\n",
534 cls, con, tag, end, *end);
535 return 0;
536 }
537
538
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 (%d) exit 1\n",
545 cls, con, tag, end, *end);
546 return 0;
547 }
548
549
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 (%d) exit 0\n",
556 cls, con, tag, end, *end);
557 return 0;
558 }
559
560
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 end = %p (%d) exit 1\n",
568 cls, con, tag, end, *end);
569 return 0;
570 }
571
572
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
608
609
610
611 return 1;
612 }