security/nss/cmd/signtool/verify.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     5 #include "signtool.h"
     8 static int	jar_cb(int status, JAR *jar, const char *metafile, 
     9 char *pathname, char *errortext);
    10 static int	verify_global (JAR *jar);
    12 /*************************************************************************
    13  *
    14  * V e r i f y J a r
    15  */
    16 int
    17 VerifyJar(char *filename)
    18 {
    19     FILE * fp;
    21     int	ret;
    22     int	status;
    23     int	failed = 0;
    24     char	*err;
    26     JAR * jar;
    27     JAR_Context * ctx;
    29     JAR_Item * it;
    31     jar = JAR_new();
    33     if ((fp = fopen (filename, "r")) == NULL) {
    34 	perror (filename);
    35 	exit (ERRX);
    36     } else
    37 	fclose (fp);
    39     JAR_set_callback (JAR_CB_SIGNAL, jar, jar_cb);
    42     status = JAR_pass_archive (jar, jarArchGuess, filename, "some-url");
    44     if (status < 0 || jar->valid < 0) {
    45 	failed = 1;
    46 	PR_fprintf(outputFD, 
    47 	    "\nNOTE -- \"%s\" archive DID NOT PASS crypto verification.\n",
    48 	     filename);
    49 	if (status < 0) {
    50 	    const char	*errtext;
    52 	    if (status >= JAR_BASE && status <= JAR_BASE_END) {
    53 		errtext = JAR_get_error (status);
    54 	    } else {
    55 		errtext = SECU_Strerror(PORT_GetError());
    56 	    }
    58 	    PR_fprintf(outputFD, "  (reported reason: %s)\n\n",
    59 	         errtext);
    61 	    /* corrupt files should not have their contents listed */
    63 	    if (status == JAR_ERR_CORRUPT)
    64 		return - 1;
    65 	}
    66 	PR_fprintf(outputFD,
    67 	    "entries shown below will have their digests checked only.\n");
    68 	jar->valid = 0;
    69     } else
    70 	PR_fprintf(outputFD,
    71 	    "archive \"%s\" has passed crypto verification.\n", filename);
    73     if (verify_global (jar))
    74 	failed = 1;
    76     PR_fprintf(outputFD, "\n");
    77     PR_fprintf(outputFD, "%16s   %s\n", "status", "path");
    78     PR_fprintf(outputFD, "%16s   %s\n", "------------", "-------------------");
    80     ctx = JAR_find (jar, NULL, jarTypeMF);
    82     while (JAR_find_next (ctx, &it) >= 0) {
    83 	if (it && it->pathname) {
    84 	    rm_dash_r(TMP_OUTPUT);
    85 	    ret = JAR_verified_extract (jar, it->pathname, TMP_OUTPUT);
    86 	    /* if (ret < 0) printf ("error %d on %s\n", ret, it->pathname); */
    87 	    if (ret < 0) 
    88 		failed = 1;
    90 	    if (ret == JAR_ERR_PNF)
    91 		err = "NOT PRESENT";
    92 	    else if (ret == JAR_ERR_HASH)
    93 		err = "HASH FAILED";
    94 	    else
    95 		err = "NOT VERIFIED";
    97 	    PR_fprintf(outputFD, "%16s   %s\n", 
    98 	        ret >= 0 ? "verified" : err, it->pathname);
   100 	    if (ret != 0 && ret != JAR_ERR_PNF && ret != JAR_ERR_HASH)
   101 		PR_fprintf(outputFD, "      (reason: %s)\n",
   102 		     JAR_get_error (ret));
   103 	}
   104     }
   106     JAR_find_end (ctx);
   108     if (status < 0 || jar->valid < 0) {
   109 	failed = 1;
   110 	PR_fprintf(outputFD,
   111 	    "\nNOTE -- \"%s\" archive DID NOT PASS crypto verification.\n",
   112 	     filename);
   113 	give_help (status);
   114     }
   116     JAR_destroy (jar);
   118     if (failed)
   119 	return - 1;
   120     return 0;
   121 }
   124 /***************************************************************************
   125  *
   126  * v e r i f y _ g l o b a l
   127  */
   128 static int	
   129 verify_global (JAR *jar)
   130 {
   131     FILE        * fp;
   132     JAR_Context * ctx;
   133     JAR_Item    * it;
   134     JAR_Digest  * globaldig;
   135     char	* ext;
   136     unsigned char *md5_digest, *sha1_digest;
   137     unsigned int  sha1_length, md5_length;
   138     int	          retval = 0;
   139     char	  buf [BUFSIZ];
   141     ctx = JAR_find (jar, "*", jarTypePhy);
   143     while (JAR_find_next (ctx, &it) >= 0) {
   144 	if (!PORT_Strncmp (it->pathname, "META-INF", 8)) {
   145 	    for (ext = it->pathname; *ext; ext++)
   146 		;
   147 	    while (ext > it->pathname && *ext != '.') 
   148 		ext--;
   150 	    if (verbosity >= 0) {
   151 		if (!PORT_Strcasecmp (ext, ".rsa")) {
   152 		    PR_fprintf(outputFD, "found a RSA signature file: %s\n",
   153 		         				  it->pathname);
   154 		}
   156 		if (!PORT_Strcasecmp (ext, ".dsa")) {
   157 		    PR_fprintf(outputFD, "found a DSA signature file: %s\n",
   158 		         				  it->pathname);
   159 		}
   161 		if (!PORT_Strcasecmp (ext, ".mf")) {
   162 		    PR_fprintf(outputFD,
   163 		        "found a MF master manifest file: %s\n",
   164 		         it->pathname);
   165 		}
   166 	    }
   168 	    if (!PORT_Strcasecmp (ext, ".sf")) {
   169 		if (verbosity >= 0) {
   170 		    PR_fprintf(outputFD,
   171 		        "found a SF signature manifest file: %s\n",
   172 		         it->pathname);
   173 		}
   175 		rm_dash_r(TMP_OUTPUT);
   176 		if (JAR_extract (jar, it->pathname, TMP_OUTPUT) < 0) {
   177 		    PR_fprintf(errorFD, "%s: error extracting %s\n",
   178 		         PROGRAM_NAME, it->pathname);
   179 		    errorCount++;
   180 		    retval = -1;
   181 		    continue;
   182 		}
   184 		md5_digest = NULL;
   185 		sha1_digest = NULL;
   187 		if ((fp = fopen (TMP_OUTPUT, "rb")) != NULL) {
   188 		    while (fgets (buf, BUFSIZ, fp)) {
   189 			char	*s;
   191 			if (*buf == 0 || *buf == '\n' || *buf == '\r') 
   192 			    break;
   194 			for (s = buf; *s && *s != '\n' && *s != '\r'; s++)
   195 			    ;
   196 			*s = 0;
   198 			if (!PORT_Strncmp (buf, "MD5-Digest: ", 12)) {
   199 			    md5_digest = 
   200 				ATOB_AsciiToData (buf + 12, &md5_length);
   201 			}
   202 			if (!PORT_Strncmp (buf, "SHA1-Digest: ", 13)) {
   203 			    sha1_digest = 
   204 				ATOB_AsciiToData (buf + 13, &sha1_length);
   205 			}
   206 			if (!PORT_Strncmp (buf, "SHA-Digest: ", 12)) {
   207 			    sha1_digest = 
   208 				ATOB_AsciiToData (buf + 12, &sha1_length);
   209 			}
   210 		    }
   212 		    globaldig = jar->globalmeta;
   214 		    if (globaldig && md5_digest && verbosity >= 0) {
   215 			PR_fprintf(outputFD,
   216 			   "  md5 digest on global metainfo: %s\n",
   217 			    PORT_Memcmp(md5_digest, globaldig->md5, MD5_LENGTH)
   218 			    ? "no match" : "match");
   219 		    }
   221 		    if (globaldig && sha1_digest && verbosity >= 0) {
   222 			PR_fprintf(outputFD,
   223 			    "  sha digest on global metainfo: %s\n",
   224 			    PORT_Memcmp(sha1_digest, globaldig->sha1, SHA1_LENGTH) 
   225 			    ? "no match" : "match");
   226 		    }
   228 		    if (globaldig == NULL && verbosity >= 0) {
   229 			PR_fprintf(outputFD,
   230 			     "global metadigest is not available, strange.\n");
   231 		    }
   233 		    fclose (fp);
   234 		}
   235 	    }
   236 	}
   237     }
   239     JAR_find_end (ctx);
   241     return retval;
   242 }
   245 /************************************************************************
   246  *
   247  * J a r W h o
   248  */
   249 int
   250 JarWho(char *filename)
   251 {
   252     FILE * fp;
   254     JAR * jar;
   255     JAR_Context * ctx;
   257     int	status;
   258     int	retval = 0;
   260     JAR_Item * it;
   261     JAR_Cert * fing;
   263     CERTCertificate * cert, *prev = NULL;
   265     jar = JAR_new();
   267     if ((fp = fopen (filename, "r")) == NULL) {
   268 	perror (filename);
   269 	exit (ERRX);
   270     } 
   271     fclose (fp);
   273     status = JAR_pass_archive (jar, jarArchGuess, filename, "some-url");
   275     if (status < 0 || jar->valid < 0) {
   276 	PR_fprintf(outputFD,
   277 	    "NOTE -- \"%s\" archive DID NOT PASS crypto verification.\n",
   278 	     filename);
   279 	retval = -1;
   280 	if (jar->valid < 0 || status != -1) {
   281 	    const char	*errtext;
   283 	    if (status >= JAR_BASE && status <= JAR_BASE_END) {
   284 		errtext = JAR_get_error (status);
   285 	    } else {
   286 		errtext = SECU_Strerror(PORT_GetError());
   287 	    }
   289 	    PR_fprintf(outputFD, "  (reported reason: %s)\n\n", errtext);
   290 	}
   291     }
   293     PR_fprintf(outputFD, "\nSigner information:\n\n");
   295     ctx = JAR_find (jar, NULL, jarTypeSign);
   297     while (JAR_find_next (ctx, &it) >= 0) {
   298 	fing = (JAR_Cert * ) it->data;
   299 	cert = fing->cert;
   301 	if (cert) {
   302 	    if (prev == cert)
   303 		break;
   305 	    if (cert->nickname)
   306 		PR_fprintf(outputFD, "nickname: %s\n", cert->nickname);
   307 	    if (cert->subjectName)
   308 		PR_fprintf(outputFD, "subject name: %s\n",
   309 		     cert->subjectName);
   310 	    if (cert->issuerName)
   311 		PR_fprintf(outputFD, "issuer name: %s\n", cert->issuerName);
   312 	} else {
   313 	    PR_fprintf(outputFD, "no certificate could be found\n");
   314 	    retval = -1;
   315 	}
   317 	prev = cert;
   318     }
   320     JAR_find_end (ctx);
   322     JAR_destroy (jar);
   323     return retval;
   324 }
   327 /************************************************************************
   328  * j a r _ c b
   329  */
   330 static int	jar_cb(int status, JAR *jar, const char *metafile,
   331 char *pathname, char *errortext)
   332 {
   333     PR_fprintf(errorFD, "error %d: %s IN FILE %s\n", status, errortext,
   334          pathname);
   335     errorCount++;
   336     return 0;
   337 }

mercurial