sign.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 862 行 · 第 1/2 页

C
862
字号
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "signtool.h"#include "zip.h" #include "prmem.h"#include "blapi.h"static int create_pk7 (char *dir, char *keyName, int *keyType);static int jar_find_key_type (CERTCertificate *cert);static int manifesto (char *dirname, char *install_script, PRBool recurse);static int manifesto_fn(char *relpath, char *basedir, char *reldir,	char *filename, void *arg);static int sign_all_arc_fn(char *relpath, char *basedir, char *reldir,	char *filename, void *arg);static int add_meta (FILE *fp, char *name);static int SignFile (FILE *outFile, FILE *inFile, CERTCertificate *cert);static int generate_SF_file (char *manifile, char *who);static int calculate_MD5_range (FILE *fp, long r1, long r2, JAR_Digest *dig);static void SignOut (void *arg, const char *buf, unsigned long len);static char *metafile = NULL;static int optimize = 0;static FILE *mf;static ZIPfile *zipfile=NULL;/*  *  S i g n A r c h i v e * *  Sign an individual archive tree. A directory  *  called META-INF is created underneath this. * */intSignArchive(char *tree, char *keyName, char *zip_file, int javascript,	char *meta_file, char *install_script, int _optimize, PRBool recurse){  int status;  char tempfn [FNSIZE], fullfn [FNSIZE];	int keyType = rsaKey;	metafile = meta_file;	optimize = _optimize;	if(zip_file) {		zipfile = JzipOpen(zip_file, NULL /*no comment*/);	}  manifesto (tree, install_script, recurse);  if (keyName)    {    status = create_pk7 (tree, keyName, &keyType);    if (status < 0)      {      PR_fprintf(errorFD, "the tree \"%s\" was NOT SUCCESSFULLY SIGNED\n", tree);		errorCount++;      exit (ERRX);      }    }  /* mf to zip */  strcpy (tempfn, "META-INF/manifest.mf");  sprintf (fullfn, "%s/%s", tree, tempfn);  JzipAdd(fullfn, tempfn, zipfile, compression_level);  /* sf to zip */  sprintf (tempfn, "META-INF/%s.sf", base);  sprintf (fullfn, "%s/%s", tree, tempfn);  JzipAdd(fullfn, tempfn, zipfile, compression_level);  /* rsa/dsa to zip */  sprintf (tempfn, "META-INF/%s.%s", base, (keyType==dsaKey ? "dsa" : "rsa"));  sprintf (fullfn, "%s/%s", tree, tempfn);  JzipAdd(fullfn, tempfn, zipfile, compression_level);  JzipClose(zipfile);	if(verbosity >= 0) {		if (javascript) {			PR_fprintf(outputFD,"jarfile \"%s\" signed successfully\n",				zip_file);		} else {			PR_fprintf(outputFD, "tree \"%s\" signed successfully\n", tree);		}	}  return 0;}typedef struct {	char *keyName;	int javascript;	char *metafile;	char *install_script;	int optimize;} SignArcInfo;/*  *  S i g n A l l A r c * *  Javascript may generate multiple .arc directories, one *  for each jar archive needed. Sign them all. * */intSignAllArc(char *jartree, char *keyName, int javascript, char *metafile,	char *install_script, int optimize, PRBool recurse){	SignArcInfo info;	info.keyName = keyName;	info.javascript = javascript;	info.metafile = metafile;	info.install_script = install_script;	info.optimize = optimize;	return foreach(jartree, "", sign_all_arc_fn, recurse,		PR_TRUE /*include dirs*/, (void*)&info);}static intsign_all_arc_fn(char *relpath, char *basedir, char *reldir, char *filename,	void *arg){	char *zipfile=NULL;	char *arc=NULL, *archive=NULL;	int retval=0;	SignArcInfo *infop = (SignArcInfo*)arg;	/* Make sure there is one and only one ".arc" in the relative path, 	 * and that it is at the end of the path (don't sign .arcs within .arcs) */	if ( (PL_strcaserstr(relpath, ".arc") == relpath + strlen(relpath) - 4) &&		 (PL_strcasestr(relpath, ".arc") == relpath + strlen(relpath) - 4) ) {		if(!infop) {			retval = -1;			goto finish;		}		archive = PR_smprintf("%s/%s", basedir, relpath);		zipfile = PL_strdup(archive);		arc = PORT_Strrchr (zipfile, '.');		if (arc == NULL) {			PR_fprintf(errorFD, "%s: Internal failure\n", PROGRAM_NAME);			errorCount++;			retval = -1;			goto finish;		}		PL_strcpy (arc, ".jar");		if(verbosity >= 0) {			PR_fprintf(outputFD, "\nsigning: %s\n", zipfile);		}		retval = SignArchive(archive, infop->keyName, zipfile,			infop->javascript, infop->metafile, infop->install_script,			infop->optimize, PR_TRUE /* recurse */);	}finish:	if(archive) PR_Free(archive);	if(zipfile) PR_Free(zipfile);	return retval;}/********************************************************************* * * c r e a t e _ p k 7 */static intcreate_pk7 (char *dir, char *keyName, int *keyType){  int status = 0;	char *file_ext;  CERTCertificate *cert;  CERTCertDBHandle *db;  SECKEYKeyDBHandle *keyHandle;  FILE *in, *out;  char sf_file [FNSIZE];  char pk7_file [FNSIZE];  /* open key database */  keyHandle = SECU_OpenKeyDB(PR_TRUE /*readOnly*/);  if (keyHandle == NULL)     return -1;   SECKEY_SetDefaultKeyDB (keyHandle);  /* open cert database */  db = OpenCertDB(PR_TRUE /*readOnly*/);   if (db == NULL)     return -1;  /* find cert */	/*cert = CERT_FindCertByNicknameOrEmailAddr(db, keyName);*/	cert = PK11_FindCertFromNickname(keyName, NULL /*wincx*/);  if (cert == NULL)     {    SECU_PrintError      (      PROGRAM_NAME,      "the cert \"%s\" does not exist in the database",      keyName      );    return -1;    }  /* determine the key type, which sets the extension for pkcs7 object */  *keyType = jar_find_key_type (cert);  file_ext = (*keyType == dsaKey) ? "dsa" : "rsa";  sprintf (sf_file, "%s/META-INF/%s.sf", dir, base);  sprintf (pk7_file, "%s/META-INF/%s.%s", dir, base, file_ext);  if ((in = fopen (sf_file, "rb")) == NULL)    {    PR_fprintf(errorFD, "%s: Can't open %s for reading\n", PROGRAM_NAME, sf_file);	errorCount++;    exit (ERRX);    }  if ((out = fopen (pk7_file, "wb")) == NULL)    {    PR_fprintf(errorFD, "%s: Can't open %s for writing\n", PROGRAM_NAME, sf_file);	errorCount++;    exit (ERRX);    }  status = SignFile (out, in, cert);  fclose (in);  fclose (out);  if (status)    {    PR_fprintf(errorFD, "%s: PROBLEM signing data (%s)\n",		PROGRAM_NAME, SECU_ErrorString ((int16) PORT_GetError()));	errorCount++;    return -1;    }  return 0;}/* *  j a r _ f i n d _ k e y _ t y p e *  *  Determine the key type for a given cert, which  * should be rsaKey or dsaKey. Any error return 0. * */static intjar_find_key_type (CERTCertificate *cert){  PK11SlotInfo *slot = NULL;  SECKEYPrivateKey *privk = NULL;  /* determine its type */  PK11_FindObjectForCert (cert, /*wincx*/ NULL, &slot);  if (slot == NULL)    {    PR_fprintf(errorFD, "warning - can't find slot for this cert\n");	warningCount++;    return 0;    }  privk = PK11_FindPrivateKeyFromCert (slot, cert, /*wincx*/ NULL);  if (privk == NULL)    {    PR_fprintf(errorFD, "warning - can't find private key for this cert\n");	warningCount++;    return 0;    }  return privk->keyType;  }/* *  m a n i f e s t o * *  Run once for every subdirectory in which a  *  manifest is to be created -- usually exactly once. * */static intmanifesto (char *dirname, char *install_script, PRBool recurse){  char metadir [FNSIZE], sfname [FNSIZE];  /* Create the META-INF directory to hold signing info */  if (PR_Access (dirname, PR_ACCESS_READ_OK))    {    PR_fprintf(errorFD, "%s: unable to read your directory: %s\n", PROGRAM_NAME,		dirname);	errorCount++;    perror (dirname);    exit (ERRX);    }	if (PR_Access (dirname, PR_ACCESS_WRITE_OK)) {		PR_fprintf(errorFD, "%s: unable to write to your directory: %s\n",			PROGRAM_NAME, dirname);		errorCount++;		perror(dirname);		exit(ERRX);	}  sprintf (metadir, "%s/META-INF", dirname);  strcpy (sfname, metadir);  PR_MkDir (metadir, 0777);  strcat (metadir, "/");  strcat (metadir, MANIFEST);  if ((mf = fopen (metadir, "wb")) == NULL)    {    perror (MANIFEST);    PR_fprintf(errorFD, "%s: Probably, the directory you are trying to"		" sign has\n", PROGRAM_NAME);    PR_fprintf(errorFD, "%s: permissions problems or may not exist.\n",		PROGRAM_NAME);	errorCount++;    exit (ERRX);    }	if(verbosity >= 0) {		PR_fprintf(outputFD, "Generating %s file..\n", metadir);	}  fprintf(mf, "Manifest-Version: 1.0\n");  fprintf (mf, "Created-By: %s\n", CREATOR);  fprintf (mf, "Comments: %s\n", BREAKAGE);  if (scriptdir)    {    fprintf (mf, "Comments: --\n");    fprintf (mf, "Comments: --\n");    fprintf (mf, "Comments: -- This archive signs Javascripts which may not necessarily\n");    fprintf (mf, "Comments: -- be included in the physical jar file.\n");    fprintf (mf, "Comments: --\n");    fprintf (mf, "Comments: --\n");    }  if (install_script)    fprintf (mf, "Install-Script: %s\n", install_script);  if (metafile)    add_meta (mf, "+");  /* Loop through all files & subdirectories */  foreach (dirname, "", manifesto_fn, recurse, PR_FALSE /*include dirs */,		(void*)NULL);  fclose (mf);  strcat (sfname, "/");  strcat (sfname, base);  strcat (sfname, ".sf");	if(verbosity >= 0) {		PR_fprintf(outputFD, "Generating %s.sf file..\n", base);	}  generate_SF_file (metadir, sfname);  return 0;}/* *  m a n i f e s t o _ f n * *  Called by pointer from manifesto(), once for *  each file within the directory. * */static int manifesto_fn      (char *relpath, char *basedir, char *reldir, char *filename, void *arg){  int use_js;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?