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 + -
显示快捷键?