util.c

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

C
1,013
字号
/* * 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 "cdbhdl.h"#include "prio.h"#include "prmem.h"static int is_dir (char *filename);static char *certDBNameCallback(void *arg, int dbVersion);/*********************************************************************** * * O p e n C e r t D B */CERTCertDBHandle *OpenCertDB(PRBool readOnly){    CERTCertDBHandle *db;    SECStatus rv;    /* Allocate a handle to fill with CERT_OpenCertDB below */    db = (CERTCertDBHandle *) PORT_ZAlloc (sizeof(CERTCertDBHandle));    if (db == NULL)         {	SECU_PrintError(progName, "unable to get database handle");	return NULL;        }    rv = CERT_OpenCertDB (db, readOnly, certDBNameCallback, NULL);    if (rv)         {	SECU_PrintError(progName, "could not open certificate database");	if (db) PORT_Free (db);	return NULL;        }     else        {	CERT_SetDefaultCertDB(db);        }    return db;}/*********************************************************** * Nasty hackish function definitions */long *mozilla_event_queue = 0;#ifndef XP_WINchar *XP_GetString (int i){  return SECU_ErrorStringRaw ((int16) i);}#endifvoid FE_SetPasswordEnabled(){}void /*MWContext*/ *FE_GetInitContext (void){  return 0;}void /*MWContext*/ *XP_FindSomeContext(){  /* No windows context in command tools */  return NULL;}void ET_moz_CallFunction(){}/* *  R e m o v e A l l A r c * *  Remove .arc directories that are lingering *  from a previous run of signtool. * */intRemoveAllArc(char *tree){	PRDir *dir;	PRDirEntry *entry;	char *archive=NULL;	int retval = 0;	dir = PR_OpenDir (tree);	if (!dir) return -1;	for (entry = PR_ReadDir (dir,0); entry; entry = PR_ReadDir (dir,0)) {		if(entry->name[0] == '.') {			continue;		}		if(archive) PR_Free(archive);		archive = PR_smprintf("%s/%s", tree, entry->name);	    if (PL_strcaserstr (entry->name, ".arc")			== (entry->name + strlen(entry->name) - 4) ) {			if(verbosity >= 0) {				PR_fprintf(outputFD, "removing: %s\n", archive);			}			if(rm_dash_r(archive)) {				PR_fprintf(errorFD, "Error removing %s\n", archive);				errorCount++;				retval = -1;				goto finish;			}		} else if(is_dir(archive)) {			if(RemoveAllArc(archive)) {				retval = -1;				goto finish;			}		}	}finish:	PR_CloseDir (dir);	if(archive) PR_Free(archive);	return retval;}/* *  r m _ d a s h _ r * *  Remove a file, or a directory recursively. * */int rm_dash_r (char *path){	PRDir	*dir;	PRDirEntry *entry;	PRFileInfo fileinfo;	char filename[FNSIZE];	if(PR_GetFileInfo(path, &fileinfo) != PR_SUCCESS) {		/*fprintf(stderr, "Error: Unable to access %s\n", filename);*/		return -1;	}	if(fileinfo.type == PR_FILE_DIRECTORY) {		dir = PR_OpenDir(path);		if(!dir) {			PR_fprintf(errorFD, "Error: Unable to open directory %s.\n", path);			errorCount++;			return -1;		}		/* Recursively delete all entries in the directory */		while((entry = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) {			sprintf(filename, "%s/%s", path, entry->name);			if(rm_dash_r(filename)) return -1;		}		if(PR_CloseDir(dir) != PR_SUCCESS) {			PR_fprintf(errorFD, "Error: Could not close %s.\n", path);			errorCount++;			return -1;		}		/* Delete the directory itself */		if(PR_RmDir(path) != PR_SUCCESS) {			PR_fprintf(errorFD, "Error: Unable to delete %s\n", path);			errorCount++;			return -1;		}	} else {		if(PR_Delete(path) != PR_SUCCESS) {			PR_fprintf(errorFD, "Error: Unable to delete %s\n", path);			errorCount++;			return -1;		}	}	return 0;}/* *  u s a g e  *  *  Print some useful help information * */voidusage (void){  PR_fprintf(outputFD, "\n");  PR_fprintf(outputFD, "%s %s - a signing tool for jar files\n", LONG_PROGRAM_NAME, VERSION);  PR_fprintf(outputFD, "\n");  PR_fprintf(outputFD, "Usage:  %s [options] directory-tree \n\n", PROGRAM_NAME);  PR_fprintf(outputFD, "    -b\"basename\"\t\tbasename of .sf, .rsa files for signing\n");  PR_fprintf(outputFD, "    -c#\t\t\t\tCompression level, 0-9, 0=none\n");  PR_fprintf(outputFD, "    -d\"certificate directory\"\tcontains cert*.db and key*.db\n");  PR_fprintf(outputFD, "    -e\".ext\"\t\t\tsign only files with this extension\n");  PR_fprintf(outputFD, "    -f\"filename\"\t\t\tread commands from file\n");  PR_fprintf(outputFD, "    -G\"nickname\"\t\tcreate object-signing cert with this nickname\n");  PR_fprintf(outputFD, "    -i\"installer script\"\tassign installer javascript\n");  PR_fprintf(outputFD, "    -j\"javascript directory\"\tsign javascript files in this subtree\n");  PR_fprintf(outputFD, "    -J\t\t\t\tdirectory contains HTML files. Javascript will\n"			"\t\t\t\tbe extracted and signed.\n");  PR_fprintf(outputFD, "    -k\"cert nickname\"\t\tsign with this certificate\n");  PR_fprintf(outputFD, "    --leavearc\t\t\tdo not delete .arc directories created\n"			"\t\t\t\tby -J option\n");  PR_fprintf(outputFD, "    -m\"metafile\"\t\tinclude custom meta-information\n");  PR_fprintf(outputFD, "    --norecurse\t\t\tdo not operate on subdirectories\n");  PR_fprintf(outputFD, "    -o\t\t\t\toptimize - omit optional headers\n");  PR_fprintf(outputFD, "    --outfile \"filename\"\tredirect output to file\n");  PR_fprintf(outputFD, "    -p\"password\"\t\tfor password on command line (insecure)\n");  PR_fprintf(outputFD, "    -s keysize\t\t\tkeysize in bits of generated cert\n");  PR_fprintf(outputFD, "    -t token\t\t\tname of token on which to generate cert\n");  PR_fprintf(outputFD, "    --verbosity #\t\tSet amount of debugging information to generate.\n"			"\t\t\t\tLower number means less output, 0 is default.\n");  PR_fprintf(outputFD, "    -x\"name\"\t\t\tdirectory or filename to exclude\n");  PR_fprintf(outputFD, "    -z\t\t\t\tomit signing time from signature\n");  PR_fprintf(outputFD, "    -Z\"jarfile\"\t\t\tcreate JAR file with the given name.\n"		  "\t\t\t\t(Default compression level is 6.)\n");  PR_fprintf(outputFD, "\n");  PR_fprintf(outputFD, "%s -l\n", PROGRAM_NAME);  PR_fprintf(outputFD, "  lists the signing certificates in your database\n");  PR_fprintf(outputFD, "\n");  PR_fprintf(outputFD, "%s -L\n", PROGRAM_NAME);  PR_fprintf(outputFD, "  lists all certificates in your database, marks object-signing certificates\n");  PR_fprintf(outputFD, "\n");  PR_fprintf(outputFD, "%s -M\n", PROGRAM_NAME);  PR_fprintf(outputFD, "  lists the PKCS #11 modules available to %s\n", PROGRAM_NAME);  PR_fprintf(outputFD, "\n");  PR_fprintf(outputFD, "%s -v file.jar\n", PROGRAM_NAME);  PR_fprintf(outputFD, "  show the contents of the specified jar file\n");  PR_fprintf(outputFD, "\n");  PR_fprintf(outputFD, "%s -w file.jar\n", PROGRAM_NAME);  PR_fprintf(outputFD, "  if valid, tries to tell you who signed the jar file\n");  PR_fprintf(outputFD, "\n");  PR_fprintf(outputFD, "For more details, visit\n");  PR_fprintf(outputFD, "  http://developer.netscape.com/library/documentation/signedobj/signtool/\n");  exit (0);}/* *  p r i n t _ e r r o r * *  For the undocumented -E function. If an older version *  of communicator gives you a numeric error, we can see what *  really happened without doing hex math. * */voidprint_error (int err){  PR_fprintf(errorFD, "Error %d: %s\n", err, JAR_get_error (err));	errorCount++;  give_help (err);}/* *  o u t _ o f _ m e m o r y * *  Out of memory, exit Signtool. *  */voidout_of_memory (void){  PR_fprintf(errorFD, "%s: out of memory\n", PROGRAM_NAME);	errorCount++;  exit (ERRX);}/* *  V e r i f y C e r t D i r * *  Validate that the specified directory *  contains a certificate database * */voidVerifyCertDir(char *dir, char *keyName){  char fn [FNSIZE];  sprintf (fn, "%s/cert7.db", dir);  if (PR_Access (fn, PR_ACCESS_EXISTS))    {    PR_fprintf(errorFD, "%s: No certificate database in \"%s\"\n", PROGRAM_NAME,		dir);    PR_fprintf(errorFD, "%s: Check the -d arguments that you gave\n",		PROGRAM_NAME);	errorCount++;    exit (ERRX);    }	if(verbosity >= 0) {		PR_fprintf(outputFD, "using certificate directory: %s\n", dir);	}  if (keyName == NULL)    return;  /* if the user gave the -k key argument, verify that      a key database already exists */  sprintf (fn, "%s/key3.db", dir);  if (PR_Access (fn, PR_ACCESS_EXISTS))    {    PR_fprintf(errorFD, "%s: No private key database in \"%s\"\n", PROGRAM_NAME,		dir);    PR_fprintf(errorFD, "%s: Check the -d arguments that you gave\n",		PROGRAM_NAME);	errorCount++;    exit (ERRX);    }}/* *  f o r e a c h  *  *  A recursive function to loop through all names in *  the specified directory, as well as all subdirectories. * *  FIX: Need to see if all platforms allow multiple *  opendir's to be called. * */intforeach(char *dirname, char *prefix,        int (*fn)(char *relpath, char *basedir, char *reldir, char *filename,		void* arg),		PRBool recurse, PRBool includeDirs, void *arg) {	char newdir [FNSIZE];	int retval = 0;	PRDir *dir;	PRDirEntry *entry;	strcpy (newdir, dirname);	if (*prefix) {		strcat (newdir, "/");		strcat (newdir, prefix);	}	dir = PR_OpenDir (newdir);	if (!dir) return -1;	for (entry = PR_ReadDir (dir,0); entry; entry = PR_ReadDir (dir,0)) {		if (*entry->name == '.' || *entry->name == '#')			continue;		/* can't sign self */		if (!strcmp (entry->name, "META-INF"))			continue;		/* -x option */		if (PL_HashTableLookup(excludeDirs, entry->name))			continue;		strcpy (newdir, dirname);		if (*dirname)			strcat (newdir, "/");		if (*prefix) {			strcat (newdir, prefix);			strcat (newdir, "/");		}		strcat (newdir, entry->name);		if(!is_dir(newdir) || includeDirs) {			char newpath [FNSIZE];			strcpy (newpath, prefix);			if (*newpath)				strcat (newpath, "/");			strcat (newpath, entry->name);			if( (*fn) (newpath, dirname, prefix, (char *) entry->name, arg)) {				retval = -1;				break;			}		}		if (is_dir (newdir)) {			if(recurse) {				char newprefix [FNSIZE];				strcpy (newprefix, prefix);				if (*newprefix) {					strcat (newprefix, "/");				}				strcat (newprefix, entry->name);				if(foreach (dirname, newprefix, fn, recurse, includeDirs,arg)) {					retval = -1;					break;				}			}		}	}	PR_CloseDir (dir);	return retval;}/* *  i s _ d i r * *  Return 1 if file is a directory. *  Wonder if this runs on a mac, trust not. * */static int is_dir (char *filename){	PRFileInfo	finfo;	if( PR_GetFileInfo(filename, &finfo) != PR_SUCCESS ) {		printf("Unable to get information about %s\n", filename);		return 0;	}	return ( finfo.type == PR_FILE_DIRECTORY );}/* *  p a s s w o r d _ h a r d c o d e  * *  A function to use the password passed in the -p(password) argument *  of the command line. This is only to be used for build & testing purposes, *  as it's extraordinarily insecure.  * *  After use once, null it out otherwise PKCS11 calls us forever. * */SECItem *password_hardcode(void *arg, SECKEYKeyDBHandle *handle){  SECItem *pw = NULL;  if (password) {    pw = SECITEM_AllocItem(NULL, NULL, PL_strlen(password));    pw->data = PL_strdup(password);    password = NULL;  }  return pw;}char *pk11_password_hardcode(PK11SlotInfo *slot, PRBool retry, void *arg){  char *pw;  pw = password ? PORT_Strdup (password) : NULL;  password = NULL;  return pw;}/************************************************************************ * * c e r t D B N a m e C a l l b a c k */static char *certDBNameCallback(void *arg, int dbVersion){    char *fnarg;    char *dir;

⌨️ 快捷键说明

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