Coverage Report

Created: 2026-09-03 07:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/lib/util/asn1.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
   simple ASN1 routines
4
   Copyright (C) Andrew Tridgell 2001
5
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
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
16
   You should have received a copy of the GNU General Public License
17
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#include "replace.h"
21
#include "system/locale.h"
22
#include "lib/util/asn1.h"
23
#include "lib/util/debug.h"
24
#include "lib/util/samba_util.h"
25
#include "lib/util/smb_strtox.h"
26
27
struct nesting {
28
  off_t start;
29
  size_t taglen; /* for parsing */
30
  struct nesting *next;
31
};
32
33
34
struct asn1_data {
35
  uint8_t *data;
36
  size_t length;
37
  off_t ofs;
38
  struct nesting *nesting;
39
  bool has_error;
40
  unsigned depth;
41
  unsigned max_depth;
42
};
43
44
/* allocate an asn1 structure */
45
struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx, unsigned max_depth)
46
4.13k
{
47
4.13k
  struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data);
48
4.13k
  if (ret == NULL) {
49
0
    DBG_ERR("asn1_init failed! out of memory\n");
50
0
    return ret;
51
0
  }
52
4.13k
  ret->max_depth = max_depth;
53
4.13k
  return ret;
54
4.13k
}
55
56
/* free an asn1 structure */
57
void asn1_free(struct asn1_data *data)
58
486
{
59
486
  talloc_free(data);
60
486
}
61
62
bool asn1_has_error(const struct asn1_data *data)
63
1.28k
{
64
1.28k
  return data->has_error;
65
1.28k
}
66
67
void asn1_set_error(struct asn1_data *data)
68
0
{
69
0
  data->has_error = true;
70
0
}
71
72
bool asn1_has_nesting(const struct asn1_data *data)
73
11
{
74
11
  return data->nesting != NULL;
75
11
}
76
77
off_t asn1_current_ofs(const struct asn1_data *data)
78
0
{
79
0
  return data->ofs;
80
0
}
81
82
/* write to the ASN1 buffer, advancing the buffer pointer */
83
bool asn1_write(struct asn1_data *data, const void *p, int _len)
84
0
{
85
0
  size_t len, ofs, newlen;
86
87
0
  if (data->has_error) return false;
88
89
0
  if (_len < 0) {
90
0
    goto error;
91
0
  }
92
0
  len = _len;
93
94
0
  if (data->ofs < 0) {
95
0
    goto error;
96
0
  }
97
0
  ofs = data->ofs;
98
99
0
  newlen = ofs + len;
100
0
  if (newlen < ofs) {
101
0
    goto error;
102
0
  }
103
104
0
  if (data->length < newlen) {
105
0
    uint8_t *newp;
106
0
    newp = talloc_realloc(data, data->data, uint8_t, newlen);
107
0
    if (!newp) {
108
0
      goto error;
109
0
    }
110
0
    data->data = newp;
111
0
    data->length = newlen;
112
0
  }
113
0
  if (len > 0) {
114
0
    memcpy(data->data + data->ofs, p, len);
115
0
    data->ofs += len;
116
0
  }
117
0
  return true;
118
0
error:
119
0
  data->has_error = true;
120
0
  return false;
121
0
}
122
123
/* useful fn for writing a uint8_t */
124
bool asn1_write_uint8(struct asn1_data *data, uint8_t v)
125
0
{
126
0
  return asn1_write(data, &v, 1);
127
0
}
128
129
/* push a tag onto the asn1 data buffer. Used for nested structures */
130
bool asn1_push_tag(struct asn1_data *data, uint8_t tag)
131
0
{
132
0
  struct nesting *nesting;
133
134
0
  if (!asn1_write_uint8(data, tag)) {
135
0
    return false;
136
0
  }
137
0
  nesting = talloc(data, struct nesting);
138
0
  if (!nesting) {
139
0
    data->has_error = true;
140
0
    return false;
141
0
  }
142
143
0
  nesting->start = data->ofs;
144
0
  nesting->next = data->nesting;
145
0
  data->nesting = nesting;
146
0
  return asn1_write_uint8(data, 0xff);
147
0
}
148
149
/* pop a tag */
150
bool asn1_pop_tag(struct asn1_data *data)
151
0
{
152
0
  struct nesting *nesting;
153
0
  size_t len;
154
155
0
  if (data->has_error) {
156
0
    return false;
157
0
  }
158
159
0
  nesting = data->nesting;
160
161
0
  if (!nesting) {
162
0
    data->has_error = true;
163
0
    return false;
164
0
  }
165
0
  len = data->ofs - (nesting->start+1);
166
  /* yes, this is ugly. We don't know in advance how many bytes the length
167
     of a tag will take, so we assumed 1 byte. If we were wrong then we
168
     need to correct our mistake */
169
0
  if (len > 0xFFFFFF) {
170
0
    data->data[nesting->start] = 0x84;
171
0
    if (!asn1_write_uint8(data, 0)) return false;
172
0
    if (!asn1_write_uint8(data, 0)) return false;
173
0
    if (!asn1_write_uint8(data, 0)) return false;
174
0
    if (!asn1_write_uint8(data, 0)) return false;
175
0
    memmove(data->data+nesting->start+5, data->data+nesting->start+1, len);
176
0
    data->data[nesting->start+1] = (len>>24) & 0xFF;
177
0
    data->data[nesting->start+2] = (len>>16) & 0xFF;
178
0
    data->data[nesting->start+3] = (len>>8) & 0xFF;
179
0
    data->data[nesting->start+4] = len&0xff;
180
0
  } else if (len > 0xFFFF) {
181
0
    data->data[nesting->start] = 0x83;
182
0
    if (!asn1_write_uint8(data, 0)) return false;
183
0
    if (!asn1_write_uint8(data, 0)) return false;
184
0
    if (!asn1_write_uint8(data, 0)) return false;
185
0
    memmove(data->data+nesting->start+4, data->data+nesting->start+1, len);
186
0
    data->data[nesting->start+1] = (len>>16) & 0xFF;
187
0
    data->data[nesting->start+2] = (len>>8) & 0xFF;
188
0
    data->data[nesting->start+3] = len&0xff;
189
0
  } else if (len > 255) {
190
0
    data->data[nesting->start] = 0x82;
191
0
    if (!asn1_write_uint8(data, 0)) return false;
192
0
    if (!asn1_write_uint8(data, 0)) return false;
193
0
    memmove(data->data+nesting->start+3, data->data+nesting->start+1, len);
194
0
    data->data[nesting->start+1] = len>>8;
195
0
    data->data[nesting->start+2] = len&0xff;
196
0
  } else if (len > 127) {
197
0
    data->data[nesting->start] = 0x81;
198
0
    if (!asn1_write_uint8(data, 0)) return false;
199
0
    memmove(data->data+nesting->start+2, data->data+nesting->start+1, len);
200
0
    data->data[nesting->start+1] = len;
201
0
  } else {
202
0
    data->data[nesting->start] = len;
203
0
  }
204
205
0
  data->nesting = nesting->next;
206
0
  talloc_free(nesting);
207
0
  return true;
208
0
}
209
210
/* "i" is the one's complement representation, as is the normal result of an
211
 * implicit signed->unsigned conversion */
212
213
static bool push_int_bigendian(struct asn1_data *data, unsigned int i, bool negative)
214
0
{
215
0
  uint8_t lowest = i & 0xFF;
216
217
0
  i = i >> 8;
218
0
  if (i != 0)
219
0
    if (!push_int_bigendian(data, i, negative))
220
0
      return false;
221
222
0
  if (data->nesting->start+1 == data->ofs) {
223
224
    /* We did not write anything yet, looking at the highest
225
     * valued byte */
226
227
0
    if (negative) {
228
      /* Don't write leading 0xff's */
229
0
      if (lowest == 0xFF)
230
0
        return true;
231
232
0
      if ((lowest & 0x80) == 0) {
233
        /* The only exception for a leading 0xff is if
234
         * the highest bit is 0, which would indicate
235
         * a positive value */
236
0
        if (!asn1_write_uint8(data, 0xff))
237
0
          return false;
238
0
      }
239
0
    } else {
240
0
      if (lowest & 0x80) {
241
        /* The highest bit of a positive integer is 1,
242
         * this would indicate a negative number. Push
243
         * a 0 to indicate a positive one */
244
0
        if (!asn1_write_uint8(data, 0))
245
0
          return false;
246
0
      }
247
0
    }
248
0
  }
249
250
0
  return asn1_write_uint8(data, lowest);
251
0
}
252
253
/* write an Integer without the tag framing. Needed for example for the LDAP
254
 * Abandon Operation */
255
256
bool asn1_write_implicit_Integer(struct asn1_data *data, int i)
257
0
{
258
0
  if (data->has_error) {
259
0
    return false;
260
0
  }
261
262
0
  if (i == -1) {
263
    /* -1 is special as it consists of all-0xff bytes. In
264
                    push_int_bigendian this is the only case that is not
265
                    properly handled, as all 0xff bytes would be handled as
266
                    leading ones to be ignored. */
267
0
    return asn1_write_uint8(data, 0xff);
268
0
  } else {
269
0
    return push_int_bigendian(data, i, i<0);
270
0
  }
271
0
}
272
273
274
/* write an integer */
275
bool asn1_write_Integer(struct asn1_data *data, int i)
276
0
{
277
0
  bool ok = !asn1_has_error(data);
278
0
  ok = ok && asn1_push_tag(data, ASN1_INTEGER);
279
0
  ok = ok && asn1_write_implicit_Integer(data, i);
280
0
  ok = ok && asn1_pop_tag(data);
281
0
  return ok;
282
0
}
283
284
/* write a BIT STRING */
285
bool asn1_write_BitString(struct asn1_data *data, const void *p, size_t length, uint8_t padding)
286
0
{
287
0
  bool ok = !asn1_has_error(data);
288
0
  ok = ok && asn1_push_tag(data, ASN1_BIT_STRING);
289
0
  ok = ok && asn1_write_uint8(data, padding);
290
0
  ok = ok && asn1_write(data, p, length);
291
0
  ok = ok && asn1_pop_tag(data);
292
0
  return ok;
293
0
}
294
295
bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID)
296
0
{
297
0
  unsigned long int v, v2;
298
0
  const char *p = (const char *)OID;
299
0
  char *newp;
300
0
  int i;
301
0
  int error = 0;
302
303
0
  if (!isdigit(*p)) return false;
304
0
  v = smb_strtoul(p, &newp, 10, &error, SMB_STR_STANDARD);
305
0
  if (newp[0] != '.' || error != 0) {
306
0
    return false;
307
0
  }
308
0
  p = newp + 1;
309
310
0
  if (!isdigit(*p)) return false;
311
0
  v2 = smb_strtoul(p, &newp, 10, &error, SMB_STR_STANDARD);
312
0
  if (newp[0] != '.' || error != 0) {
313
0
    return false;
314
0
  }
315
0
  p = newp + 1;
316
317
  /*the ber representation can't use more space than the string one */
318
0
  *blob = data_blob_talloc(mem_ctx, NULL, strlen(OID));
319
0
  if (!blob->data) return false;
320
321
0
  blob->data[0] = 40*v + v2;
322
323
0
  i = 1;
324
0
  while (*p) {
325
0
    if (!isdigit(*p)) return false;
326
0
    v = smb_strtoul(p, &newp, 10, &error, SMB_STR_STANDARD);
327
0
    if (newp[0] == '.' || error != 0) {
328
0
      p = newp + 1;
329
0
      if (!*p) {
330
        /* empty last component */
331
0
        data_blob_free(blob);
332
0
        return false;
333
0
      }
334
0
    } else if (newp[0] == '\0') {
335
0
      p = newp;
336
0
    } else {
337
0
      data_blob_free(blob);
338
0
      return false;
339
0
    }
340
0
    if (v >= (1<<28)) blob->data[i++] = (0x80 | ((v>>28)&0x7f));
341
0
    if (v >= (1<<21)) blob->data[i++] = (0x80 | ((v>>21)&0x7f));
342
0
    if (v >= (1<<14)) blob->data[i++] = (0x80 | ((v>>14)&0x7f));
343
0
    if (v >= (1<<7)) blob->data[i++] = (0x80 | ((v>>7)&0x7f));
344
0
    blob->data[i++] = (v&0x7f);
345
0
  }
346
347
0
  blob->length = i;
348
349
0
  return true;
350
0
}
351
352
/**
353
 * Serialize partial OID string.
354
 * Partial OIDs are in the form:
355
 *   1:2.5.6:0x81
356
 *   1:2.5.6:0x8182
357
 */
358
bool ber_write_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *partial_oid)
359
0
{
360
0
  TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
361
0
  char *oid = talloc_strdup(tmp_ctx, partial_oid);
362
0
  char *p;
363
364
  /* truncate partial part so ber_write_OID_String() works */
365
0
  p = strchr(oid, ':');
366
0
  if (p) {
367
0
    *p = '\0';
368
0
    p++;
369
0
  }
370
371
0
  if (!ber_write_OID_String(mem_ctx, blob, oid)) {
372
0
    talloc_free(tmp_ctx);
373
0
    return false;
374
0
  }
375
376
  /* Add partially encoded sub-identifier */
377
0
  if (p) {
378
0
    DATA_BLOB tmp_blob = strhex_to_data_blob(tmp_ctx, p);
379
0
    if (!data_blob_append(mem_ctx, blob, tmp_blob.data,
380
0
              tmp_blob.length)) {
381
0
      talloc_free(tmp_ctx);
382
0
      return false;
383
0
    }
384
0
  }
385
386
0
  talloc_free(tmp_ctx);
387
388
0
  return true;
389
0
}
390
391
/* write an object ID to a ASN1 buffer */
392
bool asn1_write_OID(struct asn1_data *data, const char *OID)
393
0
{
394
0
  DATA_BLOB blob;
395
396
0
  if (!asn1_push_tag(data, ASN1_OID)) return false;
397
398
0
  if (!ber_write_OID_String(NULL, &blob, OID)) {
399
0
    data->has_error = true;
400
0
    return false;
401
0
  }
402
403
0
  if (!asn1_write(data, blob.data, blob.length)) {
404
0
    data_blob_free(&blob);
405
0
    data->has_error = true;
406
0
    return false;
407
0
  }
408
0
  data_blob_free(&blob);
409
0
  return asn1_pop_tag(data);
410
0
}
411
412
/* write an octet string */
413
bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length)
414
0
{
415
0
  bool ok = !asn1_has_error(data);
416
0
  ok = ok && asn1_push_tag(data, ASN1_OCTET_STRING);
417
0
  ok = ok && asn1_write(data, p, length);
418
0
  ok = ok && asn1_pop_tag(data);
419
0
  return ok;
420
0
}
421
422
/* write a LDAP string */
423
bool asn1_write_LDAPString(struct asn1_data *data, const char *s)
424
0
{
425
0
  return asn1_write(data, s, strlen(s));
426
0
}
427
428
/* write a LDAP string from a DATA_BLOB */
429
bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s)
430
0
{
431
0
  return asn1_write(data, s->data, s->length);
432
0
}
433
434
/* write a general string */
435
bool asn1_write_GeneralString(struct asn1_data *data, const char *s)
436
0
{
437
0
  bool ok = !asn1_has_error(data);
438
0
  ok = ok && asn1_push_tag(data, ASN1_GENERAL_STRING);
439
0
  ok = ok && asn1_write_LDAPString(data, s);
440
0
  ok = ok && asn1_pop_tag(data);
441
0
  return ok;
442
0
}
443
444
bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob)
445
0
{
446
0
  bool ok = !asn1_has_error(data);
447
0
  ok = ok && asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num));
448
0
  ok = ok && asn1_write(data, blob->data, blob->length);
449
0
  ok = ok && asn1_pop_tag(data);
450
0
  return ok;
451
0
}
452
453
/* write a BOOLEAN */
454
bool asn1_write_BOOLEAN(struct asn1_data *data, bool v)
455
0
{
456
0
  bool ok = !asn1_has_error(data);
457
0
  ok = ok && asn1_push_tag(data, ASN1_BOOLEAN);
458
0
  ok = ok && asn1_write_uint8(data, v ? 0xFF : 0);
459
0
  ok = ok && asn1_pop_tag(data);
460
0
  return ok;
461
0
}
462
463
bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v)
464
796
{
465
796
  uint8_t tmp = 0;
466
796
  if (!asn1_start_tag(data, ASN1_BOOLEAN)) return false;
467
786
  *v = false;
468
786
  if (!asn1_read_uint8(data, &tmp)) return false;
469
780
  if (tmp == 0xFF) {
470
92
    *v = true;
471
92
  }
472
780
  return asn1_end_tag(data);
473
786
}
474
475
/* write a BOOLEAN in a simple context */
476
bool asn1_write_BOOLEAN_context(struct asn1_data *data, bool v, int context)
477
0
{
478
0
  bool ok = !asn1_has_error(data);
479
0
  ok = ok && asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(context));
480
0
  ok = ok && asn1_write_uint8(data, v ? 0xFF : 0);
481
0
  ok = ok && asn1_pop_tag(data);
482
0
  return ok;
483
0
}
484
485
bool asn1_read_BOOLEAN_context(struct asn1_data *data, bool *v, int context)
486
69
{
487
69
  uint8_t tmp = 0;
488
69
  if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(context))) return false;
489
59
  *v = false;
490
59
  if (!asn1_read_uint8(data, &tmp)) return false;
491
52
  if (tmp == 0xFF) {
492
18
    *v = true;
493
18
  }
494
52
  return asn1_end_tag(data);
495
59
}
496
497
/* check a BOOLEAN */
498
bool asn1_check_BOOLEAN(struct asn1_data *data, bool v)
499
0
{
500
0
  uint8_t b = 0;
501
502
0
  if (!asn1_read_uint8(data, &b)) return false;
503
0
  if (b != ASN1_BOOLEAN) {
504
0
    data->has_error = true;
505
0
    return false;
506
0
  }
507
0
  if (!asn1_read_uint8(data, &b)) return false;
508
0
  if (b != v) {
509
0
    data->has_error = true;
510
0
    return false;
511
0
  }
512
0
  return !data->has_error;
513
0
}
514
515
516
/* load a struct asn1_data structure with a lump of data, ready to be parsed */
517
bool asn1_load(struct asn1_data *data, DATA_BLOB blob)
518
1.15k
{
519
  /*
520
   * Save the maximum depth
521
   */
522
1.15k
  unsigned max_depth = data->max_depth;
523
524
1.15k
  *data = (struct asn1_data){
525
1.15k
    .data = talloc_memdup(data, blob.data, blob.length),
526
1.15k
    .length = blob.length,
527
1.15k
    .max_depth = max_depth,
528
1.15k
  };
529
530
1.15k
  if (data->data == NULL) {
531
0
    data->has_error = true;
532
0
    return false;
533
0
  }
534
535
1.15k
  return true;
536
1.15k
}
537
538
/* Peek into an ASN1 buffer, not advancing the pointer */
539
static bool asn1_peek(struct asn1_data *data, void *p, int len)
540
9.72M
{
541
9.72M
  size_t ofs, end;
542
543
9.72M
  if (data->has_error)
544
25
    return false;
545
546
9.72M
  if (len < 0) {
547
0
    return false;
548
0
  }
549
550
9.72M
  if (data->ofs < 0) {
551
0
    data->has_error = true;
552
0
    return false;
553
0
  }
554
9.72M
  ofs = data->ofs;
555
556
9.72M
  end = ofs + len;
557
9.72M
  if (end < ofs) {
558
0
    return false;
559
0
  }
560
561
9.72M
  if (end > data->length) {
562
    /* we need to mark the buffer as consumed, so the caller knows
563
       this was an out of data error, and not a decode error */
564
928
    data->ofs = data->length;
565
928
    return false;
566
928
  }
567
568
9.72M
  memcpy(p, data->data + data->ofs, len);
569
9.72M
  return true;
570
9.72M
}
571
572
/* read from a ASN1 buffer, advancing the buffer pointer */
573
bool asn1_read(struct asn1_data *data, void *p, int len)
574
9.51M
{
575
9.51M
  if (!asn1_peek(data, p, len)) {
576
878
    data->has_error = true;
577
878
    return false;
578
878
  }
579
580
9.51M
  data->ofs += len;
581
9.51M
  return true;
582
9.51M
}
583
584
/* read a uint8_t from a ASN1 buffer */
585
bool asn1_read_uint8(struct asn1_data *data, uint8_t *v)
586
9.25M
{
587
9.25M
  return asn1_read(data, v, 1);
588
9.25M
}
589
590
bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v)
591
206k
{
592
206k
  return asn1_peek(data, v, 1);
593
206k
}
594
595
bool asn1_peek_tag(struct asn1_data *data, uint8_t tag)
596
157k
{
597
157k
  uint8_t b;
598
599
157k
  if (asn1_tag_remaining(data) <= 0) {
600
10.8k
    return false;
601
10.8k
  }
602
603
146k
  if (!asn1_peek_uint8(data, &b))
604
0
    return false;
605
606
146k
  return (b == tag);
607
146k
}
608
609
/*
610
 * just get the needed size the tag would consume
611
 */
612
static bool asn1_peek_tag_needed_size(struct asn1_data *data, uint8_t tag,
613
              size_t *size)
614
0
{
615
0
  off_t start_ofs = data->ofs;
616
0
  uint8_t b;
617
0
  size_t taglen = 0;
618
619
0
  if (data->has_error) {
620
0
    return false;
621
0
  }
622
623
0
  if (!asn1_read_uint8(data, &b)) {
624
0
    data->ofs = start_ofs;
625
0
    data->has_error = false;
626
0
    return false;
627
0
  }
628
629
0
  if (b != tag) {
630
0
    data->ofs = start_ofs;
631
0
    data->has_error = false;
632
0
    return false;
633
0
  }
634
635
0
  if (!asn1_read_uint8(data, &b)) {
636
0
    data->ofs = start_ofs;
637
0
    data->has_error = false;
638
0
    return false;
639
0
  }
640
641
0
  if (b & 0x80) {
642
0
    int n = b & 0x7f;
643
0
    if (!asn1_read_uint8(data, &b)) {
644
0
      data->ofs = start_ofs;
645
0
      data->has_error = false;
646
0
      return false;
647
0
    }
648
0
    if (n > 4) {
649
      /*
650
       * We should not allow more than 4 bytes
651
       * for the encoding of the tag length.
652
       *
653
       * Otherwise we'd overflow the taglen
654
       * variable on 32 bit systems.
655
       */
656
0
      data->ofs = start_ofs;
657
0
      data->has_error = false;
658
0
      return false;
659
0
    }
660
0
    taglen = b;
661
0
    while (n > 1) {
662
0
      size_t tmp_taglen;
663
664
0
      if (!asn1_read_uint8(data, &b)) {
665
0
        data->ofs = start_ofs;
666
0
        data->has_error = false;
667
0
        return false;
668
0
      }
669
670
0
      tmp_taglen = (taglen << 8) | b;
671
672
0
      if ((tmp_taglen >> 8) != taglen) {
673
        /* overflow */
674
0
        data->ofs = start_ofs;
675
0
        data->has_error = false;
676
0
        return false;
677
0
      }
678
0
      taglen = tmp_taglen;
679
680
0
      n--;
681
0
    }
682
0
  } else {
683
0
    taglen = b;
684
0
  }
685
686
0
  *size = (data->ofs - start_ofs) + taglen;
687
688
0
  data->ofs = start_ofs;
689
0
  data->has_error = false;
690
0
  return true;
691
0
}
692
693
/* start reading a nested asn1 structure */
694
bool asn1_start_tag(struct asn1_data *data, uint8_t tag)
695
309k
{
696
309k
  uint8_t b;
697
309k
  struct nesting *nesting;
698
699
  /*
700
   * Check the depth of the parse tree and prevent it from growing
701
   * too large.
702
   */
703
309k
  data->depth++;
704
309k
  if (data->depth > data->max_depth) {
705
2
    data->has_error = true;
706
2
    return false;
707
2
  }
708
709
309k
  if (!asn1_read_uint8(data, &b))
710
480
    return false;
711
712
308k
  if (b != tag) {
713
352
    data->has_error = true;
714
352
    return false;
715
352
  }
716
308k
  nesting = talloc(data, struct nesting);
717
308k
  if (!nesting) {
718
0
    data->has_error = true;
719
0
    return false;
720
0
  }
721
722
308k
  if (!asn1_read_uint8(data, &b)) {
723
174
    return false;
724
174
  }
725
726
308k
  if (b & 0x80) {
727
4.42k
    int n = b & 0x7f;
728
4.42k
    if (!asn1_read_uint8(data, &b))
729
49
      return false;
730
4.37k
    nesting->taglen = b;
731
15.0k
    while (n > 1) {
732
10.8k
      size_t taglen;
733
734
10.8k
      if (!asn1_read_uint8(data, &b))
735
161
        return false;
736
737
10.6k
      taglen = (nesting->taglen << 8) | b;
738
739
10.6k
      if ((taglen >> 8) != nesting->taglen) {
740
        /* overflow */
741
62
        data->has_error = true;
742
62
        return false;
743
62
      }
744
10.6k
      nesting->taglen = taglen;
745
746
10.6k
      n--;
747
10.6k
    }
748
303k
  } else {
749
303k
    nesting->taglen = b;
750
303k
  }
751
308k
  nesting->start = data->ofs;
752
308k
  nesting->next = data->nesting;
753
308k
  data->nesting = nesting;
754
308k
  if (asn1_tag_remaining(data) == -1) {
755
436
    return false;
756
436
  }
757
307k
  return !data->has_error;
758
308k
}
759
760
/* stop reading a tag */
761
bool asn1_end_tag(struct asn1_data *data)
762
289k
{
763
289k
  struct nesting *nesting;
764
765
289k
  if (data->depth == 0) {
766
0
    smb_panic("Unbalanced ASN.1 Tag nesting");
767
0
  }
768
289k
  data->depth--;
769
  /* make sure we read it all */
770
289k
  if (asn1_tag_remaining(data) != 0) {
771
1.63k
    data->has_error = true;
772
1.63k
    return false;
773
1.63k
  }
774
775
287k
  nesting = data->nesting;
776
777
287k
  if (!nesting) {
778
0
    data->has_error = true;
779
0
    return false;
780
0
  }
781
782
287k
  data->nesting = nesting->next;
783
287k
  talloc_free(nesting);
784
287k
  return true;
785
287k
}
786
787
/* work out how many bytes are left in this nested tag */
788
int asn1_tag_remaining(struct asn1_data *data)
789
9.77M
{
790
9.77M
  size_t consumed, remaining_tag, remaining_data;
791
9.77M
  if (data->has_error) {
792
1.05k
    return -1;
793
1.05k
  }
794
795
9.77M
  if (!data->nesting) {
796
0
    goto error;
797
0
  }
798
799
9.77M
  if (data->ofs < data->nesting->start) {
800
0
    goto error;
801
0
  }
802
9.77M
  consumed = data->ofs - data->nesting->start;
803
804
9.77M
  if (data->nesting->taglen < consumed) {
805
1.40k
    goto error;
806
1.40k
  }
807
9.77M
  remaining_tag = data->nesting->taglen - consumed;
808
809
9.77M
  if ((data->ofs < 0) || (data->length < (size_t)data->ofs)) {
810
0
    goto error;
811
0
  }
812
9.77M
  remaining_data = data->length - data->ofs;
813
814
9.77M
  if (remaining_tag > remaining_data) {
815
436
    goto error;
816
436
  }
817
9.77M
  if (remaining_tag > INT_MAX) {
818
0
    goto error;
819
0
  }
820
9.77M
  return remaining_tag;
821
1.83k
error:
822
1.83k
  data->has_error = true;
823
1.83k
  return -1;
824
9.77M
}
825
826
/**
827
 * Internal implementation for reading binary OIDs
828
 * Reading is done as far in the buffer as valid OID
829
 * till buffer ends or not valid sub-identifier is found.
830
 */
831
static bool _ber_read_OID_String_impl(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
832
              char **OID, size_t *bytes_eaten)
833
5.10k
{
834
5.10k
  size_t i;
835
5.10k
  uint8_t *b;
836
5.10k
  unsigned int v;
837
5.10k
  char *tmp_oid = NULL;
838
839
5.10k
  if (blob.length < 2) return false;
840
841
1.26k
  b = blob.data;
842
843
1.26k
  tmp_oid = talloc_asprintf(mem_ctx, "%u.%u", b[0]/40, b[0]%40);
844
845
1.26k
  if (bytes_eaten != NULL) {
846
1.26k
    *bytes_eaten = 0;
847
1.26k
  }
848
849
1.37M
  for(i = 1, v = 0; i < blob.length; i++) {
850
1.37M
    v = (v<<7) | (b[i]&0x7f);
851
1.37M
    if ( ! (b[i] & 0x80)) {
852
1.05M
      talloc_asprintf_addbuf(&tmp_oid, ".%u",  v);
853
1.05M
      v = 0;
854
1.05M
      if (bytes_eaten)
855
1.05M
        *bytes_eaten = i+1;
856
1.05M
    }
857
1.37M
  }
858
859
1.26k
  if (tmp_oid == NULL) {
860
0
    goto nomem;
861
0
  }
862
863
1.26k
  *OID = tmp_oid;
864
1.26k
  return true;
865
866
0
nomem:
867
0
  return false;
868
1.26k
}
869
870
/* read an object ID from a data blob */
871
bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, char **OID)
872
229
{
873
229
  size_t bytes_eaten;
874
875
229
  if (!_ber_read_OID_String_impl(mem_ctx, blob, OID, &bytes_eaten))
876
25
    return false;
877
878
204
  return (bytes_eaten == blob.length);
879
229
}
880
881
/**
882
 * Deserialize partial OID string.
883
 * Partial OIDs are in the form:
884
 *   1:2.5.6:0x81
885
 *   1:2.5.6:0x8182
886
 */
887
bool ber_read_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
888
         char **partial_oid)
889
4.87k
{
890
4.87k
  size_t bytes_left;
891
4.87k
  size_t bytes_eaten;
892
4.87k
  char *identifier = NULL;
893
4.87k
  char *tmp_oid = NULL;
894
895
4.87k
  if (!_ber_read_OID_String_impl(mem_ctx, blob, &tmp_oid, &bytes_eaten))
896
3.81k
    return false;
897
898
1.05k
  if (bytes_eaten < blob.length) {
899
279
    bytes_left = blob.length - bytes_eaten;
900
279
    identifier = hex_encode_talloc(mem_ctx, &blob.data[bytes_eaten], bytes_left);
901
279
    if (!identifier)  goto nomem;
902
903
279
    *partial_oid = talloc_asprintf_append_buffer(tmp_oid, ":0x%s", identifier);
904
279
    if (!*partial_oid)  goto nomem;
905
279
    TALLOC_FREE(identifier);
906
779
  } else {
907
779
    *partial_oid = tmp_oid;
908
779
  }
909
910
1.05k
  return true;
911
912
0
nomem:
913
0
  TALLOC_FREE(identifier);
914
0
  TALLOC_FREE(tmp_oid);
915
0
  return false;
916
1.05k
}
917
918
/* read an object ID from a ASN1 buffer */
919
bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **OID)
920
274
{
921
274
  DATA_BLOB blob;
922
274
  int len;
923
924
274
  if (!asn1_start_tag(data, ASN1_OID)) return false;
925
926
235
  len = asn1_tag_remaining(data);
927
235
  if (len < 0) {
928
0
    data->has_error = true;
929
0
    return false;
930
0
  }
931
932
235
  blob = data_blob(NULL, len);
933
235
  if (!blob.data) {
934
6
    data->has_error = true;
935
6
    return false;
936
6
  }
937
938
229
  if (!asn1_read(data, blob.data, len)) {
939
0
    data_blob_free(&blob);
940
0
    return false;
941
0
  }
942
943
229
  if (!asn1_end_tag(data)) {
944
0
    data_blob_free(&blob);
945
0
    return false;
946
0
  }
947
948
229
  if (!ber_read_OID_String(mem_ctx, blob, OID)) {
949
78
    data->has_error = true;
950
78
    data_blob_free(&blob);
951
78
    return false;
952
78
  }
953
954
151
  data_blob_free(&blob);
955
151
  return true;
956
229
}
957
958
/* check that the next object ID is correct */
959
bool asn1_check_OID(struct asn1_data *data, const char *OID)
960
274
{
961
274
  char *id;
962
963
274
  if (!asn1_read_OID(data, data, &id)) return false;
964
965
151
  if (strcmp(id, OID) != 0) {
966
151
    talloc_free(id);
967
151
    data->has_error = true;
968
151
    return false;
969
151
  }
970
0
  talloc_free(id);
971
0
  return true;
972
151
}
973
974
/* read a LDAPString from a ASN1 buffer */
975
bool asn1_read_LDAPString(struct asn1_data *data,
976
        TALLOC_CTX *mem_ctx,
977
        char **_s)
978
48.3k
{
979
48.3k
  int len;
980
48.3k
  char *s = NULL;
981
48.3k
  bool ok;
982
983
48.3k
  len = asn1_tag_remaining(data);
984
48.3k
  if (len < 0) {
985
0
    data->has_error = true;
986
0
    return false;
987
0
  }
988
48.3k
  s = talloc_array(mem_ctx, char, len + 1);
989
48.3k
  if (s == NULL) {
990
0
    data->has_error = true;
991
0
    return false;
992
0
  }
993
48.3k
  s[len] = 0;
994
995
48.3k
  ok = asn1_read(data, s, len);
996
48.3k
  if (!ok) {
997
0
    TALLOC_FREE(s);
998
0
    return false;
999
0
  }
1000
1001
48.3k
  *_s = s;
1002
48.3k
  return true;
1003
48.3k
}
1004
1005
1006
/* read a GeneralString from a ASN1 buffer */
1007
bool asn1_read_GeneralString(struct asn1_data *data,
1008
           TALLOC_CTX *mem_ctx,
1009
           char **_s)
1010
0
{
1011
0
  char *s = NULL;
1012
0
  bool ok = false;
1013
1014
0
  if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return false;
1015
0
  if (!asn1_read_LDAPString(data, mem_ctx, &s)) return false;
1016
1017
0
  ok = asn1_end_tag(data);
1018
0
  if (!ok) {
1019
0
    TALLOC_FREE(s);
1020
0
    return false;
1021
0
  }
1022
1023
0
  *_s = s;
1024
0
  return true;
1025
0
}
1026
1027
1028
static bool asn1_read_blob_tag(struct asn1_data *data, TALLOC_CTX *mem_ctx,
1029
             uint8_t tag, DATA_BLOB *blob)
1030
209k
{
1031
209k
  int len;
1032
209k
  ZERO_STRUCTP(blob);
1033
209k
  if (!asn1_start_tag(data, tag)) return false;
1034
208k
  len = asn1_tag_remaining(data);
1035
208k
  if (len < 0) {
1036
0
    data->has_error = true;
1037
0
    return false;
1038
0
  }
1039
208k
  *blob = data_blob_talloc(mem_ctx, NULL, len+1);
1040
208k
  if (!blob->data || blob->length < (unsigned)len) {
1041
0
    data->has_error = true;
1042
0
    return false;
1043
0
  }
1044
208k
  if (!asn1_read(data, blob->data, len)) goto err;
1045
208k
  if (!asn1_end_tag(data)) goto err;
1046
208k
  blob->length--;
1047
208k
  blob->data[len] = 0;
1048
208k
  return true;
1049
1050
0
  err:
1051
1052
0
  data_blob_free(blob);
1053
0
  return false;
1054
208k
}
1055
1056
/* read a octet string blob */
1057
bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
1058
209k
{
1059
209k
  return asn1_read_blob_tag(data, mem_ctx, ASN1_OCTET_STRING, blob);
1060
209k
}
1061
1062
bool asn1_read_ContextSimple(struct asn1_data *data, TALLOC_CTX *mem_ctx, uint8_t num,
1063
           DATA_BLOB *blob)
1064
214
{
1065
214
  return asn1_read_blob_tag(data, mem_ctx, ASN1_CONTEXT_SIMPLE(num), blob);
1066
214
}
1067
1068
/* read an integer without tag*/
1069
bool asn1_read_implicit_Integer(struct asn1_data *data, int *i)
1070
4.51k
{
1071
4.51k
  uint8_t b;
1072
4.51k
  uint32_t x = 0;
1073
4.51k
  bool first_byte = true;
1074
1075
4.51k
  *i = 0;
1076
1077
7.16M
  while (!data->has_error && asn1_tag_remaining(data)>0) {
1078
7.16M
    if (!asn1_read_uint8(data, &b)) return false;
1079
7.16M
    if (first_byte) {
1080
444
      if (b & 0x80) {
1081
        /* Number is negative. */
1082
127
        x = (uint32_t)-1;
1083
127
      }
1084
444
      first_byte = false;
1085
444
    }
1086
7.16M
    x = (x << 8) + b;
1087
7.16M
  }
1088
4.51k
  *i = (int)x;
1089
1090
4.51k
  return !data->has_error;
1091
4.51k
}
1092
1093
/* read an integer */
1094
bool asn1_read_Integer(struct asn1_data *data, int *i)
1095
4.45k
{
1096
4.45k
  *i = 0;
1097
1098
4.45k
  if (!asn1_start_tag(data, ASN1_INTEGER)) return false;
1099
4.26k
  if (!asn1_read_implicit_Integer(data, i)) return false;
1100
4.26k
  return asn1_end_tag(data);
1101
4.26k
}
1102
1103
/* read a BIT STRING */
1104
bool asn1_read_BitString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint8_t *padding)
1105
0
{
1106
0
  int len;
1107
0
  ZERO_STRUCTP(blob);
1108
0
  if (!asn1_start_tag(data, ASN1_BIT_STRING)) return false;
1109
0
  len = asn1_tag_remaining(data);
1110
0
  if (len < 0) {
1111
0
    data->has_error = true;
1112
0
    return false;
1113
0
  }
1114
0
  if (!asn1_read_uint8(data, padding)) return false;
1115
1116
0
  *blob = data_blob_talloc(mem_ctx, NULL, len+1);
1117
0
  if (!blob->data || blob->length < (unsigned)len) {
1118
0
    data->has_error = true;
1119
0
    return false;
1120
0
  }
1121
0
  if (asn1_read(data, blob->data, len - 1)) {
1122
0
    blob->length--;
1123
0
    blob->data[len] = 0;
1124
0
    asn1_end_tag(data);
1125
0
  }
1126
1127
0
  if (data->has_error) {
1128
0
    data_blob_free(blob);
1129
0
    *padding = 0;
1130
0
    return false;
1131
0
  }
1132
0
  return true;
1133
0
}
1134
1135
/* read a non-negative enumerated value */
1136
bool asn1_read_enumerated(struct asn1_data *data, int *v)
1137
1.69k
{
1138
1.69k
  unsigned int val_will_wrap = (0xFFU << ((sizeof(int)*8)-8));
1139
1.69k
  *v = 0;
1140
1141
1.69k
  if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;
1142
1.45M
  while (!data->has_error && asn1_tag_remaining(data)>0) {
1143
1.45M
    uint8_t b;
1144
1.45M
    if (!asn1_read_uint8(data, &b)) {
1145
0
      return false;
1146
0
    }
1147
1.45M
    if (*v & val_will_wrap) {
1148
      /*
1149
       * There is something already in
1150
       * the top byte of the int. If we
1151
       * shift left by 8 it's going to
1152
       * wrap. Prevent this.
1153
       */
1154
37
      data->has_error = true;
1155
37
      return false;
1156
37
    }
1157
    /*
1158
     * To please/fool the Undefined Behaviour Sanitizer we cast to
1159
     * unsigned for the left shift.
1160
     */
1161
1.45M
    *v = ((unsigned int)*v << 8) + b;
1162
1.45M
    if (*v < 0) {
1163
      /* ASN1_ENUMERATED can't be -ve. */
1164
63
      data->has_error = true;
1165
63
      return false;
1166
63
    }
1167
1.45M
  }
1168
1.49k
  return asn1_end_tag(data);
1169
1.59k
}
1170
1171
/* write an enumerated value to the stream */
1172
bool asn1_write_enumerated(struct asn1_data *data, uint8_t v)
1173
0
{
1174
0
  bool ok = !asn1_has_error(data);
1175
0
  ok = ok && asn1_push_tag(data, ASN1_ENUMERATED);
1176
0
  ok = ok && asn1_write_uint8(data, v);
1177
0
  ok = ok && asn1_pop_tag(data);
1178
0
  return ok;
1179
0
}
1180
1181
/*
1182
  Get us the data just written without copying
1183
*/
1184
bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob)
1185
0
{
1186
0
  if (asn1->has_error) {
1187
0
    return false;
1188
0
  }
1189
0
  if (asn1->nesting != NULL) {
1190
0
    return false;
1191
0
  }
1192
0
  blob->data = asn1->data;
1193
0
  blob->length = asn1->length;
1194
0
  return true;
1195
0
}
1196
1197
bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
1198
           DATA_BLOB *pblob)
1199
0
{
1200
0
  DATA_BLOB blob;
1201
1202
0
  if (!asn1_blob(asn1, &blob)) {
1203
0
    return false;
1204
0
  }
1205
1206
0
  *pblob = (DATA_BLOB){
1207
0
    .length = blob.length,
1208
0
    .data = talloc_move(mem_ctx, &blob.data),
1209
0
  };
1210
1211
  /*
1212
   * Stop access from here on
1213
   */
1214
0
  asn1->has_error = true;
1215
1216
0
  return true;
1217
0
}
1218
1219
/*
1220
  Fill in an asn1 struct without making a copy
1221
*/
1222
void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len)
1223
2.97k
{
1224
  /*
1225
   * Save max_depth
1226
   */
1227
2.97k
  unsigned max_depth = data->max_depth;
1228
1229
2.97k
  *data = (struct asn1_data) {
1230
2.97k
    .data = buf,
1231
2.97k
    .length = len,
1232
2.97k
    .max_depth = max_depth,
1233
2.97k
  };
1234
2.97k
}
1235
1236
int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
1237
0
{
1238
0
  struct asn1_data asn1 = {};
1239
0
  size_t size;
1240
0
  bool ok;
1241
1242
0
  asn1_load_nocopy(&asn1, blob.data, blob.length);
1243
1244
0
  ok = asn1_peek_tag_needed_size(&asn1, tag, &size);
1245
0
  if (!ok) {
1246
0
    return EMSGSIZE;
1247
0
  }
1248
1249
0
  if (size > blob.length) {
1250
0
    *packet_size = size;
1251
0
    return EAGAIN;
1252
0
  }
1253
1254
0
  *packet_size = size;
1255
0
  return 0;
1256
0
}
1257
1258
/*
1259
 * Get the length of the ASN.1 data
1260
 */
1261
694
size_t asn1_get_length(const struct asn1_data *asn1) {
1262
694
  return asn1->length;
1263
694
}