Bug Summary

File:src/lib/libcrypto/asn1/a_string.c
Warning:line 428, column 16
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name a_string.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 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/lib/libcrypto/obj -resource-dir /usr/local/llvm16/lib/clang/16 -D LIBRESSL_INTERNAL -D HAVE_FUNOPEN -I /usr/src/lib/libcrypto -I /usr/src/lib/libcrypto/arch/amd64 -I /usr/src/lib/libcrypto/asn1 -I /usr/src/lib/libcrypto/bio -I /usr/src/lib/libcrypto/bn -I /usr/src/lib/libcrypto/bn/arch/amd64 -I /usr/src/lib/libcrypto/bytestring -I /usr/src/lib/libcrypto/curve25519 -I /usr/src/lib/libcrypto/dh -I /usr/src/lib/libcrypto/dsa -I /usr/src/lib/libcrypto/ec -I /usr/src/lib/libcrypto/ecdsa -I /usr/src/lib/libcrypto/evp -I /usr/src/lib/libcrypto/hidden -I /usr/src/lib/libcrypto/hmac -I /usr/src/lib/libcrypto/kdf -I /usr/src/lib/libcrypto/modes -I /usr/src/lib/libcrypto/ocsp -I /usr/src/lib/libcrypto/pkcs12 -I /usr/src/lib/libcrypto/rsa -I /usr/src/lib/libcrypto/sha -I /usr/src/lib/libcrypto/ts -I /usr/src/lib/libcrypto/x509 -I /usr/src/lib/libcrypto/obj -D AES_ASM -D BSAES_ASM -D VPAES_ASM -D OPENSSL_IA32_SSE2 -D RSA_ASM -D OPENSSL_BN_ASM_MONT -D OPENSSL_BN_ASM_MONT5 -D MD5_ASM -D GHASH_ASM -D RC4_MD5_ASM -D SHA1_ASM -D SHA256_ASM -D SHA512_ASM -D WHIRLPOOL_ASM -D OPENSSL_CPUID_OBJ -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libcrypto/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/lib/libcrypto/asn1/a_string.c
1/* $OpenBSD: a_string.c,v 1.17 2023/08/15 18:05:15 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <limits.h>
60#include <stdlib.h>
61#include <string.h>
62
63#include <openssl/asn1.h>
64#include <openssl/err.h>
65
66#include "asn1_local.h"
67
68ASN1_STRING *
69ASN1_STRING_new(void)
70{
71 return ASN1_STRING_type_new(V_ASN1_OCTET_STRING4);
72}
73LCRYPTO_ALIAS(ASN1_STRING_new)asm("");
74
75ASN1_STRING *
76ASN1_STRING_type_new(int type)
77{
78 ASN1_STRING *astr;
79
80 if ((astr = calloc(1, sizeof(ASN1_STRING))) == NULL((void *)0)) {
81 ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/a_string.c"
,81)
;
82 return NULL((void *)0);
83 }
84 astr->type = type;
85
86 return astr;
87}
88LCRYPTO_ALIAS(ASN1_STRING_type_new)asm("");
89
90static void
91ASN1_STRING_clear(ASN1_STRING *astr)
92{
93 if (!(astr->flags & ASN1_STRING_FLAG_NDEF0x010))
94 freezero(astr->data, astr->length);
95
96 astr->flags &= ~ASN1_STRING_FLAG_NDEF0x010;
97 astr->data = NULL((void *)0);
98 astr->length = 0;
99}
100
101void
102ASN1_STRING_free(ASN1_STRING *astr)
103{
104 if (astr == NULL((void *)0))
105 return;
106
107 ASN1_STRING_clear(astr);
108
109 free(astr);
110}
111LCRYPTO_ALIAS(ASN1_STRING_free)asm("");
112
113int
114ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
115{
116 int cmp;
117
118 if (a == NULL((void *)0) || b == NULL((void *)0))
119 return -1;
120 if ((cmp = (a->length - b->length)) != 0)
121 return cmp;
122 if (a->length != 0) {
123 if ((cmp = memcmp(a->data, b->data, a->length)) != 0)
124 return cmp;
125 }
126
127 return a->type - b->type;
128}
129LCRYPTO_ALIAS(ASN1_STRING_cmp)asm("");
130
131int
132ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *src)
133{
134 if (src == NULL((void *)0))
135 return 0;
136
137 if (!ASN1_STRING_set(dst, src->data, src->length))
138 return 0;
139
140 dst->type = src->type;
141 dst->flags = src->flags & ~ASN1_STRING_FLAG_NDEF0x010;
142
143 return 1;
144}
145LCRYPTO_ALIAS(ASN1_STRING_copy)asm("");
146
147ASN1_STRING *
148ASN1_STRING_dup(const ASN1_STRING *src)
149{
150 ASN1_STRING *astr;
151
152 if (src == NULL((void *)0))
153 return NULL((void *)0);
154
155 if ((astr = ASN1_STRING_new()) == NULL((void *)0))
156 return NULL((void *)0);
157 if (!ASN1_STRING_copy(astr, src)) {
158 ASN1_STRING_free(astr);
159 return NULL((void *)0);
160 }
161 return astr;
162}
163LCRYPTO_ALIAS(ASN1_STRING_dup)asm("");
164
165int
166ASN1_STRING_set(ASN1_STRING *astr, const void *_data, int len)
167{
168 const char *data = _data;
169
170 if (len == -1) {
171 size_t slen;
172
173 if (data == NULL((void *)0))
174 return 0;
175
176 if ((slen = strlen(data)) > INT_MAX0x7fffffff)
177 return 0;
178
179 len = (int)slen;
180 }
181
182 ASN1_STRING_clear(astr);
183
184 if (len < 0 || len >= INT_MAX0x7fffffff)
185 return 0;
186
187 if ((astr->data = calloc(1, len + 1)) == NULL((void *)0)) {
188 ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/a_string.c"
,188)
;
189 return 0;
190 }
191 astr->length = len;
192
193 if (data != NULL((void *)0)) {
194 memcpy(astr->data, data, len);
195 astr->data[len] = '\0';
196 }
197
198 return 1;
199}
200LCRYPTO_ALIAS(ASN1_STRING_set)asm("");
201
202void
203ASN1_STRING_set0(ASN1_STRING *astr, void *data, int len)
204{
205 ASN1_STRING_clear(astr);
206
207 astr->data = data;
208 astr->length = len;
209}
210LCRYPTO_ALIAS(ASN1_STRING_set0)asm("");
211
212int
213ASN1_STRING_length(const ASN1_STRING *astr)
214{
215 return astr->length;
216}
217LCRYPTO_ALIAS(ASN1_STRING_length)asm("");
218
219void
220ASN1_STRING_length_set(ASN1_STRING *astr, int len)
221{
222 /* This is dangerous and unfixable. */
223 astr->length = len;
224}
225LCRYPTO_ALIAS(ASN1_STRING_length_set)asm("");
226
227int
228ASN1_STRING_type(const ASN1_STRING *astr)
229{
230 return astr->type;
231}
232LCRYPTO_ALIAS(ASN1_STRING_type)asm("");
233
234unsigned char *
235ASN1_STRING_data(ASN1_STRING *astr)
236{
237 return astr->data;
238}
239LCRYPTO_ALIAS(ASN1_STRING_data)asm("");
240
241const unsigned char *
242ASN1_STRING_get0_data(const ASN1_STRING *astr)
243{
244 return astr->data;
245}
246LCRYPTO_ALIAS(ASN1_STRING_get0_data)asm("");
247
248int
249ASN1_STRING_print(BIO *bp, const ASN1_STRING *astr)
250{
251 int i, n;
252 char buf[80];
253 const char *p;
254
255 if (astr == NULL((void *)0))
256 return 0;
257
258 n = 0;
259 p = (const char *)astr->data;
260 for (i = 0; i < astr->length; i++) {
261 if ((p[i] > '~') || ((p[i] < ' ') &&
262 (p[i] != '\n') && (p[i] != '\r')))
263 buf[n] = '.';
264 else
265 buf[n] = p[i];
266 n++;
267 if (n >= 80) {
268 if (BIO_write(bp, buf, n) <= 0)
269 return 0;
270 n = 0;
271 }
272 }
273 if (n > 0) {
274 if (BIO_write(bp, buf, n) <= 0)
275 return 0;
276 }
277
278 return 1;
279}
280LCRYPTO_ALIAS(ASN1_STRING_print)asm("");
281
282/*
283 * Utility function: convert any string type to UTF8, returns number of bytes
284 * in output string or a negative error code
285 */
286int
287ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in)
288{
289 ASN1_STRING *astr = NULL((void *)0);
290 int mbflag;
291 int ret = -1;
292
293 /*
294 * XXX We can't fail on *out != NULL here since things like haproxy and
295 * grpc pass in a pointer to an uninitialized pointer on the stack.
296 */
297 if (out == NULL((void *)0))
298 goto err;
299
300 if (in == NULL((void *)0))
301 goto err;
302
303 if ((mbflag = asn1_tag2charwidth(in->type)) == -1)
304 goto err;
305
306 mbflag |= MBSTRING_FLAG0x1000;
307
308 if ((ret = ASN1_mbstring_copy(&astr, in->data, in->length, mbflag,
309 B_ASN1_UTF8STRING0x2000)) < 0)
310 goto err;
311
312 *out = astr->data;
313 ret = astr->length;
314
315 astr->data = NULL((void *)0);
316 astr->length = 0;
317
318 err:
319 ASN1_STRING_free(astr);
320
321 return ret;
322}
323LCRYPTO_ALIAS(ASN1_STRING_to_UTF8)asm("");
324
325int
326i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *astr, int type)
327{
328 int i, n = 0;
329 static const char h[] = "0123456789ABCDEF";
330 char buf[2];
331
332 if (astr == NULL((void *)0))
333 return 0;
334
335 if (astr->length == 0) {
336 if (BIO_write(bp, "0", 1) != 1)
337 goto err;
338 n = 1;
339 } else {
340 for (i = 0; i < astr->length; i++) {
341 if ((i != 0) && (i % 35 == 0)) {
342 if (BIO_write(bp, "\\\n", 2) != 2)
343 goto err;
344 n += 2;
345 }
346 buf[0] = h[((unsigned char)astr->data[i] >> 4) & 0x0f];
347 buf[1] = h[((unsigned char)astr->data[i]) & 0x0f];
348 if (BIO_write(bp, buf, 2) != 2)
349 goto err;
350 n += 2;
351 }
352 }
353 return n;
354
355 err:
356 return -1;
357}
358LCRYPTO_ALIAS(i2a_ASN1_STRING)asm("");
359
360int
361a2i_ASN1_STRING(BIO *bp, ASN1_STRING *astr, char *buf, int size)
362{
363 int ret = 0;
364 int i, j, k, m, n, again, bufsize;
365 unsigned char *s = NULL((void *)0), *sp;
366 unsigned char *bufp;
367 int first = 1;
368 size_t num = 0, slen = 0;
369
370 bufsize = BIO_gets(bp, buf, size);
371 for (;;) {
1
Loop condition is true. Entering loop body
372 if (bufsize < 1) {
2
Assuming 'bufsize' is >= 1
3
Taking false branch
373 if (first)
374 break;
375 else
376 goto err_sl;
377 }
378 first = 0;
379
380 i = bufsize;
381 if (buf[i-1] == '\n')
4
Assuming the condition is false
5
Taking false branch
382 buf[--i] = '\0';
383 if (i
5.1
'i' is not equal to 0
== 0)
6
Taking false branch
384 goto err_sl;
385 if (buf[i-1] == '\r')
7
Assuming the condition is false
8
Taking false branch
386 buf[--i] = '\0';
387 if (i
8.1
'i' is not equal to 0
== 0)
9
Taking false branch
388 goto err_sl;
389 if (buf[i - 1] == '\\') {
10
Assuming the condition is false
11
Taking false branch
390 i--;
391 again = 1;
392 } else
393 again = 0;
394 buf[i] = '\0';
395 if (i < 2)
12
Assuming 'i' is >= 2
13
Taking false branch
396 goto err_sl;
397
398 bufp = (unsigned char *)buf;
399
400 k = 0;
401 if (i % 2 != 0) {
14
Assuming the condition is false
15
Taking false branch
402 ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS)ERR_put_error(13,(0xfff),(145),"/usr/src/lib/libcrypto/asn1/a_string.c"
,402)
;
403 goto err;
404 }
405 i /= 2;
406 if (num + i > slen) {
16
Assuming the condition is true
17
Taking true branch
407 sp = realloc(s, num + i);
18
Storing uninitialized value
408 if (sp == NULL((void *)0)) {
19
Assuming 'sp' is not equal to NULL
20
Taking false branch
409 ASN1error(ERR_R_MALLOC_FAILURE)ERR_put_error(13,(0xfff),((1|64)),"/usr/src/lib/libcrypto/asn1/a_string.c"
,409)
;
410 goto err;
411 }
412 s = sp;
413 slen = num + i;
414 }
415 for (j = 0; j
20.1
'j' is < 'i'
< i; j++, k += 2) {
21
Loop condition is true. Entering loop body
416 for (n = 0; n < 2; n++) {
22
Loop condition is true. Entering loop body
417 m = bufp[k + n];
418 if ((m >= '0') && (m <= '9'))
23
Assuming the condition is true
24
Assuming the condition is true
25
Taking true branch
419 m -= '0';
420 else if ((m >= 'a') && (m <= 'f'))
421 m = m - 'a' + 10;
422 else if ((m >= 'A') && (m <= 'F'))
423 m = m - 'A' + 10;
424 else {
425 ASN1error(ASN1_R_NON_HEX_CHARACTERS)ERR_put_error(13,(0xfff),(141),"/usr/src/lib/libcrypto/asn1/a_string.c"
,425)
;
426 goto err;
427 }
428 s[num + j] <<= 4;
26
The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage
429 s[num + j] |= m;
430 }
431 }
432 num += i;
433 if (again)
434 bufsize = BIO_gets(bp, buf, size);
435 else
436 break;
437 }
438 astr->length = num;
439 astr->data = s;
440
441 return 1;
442
443 err_sl:
444 ASN1error(ASN1_R_SHORT_LINE)ERR_put_error(13,(0xfff),(150),"/usr/src/lib/libcrypto/asn1/a_string.c"
,444)
;
445 err:
446 free(s);
447
448 return ret;
449}
450LCRYPTO_ALIAS(a2i_ASN1_STRING)asm("");