Bug Summary

File:out/../deps/openssl/openssl/crypto/asn1/tasn_enc.c
Warning:line 146, column 16
Access to field 'asn1_ex_i2d' results in a dereference of a null pointer (loaded from variable 'ef')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name tasn_enc.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D V8_DEPRECATION_WARNINGS -D V8_IMMINENT_DEPRECATION_WARNINGS -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D OPENSSL_NO_HW -D OPENSSL_API_COMPAT=0x10100001L -D STATIC_LEGACY -D NDEBUG -D OPENSSL_USE_NODELETE -D L_ENDIAN -D OPENSSL_BUILDING_OPENSSL -D AES_ASM -D BSAES_ASM -D CMLL_ASM -D ECP_NISTZ256_ASM -D GHASH_ASM -D KECCAK1600_ASM -D MD5_ASM -D OPENSSL_BN_ASM_GF2m -D OPENSSL_BN_ASM_MONT -D OPENSSL_BN_ASM_MONT5 -D OPENSSL_CPUID_OBJ -D OPENSSL_IA32_SSE2 -D PADLOCK_ASM -D POLY1305_ASM -D SHA1_ASM -D SHA256_ASM -D SHA512_ASM -D VPAES_ASM -D WHIRLPOOL_ASM -D X25519_ASM -D OPENSSL_PIC -D MODULESDIR="/home/maurizio/node-v18.6.0/out/Release/obj.target/deps/openssl/lib/openssl-modules" -D OPENSSLDIR="/home/maurizio/node-v18.6.0/out/Release/obj.target/deps/openssl" -D OPENSSLDIR="/etc/ssl" -D ENGINESDIR="/dev/null" -D TERMIOS -I ../deps/openssl/openssl -I ../deps/openssl/openssl/include -I ../deps/openssl/openssl/crypto -I ../deps/openssl/openssl/crypto/include -I ../deps/openssl/openssl/crypto/modes -I ../deps/openssl/openssl/crypto/ec/curve448 -I ../deps/openssl/openssl/crypto/ec/curve448/arch_32 -I ../deps/openssl/openssl/providers/common/include -I ../deps/openssl/openssl/providers/implementations/include -I ../deps/openssl/config -I ../deps/openssl/config/archs/linux-x86_64/asm -I ../deps/openssl/config/archs/linux-x86_64/asm/include -I ../deps/openssl/config/archs/linux-x86_64/asm/crypto -I ../deps/openssl/config/archs/linux-x86_64/asm/crypto/include/internal -I ../deps/openssl/config/archs/linux-x86_64/asm/providers/common/include -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-missing-field-initializers -Wno-old-style-declaration -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c ../deps/openssl/openssl/crypto/asn1/tasn_enc.c
1/*
2 * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stddef.h>
11#include <string.h>
12#include "internal/cryptlib.h"
13#include <openssl/asn1.h>
14#include <openssl/asn1t.h>
15#include <openssl/objects.h>
16#include "crypto/asn1.h"
17#include "asn1_local.h"
18
19static int asn1_i2d_ex_primitive(const ASN1_VALUE **pval, unsigned char **out,
20 const ASN1_ITEM *it, int tag, int aclass);
21static int asn1_set_seq_out(STACK_OF(const_ASN1_VALUE)struct stack_st_const_ASN1_VALUE *sk,
22 unsigned char **out,
23 int skcontlen, const ASN1_ITEM *item,
24 int do_sort, int iclass);
25static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
26 const ASN1_TEMPLATE *tt, int tag, int aclass);
27static int asn1_item_flags_i2d(const ASN1_VALUE *val, unsigned char **out,
28 const ASN1_ITEM *it, int flags);
29static int asn1_ex_i2c(const ASN1_VALUE **pval, unsigned char *cout, int *putype,
30 const ASN1_ITEM *it);
31
32/*
33 * Top level i2d equivalents: the 'ndef' variant instructs the encoder to use
34 * indefinite length constructed encoding, where appropriate
35 */
36
37int ASN1_item_ndef_i2d(const ASN1_VALUE *val, unsigned char **out,
38 const ASN1_ITEM *it)
39{
40 return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF(0x1<<11));
41}
42
43int ASN1_item_i2d(const ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
44{
45 return asn1_item_flags_i2d(val, out, it, 0);
1
Calling 'asn1_item_flags_i2d'
46}
47
48/*
49 * Encode an ASN1 item, this is use by the standard 'i2d' function. 'out'
50 * points to a buffer to output the data to. The new i2d has one additional
51 * feature. If the output buffer is NULL (i.e. *out == NULL) then a buffer is
52 * allocated and populated with the encoding.
53 */
54
55static int asn1_item_flags_i2d(const ASN1_VALUE *val, unsigned char **out,
56 const ASN1_ITEM *it, int flags)
57{
58 if (out != NULL((void*)0) && *out == NULL((void*)0)) {
2
Assuming 'out' is equal to NULL
59 unsigned char *p, *buf;
60 int len;
61
62 len = ASN1_item_ex_i2d(&val, NULL((void*)0), it, -1, flags);
63 if (len <= 0)
64 return len;
65 if ((buf = OPENSSL_malloc(len)CRYPTO_malloc(len, "../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
, 65)
) == NULL((void*)0)) {
66 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
,66,__func__), ERR_set_error)((13),((256|((0x1 << 18L)|
(0x2 << 18L)))),((void*)0))
;
67 return -1;
68 }
69 p = buf;
70 ASN1_item_ex_i2d(&val, &p, it, -1, flags);
71 *out = buf;
72 return len;
73 }
74
75 return ASN1_item_ex_i2d(&val, out, it, -1, flags);
3
Calling 'ASN1_item_ex_i2d'
76}
77
78/*
79 * Encode an item, taking care of IMPLICIT tagging (if any). This function
80 * performs the normal item handling: it can be used in external types.
81 */
82
83int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
84 const ASN1_ITEM *it, int tag, int aclass)
85{
86 const ASN1_TEMPLATE *tt = NULL((void*)0);
87 int i, seqcontlen, seqlen, ndef = 1;
88 const ASN1_EXTERN_FUNCS *ef;
89 const ASN1_AUX *aux = it->funcs;
90 ASN1_aux_const_cb *asn1_cb = NULL((void*)0);
91
92 if ((it->itype != ASN1_ITYPE_PRIMITIVE0x0) && *pval == NULL((void*)0))
4
Assuming field 'itype' is not equal to ASN1_ITYPE_PRIMITIVE
5
Assuming the condition is false
6
Taking false branch
93 return 0;
94
95 if (aux != NULL((void*)0)) {
7
Assuming 'aux' is equal to NULL
8
Taking false branch
96 asn1_cb = ((aux->flags & ASN1_AFLG_CONST_CB8) != 0) ? aux->asn1_const_cb
97 : (ASN1_aux_const_cb *)aux->asn1_cb; /* backward compatibility */
98 }
99
100 switch (it->itype) {
9
Control jumps to 'case 4:' at line 143
101
102 case ASN1_ITYPE_PRIMITIVE0x0:
103 if (it->templates)
104 return asn1_template_ex_i2d(pval, out, it->templates,
105 tag, aclass);
106 return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
107
108 case ASN1_ITYPE_MSTRING0x5:
109 /*
110 * It never makes sense for multi-strings to have implicit tagging, so
111 * if tag != -1, then this looks like an error in the template.
112 */
113 if (tag != -1) {
114 ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_TEMPLATE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
,114,__func__), ERR_set_error)((13),(230),((void*)0))
;
115 return -1;
116 }
117 return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
118
119 case ASN1_ITYPE_CHOICE0x2:
120 /*
121 * It never makes sense for CHOICE types to have implicit tagging, so
122 * if tag != -1, then this looks like an error in the template.
123 */
124 if (tag != -1) {
125 ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_TEMPLATE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
,125,__func__), ERR_set_error)((13),(230),((void*)0))
;
126 return -1;
127 }
128 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE6, pval, it, NULL((void*)0)))
129 return 0;
130 i = ossl_asn1_get_choice_selector_const(pval, it);
131 if ((i >= 0) && (i < it->tcount)) {
132 const ASN1_VALUE **pchval;
133 const ASN1_TEMPLATE *chtt;
134 chtt = it->templates + i;
135 pchval = ossl_asn1_get_const_field_ptr(pval, chtt);
136 return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass);
137 }
138 /* Fixme: error condition if selector out of range */
139 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST7, pval, it, NULL((void*)0)))
140 return 0;
141 break;
142
143 case ASN1_ITYPE_EXTERN0x4:
144 /* If new style i2d it does all the work */
145 ef = it->funcs;
10
Null pointer value stored to 'ef'
146 return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
11
Access to field 'asn1_ex_i2d' results in a dereference of a null pointer (loaded from variable 'ef')
147
148 case ASN1_ITYPE_NDEF_SEQUENCE0x6:
149 /* Use indefinite length constructed if requested */
150 if (aclass & ASN1_TFLG_NDEF(0x1<<11))
151 ndef = 2;
152 /* fall through */
153
154 case ASN1_ITYPE_SEQUENCE0x1:
155 i = ossl_asn1_enc_restore(&seqcontlen, out, pval, it);
156 /* An error occurred */
157 if (i < 0)
158 return 0;
159 /* We have a valid cached encoding... */
160 if (i > 0)
161 return seqcontlen;
162 /* Otherwise carry on */
163 seqcontlen = 0;
164 /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
165 if (tag == -1) {
166 tag = V_ASN1_SEQUENCE16;
167 /* Retain any other flags in aclass */
168 aclass = (aclass & ~ASN1_TFLG_TAG_CLASS(0x3<<6))
169 | V_ASN1_UNIVERSAL0x00;
170 }
171 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE6, pval, it, NULL((void*)0)))
172 return 0;
173 /* First work out sequence content length */
174 for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
175 const ASN1_TEMPLATE *seqtt;
176 const ASN1_VALUE **pseqval;
177 int tmplen;
178 seqtt = ossl_asn1_do_adb(*pval, tt, 1);
179 if (!seqtt)
180 return 0;
181 pseqval = ossl_asn1_get_const_field_ptr(pval, seqtt);
182 tmplen = asn1_template_ex_i2d(pseqval, NULL((void*)0), seqtt, -1, aclass);
183 if (tmplen == -1 || (tmplen > INT_MAX2147483647 - seqcontlen))
184 return -1;
185 seqcontlen += tmplen;
186 }
187
188 seqlen = ASN1_object_size(ndef, seqcontlen, tag);
189 if (!out || seqlen == -1)
190 return seqlen;
191 /* Output SEQUENCE header */
192 ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
193 for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
194 const ASN1_TEMPLATE *seqtt;
195 const ASN1_VALUE **pseqval;
196 seqtt = ossl_asn1_do_adb(*pval, tt, 1);
197 if (!seqtt)
198 return 0;
199 pseqval = ossl_asn1_get_const_field_ptr(pval, seqtt);
200 /* FIXME: check for errors in enhanced version */
201 asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
202 }
203 if (ndef == 2)
204 ASN1_put_eoc(out);
205 if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST7, pval, it, NULL((void*)0)))
206 return 0;
207 return seqlen;
208
209 default:
210 return 0;
211
212 }
213 return 0;
214}
215
216static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
217 const ASN1_TEMPLATE *tt, int tag, int iclass)
218{
219 const int flags = tt->flags;
220 int i, ret, ttag, tclass, ndef, len;
221 const ASN1_VALUE *tval;
222
223 /*
224 * If field is embedded then val needs fixing so it is a pointer to
225 * a pointer to a field.
226 */
227 if (flags & ASN1_TFLG_EMBED(0x1 << 12)) {
228 tval = (ASN1_VALUE *)pval;
229 pval = &tval;
230 }
231 /*
232 * Work out tag and class to use: tagging may come either from the
233 * template or the arguments, not both because this would create
234 * ambiguity. Additionally the iclass argument may contain some
235 * additional flags which should be noted and passed down to other
236 * levels.
237 */
238 if (flags & ASN1_TFLG_TAG_MASK(0x3 << 3)) {
239 /* Error if argument and template tagging */
240 if (tag != -1)
241 /* FIXME: error code here */
242 return -1;
243 /* Get tagging from template */
244 ttag = tt->tag;
245 tclass = flags & ASN1_TFLG_TAG_CLASS(0x3<<6);
246 } else if (tag != -1) {
247 /* No template tagging, get from arguments */
248 ttag = tag;
249 tclass = iclass & ASN1_TFLG_TAG_CLASS(0x3<<6);
250 } else {
251 ttag = -1;
252 tclass = 0;
253 }
254 /*
255 * Remove any class mask from iflag.
256 */
257 iclass &= ~ASN1_TFLG_TAG_CLASS(0x3<<6);
258
259 /*
260 * At this point 'ttag' contains the outer tag to use, 'tclass' is the
261 * class and iclass is any flags passed to this function.
262 */
263
264 /* if template and arguments require ndef, use it */
265 if ((flags & ASN1_TFLG_NDEF(0x1<<11)) && (iclass & ASN1_TFLG_NDEF(0x1<<11)))
266 ndef = 2;
267 else
268 ndef = 1;
269
270 if (flags & ASN1_TFLG_SK_MASK(0x3 << 1)) {
271 /* SET OF, SEQUENCE OF */
272 STACK_OF(const_ASN1_VALUE)struct stack_st_const_ASN1_VALUE *sk = (STACK_OF(const_ASN1_VALUE)struct stack_st_const_ASN1_VALUE *)*pval;
273 int isset, sktag, skaclass;
274 int skcontlen, sklen;
275 const ASN1_VALUE *skitem;
276
277 if (*pval == NULL((void*)0))
278 return 0;
279
280 if (flags & ASN1_TFLG_SET_OF(0x1 << 1)) {
281 isset = 1;
282 /* 2 means we reorder */
283 if (flags & ASN1_TFLG_SEQUENCE_OF(0x2 << 1))
284 isset = 2;
285 } else
286 isset = 0;
287
288 /*
289 * Work out inner tag value: if EXPLICIT or no tagging use underlying
290 * type.
291 */
292 if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG(0x2 << 3))) {
293 sktag = ttag;
294 skaclass = tclass;
295 } else {
296 skaclass = V_ASN1_UNIVERSAL0x00;
297 if (isset)
298 sktag = V_ASN1_SET17;
299 else
300 sktag = V_ASN1_SEQUENCE16;
301 }
302
303 /* Determine total length of items */
304 skcontlen = 0;
305 for (i = 0; i < sk_const_ASN1_VALUE_num(sk); i++) {
306 skitem = sk_const_ASN1_VALUE_value(sk, i);
307 len = ASN1_item_ex_i2d(&skitem, NULL((void*)0), ASN1_ITEM_ptr(tt->item)(tt->item()),
308 -1, iclass);
309 if (len == -1 || (skcontlen > INT_MAX2147483647 - len))
310 return -1;
311 if (len == 0 && (tt->flags & ASN1_TFLG_OPTIONAL(0x1)) == 0) {
312 ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
,312,__func__), ERR_set_error)((13),(222),((void*)0))
;
313 return -1;
314 }
315 skcontlen += len;
316 }
317 sklen = ASN1_object_size(ndef, skcontlen, sktag);
318 if (sklen == -1)
319 return -1;
320 /* If EXPLICIT need length of surrounding tag */
321 if (flags & ASN1_TFLG_EXPTAG(0x2 << 3))
322 ret = ASN1_object_size(ndef, sklen, ttag);
323 else
324 ret = sklen;
325
326 if (!out || ret == -1)
327 return ret;
328
329 /* Now encode this lot... */
330 /* EXPLICIT tag */
331 if (flags & ASN1_TFLG_EXPTAG(0x2 << 3))
332 ASN1_put_object(out, ndef, sklen, ttag, tclass);
333 /* SET or SEQUENCE and IMPLICIT tag */
334 ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
335 /* And the stuff itself */
336 asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item)(tt->item()),
337 isset, iclass);
338 if (ndef == 2) {
339 ASN1_put_eoc(out);
340 if (flags & ASN1_TFLG_EXPTAG(0x2 << 3))
341 ASN1_put_eoc(out);
342 }
343
344 return ret;
345 }
346
347 if (flags & ASN1_TFLG_EXPTAG(0x2 << 3)) {
348 /* EXPLICIT tagging */
349 /* Find length of tagged item */
350 i = ASN1_item_ex_i2d(pval, NULL((void*)0), ASN1_ITEM_ptr(tt->item)(tt->item()), -1, iclass);
351 if (i == 0) {
352 if ((tt->flags & ASN1_TFLG_OPTIONAL(0x1)) == 0) {
353 ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
,353,__func__), ERR_set_error)((13),(222),((void*)0))
;
354 return -1;
355 }
356 return 0;
357 }
358 /* Find length of EXPLICIT tag */
359 ret = ASN1_object_size(ndef, i, ttag);
360 if (out && ret != -1) {
361 /* Output tag and item */
362 ASN1_put_object(out, ndef, i, ttag, tclass);
363 ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item)(tt->item()), -1, iclass);
364 if (ndef == 2)
365 ASN1_put_eoc(out);
366 }
367 return ret;
368 }
369
370 /* Either normal or IMPLICIT tagging: combine class and flags */
371 len = ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item)(tt->item()),
372 ttag, tclass | iclass);
373 if (len == 0 && (tt->flags & ASN1_TFLG_OPTIONAL(0x1)) == 0) {
374 ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
,374,__func__), ERR_set_error)((13),(222),((void*)0))
;
375 return -1;
376 }
377 return len;
378}
379
380/* Temporary structure used to hold DER encoding of items for SET OF */
381
382typedef struct {
383 unsigned char *data;
384 int length;
385 const ASN1_VALUE *field;
386} DER_ENC;
387
388static int der_cmp(const void *a, const void *b)
389{
390 const DER_ENC *d1 = a, *d2 = b;
391 int cmplen, i;
392 cmplen = (d1->length < d2->length) ? d1->length : d2->length;
393 i = memcmp(d1->data, d2->data, cmplen);
394 if (i)
395 return i;
396 return d1->length - d2->length;
397}
398
399/* Output the content octets of SET OF or SEQUENCE OF */
400
401static int asn1_set_seq_out(STACK_OF(const_ASN1_VALUE)struct stack_st_const_ASN1_VALUE *sk,
402 unsigned char **out,
403 int skcontlen, const ASN1_ITEM *item,
404 int do_sort, int iclass)
405{
406 int i, ret = 0;
407 const ASN1_VALUE *skitem;
408 unsigned char *tmpdat = NULL((void*)0), *p = NULL((void*)0);
409 DER_ENC *derlst = NULL((void*)0), *tder;
410
411 if (do_sort) {
412 /* Don't need to sort less than 2 items */
413 if (sk_const_ASN1_VALUE_num(sk) < 2)
414 do_sort = 0;
415 else {
416 derlst = OPENSSL_malloc(sk_const_ASN1_VALUE_num(sk)CRYPTO_malloc(sk_const_ASN1_VALUE_num(sk) * sizeof(*derlst), "../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
, 417)
417 * sizeof(*derlst))CRYPTO_malloc(sk_const_ASN1_VALUE_num(sk) * sizeof(*derlst), "../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
, 417)
;
418 if (derlst == NULL((void*)0)) {
419 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
,419,__func__), ERR_set_error)((13),((256|((0x1 << 18L)
|(0x2 << 18L)))),((void*)0))
;
420 return 0;
421 }
422 tmpdat = OPENSSL_malloc(skcontlen)CRYPTO_malloc(skcontlen, "../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
, 422)
;
423 if (tmpdat == NULL((void*)0)) {
424 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
,424,__func__), ERR_set_error)((13),((256|((0x1 << 18L)
|(0x2 << 18L)))),((void*)0))
;
425 goto err;
426 }
427 }
428 }
429 /* If not sorting just output each item */
430 if (!do_sort) {
431 for (i = 0; i < sk_const_ASN1_VALUE_num(sk); i++) {
432 skitem = sk_const_ASN1_VALUE_value(sk, i);
433 ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
434 }
435 return 1;
436 }
437 p = tmpdat;
438
439 /* Doing sort: build up a list of each member's DER encoding */
440 for (i = 0, tder = derlst; i < sk_const_ASN1_VALUE_num(sk); i++, tder++) {
441 skitem = sk_const_ASN1_VALUE_value(sk, i);
442 tder->data = p;
443 tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
444 tder->field = skitem;
445 }
446
447 /* Now sort them */
448 qsort(derlst, sk_const_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
449 /* Output sorted DER encoding */
450 p = *out;
451 for (i = 0, tder = derlst; i < sk_const_ASN1_VALUE_num(sk); i++, tder++) {
452 memcpy(p, tder->data, tder->length);
453 p += tder->length;
454 }
455 *out = p;
456 /* If do_sort is 2 then reorder the STACK */
457 if (do_sort == 2) {
458 for (i = 0, tder = derlst; i < sk_const_ASN1_VALUE_num(sk); i++, tder++)
459 (void)sk_const_ASN1_VALUE_set(sk, i, tder->field);
460 }
461 ret = 1;
462err:
463 OPENSSL_free(derlst)CRYPTO_free(derlst, "../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
, 463)
;
464 OPENSSL_free(tmpdat)CRYPTO_free(tmpdat, "../deps/openssl/openssl/crypto/asn1/tasn_enc.c"
, 464)
;
465 return ret;
466}
467
468static int asn1_i2d_ex_primitive(const ASN1_VALUE **pval, unsigned char **out,
469 const ASN1_ITEM *it, int tag, int aclass)
470{
471 int len;
472 int utype;
473 int usetag;
474 int ndef = 0;
475
476 utype = it->utype;
477
478 /*
479 * Get length of content octets and maybe find out the underlying type.
480 */
481
482 len = asn1_ex_i2c(pval, NULL((void*)0), &utype, it);
483
484 /*
485 * If SEQUENCE, SET or OTHER then header is included in pseudo content
486 * octets so don't include tag+length. We need to check here because the
487 * call to asn1_ex_i2c() could change utype.
488 */
489 if ((utype == V_ASN1_SEQUENCE16) || (utype == V_ASN1_SET17) ||
490 (utype == V_ASN1_OTHER-3))
491 usetag = 0;
492 else
493 usetag = 1;
494
495 /* -1 means omit type */
496
497 if (len == -1)
498 return 0;
499
500 /* -2 return is special meaning use ndef */
501 if (len == -2) {
502 ndef = 2;
503 len = 0;
504 }
505
506 /* If not implicitly tagged get tag from underlying type */
507 if (tag == -1)
508 tag = utype;
509
510 /* Output tag+length followed by content octets */
511 if (out) {
512 if (usetag)
513 ASN1_put_object(out, ndef, len, tag, aclass);
514 asn1_ex_i2c(pval, *out, &utype, it);
515 if (ndef)
516 ASN1_put_eoc(out);
517 else
518 *out += len;
519 }
520
521 if (usetag)
522 return ASN1_object_size(ndef, len, tag);
523 return len;
524}
525
526/* Produce content octets from a structure */
527
528static int asn1_ex_i2c(const ASN1_VALUE **pval, unsigned char *cout, int *putype,
529 const ASN1_ITEM *it)
530{
531 ASN1_BOOLEAN *tbool = NULL((void*)0);
532 ASN1_STRING *strtmp;
533 ASN1_OBJECT *otmp;
534 int utype;
535 const unsigned char *cont;
536 unsigned char c;
537 int len;
538 const ASN1_PRIMITIVE_FUNCS *pf;
539 pf = it->funcs;
540 if (pf && pf->prim_i2c)
541 return pf->prim_i2c(pval, cout, putype, it);
542
543 /* Should type be omitted? */
544 if ((it->itype != ASN1_ITYPE_PRIMITIVE0x0)
545 || (it->utype != V_ASN1_BOOLEAN1)) {
546 if (*pval == NULL((void*)0))
547 return -1;
548 }
549
550 if (it->itype == ASN1_ITYPE_MSTRING0x5) {
551 /* If MSTRING type set the underlying type */
552 strtmp = (ASN1_STRING *)*pval;
553 utype = strtmp->type;
554 *putype = utype;
555 } else if (it->utype == V_ASN1_ANY-4) {
556 /* If ANY set type and pointer to value */
557 ASN1_TYPE *typ;
558 typ = (ASN1_TYPE *)*pval;
559 utype = typ->type;
560 *putype = utype;
561 pval = (const ASN1_VALUE **)&typ->value.asn1_value; /* actually is const */
562 } else
563 utype = *putype;
564
565 switch (utype) {
566 case V_ASN1_OBJECT6:
567 otmp = (ASN1_OBJECT *)*pval;
568 cont = otmp->data;
569 len = otmp->length;
570 if (cont == NULL((void*)0) || len == 0)
571 return -1;
572 break;
573
574 case V_ASN1_NULL5:
575 cont = NULL((void*)0);
576 len = 0;
577 break;
578
579 case V_ASN1_BOOLEAN1:
580 tbool = (ASN1_BOOLEAN *)pval;
581 if (*tbool == -1)
582 return -1;
583 if (it->utype != V_ASN1_ANY-4) {
584 /*
585 * Default handling if value == size field then omit
586 */
587 if (*tbool && (it->size > 0))
588 return -1;
589 if (!*tbool && !it->size)
590 return -1;
591 }
592 c = (unsigned char)*tbool;
593 cont = &c;
594 len = 1;
595 break;
596
597 case V_ASN1_BIT_STRING3:
598 return ossl_i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
599 cout ? &cout : NULL((void*)0));
600
601 case V_ASN1_INTEGER2:
602 case V_ASN1_ENUMERATED10:
603 /*
604 * These are all have the same content format as ASN1_INTEGER
605 */
606 return ossl_i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL((void*)0));
607
608 case V_ASN1_OCTET_STRING4:
609 case V_ASN1_NUMERICSTRING18:
610 case V_ASN1_PRINTABLESTRING19:
611 case V_ASN1_T61STRING20:
612 case V_ASN1_VIDEOTEXSTRING21:
613 case V_ASN1_IA5STRING22:
614 case V_ASN1_UTCTIME23:
615 case V_ASN1_GENERALIZEDTIME24:
616 case V_ASN1_GRAPHICSTRING25:
617 case V_ASN1_VISIBLESTRING26:
618 case V_ASN1_GENERALSTRING27:
619 case V_ASN1_UNIVERSALSTRING28:
620 case V_ASN1_BMPSTRING30:
621 case V_ASN1_UTF8STRING12:
622 case V_ASN1_SEQUENCE16:
623 case V_ASN1_SET17:
624 default:
625 /* All based on ASN1_STRING and handled the same */
626 strtmp = (ASN1_STRING *)*pval;
627 /* Special handling for NDEF */
628 if ((it->size == ASN1_TFLG_NDEF(0x1<<11))
629 && (strtmp->flags & ASN1_STRING_FLAG_NDEF0x010)) {
630 if (cout) {
631 strtmp->data = cout;
632 strtmp->length = 0;
633 }
634 /* Special return code */
635 return -2;
636 }
637 cont = strtmp->data;
638 len = strtmp->length;
639
640 break;
641
642 }
643 if (cout && len)
644 memcpy(cout, cont, len);
645 return len;
646}