root/fs/cifs/asn1.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. asn1_open
  2. asn1_octet_decode
  3. asn1_enum_decode
  4. asn1_tag_decode
  5. asn1_id_decode
  6. asn1_length_decode
  7. asn1_header_decode
  8. asn1_eoc_decode
  9. asn1_subid_decode
  10. asn1_oid_decode
  11. compare_oid
  12. decode_negTokenInit

   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
  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  * ASN.1 context.
  81  */
  82 struct 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  */
  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 /* will be needed later by spnego decoding/encoding of ntlmssp */
 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)++; /* 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 
 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         /* don't trust len bigger than ctx buffer */
 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         /* 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 
 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 /* static unsigned char asn1_null_decode(struct asn1_ctx *ctx,
 268                                       unsigned char *eoc)
 269 {
 270         ctx->pointer = eoc;
 271         return 1;
 272 }
 273 
 274 static 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 
 301 static 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 
 332 static 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 
 363 static unsigned char
 364 asn1_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 
 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         /* 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 
 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         /* BB check for endian conversion issues here */
 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         /* 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 (%d) exit 0\n",
 534                          cls, con, tag, end, *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 (%d) exit 1\n",
 545                          cls, con, tag, end, *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 (%d) exit 0\n",
 556                          cls, con, tag, end, *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 end = %p (%d) exit 1\n",
 568                          cls, con, tag, end, *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 }

/* [<][>][^][v][top][bottom][index][help] */