/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 *  JARVER
 *
 *  Jarnature Parsing & Verification
 */

#include "nssrenam.h"
#include "jar.h"
#include "jarint.h"
#include "certdb.h"
#include "certt.h"
#include "secpkcs7.h"
#include "secder.h"

#define SZ 512

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 *
jar_eat_line(int lines, int eating, char *data, long *len);

static JAR_Digest *
jar_digest_section(char *manifest, long length);

static JAR_Digest *jar_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 char *jar_basename(const char *path);

static int
jar_signal(int status, JAR *jar, const char *metafile, char *pathname);

#ifdef DEBUG
static int jar_insanity_check(char *data, long length);
#endif

int
jar_parse_mf(JAR *jar, char *raw_manifest, long length,
             const char *path, const char *url);

int
jar_parse_sf(JAR *jar, char *raw_manifest, long length,
             const char *path, const char *url);

int
jar_parse_sig(JAR *jar, const char *path, char *raw_manifest,
              long length);

int
jar_parse_any(JAR *jar, int type, JAR_Signer *signer,
              char *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);

/*
 *  J A R _ p a r s e _ m a n i f e s t
 *
 *  Pass manifest files to this function. They are
 *  decoded and placed into internal representations.
 *
 *  Accepts both signature and manifest files. Use
 *  the same "jar" for both.
 *
 */
int
JAR_parse_manifest(JAR *jar, char *raw_manifest, long length,
                   const char *path, const char *url)
{
    int filename_free = 0;

    /* fill in the path, if supplied. This is 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;
        filename_free = 1;
    }

    /* 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) {
            if (filename_free) {
                PORT_Free(jar->filename);
            }
            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 (!PORT_Strncasecmp(raw_manifest, "Manifest-Version:", 17)) {
        return jar_parse_mf(jar, raw_manifest, length, path, url);
    } else if (!PORT_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);
    }
}

/*
 *  j a r _ p a r s e _ s i g
 *
 *  Pass some manner of RSA or DSA digital signature
 *  on, after checking to see if it comes at an appropriate state.
 *
 */
int
jar_parse_sig(JAR *jar, const char *path, char *raw_manifest,
              long length)
{
    JAR_Signer *signer;
    int status = JAR_ERR_ORDER;

    if (length <= 128) {
        /* signature is way too small */
        return JAR_ERR_SIG;
    }

    /* make sure that MF and SF have already been processed */

    if (jar->globalmeta == NULL)
        return JAR_ERR_ORDER;

    /* Determine whether or not this RSA file has
       has an associated SF file */

    if (path) {
        char *owner;
        owner = jar_basename(path);

        if (owner == NULL)
            return JAR_ERR_MEMORY;

        signer = jar_get_signer(jar, owner);
        PORT_Free(owner);
    } else
        signer = jar_get_signer(jar, "*");

    if (signer == NULL)
        return JAR_ERR_ORDER;

    /* Do not pass a huge pointer to this function,
       since the underlying security code is unaware. We will
       never pass >64k through here. */

    if (length > 64000) {
        /* this digital signature is way too big */
        return JAR_ERR_SIG;
    }

    /* don't expense unneeded calloc overhead on non-win16 */
    status = jar_parse_digital_signature(raw_manifest, signer, length, jar);

    return status;
}

/*
 *  j a r _ p a r s e _ m f
 *
 *  Parse the META-INF/manifest.mf file, whose
 *  information applies to all signers.
 *
 */
int
jar_parse_mf(JAR *jar, char *raw_manifest, long length,
             const char *path, const char *url)
{
    if (jar->globalmeta) {
        /* refuse a second manifest file, if passed for some reason */
        return JAR_ERR_ORDER;
    }

    /* remember a digest for the global section */
    jar->globalmeta = jar_digest_section(raw_manifest, length);
    if (jar->globalmeta == NULL)
        return JAR_ERR_MEMORY;
    return jar_parse_any(jar, jarTypeMF, NULL, raw_manifest, length,
                         path, url);
}

/*
 *  j a r _ p a r s e _ s f
 *
 *  Parse META-INF/xxx.sf, a digitally signed file
 *  pointing to a subset of MF sections.
 *
 */
int
jar_parse_sf(JAR *jar, char *raw_manifest, long length,
             const char *path, const char *url)
{
    JAR_Signer *signer = NULL;
    int status = JAR_ERR_MEMORY;

    if (jar->globalmeta == NULL) {
        /* It is a requirement that the MF file be passed before the SF file */
        return JAR_ERR_ORDER;
    }

    signer = JAR_new_signer();
    if (signer == NULL)
        goto loser;

    if (path) {
        signer->owner = jar_basename(path);
        if (signer->owner == NULL)
            goto loser;
    }

    /* check for priors. When someone doctors a jar file
       to contain identical path entries, prevent the second
       one from affecting JAR functions */
    if (jar_get_signer(jar, signer->owner)) {
        /* someone is trying to spoof us */
        status = JAR_ERR_ORDER;
        goto loser;
    }

    /* remember its digest */
    signer->digest = JAR_calculate_digest(raw_manifest, length);
    if (signer->digest == NULL)
        goto loser;

    /* Add this signer to the jar */
    ADDITEM(jar->signers, jarTypeOwner, signer->owner, signer,
            sizeof(JAR_Signer));

    return jar_parse_any(jar, jarTypeSF, signer, raw_manifest, length,
                         path, url);

loser:
    if (signer)
        JAR_destroy_signer(signer);
    return status;
}

/*
 *  j a r _ p a r s e _ a n y
 *
 *  Parse a MF or SF manifest file.
 *
 */
int
jar_parse_any(JAR *jar, int type, JAR_Signer *signer,
              char *raw_manifest, long length, const char *path,
              const char *url)
{
    int status;
    long raw_len;
    JAR_Digest *dig, *mfdig = NULL;
    char line[SZ];
    char x_name[SZ], x_md5[SZ], x_sha[SZ];
    char *x_info;
    char *sf_md5 = NULL, *sf_sha1 = NULL;

    *x_name = 0;
    *x_md5 = 0;
    *x_sha = 0;

    PORT_Assert(length > 0);
    raw_len = length;

#ifdef DEBUG
    if ((status = jar_insanity_check(raw_manifest, raw_len)) < 0)
        return status;
#endif

    /* null terminate the first line */
    raw_manifest = jar_eat_line(0, PR_TRUE, raw_manifest, &raw_len);

    /* skip over the preliminary section */
    /* This is one section at the top of the file with global metainfo */
    while (raw_len > 0) {
        JAR_Metainfo *met;

        raw_manifest = jar_eat_line(1, PR_TRUE, raw_manifest, &raw_len);
        if (raw_len <= 0 || !*raw_manifest)
            break;

        met = PORT_ZNew(JAR_Metainfo);
        if (met == NULL)
            return JAR_ERR_MEMORY;

        /* Parse out the header & info */
        if (PORT_Strlen(raw_manifest) >= SZ) {
            /* almost certainly nonsense */
            PORT_Free(met);
            continue;
        }

        PORT_Strcpy(line, raw_manifest);
        x_info = line;

        while (*x_info && *x_info != ' ' && *x_info != '\t' && *x_info != ':')
            x_info++;

        if (*x_info)
            *x_info++ = 0;

        while (*x_info == ' ' || *x_info == '\t')
            x_info++;

        /* metainfo (name, value) pair is now (line, x_info) */
        met->header = PORT_Strdup(line);
        met->info = PORT_Strdup(x_info);

        if (type == jarTypeMF) {
            ADDITEM(jar->metainfo, jarTypeMeta,
                    /* pathname */ NULL, met, sizeof(JAR_Metainfo));
        }

        /* For SF files, this metadata may be the digests
           of the MF file, still in the "met" structure. */

        if (type == jarTypeSF) {
            if (!PORT_Strcasecmp(line, "MD5-Digest")) {
                sf_md5 = (char *)met->info;
            } else if (!PORT_Strcasecmp(line, "SHA1-Digest") ||
                       !PORT_Strcasecmp(line, "SHA-Digest")) {
                sf_sha1 = (char *)met->info;
            } else {
                PORT_Free(met->info);
                met->info = NULL;
            }
        }

        if (type != jarTypeMF) {
            PORT_Free(met->header);
            if ((type != jarTypeSF || !jar->globalmeta) && met->info) {
                PORT_Free(met->info);
            }
            PORT_Free(met);
        }
    }

    if (type == jarTypeSF && jar->globalmeta) {
        /* this is a SF file which may contain a digest of the manifest.mf's
           global metainfo. */

        int match = 0;
        JAR_Digest *glob = jar->globalmeta;

        if (sf_md5) {
            unsigned int md5_length;
            unsigned char *md5_digest;

            md5_digest = ATOB_AsciiToData(sf_md5, &md5_length);
            PORT_Assert(md5_length == MD5_LENGTH);
            PORT_Free(sf_md5);

            if (md5_length != MD5_LENGTH)
                return JAR_ERR_CORRUPT;

            match = PORT_Memcmp(md5_digest, glob->md5, MD5_LENGTH);
            PORT_Free(md5_digest);
        }

        if (sf_sha1 && match == 0) {
            unsigned int sha1_length;
            unsigned char *sha1_digest;

            sha1_digest = ATOB_AsciiToData(sf_sha1, &sha1_length);
            PORT_Assert(sha1_length == SHA1_LENGTH);
            PORT_Free(sf_sha1);

            if (sha1_length != SHA1_LENGTH)
                return JAR_ERR_CORRUPT;

            match = PORT_Memcmp(sha1_digest, glob->sha1, SHA1_LENGTH);
            PORT_Free(sha1_digest);
        }

        if (match != 0) {
            /* global digest doesn't match, SF file therefore invalid */
            jar->valid = JAR_ERR_METADATA;
            return JAR_ERR_METADATA;
        }
    }

    /* done with top section of global data */
    while (raw_len > 0) {
        *x_md5 = 0;
        *x_sha = 0;
        *x_name = 0;

        /* If this is a manifest file, attempt to get a digest of the following
           section, without damaging it. This digest will be saved later. */

        if (type == jarTypeMF) {
            char *sec;
            long sec_len = raw_len;

            if (!*raw_manifest || *raw_manifest == '\n') {
                /* skip the blank line */
                sec = jar_eat_line(1, PR_FALSE, raw_manifest, &sec_len);
            } else
                sec = raw_manifest;

            if (sec_len > 0 && !PORT_Strncasecmp(sec, "Name:", 5)) {
                if (type == jarTypeMF)
                    mfdig = jar_digest_section(sec, sec_len);
                else
                    mfdig = NULL;
            }
        }

        while (raw_len > 0) {
            raw_manifest = jar_eat_line(1, PR_TRUE, raw_manifest, &raw_len);
            if (raw_len <= 0 || !*raw_manifest)
                break; /* blank line, done with this entry */

            if (PORT_Strlen(raw_manifest) >= SZ) {
                /* almost certainly nonsense */
                continue;
            }

            /* Parse out the name/value pair */
            PORT_Strcpy(line, raw_manifest);
            x_info = line;

            while (*x_info && *x_info != ' ' && *x_info != '\t' &&
                   *x_info != ':')
                x_info++;

            if (*x_info)
                *x_info++ = 0;

            while (*x_info == ' ' || *x_info == '\t')
                x_info++;

            if (!PORT_Strcasecmp(line, "Name"))
                PORT_Strcpy(x_name, x_info);
            else if (!PORT_Strcasecmp(line, "MD5-Digest"))
                PORT_Strcpy(x_md5, x_info);
            else if (!PORT_Strcasecmp(line, "SHA1-Digest") ||
                     !PORT_Strcasecmp(line, "SHA-Digest"))
                PORT_Strcpy(x_sha, x_info);

            /* Algorithm list is meta info we don't care about; keeping it out
               of metadata saves significant space for large jar files */
            else if (!PORT_Strcasecmp(line, "Digest-Algorithms") ||
                     !PORT_Strcasecmp(line, "Hash-Algorithms"))
                continue;

            /* Meta info is only collected for the manifest.mf file,
               since the JAR_get_metainfo call does not support identity */
            else if (type == jarTypeMF) {
                JAR_Metainfo *met;

                /* this is meta-data */
                met = PORT_ZNew(JAR_Metainfo);
                if (met == NULL)
                    return JAR_ERR_MEMORY;

                /* metainfo (name, value) pair is now (line, x_info) */
                if ((met->header = PORT_Strdup(line)) == NULL) {
                    PORT_Free(met);
                    return JAR_ERR_MEMORY;
                }

                if ((met->info = PORT_Strdup(x_info)) == NULL) {
                    PORT_Free(met->header);
                    PORT_Free(met);
                    return JAR_ERR_MEMORY;
                }

                ADDITEM(jar->metainfo, jarTypeMeta,
                        x_name, met, sizeof(JAR_Metainfo));
            }
        }

        if (!*x_name) {
            /* Whatever that was, it wasn't an entry, because we didn't get a
               name. We don't really have anything, so don't record this. */
            continue;
        }

        dig = PORT_ZNew(JAR_Digest);
        if (dig == NULL)
            return JAR_ERR_MEMORY;

        if (*x_md5) {
            unsigned int binary_length;
            unsigned char *binary_digest;

            binary_digest = ATOB_AsciiToData(x_md5, &binary_length);
            PORT_Assert(binary_length == MD5_LENGTH);
            if (binary_length != MD5_LENGTH) {
                PORT_Free(dig);
                return JAR_ERR_CORRUPT;
            }
            memcpy(dig->md5, binary_digest, MD5_LENGTH);
            dig->md5_status = jarHashPresent;
            PORT_Free(binary_digest);
        }

        if (*x_sha) {
            unsigned int binary_length;
            unsigned char *binary_digest;

            binary_digest = ATOB_AsciiToData(x_sha, &binary_length);
            PORT_Assert(binary_length == SHA1_LENGTH);
            if (binary_length != SHA1_LENGTH) {
                PORT_Free(dig);
                return JAR_ERR_CORRUPT;
            }
            memcpy(dig->sha1, binary_digest, SHA1_LENGTH);
            dig->sha1_status = jarHashPresent;
            PORT_Free(binary_digest);
        }

        PORT_Assert(type == jarTypeMF || type == jarTypeSF);
        if (type == jarTypeMF) {
            ADDITEM(jar->hashes, jarTypeMF, x_name, dig, sizeof(JAR_Digest));
        } else if (type == jarTypeSF) {
            ADDITEM(signer->sf, jarTypeSF, x_name, dig, sizeof(JAR_Digest));
        } else {
            PORT_Free(dig);
            return JAR_ERR_ORDER;
        }

        /* we're placing these calculated digests of manifest.mf
           sections in a list where they can subsequently be forgotten */
        if (type == jarTypeMF && mfdig) {
            ADDITEM(jar->manifest, jarTypeSect,
                    x_name, mfdig, sizeof(JAR_Digest));
            mfdig = NULL;
        }

        /* Retrieve our saved SHA1 digest from saved copy and check digests.
           This is just comparing the digest of the MF section as indicated in
           the SF file with the one we remembered from parsing the MF file */

        if (type == jarTypeSF) {
            if ((status = jar_internal_digest(jar, path, x_name, dig)) < 0)
                return status;
        }
    }

    return 0;
}

static int
jar_internal_digest(JAR *jar, const char *path, char *x_name, JAR_Digest *dig)
{
    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; */
        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; */
            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; */
            return status;
        }
    }
    return 0;
}

#ifdef DEBUG
/*
 *  j a r _ i n s a n i t y _ c h e c k
 *
 *  Check for illegal characters (or possibly so)
 *  in the manifest files, to detect potential memory
 *  corruption by our neighbors. Debug only, since
 *  not I18N safe.
 *
 */
static int
jar_insanity_check(char *data, long length)
{
    int c;
    long off;

    for (off = 0; off < length; off++) {
        c = data[off];
        if (c == '\n' || c == '\r' || (c >= ' ' && c <= 128))
            continue;
        return JAR_ERR_CORRUPT;
    }
    return 0;
}
#endif

/*
 *  j a r _ p a r s e _ d i g i t a l _ s i g n a t u r e
 *
 *  Parse an RSA or DSA (or perhaps other) digital signature.
 *  Right now everything is PKCS7.
 *
 */
static int
jar_parse_digital_signature(char *raw_manifest, JAR_Signer *signer,
                            long length, JAR *jar)
{
    return jar_validate_pkcs7(jar, signer, raw_manifest, length);
}

/*
 *  j a r _ a d d _ c e r t
 *
 *  Add information for the given certificate
 *  (or whatever) to the JAR linked list. A pointer
 *  is passed for some relevant reference, say
 *  for example the original certificate.
 *
 */
static int
jar_add_cert(JAR *jar, JAR_Signer *signer, int type, CERTCertificate *cert)
{
    JAR_Cert *fing;
    unsigned char *keyData;

    if (cert == NULL)
        return JAR_ERR_ORDER;

    fing = PORT_ZNew(JAR_Cert);
    if (fing == NULL)
        goto loser;

    fing->cert = CERT_DupCertificate(cert);

    /* get the certkey */
    fing->length = cert->derIssuer.len + 2 + cert->serialNumber.len;
    fing->key = keyData = (unsigned char *)PORT_ZAlloc(fing->length);
    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, NULL, fing, sizeof(JAR_Cert));
    return 0;

loser:
    if (fing) {
        if (fing->cert)
            CERT_DestroyCertificate(fing->cert);
        PORT_Free(fing);
    }
    return JAR_ERR_MEMORY;
}

/*
 *  e a t _ l i n e
 *
 * Reads and/or modifies input buffer "data" of length "*len".
 * This function does zero, one or two of the following tasks:
 * 1) if "lines" is non-zero, it reads and discards that many lines from
 *    the input.  NUL characters are treated as end-of-line characters,
 *    not as end-of-input characters.  The input is NOT NUL terminated.
 *    Note: presently, all callers pass either 0 or 1 for lines.
 * 2) After skipping the specified number of input lines, if "eating" is
 *    non-zero, it finds the end of the next line of input and replaces
 *    the end of line character(s) with a NUL character.
 *  This function modifies the input buffer, containing the file, in place.
 *  This function handles PC, Mac, and Unix style text files.
 *  On entry, *len contains the maximum number of characters that this
 *  function should ever examine, starting with the character in *data.
 *  On return, *len is reduced by the number of characters skipped by the
 *  first task, if any;
 *  If lines is zero and eating is false, this function returns
 *  the value in the data argument, but otherwise does nothing.
 */
static char *
jar_eat_line(int lines, int eating, char *data, long *len)
{
    char *start = data;
    long maxLen = *len;

    if (maxLen <= 0)
        return start;

#define GO_ON ((data - start) < maxLen)

    /* Eat the requisite number of lines, if any;
       prior to terminating the current line with a 0. */
    for (/* yip */; lines > 0; lines--) {
        while (GO_ON && *data && *data != '\r' && *data != '\n')
            data++;

        /* Eat any leading CR */
        if (GO_ON && *data == '\r')
            data++;

        /* After the CR, ok to eat one LF */
        if (GO_ON && *data == '\n')
            data++;

        /* If there are NULs, this function probably put them there */
        while (GO_ON && !*data)
            data++;
    }
    maxLen -= data - start; /* we have this many characters left. */
    *len = maxLen;
    start = data; /* now start again here.            */
    if (maxLen > 0 && eating) {
        /* Terminate this line with a 0 */
        while (GO_ON && *data && *data != '\n' && *data != '\r')
            data++;

        /* If not past the end, we are allowed to eat one CR */
        if (GO_ON && *data == '\r')
            *data++ = 0;

        /* After the CR (if any), if not past the end, ok to eat one LF */
        if (GO_ON && *data == '\n')
            *data++ = 0;
    }
    return start;
}
#undef GO_ON

/*
 *  j a r _ d i g e s t _ s e c t i o n
 *
 *  Return the digests of the next section of the manifest file.
 *  Does not damage the manifest file, unlike parse_manifest.
 *
 */
static JAR_Digest *
jar_digest_section(char *manifest, long length)
{
    long global_len;
    char *global_end;

    global_end = manifest;
    global_len = length;

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

/*
 *  J A R _ v e r i f y _ d i g e s t
 *
 *  Verifies that a precalculated digest matches the
 *  expected value in the manifest.
 *
 */
int PR_CALLBACK
JAR_verify_digest(JAR *jar, const char *name, JAR_Digest *dig)
{
    JAR_Item *it;
    JAR_Digest *shindig;
    ZZLink *link;
    ZZList *list = jar->hashes;
    int result1 = 0;
    int 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;
                result1 = memcmp(dig->md5, shindig->md5, MD5_LENGTH);
            }
            if (shindig->sha1_status) {
                if (shindig->sha1_status == jarHashBad)
                    return JAR_ERR_HASH;
                result2 = memcmp(dig->sha1, shindig->sha1, SHA1_LENGTH);
            }
            return (result1 == 0 && result2 == 0) ? 0 : JAR_ERR_HASH;
        }
    }
    return JAR_ERR_PNF;
}

/*
 *  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.
 *
 */
CERTCertificate *
JAR_fetch_cert(long length, void *key)
{
    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];
        cert = CERT_FindCertByIssuerAndSN(certdb, &issuerSN);
        JAR_close_database(certdb);
    }
    return 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 = 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)
{

    SEC_PKCS7ContentInfo *cinfo = NULL;
    SEC_PKCS7DecoderContext *dcx;
    PRBool goodSig;
    int status = 0;
    SECItem detdig;

    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 */
    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;
    goodSig = SEC_PKCS7VerifyDetachedSignature(cinfo,
                                               certUsageObjectSigner,
                                               &detdig, HASH_AlgSHA1,
                                               PR_FALSE);
    jar_gather_signers(jar, signer, cinfo);
    if (goodSig == PR_TRUE) {
        /* signature is valid */
        signer->valid = 0;
    } else {
        status = PORT_GetError();
        PORT_Assert(status < 0);
        if (status >= 0)
            status = JAR_ERR_SIG;
        jar->valid = status;
        signer->valid = status;
    }
    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 = cinfo->content.signedData;
    SEC_PKCS7SignerInfo **pksigners, *pksigner;

    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)
{
    return CERT_GetDefaultCertDB();
}

/*
 *  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)
{
    return 0;
}

/*
 *  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 = 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 = PORT_ZNew(JAR_Item);
    ZZLink *entity;

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