Bug Summary

File:s/cmd/p7sign/p7sign.c
Warning:line 205, column 13
Although the value stored to 'status' is used in the enclosing expression, the value is never actually read from 'status'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name p7sign.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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -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 -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/p7sign -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/p7sign -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -I ../../../dist/public/seccmd -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c p7sign.c
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5/*
6 * p7sign -- A command to create a *detached* pkcs7 signature (over a given
7 * input file).
8 */
9
10#include "nspr.h"
11#include "plgetopt.h"
12#include "secutil.h"
13#include "secpkcs7.h"
14#include "cert.h"
15#include "certdb.h"
16#include "sechash.h" /* for HASH_GetHashObject() */
17#include "nss.h"
18#include "pk11func.h"
19
20#if defined(XP_UNIX1)
21#include <unistd.h>
22#endif
23
24#include <stdio.h>
25#include <string.h>
26
27#if (defined(XP_WIN) && !defined(WIN32)) || (defined(__sun) && !defined(SVR4))
28extern int fread(char *, size_t, size_t, FILE *);
29extern int fwrite(char *, size_t, size_t, FILE *);
30extern int fprintf(FILE *, char *, ...);
31#endif
32
33static secuPWData pwdata = { PW_NONE, 0 };
34
35static void
36Usage(char *progName)
37{
38 HASH_HashType hashAlg;
39
40 fprintf(stderrstderr,
41 "Usage: %s -k keyname [-d keydir] [-i input] [-o output] [-e]\n",
42 progName);
43 fprintf(stderrstderr,
44 " %*s [-p password|-f password file] [-a hash] [-u certusage]\n",
45 (int)strlen(progName), "");
46 fprintf(stderrstderr, "%-20s Nickname of key to use for signature\n",
47 "-k keyname");
48 fprintf(stderrstderr, "%-20s Key database directory (default is ~/.netscape)\n",
49 "-d keydir");
50 fprintf(stderrstderr, "%-20s Define an input file to use (default is stdin)\n",
51 "-i input");
52 fprintf(stderrstderr, "%-20s Define an output file to use (default is stdout)\n",
53 "-o output");
54 fprintf(stderrstderr, "%-20s Encapsulate content in signature message\n",
55 "-e");
56 fprintf(stderrstderr, "%-20s Password to the key databse\n", "-p password");
57 fprintf(stderrstderr, "%-20s File to read password from\n", "-f password file");
58 fprintf(stderrstderr, "%-20s Use case-insensitive hash algorithm (default: SHA-1)\n",
59 "-a hash");
60 fprintf(stderrstderr, "%-25s ", "");
61 for (hashAlg = HASH_AlgNULL + 1; hashAlg != HASH_AlgTOTAL; ++hashAlg)
62 fprintf(stderrstderr, "%s%s", hashAlg == HASH_AlgNULL + 1 ? "" : ", ",
63 SECOID_FindOIDByTagSECOID_FindOIDByTag_Util(HASH_GetHashOidTagByHashType(hashAlg))->desc);
64 fputc('\n', stderrstderr);
65 fprintf(stderrstderr, "%-20s Sign for usage (default: certUsageEmailSigner)\n",
66 "-u certusage");
67 fprintf(stderrstderr, "%-25s 0 - certUsageSSLClient\n", "");
68 fprintf(stderrstderr, "%-25s 1 - certUsageSSLServer\n", "");
69 fprintf(stderrstderr, "%-25s 2 - certUsageSSLServerWithStepUp\n", "");
70 fprintf(stderrstderr, "%-25s 3 - certUsageSSLCA\n", "");
71 fprintf(stderrstderr, "%-25s 4 - certUsageEmailSigner\n", "");
72 fprintf(stderrstderr, "%-25s 5 - certUsageEmailRecipient\n", "");
73 fprintf(stderrstderr, "%-25s 6 - certUsageObjectSigner\n", "");
74 fprintf(stderrstderr, "%-25s 7 - certUsageUserCertImport\n", "");
75 fprintf(stderrstderr, "%-25s 8 - certUsageVerifyCA\n", "");
76 fprintf(stderrstderr, "%-25s 9 - certUsageProtectedObjectSigner\n", "");
77 fprintf(stderrstderr, "%-25s 10 - certUsageStatusResponder\n", "");
78 fprintf(stderrstderr, "%-25s 11 - certUsageAnyCA\n", "");
79 fprintf(stderrstderr, "%-25s 12 - certUsageIPsec\n", "");
80 exit(-1);
81}
82
83static void
84SignOut(void *arg, const char *buf, unsigned long len)
85{
86 FILE *out;
87
88 out = (FILE *)arg;
89 fwrite(buf, len, 1, out);
90}
91
92static int
93CreateDigest(SECItem *data, char *digestdata, unsigned int *len,
94 unsigned int maxlen, HASH_HashType hashAlg)
95{
96 const SECHashObject *hashObj;
97 void *hashcx;
98
99 hashObj = HASH_GetHashObject(hashAlg);
100
101 hashcx = (*hashObj->create)();
102 if (hashcx == NULL((void*)0))
103 return -1;
104
105 (*hashObj->begin)(hashcx);
106 (*hashObj->update)(hashcx, data->data, data->len);
107 (*hashObj->end)(hashcx, (unsigned char *)digestdata, len, maxlen);
108 (*hashObj->destroy)(hashcx, PR_TRUE1);
109 return 0;
110}
111
112static int
113SignFile(FILE *outFile, PRFileDesc *inFile, CERTCertificate *cert,
114 PRBool encapsulated, HASH_HashType hashAlg, SECOidTag hashAlgOid,
115 SECCertUsage usage)
116{
117 char digestdata[HASH_LENGTH_MAX64];
118 unsigned int len;
119 SECItem digest, data2sign;
120 SEC_PKCS7ContentInfo *cinfo;
121 SECStatus rv;
122
123 if (outFile == NULL((void*)0) || inFile == NULL((void*)0) || cert == NULL((void*)0))
124 return -1;
125
126 /* suck the file in */
127 if (SECU_ReadDERFromFile(&data2sign, inFile, PR_FALSE0,
128 PR_FALSE0) != SECSuccess)
129 return -1;
130
131 if (!encapsulated) {
132 /* unfortunately, we must create the digest ourselves */
133 /* SEC_PKCS7CreateSignedData should have a flag to not include */
134 /* the content for non-encapsulated content at encode time, but */
135 /* should always compute the hash itself */
136 if (CreateDigest(&data2sign, digestdata, &len,
137 sizeof(digestdata), hashAlg) < 0) {
138 SECITEM_FreeItemSECITEM_FreeItem_Util(&data2sign, PR_FALSE0);
139 return -1;
140 }
141 digest.data = (unsigned char *)digestdata;
142 digest.len = len;
143 }
144
145 cinfo = SEC_PKCS7CreateSignedData(cert, usage, NULL((void*)0),
146 hashAlgOid,
147 encapsulated ? NULL((void*)0) : &digest,
148 NULL((void*)0), NULL((void*)0));
149 if (cinfo == NULL((void*)0)) {
150 SECITEM_FreeItemSECITEM_FreeItem_Util(&data2sign, PR_FALSE0);
151 return -1;
152 }
153
154 if (encapsulated) {
155 SEC_PKCS7SetContent(cinfo, (char *)data2sign.data, data2sign.len);
156 }
157
158 rv = SEC_PKCS7IncludeCertChain(cinfo, NULL((void*)0));
159 if (rv != SECSuccess) {
160 SEC_PKCS7DestroyContentInfo(cinfo);
161 SECITEM_FreeItemSECITEM_FreeItem_Util(&data2sign, PR_FALSE0);
162 return -1;
163 }
164
165 rv = SEC_PKCS7Encode(cinfo, SignOut, outFile, NULL((void*)0),
166 NULL((void*)0), &pwdata);
167
168 SECITEM_FreeItemSECITEM_FreeItem_Util(&data2sign, PR_FALSE0);
169 SEC_PKCS7DestroyContentInfo(cinfo);
170
171 if (rv != SECSuccess)
172 return -1;
173
174 return 0;
175}
176
177int
178main(int argc, char **argv)
179{
180 char *progName;
181 FILE *outFile;
182 PRFileDesc *inFile;
183 char *keyName = NULL((void*)0);
184 CERTCertDBHandle *certHandle;
185 CERTCertificate *cert = NULL((void*)0);
186 PRBool encapsulated = PR_FALSE0;
187 HASH_HashType hashAlg = HASH_AlgSHA1;
188 SECOidTag hashAlgOid = SEC_OID_SHA1;
189 SECCertUsage usage = certUsageEmailSigner;
190 PLOptState *optstate;
191 PLOptStatus status;
192 SECStatus rv;
193
194 progName = strrchr(argv[0], '/');
195 progName = progName ? progName + 1 : argv[0];
196
197 inFile = NULL((void*)0);
198 outFile = NULL((void*)0);
199 keyName = NULL((void*)0);
200
201 /*
202 * Parse command line arguments
203 */
204 optstate = PL_CreateOptState(argc, argv, "ed:k:i:o:p:f:a:u:");
205 while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
Although the value stored to 'status' is used in the enclosing expression, the value is never actually read from 'status'
206 switch (optstate->option) {
207 case '?':
208 Usage(progName);
209 break;
210
211 case 'e':
212 /* create a message with the signed content encapsulated */
213 encapsulated = PR_TRUE1;
214 break;
215
216 case 'd':
217 SECU_ConfigDirectory(optstate->value);
218 break;
219
220 case 'i':
221 inFile = PR_Open(optstate->value, PR_RDONLY0x01, 0);
222 if (!inFile) {
223 fprintf(stderrstderr, "%s: unable to open \"%s\" for reading\n",
224 progName, optstate->value);
225 return -1;
226 }
227 break;
228
229 case 'k':
230 keyName = strdup(optstate->value);
231 break;
232
233 case 'o':
234 outFile = fopen(optstate->value, "wb");
235 if (!outFile) {
236 fprintf(stderrstderr, "%s: unable to open \"%s\" for writing\n",
237 progName, optstate->value);
238 return -1;
239 }
240 break;
241 case 'p':
242 pwdata.source = PW_PLAINTEXT;
243 pwdata.data = strdup(optstate->value);
244 break;
245
246 case 'f':
247 pwdata.source = PW_FROMFILE;
248 pwdata.data = PORT_StrdupPORT_Strdup_Util(optstate->value);
249 break;
250
251 case 'a':
252 for (hashAlg = HASH_AlgNULL + 1; hashAlg != HASH_AlgTOTAL;
253 ++hashAlg) {
254 hashAlgOid = HASH_GetHashOidTagByHashType(hashAlg);
255 if (!PORT_StrcasecmpPL_strcasecmp(optstate->value,
256 SECOID_FindOIDByTagSECOID_FindOIDByTag_Util(hashAlgOid)->desc))
257 break;
258 }
259 if (hashAlg == HASH_AlgTOTAL)
260 Usage(progName);
261 break;
262
263 case 'u':
264 usage = atoi(optstate->value);
265 if (usage < certUsageSSLClient || usage > certUsageIPsec)
266 Usage(progName);
267 break;
268 }
269 }
270 PL_DestroyOptState(optstate);
271
272 if (!keyName)
273 Usage(progName);
274
275 if (!inFile)
276 inFile = PR_STDINPR_GetSpecialFD(PR_StandardInput);
277 if (!outFile)
278 outFile = stdoutstdout;
279
280 /* Call the initialization routines */
281 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
282 rv = NSS_Init(SECU_ConfigDirectory(NULL((void*)0)));
283 if (rv != SECSuccess) {
284 SECU_PrintPRandOSError(progName);
285 goto loser;
286 }
287
288 PK11_SetPasswordFunc(SECU_GetModulePassword);
289
290 /* open cert database */
291 certHandle = CERT_GetDefaultCertDB();
292 if (certHandle == NULL((void*)0)) {
293 rv = SECFailure;
294 goto loser;
295 }
296
297 /* find cert */
298 cert = SECU_FindCertByNicknameOrFilename(certHandle, keyName, PR_FALSE0, NULL((void*)0));
299 if (cert == NULL((void*)0)) {
300 SECU_PrintError(progName,
301 "the corresponding cert for key \"%s\" does not exist",
302 keyName);
303 rv = SECFailure;
304 goto loser;
305 }
306
307 if (SignFile(outFile, inFile, cert, encapsulated,
308 hashAlg, hashAlgOid, usage)) {
309 SECU_PrintError(progName, "problem signing data");
310 rv = SECFailure;
311 goto loser;
312 }
313
314loser:
315 if (pwdata.data) {
316 PORT_FreePORT_Free_Util(pwdata.data);
317 }
318 if (keyName) {
319 PORT_FreePORT_Free_Util(keyName);
320 }
321 if (cert) {
322 CERT_DestroyCertificate(cert);
323 }
324 if (inFile && inFile != PR_STDINPR_GetSpecialFD(PR_StandardInput)) {
325 PR_Close(inFile);
326 }
327 if (outFile && outFile != stdoutstdout) {
328 fclose(outFile);
329 }
330 if (NSS_Shutdown() != SECSuccess) {
331 SECU_PrintError(progName, "NSS shutdown:");
332 exit(1);
333 }
334
335 return (rv != SECSuccess);
336}