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 | |
2 | |
3 | |
4 | |
5 | |
6 | |
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" |
21 | static const char default_value[] = { DEFAULT_VALUE }; |
22 | |
23 | PRFileDesc *pr_stderr; |
24 | PRBool verbose = PR_FALSE; |
25 | |
26 | static void |
27 | synopsis(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 | |
36 | static void |
37 | short_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 | |
45 | static void |
46 | long_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 | |
70 | int |
71 | readStdin(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; |
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_STDIN, 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 | |
100 | int |
101 | readInputFile(const char *filename, SECItem *result) |
102 | { |
103 | PRFileDesc *file ; |
104 | PRFileInfo info; |
105 | PRStatus s; |
106 | PRInt32 count; |
107 | int retval = -1; |
108 | |
109 | file = PR_Open(filename, PR_RDONLY, 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 | |
139 | file_loser: |
140 | PR_Close(file); |
141 | loser: |
142 | return retval; |
143 | } |
144 | |
145 | int |
146 | main(int argc, char **argv) |
147 | { |
148 | int retval = 0; |
149 | SECStatus rv; |
150 | PLOptState *optstate; |
151 | PLOptStatus optstatus; |
152 | char *program_name; |
153 | const char *input_file = NULL; |
154 | const char *output_file = NULL; |
| 1 | 'output_file' initialized to a null pointer value | |
|
155 | const char *value = default_value; |
156 | SECItem data; |
157 | SECItem result = { 0, 0, 0 }; |
158 | SECItem text; |
159 | PRBool ascii = PR_FALSE; |
160 | secuPWData pwdata = { PW_NONE, 0 }; |
161 | |
162 | pr_stderr = PR_STDERR; |
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 | |
|
| |
169 | |
170 | optstate = PL_CreateOptState(argc, argv, "?Had:i:o:t:vf:p:"); |
171 | if (optstate == NULL) { |
| 4 | | Assuming 'optstate' is not equal to NULL | |
|
| |
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_TRUE; |
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_Free(pwdata.data); |
209 | short_usage(program_name); |
210 | return -1; |
211 | } |
212 | pwdata.source = PW_FROMFILE; |
213 | pwdata.data = PORT_Strdup(optstate->value); |
214 | break; |
215 | |
216 | case 'p': |
217 | if (pwdata.data) { |
218 | PORT_Free(pwdata.data); |
219 | short_usage(program_name); |
220 | return -1; |
221 | } |
222 | pwdata.source = PW_PLAINTEXT; |
223 | pwdata.data = PORT_Strdup(optstate->value); |
224 | break; |
225 | |
226 | case 'v': |
227 | verbose = PR_TRUE; |
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 && !input_file && value == default_value) { |
| 13 | | Assuming 'value' is not equal to 'default_value' | |
|
| |
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 | |
244 | |
245 | PK11_SetPasswordFunc(SECU_GetModulePassword); |
246 | |
247 | if (output_file) { |
| |
248 | rv = NSS_InitReadWrite(SECU_ConfigDirectory(NULL)); |
249 | } else { |
250 | rv = NSS_Init(SECU_ConfigDirectory(NULL)); |
251 | } |
252 | if (rv != SECSuccess) { |
| 16 | | Assuming 'rv' is equal to SECSuccess | |
|
| |
253 | SECU_PrintError(program_name, "NSS_Init failed"); |
254 | retval = -1; |
255 | goto prdone; |
256 | } |
257 | |
258 | |
259 | data.data = (unsigned char *)value; |
260 | data.len = strlen(value); |
261 | |
262 | |
263 | |
264 | |
265 | if (input_file) { |
| |
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_TRUE; |
272 | } else { |
273 | retval = readInputFile(input_file, &result); |
274 | } |
275 | if (retval != 0) |
276 | goto loser; |
277 | if (ascii) { |
278 | |
279 | SECItem newResult = { 0, 0, 0 }; |
280 | SECItem *ok = NSSBase64_DecodeBuffer(NULL, &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_ZfreeItem(&result, PR_FALSE); |
288 | result = *ok; |
289 | } |
290 | } else { |
291 | SECItem keyid = { 0, 0, 0 }; |
292 | SECItem outBuf = { 0, 0, 0 }; |
293 | PK11SlotInfo *slot = NULL; |
294 | |
295 | |
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) { |
| |
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 | |
|
| |
321 | if (verbose) |
322 | SECU_PrintError(program_name, "Encrypt operation failed\n"); |
323 | retval = -1; |
324 | goto loser; |
325 | } |
326 | |
327 | if (verbose) |
| |
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_TRUE; |
332 | } |
333 | |
334 | if (ascii) { |
335 | |
336 | char *newResult = NSSBase64_EncodeItem(NULL, NULL, 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 | |
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_STDOUT; |
359 | } else { |
360 | |
361 | file = PR_Open(output_file, PR_CREATE_FILE | PR_WRONLY, 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_STDOUT) { |
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 | |
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 | |
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 | |
412 | loser: |
413 | if (text.data) |
414 | SECITEM_ZfreeItem(&text, PR_FALSE); |
415 | if (result.data) |
416 | SECITEM_ZfreeItem(&result, PR_FALSE); |
417 | if (NSS_Shutdown() != SECSuccess) { |
418 | exit(1); |
419 | } |
420 | |
421 | prdone: |
422 | PR_Cleanup(); |
423 | if (pwdata.data) { |
424 | PORT_Free(pwdata.data); |
425 | } |
426 | return retval; |
427 | } |