jarver.c

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

C
2,030
字号
    /* Try the CN plus O */    cert_o = CERT_GetOrgName (&cert->subject);    cn_o_length = PORT_Strlen (cert_cn) + 3 + PORT_Strlen (cert_o) + 20;    cert_cn_o = (char*)PORT_ZAlloc (cn_o_length);    PR_snprintf (cert_cn_o, cn_o_length,            "%s's %s Certificate", cert_cn, cert_o);#ifdef USE_MOZ_THREAD    if (jar_moz_nickname (CERT_GetDefaultCertDB(), cert_cn_o) == NULL)#else    if (CERT_FindCertByNickname (CERT_GetDefaultCertDB(), cert_cn_o) == NULL)#endif      return cert_cn;    }  /* If all that failed, use the ugly nickname */  return cert->nickname ? PORT_Strdup (cert->nickname) : NULL;  }/* *  J A R _ c e r t _ h t m l  * *  Return an HTML representation of the certificate *  designated by the given fingerprint, in specified style. * *  JAR is optional, but supply it if you can in order *  to optimize. * */char *JAR_cert_html    (JAR *jar, int style, long keylen, void *key, int *result)  {  char *html;  CERTCertificate *cert;  *result = -1;  if (style != 0)    return NULL;  cert = jar_get_certificate (jar, keylen, key, result);  if (cert == NULL || *result < 0)    return NULL;  *result = 0;  html = CERT_HTMLCertInfo (cert, /* show images */ PR_TRUE,		/*show issuer*/PR_TRUE);  if (html == NULL)    *result = -1;  return html;  }/* *  J A R _ s t a s h _ c e r t * *  Stash the certificate pointed to by this *  fingerprint, in persistent storage somewhere. * */extern int PR_CALLBACK JAR_stash_cert    (JAR *jar, long keylen, void *key)  {  int result = 0;  char *nickname;  CERTCertTrust trust;  CERTCertDBHandle *certdb;  CERTCertificate *cert, *newcert;  cert = jar_get_certificate (jar, keylen, key, &result);  if (result < 0)    return result;  if (cert == NULL)    return JAR_ERR_GENERAL;  if ((certdb = JAR_open_database()) == NULL)    return JAR_ERR_GENERAL;  /* Attempt to give a name to the newish certificate */  nickname = jar_choose_nickname (cert);#ifdef USE_MOZ_THREAD  newcert = jar_moz_nickname (certdb, nickname);#else  newcert = CERT_FindCertByNickname (certdb, nickname);#endif  if (newcert && newcert->isperm)     {    /* already in permanant database */    return 0;    }  if (newcert) cert = newcert;  /* FIX, since FindCert returns a bogus dbhandle     set it ourselves */  cert->dbhandle = certdb;#if 0  nickname = cert->subjectName;  if (nickname)    {    /* Not checking for a conflict here. But this should       be a new cert or it would have been found earlier. */    nickname = jar_cert_element (nickname, "CN=", 1);    if (SEC_CertNicknameConflict (nickname, cert->dbhandle))      {      /* conflict */      nickname = PORT_Realloc (&nickname, PORT_Strlen (nickname) + 3);      /* Beyond one copy, there are probably serious problems          so we will stop at two rather than counting.. */      PORT_Strcat (nickname, " #2");      }    }#endif  if (nickname != NULL)    {    PORT_Memset ((void *) &trust, 0, sizeof(trust));#ifdef USE_MOZ_THREAD    if (jar_moz_perm (cert, nickname, &trust) != SECSuccess) #else    if (CERT_AddTempCertToPerm (cert, nickname, &trust) != SECSuccess) #endif      {      /* XXX might want to call PORT_GetError here */      result = JAR_ERR_GENERAL;      }    }  JAR_close_database (certdb);  return result;  }/* *  J A R _ f e t c h _ c e r t * *  Given an opaque identifier of a certificate,  *  return the full certificate. * * The new function, which retrieves by key. * */void *JAR_fetch_cert (long length, void *key)  {  SECItem seckey;  CERTCertificate *cert = NULL;  CERTCertDBHandle *certdb;  certdb = JAR_open_database();  if (certdb)    {    seckey.len = length;    seckey.data = (unsigned char*)key;#ifdef USE_MOZ_THREAD    cert = jar_moz_certkey (certdb, &seckey);#else    cert = CERT_FindCertByKey (certdb, &seckey);#endif    JAR_close_database (certdb);    }  return (void *) cert;  }/* *  j a r _ g e t _ m f _ d i g e s t * *  Retrieve a corresponding saved digest over a section *  of the main manifest file.  * */static JAR_Digest *jar_get_mf_digest (JAR *jar, char *pathname)  {  JAR_Item *it;  JAR_Digest *dig;  ZZLink *link;  ZZList *list;  list = jar->manifest;  if (ZZ_ListEmpty (list))    return NULL;  for (link = ZZ_ListHead (list);       !ZZ_ListIterDone (list, link);       link = link->next)    {    it = link->thing;    if (it->type == jarTypeSect           && it->pathname && !PORT_Strcmp (it->pathname, pathname))      {      dig = (JAR_Digest *) it->data;      return dig;      }    }  return NULL;  }/* *  j a r _ b a s e n a m e * *  Return the basename -- leading components of path stripped off, *  extension ripped off -- of a path. * */static char *jar_basename (const char *path)  {  char *pith, *e, *basename, *ext;  if (path == NULL)    return PORT_Strdup ("");  pith = PORT_Strdup (path);  basename = pith;  while (1)    {    for (e = basename; *e && *e != '/' && *e != '\\'; e++)      /* yip */ ;    if (*e)       basename = ++e;     else      break;    }  if ((ext = PORT_Strrchr (basename, '.')) != NULL)    *ext = 0;  /* We already have the space allocated */  PORT_Strcpy (pith, basename);  return pith;  }/* *  + + + + + + + + + + + + + + + * *  CRYPTO ROUTINES FOR JAR * *  The following functions are the cryptographic  *  interface to PKCS7 for Jarnatures. * *  + + + + + + + + + + + + + + + * *//* *  j a r _ c a t c h _ b y t e s * *  In the event signatures contain enveloped data, it will show up here. *  But note that the lib/pkcs7 routines aren't ready for it. * */static void jar_catch_bytes     (void *arg, const char *buf, unsigned long len)  {  /* Actually this should never be called, since there is     presumably no data in the signature itself. */  }/* *  j a r _ v a l i d a t e _ p k c s 7 * *  Validate (and decode, if necessary) a binary pkcs7 *  signature in DER format. * */static int jar_validate_pkcs7      (JAR *jar, JAR_Signer *signer, char *data, long length)  {  SECItem detdig;  SEC_PKCS7ContentInfo *cinfo;  SEC_PKCS7DecoderContext *dcx;  int status = 0;  char *errstring = NULL;  PORT_Assert( jar != NULL && signer != NULL );  if (jar == NULL || signer == NULL)    return JAR_ERR_ORDER;  signer->valid = JAR_ERR_SIG;  /* We need a context if we can get one */#ifdef MOZILLA_CLIENT_OLD  if (jar->mw == NULL) {    JAR_set_context (jar, NULL);  }#endif  dcx = SEC_PKCS7DecoderStart           (jar_catch_bytes, NULL /*cb_arg*/, NULL /*getpassword*/, jar->mw,            NULL, NULL, NULL);  if (dcx != NULL)     {    SEC_PKCS7DecoderUpdate (dcx, data, length);    cinfo = SEC_PKCS7DecoderFinish (dcx);    }  if (cinfo == NULL)    {    /* strange pkcs7 failure */    return JAR_ERR_PK7;    }  if (SEC_PKCS7ContentIsEncrypted (cinfo))    {    /* content was encrypted, fail */    return JAR_ERR_PK7;    }  if (SEC_PKCS7ContentIsSigned (cinfo) == PR_FALSE)    {    /* content was not signed, fail */    return JAR_ERR_PK7;    }  PORT_SetError (0);  /* use SHA1 only */  detdig.len = SHA1_LENGTH;  detdig.data = signer->digest->sha1;#ifdef USE_MOZ_THREAD  if (jar_moz_verify        (cinfo, certUsageObjectSigner, &detdig, HASH_AlgSHA1, PR_FALSE)==		SECSuccess)#else  if (SEC_PKCS7VerifyDetachedSignature         (cinfo, certUsageObjectSigner, &detdig, HASH_AlgSHA1, PR_FALSE)==		PR_TRUE)#endif    {    /* signature is valid */    signer->valid = 0;    jar_gather_signers (jar, signer, cinfo);    }  else    {    status = PORT_GetError();    PORT_Assert( status < 0 );    if (status >= 0) status = JAR_ERR_SIG;    jar->valid = status;    signer->valid = status;    errstring = JAR_get_error (status);    /*XP_TRACE(("JAR signature invalid (reason %d = %s)", status, errstring));*/    }  jar->pkcs7 = PR_TRUE;  signer->pkcs7 = PR_TRUE;  SEC_PKCS7DestroyContentInfo (cinfo);  return status;  }/* *  j a r _ g a t h e r _ s i g n e r s * *  Add the single signer of this signature to the *  certificate linked list. * */static int jar_gather_signers     (JAR *jar, JAR_Signer *signer, SEC_PKCS7ContentInfo *cinfo)  {  int result;  CERTCertificate *cert;  CERTCertDBHandle *certdb;  SEC_PKCS7SignedData *sdp;  SEC_PKCS7SignerInfo **pksigners, *pksigner;  sdp = cinfo->content.signedData;  if (sdp == NULL)    return JAR_ERR_PK7;  pksigners = sdp->signerInfos;  /* permit exactly one signer */  if (pksigners == NULL || pksigners [0] == NULL || pksigners [1] != NULL)    return JAR_ERR_PK7;  pksigner = *pksigners;  cert = pksigner->cert;  if (cert == NULL)    return JAR_ERR_PK7;  certdb = JAR_open_database();  if (certdb == NULL)    return JAR_ERR_GENERAL;  result = jar_add_cert (jar, signer, jarTypeSign, cert);  JAR_close_database (certdb);  return result;  }/* *  j a r _ o p e n _ d a t a b a s e * *  Open the certificate database, *  for use by JAR functions. * */CERTCertDBHandle *JAR_open_database (void)  {  int keepcerts = 0;  CERTCertDBHandle *certdb;  /* local_certdb will only be used if calling from a command line tool */  static CERTCertDBHandle local_certdb;  certdb = CERT_GetDefaultCertDB();  if (certdb == NULL)     {    if (CERT_OpenCertDBFilename (&local_certdb, NULL, (PRBool)!keepcerts) != 	                                                           SECSuccess)      {      return NULL;      }    certdb = &local_certdb;    }  return certdb;  }/* *  j a r _ c l o s e _ d a t a b a s e * *  Close the certificate database. *  For use by JAR functions. * */int JAR_close_database (CERTCertDBHandle *certdb)  {  CERTCertDBHandle *defaultdb;  /* This really just retrieves the handle, nothing more */  defaultdb = CERT_GetDefaultCertDB();  /* If there is no default db, it means we opened      the permanent database for some reason */  if (defaultdb == NULL && certdb != NULL)    CERT_ClosePermCertDB (certdb);  return 0;  }/* *  j a r _ g e t _ c e r t i f i c a t e * *  Return the certificate referenced *  by a given fingerprint, or NULL if not found. *  Error code is returned in result. * */static CERTCertificate *jar_get_certificate      (JAR *jar, long keylen, void *key, int *result)  {  int found = 0;  JAR_Item *it;  JAR_Cert *fing;  JAR_Context *ctx;  if (jar == NULL)     {    void *cert;    cert = JAR_fetch_cert (keylen, key);    *result = (cert == NULL) ? JAR_ERR_GENERAL : 0;    return (CERTCertificate *) cert;    }  ctx = JAR_find (jar, NULL, jarTypeSign);  while (JAR_find_next (ctx, &it) >= 0)    {    fing = (JAR_Cert *) it->data;    if (keylen != fing->length)      continue;    PORT_Assert( keylen < 0xFFFF );    if (!PORT_Memcmp (fing->key, key, keylen))      {      found = 1;      break;      }    }  JAR_find_end (ctx);  if (found == 0)    {    *result = JAR_ERR_GENERAL;    return NULL;    }  *result = 0;  return fing->cert;  }/* *  j a r _ s i g n a l * *  Nonfatal errors come here to callback Java. *   */static int jar_signal      (int status, JAR *jar, const char *metafile, char *pathname)  {  char *errstring;  errstring = JAR_get_error (status);  if (jar->signal)    {    (*jar->signal) (status, jar, metafile, pathname, errstring);    return 0;    }  return status;  }/* *  j a r _ a p p e n d * *  Tack on an element to one of a JAR's linked *  lists, with rudimentary error handling. * */int jar_append (ZZList *list, int type,         char *pathname, void *data, size_t size)  {  JAR_Item *it;  ZZLink *entity;  it = (JAR_Item*)PORT_ZAlloc (sizeof (JAR_Item));  if (it == NULL)    goto loser;  if (pathname)    {    it->pathname = PORT_Strdup (pathname);    if (it->pathname == NULL)      goto loser;    }  it->type = (jarType)type;  it->data = (unsigned char *) data;  it->size = size;  entity = ZZ_NewLink (it);  if (entity)    {    ZZ_AppendLink (list, entity);    return 0;    }loser:  if (it)    {    if (it->pathname) PORT_Free (it->pathname);    PORT_Free (it);    }  return JAR_ERR_MEMORY;  }/*  *  W I N 1 6   s t u f f * *  These functions possibly belong in xp_mem.c, they operate  *  on huge string pointers for win16. * */#if defined(XP_WIN16)int xp_HUGE_STRNCASECMP (char ZHUGEP *buf, char *key, int len)  {  while (len--)     {    char c1, c2;    c1 = *buf++;    c2 = *key++;    if (c1 >= 'a' && c1 <= 'z') c1 -= ('a' - 'A');    if (c2 >= 'a' && c2 <= 'z') c2 -= ('a' - 'A');    if (c1 != c2)       return (c1 < c2) ? -1 : 1;    }  return 0;  }size_t xp_HUGE_STRLEN (char ZHUGEP *s)  {  size_t len = 0L;  while (*s++) len++;  return len;  }char *xp_HUGE_STRCPY (char *to, char ZHUGEP *from)  {  char *ret = to;  while (*from)    *to++ = *from++;  *to = 0;  return ret;  }#endif

⌨️ 快捷键说明

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