Coverage Report

Created: 2026-02-14 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/asn1/tasn_dec.cc
Line
Count
Source
1
// Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/asn1.h>
16
#include <openssl/asn1t.h>
17
#include <openssl/bytestring.h>
18
#include <openssl/err.h>
19
#include <openssl/mem.h>
20
#include <openssl/pool.h>
21
22
#include <assert.h>
23
#include <limits.h>
24
#include <string.h>
25
26
#include "../bytestring/internal.h"
27
#include "../internal.h"
28
#include "internal.h"
29
30
31
using namespace bssl;
32
33
// Constructed types with a recursive definition (such as can be found in PKCS7)
34
// could eventually exceed the stack given malicious input with excessive
35
// recursion. Therefore we limit the stack depth. This is the maximum number of
36
// recursive invocations of asn1_item_embed_d2i().
37
3.45M
#define ASN1_MAX_CONSTRUCTED_NEST 30
38
39
static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
40
                           char *cst, const unsigned char **in, long len,
41
                           int exptag, int expclass, char opt);
42
43
static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
44
                                long len, const ASN1_TEMPLATE *tt, char opt,
45
                                int depth);
46
static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in,
47
                                   long len, const ASN1_TEMPLATE *tt, char opt,
48
                                   int depth);
49
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in,
50
                                 long len, const ASN1_ITEM *it, int tag,
51
                                 int aclass, char opt);
52
static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
53
                            long len, const ASN1_ITEM *it, int tag, int aclass,
54
                            char opt, int depth);
55
56
128k
unsigned long ASN1_tag2bit(int tag) {
57
128k
  switch (tag) {
58
2
    case V_ASN1_BIT_STRING:
59
2
      return B_ASN1_BIT_STRING;
60
3
    case V_ASN1_OCTET_STRING:
61
3
      return B_ASN1_OCTET_STRING;
62
1.42k
    case V_ASN1_UTF8STRING:
63
1.42k
      return B_ASN1_UTF8STRING;
64
4
    case V_ASN1_SEQUENCE:
65
4
      return B_ASN1_SEQUENCE;
66
0
    case V_ASN1_NUMERICSTRING:
67
0
      return B_ASN1_NUMERICSTRING;
68
1.35k
    case V_ASN1_PRINTABLESTRING:
69
1.35k
      return B_ASN1_PRINTABLESTRING;
70
3.59k
    case V_ASN1_T61STRING:
71
3.59k
      return B_ASN1_T61STRING;
72
2
    case V_ASN1_VIDEOTEXSTRING:
73
2
      return B_ASN1_VIDEOTEXSTRING;
74
1.72k
    case V_ASN1_IA5STRING:
75
1.72k
      return B_ASN1_IA5STRING;
76
0
    case V_ASN1_UTCTIME:
77
0
      return B_ASN1_UTCTIME;
78
10
    case V_ASN1_GENERALIZEDTIME:
79
10
      return B_ASN1_GENERALIZEDTIME;
80
5
    case V_ASN1_GRAPHICSTRING:
81
5
      return B_ASN1_GRAPHICSTRING;
82
39
    case V_ASN1_ISO64STRING:
83
39
      return B_ASN1_ISO64STRING;
84
9
    case V_ASN1_GENERALSTRING:
85
9
      return B_ASN1_GENERALSTRING;
86
115k
    case V_ASN1_UNIVERSALSTRING:
87
115k
      return B_ASN1_UNIVERSALSTRING;
88
4.74k
    case V_ASN1_BMPSTRING:
89
4.74k
      return B_ASN1_BMPSTRING;
90
16
    default:
91
16
      return 0;
92
128k
  }
93
128k
}
94
95
// Decode an ASN1 item, this currently behaves just like a standard 'd2i'
96
// function. 'in' points to a buffer to read the data from, in future we
97
// will have more advanced versions that can input data a piece at a time and
98
// this will simply be a special case.
99
100
ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
101
224k
                          const ASN1_ITEM *it) {
102
224k
  ASN1_VALUE *ret = nullptr;
103
224k
  if (asn1_item_ex_d2i(&ret, in, len, it, /*tag=*/-1, /*aclass=*/0, /*opt=*/0,
104
224k
                       /*depth=*/0) <= 0) {
105
    // Clean up, in case the caller left a partial object.
106
    //
107
    // TODO(davidben): I don't think it can leave one, but the codepaths below
108
    // are a bit inconsistent. Revisit this when rewriting this function.
109
17.9k
    ASN1_item_ex_free(&ret, it);
110
17.9k
  }
111
112
  // If the caller supplied an output pointer, free the old one and replace it
113
  // with |ret|. This differs from OpenSSL slightly in that we don't support
114
  // object reuse. We run this on both success and failure. On failure, even
115
  // with object reuse, OpenSSL destroys the previous object.
116
224k
  if (pval != nullptr) {
117
0
    ASN1_item_ex_free(pval, it);
118
0
    *pval = ret;
119
0
  }
120
224k
  return ret;
121
224k
}
122
123
// Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
124
// tag mismatch return -1 to handle OPTIONAL
125
//
126
// TODO(davidben): Historically, all functions in this file had to account for
127
// |*pval| containing an arbitrary existing value. This is no longer the case
128
// because |ASN1_item_d2i| now always starts from NULL. As part of rewriting
129
// this function, take the simplified assumptions into account. Though we must
130
// still account for the internal calls to |ASN1_item_ex_new|.
131
132
static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
133
                            long len, const ASN1_ITEM *it, int tag, int aclass,
134
3.45M
                            char opt, int depth) {
135
3.45M
  const ASN1_TEMPLATE *tt, *errtt = nullptr;
136
3.45M
  const unsigned char *p = nullptr, *q;
137
3.45M
  unsigned char oclass;
138
3.45M
  char cst, isopt;
139
3.45M
  int i;
140
3.45M
  int otag;
141
3.45M
  int ret = 0;
142
3.45M
  ASN1_VALUE **pchptr;
143
3.45M
  if (!pval) {
144
0
    return 0;
145
0
  }
146
3.45M
  if (len < 0) {
147
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
148
0
    goto err;
149
0
  }
150
151
  // Bound |len| to comfortably fit in an int. Lengths in this module often
152
  // switch between int and long without overflow checks.
153
3.45M
  if (len > INT_MAX / 2) {
154
0
    len = INT_MAX / 2;
155
0
  }
156
157
3.45M
  if (++depth > ASN1_MAX_CONSTRUCTED_NEST) {
158
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_TOO_DEEP);
159
0
    goto err;
160
0
  }
161
162
3.45M
  switch (it->itype) {
163
2.37M
    case ASN1_ITYPE_PRIMITIVE:
164
2.37M
      if (it->templates) {
165
        // tagging or OPTIONAL is currently illegal on an item template
166
        // because the flags can't get passed down. In practice this
167
        // isn't a problem: we include the relevant flags from the item
168
        // template in the template itself.
169
152k
        if ((tag != -1) || opt) {
170
0
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
171
0
          goto err;
172
0
        }
173
152k
        return asn1_template_ex_d2i(pval, in, len, it->templates, opt, depth);
174
152k
      }
175
2.22M
      return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt);
176
177
496
    case ASN1_ITYPE_MSTRING:
178
      // It never makes sense for multi-strings to have implicit tagging, so
179
      // if tag != -1, then this looks like an error in the template.
180
496
      if (tag != -1) {
181
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
182
0
        goto err;
183
0
      }
184
185
496
      p = *in;
186
      // Just read in tag and class
187
496
      ret =
188
496
          asn1_check_tlen(nullptr, &otag, &oclass, nullptr, &p, len, -1, 0, 1);
189
496
      if (!ret) {
190
18
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
191
18
        goto err;
192
18
      }
193
194
      // Must be UNIVERSAL class
195
478
      if (oclass != V_ASN1_UNIVERSAL) {
196
        // If OPTIONAL, assume this is OK
197
15
        if (opt) {
198
0
          return -1;
199
0
        }
200
15
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL);
201
15
        goto err;
202
15
      }
203
      // Check tag matches bit map
204
463
      if (!(ASN1_tag2bit(otag) & it->utype)) {
205
        // If OPTIONAL, assume this is OK
206
55
        if (opt) {
207
0
          return -1;
208
0
        }
209
55
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG);
210
55
        goto err;
211
55
      }
212
408
      return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0);
213
214
4.05k
    case ASN1_ITYPE_EXTERN: {
215
      // We don't support implicit tagging with external types.
216
4.05k
      if (tag != -1) {
217
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
218
0
        goto err;
219
0
      }
220
4.05k
      const ASN1_EXTERN_FUNCS *ef =
221
4.05k
          reinterpret_cast<const ASN1_EXTERN_FUNCS *>(it->funcs);
222
4.05k
      CBS cbs;
223
4.05k
      CBS_init(&cbs, *in, len);
224
4.05k
      CBS copy = cbs;
225
4.05k
      if (!ef->asn1_ex_parse(pval, &cbs, it, opt)) {
226
525
        goto err;
227
525
      }
228
3.52k
      *in = CBS_data(&cbs);
229
      // Check whether the function skipped an optional element.
230
      //
231
      // TODO(crbug.com/42290418): Switch the rest of this function to
232
      // |asn1_ex_parse|'s calling convention.
233
3.52k
      return CBS_len(&cbs) == CBS_len(&copy) ? -1 : 1;
234
4.05k
    }
235
236
224k
    case ASN1_ITYPE_CHOICE: {
237
      // It never makes sense for CHOICE types to have implicit tagging, so if
238
      // tag != -1, then this looks like an error in the template.
239
224k
      if (tag != -1) {
240
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
241
0
        goto err;
242
0
      }
243
244
224k
      const ASN1_AUX *aux = reinterpret_cast<const ASN1_AUX *>(it->funcs);
245
224k
      ASN1_aux_cb *asn1_cb = aux != nullptr ? aux->asn1_cb : nullptr;
246
224k
      if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, nullptr)) {
247
0
        goto auxerr;
248
0
      }
249
250
224k
      if (*pval) {
251
        // Free up and zero CHOICE value if initialised
252
1.03k
        i = asn1_get_choice_selector(pval, it);
253
1.03k
        if ((i >= 0) && (i < it->tcount)) {
254
0
          tt = it->templates + i;
255
0
          pchptr = asn1_get_field_ptr(pval, tt);
256
0
          ASN1_template_free(pchptr, tt);
257
0
          asn1_set_choice_selector(pval, -1, it);
258
0
        }
259
223k
      } else if (!ASN1_item_ex_new(pval, it)) {
260
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
261
0
        goto err;
262
0
      }
263
      // CHOICE type, try each possibility in turn
264
224k
      p = *in;
265
1.37M
      for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
266
1.37M
        pchptr = asn1_get_field_ptr(pval, tt);
267
        // We mark field as OPTIONAL so its absence can be recognised.
268
1.37M
        ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, depth);
269
        // If field not present, try the next one
270
1.37M
        if (ret == -1) {
271
1.15M
          continue;
272
1.15M
        }
273
        // If positive return, read OK, break loop
274
223k
        if (ret > 0) {
275
221k
          break;
276
221k
        }
277
        // Otherwise must be an ASN1 parsing error
278
1.92k
        errtt = tt;
279
1.92k
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
280
1.92k
        goto err;
281
223k
      }
282
283
      // Did we fall off the end without reading anything?
284
222k
      if (i == it->tcount) {
285
        // If OPTIONAL, this is OK
286
448
        if (opt) {
287
          // Free and zero it
288
0
          ASN1_item_ex_free(pval, it);
289
0
          return -1;
290
0
        }
291
448
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
292
448
        goto err;
293
448
      }
294
295
221k
      asn1_set_choice_selector(pval, i, it);
296
221k
      if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, nullptr)) {
297
0
        goto auxerr;
298
0
      }
299
221k
      *in = p;
300
221k
      return 1;
301
221k
    }
302
303
856k
    case ASN1_ITYPE_SEQUENCE: {
304
856k
      p = *in;
305
306
      // If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL
307
856k
      if (tag == -1) {
308
458k
        tag = V_ASN1_SEQUENCE;
309
458k
        aclass = V_ASN1_UNIVERSAL;
310
458k
      }
311
      // Get SEQUENCE length and update len, p
312
856k
      ret = asn1_check_tlen(&len, nullptr, nullptr, &cst, &p, len, tag, aclass,
313
856k
                            opt);
314
856k
      if (!ret) {
315
3.26k
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
316
3.26k
        goto err;
317
852k
      } else if (ret == -1) {
318
389k
        return -1;
319
389k
      }
320
463k
      if (!cst) {
321
107
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
322
107
        goto err;
323
107
      }
324
325
463k
      if (!*pval && !ASN1_item_ex_new(pval, it)) {
326
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
327
0
        goto err;
328
0
      }
329
330
463k
      const ASN1_AUX *aux = reinterpret_cast<const ASN1_AUX *>(it->funcs);
331
463k
      ASN1_aux_cb *asn1_cb = aux != nullptr ? aux->asn1_cb : nullptr;
332
463k
      if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, nullptr)) {
333
0
        goto auxerr;
334
0
      }
335
336
      // Free up and zero any ADB found
337
1.84M
      for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
338
1.38M
        if (tt->flags & ASN1_TFLG_ADB_MASK) {
339
2.17k
          const ASN1_TEMPLATE *seqtt;
340
2.17k
          ASN1_VALUE **pseqval;
341
2.17k
          seqtt = asn1_do_adb(pval, tt, 0);
342
2.17k
          if (seqtt == nullptr) {
343
2.17k
            continue;
344
2.17k
          }
345
0
          pseqval = asn1_get_field_ptr(pval, seqtt);
346
0
          ASN1_template_free(pseqval, seqtt);
347
0
        }
348
1.38M
      }
349
350
      // Get each field entry
351
1.82M
      for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
352
1.37M
        const ASN1_TEMPLATE *seqtt;
353
1.37M
        ASN1_VALUE **pseqval;
354
1.37M
        seqtt = asn1_do_adb(pval, tt, 1);
355
1.37M
        if (seqtt == nullptr) {
356
0
          goto err;
357
0
        }
358
1.37M
        pseqval = asn1_get_field_ptr(pval, seqtt);
359
        // Have we ran out of data?
360
1.37M
        if (!len) {
361
4.20k
          break;
362
4.20k
        }
363
1.36M
        q = p;
364
        // This determines the OPTIONAL flag value. The field cannot be
365
        // omitted if it is the last of a SEQUENCE and there is still
366
        // data to be read. This isn't strictly necessary but it
367
        // increases efficiency in some cases.
368
1.36M
        if (i == (it->tcount - 1)) {
369
457k
          isopt = 0;
370
909k
        } else {
371
909k
          isopt = (seqtt->flags & ASN1_TFLG_OPTIONAL) != 0;
372
909k
        }
373
        // attempt to read in field, allowing each to be OPTIONAL
374
375
1.36M
        ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, depth);
376
1.36M
        if (!ret) {
377
4.17k
          errtt = seqtt;
378
4.17k
          goto err;
379
1.36M
        } else if (ret == -1) {
380
          // OPTIONAL component absent. Free and zero the field.
381
324k
          ASN1_template_free(pseqval, seqtt);
382
324k
          continue;
383
324k
        }
384
        // Update length
385
1.03M
        len -= p - q;
386
1.03M
      }
387
388
      // Check all data read
389
459k
      if (len) {
390
112
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
391
112
        goto err;
392
112
      }
393
394
      // If we get here we've got no more data in the SEQUENCE, however we
395
      // may not have read all fields so check all remaining are OPTIONAL
396
      // and clear any that are.
397
469k
      for (; i < it->tcount; tt++, i++) {
398
10.3k
        const ASN1_TEMPLATE *seqtt;
399
10.3k
        seqtt = asn1_do_adb(pval, tt, 1);
400
10.3k
        if (seqtt == nullptr) {
401
0
          goto err;
402
0
        }
403
10.3k
        if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
404
10.1k
          ASN1_VALUE **pseqval;
405
10.1k
          pseqval = asn1_get_field_ptr(pval, seqtt);
406
10.1k
          ASN1_template_free(pseqval, seqtt);
407
10.1k
        } else {
408
207
          errtt = seqtt;
409
207
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING);
410
207
          goto err;
411
207
        }
412
10.3k
      }
413
      // Save encoding
414
458k
      if (!asn1_enc_save(pval, *in, p - *in, it)) {
415
0
        goto auxerr;
416
0
      }
417
458k
      if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, nullptr)) {
418
0
        goto auxerr;
419
0
      }
420
458k
      *in = p;
421
458k
      return 1;
422
458k
    }
423
424
0
    default:
425
0
      return 0;
426
3.45M
  }
427
0
auxerr:
428
0
  OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
429
10.8k
err:
430
10.8k
  ASN1_item_ex_free(pval, it);
431
10.8k
  if (errtt) {
432
6.30k
    ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname);
433
6.30k
  } else {
434
4.54k
    ERR_add_error_data(2, "Type=", it->sname);
435
4.54k
  }
436
10.8k
  return 0;
437
0
}
438
439
int bssl::ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
440
                           long len, const ASN1_ITEM *it, int tag, int aclass,
441
0
                           char opt) {
442
0
  return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, /*depth=*/0);
443
0
}
444
445
// Templates are handled with two separate functions. One handles any
446
// EXPLICIT tag and the other handles the rest.
447
448
static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
449
                                long inlen, const ASN1_TEMPLATE *tt, char opt,
450
2.89M
                                int depth) {
451
2.89M
  int aclass;
452
2.89M
  int ret;
453
2.89M
  long len;
454
2.89M
  const unsigned char *p, *q;
455
2.89M
  if (!val) {
456
0
    return 0;
457
0
  }
458
2.89M
  uint32_t flags = tt->flags;
459
2.89M
  aclass = flags & ASN1_TFLG_TAG_CLASS;
460
461
2.89M
  p = *in;
462
463
  // Check if EXPLICIT tag expected
464
2.89M
  if (flags & ASN1_TFLG_EXPTAG) {
465
187k
    char cst;
466
    // Need to work out amount of data available to the inner content and
467
    // where it starts: so read in EXPLICIT header to get the info.
468
187k
    ret = asn1_check_tlen(&len, nullptr, nullptr, &cst, &p, inlen, tt->tag,
469
187k
                          aclass, opt);
470
187k
    q = p;
471
187k
    if (!ret) {
472
186
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
473
186
      return 0;
474
187k
    } else if (ret == -1) {
475
174k
      return -1;
476
174k
    }
477
12.3k
    if (!cst) {
478
87
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
479
87
      return 0;
480
87
    }
481
    // We've found the field so it can't be OPTIONAL now
482
12.2k
    ret = asn1_template_noexp_d2i(val, &p, len, tt, /*opt=*/0, depth);
483
12.2k
    if (!ret) {
484
1.01k
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
485
1.01k
      return 0;
486
1.01k
    }
487
    // We read the field in OK so update length
488
11.2k
    len -= p - q;
489
    // Check for trailing data.
490
11.2k
    if (len) {
491
102
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
492
102
      goto err;
493
102
    }
494
2.71M
  } else {
495
2.71M
    return asn1_template_noexp_d2i(val, in, inlen, tt, opt, depth);
496
2.71M
  }
497
498
11.1k
  *in = p;
499
11.1k
  return 1;
500
501
102
err:
502
102
  ASN1_template_free(val, tt);
503
102
  return 0;
504
2.89M
}
505
506
static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in,
507
                                   long len, const ASN1_TEMPLATE *tt, char opt,
508
2.72M
                                   int depth) {
509
2.72M
  int aclass;
510
2.72M
  int ret;
511
2.72M
  const unsigned char *p;
512
2.72M
  if (!val) {
513
0
    return 0;
514
0
  }
515
2.72M
  uint32_t flags = tt->flags;
516
2.72M
  aclass = flags & ASN1_TFLG_TAG_CLASS;
517
518
2.72M
  p = *in;
519
520
2.72M
  if (flags & ASN1_TFLG_SK_MASK) {
521
    // SET OF, SEQUENCE OF
522
157k
    int sktag, skaclass;
523
    // First work out expected inner tag value
524
157k
    if (flags & ASN1_TFLG_IMPTAG) {
525
3.67k
      sktag = tt->tag;
526
3.67k
      skaclass = aclass;
527
153k
    } else {
528
153k
      skaclass = V_ASN1_UNIVERSAL;
529
153k
      if (flags & ASN1_TFLG_SET_OF) {
530
0
        sktag = V_ASN1_SET;
531
153k
      } else {
532
153k
        sktag = V_ASN1_SEQUENCE;
533
153k
      }
534
153k
    }
535
    // Get the tag
536
157k
    ret = asn1_check_tlen(&len, nullptr, nullptr, nullptr, &p, len, sktag,
537
157k
                          skaclass, opt);
538
157k
    if (!ret) {
539
3.52k
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
540
3.52k
      return 0;
541
153k
    } else if (ret == -1) {
542
950
      return -1;
543
950
    }
544
152k
    if (!*val) {
545
152k
      *val = (ASN1_VALUE *)sk_ASN1_VALUE_new_null();
546
152k
    } else {
547
      // We've got a valid STACK: free up any items present
548
15
      STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val;
549
15
      ASN1_VALUE *vtmp;
550
15
      while (sk_ASN1_VALUE_num(sktmp) > 0) {
551
0
        vtmp = sk_ASN1_VALUE_pop(sktmp);
552
0
        ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
553
0
      }
554
15
    }
555
556
152k
    if (!*val) {
557
0
      goto err;
558
0
    }
559
560
    // Read as many items as we can
561
814k
    while (len > 0) {
562
667k
      ASN1_VALUE *skfield;
563
667k
      const unsigned char *q = p;
564
667k
      skfield = nullptr;
565
667k
      if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item),
566
667k
                            /*tag=*/-1, /*aclass=*/0, /*opt=*/0, depth)) {
567
5.29k
        ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item));
568
5.29k
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
569
5.29k
        goto err;
570
5.29k
      }
571
662k
      len -= p - q;
572
662k
      if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
573
0
        ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item));
574
0
        goto err;
575
0
      }
576
662k
    }
577
2.56M
  } else if (flags & ASN1_TFLG_IMPTAG) {
578
    // IMPLICIT tagging
579
1.20M
    ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag,
580
1.20M
                           aclass, opt, depth);
581
1.20M
    if (!ret) {
582
1.73k
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
583
1.73k
      goto err;
584
1.20M
    } else if (ret == -1) {
585
982k
      return -1;
586
982k
    }
587
1.36M
  } else {
588
    // Nothing special
589
1.36M
    ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), /*tag=*/-1,
590
1.36M
                           /*aclass=*/0, opt, depth);
591
1.36M
    if (!ret) {
592
2.32k
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
593
2.32k
      goto err;
594
1.35M
    } else if (ret == -1) {
595
320k
      return -1;
596
320k
    }
597
1.36M
  }
598
599
1.40M
  *in = p;
600
1.40M
  return 1;
601
602
9.35k
err:
603
9.35k
  ASN1_template_free(val, tt);
604
9.35k
  return 0;
605
2.72M
}
606
607
// TODO(crbug.com/42290418): Switch the whole file to use a CBS-based calling
608
// convention.
609
static int asn1_d2i_ex_primitive_cbs(ASN1_VALUE **pval, CBS *cbs,
610
                                     const ASN1_ITEM *it, int tag, int aclass,
611
                                     char opt);
612
613
// asn1_d2i_ex_primitive returns one on success, zero on error, and -1 if an
614
// optional value was skipped.
615
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in,
616
                                 long inlen, const ASN1_ITEM *it, int tag,
617
2.22M
                                 int aclass, char opt) {
618
2.22M
  CBS cbs;
619
2.22M
  CBS_init(&cbs, *in, inlen);
620
2.22M
  int ret = asn1_d2i_ex_primitive_cbs(pval, &cbs, it, tag, aclass, opt);
621
2.22M
  if (ret <= 0) {
622
923k
    return ret;
623
923k
  }
624
1.29M
  *in = CBS_data(&cbs);
625
1.29M
  return 1;
626
2.22M
}
627
628
659k
static ASN1_STRING *ensure_string(ASN1_VALUE **pval) {
629
659k
  if (*pval) {
630
444k
    return (ASN1_STRING *)*pval;
631
444k
  }
632
214k
  ASN1_STRING *str = ASN1_STRING_new();
633
214k
  if (str == nullptr) {
634
0
    return nullptr;
635
0
  }
636
214k
  *pval = (ASN1_VALUE *)str;
637
214k
  return str;
638
214k
}
639
640
static int asn1_d2i_ex_primitive_cbs(ASN1_VALUE **pval, CBS *cbs,
641
                                     const ASN1_ITEM *it, int tag, int aclass,
642
2.22M
                                     char opt) {
643
  // Historically, |it->funcs| for primitive types contained an
644
  // |ASN1_PRIMITIVE_FUNCS| table of callbacks.
645
2.22M
  assert(it->funcs == nullptr);
646
647
2.22M
  int utype;
648
2.22M
  assert(it->itype == ASN1_ITYPE_PRIMITIVE || it->itype == ASN1_ITYPE_MSTRING);
649
2.22M
  if (it->itype == ASN1_ITYPE_MSTRING) {
650
    // MSTRING passes utype in |tag|, normally used for implicit tagging.
651
408
    utype = tag;
652
408
    tag = -1;
653
2.22M
  } else {
654
2.22M
    utype = it->utype;
655
2.22M
  }
656
657
  // Handle ANY types.
658
2.22M
  if (utype == V_ASN1_ANY) {
659
52.4k
    if (tag >= 0) {
660
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY);
661
0
      return 0;
662
0
    }
663
52.4k
    if (opt && CBS_len(cbs) == 0) {
664
0
      return -1;  // Omitted OPTIONAL value.
665
0
    }
666
52.4k
    ASN1_TYPE *typ;
667
52.4k
    if (!*pval) {
668
45.5k
      typ = ASN1_TYPE_new();
669
45.5k
      if (typ == nullptr) {
670
0
        return 0;
671
0
      }
672
45.5k
      *pval = (ASN1_VALUE *)typ;
673
45.5k
    } else {
674
6.94k
      typ = (ASN1_TYPE *)*pval;
675
6.94k
    }
676
52.4k
    return asn1_parse_any(cbs, typ);
677
52.4k
  }
678
679
  // Convert the crypto/asn1 tag into a CBS one.
680
2.16M
  if (tag == -1) {
681
1.36M
    tag = utype;
682
1.36M
    aclass = V_ASN1_UNIVERSAL;
683
1.36M
  }
684
685
  // All edge cases of |utype| should have been handled already. |utype| is now
686
  // either a primitive |ASN1_ITEM|, handled by |DECLARE_ASN1_ITEM|, or a
687
  // multistring option with a corresponding |B_ASN1_*| constant.
688
2.16M
  assert(utype >= 0 && utype <= V_ASN1_MAX_UNIVERSAL);
689
2.16M
  CBS_ASN1_TAG cbs_tag =
690
2.16M
      (static_cast<CBS_ASN1_TAG>(aclass) << CBS_ASN1_TAG_SHIFT) |
691
2.16M
      static_cast<CBS_ASN1_TAG>(tag);
692
2.16M
  if (utype == V_ASN1_SEQUENCE || utype == V_ASN1_SET) {
693
185k
    cbs_tag |= CBS_ASN1_CONSTRUCTED;
694
185k
  }
695
696
2.16M
  if (opt && !CBS_peek_asn1_tag(cbs, cbs_tag)) {
697
913k
    return -1;  // Omitted OPTIONAL value.
698
913k
  }
699
700
  // Handle non-|ASN1_STRING| types.
701
1.25M
  switch (utype) {
702
469k
    case V_ASN1_OBJECT: {
703
469k
      UniquePtr<ASN1_OBJECT> obj(asn1_parse_object(cbs, cbs_tag));
704
469k
      if (obj == nullptr) {
705
602
        return 0;
706
602
      }
707
468k
      ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
708
468k
      *pval = (ASN1_VALUE *)obj.release();
709
468k
      return 1;
710
469k
    }
711
55
    case V_ASN1_NULL: {
712
55
      CBS null;
713
55
      if (!CBS_get_asn1(cbs, &null, cbs_tag)) {
714
37
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
715
37
        return 0;
716
37
      }
717
18
      if (CBS_len(&null) != 0) {
718
11
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH);
719
11
        return 0;
720
11
      }
721
7
      *pval = (ASN1_VALUE *)1;
722
7
      return 1;
723
18
    }
724
124k
    case V_ASN1_BOOLEAN: {
725
124k
      CBS child;
726
124k
      if (!CBS_get_asn1(cbs, &child, cbs_tag)) {
727
165
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
728
165
        return 0;
729
165
      }
730
      // TODO(crbug.com/42290221): Reject invalid BOOLEAN encodings and just
731
      // call |CBS_get_asn1_bool|.
732
124k
      if (CBS_len(&child) != 1) {
733
116
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
734
116
        return 0;
735
116
      }
736
124k
      ASN1_BOOLEAN *tbool;
737
124k
      tbool = (ASN1_BOOLEAN *)pval;
738
124k
      *tbool = CBS_data(&child)[0];
739
124k
      return 1;
740
124k
    }
741
1.25M
  }
742
743
  // All other types as an |ASN1_STRING| representation.
744
659k
  ASN1_STRING *str = ensure_string(pval);
745
659k
  if (str == nullptr) {
746
0
    return 0;
747
0
  }
748
749
659k
  switch (utype) {
750
3.66k
    case V_ASN1_BIT_STRING:
751
3.66k
      return asn1_parse_bit_string(cbs, str, cbs_tag);
752
2.81k
    case V_ASN1_INTEGER:
753
2.81k
      return asn1_parse_integer(cbs, str, cbs_tag);
754
2.90k
    case V_ASN1_ENUMERATED:
755
2.90k
      return asn1_parse_enumerated(cbs, str, cbs_tag);
756
61
    case V_ASN1_UNIVERSALSTRING:
757
61
      return asn1_parse_universal_string(cbs, str, cbs_tag);
758
65
    case V_ASN1_BMPSTRING:
759
65
      return asn1_parse_bmp_string(cbs, str, cbs_tag);
760
113
    case V_ASN1_UTF8STRING:
761
113
      return asn1_parse_utf8_string(cbs, str, cbs_tag);
762
0
    case V_ASN1_UTCTIME:
763
      // TODO(crbug.com/42290221): Reject timezone offsets. We need to parse
764
      // invalid timestamps in |X509| objects, but that parser no longer uses
765
      // this code.
766
0
      return asn1_parse_utc_time(cbs, str, cbs_tag,
767
0
                                 /*allow_timezone_offset=*/1);
768
2.18k
    case V_ASN1_GENERALIZEDTIME:
769
2.18k
      return asn1_parse_generalized_time(cbs, str, cbs_tag);
770
457k
    case V_ASN1_OCTET_STRING:
771
457k
    case V_ASN1_NUMERICSTRING:
772
457k
    case V_ASN1_PRINTABLESTRING:
773
457k
    case V_ASN1_T61STRING:
774
457k
    case V_ASN1_VIDEOTEXSTRING:
775
640k
    case V_ASN1_IA5STRING:
776
640k
    case V_ASN1_GRAPHICSTRING:
777
640k
    case V_ASN1_VISIBLESTRING:
778
640k
    case V_ASN1_GENERALSTRING:
779
      // T61String is parsed as Latin-1, so all byte strings are valid. The
780
      // others we currently do not enforce.
781
      //
782
      // TODO(crbug.com/42290290): Enforce the encoding of the other string
783
      // types.
784
640k
      if (!asn1_parse_octet_string(cbs, str, cbs_tag)) {
785
1.19k
        return 0;
786
1.19k
      }
787
638k
      str->type = utype;
788
638k
      return 1;
789
7.68k
    case V_ASN1_SEQUENCE: {
790
      // Save the entire element in the string.
791
7.68k
      CBS elem;
792
7.68k
      if (!CBS_get_asn1_element(cbs, &elem, cbs_tag)) {
793
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
794
0
        return 0;
795
0
      }
796
7.68k
      str->type = V_ASN1_SEQUENCE;
797
7.68k
      return ASN1_STRING_set(str, CBS_data(&elem), CBS_len(&elem));
798
7.68k
    }
799
0
    default:
800
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
801
0
      return 0;
802
659k
    }
803
659k
}
804
805
// Check an ASN1 tag and length: a bit like ASN1_get_object but it
806
// checks the expected tag.
807
808
static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
809
                           char *cst, const unsigned char **in, long len,
810
1.20M
                           int exptag, int expclass, char opt) {
811
1.20M
  int i;
812
1.20M
  int ptag, pclass;
813
1.20M
  long plen;
814
1.20M
  const unsigned char *p;
815
1.20M
  p = *in;
816
817
1.20M
  i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
818
1.20M
  if (i & 0x80) {
819
4.37k
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER);
820
4.37k
    return 0;
821
4.37k
  }
822
1.19M
  if (exptag >= 0) {
823
1.19M
    if ((exptag != ptag) || (expclass != pclass)) {
824
      // If type is OPTIONAL, not an error: indicate missing type.
825
567k
      if (opt) {
826
565k
        return -1;
827
565k
      }
828
2.60k
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG);
829
2.60k
      return 0;
830
567k
    }
831
1.19M
  }
832
833
628k
  if (cst) {
834
475k
    *cst = i & V_ASN1_CONSTRUCTED;
835
475k
  }
836
837
628k
  if (olen) {
838
628k
    *olen = plen;
839
628k
  }
840
841
628k
  if (oclass) {
842
478
    *oclass = pclass;
843
478
  }
844
845
628k
  if (otag) {
846
478
    *otag = ptag;
847
478
  }
848
849
628k
  *in = p;
850
628k
  return 1;
851
1.19M
}