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