Bug Summary

File:src/lib/libcrypto/cms/cms_ess.c
Warning:line 213, column 7
Access to field 'digestAlgorithm' results in a dereference of a null pointer (loaded from variable 'si')

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 cms_ess.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/cms/cms_ess.c
1/* $OpenBSD: cms_ess.c,v 1.23 2023/07/08 08:26:26 beck Exp $ */
2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4 * project.
5 */
6/* ====================================================================
7 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 */
54
55#include <string.h>
56
57#include "cryptlib.h"
58#include <openssl/asn1t.h>
59#include <openssl/pem.h>
60#include <openssl/rand.h>
61#include <openssl/x509v3.h>
62#include <openssl/err.h>
63#include <openssl/cms.h>
64#include "cms_local.h"
65
66
67CMS_ReceiptRequest *
68d2i_CMS_ReceiptRequest(CMS_ReceiptRequest **a, const unsigned char **in, long len)
69{
70 return (CMS_ReceiptRequest *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
71 &CMS_ReceiptRequest_it);
72}
73LCRYPTO_ALIAS(d2i_CMS_ReceiptRequest)asm("");
74
75int
76i2d_CMS_ReceiptRequest(CMS_ReceiptRequest *a, unsigned char **out)
77{
78 return ASN1_item_i2d((ASN1_VALUE *)a, out, &CMS_ReceiptRequest_it);
79}
80LCRYPTO_ALIAS(i2d_CMS_ReceiptRequest)asm("");
81
82CMS_ReceiptRequest *
83CMS_ReceiptRequest_new(void)
84{
85 return (CMS_ReceiptRequest *)ASN1_item_new(&CMS_ReceiptRequest_it);
86}
87LCRYPTO_ALIAS(CMS_ReceiptRequest_new)asm("");
88
89void
90CMS_ReceiptRequest_free(CMS_ReceiptRequest *a)
91{
92 ASN1_item_free((ASN1_VALUE *)a, &CMS_ReceiptRequest_it);
93}
94LCRYPTO_ALIAS(CMS_ReceiptRequest_free)asm("");
95
96/* ESS services: for now just Signed Receipt related */
97
98int
99CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
100{
101 ASN1_STRING *str;
102 CMS_ReceiptRequest *rr = NULL((void *)0);
103
104 if (prr)
105 *prr = NULL((void *)0);
106 str = CMS_signed_get0_data_by_OBJ(si,
107 OBJ_nid2obj(NID_id_smime_aa_receiptRequest212), -3, V_ASN1_SEQUENCE16);
108 if (!str)
109 return 0;
110
111 rr = ASN1_item_unpack(str, &CMS_ReceiptRequest_it);
112 if (!rr)
113 return -1;
114 if (prr)
115 *prr = rr;
116 else
117 CMS_ReceiptRequest_free(rr);
118
119 return 1;
120}
121
122CMS_ReceiptRequest *
123CMS_ReceiptRequest_create0(unsigned char *id, int idlen, int allorfirst,
124 STACK_OF(GENERAL_NAMES)struct stack_st_GENERAL_NAMES *receiptList, STACK_OF(GENERAL_NAMES)struct stack_st_GENERAL_NAMES *receiptsTo)
125{
126 CMS_ReceiptRequest *rr = NULL((void *)0);
127
128 rr = CMS_ReceiptRequest_new();
129 if (rr == NULL((void *)0))
130 goto merr;
131 if (id)
132 ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
133 else {
134 if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL((void *)0), 32))
135 goto merr;
136 arc4random_buf(rr->signedContentIdentifier->data, 32);
137 }
138
139 sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free)sk_pop_free(((_STACK*) (1 ? (rr->receiptsTo) : (struct stack_st_GENERAL_NAMES
*)0)), ((void (*)(void *)) ((1 ? (GENERAL_NAMES_free) : (void
(*)(GENERAL_NAMES *))0))))
;
140 rr->receiptsTo = receiptsTo;
141
142 if (receiptList) {
143 rr->receiptsFrom->type = 1;
144 rr->receiptsFrom->d.receiptList = receiptList;
145 } else {
146 rr->receiptsFrom->type = 0;
147 rr->receiptsFrom->d.allOrFirstTier = allorfirst;
148 }
149
150 return rr;
151
152 merr:
153 CMSerror(ERR_R_MALLOC_FAILURE)ERR_put_error(46,(0xfff),((1|64)),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,153)
;
154 CMS_ReceiptRequest_free(rr);
155
156 return NULL((void *)0);
157}
158
159int
160CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
161{
162 unsigned char *rrder = NULL((void *)0);
163 int rrderlen, r = 0;
164
165 rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
166 if (rrderlen < 0)
167 goto merr;
168
169 if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest212,
170 V_ASN1_SEQUENCE16, rrder, rrderlen))
171 goto merr;
172
173 r = 1;
174
175 merr:
176 if (!r)
177 CMSerror(ERR_R_MALLOC_FAILURE)ERR_put_error(46,(0xfff),((1|64)),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,177)
;
178
179 free(rrder);
180
181 return r;
182}
183
184void
185CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, ASN1_STRING **pcid,
186 int *pallorfirst, STACK_OF(GENERAL_NAMES)struct stack_st_GENERAL_NAMES **plist,
187 STACK_OF(GENERAL_NAMES)struct stack_st_GENERAL_NAMES **prto)
188{
189 if (pcid)
190 *pcid = rr->signedContentIdentifier;
191 if (rr->receiptsFrom->type == 0) {
192 if (pallorfirst)
193 *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
194 if (plist)
195 *plist = NULL((void *)0);
196 } else {
197 if (pallorfirst)
198 *pallorfirst = -1;
199 if (plist)
200 *plist = rr->receiptsFrom->d.receiptList;
201 }
202 if (prto)
203 *prto = rr->receiptsTo;
204}
205
206/* Digest a SignerInfo structure for msgSigDigest attribute processing */
207
208static int
209cms_msgSigDigest(CMS_SignerInfo *si, unsigned char *dig, unsigned int *diglen)
210{
211 const EVP_MD *md;
212
213 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm)EVP_get_digestbyname(OBJ_nid2sn(OBJ_obj2nid(si->digestAlgorithm
->algorithm)))
;
26
Access to field 'digestAlgorithm' results in a dereference of a null pointer (loaded from variable 'si')
214 if (md == NULL((void *)0))
215 return 0;
216 if (!ASN1_item_digest(&CMS_Attributes_Verify_it, md,
217 si->signedAttrs, dig, diglen))
218 return 0;
219
220 return 1;
221}
222
223/* Add a msgSigDigest attribute to a SignerInfo */
224
225int
226cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
227{
228 unsigned char dig[EVP_MAX_MD_SIZE64];
229 unsigned int diglen;
230
231 if (!cms_msgSigDigest(src, dig, &diglen)) {
232 CMSerror(CMS_R_MSGSIGDIGEST_ERROR)ERR_put_error(46,(0xfff),(172),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,232)
;
233 return 0;
234 }
235 if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest216,
236 V_ASN1_OCTET_STRING4, dig, diglen)) {
237 CMSerror(ERR_R_MALLOC_FAILURE)ERR_put_error(46,(0xfff),((1|64)),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,237)
;
238 return 0;
239 }
240
241 return 1;
242}
243
244/* Verify signed receipt after it has already passed normal CMS verify */
245
246int
247cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
248{
249 int r = 0, i;
250 CMS_ReceiptRequest *rr = NULL((void *)0);
251 CMS_Receipt *rct = NULL((void *)0);
252 STACK_OF(CMS_SignerInfo)struct stack_st_CMS_SignerInfo *sis, *osis;
253 CMS_SignerInfo *si, *osi = NULL((void *)0);
1
'osi' initialized to a null pointer value
254 ASN1_OCTET_STRING *msig, **pcont;
255 ASN1_OBJECT *octype;
256 unsigned char dig[EVP_MAX_MD_SIZE64];
257 unsigned int diglen;
258
259 /* Get SignerInfos, also checks SignedData content type */
260 osis = CMS_get0_SignerInfos(req_cms);
261 sis = CMS_get0_SignerInfos(cms);
262 if (!osis || !sis)
2
Assuming 'osis' is non-null
3
Assuming 'sis' is non-null
4
Taking false branch
263 goto err;
264
265 if (sk_CMS_SignerInfo_num(sis)sk_num(((_STACK*) (1 ? (sis) : (struct stack_st_CMS_SignerInfo
*)0)))
!= 1
) {
5
'?' condition is true
6
Assuming the condition is false
7
Taking false branch
266 CMSerror(CMS_R_NEED_ONE_SIGNER)ERR_put_error(46,(0xfff),(164),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,266)
;
267 goto err;
268 }
269
270 /* Check receipt content type */
271 if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt204) {
8
Assuming the condition is false
9
Taking false branch
272 CMSerror(CMS_R_NOT_A_SIGNED_RECEIPT)ERR_put_error(46,(0xfff),(165),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,272)
;
273 goto err;
274 }
275
276 /* Extract and decode receipt content */
277 pcont = CMS_get0_content(cms);
278 if (!pcont || !*pcont) {
10
Assuming 'pcont' is non-null
11
Assuming the condition is false
12
Taking false branch
279 CMSerror(CMS_R_NO_CONTENT)ERR_put_error(46,(0xfff),(127),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,279)
;
280 goto err;
281 }
282
283 rct = ASN1_item_unpack(*pcont, &CMS_Receipt_it);
284
285 if (!rct) {
13
Assuming 'rct' is non-null
14
Taking false branch
286 CMSerror(CMS_R_RECEIPT_DECODE_ERROR)ERR_put_error(46,(0xfff),(169),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,286)
;
287 goto err;
288 }
289
290 /* Locate original request */
291
292 for (i = 0; i < sk_CMS_SignerInfo_num(osis)sk_num(((_STACK*) (1 ? (osis) : (struct stack_st_CMS_SignerInfo
*)0)))
; i++) {
15
'?' condition is true
16
Assuming the condition is false
17
Loop condition is false. Execution continues on line 298
293 osi = sk_CMS_SignerInfo_value(osis, i)((CMS_SignerInfo *)sk_value(((_STACK*) (1 ? (osis) : (struct stack_st_CMS_SignerInfo
*)0)), (i)))
;
294 if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue))
295 break;
296 }
297
298 if (i == sk_CMS_SignerInfo_num(osis)sk_num(((_STACK*) (1 ? (osis) : (struct stack_st_CMS_SignerInfo
*)0)))
) {
18
'?' condition is true
19
Assuming the condition is false
20
Taking false branch
299 CMSerror(CMS_R_NO_MATCHING_SIGNATURE)ERR_put_error(46,(0xfff),(166),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,299)
;
300 goto err;
301 }
302
303 si = sk_CMS_SignerInfo_value(sis, 0)((CMS_SignerInfo *)sk_value(((_STACK*) (1 ? (sis) : (struct stack_st_CMS_SignerInfo
*)0)), (0)))
;
21
'?' condition is true
304
305 /* Get msgSigDigest value and compare */
306
307 msig = CMS_signed_get0_data_by_OBJ(si,
308 OBJ_nid2obj(NID_id_smime_aa_msgSigDigest216), -3, V_ASN1_OCTET_STRING4);
309
310 if (!msig) {
22
Assuming 'msig' is non-null
23
Taking false branch
311 CMSerror(CMS_R_NO_MSGSIGDIGEST)ERR_put_error(46,(0xfff),(167),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,311)
;
312 goto err;
313 }
314
315 if (!cms_msgSigDigest(osi, dig, &diglen)) {
24
Passing null pointer value via 1st parameter 'si'
25
Calling 'cms_msgSigDigest'
316 CMSerror(CMS_R_MSGSIGDIGEST_ERROR)ERR_put_error(46,(0xfff),(172),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,316)
;
317 goto err;
318 }
319
320 if (diglen != (unsigned int)msig->length) {
321 CMSerror(CMS_R_MSGSIGDIGEST_WRONG_LENGTH)ERR_put_error(46,(0xfff),(163),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,321)
;
322 goto err;
323 }
324
325 if (memcmp(dig, msig->data, diglen)) {
326 CMSerror(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE)ERR_put_error(46,(0xfff),(162),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,326)
;
327 goto err;
328 }
329
330 /* Compare content types */
331
332 octype = CMS_signed_get0_data_by_OBJ(osi,
333 OBJ_nid2obj(NID_pkcs9_contentType50), -3, V_ASN1_OBJECT6);
334 if (!octype) {
335 CMSerror(CMS_R_NO_CONTENT_TYPE)ERR_put_error(46,(0xfff),(173),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,335)
;
336 goto err;
337 }
338
339 /* Compare details in receipt request */
340
341 if (OBJ_cmp(octype, rct->contentType)) {
342 CMSerror(CMS_R_CONTENT_TYPE_MISMATCH)ERR_put_error(46,(0xfff),(171),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,342)
;
343 goto err;
344 }
345
346 /* Get original receipt request details */
347
348 if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) {
349 CMSerror(CMS_R_NO_RECEIPT_REQUEST)ERR_put_error(46,(0xfff),(168),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,349)
;
350 goto err;
351 }
352
353 if (ASN1_STRING_cmp(rr->signedContentIdentifier,
354 rct->signedContentIdentifier)) {
355 CMSerror(CMS_R_CONTENTIDENTIFIER_MISMATCH)ERR_put_error(46,(0xfff),(170),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,355)
;
356 goto err;
357 }
358
359 r = 1;
360
361 err:
362 CMS_ReceiptRequest_free(rr);
363 ASN1_item_free((ASN1_VALUE *)rct, &CMS_Receipt_it);
364 return r;
365}
366
367/*
368 * Encode a Receipt into an OCTET STRING read for including into content of a
369 * SignedData ContentInfo.
370 */
371
372ASN1_OCTET_STRING *
373cms_encode_Receipt(CMS_SignerInfo *si)
374{
375 CMS_Receipt rct;
376 CMS_ReceiptRequest *rr = NULL((void *)0);
377 ASN1_OBJECT *ctype;
378 ASN1_OCTET_STRING *os = NULL((void *)0);
379
380 /* Get original receipt request */
381
382 /* Get original receipt request details */
383
384 if (CMS_get1_ReceiptRequest(si, &rr) <= 0) {
385 CMSerror(CMS_R_NO_RECEIPT_REQUEST)ERR_put_error(46,(0xfff),(168),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,385)
;
386 goto err;
387 }
388
389 /* Get original content type */
390
391 ctype = CMS_signed_get0_data_by_OBJ(si,
392 OBJ_nid2obj(NID_pkcs9_contentType50), -3, V_ASN1_OBJECT6);
393 if (!ctype) {
394 CMSerror(CMS_R_NO_CONTENT_TYPE)ERR_put_error(46,(0xfff),(173),"/usr/src/lib/libcrypto/cms/cms_ess.c"
,394)
;
395 goto err;
396 }
397
398 rct.version = 1;
399 rct.contentType = ctype;
400 rct.signedContentIdentifier = rr->signedContentIdentifier;
401 rct.originatorSignatureValue = si->signature;
402
403 os = ASN1_item_pack(&rct, &CMS_Receipt_it, NULL((void *)0));
404
405 err:
406 CMS_ReceiptRequest_free(rr);
407 return os;
408}