/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "signtool.h"
static int jar_cb(
int status, JAR *jar,
const char *metafile,
char *pathname,
char *errortext);
static int verify_global(JAR *jar);
/*************************************************************************
*
* V e r i f y J a r
*/
int
VerifyJar(
char *filename)
{
FILE *fp;
int ret;
int status;
int failed =
0 ;
char *err;
JAR *jar;
JAR_Context *ctx;
JAR_Item *it;
jar = JAR_new();
if ((fp = fopen(filename,
"r" )) == NULL) {
perror(filename);
exit (ERRX);
}
else
fclose(fp);
JAR_set_callback(JAR_CB_SIGNAL, jar, jar_cb);
status = JAR_pass_archive(jar, jarArchGuess, filename,
"some-url" );
if (status <
0 || jar->valid <
0 ) {
failed =
1 ;
PR_fprintf(outputFD,
"\nNOTE -- \" %s\
" archive DID NOT PASS crypto verification.\n" ,
filename);
if (status <
0 ) {
const char *errtext;
if (status >= JAR_BASE && status <= JAR_BASE_END) {
errtext = JAR_get_error(status);
}
else {
errtext = SECU_Strerror(PORT_GetError());
}
PR_fprintf(outputFD,
" (reported reason: %s)\n\n" ,
errtext);
/* corrupt files should not have their contents listed */
if (status == JAR_ERR_CORRUPT)
return -
1 ;
}
PR_fprintf(outputFD,
"entries shown below will have their digests checked only.\n" );
jar->valid =
0 ;
}
else
PR_fprintf(outputFD,
"archive \" %s\
" has passed crypto verification.\n" , filename);
if (verify_global(jar))
failed =
1 ;
PR_fprintf(outputFD,
"\n" );
PR_fprintf(outputFD,
"%16s %s\n" ,
"status" ,
"path" );
PR_fprintf(outputFD,
"%16s %s\n" ,
"------------" ,
"-------------------" );
ctx = JAR_find(jar, NULL, jarTypeMF);
while (JAR_find_next(ctx, &it) >=
0 ) {
if (it && it->pathname) {
rm_dash_r(TMP_OUTPUT);
ret = JAR_verified_extract(jar, it->pathname, TMP_OUTPUT);
/* if (ret < 0) printf ("error %d on %s\n", ret, it->pathname); */
if (ret <
0 )
failed =
1 ;
if (ret == JAR_ERR_PNF)
err =
"NOT PRESENT" ;
else if (ret == JAR_ERR_HASH)
err =
"HASH FAILED" ;
else
err =
"NOT VERIFIED" ;
PR_fprintf(outputFD,
"%16s %s\n" ,
ret >=
0 ?
"verified" : err, it->pathname);
if (ret !=
0 && ret != JAR_ERR_PNF && ret != JAR_ERR_HASH)
PR_fprintf(outputFD,
" (reason: %s)\n" ,
JAR_get_error(ret));
}
}
JAR_find_end(ctx);
if (status <
0 || jar->valid <
0 ) {
failed =
1 ;
PR_fprintf(outputFD,
"\nNOTE -- \" %s\
" archive DID NOT PASS crypto verification.\n" ,
filename);
give_help(status);
}
JAR_destroy(jar);
if (failed)
return -
1 ;
return 0 ;
}
/***************************************************************************
*
* v e r i f y _ g l o b a l
*/
static int
verify_global(JAR *jar)
{
FILE *fp;
JAR_Context *ctx;
JAR_Item *it;
JAR_Digest *globaldig;
char *ext;
unsigned char *md5_digest, *sha1_digest;
unsigned int sha1_length, md5_length;
int retval =
0 ;
char buf[BUFSIZ];
ctx = JAR_find(jar,
"*" , jarTypePhy);
while (JAR_find_next(ctx, &it) >=
0 ) {
if (!PORT_Strncmp(it->pathname,
"META-INF" ,
8 )) {
for (ext = it->pathname; *ext; ext++)
;
while (ext > it->pathname && *ext !=
'.' )
ext--;
if (verbosity >=
0 ) {
if (!PORT_Strcasecmp(ext,
".rsa" )) {
PR_fprintf(outputFD,
"found a RSA signature file: %s\n" ,
it->pathname);
}
if (!PORT_Strcasecmp(ext,
".dsa" )) {
PR_fprintf(outputFD,
"found a DSA signature file: %s\n" ,
it->pathname);
}
if (!PORT_Strcasecmp(ext,
".mf" )) {
PR_fprintf(outputFD,
"found a MF master manifest file: %s\n" ,
it->pathname);
}
}
if (!PORT_Strcasecmp(ext,
".sf" )) {
if (verbosity >=
0 ) {
PR_fprintf(outputFD,
"found a SF signature manifest file: %s\n" ,
it->pathname);
}
rm_dash_r(TMP_OUTPUT);
if (JAR_extract(jar, it->pathname, TMP_OUTPUT) <
0 ) {
PR_fprintf(errorFD,
"%s: error extracting %s\n" ,
PROGRAM_NAME, it->pathname);
errorCount++;
retval = -
1 ;
continue ;
}
md5_digest = NULL;
sha1_digest = NULL;
if ((fp = fopen(TMP_OUTPUT,
"rb" )) != NULL) {
while (fgets(buf, BUFSIZ, fp)) {
char *s;
if (*buf ==
0 || *buf ==
'\n' || *buf ==
'\r' )
break ;
for (s = buf; *s && *s !=
'\n' && *s !=
'\r' ; s++)
;
*s =
0 ;
if (!PORT_Strncmp(buf,
"MD5-Digest: " ,
12 )) {
md5_digest =
ATOB_AsciiToData(buf +
12 , &md5_length);
}
if (!PORT_Strncmp(buf,
"SHA1-Digest: " ,
13 )) {
sha1_digest =
ATOB_AsciiToData(buf +
13 , &sha1_length);
}
if (!PORT_Strncmp(buf,
"SHA-Digest: " ,
12 )) {
sha1_digest =
ATOB_AsciiToData(buf +
12 , &sha1_length);
}
}
globaldig = jar->globalmeta;
if (globaldig && md5_digest && verbosity >=
0 ) {
PR_fprintf(outputFD,
" md5 digest on global metainfo: %s\n" ,
PORT_Memcmp(md5_digest, globaldig->md5, MD5_LENGTH)
?
"no match"
:
"match" );
}
if (globaldig && sha1_digest && verbosity >=
0 ) {
PR_fprintf(outputFD,
" sha digest on global metainfo: %s\n" ,
PORT_Memcmp(sha1_digest, globaldig->sha1, SHA1_LENGTH)
?
"no match"
:
"match" );
}
if (globaldig == NULL && verbosity >=
0 ) {
PR_fprintf(outputFD,
"global metadigest is not available, strange.\n" );
}
PORT_Free(md5_digest);
PORT_Free(sha1_digest);
fclose(fp);
}
}
}
}
JAR_find_end(ctx);
return retval;
}
/************************************************************************
*
* J a r W h o
*/
int
JarWho(
char *filename)
{
FILE *fp;
JAR *jar;
JAR_Context *ctx;
int status;
int retval =
0 ;
JAR_Item *it;
JAR_Cert *fing;
CERTCertificate *cert, *prev = NULL;
jar = JAR_new();
if ((fp = fopen(filename,
"r" )) == NULL) {
perror(filename);
exit (ERRX);
}
fclose(fp);
status = JAR_pass_archive(jar, jarArchGuess, filename,
"some-url" );
if (status <
0 || jar->valid <
0 ) {
PR_fprintf(outputFD,
"NOTE -- \" %s\
" archive DID NOT PASS crypto verification.\n" ,
filename);
retval = -
1 ;
if (jar->valid <
0 || status != -
1 ) {
const char *errtext;
if (status >= JAR_BASE && status <= JAR_BASE_END) {
errtext = JAR_get_error(status);
}
else {
errtext = SECU_Strerror(PORT_GetError());
}
PR_fprintf(outputFD,
" (reported reason: %s)\n\n" , errtext);
}
}
PR_fprintf(outputFD,
"\nSigner information:\n\n" );
ctx = JAR_find(jar, NULL, jarTypeSign);
while (JAR_find_next(ctx, &it) >=
0 ) {
fing = (JAR_Cert *)it->data;
cert = fing->cert;
if (cert) {
if (prev == cert)
break ;
if (cert->nickname)
PR_fprintf(outputFD,
"nickname: %s\n" , cert->nickname);
if (cert->subjectName)
PR_fprintf(outputFD,
"subject name: %s\n" ,
cert->subjectName);
if (cert->issuerName)
PR_fprintf(outputFD,
"issuer name: %s\n" , cert->issuerName);
}
else {
PR_fprintf(outputFD,
"no certificate could be found\n" );
retval = -
1 ;
}
prev = cert;
}
JAR_find_end(ctx);
JAR_destroy(jar);
return retval;
}
/************************************************************************
* j a r _ c b
*/
static int
jar_cb(
int status, JAR *jar,
const char *metafile,
char *pathname,
char *errortext)
{
PR_fprintf(errorFD,
"error %d: %s IN FILE %s\n" , status, errortext,
pathname);
errorCount++;
return 0 ;
}
Messung V0.5 in Prozent C=98 H=87 G=92
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-09-30)
¤
*© Formatika GbR, Deutschland