Coverage Report

Created: 2023-06-29 07:25

/src/boringssl/crypto/asn1/tasn_enc.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2
 * All rights reserved.
3
 *
4
 * This package is an SSL implementation written
5
 * by Eric Young (eay@cryptsoft.com).
6
 * The implementation was written so as to conform with Netscapes SSL.
7
 *
8
 * This library is free for commercial and non-commercial use as long as
9
 * the following conditions are aheared to.  The following conditions
10
 * apply to all code found in this distribution, be it the RC4, RSA,
11
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12
 * included with this distribution is covered by the same copyright terms
13
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14
 *
15
 * Copyright remains Eric Young's, and as such any Copyright notices in
16
 * the code are not to be removed.
17
 * If this package is used in a product, Eric Young should be given attribution
18
 * as the author of the parts of the library used.
19
 * This can be in the form of a textual message at program startup or
20
 * in documentation (online or textual) provided with the package.
21
 *
22
 * Redistribution and use in source and binary forms, with or without
23
 * modification, are permitted provided that the following conditions
24
 * are met:
25
 * 1. Redistributions of source code must retain the copyright
26
 *    notice, this list of conditions and the following disclaimer.
27
 * 2. Redistributions in binary form must reproduce the above copyright
28
 *    notice, this list of conditions and the following disclaimer in the
29
 *    documentation and/or other materials provided with the distribution.
30
 * 3. All advertising materials mentioning features or use of this software
31
 *    must display the following acknowledgement:
32
 *    "This product includes cryptographic software written by
33
 *     Eric Young (eay@cryptsoft.com)"
34
 *    The word 'cryptographic' can be left out if the rouines from the library
35
 *    being used are not cryptographic related :-).
36
 * 4. If you include any Windows specific code (or a derivative thereof) from
37
 *    the apps directory (application code) you must include an acknowledgement:
38
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39
 *
40
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50
 * SUCH DAMAGE.
51
 *
52
 * The licence and distribution terms for any publically available version or
53
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
54
 * copied and put under another distribution licence
55
 * [including the GNU Public Licence.] */
56
57
#include <openssl/asn1.h>
58
59
#include <assert.h>
60
#include <limits.h>
61
#include <string.h>
62
63
#include <openssl/asn1t.h>
64
#include <openssl/mem.h>
65
66
#include "../internal.h"
67
#include "internal.h"
68
69
70
static int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out,
71
                                const ASN1_ITEM *it, int tag, int aclass,
72
                                int optional);
73
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
74
                                 const ASN1_ITEM *it, int tag, int aclass,
75
                                 int optional);
76
static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *out_omit,
77
                       int *putype, const ASN1_ITEM *it);
78
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
79
                            int skcontlen, const ASN1_ITEM *item, int do_sort);
80
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
81
                                const ASN1_TEMPLATE *tt, int tag, int aclass,
82
                                int optional);
83
84
// Top level i2d equivalents
85
86
502k
int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) {
87
502k
  if (out && !*out) {
88
328k
    unsigned char *p, *buf;
89
328k
    int len = ASN1_item_ex_i2d(&val, NULL, it, /*tag=*/-1, /*aclass=*/0);
90
328k
    if (len <= 0) {
91
211
      return len;
92
211
    }
93
327k
    buf = OPENSSL_malloc(len);
94
327k
    if (!buf) {
95
0
      return -1;
96
0
    }
97
327k
    p = buf;
98
327k
    int len2 = ASN1_item_ex_i2d(&val, &p, it, /*tag=*/-1, /*aclass=*/0);
99
327k
    if (len2 <= 0) {
100
0
      OPENSSL_free(buf);
101
0
      return len2;
102
0
    }
103
327k
    assert(len == len2);
104
327k
    *out = buf;
105
327k
    return len;
106
327k
  }
107
108
174k
  return ASN1_item_ex_i2d(&val, out, it, /*tag=*/-1, /*aclass=*/0);
109
502k
}
110
111
// Encode an item, taking care of IMPLICIT tagging (if any). This function
112
// performs the normal item handling: it can be used in external types.
113
114
int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
115
8.71M
                     const ASN1_ITEM *it, int tag, int aclass) {
116
8.71M
  int ret = asn1_item_ex_i2d_opt(pval, out, it, tag, aclass, /*optional=*/0);
117
8.71M
  assert(ret != 0);
118
8.71M
  return ret;
119
8.71M
}
120
121
// asn1_item_ex_i2d_opt behaves like |ASN1_item_ex_i2d| but, if |optional| is
122
// non-zero and |*pval| is omitted, it returns zero and writes no bytes.
123
int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out,
124
                         const ASN1_ITEM *it, int tag, int aclass,
125
23.1M
                         int optional) {
126
23.1M
  const ASN1_TEMPLATE *tt = NULL;
127
23.1M
  int i, seqcontlen, seqlen;
128
129
  // Historically, |aclass| was repurposed to pass additional flags into the
130
  // encoding process.
131
23.1M
  assert((aclass & ASN1_TFLG_TAG_CLASS) == aclass);
132
  // If not overridding the tag, |aclass| is ignored and should be zero.
133
23.1M
  assert(tag != -1 || aclass == 0);
134
135
  // All fields are pointers, except for boolean |ASN1_ITYPE_PRIMITIVE|s.
136
  // Optional primitives are handled later.
137
23.1M
  if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) {
138
95.1k
    if (optional) {
139
95.1k
      return 0;
140
95.1k
    }
141
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
142
0
    return -1;
143
95.1k
  }
144
145
23.1M
  switch (it->itype) {
146
9.86M
    case ASN1_ITYPE_PRIMITIVE:
147
9.86M
      if (it->templates) {
148
        // This is an |ASN1_ITEM_TEMPLATE|.
149
2.17M
        if (it->templates->flags & ASN1_TFLG_OPTIONAL) {
150
0
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
151
0
          return -1;
152
0
        }
153
2.17M
        return asn1_template_ex_i2d(pval, out, it->templates, tag, aclass,
154
2.17M
                                    optional);
155
2.17M
      }
156
7.68M
      return asn1_i2d_ex_primitive(pval, out, it, tag, aclass, optional);
157
158
6.13M
    case ASN1_ITYPE_MSTRING:
159
      // It never makes sense for multi-strings to have implicit tagging, so
160
      // if tag != -1, then this looks like an error in the template.
161
6.13M
      if (tag != -1) {
162
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
163
0
        return -1;
164
0
      }
165
6.13M
      return asn1_i2d_ex_primitive(pval, out, it, -1, 0, optional);
166
167
1.52M
    case ASN1_ITYPE_CHOICE: {
168
      // It never makes sense for CHOICE types to have implicit tagging, so if
169
      // tag != -1, then this looks like an error in the template.
170
1.52M
      if (tag != -1) {
171
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
172
0
        return -1;
173
0
      }
174
1.52M
      i = asn1_get_choice_selector(pval, it);
175
1.52M
      if (i < 0 || i >= it->tcount) {
176
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
177
0
        return -1;
178
0
      }
179
1.52M
      const ASN1_TEMPLATE *chtt = it->templates + i;
180
1.52M
      if (chtt->flags & ASN1_TFLG_OPTIONAL) {
181
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
182
0
        return -1;
183
0
      }
184
1.52M
      ASN1_VALUE **pchval = asn1_get_field_ptr(pval, chtt);
185
1.52M
      return asn1_template_ex_i2d(pchval, out, chtt, -1, 0, /*optional=*/0);
186
1.52M
    }
187
188
677k
    case ASN1_ITYPE_EXTERN: {
189
      // We don't support implicit tagging with external types.
190
677k
      if (tag != -1) {
191
0
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
192
0
        return -1;
193
0
      }
194
677k
      const ASN1_EXTERN_FUNCS *ef = it->funcs;
195
677k
      int ret = ef->asn1_ex_i2d(pval, out, it);
196
677k
      if (ret == 0) {
197
        // |asn1_ex_i2d| should never return zero. We have already checked
198
        // for optional values generically, and |ASN1_ITYPE_EXTERN| fields
199
        // must be pointers.
200
0
        OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR);
201
0
        return -1;
202
0
      }
203
677k
      return ret;
204
677k
    }
205
206
4.90M
    case ASN1_ITYPE_SEQUENCE: {
207
4.90M
      i = asn1_enc_restore(&seqcontlen, out, pval, it);
208
      // An error occurred
209
4.90M
      if (i < 0) {
210
0
        return -1;
211
0
      }
212
      // We have a valid cached encoding...
213
4.90M
      if (i > 0) {
214
58.1k
        return seqcontlen;
215
58.1k
      }
216
      // Otherwise carry on
217
4.84M
      seqcontlen = 0;
218
      // If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL
219
4.84M
      if (tag == -1) {
220
4.79M
        tag = V_ASN1_SEQUENCE;
221
4.79M
        aclass = V_ASN1_UNIVERSAL;
222
4.79M
      }
223
      // First work out sequence content length
224
14.6M
      for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
225
9.79M
        const ASN1_TEMPLATE *seqtt;
226
9.79M
        ASN1_VALUE **pseqval;
227
9.79M
        int tmplen;
228
9.79M
        seqtt = asn1_do_adb(pval, tt, 1);
229
9.79M
        if (!seqtt) {
230
0
          return -1;
231
0
        }
232
9.79M
        pseqval = asn1_get_field_ptr(pval, seqtt);
233
9.79M
        tmplen =
234
9.79M
            asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, 0, /*optional=*/0);
235
9.79M
        if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen)) {
236
208
          return -1;
237
208
        }
238
9.79M
        seqcontlen += tmplen;
239
9.79M
      }
240
241
4.84M
      seqlen = ASN1_object_size(/*constructed=*/1, seqcontlen, tag);
242
4.84M
      if (!out || seqlen == -1) {
243
3.22M
        return seqlen;
244
3.22M
      }
245
      // Output SEQUENCE header
246
1.62M
      ASN1_put_object(out, /*constructed=*/1, seqcontlen, tag, aclass);
247
4.91M
      for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
248
3.28M
        const ASN1_TEMPLATE *seqtt;
249
3.28M
        ASN1_VALUE **pseqval;
250
3.28M
        seqtt = asn1_do_adb(pval, tt, 1);
251
3.28M
        if (!seqtt) {
252
0
          return -1;
253
0
        }
254
3.28M
        pseqval = asn1_get_field_ptr(pval, seqtt);
255
3.28M
        if (asn1_template_ex_i2d(pseqval, out, seqtt, -1, 0, /*optional=*/0) <
256
3.28M
            0) {
257
0
          return -1;
258
0
        }
259
3.28M
      }
260
1.62M
      return seqlen;
261
1.62M
    }
262
263
0
    default:
264
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
265
0
      return -1;
266
23.1M
  }
267
23.1M
}
268
269
// asn1_template_ex_i2d behaves like |asn1_item_ex_i2d_opt| but uses an
270
// |ASN1_TEMPLATE| instead of an |ASN1_ITEM|. An |ASN1_TEMPLATE| wraps an
271
// |ASN1_ITEM| with modifiers such as tagging, SEQUENCE or SET, etc.
272
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
273
                                const ASN1_TEMPLATE *tt, int tag, int iclass,
274
16.7M
                                int optional) {
275
16.7M
  int i, ret, ttag, tclass;
276
16.7M
  size_t j;
277
16.7M
  uint32_t flags = tt->flags;
278
279
  // Historically, |iclass| was repurposed to pass additional flags into the
280
  // encoding process.
281
16.7M
  assert((iclass & ASN1_TFLG_TAG_CLASS) == iclass);
282
  // If not overridding the tag, |iclass| is ignored and should be zero.
283
16.7M
  assert(tag != -1 || iclass == 0);
284
285
  // Work out tag and class to use: tagging may come either from the
286
  // template or the arguments, not both because this would create
287
  // ambiguity.
288
16.7M
  if (flags & ASN1_TFLG_TAG_MASK) {
289
    // Error if argument and template tagging
290
1.92M
    if (tag != -1) {
291
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
292
0
      return -1;
293
0
    }
294
    // Get tagging from template
295
1.92M
    ttag = tt->tag;
296
1.92M
    tclass = flags & ASN1_TFLG_TAG_CLASS;
297
14.8M
  } else if (tag != -1) {
298
    // No template tagging, get from arguments
299
0
    ttag = tag;
300
0
    tclass = iclass & ASN1_TFLG_TAG_CLASS;
301
14.8M
  } else {
302
14.8M
    ttag = -1;
303
14.8M
    tclass = 0;
304
14.8M
  }
305
306
  // The template may itself by marked as optional, or this may be the template
307
  // of an |ASN1_ITEM_TEMPLATE| type which was contained inside an outer
308
  // optional template. (They cannot both be true because the
309
  // |ASN1_ITEM_TEMPLATE| codepath rejects optional templates.)
310
16.7M
  assert(!optional || (flags & ASN1_TFLG_OPTIONAL) == 0);
311
16.7M
  optional = optional || (flags & ASN1_TFLG_OPTIONAL) != 0;
312
313
  // At this point 'ttag' contains the outer tag to use, and 'tclass' is the
314
  // class.
315
316
16.7M
  if (flags & ASN1_TFLG_SK_MASK) {
317
    // SET OF, SEQUENCE OF
318
2.30M
    STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
319
2.30M
    int isset, sktag, skaclass;
320
2.30M
    int skcontlen, sklen;
321
2.30M
    ASN1_VALUE *skitem;
322
323
2.30M
    if (!*pval) {
324
32.8k
      if (optional) {
325
32.8k
        return 0;
326
32.8k
      }
327
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
328
0
      return -1;
329
32.8k
    }
330
331
2.27M
    if (flags & ASN1_TFLG_SET_OF) {
332
1.94M
      isset = 1;
333
      // Historically, types with both bits set were mutated when
334
      // serialized to apply the sort. We no longer support this.
335
1.94M
      assert((flags & ASN1_TFLG_SEQUENCE_OF) == 0);
336
1.94M
    } else {
337
323k
      isset = 0;
338
323k
    }
339
340
    // Work out inner tag value: if EXPLICIT or no tagging use underlying
341
    // type.
342
2.27M
    if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
343
99.5k
      sktag = ttag;
344
99.5k
      skaclass = tclass;
345
2.17M
    } else {
346
2.17M
      skaclass = V_ASN1_UNIVERSAL;
347
2.17M
      if (isset) {
348
1.94M
        sktag = V_ASN1_SET;
349
1.94M
      } else {
350
227k
        sktag = V_ASN1_SEQUENCE;
351
227k
      }
352
2.17M
    }
353
354
    // Determine total length of items
355
2.27M
    skcontlen = 0;
356
6.56M
    for (j = 0; j < sk_ASN1_VALUE_num(sk); j++) {
357
4.28M
      int tmplen;
358
4.28M
      skitem = sk_ASN1_VALUE_value(sk, j);
359
4.28M
      tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), -1, 0);
360
4.28M
      if (tmplen == -1 || (skcontlen > INT_MAX - tmplen)) {
361
243
        return -1;
362
243
      }
363
4.28M
      skcontlen += tmplen;
364
4.28M
    }
365
2.27M
    sklen = ASN1_object_size(/*constructed=*/1, skcontlen, sktag);
366
2.27M
    if (sklen == -1) {
367
0
      return -1;
368
0
    }
369
    // If EXPLICIT need length of surrounding tag
370
2.27M
    if (flags & ASN1_TFLG_EXPTAG) {
371
0
      ret = ASN1_object_size(/*constructed=*/1, sklen, ttag);
372
2.27M
    } else {
373
2.27M
      ret = sklen;
374
2.27M
    }
375
376
2.27M
    if (!out || ret == -1) {
377
1.23M
      return ret;
378
1.23M
    }
379
380
    // Now encode this lot...
381
    // EXPLICIT tag
382
1.03M
    if (flags & ASN1_TFLG_EXPTAG) {
383
0
      ASN1_put_object(out, /*constructed=*/1, sklen, ttag, tclass);
384
0
    }
385
    // SET or SEQUENCE and IMPLICIT tag
386
1.03M
    ASN1_put_object(out, /*constructed=*/1, skcontlen, sktag, skaclass);
387
    // And the stuff itself
388
1.03M
    if (!asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), isset)) {
389
0
      return -1;
390
0
    }
391
1.03M
    return ret;
392
1.03M
  }
393
394
14.4M
  if (flags & ASN1_TFLG_EXPTAG) {
395
    // EXPLICIT tagging
396
    // Find length of tagged item
397
727k
    i = asn1_item_ex_i2d_opt(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, 0,
398
727k
                             optional);
399
727k
    if (i <= 0) {
400
95.1k
      return i;
401
95.1k
    }
402
    // Find length of EXPLICIT tag
403
632k
    ret = ASN1_object_size(/*constructed=*/1, i, ttag);
404
632k
    if (out && ret != -1) {
405
      // Output tag and item
406
125k
      ASN1_put_object(out, /*constructed=*/1, i, ttag, tclass);
407
125k
      if (ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0) < 0) {
408
0
        return -1;
409
0
      }
410
125k
    }
411
632k
    return ret;
412
632k
  }
413
414
  // Either normal or IMPLICIT tagging
415
13.7M
  return asn1_item_ex_i2d_opt(pval, out, ASN1_ITEM_ptr(tt->item), ttag, tclass,
416
13.7M
                              optional);
417
14.4M
}
418
419
// Temporary structure used to hold DER encoding of items for SET OF
420
421
typedef struct {
422
  unsigned char *data;
423
  int length;
424
} DER_ENC;
425
426
500k
static int der_cmp(const void *a, const void *b) {
427
500k
  const DER_ENC *d1 = a, *d2 = b;
428
500k
  int cmplen, i;
429
500k
  cmplen = (d1->length < d2->length) ? d1->length : d2->length;
430
500k
  i = OPENSSL_memcmp(d1->data, d2->data, cmplen);
431
500k
  if (i) {
432
450k
    return i;
433
450k
  }
434
50.0k
  return d1->length - d2->length;
435
500k
}
436
437
// asn1_set_seq_out writes |sk| to |out| under the i2d output convention,
438
// excluding the tag and length. It returns one on success and zero on error.
439
// |skcontlen| must be the total encoded size. If |do_sort| is non-zero, the
440
// elements are sorted for a SET OF type. Each element of |sk| has type
441
// |item|.
442
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
443
1.03M
                            int skcontlen, const ASN1_ITEM *item, int do_sort) {
444
  // No need to sort if there are fewer than two items.
445
1.03M
  if (!do_sort || sk_ASN1_VALUE_num(sk) < 2) {
446
2.13M
    for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
447
1.25M
      ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i);
448
1.25M
      if (ASN1_item_ex_i2d(&skitem, out, item, -1, 0) < 0) {
449
0
        return 0;
450
0
      }
451
1.25M
    }
452
882k
    return 1;
453
882k
  }
454
455
155k
  if (sk_ASN1_VALUE_num(sk) > ((size_t)-1) / sizeof(DER_ENC)) {
456
0
    OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW);
457
0
    return 0;
458
0
  }
459
460
155k
  int ret = 0;
461
155k
  unsigned char *const buf = OPENSSL_malloc(skcontlen);
462
155k
  DER_ENC *encoded = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*encoded));
463
155k
  if (encoded == NULL || buf == NULL) {
464
0
    goto err;
465
0
  }
466
467
  // Encode all the elements into |buf| and populate |encoded|.
468
155k
  unsigned char *p = buf;
469
642k
  for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
470
486k
    ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i);
471
486k
    encoded[i].data = p;
472
486k
    encoded[i].length = ASN1_item_ex_i2d(&skitem, &p, item, -1, 0);
473
486k
    if (encoded[i].length < 0) {
474
0
      goto err;
475
0
    }
476
486k
    assert(p - buf <= skcontlen);
477
486k
  }
478
479
155k
  qsort(encoded, sk_ASN1_VALUE_num(sk), sizeof(*encoded), der_cmp);
480
481
  // Output the elements in sorted order.
482
155k
  p = *out;
483
642k
  for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
484
486k
    OPENSSL_memcpy(p, encoded[i].data, encoded[i].length);
485
486k
    p += encoded[i].length;
486
486k
  }
487
155k
  *out = p;
488
489
155k
  ret = 1;
490
491
155k
err:
492
155k
  OPENSSL_free(encoded);
493
155k
  OPENSSL_free(buf);
494
155k
  return ret;
495
155k
}
496
497
// asn1_i2d_ex_primitive behaves like |ASN1_item_ex_i2d| but |item| must be a
498
// a PRIMITIVE or MSTRING type that is not an |ASN1_ITEM_TEMPLATE|.
499
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
500
                                 const ASN1_ITEM *it, int tag, int aclass,
501
13.8M
                                 int optional) {
502
  // Get length of content octets and maybe find out the underlying type.
503
13.8M
  int omit;
504
13.8M
  int utype = it->utype;
505
13.8M
  int len = asn1_ex_i2c(pval, NULL, &omit, &utype, it);
506
13.8M
  if (len < 0) {
507
211
    return -1;
508
211
  }
509
13.8M
  if (omit) {
510
160k
    if (optional) {
511
160k
      return 0;
512
160k
    }
513
0
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
514
0
    return -1;
515
160k
  }
516
517
  // If SEQUENCE, SET or OTHER then header is included in pseudo content
518
  // octets so don't include tag+length. We need to check here because the
519
  // call to asn1_ex_i2c() could change utype.
520
13.6M
  int usetag =
521
13.6M
      utype != V_ASN1_SEQUENCE && utype != V_ASN1_SET && utype != V_ASN1_OTHER;
522
523
  // If not implicitly tagged get tag from underlying type
524
13.6M
  if (tag == -1) {
525
12.7M
    tag = utype;
526
12.7M
  }
527
528
  // Output tag+length followed by content octets
529
13.6M
  if (out) {
530
3.42M
    if (usetag) {
531
3.39M
      ASN1_put_object(out, /*constructed=*/0, len, tag, aclass);
532
3.39M
    }
533
3.42M
    int len2 = asn1_ex_i2c(pval, *out, &omit, &utype, it);
534
3.42M
    if (len2 < 0) {
535
0
      return -1;
536
0
    }
537
3.42M
    assert(len == len2);
538
3.42M
    assert(!omit);
539
3.42M
    *out += len;
540
3.42M
  }
541
542
13.6M
  if (usetag) {
543
13.5M
    return ASN1_object_size(/*constructed=*/0, len, tag);
544
13.5M
  }
545
111k
  return len;
546
13.6M
}
547
548
// asn1_ex_i2c writes the |*pval| to |cout| under the i2d output convention,
549
// excluding the tag and length. It returns the number of bytes written,
550
// possibly zero, on success or -1 on error. If |*pval| should be omitted, it
551
// returns zero and sets |*out_omit| to true.
552
//
553
// If |it| is an MSTRING or ANY type, it gets the underlying type from |*pval|,
554
// which must be an |ASN1_STRING| or |ASN1_TYPE|, respectively. It then updates
555
// |*putype| with the tag number of type used, or |V_ASN1_OTHER| if it was not a
556
// universal type. If |*putype| is set to |V_ASN1_SEQUENCE|, |V_ASN1_SET|, or
557
// |V_ASN1_OTHER|, it additionally outputs the tag and length, so the caller
558
// must not do so.
559
//
560
// Otherwise, |*putype| must contain |it->utype|.
561
//
562
// WARNING: Unlike most functions in this file, |asn1_ex_i2c| can return zero
563
// without omitting the element. ASN.1 values may have empty contents.
564
static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *out_omit,
565
17.2M
                       int *putype, const ASN1_ITEM *it) {
566
17.2M
  ASN1_BOOLEAN *tbool = NULL;
567
17.2M
  ASN1_STRING *strtmp;
568
17.2M
  ASN1_OBJECT *otmp;
569
17.2M
  int utype;
570
17.2M
  const unsigned char *cont;
571
17.2M
  unsigned char c;
572
17.2M
  int len;
573
574
  // Historically, |it->funcs| for primitive types contained an
575
  // |ASN1_PRIMITIVE_FUNCS| table of callbacks.
576
17.2M
  assert(it->funcs == NULL);
577
578
17.2M
  *out_omit = 0;
579
580
  // Should type be omitted?
581
17.2M
  if ((it->itype != ASN1_ITYPE_PRIMITIVE) || (it->utype != V_ASN1_BOOLEAN)) {
582
17.2M
    if (!*pval) {
583
133k
      *out_omit = 1;
584
133k
      return 0;
585
133k
    }
586
17.2M
  }
587
588
17.1M
  if (it->itype == ASN1_ITYPE_MSTRING) {
589
    // If MSTRING type set the underlying type
590
7.66M
    strtmp = (ASN1_STRING *)*pval;
591
7.66M
    utype = strtmp->type;
592
7.66M
    if (utype < 0 && utype != V_ASN1_OTHER) {
593
      // MSTRINGs can have type -1 when default-constructed.
594
1
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE);
595
1
      return -1;
596
1
    }
597
    // Negative INTEGER and ENUMERATED values use |ASN1_STRING| type values
598
    // that do not match their corresponding utype values. INTEGERs cannot
599
    // participate in MSTRING types, but ENUMERATEDs can.
600
    //
601
    // TODO(davidben): Is this a bug? Although arguably one of the MSTRING
602
    // types should contain more values, rather than less. See
603
    // https://crbug.com/boringssl/412. But it is not possible to fit all
604
    // possible ANY values into an |ASN1_STRING|, so matching the spec here
605
    // is somewhat hopeless.
606
7.66M
    if (utype == V_ASN1_NEG_INTEGER) {
607
0
      utype = V_ASN1_INTEGER;
608
7.66M
    } else if (utype == V_ASN1_NEG_ENUMERATED) {
609
139k
      utype = V_ASN1_ENUMERATED;
610
139k
    }
611
7.66M
    *putype = utype;
612
9.44M
  } else if (it->utype == V_ASN1_ANY) {
613
    // If ANY set type and pointer to value
614
224k
    ASN1_TYPE *typ;
615
224k
    typ = (ASN1_TYPE *)*pval;
616
224k
    utype = typ->type;
617
224k
    if (utype < 0 && utype != V_ASN1_OTHER) {
618
      // |ASN1_TYPE|s can have type -1 when default-constructed.
619
0
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE);
620
0
      return -1;
621
0
    }
622
224k
    *putype = utype;
623
224k
    pval = &typ->value.asn1_value;
624
9.22M
  } else {
625
9.22M
    utype = *putype;
626
9.22M
  }
627
628
17.1M
  switch (utype) {
629
7.94M
    case V_ASN1_OBJECT:
630
7.94M
      otmp = (ASN1_OBJECT *)*pval;
631
7.94M
      cont = otmp->data;
632
7.94M
      len = otmp->length;
633
7.94M
      if (len == 0) {
634
        // Some |ASN1_OBJECT|s do not have OIDs and cannot be serialized.
635
210
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT);
636
210
        return -1;
637
210
      }
638
7.94M
      break;
639
640
7.94M
    case V_ASN1_NULL:
641
105k
      cont = NULL;
642
105k
      len = 0;
643
105k
      break;
644
645
30.3k
    case V_ASN1_BOOLEAN:
646
30.3k
      tbool = (ASN1_BOOLEAN *)pval;
647
30.3k
      if (*tbool == ASN1_BOOLEAN_NONE) {
648
27.2k
        *out_omit = 1;
649
27.2k
        return 0;
650
27.2k
      }
651
3.17k
      if (it->utype != V_ASN1_ANY) {
652
        // Default handling if value == size field then omit
653
655
        if ((*tbool && (it->size > 0)) || (!*tbool && !it->size)) {
654
387
          *out_omit = 1;
655
387
          return 0;
656
387
        }
657
655
      }
658
2.79k
      c = *tbool ? 0xff : 0x00;
659
2.79k
      cont = &c;
660
2.79k
      len = 1;
661
2.79k
      break;
662
663
177k
    case V_ASN1_BIT_STRING: {
664
177k
      int ret =
665
177k
          i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, cout ? &cout : NULL);
666
      // |i2c_ASN1_BIT_STRING| returns zero on error instead of -1.
667
177k
      return ret <= 0 ? -1 : ret;
668
3.17k
    }
669
670
26.5k
    case V_ASN1_INTEGER:
671
278k
    case V_ASN1_ENUMERATED: {
672
      // |i2c_ASN1_INTEGER| also handles ENUMERATED.
673
278k
      int ret = i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL);
674
      // |i2c_ASN1_INTEGER| returns zero on error instead of -1.
675
278k
      return ret <= 0 ? -1 : ret;
676
26.5k
    }
677
678
78.7k
    case V_ASN1_OCTET_STRING:
679
85.3k
    case V_ASN1_NUMERICSTRING:
680
93.5k
    case V_ASN1_PRINTABLESTRING:
681
97.4k
    case V_ASN1_T61STRING:
682
99.1k
    case V_ASN1_VIDEOTEXSTRING:
683
1.17M
    case V_ASN1_IA5STRING:
684
1.17M
    case V_ASN1_UTCTIME:
685
1.17M
    case V_ASN1_GENERALIZEDTIME:
686
1.17M
    case V_ASN1_GRAPHICSTRING:
687
1.17M
    case V_ASN1_VISIBLESTRING:
688
1.17M
    case V_ASN1_GENERALSTRING:
689
1.18M
    case V_ASN1_UNIVERSALSTRING:
690
1.19M
    case V_ASN1_BMPSTRING:
691
8.42M
    case V_ASN1_UTF8STRING:
692
8.54M
    case V_ASN1_SEQUENCE:
693
8.55M
    case V_ASN1_SET:
694
    // This is not a valid |ASN1_ITEM| type, but it appears in |ASN1_TYPE|.
695
8.56M
    case V_ASN1_OTHER:
696
    // TODO(crbug.com/boringssl/412): This default case should be removed, now
697
    // that we've resolved https://crbug.com/boringssl/561. However, it is still
698
    // needed to support some edge cases in |ASN1_PRINTABLE|. |ASN1_PRINTABLE|
699
    // broadly doesn't tolerate unrecognized universal tags, but except for
700
    // eight values that map to |B_ASN1_UNKNOWN| instead of zero. See the
701
    // X509Test.NameAttributeValues test.
702
8.57M
    default:
703
      // All based on ASN1_STRING and handled the same
704
8.57M
      strtmp = (ASN1_STRING *)*pval;
705
8.57M
      cont = strtmp->data;
706
8.57M
      len = strtmp->length;
707
8.57M
      break;
708
17.1M
  }
709
16.6M
  if (cout && len) {
710
3.28M
    OPENSSL_memcpy(cout, cont, len);
711
3.28M
  }
712
16.6M
  return len;
713
17.1M
}