^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2000 RP Internet (www.rpi.net.au).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "cifspdu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "cifsglob.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "cifs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "cifsproto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* Class */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define ASN1_UNI 0 /* Universal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define ASN1_APL 1 /* Application */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define ASN1_CTX 2 /* Context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define ASN1_PRV 3 /* Private */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* Tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define ASN1_EOC 0 /* End Of Contents or N/A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define ASN1_BOL 1 /* Boolean */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define ASN1_INT 2 /* Integer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define ASN1_BTS 3 /* Bit String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ASN1_OTS 4 /* Octet String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define ASN1_NUL 5 /* Null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define ASN1_OJI 6 /* Object Identifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define ASN1_OJD 7 /* Object Description */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ASN1_EXT 8 /* External */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ASN1_ENUM 10 /* Enumerated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define ASN1_SEQ 16 /* Sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ASN1_SET 17 /* Set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define ASN1_NUMSTR 18 /* Numerical String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define ASN1_PRNSTR 19 /* Printable String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define ASN1_TEXSTR 20 /* Teletext String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define ASN1_VIDSTR 21 /* Video String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define ASN1_IA5STR 22 /* IA5 String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define ASN1_UNITIM 23 /* Universal Time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define ASN1_GENTIM 24 /* General Time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define ASN1_GRASTR 25 /* Graphical String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define ASN1_VISSTR 26 /* Visible String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define ASN1_GENSTR 27 /* General String */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Primitive / Constructed methods*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define ASN1_PRI 0 /* Primitive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define ASN1_CON 1 /* Constructed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Error codes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define ASN1_ERR_NOERROR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define ASN1_ERR_DEC_EMPTY 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define ASN1_ERR_DEC_EOC_MISMATCH 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define ASN1_ERR_DEC_LENGTH_MISMATCH 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define ASN1_ERR_DEC_BADVALUE 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define SPNEGO_OID_LEN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define NTLMSSP_OID_LEN 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define KRB5_OID_LEN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define KRB5U2U_OID_LEN 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define MSKRB5_OID_LEN 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static unsigned long KRB5U2U_OID[8] = { 1, 2, 840, 113554, 1, 2, 2, 3 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * ASN.1 context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct asn1_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int error; /* Error condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned char *pointer; /* Octet just to be decoded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) unsigned char *begin; /* First octet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned char *end; /* Octet after last octet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Octet string (not null terminated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct asn1_octstr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) asn1_open(struct asn1_ctx *ctx, unsigned char *buf, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ctx->begin = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ctx->end = buf + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ctx->pointer = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ctx->error = ASN1_ERR_NOERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (ctx->pointer >= ctx->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ctx->error = ASN1_ERR_DEC_EMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) *ch = *(ctx->pointer)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #if 0 /* will be needed later by spnego decoding/encoding of ntlmssp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) asn1_enum_decode(struct asn1_ctx *ctx, __le32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (ctx->pointer >= ctx->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ctx->error = ASN1_ERR_DEC_EMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to length octet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if ((ch) == ASN1_ENUM) /* if ch value is ENUM, 0xa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *val = *(++(ctx->pointer)); /* value has enum value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ctx->pointer++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *tag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *tag <<= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) *tag |= ch & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) } while ((ch & 0x80) == 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) asn1_id_decode(struct asn1_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) unsigned int *cls, unsigned int *con, unsigned int *tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) *cls = (ch & 0xC0) >> 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) *con = (ch & 0x20) >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *tag = (ch & 0x1F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (*tag == 0x1F) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (!asn1_tag_decode(ctx, tag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned char ch, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (ch == 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *def = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) *def = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (ch < 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *len = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) cnt = (unsigned char) (ch & 0x7F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) while (cnt > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) *len <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) *len |= ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* don't trust len bigger than ctx buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (*len > ctx->end - ctx->pointer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) asn1_header_decode(struct asn1_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unsigned char **eoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) unsigned int *cls, unsigned int *con, unsigned int *tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) unsigned int def = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) unsigned int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!asn1_id_decode(ctx, cls, con, tag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (!asn1_length_decode(ctx, &def, &len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* primitive shall be definite, indefinite shall be constructed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (*con == ASN1_PRI && !def)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (def)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) *eoc = ctx->pointer + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) *eoc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) unsigned char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (eoc == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (ch != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (ch != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (ctx->pointer != eoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* static unsigned char asn1_null_decode(struct asn1_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) unsigned char *eoc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ctx->pointer = eoc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static unsigned char asn1_long_decode(struct asn1_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) unsigned char *eoc, long *integer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) unsigned char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) *integer = (signed char) ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) while (ctx->pointer < eoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (++len > sizeof(long)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ctx->error = ASN1_ERR_DEC_BADVALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) *integer <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) *integer |= ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static unsigned char asn1_uint_decode(struct asn1_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) unsigned char *eoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) unsigned int *integer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) unsigned char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) *integer = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (ch == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) while (ctx->pointer < eoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (++len > sizeof(unsigned int)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) ctx->error = ASN1_ERR_DEC_BADVALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) *integer <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) *integer |= ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) unsigned char *eoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsigned long *integer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) unsigned char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) *integer = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (ch == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) while (ctx->pointer < eoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (++len > sizeof(unsigned long)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ctx->error = ASN1_ERR_DEC_BADVALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) *integer <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) *integer |= ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) asn1_octets_decode(struct asn1_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) unsigned char *eoc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) unsigned char **octets, unsigned int *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) unsigned char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) *len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (*octets == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ptr = *octets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) while (ctx->pointer < eoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (!asn1_octet_decode(ctx, (unsigned char *) ptr++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) kfree(*octets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) *octets = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) (*len)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) } */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static unsigned char
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) unsigned char ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) *subid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (!asn1_octet_decode(ctx, &ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *subid <<= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) *subid |= ch & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) } while ((ch & 0x80) == 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) asn1_oid_decode(struct asn1_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) unsigned char *eoc, unsigned long **oid, unsigned int *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) unsigned long subid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) unsigned long *optr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) size = eoc - ctx->pointer + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* first subid actually encodes first two subids */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (size < 2 || size > UINT_MAX/sizeof(unsigned long))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) *oid = kmalloc_array(size, sizeof(unsigned long), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (*oid == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) optr = *oid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (!asn1_subid_decode(ctx, &subid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) kfree(*oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) *oid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (subid < 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) optr[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) optr[1] = subid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) } else if (subid < 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) optr[0] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) optr[1] = subid - 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) optr[0] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) optr[1] = subid - 80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) *len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) optr += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) while (ctx->pointer < eoc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (++(*len) > size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ctx->error = ASN1_ERR_DEC_BADVALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) kfree(*oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) *oid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!asn1_subid_decode(ctx, optr++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) kfree(*oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) *oid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) compare_oid(unsigned long *oid1, unsigned int oid1len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) unsigned long *oid2, unsigned int oid2len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (oid1len != oid2len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) for (i = 0; i < oid1len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (oid1[i] != oid2[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* BB check for endian conversion issues here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) decode_negTokenInit(unsigned char *security_blob, int length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct asn1_ctx ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) unsigned char *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) unsigned char *sequence_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) unsigned long *oid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) unsigned int cls, con, tag, oidlen, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) asn1_open(&ctx, security_blob, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* GSSAPI header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) cifs_dbg(FYI, "Error decoding negTokenInit header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) } else if ((cls != ASN1_APL) || (con != ASN1_CON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) || (tag != ASN1_EOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) cifs_dbg(FYI, "cls = %d con = %d tag = %d\n", cls, con, tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* Check for SPNEGO OID -- remember to free obj->oid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if ((tag == ASN1_OJI) && (con == ASN1_PRI) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) (cls == ASN1_UNI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) rc = compare_oid(oid, oidlen, SPNEGO_OID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) SPNEGO_OID_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) kfree(oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* SPNEGO OID not present or garbled -- bail out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) cifs_dbg(FYI, "Error decoding negTokenInit header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* SPNEGO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) cifs_dbg(FYI, "Error decoding negTokenInit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) || (tag != ASN1_EOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) cifs_dbg(FYI, "cls = %d con = %d tag = %d end = %p exit 0\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) cls, con, tag, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /* negTokenInit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) cifs_dbg(FYI, "Error decoding negTokenInit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) || (tag != ASN1_SEQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) cifs_dbg(FYI, "cls = %d con = %d tag = %d end = %p exit 1\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) cls, con, tag, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /* sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) cifs_dbg(FYI, "Error decoding 2nd part of negTokenInit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) || (tag != ASN1_EOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) cifs_dbg(FYI, "cls = %d con = %d tag = %d end = %p exit 0\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) cls, con, tag, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* sequence of */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (asn1_header_decode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) (&ctx, &sequence_end, &cls, &con, &tag) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) cifs_dbg(FYI, "Error decoding 2nd part of negTokenInit\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) || (tag != ASN1_SEQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) cifs_dbg(FYI, "cls = %d con = %d tag = %d sequence_end = %p exit 1\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) cls, con, tag, sequence_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /* list of security mechanisms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) while (!asn1_eoc_decode(&ctx, sequence_end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) cifs_dbg(FYI, "Error decoding negTokenInit hdr exit2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) cifs_dbg(FYI, "OID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) oidlen, *oid, *(oid + 1), *(oid + 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) *(oid + 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (compare_oid(oid, oidlen, MSKRB5_OID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) MSKRB5_OID_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) server->sec_mskerberos = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) else if (compare_oid(oid, oidlen, KRB5U2U_OID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) KRB5U2U_OID_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) server->sec_kerberosu2u = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) else if (compare_oid(oid, oidlen, KRB5_OID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) KRB5_OID_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) server->sec_kerberos = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) else if (compare_oid(oid, oidlen, NTLMSSP_OID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) NTLMSSP_OID_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) server->sec_ntlmssp = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) kfree(oid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) cifs_dbg(FYI, "Should be an oid what is going on?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * We currently ignore anything at the end of the SPNEGO blob after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * the mechTypes have been parsed, since none of that info is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * used at the moment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }