/* 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/. */

/*
 *  JAR.C
 *
 *  Jarnature.
 *  Routines common to signing and validating.
 *
 */

#include "jar.h"
#include "jarint.h"
#include "portreg.h"

static void
jar_destroy_list(ZZList *list);

static int
jar_find_first_cert(JAR_Signer *signer, int type, JAR_Item **it);

/*
 *  J A R _ n e w
 *
 *  Create a new instantiation of a manifest representation.
 *  Use this as a token to any calls to this API.
 *
 */
JAR *
JAR_new(void)
{
    JAR *jar;

    if ((jar = (JAR *)PORT_ZAlloc(sizeof(JAR))) == NULL)
        goto loser;
    if ((jar->manifest = ZZ_NewList()) == NULL)
        goto loser;
    if ((jar->hashes = ZZ_NewList()) == NULL)
        goto loser;
    if ((jar->phy = ZZ_NewList()) == NULL)
        goto loser;
    if ((jar->metainfo = ZZ_NewList()) == NULL)
        goto loser;
    if ((jar->signers = ZZ_NewList()) == NULL)
        goto loser;
    return jar;

loser:
    if (jar) {
        if (jar->manifest)
            ZZ_DestroyList(jar->manifest);
        if (jar->hashes)
            ZZ_DestroyList(jar->hashes);
        if (jar->phy)
            ZZ_DestroyList(jar->phy);
        if (jar->metainfo)
            ZZ_DestroyList(jar->metainfo);
        if (jar->signers)
            ZZ_DestroyList(jar->signers);
        PORT_Free(jar);
    }
    return NULL;
}

/*
 *  J A R _ d e s t r o y
 */
void PR_CALLBACK
JAR_destroy(JAR *jar)
{
    PORT_Assert(jar != NULL);

    if (jar == NULL)
        return;

    if (jar->fp)
        JAR_FCLOSE((PRFileDesc *)jar->fp);
    if (jar->url)
        PORT_Free(jar->url);
    if (jar->filename)
        PORT_Free(jar->filename);
    if (jar->globalmeta)
        PORT_Free(jar->globalmeta);

    /* Free the linked list elements */
    jar_destroy_list(jar->manifest);
    ZZ_DestroyList(jar->manifest);
    jar_destroy_list(jar->hashes);
    ZZ_DestroyList(jar->hashes);
    jar_destroy_list(jar->phy);
    ZZ_DestroyList(jar->phy);
    jar_destroy_list(jar->metainfo);
    ZZ_DestroyList(jar->metainfo);
    jar_destroy_list(jar->signers);
    ZZ_DestroyList(jar->signers);
    PORT_Free(jar);
}

static void
jar_destroy_list(ZZList *list)
{
    ZZLink *link, *oldlink;
    JAR_Item *it;
    JAR_Physical *phy;
    JAR_Digest *dig;
    JAR_Cert *fing;
    JAR_Metainfo *met;
    JAR_Signer *signer;

    if (list && !ZZ_ListEmpty(list)) {
        link = ZZ_ListHead(list);
        while (!ZZ_ListIterDone(list, link)) {
            it = link->thing;
            if (!it)
                goto next;
            if (it->pathname)
                PORT_Free(it->pathname);

            switch (it->type) {
                case jarTypeMeta:
                    met = (JAR_Metainfo *)it->data;
                    if (met) {
                        if (met->header)
                            PORT_Free(met->header);
                        if (met->info)
                            PORT_Free(met->info);
                        PORT_Free(met);
                    }
                    break;

                case jarTypePhy:
                    phy = (JAR_Physical *)it->data;
                    if (phy)
                        PORT_Free(phy);
                    break;

                case jarTypeSign:
                    fing = (JAR_Cert *)it->data;
                    if (fing) {
                        if (fing->cert)
                            CERT_DestroyCertificate(fing->cert);
                        if (fing->key)
                            PORT_Free(fing->key);
                        PORT_Free(fing);
                    }
                    break;

                case jarTypeSect:
                case jarTypeMF:
                case jarTypeSF:
                    dig = (JAR_Digest *)it->data;
                    if (dig) {
                        PORT_Free(dig);
                    }
                    break;

                case jarTypeOwner:
                    signer = (JAR_Signer *)it->data;
                    if (signer)
                        JAR_destroy_signer(signer);
                    break;

                default:
                    /* PORT_Assert( 1 != 2 ); */
                    break;
            }
            PORT_Free(it);

        next:
            oldlink = link;
            link = link->next;
            ZZ_DestroyLink(oldlink);
        }
    }
}

/*
 *  J A R _ g e t _ m e t a i n f o
 *
 *  Retrieve meta information from the manifest file.
 *  It doesn't matter whether it's from .MF or .SF, does it?
 *
 */

int
JAR_get_metainfo(JAR *jar, char *name, char *header, void **info,
                 unsigned long *length)
{
    JAR_Item *it;
    ZZLink *link;
    ZZList *list;

    PORT_Assert(jar != NULL && header != NULL);

    if (jar == NULL || header == NULL)
        return JAR_ERR_PNF;

    list = jar->metainfo;

    if (ZZ_ListEmpty(list))
        return JAR_ERR_PNF;

    for (link = ZZ_ListHead(list);
         !ZZ_ListIterDone(list, link);
         link = link->next) {
        it = link->thing;
        if (it->type == jarTypeMeta) {
            JAR_Metainfo *met;

            if ((name && !it->pathname) || (!name && it->pathname))
                continue;
            if (name && it->pathname && strcmp(it->pathname, name))
                continue;
            met = (JAR_Metainfo *)it->data;
            if (!PORT_Strcasecmp(met->header, header)) {
                *info = PORT_Strdup(met->info);
                *length = PORT_Strlen(met->info);
                return 0;
            }
        }
    }
    return JAR_ERR_PNF;
}

/*
 *  J A R _ f i n d
 *
 *  Establish the search pattern for use
 *  by JAR_find_next, to traverse the filenames
 *  or certificates in the JAR structure.
 *
 *  See jar.h for a description on how to use.
 *
 */
JAR_Context *
JAR_find(JAR *jar, char *pattern, jarType type)
{
    JAR_Context *ctx;

    PORT_Assert(jar != NULL);

    if (!jar)
        return NULL;

    ctx = (JAR_Context *)PORT_ZAlloc(sizeof(JAR_Context));
    if (ctx == NULL)
        return NULL;

    ctx->jar = jar;
    if (pattern) {
        if ((ctx->pattern = PORT_Strdup(pattern)) == NULL) {
            PORT_Free(ctx);
            return NULL;
        }
    }
    ctx->finding = type;

    switch (type) {
        case jarTypeMF:
            ctx->next = ZZ_ListHead(jar->hashes);
            break;

        case jarTypeSF:
        case jarTypeSign:
            ctx->next = NULL;
            ctx->nextsign = ZZ_ListHead(jar->signers);
            break;

        case jarTypeSect:
            ctx->next = ZZ_ListHead(jar->manifest);
            break;

        case jarTypePhy:
            ctx->next = ZZ_ListHead(jar->phy);
            break;

        case jarTypeOwner:
            if (jar->signers)
                ctx->next = ZZ_ListHead(jar->signers);
            else
                ctx->next = NULL;
            break;

        case jarTypeMeta:
            ctx->next = ZZ_ListHead(jar->metainfo);
            break;

        default:
            PORT_Assert(1 != 2);
            break;
    }
    return ctx;
}

/*
 *  J A R _ f i n d _ e n d
 *
 *  Destroy the find iterator context.
 *
 */
void
JAR_find_end(JAR_Context *ctx)
{
    PORT_Assert(ctx != NULL);
    if (ctx) {
        if (ctx->pattern)
            PORT_Free(ctx->pattern);
        PORT_Free(ctx);
    }
}

/*
 *  J A R _ f i n d _ n e x t
 *
 *  Return the next item of the given type
 *  from one of the JAR linked lists.
 *
 */

int
JAR_find_next(JAR_Context *ctx, JAR_Item **it)
{
    JAR *jar;
    ZZList *list = NULL;
    int finding;
    JAR_Signer *signer = NULL;

    PORT_Assert(ctx != NULL);
    PORT_Assert(ctx->jar != NULL);

    jar = ctx->jar;

    /* Internally, convert jarTypeSign to jarTypeSF, and return
       the actual attached certificate later */
    finding = (ctx->finding == jarTypeSign) ? jarTypeSF : ctx->finding;
    if (ctx->nextsign) {
        if (ZZ_ListIterDone(jar->signers, ctx->nextsign)) {
            *it = NULL;
            return -1;
        }
        PORT_Assert(ctx->nextsign->thing != NULL);
        signer = (JAR_Signer *)ctx->nextsign->thing->data;
    }

    /* Find out which linked list to traverse. Then if
       necessary, advance to the next linked list. */
    while (1) {
        switch (finding) {
            case jarTypeSign: /* not any more */
                PORT_Assert(finding != jarTypeSign);
                list = signer->certs;
                break;

            case jarTypeSect:
                list = jar->manifest;
                break;

            case jarTypePhy:
                list = jar->phy;
                break;

            case jarTypeSF: /* signer, not jar */
                PORT_Assert(signer != NULL);
                list = signer ? signer->sf : NULL;
                break;

            case jarTypeMF:
                list = jar->hashes;
                break;

            case jarTypeOwner:
                list = jar->signers;
                break;

            case jarTypeMeta:
                list = jar->metainfo;
                break;

            default:
                PORT_Assert(1 != 2);
                list = NULL;
                break;
        }
        if (list == NULL) {
            *it = NULL;
            return -1;
        }
        /* When looping over lists of lists, advance to the next signer.
	   This is done when multiple signers are possible. */
        if (ZZ_ListIterDone(list, ctx->next)) {
            if (ctx->nextsign && jar->signers) {
                ctx->nextsign = ctx->nextsign->next;
                if (!ZZ_ListIterDone(jar->signers, ctx->nextsign)) {
                    PORT_Assert(ctx->nextsign->thing != NULL);
                    signer = (JAR_Signer *)ctx->nextsign->thing->data;
                    PORT_Assert(signer != NULL);
                    ctx->next = NULL;
                    continue;
                }
            }
            *it = NULL;
            return -1;
        }

        /* if the signer changed, still need to fill in the "next" link */
        if (ctx->nextsign && ctx->next == NULL) {
            switch (finding) {
                case jarTypeSF:
                    ctx->next = ZZ_ListHead(signer->sf);
                    break;

                case jarTypeSign:
                    ctx->next = ZZ_ListHead(signer->certs);
                    break;
            }
        }
        PORT_Assert(ctx->next != NULL);
        if (ctx->next == NULL) {
            *it = NULL;
            return -1;
        }
        while (!ZZ_ListIterDone(list, ctx->next)) {
            *it = ctx->next->thing;
            ctx->next = ctx->next->next;
            if (!*it || (*it)->type != finding)
                continue;
            if (ctx->pattern && *ctx->pattern) {
                if (PORT_RegExpSearch((*it)->pathname, ctx->pattern))
                    continue;
            }
            /* We have a valid match. If this is a jarTypeSign
	       return the certificate instead.. */
            if (ctx->finding == jarTypeSign) {
                JAR_Item *itt;

                /* just the first one for now */
                if (jar_find_first_cert(signer, jarTypeSign, &itt) >= 0) {
                    *it = itt;
                    return 0;
                }
                continue;
            }
            return 0;
        }
    } /* end while */
}

static int
jar_find_first_cert(JAR_Signer *signer, int type, JAR_Item **it)
{
    ZZLink *link;
    ZZList *list = signer->certs;
    int status = JAR_ERR_PNF;

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

    for (link = ZZ_ListHead(list);
         !ZZ_ListIterDone(list, link);
         link = link->next) {
        if (link->thing->type == type) {
            *it = link->thing;
            status = 0;
            break;
        }
    }
    return status;
}

JAR_Signer *
JAR_new_signer(void)
{
    JAR_Signer *signer = (JAR_Signer *)PORT_ZAlloc(sizeof(JAR_Signer));
    if (signer == NULL)
        goto loser;

    /* certs */
    signer->certs = ZZ_NewList();
    if (signer->certs == NULL)
        goto loser;

    /* sf */
    signer->sf = ZZ_NewList();
    if (signer->sf == NULL)
        goto loser;
    return signer;

loser:
    if (signer) {
        if (signer->certs)
            ZZ_DestroyList(signer->certs);
        if (signer->sf)
            ZZ_DestroyList(signer->sf);
        PORT_Free(signer);
    }
    return NULL;
}

void
JAR_destroy_signer(JAR_Signer *signer)
{
    if (signer) {
        if (signer->owner)
            PORT_Free(signer->owner);
        if (signer->digest)
            PORT_Free(signer->digest);
        jar_destroy_list(signer->sf);
        ZZ_DestroyList(signer->sf);
        jar_destroy_list(signer->certs);
        ZZ_DestroyList(signer->certs);
        PORT_Free(signer);
    }
}

JAR_Signer *
jar_get_signer(JAR *jar, char *basename)
{
    JAR_Item *it;
    JAR_Context *ctx = JAR_find(jar, NULL, jarTypeOwner);
    JAR_Signer *candidate;
    JAR_Signer *signer = NULL;

    if (ctx == NULL)
        return NULL;

    while (JAR_find_next(ctx, &it) >= 0) {
        candidate = (JAR_Signer *)it->data;
        if (*basename == '*' || !PORT_Strcmp(candidate->owner, basename)) {
            signer = candidate;
            break;
        }
    }
    JAR_find_end(ctx);
    return signer;
}

/*
 *  J A R _ g e t _ f i l e n a m e
 *
 *  Returns the filename associated with
 *  a JAR structure.
 *
 */
char *
JAR_get_filename(JAR *jar)
{
    return jar->filename;
}

/*
 *  J A R _ g e t _ u r l
 *
 *  Returns the URL associated with
 *  a JAR structure. Nobody really uses this now.
 *
 */
char *
JAR_get_url(JAR *jar)
{
    return jar->url;
}

/*
 *  J A R _ s e t _ c a l l b a c k
 *
 *  Register some manner of callback function for this jar.
 *
 */
int
JAR_set_callback(int type, JAR *jar, jar_settable_callback_fn *fn)
{
    if (type == JAR_CB_SIGNAL) {
        jar->signal = fn;
        return 0;
    }
    return -1;
}

/*
 *  Callbacks
 *
 */

/* To return an error string */
char *(*jar_fn_GetString)(int) = NULL;

/* To return an MWContext for Java */
void *(*jar_fn_FindSomeContext)(void) = NULL;

/* To fabricate an MWContext for FE_GetPassword */
void *(*jar_fn_GetInitContext)(void) = NULL;

void
JAR_init_callbacks(char *(*string_cb)(int),
                   void *(*find_cx)(void),
                   void *(*init_cx)(void))
{
    jar_fn_GetString = string_cb;
    jar_fn_FindSomeContext = find_cx;
    jar_fn_GetInitContext = init_cx;
}

/*
 *  J A R _ g e t _ e r r o r
 *
 *  This is provided to map internal JAR errors to strings for
 *  the Java console. Also, a DLL may call this function if it does
 *  not have access to the XP_GetString function.
 *
 *  These strings aren't UI, since they are Java console only.
 *
 */
char *
JAR_get_error(int status)
{
    char *errstring = NULL;

    switch (status) {
        case JAR_ERR_GENERAL:
            errstring = "General JAR file error";
            break;

        case JAR_ERR_FNF:
            errstring = "JAR file not found";
            break;

        case JAR_ERR_CORRUPT:
            errstring = "Corrupt JAR file";
            break;

        case JAR_ERR_MEMORY:
            errstring = "Out of memory";
            break;

        case JAR_ERR_DISK:
            errstring = "Disk error (perhaps out of space)";
            break;

        case JAR_ERR_ORDER:
            errstring = "Inconsistent files in META-INF directory";
            break;

        case JAR_ERR_SIG:
            errstring = "Invalid digital signature file";
            break;

        case JAR_ERR_METADATA:
            errstring = "JAR metadata failed verification";
            break;

        case JAR_ERR_ENTRY:
            errstring = "No Manifest entry for this JAR entry";
            break;

        case JAR_ERR_HASH:
            errstring = "Invalid Hash of this JAR entry";
            break;

        case JAR_ERR_PK7:
            errstring = "Strange PKCS7 or RSA failure";
            break;

        case JAR_ERR_PNF:
            errstring = "Path not found inside JAR file";
            break;

        default:
            if (jar_fn_GetString) {
                errstring = jar_fn_GetString(status);
            } else {
                /* this is not a normal situation, and would only be
	       called in cases of improper initialization */
                char *err = (char *)PORT_Alloc(40);
                if (err)
                    PR_snprintf(err, 39, "Error %d\n", status); /* leak me! */
                else
                    err = "Error! Bad! Out of memory!";
                return err;
            }
            break;
    }
    return errstring;
}
