tasn_enc.c
Go to the documentation of this file.
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 
83 /*
84  * Top level i2d equivalents
85  */
86 
87 int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
88 {
89  if (out && !*out) {
90  unsigned char *p, *buf;
91  int len = ASN1_item_ex_i2d(&val, NULL, it, /*tag=*/-1, /*aclass=*/0);
92  if (len <= 0) {
93  return len;
94  }
96  if (!buf) {
98  return -1;
99  }
100  p = buf;
101  int len2 = ASN1_item_ex_i2d(&val, &p, it, /*tag=*/-1, /*aclass=*/0);
102  if (len2 <= 0) {
103  return len2;
104  }
105  assert(len == len2);
106  *out = buf;
107  return len;
108  }
109 
110  return ASN1_item_ex_i2d(&val, out, it, /*tag=*/-1, /*aclass=*/0);
111 }
112 
113 /*
114  * Encode an item, taking care of IMPLICIT tagging (if any). This function
115  * performs the normal item handling: it can be used in external types.
116  */
117 
118 int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
119  const ASN1_ITEM *it, int tag, int aclass)
120 {
121  int ret = asn1_item_ex_i2d_opt(pval, out, it, tag, aclass, /*optional=*/0);
122  assert(ret != 0);
123  return ret;
124 }
125 
126 /* asn1_item_ex_i2d_opt behaves like |ASN1_item_ex_i2d| but, if |optional| is
127  * non-zero and |*pval| is omitted, it returns zero and writes no bytes. */
128 int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out,
129  const ASN1_ITEM *it, int tag, int aclass,
130  int optional)
131 {
132  const ASN1_TEMPLATE *tt = NULL;
133  int i, seqcontlen, seqlen;
134 
135  /* Historically, |aclass| was repurposed to pass additional flags into the
136  * encoding process. */
137  assert((aclass & ASN1_TFLG_TAG_CLASS) == aclass);
138  /* If not overridding the tag, |aclass| is ignored and should be zero. */
139  assert(tag != -1 || aclass == 0);
140 
141  /* All fields are pointers, except for boolean |ASN1_ITYPE_PRIMITIVE|s.
142  * Optional primitives are handled later. */
143  if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) {
144  if (optional) {
145  return 0;
146  }
148  return -1;
149  }
150 
151  switch (it->itype) {
152 
154  if (it->templates) {
155  if (it->templates->flags & ASN1_TFLG_OPTIONAL) {
157  return -1;
158  }
159  return asn1_template_ex_i2d(pval, out, it->templates, tag, aclass);
160  }
161  return asn1_i2d_ex_primitive(pval, out, it, tag, aclass, optional);
162 
163  case ASN1_ITYPE_MSTRING:
164  /*
165  * It never makes sense for multi-strings to have implicit tagging, so
166  * if tag != -1, then this looks like an error in the template.
167  */
168  if (tag != -1) {
170  return -1;
171  }
172  return asn1_i2d_ex_primitive(pval, out, it, -1, 0, optional);
173 
174  case ASN1_ITYPE_CHOICE: {
175  /*
176  * It never makes sense for CHOICE types to have implicit tagging, so if
177  * tag != -1, then this looks like an error in the template.
178  */
179  if (tag != -1) {
181  return -1;
182  }
183  i = asn1_get_choice_selector(pval, it);
184  if (i < 0 || i >= it->tcount) {
186  return -1;
187  }
188  const ASN1_TEMPLATE *chtt = it->templates + i;
189  if (chtt->flags & ASN1_TFLG_OPTIONAL) {
191  return -1;
192  }
193  ASN1_VALUE **pchval = asn1_get_field_ptr(pval, chtt);
194  return asn1_template_ex_i2d(pchval, out, chtt, -1, 0);
195  }
196 
197  case ASN1_ITYPE_EXTERN: {
198  /* If new style i2d it does all the work */
199  const ASN1_EXTERN_FUNCS *ef = it->funcs;
200  int ret = ef->asn1_ex_i2d(pval, out, it, tag, aclass);
201  if (ret == 0) {
202  /* |asn1_ex_i2d| should never return zero. We have already checked
203  * for optional values generically, and |ASN1_ITYPE_EXTERN| fields
204  * must be pointers. */
206  return -1;
207  }
208  return ret;
209  }
210 
211  case ASN1_ITYPE_SEQUENCE: {
212  i = asn1_enc_restore(&seqcontlen, out, pval, it);
213  /* An error occurred */
214  if (i < 0)
215  return -1;
216  /* We have a valid cached encoding... */
217  if (i > 0)
218  return seqcontlen;
219  /* Otherwise carry on */
220  seqcontlen = 0;
221  /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
222  if (tag == -1) {
224  aclass = V_ASN1_UNIVERSAL;
225  }
226  /* First work out sequence content length */
227  for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
228  const ASN1_TEMPLATE *seqtt;
229  ASN1_VALUE **pseqval;
230  int tmplen;
231  seqtt = asn1_do_adb(pval, tt, 1);
232  if (!seqtt)
233  return -1;
234  pseqval = asn1_get_field_ptr(pval, seqtt);
235  tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, 0);
236  if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen))
237  return -1;
238  seqcontlen += tmplen;
239  }
240 
241  seqlen = ASN1_object_size(/*constructed=*/1, seqcontlen, tag);
242  if (!out || seqlen == -1)
243  return seqlen;
244  /* Output SEQUENCE header */
245  ASN1_put_object(out, /*constructed=*/1, seqcontlen, tag, aclass);
246  for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
247  const ASN1_TEMPLATE *seqtt;
248  ASN1_VALUE **pseqval;
249  seqtt = asn1_do_adb(pval, tt, 1);
250  if (!seqtt)
251  return -1;
252  pseqval = asn1_get_field_ptr(pval, seqtt);
253  if (asn1_template_ex_i2d(pseqval, out, seqtt, -1, 0) < 0) {
254  return -1;
255  }
256  }
257  return seqlen;
258  }
259 
260  default:
262  return -1;
263  }
264 }
265 
266 /* asn1_template_ex_i2d behaves like |asn1_item_ex_i2d_opt| but uses an
267  * |ASN1_TEMPLATE| instead of an |ASN1_ITEM|. An |ASN1_TEMPLATE| wraps an
268  * |ASN1_ITEM| with modifiers such as tagging, SEQUENCE or SET, etc. Instead of
269  * taking an |optional| parameter, it uses the |ASN1_TFLG_OPTIONAL| flag. */
270 static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
271  const ASN1_TEMPLATE *tt, int tag, int iclass)
272 {
273  int i, ret, flags, ttag, tclass;
274  size_t j;
275  flags = tt->flags;
276 
277  /* Historically, |iclass| was repurposed to pass additional flags into the
278  * encoding process. */
279  assert((iclass & ASN1_TFLG_TAG_CLASS) == iclass);
280  /* If not overridding the tag, |iclass| is ignored and should be zero. */
281  assert(tag != -1 || iclass == 0);
282 
283  /*
284  * Work out tag and class to use: tagging may come either from the
285  * template or the arguments, not both because this would create
286  * ambiguity.
287  */
288  if (flags & ASN1_TFLG_TAG_MASK) {
289  /* Error if argument and template tagging */
290  if (tag != -1) {
292  return -1;
293  }
294  /* Get tagging from template */
295  ttag = tt->tag;
296  tclass = flags & ASN1_TFLG_TAG_CLASS;
297  } else if (tag != -1) {
298  /* No template tagging, get from arguments */
299  ttag = tag;
300  tclass = iclass & ASN1_TFLG_TAG_CLASS;
301  } else {
302  ttag = -1;
303  tclass = 0;
304  }
305 
306  const int optional = (flags & ASN1_TFLG_OPTIONAL) != 0;
307 
308  /*
309  * At this point 'ttag' contains the outer tag to use, and 'tclass' is the
310  * class.
311  */
312 
313  if (flags & ASN1_TFLG_SK_MASK) {
314  /* SET OF, SEQUENCE OF */
315  STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
316  int isset, sktag, skaclass;
317  int skcontlen, sklen;
318  ASN1_VALUE *skitem;
319 
320  if (!*pval) {
321  if (optional) {
322  return 0;
323  }
325  return -1;
326  }
327 
328  if (flags & ASN1_TFLG_SET_OF) {
329  isset = 1;
330  /* Historically, types with both bits set were mutated when
331  * serialized to apply the sort. We no longer support this. */
332  assert((flags & ASN1_TFLG_SEQUENCE_OF) == 0);
333  } else {
334  isset = 0;
335  }
336 
337  /*
338  * Work out inner tag value: if EXPLICIT or no tagging use underlying
339  * type.
340  */
341  if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
342  sktag = ttag;
343  skaclass = tclass;
344  } else {
345  skaclass = V_ASN1_UNIVERSAL;
346  if (isset)
347  sktag = V_ASN1_SET;
348  else
349  sktag = V_ASN1_SEQUENCE;
350  }
351 
352  /* Determine total length of items */
353  skcontlen = 0;
354  for (j = 0; j < sk_ASN1_VALUE_num(sk); j++) {
355  int tmplen;
356  skitem = sk_ASN1_VALUE_value(sk, j);
357  tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
358  -1, 0);
359  if (tmplen == -1 || (skcontlen > INT_MAX - tmplen))
360  return -1;
361  skcontlen += tmplen;
362  }
363  sklen = ASN1_object_size(/*constructed=*/1, skcontlen, sktag);
364  if (sklen == -1)
365  return -1;
366  /* If EXPLICIT need length of surrounding tag */
367  if (flags & ASN1_TFLG_EXPTAG)
368  ret = ASN1_object_size(/*constructed=*/1, sklen, ttag);
369  else
370  ret = sklen;
371 
372  if (!out || ret == -1)
373  return ret;
374 
375  /* Now encode this lot... */
376  /* EXPLICIT tag */
377  if (flags & ASN1_TFLG_EXPTAG)
378  ASN1_put_object(out, /*constructed=*/1, sklen, ttag, tclass);
379  /* SET or SEQUENCE and IMPLICIT tag */
380  ASN1_put_object(out, /*constructed=*/1, skcontlen, sktag, skaclass);
381  /* And the stuff itself */
382  if (!asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
383  isset)) {
384  return -1;
385  }
386  return ret;
387  }
388 
389  if (flags & ASN1_TFLG_EXPTAG) {
390  /* EXPLICIT tagging */
391  /* Find length of tagged item */
392  i = asn1_item_ex_i2d_opt(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, 0,
393  optional);
394  if (i <= 0)
395  return i;
396  /* Find length of EXPLICIT tag */
397  ret = ASN1_object_size(/*constructed=*/1, i, ttag);
398  if (out && ret != -1) {
399  /* Output tag and item */
400  ASN1_put_object(out, /*constructed=*/1, i, ttag, tclass);
401  if (ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1,
402  0) < 0) {
403  return -1;
404  }
405  }
406  return ret;
407  }
408 
409  /* Either normal or IMPLICIT tagging */
410  return asn1_item_ex_i2d_opt(pval, out, ASN1_ITEM_ptr(tt->item),
411  ttag, tclass, optional);
412 
413 }
414 
415 /* Temporary structure used to hold DER encoding of items for SET OF */
416 
417 typedef struct {
418  unsigned char *data;
419  int length;
420 } DER_ENC;
421 
422 static int der_cmp(const void *a, const void *b)
423 {
424  const DER_ENC *d1 = a, *d2 = b;
425  int cmplen, i;
426  cmplen = (d1->length < d2->length) ? d1->length : d2->length;
427  i = OPENSSL_memcmp(d1->data, d2->data, cmplen);
428  if (i)
429  return i;
430  return d1->length - d2->length;
431 }
432 
433 /* asn1_set_seq_out writes |sk| to |out| under the i2d output convention,
434  * excluding the tag and length. It returns one on success and zero on error.
435  * |skcontlen| must be the total encoded size. If |do_sort| is non-zero, the
436  * elements are sorted for a SET OF type. Each element of |sk| has type
437  * |item|. */
438 static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
439  int skcontlen, const ASN1_ITEM *item, int do_sort)
440 {
441  /* No need to sort if there are fewer than two items. */
442  if (!do_sort || sk_ASN1_VALUE_num(sk) < 2) {
443  for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
444  ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i);
445  if (ASN1_item_ex_i2d(&skitem, out, item, -1, 0) < 0) {
446  return 0;
447  }
448  }
449  return 1;
450  }
451 
452  if (sk_ASN1_VALUE_num(sk) > ((size_t)-1) / sizeof(DER_ENC)) {
454  return 0;
455  }
456 
457  int ret = 0;
458  unsigned char *const buf = OPENSSL_malloc(skcontlen);
459  DER_ENC *encoded = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*encoded));
460  if (encoded == NULL || buf == NULL) {
462  goto err;
463  }
464 
465  /* Encode all the elements into |buf| and populate |encoded|. */
466  unsigned char *p = buf;
467  for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
468  ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i);
469  encoded[i].data = p;
470  encoded[i].length = ASN1_item_ex_i2d(&skitem, &p, item, -1, 0);
471  if (encoded[i].length < 0) {
472  goto err;
473  }
474  assert(p - buf <= skcontlen);
475  }
476 
477  qsort(encoded, sk_ASN1_VALUE_num(sk), sizeof(*encoded), der_cmp);
478 
479  /* Output the elements in sorted order. */
480  p = *out;
481  for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
482  OPENSSL_memcpy(p, encoded[i].data, encoded[i].length);
483  p += encoded[i].length;
484  }
485  *out = p;
486 
487  ret = 1;
488 
489 err:
490  OPENSSL_free(encoded);
491  OPENSSL_free(buf);
492  return ret;
493 }
494 
495 /* asn1_i2d_ex_primitive behaves like |ASN1_item_ex_i2d| but |item| must be a
496  * a PRIMITIVE or MSTRING type that is not an |ASN1_ITEM_TEMPLATE|. */
497 static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
498  const ASN1_ITEM *it, int tag, int aclass,
499  int optional)
500 {
501  /* Get length of content octets and maybe find out the underlying type. */
502  int omit;
503  int utype = it->utype;
504  int len = asn1_ex_i2c(pval, NULL, &omit, &utype, it);
505  if (len < 0) {
506  return -1;
507  }
508  if (omit) {
509  if (optional) {
510  return 0;
511  }
513  return -1;
514  }
515 
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  */
521  int usetag = utype != V_ASN1_SEQUENCE && utype != V_ASN1_SET &&
522  utype != V_ASN1_OTHER;
523 
524  /* If not implicitly tagged get tag from underlying type */
525  if (tag == -1)
526  tag = utype;
527 
528  /* Output tag+length followed by content octets */
529  if (out) {
530  if (usetag) {
531  ASN1_put_object(out, /*constructed=*/0, len, tag, aclass);
532  }
533  int len2 = asn1_ex_i2c(pval, *out, &omit, &utype, it);
534  if (len2 < 0) {
535  return -1;
536  }
537  assert(len == len2);
538  assert(!omit);
539  *out += len;
540  }
541 
542  if (usetag) {
543  return ASN1_object_size(/*constructed=*/0, len, tag);
544  }
545  return len;
546 }
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  int *putype, const ASN1_ITEM *it)
566 {
567  ASN1_BOOLEAN *tbool = NULL;
568  ASN1_STRING *strtmp;
569  ASN1_OBJECT *otmp;
570  int utype;
571  const unsigned char *cont;
572  unsigned char c;
573  int len;
574 
575  /* Historically, |it->funcs| for primitive types contained an
576  * |ASN1_PRIMITIVE_FUNCS| table of callbacks. */
577  assert(it->funcs == NULL);
578 
579  *out_omit = 0;
580 
581  /* Should type be omitted? */
582  if ((it->itype != ASN1_ITYPE_PRIMITIVE)
583  || (it->utype != V_ASN1_BOOLEAN)) {
584  if (!*pval) {
585  *out_omit = 1;
586  return 0;
587  }
588  }
589 
590  if (it->itype == ASN1_ITYPE_MSTRING) {
591  /* If MSTRING type set the underlying type */
592  strtmp = (ASN1_STRING *)*pval;
593  utype = strtmp->type;
594  if (utype < 0 && utype != V_ASN1_OTHER) {
595  /* MSTRINGs can have type -1 when default-constructed. */
597  return -1;
598  }
599  /* Negative INTEGER and ENUMERATED values use |ASN1_STRING| type values
600  * that do not match their corresponding utype values. INTEGERs cannot
601  * participate in MSTRING types, but ENUMERATEDs can.
602  *
603  * TODO(davidben): Is this a bug? Although arguably one of the MSTRING
604  * types should contain more values, rather than less. See
605  * https://crbug.com/boringssl/412. But it is not possible to fit all
606  * possible ANY values into an |ASN1_STRING|, so matching the spec here
607  * is somewhat hopeless. */
608  if (utype == V_ASN1_NEG_INTEGER) {
609  utype = V_ASN1_INTEGER;
610  } else if (utype == V_ASN1_NEG_ENUMERATED) {
611  utype = V_ASN1_ENUMERATED;
612  }
613  *putype = utype;
614  } else if (it->utype == V_ASN1_ANY) {
615  /* If ANY set type and pointer to value */
616  ASN1_TYPE *typ;
617  typ = (ASN1_TYPE *)*pval;
618  utype = typ->type;
619  if (utype < 0 && utype != V_ASN1_OTHER) {
620  /* |ASN1_TYPE|s can have type -1 when default-constructed. */
622  return -1;
623  }
624  *putype = utype;
625  pval = &typ->value.asn1_value;
626  } else
627  utype = *putype;
628 
629  switch (utype) {
630  case V_ASN1_OBJECT:
631  otmp = (ASN1_OBJECT *)*pval;
632  cont = otmp->data;
633  len = otmp->length;
634  if (len == 0) {
635  /* Some |ASN1_OBJECT|s do not have OIDs and cannot be serialized. */
637  return -1;
638  }
639  break;
640 
641  case V_ASN1_NULL:
642  cont = NULL;
643  len = 0;
644  break;
645 
646  case V_ASN1_BOOLEAN:
647  tbool = (ASN1_BOOLEAN *)pval;
648  if (*tbool == -1) {
649  *out_omit = 1;
650  return 0;
651  }
652  if (it->utype != V_ASN1_ANY) {
653  /*
654  * Default handling if value == size field then omit
655  */
656  if ((*tbool && (it->size > 0)) ||
657  (!*tbool && !it->size)) {
658  *out_omit = 1;
659  return 0;
660  }
661  }
662  c = *tbool ? 0xff : 0x00;
663  cont = &c;
664  len = 1;
665  break;
666 
667  case V_ASN1_BIT_STRING: {
668  int ret = i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
669  cout ? &cout : NULL);
670  /* |i2c_ASN1_BIT_STRING| returns zero on error instead of -1. */
671  return ret <= 0 ? -1 : ret;
672  }
673 
674  case V_ASN1_INTEGER:
675  case V_ASN1_ENUMERATED: {
676  /* |i2c_ASN1_INTEGER| also handles ENUMERATED. */
677  int ret = i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL);
678  /* |i2c_ASN1_INTEGER| returns zero on error instead of -1. */
679  return ret <= 0 ? -1 : ret;
680  }
681 
682  case V_ASN1_OCTET_STRING:
685  case V_ASN1_T61STRING:
687  case V_ASN1_IA5STRING:
688  case V_ASN1_UTCTIME:
694  case V_ASN1_BMPSTRING:
695  case V_ASN1_UTF8STRING:
696  case V_ASN1_SEQUENCE:
697  case V_ASN1_SET:
698  default:
699  /* All based on ASN1_STRING and handled the same */
700  strtmp = (ASN1_STRING *)*pval;
701  cont = strtmp->data;
702  len = strtmp->length;
703 
704  break;
705 
706  }
707  if (cout && len)
708  OPENSSL_memcpy(cout, cont, len);
709  return len;
710 }
ASN1_ITYPE_CHOICE
#define ASN1_ITYPE_CHOICE
Definition: asn1t.h:509
V_ASN1_ANY
#define V_ASN1_ANY
Definition: asn1.h:121
ASN1_TFLG_TAG_CLASS
#define ASN1_TFLG_TAG_CLASS
Definition: asn1t.h:433
asn1_object_st::length
int length
Definition: third_party/boringssl-with-bazel/src/crypto/asn1/internal.h:105
ASN1_R_NO_MATCHING_CHOICE_TYPE
#define ASN1_R_NO_MATCHING_CHOICE_TYPE
Definition: asn1.h:2006
ASN1_TEMPLATE_st::item
ASN1_ITEM_EXP * item
Definition: asn1t.h:356
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
ASN1_TFLG_SK_MASK
#define ASN1_TFLG_SK_MASK
Definition: asn1t.h:396
regen-readme.it
it
Definition: regen-readme.py:15
ASN1_put_object
#define ASN1_put_object
Definition: boringssl_prefix_symbols.h:761
ASN1_item_ex_i2d
int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
Definition: tasn_enc.c:118
OPENSSL_memcmp
static int OPENSSL_memcmp(const void *s1, const void *s2, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:811
V_ASN1_NEG_ENUMERATED
#define V_ASN1_NEG_ENUMERATED
Definition: asn1.h:157
V_ASN1_GRAPHICSTRING
#define V_ASN1_GRAPHICSTRING
Definition: asn1.h:146
asn1_ex_i2c
static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *out_omit, int *putype, const ASN1_ITEM *it)
Definition: tasn_enc.c:564
ASN1_BOOLEAN
int ASN1_BOOLEAN
Definition: base.h:335
ASN1_R_WRONG_TYPE
#define ASN1_R_WRONG_TYPE
Definition: asn1.h:2034
V_ASN1_PRINTABLESTRING
#define V_ASN1_PRINTABLESTRING
Definition: asn1.h:139
ASN1_R_ILLEGAL_OBJECT
#define ASN1_R_ILLEGAL_OBJECT
Definition: asn1.h:1977
OPENSSL_PUT_ERROR
#define OPENSSL_PUT_ERROR(library, reason)
Definition: err.h:423
string.h
V_ASN1_SEQUENCE
#define V_ASN1_SEQUENCE
Definition: asn1.h:136
ASN1_EXTERN_FUNCS_st
Definition: asn1t.h:547
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
error_ref_leak.err
err
Definition: error_ref_leak.py:35
V_ASN1_SET
#define V_ASN1_SET
Definition: asn1.h:137
V_ASN1_UTF8STRING
#define V_ASN1_UTF8STRING
Definition: asn1.h:135
asn1_type_st::asn1_value
ASN1_VALUE * asn1_value
Definition: asn1.h:1505
V_ASN1_OCTET_STRING
#define V_ASN1_OCTET_STRING
Definition: asn1.h:128
V_ASN1_VIDEOTEXSTRING
#define V_ASN1_VIDEOTEXSTRING
Definition: asn1.h:142
ASN1_ITYPE_SEQUENCE
#define ASN1_ITYPE_SEQUENCE
Definition: asn1t.h:507
i2c_ASN1_INTEGER
#define i2c_ASN1_INTEGER
Definition: boringssl_prefix_symbols.h:3175
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
xds_manager.p
p
Definition: xds_manager.py:60
asn1_do_adb
#define asn1_do_adb
Definition: boringssl_prefix_symbols.h:2828
ASN1_ITEM_ptr
#define ASN1_ITEM_ptr(iptr)
Definition: asn1.h:316
ASN1_R_MISSING_VALUE
#define ASN1_R_MISSING_VALUE
Definition: asn1.h:1998
V_ASN1_GENERALSTRING
#define V_ASN1_GENERALSTRING
Definition: asn1.h:149
asn1_string_st::data
unsigned char * data
Definition: asn1.h:546
ASN1_item_i2d
int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
Definition: tasn_enc.c:87
V_ASN1_GENERALIZEDTIME
#define V_ASN1_GENERALIZEDTIME
Definition: asn1.h:145
asn1_object_st
Definition: third_party/boringssl-with-bazel/src/crypto/asn1/internal.h:102
ASN1_TFLG_SEQUENCE_OF
#define ASN1_TFLG_SEQUENCE_OF
Definition: asn1t.h:393
ASN1_EXTERN_FUNCS_st::asn1_ex_i2d
ASN1_ex_i2d * asn1_ex_i2d
Definition: asn1t.h:553
asn1_template_ex_i2d
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt, int tag, int aclass)
Definition: tasn_enc.c:270
OPENSSL_malloc
#define OPENSSL_malloc
Definition: boringssl_prefix_symbols.h:1885
asn1_get_field_ptr
#define asn1_get_field_ptr
Definition: boringssl_prefix_symbols.h:2835
V_ASN1_BMPSTRING
#define V_ASN1_BMPSTRING
Definition: asn1.h:151
ASN1_TFLG_OPTIONAL
#define ASN1_TFLG_OPTIONAL
Definition: asn1t.h:387
asn1_type_st::type
int type
Definition: asn1.h:1482
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
V_ASN1_UNIVERSAL
#define V_ASN1_UNIVERSAL
Definition: asn1.h:92
d2
static const fe d2
Definition: curve25519_tables.h:39
ASN1_ITEM_st
Definition: asn1t.h:459
internal.h
ASN1_TEMPLATE_st::tag
long tag
Definition: asn1t.h:353
STACK_OF
#define STACK_OF(type)
Definition: stack.h:125
V_ASN1_ENUMERATED
#define V_ASN1_ENUMERATED
Definition: asn1.h:134
asn1_string_st::length
int length
Definition: asn1.h:544
tag
static void * tag(intptr_t t)
Definition: bad_client.cc:318
asn1_item_ex_i2d_opt
static int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass, int optional)
Definition: tasn_enc.c:128
V_ASN1_VISIBLESTRING
#define V_ASN1_VISIBLESTRING
Definition: asn1.h:148
asn1_object_st::data
const unsigned char * data
Definition: third_party/boringssl-with-bazel/src/crypto/asn1/internal.h:106
OPENSSL_memcpy
static void * OPENSSL_memcpy(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:819
DER_ENC::data
unsigned char * data
Definition: tasn_enc.c:418
ASN1_TFLG_TAG_MASK
#define ASN1_TFLG_TAG_MASK
Definition: asn1t.h:410
ERR_R_INTERNAL_ERROR
#define ERR_R_INTERNAL_ERROR
Definition: err.h:374
V_ASN1_NUMERICSTRING
#define V_ASN1_NUMERICSTRING
Definition: asn1.h:138
asn1t.h
ASN1_ITYPE_EXTERN
#define ASN1_ITYPE_EXTERN
Definition: asn1t.h:511
V_ASN1_BIT_STRING
#define V_ASN1_BIT_STRING
Definition: asn1.h:127
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
asn1_i2d_ex_primitive
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass, int optional)
Definition: tasn_enc.c:497
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
V_ASN1_OTHER
#define V_ASN1_OTHER
Definition: asn1.h:118
qsort
void qsort(void *a, size_t n, size_t es, int(*cmp)(const void *, const void *))
Definition: qsort.h:130
V_ASN1_UTCTIME
#define V_ASN1_UTCTIME
Definition: asn1.h:144
ERR_R_OVERFLOW
#define ERR_R_OVERFLOW
Definition: err.h:375
V_ASN1_BOOLEAN
#define V_ASN1_BOOLEAN
Definition: asn1.h:125
V_ASN1_IA5STRING
#define V_ASN1_IA5STRING
Definition: asn1.h:143
asn1_set_seq_out
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int skcontlen, const ASN1_ITEM *item, int do_sort)
Definition: tasn_enc.c:438
V_ASN1_T61STRING
#define V_ASN1_T61STRING
Definition: asn1.h:140
ASN1_R_BAD_TEMPLATE
#define ASN1_R_BAD_TEMPLATE
Definition: asn1.h:2036
ASN1_TFLG_EXPTAG
#define ASN1_TFLG_EXPTAG
Definition: asn1t.h:408
DER_ENC
Definition: tasn_enc.c:417
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
DER_ENC::length
int length
Definition: tasn_enc.c:419
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
der_cmp
static int der_cmp(const void *a, const void *b)
Definition: tasn_enc.c:422
ASN1_TEMPLATE_st
Definition: asn1t.h:351
V_ASN1_NULL
#define V_ASN1_NULL
Definition: asn1.h:129
ASN1_VALUE
struct ASN1_VALUE_st ASN1_VALUE
Definition: asn1.h:320
ASN1_ITYPE_MSTRING
#define ASN1_ITYPE_MSTRING
Definition: asn1t.h:513
asn1_string_st::type
int type
Definition: asn1.h:545
ASN1_TEMPLATE_st::flags
unsigned long flags
Definition: asn1t.h:352
asn1_type_st::value
union asn1_type_st::@361 value
ASN1_ITYPE_PRIMITIVE
#define ASN1_ITYPE_PRIMITIVE
Definition: asn1t.h:505
flags
uint32_t flags
Definition: retry_filter.cc:632
mem.h
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
asn1_type_st
Definition: asn1.h:1481
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
ASN1_object_size
#define ASN1_object_size
Definition: boringssl_prefix_symbols.h:758
asn1_get_choice_selector
#define asn1_get_choice_selector
Definition: boringssl_prefix_symbols.h:2834
ASN1_TFLG_SET_OF
#define ASN1_TFLG_SET_OF
Definition: asn1t.h:390
asn1_enc_restore
#define asn1_enc_restore
Definition: boringssl_prefix_symbols.h:2831
OPENSSL_free
#define OPENSSL_free
Definition: boringssl_prefix_symbols.h:1869
i2c_ASN1_BIT_STRING
#define i2c_ASN1_BIT_STRING
Definition: boringssl_prefix_symbols.h:3174
V_ASN1_OBJECT
#define V_ASN1_OBJECT
Definition: asn1.h:130
V_ASN1_NEG_INTEGER
#define V_ASN1_NEG_INTEGER
Definition: asn1.h:156
V_ASN1_UNIVERSALSTRING
#define V_ASN1_UNIVERSALSTRING
Definition: asn1.h:150
asn1_string_st
Definition: asn1.h:543
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
asn1.h
ERR_R_MALLOC_FAILURE
#define ERR_R_MALLOC_FAILURE
Definition: err.h:371
V_ASN1_INTEGER
#define V_ASN1_INTEGER
Definition: asn1.h:126


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:25