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