Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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