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 73static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; 74static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; 75static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 }; 76static unsigned long KRB5U2U_OID[8] = { 1, 2, 840, 113554, 1, 2, 2, 3 }; 77static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 }; 78 79/* 80 * ASN.1 context. 81 */ 82struct 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 */ 92struct asn1_octstr { 93 unsigned char *data; 94 unsigned int len; 95}; 96 97static void 98asn1_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 106static unsigned char 107asn1_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 */ 118static unsigned char 119asn1_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 139static unsigned char 140asn1_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 155static unsigned char 156asn1_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 175static unsigned char 176asn1_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 211static unsigned char 212asn1_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 236static unsigned char 237asn1_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 274static 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 301static 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 332static 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 363static unsigned char 364asn1_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 389static unsigned char 390asn1_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 406static int 407asn1_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 463static int 464compare_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 482int 483decode_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