Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
jarver.c File Reference
#include "jar.h"
#include "jarint.h"
#include "jarevil.h"
#include "secder.h"

Go to the source code of this file.

Defines

#define USE_MOZ_THREAD
#define xp_HUGE_MEMCPY   PORT_Memcpy
#define xp_HUGE_STRCPY   PORT_Strcpy
#define xp_HUGE_STRLEN   PORT_Strlen
#define xp_HUGE_STRNCASECMP   PORT_Strncasecmp
#define CERTDB_USER   (1<<6)
#define SZ   512
#define SEP   " <br> "
#define SEPLEN   (PORT_Strlen(SEP))

Functions

static int jar_validate_pkcs7 (JAR *jar, JAR_Signer *signer, char *data, long length)
static void jar_catch_bytes (void *arg, const char *buf, unsigned long len)
static int jar_gather_signers (JAR *jar, JAR_Signer *signer, SEC_PKCS7ContentInfo *cinfo)
static char ZHUGEPjar_eat_line (int lines, int eating, char ZHUGEP *data, long *len)
static JAR_Digestjar_digest_section (char ZHUGEP *manifest, long length)
static JAR_Digestjar_get_mf_digest (JAR *jar, char *path)
static int jar_parse_digital_signature (char *raw_manifest, JAR_Signer *signer, long length, JAR *jar)
static int jar_add_cert (JAR *jar, JAR_Signer *signer, int type, CERTCertificate *cert)
static CERTCertificate * jar_get_certificate (JAR *jar, long keylen, void *key, int *result)
static char * jar_cert_element (char *name, char *tag, int occ)
static char * jar_choose_nickname (CERTCertificate *cert)
static char * jar_basename (const char *path)
static int jar_signal (int status, JAR *jar, const char *metafile, char *pathname)
int jar_parse_mf (JAR *jar, char ZHUGEP *raw_manifest, long length, const char *path, const char *url)
int jar_parse_sf (JAR *jar, char ZHUGEP *raw_manifest, long length, const char *path, const char *url)
int jar_parse_sig (JAR *jar, const char *path, char ZHUGEP *raw_manifest, long length)
int jar_parse_any (JAR *jar, int type, JAR_Signer *signer, char ZHUGEP *raw_manifest, long length, const char *path, const char *url)
static int jar_internal_digest (JAR *jar, const char *path, char *x_name, JAR_Digest *dig)
int JAR_parse_manifest (JAR *jar, char ZHUGEP *raw_manifest, long length, const char *path, const char *url)
int PR_CALLBACK JAR_verify_digest (JAR *jar, const char *name, JAR_Digest *dig)
int PR_CALLBACK JAR_cert_attribute (JAR *jar, jarCert attrib, long keylen, void *key, void **result, unsigned long *length)
char * JAR_cert_html (JAR *jar, int style, long keylen, void *key, int *result)
int PR_CALLBACK JAR_stash_cert (JAR *jar, long keylen, void *key)
voidJAR_fetch_cert (long length, void *key)
CERTCertDBHandle * JAR_open_database (void)
int JAR_close_database (CERTCertDBHandle *certdb)
int jar_append (ZZList *list, int type, char *pathname, void *data, size_t size)

Define Documentation

#define CERTDB_USER   (1<<6)

Definition at line 69 of file jarver.c.

#define SEP   " <br> "
#define SZ   512

Definition at line 71 of file jarver.c.

Definition at line 43 of file jarver.c.

Definition at line 57 of file jarver.c.

Definition at line 58 of file jarver.c.

Definition at line 59 of file jarver.c.

Definition at line 60 of file jarver.c.


Function Documentation

static int jar_add_cert ( JAR jar,
JAR_Signer signer,
int  type,
CERTCertificate *  cert 
) [static]

Definition at line 843 of file jarver.c.

  {
  JAR_Cert *fing;
  unsigned char *keyData;

  if (cert == NULL)
    return JAR_ERR_ORDER;

  fing = (JAR_Cert*)PORT_ZAlloc (sizeof (JAR_Cert));

  if (fing == NULL)
    goto loser;

#ifdef USE_MOZ_THREAD
  fing->cert = jar_moz_dup (cert);
#else
  fing->cert = CERT_DupCertificate (cert);
#endif

  /* get the certkey */

  fing->length = cert->derIssuer.len + 2 + cert->serialNumber.len;

  keyData = (unsigned char *) PORT_ZAlloc (fing->length);
  fing->key = keyData;

  if (fing->key == NULL)
    goto loser;
  keyData[0] = ((cert->derIssuer.len) >> 8) & 0xff;
  keyData[1] = ((cert->derIssuer.len) & 0xff);
  PORT_Memcpy (&keyData[2], cert->derIssuer.data, cert->derIssuer.len);
  PORT_Memcpy (&keyData[2+cert->derIssuer.len], cert->serialNumber.data,
                                           cert->serialNumber.len);

  ADDITEM (signer->certs, type, 
    /* pathname */ NULL, fing, sizeof (JAR_Cert));

  return 0;

loser:

  if (fing)
    {
    if (fing->cert) 
      CERT_DestroyCertificate (fing->cert);

    PORT_Free (fing);
    }

  return JAR_ERR_MEMORY;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

int jar_append ( ZZList *  list,
int  type,
char *  pathname,
void data,
size_t  size 
)

Definition at line 1938 of file jarver.c.

  {
  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;
  }

Here is the call graph for this function:

static char * jar_basename ( const char *  path) [static]

Definition at line 1592 of file jarver.c.

  {
  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;
  }

Here is the call graph for this function:

static void jar_catch_bytes ( void arg,
const char *  buf,
unsigned long  len 
) [static]

Definition at line 1643 of file jarver.c.

  {
  /* Actually this should never be called, since there is
     presumably no data in the signature itself. */
  }

Here is the caller graph for this function:

int PR_CALLBACK JAR_cert_attribute ( JAR jar,
jarCert  attrib,
long  keylen,
void key,
void **  result,
unsigned long length 
)

Definition at line 1060 of file jarver.c.

  {
  int status = 0;
  char *ret = NULL;

  CERTCertificate *cert;

  CERTCertDBHandle *certdb;

  JAR_Digest *dig;
  SECItem hexme;

  *length = 0;

  if (attrib == 0 || key == 0)
    return JAR_ERR_GENERAL;

  if (attrib == jarCertJavaHack)
    {
    cert = (CERTCertificate *) NULL;
    certdb = JAR_open_database();

    if (certdb)
      {
#ifdef USE_MOZ_THREAD
      cert = jar_moz_nickname (certdb, (char*)key);
#else
      cert = CERT_FindCertByNickname (certdb, key);
#endif

      if (cert)
        {
        *length = cert->certKey.len;

        *result = (void *) PORT_ZAlloc (*length);

        if (*result)
          PORT_Memcpy (*result, cert->certKey.data, *length);
        else
          return JAR_ERR_MEMORY;
        }
      JAR_close_database (certdb);
      }

    return cert ? 0 : JAR_ERR_GENERAL;
    }

  if (jar && jar->pkcs7 == 0)
    return JAR_ERR_GENERAL;

  cert = jar_get_certificate (jar, keylen, key, &status);

  if (cert == NULL || status < 0)
    return JAR_ERR_GENERAL;

#define SEP " <br> "
#define SEPLEN (PORT_Strlen(SEP))

  switch (attrib)
    {
    case jarCertCompany:

      ret = cert->subjectName;

      /* This is pretty ugly looking but only used
         here for this one purpose. */

      if (ret)
        {
        int retlen = 0;

        char *cer_ou1, *cer_ou2, *cer_ou3;
       char *cer_cn, *cer_e, *cer_o, *cer_l;

       cer_cn  = CERT_GetCommonName (&cert->subject);
        cer_e   = CERT_GetCertEmailAddress (&cert->subject);
        cer_ou3 = jar_cert_element (ret, "OU=", 3);
        cer_ou2 = jar_cert_element (ret, "OU=", 2);
        cer_ou1 = jar_cert_element (ret, "OU=", 1);
        cer_o   = CERT_GetOrgName (&cert->subject);
        cer_l   = CERT_GetCountryName (&cert->subject);

        if (cer_cn)  retlen += SEPLEN + PORT_Strlen (cer_cn);
        if (cer_e)   retlen += SEPLEN + PORT_Strlen (cer_e);
        if (cer_ou1) retlen += SEPLEN + PORT_Strlen (cer_ou1);
        if (cer_ou2) retlen += SEPLEN + PORT_Strlen (cer_ou2);
        if (cer_ou3) retlen += SEPLEN + PORT_Strlen (cer_ou3);
        if (cer_o)   retlen += SEPLEN + PORT_Strlen (cer_o);
        if (cer_l)   retlen += SEPLEN + PORT_Strlen (cer_l);

        ret = (char *) PORT_ZAlloc (1 + retlen);

        if (cer_cn)  { PORT_Strcpy (ret, cer_cn);  PORT_Strcat (ret, SEP); }
        if (cer_e)   { PORT_Strcat (ret, cer_e);   PORT_Strcat (ret, SEP); }
        if (cer_ou1) { PORT_Strcat (ret, cer_ou1); PORT_Strcat (ret, SEP); }
        if (cer_ou2) { PORT_Strcat (ret, cer_ou2); PORT_Strcat (ret, SEP); }
        if (cer_ou3) { PORT_Strcat (ret, cer_ou3); PORT_Strcat (ret, SEP); }
        if (cer_o)   { PORT_Strcat (ret, cer_o);   PORT_Strcat (ret, SEP); }
        if (cer_l)     PORT_Strcat (ret, cer_l);

       /* return here to avoid unsightly memory leak */

        *result = ret;
        *length = PORT_Strlen (ret);

        return 0;
        }
      break;

    case jarCertCA:

      ret = cert->issuerName;

      if (ret)
        {
        int retlen = 0;

        char *cer_ou1, *cer_ou2, *cer_ou3;
       char *cer_cn, *cer_e, *cer_o, *cer_l;

        /* This is pretty ugly looking but only used
           here for this one purpose. */

       cer_cn  = CERT_GetCommonName (&cert->issuer);
        cer_e   = CERT_GetCertEmailAddress (&cert->issuer);
        cer_ou3 = jar_cert_element (ret, "OU=", 3);
        cer_ou2 = jar_cert_element (ret, "OU=", 2);
        cer_ou1 = jar_cert_element (ret, "OU=", 1);
        cer_o   = CERT_GetOrgName (&cert->issuer);
        cer_l   = CERT_GetCountryName (&cert->issuer);

        if (cer_cn)  retlen += SEPLEN + PORT_Strlen (cer_cn);
        if (cer_e)   retlen += SEPLEN + PORT_Strlen (cer_e);
        if (cer_ou1) retlen += SEPLEN + PORT_Strlen (cer_ou1);
        if (cer_ou2) retlen += SEPLEN + PORT_Strlen (cer_ou2);
        if (cer_ou3) retlen += SEPLEN + PORT_Strlen (cer_ou3);
        if (cer_o)   retlen += SEPLEN + PORT_Strlen (cer_o);
        if (cer_l)   retlen += SEPLEN + PORT_Strlen (cer_l);

        ret = (char *) PORT_ZAlloc (1 + retlen);

        if (cer_cn)  { PORT_Strcpy (ret, cer_cn);  PORT_Strcat (ret, SEP); }
        if (cer_e)   { PORT_Strcat (ret, cer_e);   PORT_Strcat (ret, SEP); }
        if (cer_ou1) { PORT_Strcat (ret, cer_ou1); PORT_Strcat (ret, SEP); }
        if (cer_ou2) { PORT_Strcat (ret, cer_ou2); PORT_Strcat (ret, SEP); }
        if (cer_ou3) { PORT_Strcat (ret, cer_ou3); PORT_Strcat (ret, SEP); }
        if (cer_o)   { PORT_Strcat (ret, cer_o);   PORT_Strcat (ret, SEP); }
        if (cer_l)     PORT_Strcat (ret, cer_l);

       /* return here to avoid unsightly memory leak */

        *result = ret;
        *length = PORT_Strlen (ret);

        return 0;
        }

      break;

    case jarCertSerial:

      ret = CERT_Hexify (&cert->serialNumber, 1);
      break;

    case jarCertExpires:

      ret = DER_UTCDayToAscii (&cert->validity.notAfter);
      break;

    case jarCertNickname:

      ret = jar_choose_nickname (cert);
      break;

    case jarCertFinger:

      dig = JAR_calculate_digest 
         ((char *) cert->derCert.data, cert->derCert.len);

      if (dig)
        {
        hexme.len = sizeof (dig->md5);
        hexme.data = dig->md5;
        ret = CERT_Hexify (&hexme, 1);
        }
      break;

    default:

      return JAR_ERR_GENERAL;
    }

  *result = ret ? PORT_Strdup (ret) : NULL;
  *length = ret ? PORT_Strlen (ret) : 0;

  return 0;
  }

Here is the call graph for this function:

static char * jar_cert_element ( char *  name,
char *  tag,
int  occ 
) [static]

Definition at line 1268 of file jarver.c.

  {
  if (name && tag)
    {
    char *s;
    int found = 0;

    while (occ--)
      {
      if (PORT_Strstr (name, tag))
        {
        name = PORT_Strstr (name, tag) + PORT_Strlen (tag);
        found = 1;
        }
      else
        {
        name = PORT_Strstr (name, "=");
        if (name == NULL) return NULL;
        found = 0;
        }
      }

    if (!found) return NULL;

    /* must mangle only the copy */
    name = PORT_Strdup (name);

    /* advance to next equal */
    for (s = name; *s && *s != '='; s++)
      /* yip */ ;

    /* back up to previous comma */
    while (s > name && *s != ',') s--;

    /* zap the whitespace and return */
    *s = 0;
    }

  return name;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

char* JAR_cert_html ( JAR jar,
int  style,
long  keylen,
void key,
int result 
)

Definition at line 1381 of file jarver.c.

  {
#ifdef notdef
  char *html;
#endif
  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 = -1;

   return NULL;

#ifdef notdef
  html = CERT_HTMLCertInfo (cert, /* show images */ PR_TRUE,
              /*show issuer*/PR_TRUE);

  if (html == NULL)
    *result = -1;

  return html;
#endif
  }

Here is the call graph for this function:

static char * jar_choose_nickname ( CERTCertificate *  cert) [static]

Definition at line 1319 of file jarver.c.

  {
  char *cert_cn;
  char *cert_o;
  char *cert_cn_o;

  int cn_o_length;

  /* is the existing name ok */

  if (cert->nickname && PORT_Strncmp (cert->nickname, "tmpcert", 7))
    return PORT_Strdup (cert->nickname);

  /* we have an ugly name here people */

  /* Try the CN */
  cert_cn = CERT_GetCommonName (&cert->subject);

  if (cert_cn)
    {
    /* check for duplicate nickname */

#ifdef USE_MOZ_THREAD
    if (jar_moz_nickname (CERT_GetDefaultCertDB(), cert_cn) == NULL)
#else
    if (CERT_FindCertByNickname (CERT_GetDefaultCertDB(), cert_cn) == NULL)
#endif
      return cert_cn;

    /* 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;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

int JAR_close_database ( CERTCertDBHandle *  certdb)

Definition at line 1832 of file jarver.c.

  {
#ifdef notdef
  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);
#endif

  return 0;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

static JAR_Digest * jar_digest_section ( char ZHUGEP manifest,
long  length 
) [static]

Definition at line 964 of file jarver.c.

  {
  long global_len;
  char ZHUGEP *global_end;

  global_end = manifest;
  global_len = length;

  while (global_len)
    {
    global_end = jar_eat_line (1, PR_FALSE, global_end, &global_len);
    if (*global_end == 0 || *global_end == '\n')
      break;
    }

  return JAR_calculate_digest (manifest, global_end - manifest);
  }

Here is the call graph for this function:

static char ZHUGEP * jar_eat_line ( int  lines,
int  eating,
char ZHUGEP data,
long len 
) [static]

Definition at line 905 of file jarver.c.

  {
  char ZHUGEP *ret;

  ret = data;
  if (!*len) return ret;

  /* Eat the requisite number of lines, if any; 
     prior to terminating the current line with a 0. */

  for (/* yip */ ; lines; lines--)
    {
    while (*data && *data != '\n')
      data++;

    /* After the CR, ok to eat one LF */

    if (*data == '\n')
      data++;

    /* If there are zeros, we put them there */

    while (*data == 0 && data - ret < *len)
      data++;
    }

  *len -= data - ret;
  ret = data;

  if (eating)
    {
    /* Terminate this line with a 0 */ 

    while (*data && *data != '\n' && *data != '\r')
      data++;

    /* In any case we are allowed to eat CR */

    if (*data == '\r')
      *data++ = 0;

    /* After the CR, ok to eat one LF */

    if (*data == '\n')
      *data++ = 0;
    }

  return ret;
  }

Here is the caller graph for this function:

void* JAR_fetch_cert ( long  length,
void key 
)

Definition at line 1517 of file jarver.c.

  {
  CERTIssuerAndSN issuerSN;
  CERTCertificate *cert = NULL;

  CERTCertDBHandle *certdb;

  certdb = JAR_open_database();

  if (certdb)
    {
    unsigned char *keyData = (unsigned char *)key;
    issuerSN.derIssuer.len = (keyData[0] << 8) + keyData[0];
    issuerSN.derIssuer.data = &keyData[2];
    issuerSN.serialNumber.len = length - (2 + issuerSN.derIssuer.len);
    issuerSN.serialNumber.data = &keyData[2+issuerSN.derIssuer.len];

#ifdef USE_MOZ_THREAD
    cert = jar_moz_certkey (certdb, &issuerSN);
#else
    cert = CERT_FindCertByIssuerAndSN (certdb, &issuerSN);
#endif

    JAR_close_database (certdb);
    }

  return (void *) cert;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

static int jar_gather_signers ( JAR jar,
JAR_Signer signer,
SEC_PKCS7ContentInfo *  cinfo 
) [static]

Definition at line 1767 of file jarver.c.

  {
  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;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

static CERTCertificate * jar_get_certificate ( JAR jar,
long  keylen,
void key,
int result 
) [static]

Definition at line 1860 of file jarver.c.

  {
  int found = 0;

  JAR_Item *it;
  JAR_Cert *fing = NULL;

  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;
    }

  PORT_Assert(fing != NULL);
  *result = 0;
  return fing->cert;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

static JAR_Digest * jar_get_mf_digest ( JAR jar,
char *  path 
) [static]

Definition at line 1554 of file jarver.c.

  {
  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;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

static int jar_internal_digest ( JAR jar,
const char *  path,
char *  x_name,
JAR_Digest dig 
) [static]

Definition at line 722 of file jarver.c.

  {
  int cv;
  int status;

  JAR_Digest *savdig;

  savdig = jar_get_mf_digest (jar, x_name);

  if (savdig == NULL)
    {
    /* no .mf digest for this pathname */
    status = jar_signal (JAR_ERR_ENTRY, jar, path, x_name);
    if (status < 0) 
      return 0; /* was continue; */
    else 
      return status;
    }

  /* check for md5 consistency */
  if (dig->md5_status)
    {
    cv = PORT_Memcmp (savdig->md5, dig->md5, MD5_LENGTH);
    /* md5 hash of .mf file is not what expected */
    if (cv) 
      {
      status = jar_signal (JAR_ERR_HASH, jar, path, x_name);

      /* bad hash, man */

      dig->md5_status = jarHashBad;
      savdig->md5_status = jarHashBad;

      if (status < 0) 
        return 0; /* was continue; */
      else 
        return status;
      }
    }

  /* check for sha1 consistency */
  if (dig->sha1_status)
    {
    cv = PORT_Memcmp (savdig->sha1, dig->sha1, SHA1_LENGTH);
    /* sha1 hash of .mf file is not what expected */
    if (cv) 
      {
      status = jar_signal (JAR_ERR_HASH, jar, path, x_name);

      /* bad hash, man */

      dig->sha1_status = jarHashBad;
      savdig->sha1_status = jarHashBad;

      if (status < 0)
        return 0; /* was continue; */
      else
        return status;
      }
    }
       return 0;
  }

Here is the call graph for this function:

CERTCertDBHandle* JAR_open_database ( void  )

Definition at line 1815 of file jarver.c.

  {
  CERTCertDBHandle *certdb;

  certdb = CERT_GetDefaultCertDB();

  return certdb;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

int jar_parse_any ( JAR jar,
int  type,
JAR_Signer signer,
char ZHUGEP raw_manifest,
long  length,
const char *  path,
const char *  url 
)
static int jar_parse_digital_signature ( char *  raw_manifest,
JAR_Signer signer,
long  length,
JAR jar 
) [static]

Definition at line 824 of file jarver.c.

  {
#if defined(XP_WIN16)
  PORT_Assert( LOWORD(raw_manifest) + length < 0xFFFF );
#endif
  return jar_validate_pkcs7 (jar, signer, raw_manifest, length);
  }

Here is the call graph for this function:

int JAR_parse_manifest ( JAR jar,
char ZHUGEP raw_manifest,
long  length,
const char *  path,
const char *  url 
)

Definition at line 142 of file jarver.c.

  {

#if defined(XP_WIN16)
    PORT_Assert( !IsBadHugeReadPtr(raw_manifest, length) );
#endif

  /* fill in the path, if supplied. This is a the location
     of the jar file on disk, if known */

  if (jar->filename == NULL && path)
    {
    jar->filename = PORT_Strdup (path);
    if (jar->filename == NULL)
      return JAR_ERR_MEMORY;
    }

  /* fill in the URL, if supplied. This is the place
     from which the jar file was retrieved. */

  if (jar->url == NULL && url)
    {
    jar->url = PORT_Strdup (url);
    if (jar->url == NULL)
      return JAR_ERR_MEMORY;
    }

  /* Determine what kind of file this is from the META-INF 
     directory. It could be MF, SF, or a binary RSA/DSA file */

  if (!xp_HUGE_STRNCASECMP (raw_manifest, "Manifest-Version:", 17))
    {
    return jar_parse_mf (jar, raw_manifest, length, path, url);
    }
  else if (!xp_HUGE_STRNCASECMP (raw_manifest, "Signature-Version:", 18))
    {
    return jar_parse_sf (jar, raw_manifest, length, path, url);
    }
  else
    {
    /* This is probably a binary signature */
    return jar_parse_sig (jar, path, raw_manifest, length);
    }
  }

Here is the call graph for this function:

Here is the caller graph for this function:

int jar_parse_mf ( JAR jar,
char ZHUGEP raw_manifest,
long  length,
const char *  path,
const char *  url 
)
int jar_parse_sf ( JAR jar,
char ZHUGEP raw_manifest,
long  length,
const char *  path,
const char *  url 
)
int jar_parse_sig ( JAR jar,
const char *  path,
char ZHUGEP raw_manifest,
long  length 
)
static int jar_signal ( int  status,
JAR jar,
const char *  metafile,
char *  pathname 
) [static]

Definition at line 1915 of file jarver.c.

  {
  char *errstring;

  errstring = JAR_get_error (status);

  if (jar->signal)
    {
    (*jar->signal) (status, jar, metafile, pathname, errstring);
    return 0;
    }

  return status;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

int PR_CALLBACK JAR_stash_cert ( JAR jar,
long  keylen,
void key 
)

Definition at line 1422 of file jarver.c.

  {
  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;
  }

Here is the call graph for this function:

static int jar_validate_pkcs7 ( JAR jar,
JAR_Signer signer,
char *  data,
long  length 
) [static]

Definition at line 1658 of file jarver.c.

  {
  SECItem detdig;

  SEC_PKCS7ContentInfo *cinfo = NULL;
  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) 
    {
    /* strange pkcs7 failure */
    return JAR_ERR_PK7;
    }

  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;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

int PR_CALLBACK JAR_verify_digest ( JAR jar,
const char *  name,
JAR_Digest dig 
)

Definition at line 991 of file jarver.c.

  {
  JAR_Item *it;

  JAR_Digest *shindig;

  ZZLink *link;
  ZZList *list;

  int result1, result2;

  list = jar->hashes;

  result1 = result2 = 0;

  if (jar->valid < 0)
    {
    /* signature not valid */
    return JAR_ERR_SIG;
    }

  if (ZZ_ListEmpty (list))
    {
    /* empty list */
    return JAR_ERR_PNF;
    }

  for (link = ZZ_ListHead (list); 
       !ZZ_ListIterDone (list, link); 
       link = link->next)
    {
    it = link->thing;
    if (it->type == jarTypeMF 
           && it->pathname && !PORT_Strcmp (it->pathname, name))
      {
      shindig = (JAR_Digest *) it->data;

      if (shindig->md5_status)
        {
        if (shindig->md5_status == jarHashBad)
          return JAR_ERR_HASH;
        else
          result1 = memcmp (dig->md5, shindig->md5, MD5_LENGTH);
        }

      if (shindig->sha1_status)
        {
        if (shindig->sha1_status == jarHashBad)
          return JAR_ERR_HASH;
        else
          result2 = memcmp (dig->sha1, shindig->sha1, SHA1_LENGTH);
        }

      return (result1 == 0 && result2 == 0) ? 0 : JAR_ERR_HASH;
      }
    }

  return JAR_ERR_PNF;
  }

Here is the call graph for this function:

Here is the caller graph for this function: