sign.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 862 行 · 第 1/2 页
C
862 行
JAR_Digest dig; char fullname [FNSIZE]; if(verbosity >= 0) { PR_fprintf(outputFD, "--> %s\n", relpath); } /* extension matching */ if(extensionsGiven) { char *ext; ext = PL_strrchr(relpath, '.'); if(!ext) { return 0; } else { if(!PL_HashTableLookup(extensions, ext)) { return 0; } } } sprintf (fullname, "%s/%s", basedir, relpath); fprintf (mf, "\n"); use_js = 0; if (scriptdir && !PORT_Strcmp (scriptdir, reldir)) use_js++; /* sign non-.js files inside .arc directories using the javascript magic */ if ( (PL_strcaserstr(filename, ".js") != filename + strlen(filename) - 3) && (PL_strcaserstr(reldir, ".arc") == reldir + strlen(filename)-4)) use_js++; if (use_js) { fprintf (mf, "Name: %s\n", filename); fprintf (mf, "Magic: javascript\n"); if (optimize == 0) fprintf (mf, "javascript.id: %s\n", filename); if (metafile) add_meta (mf, filename); } else { fprintf (mf, "Name: %s\n", relpath); if (metafile) add_meta (mf, relpath); } JAR_digest_file (fullname, &dig); if (optimize == 0) { fprintf (mf, "Digest-Algorithms: MD5 SHA1\n"); fprintf (mf, "MD5-Digest: %s\n", BTOA_DataToAscii (dig.md5, MD5_LENGTH)); } fprintf (mf, "SHA1-Digest: %s\n", BTOA_DataToAscii (dig.sha1, SHA1_LENGTH)); if(!use_js) { JzipAdd(fullname, relpath, zipfile, compression_level); } return 0;}/* * a d d _ m e t a * * Parse the metainfo file, and add any details * necessary to the manifest file. In most cases you * should be using the -i option (ie, for SmartUpdate). * */static int add_meta (FILE *fp, char *name){ FILE *met; char buf [BUFSIZ]; int place; char *pattern, *meta; int num = 0; if ((met = fopen (metafile, "r")) != NULL) { while (fgets (buf, BUFSIZ, met)) { char *s; for (s = buf; *s && *s != '\n' && *s != '\r'; s++); *s = 0; if (*buf == 0) continue; pattern = buf; /* skip to whitespace */ for (s = buf; *s && *s != ' ' && *s != '\t'; s++); /* terminate pattern */ if (*s == ' ' || *s == '\t') *s++ = 0; /* eat through whitespace */ while (*s == ' ' || *s == '\t') s++; meta = s; /* this will eventually be regexp matching */ place = 0; if (!PORT_Strcmp (pattern, name)) place = 1; if (place) { num++; if(verbosity >= 0) { PR_fprintf(outputFD, "[%s] %s\n", name, meta); } fprintf (fp, "%s\n", meta); } } fclose (met); } else { PR_fprintf(errorFD, "%s: can't open metafile: %s\n", PROGRAM_NAME, metafile); errorCount++; exit (ERRX); } return num;}/********************************************************************** * * S i g n F i l e */static intSignFile (FILE *outFile, FILE *inFile, CERTCertificate *cert){ int nb; char ibuf[4096], digestdata[32]; SECHashObject *hashObj; void *hashcx; unsigned int len; SECItem digest; SEC_PKCS7ContentInfo *cinfo; SECStatus rv; if (outFile == NULL || inFile == NULL || cert == NULL) return -1; /* XXX probably want to extend interface to allow other hash algorithms */ hashObj = &SECHashObjects[HASH_AlgSHA1]; hashcx = (* hashObj->create)(); if (hashcx == NULL) return -1; (* hashObj->begin)(hashcx); for (;;) { if (feof(inFile)) break; nb = fread(ibuf, 1, sizeof(ibuf), inFile); if (nb == 0) { if (ferror(inFile)) { PORT_SetError(SEC_ERROR_IO); (* hashObj->destroy)(hashcx, PR_TRUE); return -1; } /* eof */ break; } (* hashObj->update)(hashcx, (unsigned char *) ibuf, nb); } (* hashObj->end)(hashcx, (unsigned char *) digestdata, &len, 32); (* hashObj->destroy)(hashcx, PR_TRUE); digest.data = (unsigned char *) digestdata; digest.len = len; cinfo = SEC_PKCS7CreateSignedData (cert, certUsageObjectSigner, NULL, SEC_OID_SHA1, &digest, NULL, NULL); if (cinfo == NULL) return -1; rv = SEC_PKCS7IncludeCertChain (cinfo, NULL); if (rv != SECSuccess) { SEC_PKCS7DestroyContentInfo (cinfo); return -1; } if (no_time == 0) { rv = SEC_PKCS7AddSigningTime (cinfo); if (rv != SECSuccess) { /* don't check error */ } } if(password) { rv = SEC_PKCS7Encode(cinfo, SignOut, outFile, NULL, password_hardcode, NULL); } else { rv = SEC_PKCS7Encode(cinfo, SignOut, outFile, NULL, SECU_GetPassword, NULL); } SEC_PKCS7DestroyContentInfo (cinfo); if (rv != SECSuccess) return -1; return 0;}/* * g e n e r a t e _ S F _ f i l e * * From the supplied manifest file, calculates * digests on the various sections, creating a .SF * file in the process. * */static int generate_SF_file (char *manifile, char *who){ FILE *sf; FILE *mf; long r1, r2, r3; char whofile [FNSIZE]; char *buf, *name; JAR_Digest dig; int line = 0; strcpy (whofile, who); if ((mf = fopen (manifile, "rb")) == NULL) { perror (manifile); exit (ERRX); } if ((sf = fopen (whofile, "wb")) == NULL) { perror (who); exit (ERRX); } buf = (char *) PORT_ZAlloc (BUFSIZ); if (buf) name = (char *) PORT_ZAlloc (BUFSIZ); if (buf == NULL || name == NULL) out_of_memory(); fprintf (sf, "Signature-Version: 1.0\n"); fprintf (sf, "Created-By: %s\n", CREATOR); fprintf (sf, "Comments: %s\n", BREAKAGE); if (fgets (buf, BUFSIZ, mf) == NULL) { PR_fprintf(errorFD, "%s: empty manifest file!\n", PROGRAM_NAME); errorCount++; exit (ERRX); } if (strncmp (buf, "Manifest-Version:", 17)) { PR_fprintf(errorFD, "%s: not a manifest file!\n", PROGRAM_NAME); errorCount++; exit (ERRX); } fseek (mf, 0L, SEEK_SET); /* Process blocks of headers, and calculate their hashen */ while (1) { /* Beginning range */ r1 = ftell (mf); if (fgets (name, BUFSIZ, mf) == NULL) break; line++; if (r1 != 0 && strncmp (name, "Name:", 5)) { PR_fprintf(errorFD, "warning: unexpected input in manifest file \"%s\" at line %d:\n", manifile, line); PR_fprintf(errorFD, "%s\n", name); warningCount++; } while (fgets (buf, BUFSIZ, mf)) { if (*buf == 0 || *buf == '\n' || *buf == '\r') break; line++; /* Ending range for hashing */ r2 = ftell (mf); } r3 = ftell (mf); if (r1) { fprintf (sf, "\n"); fprintf (sf, "%s", name); } calculate_MD5_range (mf, r1, r2, &dig); if (optimize == 0) { fprintf (sf, "Digest-Algorithms: MD5 SHA1\n"); fprintf (sf, "MD5-Digest: %s\n", BTOA_DataToAscii (dig.md5, MD5_LENGTH)); } fprintf (sf, "SHA1-Digest: %s\n", BTOA_DataToAscii (dig.sha1, SHA1_LENGTH)); /* restore normalcy after changing offset position */ fseek (mf, r3, SEEK_SET); } PORT_Free (buf); PORT_Free (name); fclose (sf); fclose (mf); return 0;}/* * c a l c u l a t e _ M D 5 _ r a n g e * * Calculate the MD5 digest on a range of bytes in * the specified fopen'd file. Returns base64. * */static intcalculate_MD5_range (FILE *fp, long r1, long r2, JAR_Digest *dig){ int num; int range; unsigned char *buf; MD5Context *md5 = 0; SHA1Context *sha1 = 0; unsigned int sha1_length, md5_length; range = r2 - r1; /* position to the beginning of range */ fseek (fp, r1, SEEK_SET); buf = (unsigned char *) PORT_ZAlloc (range); if (buf == NULL) out_of_memory(); if ((num = fread (buf, 1, range, fp)) != range) { PR_fprintf(errorFD, "%s: expected %d bytes, got %d\n", PROGRAM_NAME, range, num); errorCount++; exit (ERRX); } md5 = MD5_NewContext(); sha1 = SHA1_NewContext(); if (md5 == NULL || sha1 == NULL) { PR_fprintf(errorFD, "%s: can't generate digest context\n", PROGRAM_NAME); errorCount++; exit (ERRX); } MD5_Begin (md5); SHA1_Begin (sha1); MD5_Update (md5, buf, range); SHA1_Update (sha1, buf, range); MD5_End (md5, dig->md5, &md5_length, MD5_LENGTH); SHA1_End (sha1, dig->sha1, &sha1_length, SHA1_LENGTH); MD5_DestroyContext (md5, PR_TRUE); SHA1_DestroyContext (sha1, PR_TRUE); PORT_Free (buf); return 0;}static void SignOut (void *arg, const char *buf, unsigned long len){ fwrite (buf, len, 1, (FILE *) arg);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?