Bug Summary

File:src/lib/libcrypto/asn1/bio_asn1.c
Warning:line 202, column 2
Value stored to 'ret' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name bio_asn1.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -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/lib/clang/13.0.0 -D LIBRESSL_INTERNAL -D LIBRESSL_CRYPTO_INTERNAL -D DSO_DLFCN -D HAVE_DLFCN_H -D HAVE_FUNOPEN -D OPENSSL_NO_HW_PADLOCK -I /usr/src/lib/libcrypto -I /usr/src/lib/libcrypto/asn1 -I /usr/src/lib/libcrypto/bio -I /usr/src/lib/libcrypto/bn -I /usr/src/lib/libcrypto/bytestring -I /usr/src/lib/libcrypto/dh -I /usr/src/lib/libcrypto/dsa -I /usr/src/lib/libcrypto/ec -I /usr/src/lib/libcrypto/ecdh -I /usr/src/lib/libcrypto/ecdsa -I /usr/src/lib/libcrypto/evp -I /usr/src/lib/libcrypto/hmac -I /usr/src/lib/libcrypto/modes -I /usr/src/lib/libcrypto/ocsp -I /usr/src/lib/libcrypto/rsa -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 OPENSSL_BN_ASM_GF2m -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 -D PIC -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libcrypto/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -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/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/lib/libcrypto/asn1/bio_asn1.c
1/* $OpenBSD: bio_asn1.c,v 1.16 2022/01/07 09:02:17 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59/* Experimental ASN1 BIO. When written through the data is converted
60 * to an ASN1 string type: default is OCTET STRING. Additional functions
61 * can be provided to add prefix and suffix data.
62 */
63
64#include <stdlib.h>
65#include <string.h>
66
67#include <openssl/bio.h>
68#include <openssl/asn1.h>
69
70#include "bio_local.h"
71
72/* Must be large enough for biggest tag+length */
73#define DEFAULT_ASN1_BUF_SIZE20 20
74
75typedef enum {
76 ASN1_STATE_START,
77 ASN1_STATE_PRE_COPY,
78 ASN1_STATE_HEADER,
79 ASN1_STATE_HEADER_COPY,
80 ASN1_STATE_DATA_COPY,
81 ASN1_STATE_POST_COPY,
82 ASN1_STATE_DONE
83} asn1_bio_state_t;
84
85typedef struct BIO_ASN1_EX_FUNCS_st {
86 asn1_ps_func *ex_func;
87 asn1_ps_func *ex_free_func;
88} BIO_ASN1_EX_FUNCS;
89
90typedef struct BIO_ASN1_BUF_CTX_t {
91 /* Internal state */
92 asn1_bio_state_t state;
93 /* Internal buffer */
94 unsigned char *buf;
95 /* Size of buffer */
96 int bufsize;
97 /* Current position in buffer */
98 int bufpos;
99 /* Current buffer length */
100 int buflen;
101 /* Amount of data to copy */
102 int copylen;
103 /* Class and tag to use */
104 int asn1_class, asn1_tag;
105 asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
106 /* Extra buffer for prefix and suffix data */
107 unsigned char *ex_buf;
108 int ex_len;
109 int ex_pos;
110 void *ex_arg;
111} BIO_ASN1_BUF_CTX;
112
113
114static int asn1_bio_write(BIO *h, const char *buf, int num);
115static int asn1_bio_read(BIO *h, char *buf, int size);
116static int asn1_bio_puts(BIO *h, const char *str);
117static int asn1_bio_gets(BIO *h, char *str, int size);
118static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
119static int asn1_bio_new(BIO *h);
120static int asn1_bio_free(BIO *data);
121static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
122
123static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
124 asn1_ps_func *cleanup, asn1_bio_state_t next);
125static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
126 asn1_ps_func *setup, asn1_bio_state_t ex_state,
127 asn1_bio_state_t other_state);
128
129static const BIO_METHOD methods_asn1 = {
130 .type = BIO_TYPE_ASN1(22|0x0200),
131 .name = "asn1",
132 .bwrite = asn1_bio_write,
133 .bread = asn1_bio_read,
134 .bputs = asn1_bio_puts,
135 .bgets = asn1_bio_gets,
136 .ctrl = asn1_bio_ctrl,
137 .create = asn1_bio_new,
138 .destroy = asn1_bio_free,
139 .callback_ctrl = asn1_bio_callback_ctrl
140};
141
142const BIO_METHOD *
143BIO_f_asn1(void)
144{
145 return (&methods_asn1);
146}
147
148static int
149asn1_bio_new(BIO *b)
150{
151 BIO_ASN1_BUF_CTX *ctx;
152
153 if ((ctx = calloc(1, sizeof(*ctx))) == NULL((void *)0))
154 return 0;
155
156 if ((ctx->buf = malloc(DEFAULT_ASN1_BUF_SIZE20)) == NULL((void *)0)) {
157 free(ctx);
158 return 0;
159 }
160 ctx->bufsize = DEFAULT_ASN1_BUF_SIZE20;
161 ctx->asn1_class = V_ASN1_UNIVERSAL0x00;
162 ctx->asn1_tag = V_ASN1_OCTET_STRING4;
163 ctx->state = ASN1_STATE_START;
164
165 b->init = 1;
166 b->ptr = (char *)ctx;
167 b->flags = 0;
168
169 return 1;
170}
171
172static int
173asn1_bio_free(BIO *b)
174{
175 BIO_ASN1_BUF_CTX *ctx;
176
177 ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
178 if (ctx == NULL((void *)0))
179 return 0;
180 free(ctx->buf);
181 free(ctx);
182 b->init = 0;
183 b->ptr = NULL((void *)0);
184 b->flags = 0;
185 return 1;
186}
187
188static int
189asn1_bio_write(BIO *b, const char *in , int inl)
190{
191 BIO_ASN1_BUF_CTX *ctx;
192 int wrmax, wrlen, ret, buflen;
193 unsigned char *p;
194
195 if (!in || (inl < 0) || (b->next_bio == NULL((void *)0)))
196 return 0;
197 ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
198 if (ctx == NULL((void *)0))
199 return 0;
200
201 wrlen = 0;
202 ret = -1;
Value stored to 'ret' is never read
203
204 for (;;) {
205 switch (ctx->state) {
206
207 /* Setup prefix data, call it */
208 case ASN1_STATE_START:
209 if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
210 ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
211 return 0;
212 break;
213
214 /* Copy any pre data first */
215 case ASN1_STATE_PRE_COPY:
216 ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
217 ASN1_STATE_HEADER);
218 if (ret <= 0)
219 goto done;
220 break;
221
222 case ASN1_STATE_HEADER:
223 buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
224 if (buflen <= 0 || buflen > ctx->bufsize)
225 return -1;
226 ctx->buflen = buflen;
227 p = ctx->buf;
228 ASN1_put_object(&p, 0, inl,
229 ctx->asn1_tag, ctx->asn1_class);
230 ctx->copylen = inl;
231 ctx->state = ASN1_STATE_HEADER_COPY;
232 break;
233
234 case ASN1_STATE_HEADER_COPY:
235 ret = BIO_write(b->next_bio,
236 ctx->buf + ctx->bufpos, ctx->buflen);
237 if (ret <= 0)
238 goto done;
239
240 ctx->buflen -= ret;
241 if (ctx->buflen)
242 ctx->bufpos += ret;
243 else {
244 ctx->bufpos = 0;
245 ctx->state = ASN1_STATE_DATA_COPY;
246 }
247 break;
248
249 case ASN1_STATE_DATA_COPY:
250
251 if (inl > ctx->copylen)
252 wrmax = ctx->copylen;
253 else
254 wrmax = inl;
255 ret = BIO_write(b->next_bio, in, wrmax);
256 if (ret <= 0)
257 break;
258 wrlen += ret;
259 ctx->copylen -= ret;
260 in += ret;
261 inl -= ret;
262
263 if (ctx->copylen == 0)
264 ctx->state = ASN1_STATE_HEADER;
265 if (inl == 0)
266 goto done;
267 break;
268
269 default:
270 BIO_clear_retry_flags(b)BIO_clear_flags(b, ((0x01|0x02|0x04)|0x08));
271 return 0;
272 }
273
274 }
275
276 done:
277 BIO_clear_retry_flags(b)BIO_clear_flags(b, ((0x01|0x02|0x04)|0x08));
278 BIO_copy_next_retry(b);
279
280 return (wrlen > 0) ? wrlen : ret;
281}
282
283static int
284asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, asn1_ps_func *cleanup,
285 asn1_bio_state_t next)
286{
287 int ret;
288
289 if (ctx->ex_len <= 0)
290 return 1;
291 for (;;) {
292 ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
293 ctx->ex_len);
294 if (ret <= 0)
295 break;
296 ctx->ex_len -= ret;
297 if (ctx->ex_len > 0)
298 ctx->ex_pos += ret;
299 else {
300 if (cleanup)
301 cleanup(b, &ctx->ex_buf, &ctx->ex_len,
302 &ctx->ex_arg);
303 ctx->state = next;
304 ctx->ex_pos = 0;
305 break;
306 }
307 }
308 return ret;
309}
310
311static int
312asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, asn1_ps_func *setup,
313 asn1_bio_state_t ex_state, asn1_bio_state_t other_state)
314{
315 if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
316 BIO_clear_retry_flags(b)BIO_clear_flags(b, ((0x01|0x02|0x04)|0x08));
317 return 0;
318 }
319 if (ctx->ex_len > 0)
320 ctx->state = ex_state;
321 else
322 ctx->state = other_state;
323 return 1;
324}
325
326static int
327asn1_bio_read(BIO *b, char *in , int inl)
328{
329 if (!b->next_bio)
330 return 0;
331 return BIO_read(b->next_bio, in , inl);
332}
333
334static int
335asn1_bio_puts(BIO *b, const char *str)
336{
337 return asn1_bio_write(b, str, strlen(str));
338}
339
340static int
341asn1_bio_gets(BIO *b, char *str, int size)
342{
343 if (!b->next_bio)
344 return 0;
345 return BIO_gets(b->next_bio, str , size);
346}
347
348static long
349asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
350{
351 if (b->next_bio == NULL((void *)0))
352 return (0);
353 return BIO_callback_ctrl(b->next_bio, cmd, fp);
354}
355
356static long
357asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
358{
359 BIO_ASN1_BUF_CTX *ctx;
360 BIO_ASN1_EX_FUNCS *ex_func;
361 long ret = 1;
362
363 ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
364 if (ctx == NULL((void *)0))
365 return 0;
366 switch (cmd) {
367
368 case BIO_C_SET_PREFIX149:
369 ex_func = arg2;
370 ctx->prefix = ex_func->ex_func;
371 ctx->prefix_free = ex_func->ex_free_func;
372 break;
373
374 case BIO_C_GET_PREFIX150:
375 ex_func = arg2;
376 ex_func->ex_func = ctx->prefix;
377 ex_func->ex_free_func = ctx->prefix_free;
378 break;
379
380 case BIO_C_SET_SUFFIX151:
381 ex_func = arg2;
382 ctx->suffix = ex_func->ex_func;
383 ctx->suffix_free = ex_func->ex_free_func;
384 break;
385
386 case BIO_C_GET_SUFFIX152:
387 ex_func = arg2;
388 ex_func->ex_func = ctx->suffix;
389 ex_func->ex_free_func = ctx->suffix_free;
390 break;
391
392 case BIO_C_SET_EX_ARG153:
393 ctx->ex_arg = arg2;
394 break;
395
396 case BIO_C_GET_EX_ARG154:
397 *(void **)arg2 = ctx->ex_arg;
398 break;
399
400 case BIO_CTRL_FLUSH11:
401 if (!b->next_bio)
402 return 0;
403
404 /* Call post function if possible */
405 if (ctx->state == ASN1_STATE_HEADER) {
406 if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
407 ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
408 return 0;
409 }
410
411 if (ctx->state == ASN1_STATE_POST_COPY) {
412 ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
413 ASN1_STATE_DONE);
414 if (ret <= 0)
415 return ret;
416 }
417
418 if (ctx->state == ASN1_STATE_DONE)
419 return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
420 else {
421 BIO_clear_retry_flags(b)BIO_clear_flags(b, ((0x01|0x02|0x04)|0x08));
422 return 0;
423 }
424 break;
425
426
427 default:
428 if (!b->next_bio)
429 return 0;
430 return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
431
432 }
433
434 return ret;
435}
436
437static int
438asn1_bio_set_ex(BIO *b, int cmd, asn1_ps_func *ex_func, asn1_ps_func
439 *ex_free_func)
440{
441 BIO_ASN1_EX_FUNCS extmp;
442
443 extmp.ex_func = ex_func;
444 extmp.ex_free_func = ex_free_func;
445 return BIO_ctrl(b, cmd, 0, &extmp);
446}
447
448static int
449asn1_bio_get_ex(BIO *b, int cmd, asn1_ps_func **ex_func,
450 asn1_ps_func **ex_free_func)
451{
452 BIO_ASN1_EX_FUNCS extmp;
453 int ret;
454
455 ret = BIO_ctrl(b, cmd, 0, &extmp);
456 if (ret > 0) {
457 *ex_func = extmp.ex_func;
458 *ex_free_func = extmp.ex_free_func;
459 }
460 return ret;
461}
462
463int
464BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
465{
466 return asn1_bio_set_ex(b, BIO_C_SET_PREFIX149, prefix, prefix_free);
467}
468
469int
470BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
471{
472 return asn1_bio_get_ex(b, BIO_C_GET_PREFIX150, pprefix, pprefix_free);
473}
474
475int
476BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
477{
478 return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX151, suffix, suffix_free);
479}
480
481int
482BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
483{
484 return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX152, psuffix, psuffix_free);
485}