Bug Summary

File:s/cmd/sdrtest/sdrtest.c
Warning:line 330, column 14
Null pointer passed to 1st parameter expecting 'nonnull'

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 sdrtest.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/sdrtest -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/sdrtest -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/dbm -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 sdrtest.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 * Test program for SDR (Secret Decoder Ring) functions.
7 */
8
9#include "nspr.h"
10#include "string.h"
11#include "nss.h"
12#include "secutil.h"
13#include "cert.h"
14#include "pk11func.h"
15
16#include "plgetopt.h"
17#include "pk11sdr.h"
18#include "nssb64.h"
19
20#define DEFAULT_VALUE"Test" "Test"
21static const char default_value[] = { DEFAULT_VALUE"Test" };
22
23PRFileDesc *pr_stderr;
24PRBool verbose = PR_FALSE0;
25
26static void
27synopsis(char *program_name)
28{
29 PR_fprintf(pr_stderr,
30 "Usage: %s [<common>] -i <input-file>\n"
31 " %s [<common>] -o <output-file>\n"
32 " <common> [-d dir] [-v] [-t text] [-a] [-f pwfile | -p pwd]\n",
33 program_name, program_name);
34}
35
36static void
37short_usage(char *program_name)
38{
39 PR_fprintf(pr_stderr,
40 "Type %s -H for more detailed descriptions\n",
41 program_name);
42 synopsis(program_name);
43}
44
45static void
46long_usage(char *program_name)
47{
48 synopsis(program_name);
49 PR_fprintf(pr_stderr, "\nSecret Decoder Test:\n");
50 PR_fprintf(pr_stderr,
51 " %-13s Read encrypted data from \"file\"\n",
52 "-i file");
53 PR_fprintf(pr_stderr,
54 " %-13s Write newly generated encrypted data to \"file\"\n",
55 "-o file");
56 PR_fprintf(pr_stderr,
57 " %-13s Use \"text\" as the plaintext for encryption and verification\n",
58 "-t text");
59 PR_fprintf(pr_stderr,
60 " %-13s Find security databases in \"dbdir\"\n",
61 "-d dbdir");
62 PR_fprintf(pr_stderr,
63 " %-13s read the password from \"pwfile\"\n",
64 "-f pwfile");
65 PR_fprintf(pr_stderr,
66 " %-13s supply \"password\" on the command line\n",
67 "-p password");
68}
69
70int
71readStdin(SECItem *result)
72{
73 unsigned int bufsize = 0;
74 int cc;
75 unsigned int wanted = 8192U;
76
77 result->len = 0;
78 result->data = NULL((void*)0);
79 do {
80 if (bufsize < wanted) {
81 unsigned char *tmpData = (unsigned char *)PR_Realloc(result->data, wanted);
82 if (!tmpData) {
83 if (verbose)
84 PR_fprintf(pr_stderr, "Allocation of buffer failed\n");
85 return -1;
86 }
87 result->data = tmpData;
88 bufsize = wanted;
89 }
90 cc = PR_Read(PR_STDINPR_GetSpecialFD(PR_StandardInput), result->data + result->len, bufsize - result->len);
91 if (cc > 0) {
92 result->len += (unsigned)cc;
93 if (result->len >= wanted)
94 wanted *= 2;
95 }
96 } while (cc > 0);
97 return cc;
98}
99
100int
101readInputFile(const char *filename, SECItem *result)
102{
103 PRFileDesc *file /* = PR_OpenFile(input_file, 0) */;
104 PRFileInfo info;
105 PRStatus s;
106 PRInt32 count;
107 int retval = -1;
108
109 file = PR_Open(filename, PR_RDONLY0x01, 0);
110 if (!file) {
111 if (verbose)
112 PR_fprintf(pr_stderr, "Open of file %s failed\n", filename);
113 goto loser;
114 }
115
116 s = PR_GetOpenFileInfo(file, &info);
117 if (s != PR_SUCCESS) {
118 if (verbose)
119 PR_fprintf(pr_stderr, "File info operation failed\n");
120 goto file_loser;
121 }
122
123 result->len = info.size;
124 result->data = (unsigned char *)PR_Malloc(result->len);
125 if (!result->data) {
126 if (verbose)
127 PR_fprintf(pr_stderr, "Allocation of buffer failed\n");
128 goto file_loser;
129 }
130
131 count = PR_Read(file, result->data, result->len);
132 if (count != result->len) {
133 if (verbose)
134 PR_fprintf(pr_stderr, "Read failed\n");
135 goto file_loser;
136 }
137 retval = 0;
138
139file_loser:
140 PR_Close(file);
141loser:
142 return retval;
143}
144
145int
146main(int argc, char **argv)
147{
148 int retval = 0; /* 0 - test succeeded. -1 - test failed */
149 SECStatus rv;
150 PLOptState *optstate;
151 PLOptStatus optstatus;
152 char *program_name;
153 const char *input_file = NULL((void*)0); /* read encrypted data from here (or create) */
154 const char *output_file = NULL((void*)0); /* write new encrypted data here */
1
'output_file' initialized to a null pointer value
155 const char *value = default_value; /* Use this for plaintext */
156 SECItem data;
157 SECItem result = { 0, 0, 0 };
158 SECItem text;
159 PRBool ascii = PR_FALSE0;
160 secuPWData pwdata = { PW_NONE, 0 };
161
162 pr_stderr = PR_STDERRPR_GetSpecialFD(PR_StandardError);
163 result.data = 0;
164 text.data = 0;
165 text.len = 0;
166
167 program_name = PL_strrchr(argv[0], '/');
168 program_name = program_name ? (program_name + 1) : argv[0];
2
Assuming 'program_name' is non-null
3
'?' condition is true
169
170 optstate = PL_CreateOptState(argc, argv, "?Had:i:o:t:vf:p:");
171 if (optstate == NULL((void*)0)) {
4
Assuming 'optstate' is not equal to NULL
5
Taking false branch
172 SECU_PrintError(program_name, "PL_CreateOptState failed");
173 return -1;
174 }
175
176 while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
6
Assuming the condition is true
7
Loop condition is true. Entering loop body
9
Execution continues on line 176
10
Assuming the condition is false
11
Loop condition is false. Execution continues on line 231
177 switch (optstate->option) {
8
Control jumps to 'case 116:' at line 202
178 case '?':
179 short_usage(program_name);
180 return retval;
181
182 case 'H':
183 long_usage(program_name);
184 return retval;
185
186 case 'a':
187 ascii = PR_TRUE1;
188 break;
189
190 case 'd':
191 SECU_ConfigDirectory(optstate->value);
192 break;
193
194 case 'i':
195 input_file = optstate->value;
196 break;
197
198 case 'o':
199 output_file = optstate->value;
200 break;
201
202 case 't':
203 value = optstate->value;
204 break;
205
206 case 'f':
207 if (pwdata.data) {
208 PORT_FreePORT_Free_Util(pwdata.data);
209 short_usage(program_name);
210 return -1;
211 }
212 pwdata.source = PW_FROMFILE;
213 pwdata.data = PORT_StrdupPORT_Strdup_Util(optstate->value);
214 break;
215
216 case 'p':
217 if (pwdata.data) {
218 PORT_FreePORT_Free_Util(pwdata.data);
219 short_usage(program_name);
220 return -1;
221 }
222 pwdata.source = PW_PLAINTEXT;
223 pwdata.data = PORT_StrdupPORT_Strdup_Util(optstate->value);
224 break;
225
226 case 'v':
227 verbose = PR_TRUE1;
228 break;
229 }
230 }
231 PL_DestroyOptState(optstate);
232 if (optstatus == PL_OPT_BAD) {
12
Assuming 'optstatus' is not equal to PL_OPT_BAD
233 short_usage(program_name);
234 return -1;
235 }
236 if (!output_file
12.1
'output_file' is null
&& !input_file
12.2
'input_file' is null
&& value == default_value) {
13
Assuming 'value' is not equal to 'default_value'
14
Taking false branch
237 short_usage(program_name);
238 PR_fprintf(pr_stderr, "Must specify at least one of -t, -i or -o \n");
239 return -1;
240 }
241
242 /*
243 * Initialize the Security libraries.
244 */
245 PK11_SetPasswordFunc(SECU_GetModulePassword);
246
247 if (output_file
14.1
'output_file' is null
) {
15
Taking false branch
248 rv = NSS_InitReadWrite(SECU_ConfigDirectory(NULL((void*)0)));
249 } else {
250 rv = NSS_Init(SECU_ConfigDirectory(NULL((void*)0)));
251 }
252 if (rv != SECSuccess) {
16
Assuming 'rv' is equal to SECSuccess
17
Taking false branch
253 SECU_PrintError(program_name, "NSS_Init failed");
254 retval = -1;
255 goto prdone;
256 }
257
258 /* Convert value into an item */
259 data.data = (unsigned char *)value;
260 data.len = strlen(value);
261
262 /* Get the encrypted result, either from the input file
263 * or from encrypting the plaintext value
264 */
265 if (input_file
17.1
'input_file' is null
) {
18
Taking false branch
266 if (verbose)
267 printf("Reading data from %s\n", input_file);
268
269 if (!strcmp(input_file, "-")) {
270 retval = readStdin(&result);
271 ascii = PR_TRUE1;
272 } else {
273 retval = readInputFile(input_file, &result);
274 }
275 if (retval != 0)
276 goto loser;
277 if (ascii) {
278 /* input was base64 encoded. Decode it. */
279 SECItem newResult = { 0, 0, 0 };
280 SECItem *ok = NSSBase64_DecodeBufferNSSBase64_DecodeBuffer_Util(NULL((void*)0), &newResult,
281 (const char *)result.data, result.len);
282 if (!ok) {
283 SECU_PrintError(program_name, "Base 64 decode failed");
284 retval = -1;
285 goto loser;
286 }
287 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&result, PR_FALSE0);
288 result = *ok;
289 }
290 } else {
291 SECItem keyid = { 0, 0, 0 };
292 SECItem outBuf = { 0, 0, 0 };
293 PK11SlotInfo *slot = NULL((void*)0);
294
295 /* sigh, initialize the key database */
296 slot = PK11_GetInternalKeySlot();
297 if (slot && PK11_NeedUserInit(slot)) {
19
Assuming 'slot' is null
298 switch (pwdata.source) {
299 case PW_FROMFILE:
300 rv = SECU_ChangePW(slot, 0, pwdata.data);
301 break;
302 case PW_PLAINTEXT:
303 rv = SECU_ChangePW(slot, pwdata.data, 0);
304 break;
305 default:
306 rv = SECU_ChangePW(slot, "", 0);
307 break;
308 }
309 if (rv != SECSuccess) {
310 SECU_PrintError(program_name, "Failed to initialize slot \"%s\"",
311 PK11_GetSlotName(slot));
312 return SECFailure;
313 }
314 }
315 if (slot
19.1
'slot' is null
) {
20
Taking false branch
316 PK11_FreeSlot(slot);
317 }
318
319 rv = PK11SDR_Encrypt(&keyid, &data, &result, &pwdata);
320 if (rv != SECSuccess) {
21
Assuming 'rv' is equal to SECSuccess
22
Taking false branch
321 if (verbose)
322 SECU_PrintError(program_name, "Encrypt operation failed\n");
323 retval = -1;
324 goto loser;
325 }
326
327 if (verbose
22.1
'verbose' is 0
)
23
Taking false branch
328 printf("Encrypted result is %d bytes long\n", result.len);
329
330 if (!strcmp(output_file, "-")) {
24
Null pointer passed to 1st parameter expecting 'nonnull'
331 ascii = PR_TRUE1;
332 }
333
334 if (ascii) {
335 /* base64 encode output. */
336 char *newResult = NSSBase64_EncodeItemNSSBase64_EncodeItem_Util(NULL((void*)0), NULL((void*)0), 0, &result);
337 if (!newResult) {
338 SECU_PrintError(program_name, "Base 64 encode failed\n");
339 retval = -1;
340 goto loser;
341 }
342 outBuf.data = (unsigned char *)newResult;
343 outBuf.len = strlen(newResult);
344 if (verbose)
345 printf("Base 64 encoded result is %d bytes long\n", outBuf.len);
346 } else {
347 outBuf = result;
348 }
349
350 /* -v printf("Result is %.*s\n", text.len, text.data); */
351 if (output_file) {
352 PRFileDesc *file;
353 PRInt32 count;
354
355 if (verbose)
356 printf("Writing result to %s\n", output_file);
357 if (!strcmp(output_file, "-")) {
358 file = PR_STDOUTPR_GetSpecialFD(PR_StandardOutput);
359 } else {
360 /* Write to file */
361 file = PR_Open(output_file, PR_CREATE_FILE0x08 | PR_WRONLY0x02, 0666);
362 }
363 if (!file) {
364 if (verbose)
365 SECU_PrintError(program_name,
366 "Open of output file %s failed\n",
367 output_file);
368 retval = -1;
369 goto loser;
370 }
371
372 count = PR_Write(file, outBuf.data, outBuf.len);
373
374 if (file == PR_STDOUTPR_GetSpecialFD(PR_StandardOutput)) {
375 puts("");
376 } else {
377 PR_Close(file);
378 }
379
380 if (count != outBuf.len) {
381 if (verbose)
382 SECU_PrintError(program_name, "Write failed\n");
383 retval = -1;
384 goto loser;
385 }
386 if (ascii) {
387 free(outBuf.data);
388 }
389 }
390 }
391
392 /* Decrypt the value */
393 rv = PK11SDR_Decrypt(&result, &text, &pwdata);
394 if (rv != SECSuccess) {
395 if (verbose)
396 SECU_PrintError(program_name, "Decrypt operation failed\n");
397 retval = -1;
398 goto loser;
399 }
400
401 if (verbose)
402 printf("Decrypted result is \"%.*s\"\n", text.len, text.data);
403
404 /* Compare to required value */
405 if (text.len != data.len || memcmp(data.data, text.data, text.len) != 0) {
406 if (verbose)
407 PR_fprintf(pr_stderr, "Comparison failed\n");
408 retval = -1;
409 goto loser;
410 }
411
412loser:
413 if (text.data)
414 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&text, PR_FALSE0);
415 if (result.data)
416 SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(&result, PR_FALSE0);
417 if (NSS_Shutdown() != SECSuccess) {
418 exit(1);
419 }
420
421prdone:
422 PR_Cleanup();
423 if (pwdata.data) {
424 PORT_FreePORT_Free_Util(pwdata.data);
425 }
426 return retval;
427}