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_SEQ 16 /* Sequence */ 53#define ASN1_SET 17 /* Set */ 54#define ASN1_NUMSTR 18 /* Numerical String */ 55#define ASN1_PRNSTR 19 /* Printable String */ 56#define ASN1_TEXSTR 20 /* Teletext String */ 57#define ASN1_VIDSTR 21 /* Video String */ 58#define ASN1_IA5STR 22 /* IA5 String */ 59#define ASN1_UNITIM 23 /* Universal Time */ 60#define ASN1_GENTIM 24 /* General Time */ 61#define ASN1_GRASTR 25 /* Graphical String */ 62#define ASN1_VISSTR 26 /* Visible String */ 63#define ASN1_GENSTR 27 /* General String */ 64 65/* Primitive / Constructed methods*/ 66#define ASN1_PRI 0 /* Primitive */ 67#define ASN1_CON 1 /* Constructed */ 68 69/* 70 * Error codes. 71 */ 72#define ASN1_ERR_NOERROR 0 73#define ASN1_ERR_DEC_EMPTY 2 74#define ASN1_ERR_DEC_EOC_MISMATCH 3 75#define ASN1_ERR_DEC_LENGTH_MISMATCH 4 76#define ASN1_ERR_DEC_BADVALUE 5 77 78#define SPNEGO_OID_LEN 7 79#define NTLMSSP_OID_LEN 10 80static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; 81static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; 82 83/* 84 * ASN.1 context. 85 */ 86struct asn1_ctx { 87 int error; /* Error condition */ 88 unsigned char *pointer; /* Octet just to be decoded */ 89 unsigned char *begin; /* First octet */ 90 unsigned char *end; /* Octet after last octet */ 91}; 92 93/* 94 * Octet string (not null terminated) 95 */ 96struct asn1_octstr { 97 unsigned char *data; 98 unsigned int len; 99}; 100 101static void 102asn1_open(struct asn1_ctx *ctx, unsigned char *buf, unsigned int len) 103{ 104 ctx->begin = buf; 105 ctx->end = buf + len; 106 ctx->pointer = buf; 107 ctx->error = ASN1_ERR_NOERROR; 108} 109 110static unsigned char 111asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch) 112{ 113 if (ctx->pointer >= ctx->end) { 114 ctx->error = ASN1_ERR_DEC_EMPTY; 115 return 0; 116 } 117 *ch = *(ctx->pointer)++; 118 return 1; 119} 120 121static unsigned char 122asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag) 123{ 124 unsigned char ch; 125 126 *tag = 0; 127 128 do { 129 if (!asn1_octet_decode(ctx, &ch)) 130 return 0; 131 *tag <<= 7; 132 *tag |= ch & 0x7F; 133 } while ((ch & 0x80) == 0x80); 134 return 1; 135} 136 137static unsigned char 138asn1_id_decode(struct asn1_ctx *ctx, 139 unsigned int *cls, unsigned int *con, unsigned int *tag) 140{ 141 unsigned char ch; 142 143 if (!asn1_octet_decode(ctx, &ch)) 144 return 0; 145 146 *cls = (ch & 0xC0) >> 6; 147 *con = (ch & 0x20) >> 5; 148 *tag = (ch & 0x1F); 149 150 if (*tag == 0x1F) { 151 if (!asn1_tag_decode(ctx, tag)) 152 return 0; 153 } 154 return 1; 155} 156 157static unsigned char 158asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len) 159{ 160 unsigned char ch, cnt; 161 162 if (!asn1_octet_decode(ctx, &ch)) 163 return 0; 164 165 if (ch == 0x80) 166 *def = 0; 167 else { 168 *def = 1; 169 170 if (ch < 0x80) 171 *len = ch; 172 else { 173 cnt = (unsigned char) (ch & 0x7F); 174 *len = 0; 175 176 while (cnt > 0) { 177 if (!asn1_octet_decode(ctx, &ch)) 178 return 0; 179 *len <<= 8; 180 *len |= ch; 181 cnt--; 182 } 183 } 184 } 185 return 1; 186} 187 188static unsigned char 189asn1_header_decode(struct asn1_ctx *ctx, 190 unsigned char **eoc, 191 unsigned int *cls, unsigned int *con, unsigned int *tag) 192{ 193 unsigned int def = 0; 194 unsigned int len = 0; 195 196 if (!asn1_id_decode(ctx, cls, con, tag)) 197 return 0; 198 199 if (!asn1_length_decode(ctx, &def, &len)) 200 return 0; 201 202 if (def) 203 *eoc = ctx->pointer + len; 204 else 205 *eoc = NULL; 206 return 1; 207} 208 209static unsigned char 210asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc) 211{ 212 unsigned char ch; 213 214 if (eoc == NULL) { 215 if (!asn1_octet_decode(ctx, &ch)) 216 return 0; 217 218 if (ch != 0x00) { 219 ctx->error = ASN1_ERR_DEC_EOC_MISMATCH; 220 return 0; 221 } 222 223 if (!asn1_octet_decode(ctx, &ch)) 224 return 0; 225 226 if (ch != 0x00) { 227 ctx->error = ASN1_ERR_DEC_EOC_MISMATCH; 228 return 0; 229 } 230 return 1; 231 } else { 232 if (ctx->pointer != eoc) { 233 ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH; 234 return 0; 235 } 236 return 1; 237 } 238} 239 240/* static unsigned char asn1_null_decode(struct asn1_ctx *ctx, 241 unsigned char *eoc) 242{ 243 ctx->pointer = eoc; 244 return 1; 245} 246 247static unsigned char asn1_long_decode(struct asn1_ctx *ctx, 248 unsigned char *eoc, long *integer) 249{ 250 unsigned char ch; 251 unsigned int len; 252 253 if (!asn1_octet_decode(ctx, &ch)) 254 return 0; 255 256 *integer = (signed char) ch; 257 len = 1; 258 259 while (ctx->pointer < eoc) { 260 if (++len > sizeof(long)) { 261 ctx->error = ASN1_ERR_DEC_BADVALUE; 262 return 0; 263 } 264 265 if (!asn1_octet_decode(ctx, &ch)) 266 return 0; 267 268 *integer <<= 8; 269 *integer |= ch; 270 } 271 return 1; 272} 273 274static unsigned char asn1_uint_decode(struct asn1_ctx *ctx, 275 unsigned char *eoc, 276 unsigned int *integer) 277{ 278 unsigned char ch; 279 unsigned int len; 280 281 if (!asn1_octet_decode(ctx, &ch)) 282 return 0; 283 284 *integer = ch; 285 if (ch == 0) 286 len = 0; 287 else 288 len = 1; 289 290 while (ctx->pointer < eoc) { 291 if (++len > sizeof(unsigned int)) { 292 ctx->error = ASN1_ERR_DEC_BADVALUE; 293 return 0; 294 } 295 296 if (!asn1_octet_decode(ctx, &ch)) 297 return 0; 298 299 *integer <<= 8; 300 *integer |= ch; 301 } 302 return 1; 303} 304 305static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx, 306 unsigned char *eoc, 307 unsigned long *integer) 308{ 309 unsigned char ch; 310 unsigned int len; 311 312 if (!asn1_octet_decode(ctx, &ch)) 313 return 0; 314 315 *integer = ch; 316 if (ch == 0) 317 len = 0; 318 else 319 len = 1; 320 321 while (ctx->pointer < eoc) { 322 if (++len > sizeof(unsigned long)) { 323 ctx->error = ASN1_ERR_DEC_BADVALUE; 324 return 0; 325 } 326 327 if (!asn1_octet_decode(ctx, &ch)) 328 return 0; 329 330 *integer <<= 8; 331 *integer |= ch; 332 } 333 return 1; 334} 335 336static unsigned char 337asn1_octets_decode(struct asn1_ctx *ctx, 338 unsigned char *eoc, 339 unsigned char **octets, unsigned int *len) 340{ 341 unsigned char *ptr; 342 343 *len = 0; 344 345 *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC); 346 if (*octets == NULL) { 347 return 0; 348 } 349 350 ptr = *octets; 351 while (ctx->pointer < eoc) { 352 if (!asn1_octet_decode(ctx, (unsigned char *) ptr++)) { 353 kfree(*octets); 354 *octets = NULL; 355 return 0; 356 } 357 (*len)++; 358 } 359 return 1; 360} */ 361 362static unsigned char 363asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid) 364{ 365 unsigned char ch; 366 367 *subid = 0; 368 369 do { 370 if (!asn1_octet_decode(ctx, &ch)) 371 return 0; 372 373 *subid <<= 7; 374 *subid |= ch & 0x7F; 375 } while ((ch & 0x80) == 0x80); 376 return 1; 377} 378 379static int 380asn1_oid_decode(struct asn1_ctx *ctx, 381 unsigned char *eoc, unsigned long **oid, unsigned int *len) 382{ 383 unsigned long subid; 384 unsigned int size; 385 unsigned long *optr; 386 387 size = eoc - ctx->pointer + 1; 388 *oid = kmalloc(size * sizeof (unsigned long), GFP_ATOMIC); 389 if (*oid == NULL) { 390 return 0; 391 } 392 393 optr = *oid; 394 395 if (!asn1_subid_decode(ctx, &subid)) { 396 kfree(*oid); 397 *oid = NULL; 398 return 0; 399 } 400 401 if (subid < 40) { 402 optr[0] = 0; 403 optr[1] = subid; 404 } else if (subid < 80) { 405 optr[0] = 1; 406 optr[1] = subid - 40; 407 } else { 408 optr[0] = 2; 409 optr[1] = subid - 80; 410 } 411 412 *len = 2; 413 optr += 2; 414 415 while (ctx->pointer < eoc) { 416 if (++(*len) > size) { 417 ctx->error = ASN1_ERR_DEC_BADVALUE; 418 kfree(*oid); 419 *oid = NULL; 420 return 0; 421 } 422 423 if (!asn1_subid_decode(ctx, optr++)) { 424 kfree(*oid); 425 *oid = NULL; 426 return 0; 427 } 428 } 429 return 1; 430} 431 432static int 433compare_oid(unsigned long *oid1, unsigned int oid1len, 434 unsigned long *oid2, unsigned int oid2len) 435{ 436 unsigned int i; 437 438 if (oid1len != oid2len) 439 return 0; 440 else { 441 for (i = 0; i < oid1len; i++) { 442 if (oid1[i] != oid2[i]) 443 return 0; 444 } 445 return 1; 446 } 447} 448 449 /* BB check for endian conversion issues here */ 450 451int 452decode_negTokenInit(unsigned char *security_blob, int length, 453 enum securityEnum *secType) 454{ 455 struct asn1_ctx ctx; 456 unsigned char *end; 457 unsigned char *sequence_end; 458 unsigned long *oid = NULL; 459 unsigned int cls, con, tag, oidlen, rc; 460 int use_ntlmssp = FALSE; 461 462 *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default */ 463 464 /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ 465 466 asn1_open(&ctx, security_blob, length); 467 468 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 469 cFYI(1, ("Error decoding negTokenInit header")); 470 return 0; 471 } else if ((cls != ASN1_APL) || (con != ASN1_CON) 472 || (tag != ASN1_EOC)) { 473 cFYI(1, ("cls = %d con = %d tag = %d", cls, con, tag)); 474 return 0; 475 } else { 476 /* remember to free obj->oid */ 477 rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); 478 if (rc) { 479 if ((tag == ASN1_OJI) && (cls == ASN1_PRI)) { 480 rc = asn1_oid_decode(&ctx, end, &oid, &oidlen); 481 if (rc) { 482 rc = compare_oid(oid, oidlen, 483 SPNEGO_OID, 484 SPNEGO_OID_LEN); 485 kfree(oid); 486 } 487 } else 488 rc = 0; 489 } 490 491 if (!rc) { 492 cFYI(1, ("Error decoding negTokenInit header")); 493 return 0; 494 } 495 496 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 497 cFYI(1, ("Error decoding negTokenInit")); 498 return 0; 499 } else if ((cls != ASN1_CTX) || (con != ASN1_CON) 500 || (tag != ASN1_EOC)) { 501 cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 0", 502 cls, con, tag, end, *end)); 503 return 0; 504 } 505 506 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 507 cFYI(1, ("Error decoding negTokenInit")); 508 return 0; 509 } else if ((cls != ASN1_UNI) || (con != ASN1_CON) 510 || (tag != ASN1_SEQ)) { 511 cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 1", 512 cls, con, tag, end, *end)); 513 return 0; 514 } 515 516 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 517 cFYI(1, ("Error decoding 2nd part of negTokenInit")); 518 return 0; 519 } else if ((cls != ASN1_CTX) || (con != ASN1_CON) 520 || (tag != ASN1_EOC)) { 521 cFYI(1, 522 ("cls = %d con = %d tag = %d end = %p (%d) exit 0", 523 cls, con, tag, end, *end)); 524 return 0; 525 } 526 527 if (asn1_header_decode 528 (&ctx, &sequence_end, &cls, &con, &tag) == 0) { 529 cFYI(1, ("Error decoding 2nd part of negTokenInit")); 530 return 0; 531 } else if ((cls != ASN1_UNI) || (con != ASN1_CON) 532 || (tag != ASN1_SEQ)) { 533 cFYI(1, 534 ("cls = %d con = %d tag = %d end = %p (%d) exit 1", 535 cls, con, tag, end, *end)); 536 return 0; 537 } 538 539 while (!asn1_eoc_decode(&ctx, sequence_end)) { 540 rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); 541 if (!rc) { 542 cFYI(1, 543 ("Error 1 decoding negTokenInit header exit 2")); 544 return 0; 545 } 546 if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { 547 rc = asn1_oid_decode(&ctx, end, &oid, &oidlen); 548 if(rc) { 549 cFYI(1, 550 ("OID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx", 551 oidlen, *oid, *(oid + 1), *(oid + 2), 552 *(oid + 3))); 553 rc = compare_oid(oid, oidlen, NTLMSSP_OID, 554 NTLMSSP_OID_LEN); 555 kfree(oid); 556 if (rc) 557 use_ntlmssp = TRUE; 558 } 559 } else { 560 cFYI(1,("This should be an oid what is going on? ")); 561 } 562 } 563 564 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 565 cFYI(1, 566 ("Error decoding last part of negTokenInit exit 3")); 567 return 0; 568 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { /* tag = 3 indicating mechListMIC */ 569 cFYI(1, 570 ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)", 571 cls, con, tag, end, *end)); 572 return 0; 573 } 574 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 575 cFYI(1, 576 ("Error decoding last part of negTokenInit exit 5")); 577 return 0; 578 } else if ((cls != ASN1_UNI) || (con != ASN1_CON) 579 || (tag != ASN1_SEQ)) { 580 cFYI(1, 581 ("Exit 6 cls = %d con = %d tag = %d end = %p (%d)", 582 cls, con, tag, end, *end)); 583 } 584 585 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 586 cFYI(1, 587 ("Error decoding last part of negTokenInit exit 7")); 588 return 0; 589 } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { 590 cFYI(1, 591 ("Exit 8 cls = %d con = %d tag = %d end = %p (%d)", 592 cls, con, tag, end, *end)); 593 return 0; 594 } 595 if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { 596 cFYI(1, 597 ("Error decoding last part of negTokenInit exit 9")); 598 return 0; 599 } else if ((cls != ASN1_UNI) || (con != ASN1_PRI) 600 || (tag != ASN1_GENSTR)) { 601 cFYI(1, 602 ("Exit 10 cls = %d con = %d tag = %d end = %p (%d)", 603 cls, con, tag, end, *end)); 604 return 0; 605 } 606 cFYI(1, ("Need to call asn1_octets_decode() function for this %s", ctx.pointer)); /* is this UTF-8 or ASCII? */ 607 } 608 609 /* if (use_kerberos) 610 *secType = Kerberos 611 else */ 612 if (use_ntlmssp) { 613 *secType = NTLMSSP; 614 } 615 616 return 1; 617} 618