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 sign.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/signtool -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/signtool -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 sign.c
1 | |
2 | |
3 | |
4 | |
5 | #include "signtool.h" |
6 | #include "zip.h" |
7 | #include "prmem.h" |
8 | #include "blapi.h" |
9 | #include "sechash.h" /* for HASH_GetHashObject() */ |
10 | |
11 | static int create_pk7(char *dir, char *keyName, int *keyType); |
12 | static int jar_find_key_type(CERTCertificate *cert); |
13 | static int manifesto(char *dirname, char *install_script, PRBool recurse); |
14 | static int manifesto_fn(char *relpath, char *basedir, char *reldir, |
15 | char *filename, void *arg); |
16 | static int manifesto_xpi_fn(char *relpath, char *basedir, char *reldir, |
17 | char *filename, void *arg); |
18 | static int sign_all_arc_fn(char *relpath, char *basedir, char *reldir, |
19 | char *filename, void *arg); |
20 | static int add_meta(FILE *fp, char *name); |
21 | static int SignFile(FILE *outFile, FILE *inFile, CERTCertificate *cert); |
22 | static int generate_SF_file(char *manifile, char *who); |
23 | static int calculate_MD5_range(FILE *fp, long r1, long r2, |
24 | JAR_Digest *dig); |
25 | static void SignOut(void *arg, const char *buf, unsigned long len); |
26 | |
27 | static char *metafile = NULL; |
28 | static int optimize = 0; |
29 | static FILE *mf; |
30 | static ZIPfile *zipfile = NULL; |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | int |
40 | SignArchive(char *tree, char *keyName, char *zip_file, int javascript, |
41 | char *meta_file, char *install_script, int _optimize, PRBool recurse) |
42 | { |
43 | int status; |
44 | char tempfn[FNSIZE], fullfn[FNSIZE]; |
45 | int keyType = rsaKey; |
46 | int count; |
47 | |
48 | metafile = meta_file; |
49 | optimize = _optimize; |
50 | |
51 | |
52 | |
53 | |
54 | if (xpi_arc) { |
| 11 | | Assuming 'xpi_arc' is not equal to 0 | |
|
| |
55 | manifesto(tree, install_script, recurse); |
| |
56 | } |
57 | |
58 | if (zip_file) { |
59 | zipfile = JzipOpen(zip_file, NULL ); |
60 | } |
61 | |
62 | |
63 | if (!xpi_arc) { |
64 | manifesto(tree, install_script, recurse); |
65 | } |
66 | |
67 | if (keyName) { |
68 | status = create_pk7(tree, keyName, &keyType); |
69 | if (status < 0) { |
70 | PR_fprintf(errorFD, "the tree \"%s\" was NOT SUCCESSFULLY SIGNED\n", |
71 | tree); |
72 | errorCount++; |
73 | exit(ERRX); |
74 | } |
75 | } |
76 | |
77 | |
78 | |
79 | if (xpi_arc) { |
80 | if (verbosity >= 0) { |
81 | PR_fprintf(outputFD, "%s \n", XPI_TEXT); |
82 | } |
83 | |
84 | |
85 | count = snprintf(tempfn, sizeof(tempfn), "META-INF/%s.%s", base, (keyType == dsaKey ? "dsa" : "rsa")); |
86 | if (count >= sizeof(tempfn)) { |
87 | PR_fprintf(errorFD, "unable to write key metadata\n"); |
88 | errorCount++; |
89 | exit(ERRX); |
90 | } |
91 | count = snprintf(fullfn, sizeof(fullfn), "%s/%s", tree, tempfn); |
92 | if (count >= sizeof(fullfn)) { |
93 | PR_fprintf(errorFD, "unable to write key metadata\n"); |
94 | errorCount++; |
95 | exit(ERRX); |
96 | } |
97 | JzipAdd(fullfn, tempfn, zipfile, compression_level); |
98 | |
99 | |
100 | foreach (tree, "", manifesto_xpi_fn, recurse, PR_FALSE , |
101 | (void *)NULL) |
102 | ; |
103 | } |
104 | |
105 | strcpy(tempfn, "META-INF/manifest.mf"); |
106 | count = snprintf(fullfn, sizeof(fullfn), "%s/%s", tree, tempfn); |
107 | if (count >= sizeof(fullfn)) { |
108 | PR_fprintf(errorFD, "unable to write manifest\n"); |
109 | errorCount++; |
110 | exit(ERRX); |
111 | } |
112 | JzipAdd(fullfn, tempfn, zipfile, compression_level); |
113 | |
114 | |
115 | count = snprintf(tempfn, sizeof(tempfn), "META-INF/%s.sf", base); |
116 | if (count >= sizeof(tempfn)) { |
117 | PR_fprintf(errorFD, "unable to write sf metadata\n"); |
118 | errorCount++; |
119 | exit(ERRX); |
120 | } |
121 | count = snprintf(fullfn, sizeof(fullfn), "%s/%s", tree, tempfn); |
122 | if (count >= sizeof(fullfn)) { |
123 | PR_fprintf(errorFD, "unable to write sf metadata\n"); |
124 | errorCount++; |
125 | exit(ERRX); |
126 | } |
127 | JzipAdd(fullfn, tempfn, zipfile, compression_level); |
128 | |
129 | |
130 | if (!xpi_arc) { |
131 | |
132 | count = snprintf(tempfn, sizeof(tempfn), "META-INF/%s.%s", base, (keyType == dsaKey ? "dsa" : "rsa")); |
133 | if (count >= sizeof(tempfn)) { |
134 | PR_fprintf(errorFD, "unable to write key metadata\n"); |
135 | errorCount++; |
136 | exit(ERRX); |
137 | } |
138 | count = snprintf(fullfn, sizeof(fullfn), "%s/%s", tree, tempfn); |
139 | if (count >= sizeof(fullfn)) { |
140 | PR_fprintf(errorFD, "unable to write key metadata\n"); |
141 | errorCount++; |
142 | exit(ERRX); |
143 | } |
144 | JzipAdd(fullfn, tempfn, zipfile, compression_level); |
145 | } |
146 | |
147 | JzipClose(zipfile); |
148 | |
149 | if (verbosity >= 0) { |
150 | if (javascript) { |
151 | PR_fprintf(outputFD, "jarfile \"%s\" signed successfully\n", |
152 | zip_file); |
153 | } else { |
154 | PR_fprintf(outputFD, "tree \"%s\" signed successfully\n", |
155 | tree); |
156 | } |
157 | } |
158 | |
159 | return 0; |
160 | } |
161 | |
162 | typedef struct { |
163 | char *keyName; |
164 | int javascript; |
165 | char *metafile; |
166 | char *install_script; |
167 | int optimize; |
168 | } SignArcInfo; |
169 | |
170 | |
171 | |
172 | |
173 | |
174 | |
175 | |
176 | |
177 | int |
178 | SignAllArc(char *jartree, char *keyName, int javascript, char *metafilename, |
179 | char *install_script, int optimize_level, PRBool recurse) |
180 | { |
181 | SignArcInfo info; |
182 | |
183 | info.keyName = keyName; |
184 | info.javascript = javascript; |
185 | info.metafile = metafilename; |
186 | info.install_script = install_script; |
187 | info.optimize = optimize_level; |
188 | |
189 | return foreach (jartree, "", sign_all_arc_fn, recurse, |
190 | PR_TRUE , (void *)&info); |
191 | } |
192 | |
193 | static int |
194 | sign_all_arc_fn(char *relpath, char *basedir, char *reldir, char *filename, |
195 | void *arg) |
196 | { |
197 | char *zipfilename = NULL; |
198 | char *arc = NULL, *archive = NULL; |
199 | int retval = 0; |
200 | SignArcInfo *infop = (SignArcInfo *)arg; |
201 | |
202 | |
203 | |
204 | if ((PL_strcaserstr(relpath, ".arc") == relpath + strlen(relpath) - 4) && |
| 1 | Assuming the condition is true | |
|
| |
205 | (PL_strcasestr(relpath, ".arc") == relpath + strlen(relpath) - 4)) { |
| 2 | | Assuming the condition is true | |
|
206 | |
207 | if (!infop) { |
| 4 | | Assuming 'infop' is non-null | |
|
| |
208 | PR_fprintf(errorFD, "%s: Internal failure\n", PROGRAM_NAME); |
209 | errorCount++; |
210 | retval = -1; |
211 | goto finish; |
212 | } |
213 | archive = PR_smprintf("%s/%s", basedir, relpath); |
214 | |
215 | zipfilename = PL_strdup(archive); |
216 | arc = PORT_Strrchr(zipfilename, '.'); |
217 | |
218 | if (arc == NULL) { |
| 6 | | Assuming 'arc' is not equal to NULL | |
|
| |
219 | PR_fprintf(errorFD, "%s: Internal failure\n", PROGRAM_NAME); |
220 | errorCount++; |
221 | retval = -1; |
222 | goto finish; |
223 | } |
224 | |
225 | PL_strcpy(arc, ".jar"); |
226 | |
227 | if (verbosity >= 0) { |
| 8 | | Assuming 'verbosity' is < 0 | |
|
| |
228 | PR_fprintf(outputFD, "\nsigning: %s\n", zipfilename); |
229 | } |
230 | retval = SignArchive(archive, infop->keyName, zipfilename, |
| |
231 | infop->javascript, infop->metafile, infop->install_script, |
232 | infop->optimize, PR_TRUE ); |
233 | } |
234 | finish: |
235 | if (archive) |
236 | PR_Free(archive); |
237 | if (zipfilename) |
238 | PR_Free(zipfilename); |
239 | |
240 | return retval; |
241 | } |
242 | |
243 | |
244 | |
245 | |
246 | |
247 | static int |
248 | create_pk7(char *dir, char *keyName, int *keyType) |
249 | { |
250 | int status = 0; |
251 | char *file_ext; |
252 | |
253 | CERTCertificate *cert; |
254 | CERTCertDBHandle *db; |
255 | |
256 | FILE *in, *out; |
257 | |
258 | char sf_file[FNSIZE]; |
259 | char pk7_file[FNSIZE]; |
260 | |
261 | |
262 | db = CERT_GetDefaultCertDB(); |
263 | |
264 | if (db == NULL) |
265 | return -1; |
266 | |
267 | |
268 | |
269 | cert = PK11_FindCertFromNickname(keyName, &pwdata); |
270 | |
271 | if (cert == NULL) { |
272 | SECU_PrintError(PROGRAM_NAME, |
273 | "Cannot find the cert \"%s\"", keyName); |
274 | return -1; |
275 | } |
276 | |
277 | |
278 | |
279 | *keyType = jar_find_key_type(cert); |
280 | file_ext = (*keyType == dsaKey) ? "dsa" : "rsa"; |
281 | |
282 | snprintf(sf_file, sizeof(sf_file), "%s/META-INF/%s.sf", dir, base); |
283 | snprintf(pk7_file, sizeof(pk7_file), "%s/META-INF/%s.%s", dir, base, file_ext); |
284 | |
285 | if ((in = fopen(sf_file, "rb")) == NULL) { |
286 | PR_fprintf(errorFD, "%s: Can't open %s for reading\n", PROGRAM_NAME, |
287 | sf_file); |
288 | errorCount++; |
289 | exit(ERRX); |
290 | } |
291 | |
292 | if ((out = fopen(pk7_file, "wb")) == NULL) { |
293 | PR_fprintf(errorFD, "%s: Can't open %s for writing\n", PROGRAM_NAME, |
294 | sf_file); |
295 | errorCount++; |
296 | exit(ERRX); |
297 | } |
298 | |
299 | status = SignFile(out, in, cert); |
300 | |
301 | CERT_DestroyCertificate(cert); |
302 | fclose(in); |
303 | fclose(out); |
304 | |
305 | if (status) { |
306 | PR_fprintf(errorFD, "%s: PROBLEM signing data (%s)\n", |
307 | PROGRAM_NAME, SECU_Strerror(PORT_GetError())); |
308 | errorCount++; |
309 | return -1; |
310 | } |
311 | |
312 | return 0; |
313 | } |
314 | |
315 | |
316 | |
317 | |
318 | |
319 | |
320 | |
321 | |
322 | static int |
323 | jar_find_key_type(CERTCertificate *cert) |
324 | { |
325 | SECKEYPrivateKey *privk = NULL; |
326 | KeyType keyType; |
327 | |
328 | |
329 | privk = PK11_FindKeyByAnyCert(cert, &pwdata); |
330 | if (privk == NULL) { |
331 | PR_fprintf(errorFD, "warning - can't find private key for this cert\n"); |
332 | warningCount++; |
333 | return 0; |
334 | } |
335 | |
336 | keyType = privk->keyType; |
337 | SECKEY_DestroyPrivateKey(privk); |
338 | return keyType; |
339 | } |
340 | |
341 | |
342 | |
343 | |
344 | |
345 | |
346 | |
347 | |
348 | static int |
349 | manifesto(char *dirname, char *install_script, PRBool recurse) |
350 | { |
351 | char metadir[FNSIZE], sfname[FNSIZE]; |
352 | |
353 | |
354 | |
355 | if (PR_Access(dirname, PR_ACCESS_READ_OK)) { |
| 14 | | Assuming the condition is false | |
|
| |
356 | PR_fprintf(errorFD, "%s: unable to read your directory: %s\n", |
357 | PROGRAM_NAME, dirname); |
358 | errorCount++; |
359 | perror(dirname); |
360 | exit(ERRX); |
361 | } |
362 | |
363 | if (PR_Access(dirname, PR_ACCESS_WRITE_OK)) { |
| 16 | | Assuming the condition is false | |
|
| |
364 | PR_fprintf(errorFD, "%s: unable to write to your directory: %s\n", |
365 | PROGRAM_NAME, dirname); |
366 | errorCount++; |
367 | perror(dirname); |
368 | exit(ERRX); |
369 | } |
370 | |
371 | snprintf(metadir, sizeof(metadir), "%s/META-INF", dirname); |
372 | |
373 | strcpy(sfname, metadir); |
374 | |
375 | PR_MkDir(metadir, 0777); |
376 | |
377 | strcat(metadir, "/"); |
378 | strcat(metadir, MANIFEST); |
379 | |
380 | if ((mf = fopen(metadir, "wb")) == NULL) { |
| 18 | | Assuming the condition is false | |
|
| |
381 | perror(MANIFEST); |
382 | PR_fprintf(errorFD, "%s: Probably, the directory you are trying to" |
383 | " sign has\n", |
384 | PROGRAM_NAME); |
385 | PR_fprintf(errorFD, "%s: permissions problems or may not exist.\n", |
386 | PROGRAM_NAME); |
387 | errorCount++; |
388 | exit(ERRX); |
389 | } |
390 | |
391 | if (verbosity >= 0) { |
| 20 | | Assuming 'verbosity' is < 0 | |
|
| |
392 | PR_fprintf(outputFD, "Generating %s file..\n", metadir); |
393 | } |
394 | |
395 | fprintf(mf, "Manifest-Version: 1.0\n"); |
396 | fprintf(mf, "Created-By: %s\n", CREATOR); |
397 | fprintf(mf, "Comments: %s\n", BREAKAGE); |
398 | |
399 | if (scriptdir) { |
| 22 | | Assuming 'scriptdir' is null | |
|
| |
400 | fprintf(mf, "Comments: --\n"); |
401 | fprintf(mf, "Comments: --\n"); |
402 | fprintf(mf, "Comments: -- This archive signs Javascripts which may not necessarily\n"); |
403 | fprintf(mf, "Comments: -- be included in the physical jar file.\n"); |
404 | fprintf(mf, "Comments: --\n"); |
405 | fprintf(mf, "Comments: --\n"); |
406 | } |
407 | |
408 | if (install_script) |
| 24 | | Assuming 'install_script' is null | |
|
| |
409 | fprintf(mf, "Install-Script: %s\n", install_script); |
410 | |
411 | if (metafile) |
| 26 | | Assuming 'metafile' is null | |
|
| |
412 | add_meta(mf, "+"); |
413 | |
414 | |
415 | foreach (dirname, "", manifesto_fn, recurse, PR_FALSE , |
416 | (void *)NULL) |
417 | ; |
418 | |
419 | fclose(mf); |
420 | |
421 | strcat(sfname, "/"); |
422 | strcat(sfname, base); |
423 | strcat(sfname, ".sf"); |
424 | |
425 | if (verbosity >= 0) { |
| 28 | | Assuming 'verbosity' is < 0 | |
|
| |
426 | PR_fprintf(outputFD, "Generating %s.sf file..\n", base); |
427 | } |
428 | generate_SF_file(metadir, sfname); |
| 30 | | Calling 'generate_SF_file' | |
|
429 | |
430 | return 0; |
431 | } |
432 | |
433 | |
434 | |
435 | |
436 | |
437 | |
438 | |
439 | |
440 | |
441 | static int |
442 | manifesto_xpi_fn(char *relpath, char *basedir, char *reldir, char *filename, void *arg) |
443 | { |
444 | char fullname[FNSIZE]; |
445 | int count; |
446 | |
447 | if (verbosity >= 0) { |
448 | PR_fprintf(outputFD, "--> %s\n", relpath); |
449 | } |
450 | |
451 | |
452 | if (extensionsGiven) { |
453 | char *ext = PL_strrchr(relpath, '.'); |
454 | if (!ext) |
455 | return 0; |
456 | if (!PL_HashTableLookup(extensions, ext)) |
457 | return 0; |
458 | } |
459 | count = snprintf(fullname, sizeof(fullname), "%s/%s", basedir, relpath); |
460 | if (count >= sizeof(fullname)) { |
461 | return 1; |
462 | } |
463 | JzipAdd(fullname, relpath, zipfile, compression_level); |
464 | |
465 | return 0; |
466 | } |
467 | |
468 | |
469 | |
470 | |
471 | |
472 | |
473 | |
474 | |
475 | static int |
476 | manifesto_fn(char *relpath, char *basedir, char *reldir, char *filename, void *arg) |
477 | { |
478 | int use_js; |
479 | char *md5, *sha1; |
480 | |
481 | JAR_Digest dig; |
482 | char fullname[FNSIZE]; |
483 | |
484 | if (verbosity >= 0) { |
485 | PR_fprintf(outputFD, "--> %s\n", relpath); |
486 | } |
487 | |
488 | |
489 | if (extensionsGiven) { |
490 | char *ext = PL_strrchr(relpath, '.'); |
491 | if (!ext) |
492 | return 0; |
493 | if (!PL_HashTableLookup(extensions, ext)) |
494 | return 0; |
495 | } |
496 | |
497 | snprintf(fullname, sizeof(fullname), "%s/%s", basedir, relpath); |
498 | |
499 | fprintf(mf, "\n"); |
500 | |
501 | use_js = 0; |
502 | |
503 | if (scriptdir && !PORT_Strcmp(scriptdir, reldir)) |
504 | use_js++; |
505 | |
506 | |
507 | |
508 | if ((PL_strcaserstr(filename, ".js") != filename + strlen(filename) - 3) && |
509 | (PL_strcaserstr(reldir, ".arc") == reldir + strlen(filename) - 4)) |
510 | use_js++; |
511 | |
512 | if (use_js) { |
513 | fprintf(mf, "Name: %s\n", filename); |
514 | fprintf(mf, "Magic: javascript\n"); |
515 | |
516 | if (optimize == 0) |
517 | fprintf(mf, "javascript.id: %s\n", filename); |
518 | |
519 | if (metafile) |
520 | add_meta(mf, filename); |
521 | } else { |
522 | fprintf(mf, "Name: %s\n", relpath); |
523 | if (metafile) |
524 | add_meta(mf, relpath); |
525 | } |
526 | |
527 | JAR_digest_file(fullname, &dig); |
528 | |
529 | if (optimize == 0) { |
530 | fprintf(mf, "Digest-Algorithms: MD5 SHA1\n"); |
531 | |
532 | md5 = BTOA_DataToAscii(dig.md5, MD5_LENGTH); |
533 | fprintf(mf, "MD5-Digest: %s\n", md5); |
534 | PORT_Free(md5); |
535 | } |
536 | |
537 | sha1 = BTOA_DataToAscii(dig.sha1, SHA1_LENGTH); |
538 | fprintf(mf, "SHA1-Digest: %s\n", sha1); |
539 | PORT_Free(sha1); |
540 | |
541 | if (!use_js) { |
542 | JzipAdd(fullname, relpath, zipfile, compression_level); |
543 | } |
544 | |
545 | return 0; |
546 | } |
547 | |
548 | |
549 | |
550 | |
551 | |
552 | |
553 | |
554 | |
555 | |
556 | static int |
557 | add_meta(FILE *fp, char *name) |
558 | { |
559 | FILE *met; |
560 | char buf[BUFSIZ]; |
561 | |
562 | int place; |
563 | char *pattern, *meta; |
564 | |
565 | int num = 0; |
566 | |
567 | if ((met = fopen(metafile, "r")) != NULL) { |
568 | while (fgets(buf, BUFSIZ, met)) { |
569 | char *s; |
570 | |
571 | for (s = buf; *s && *s != '\n' && *s != '\r'; s++) |
572 | ; |
573 | *s = 0; |
574 | |
575 | if (*buf == 0) |
576 | continue; |
577 | |
578 | pattern = buf; |
579 | |
580 | |
581 | for (s = buf; *s && *s != ' ' && *s != '\t'; s++) |
582 | ; |
583 | |
584 | |
585 | if (*s == ' ' || *s == '\t') |
586 | *s++ = 0; |
587 | |
588 | |
589 | while (*s == ' ' || *s == '\t') |
590 | s++; |
591 | |
592 | meta = s; |
593 | |
594 | |
595 | |
596 | place = 0; |
597 | if (!PORT_Strcmp(pattern, name)) |
598 | place = 1; |
599 | |
600 | if (place) { |
601 | num++; |
602 | if (verbosity >= 0) { |
603 | PR_fprintf(outputFD, "[%s] %s\n", name, meta); |
604 | } |
605 | fprintf(fp, "%s\n", meta); |
606 | } |
607 | } |
608 | fclose(met); |
609 | } else { |
610 | PR_fprintf(errorFD, "%s: can't open metafile: %s\n", PROGRAM_NAME, |
611 | metafile); |
612 | errorCount++; |
613 | exit(ERRX); |
614 | } |
615 | |
616 | return num; |
617 | } |
618 | |
619 | |
620 | |
621 | |
622 | |
623 | static int |
624 | SignFile(FILE *outFile, FILE *inFile, CERTCertificate *cert) |
625 | { |
626 | int nb; |
627 | char ibuf[4096], digestdata[32]; |
628 | const SECHashObject *hashObj; |
629 | void *hashcx; |
630 | unsigned int len; |
631 | |
632 | SECItem digest; |
633 | SEC_PKCS7ContentInfo *cinfo; |
634 | SECStatus rv; |
635 | |
636 | if (outFile == NULL || inFile == NULL || cert == NULL) |
637 | return -1; |
638 | |
639 | |
640 | hashObj = HASH_GetHashObject(HASH_AlgSHA1); |
641 | |
642 | hashcx = (*hashObj->create)(); |
643 | if (hashcx == NULL) |
644 | return -1; |
645 | |
646 | (*hashObj->begin)(hashcx); |
647 | |
648 | for (;;) { |
649 | if (feof(inFile)) |
650 | break; |
651 | nb = fread(ibuf, 1, sizeof(ibuf), inFile); |
652 | if (nb == 0) { |
653 | if (ferror(inFile)) { |
654 | PORT_SetError(SEC_ERROR_IO); |
655 | (*hashObj->destroy)(hashcx, PR_TRUE); |
656 | return -1; |
657 | } |
658 | |
659 | break; |
660 | } |
661 | (*hashObj->update)(hashcx, (unsigned char *)ibuf, nb); |
662 | } |
663 | |
664 | (*hashObj->end)(hashcx, (unsigned char *)digestdata, &len, 32); |
665 | (*hashObj->destroy)(hashcx, PR_TRUE); |
666 | |
667 | digest.data = (unsigned char *)digestdata; |
668 | digest.len = len; |
669 | |
670 | cinfo = SEC_PKCS7CreateSignedData(cert, certUsageObjectSigner, NULL, |
671 | SEC_OID_SHA1, &digest, NULL, NULL); |
672 | |
673 | if (cinfo == NULL) |
674 | return -1; |
675 | |
676 | rv = SEC_PKCS7IncludeCertChain(cinfo, NULL); |
677 | if (rv != SECSuccess) { |
678 | SEC_PKCS7DestroyContentInfo(cinfo); |
679 | return -1; |
680 | } |
681 | |
682 | if (no_time == 0) { |
683 | rv = SEC_PKCS7AddSigningTime(cinfo); |
684 | if (rv != SECSuccess) { |
685 | |
686 | } |
687 | } |
688 | |
689 | rv = SEC_PKCS7Encode(cinfo, SignOut, outFile, NULL, NULL, &pwdata); |
690 | |
691 | SEC_PKCS7DestroyContentInfo(cinfo); |
692 | |
693 | if (rv != SECSuccess) |
694 | return -1; |
695 | |
696 | return 0; |
697 | } |
698 | |
699 | |
700 | |
701 | |
702 | |
703 | |
704 | |
705 | |
706 | |
707 | static int |
708 | generate_SF_file(char *manifile, char *who) |
709 | { |
710 | FILE *sfFile; |
711 | FILE *mfFile; |
712 | long r1, r2, r3; |
713 | char whofile[FNSIZE]; |
714 | char *buf, *name = NULL; |
715 | char *md5, *sha1; |
716 | JAR_Digest dig; |
717 | int line = 0; |
718 | |
719 | strcpy(whofile, who); |
720 | |
721 | if ((mfFile = fopen(manifile, "rb")) == NULL) { |
| 31 | | Assuming the condition is false | |
|
| |
722 | perror(manifile); |
723 | exit(ERRX); |
724 | } |
725 | |
726 | if ((sfFile = fopen(whofile, "wb")) == NULL) { |
| 33 | | Assuming the condition is false | |
|
| |
727 | perror(who); |
728 | exit(ERRX); |
729 | } |
730 | |
731 | buf = (char *)PORT_ZAlloc(BUFSIZ); |
732 | |
733 | if (buf) |
| 35 | | Assuming 'buf' is non-null | |
|
| |
734 | name = (char *)PORT_ZAlloc(BUFSIZ); |
735 | |
736 | if (buf == NULL || name == NULL) |
| 37 | | Assuming 'name' is not equal to NULL | |
|
| |
737 | out_of_memory(); |
738 | |
739 | fprintf(sfFile, "Signature-Version: 1.0\n"); |
740 | fprintf(sfFile, "Created-By: %s\n", CREATOR); |
741 | fprintf(sfFile, "Comments: %s\n", BREAKAGE); |
742 | |
743 | if (fgets(buf, BUFSIZ, mfFile) == NULL) { |
| 39 | | Assuming the condition is false | |
|
| |
744 | PR_fprintf(errorFD, "%s: empty manifest file!\n", PROGRAM_NAME); |
745 | errorCount++; |
746 | exit(ERRX); |
747 | } |
748 | |
749 | if (strncmp(buf, "Manifest-Version:", 17)) { |
| 41 | | Assuming the condition is false | |
|
| |
750 | PR_fprintf(errorFD, "%s: not a manifest file!\n", PROGRAM_NAME); |
751 | errorCount++; |
752 | exit(ERRX); |
753 | } |
754 | |
755 | fseek(mfFile, 0L, SEEK_SET); |
756 | |
757 | |
758 | |
759 | while (1) { |
| 43 | | Loop condition is true. Entering loop body | |
|
760 | |
761 | r1 = ftell(mfFile); |
762 | |
763 | if (fgets(name, BUFSIZ, mfFile) == NULL) |
| 44 | | Assuming the condition is false | |
|
| |
764 | break; |
765 | |
766 | line++; |
767 | |
768 | if (r1 != 0 && strncmp(name, "Name:", 5)) { |
| 46 | | Assuming 'r1' is equal to 0 | |
|
769 | PR_fprintf(errorFD, |
770 | "warning: unexpected input in manifest file \"%s\" at line %d:\n", |
771 | manifile, line); |
772 | PR_fprintf(errorFD, "%s\n", name); |
773 | warningCount++; |
774 | } |
775 | |
776 | r2 = r1; |
777 | while (fgets(buf, BUFSIZ, mfFile)) { |
| 51 | | Loop condition is false. Execution continues on line 787 | |
|
778 | if (*buf == 0 || *buf == '\n' || *buf == '\r') |
| 47 | | Assuming the condition is false | |
|
| 48 | | Assuming the condition is false | |
|
| 49 | | Assuming the condition is false | |
|
| |
779 | break; |
780 | |
781 | line++; |
782 | |
783 | |
784 | r2 = ftell(mfFile); |
785 | } |
786 | |
787 | r3 = ftell(mfFile); |
788 | |
789 | if (r1) { |
| |
790 | fprintf(sfFile, "\n"); |
791 | fprintf(sfFile, "%s", name); |
792 | } |
793 | |
794 | calculate_MD5_range(mfFile, r1, r2, &dig); |
| 53 | | Calling 'calculate_MD5_range' | |
|
795 | |
796 | if (optimize == 0) { |
797 | fprintf(sfFile, "Digest-Algorithms: MD5 SHA1\n"); |
798 | |
799 | md5 = BTOA_DataToAscii(dig.md5, MD5_LENGTH); |
800 | fprintf(sfFile, "MD5-Digest: %s\n", md5); |
801 | PORT_Free(md5); |
802 | } |
803 | |
804 | sha1 = BTOA_DataToAscii(dig.sha1, SHA1_LENGTH); |
805 | fprintf(sfFile, "SHA1-Digest: %s\n", sha1); |
806 | PORT_Free(sha1); |
807 | |
808 | |
809 | fseek(mfFile, r3, SEEK_SET); |
810 | } |
811 | |
812 | PORT_Free(buf); |
813 | PORT_Free(name); |
814 | |
815 | fclose(sfFile); |
816 | fclose(mfFile); |
817 | |
818 | return 0; |
819 | } |
820 | |
821 | |
822 | |
823 | |
824 | |
825 | |
826 | |
827 | |
828 | static int |
829 | calculate_MD5_range(FILE *fp, long r1, long r2, JAR_Digest *dig) |
830 | { |
831 | int num; |
832 | int range; |
833 | unsigned char *buf; |
834 | SECStatus rv; |
835 | |
836 | range = r2 - r1; |
837 | |
838 | |
839 | fseek(fp, r1, SEEK_SET); |
840 | |
841 | buf = (unsigned char *)PORT_ZAlloc(range); |
| 54 | | Value assigned to 'buf' | |
|
842 | if (buf == NULL) |
| 55 | | Assuming 'buf' is equal to NULL | |
|
| |
843 | out_of_memory(); |
844 | |
845 | if ((num = fread(buf, 1, range, fp)) != range) { |
| 57 | | The 1st argument to 'fread' is NULL but should not be NULL |
|
846 | PR_fprintf(errorFD, "%s: expected %d bytes, got %d\n", PROGRAM_NAME, |
847 | range, num); |
848 | errorCount++; |
849 | exit(ERRX); |
850 | } |
851 | |
852 | rv = PK11_HashBuf(SEC_OID_MD5, dig->md5, buf, range); |
853 | if (rv == SECSuccess) { |
854 | rv = PK11_HashBuf(SEC_OID_SHA1, dig->sha1, buf, range); |
855 | } |
856 | if (rv != SECSuccess) { |
857 | PR_fprintf(errorFD, "%s: can't generate digest context\n", |
858 | PROGRAM_NAME); |
859 | errorCount++; |
860 | exit(ERRX); |
861 | } |
862 | |
863 | PORT_Free(buf); |
864 | |
865 | return 0; |
866 | } |
867 | |
868 | static void |
869 | SignOut(void *arg, const char *buf, unsigned long len) |
870 | { |
871 | fwrite(buf, len, 1, (FILE *)arg); |
872 | } |