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

/*
 * CMS digesting.
 */

#include "cmslocal.h"

#include "cert.h"
#include "keyhi.h"
#include "secitem.h"
#include "secoid.h"
#include "pk11func.h"
#include "prtime.h"
#include "secerr.h"

/*  #define CMS_FIND_LEAK_MULTIPLE 1 */
#ifdef CMS_FIND_LEAK_MULTIPLE
static int stop_on_err = 1;
static int global_num_digests = 0;
#endif

struct digestPairStr {
    const SECHashObject *digobj;
    void *digcx;
};
typedef struct digestPairStr digestPair;

struct NSSCMSDigestContextStr {
    PRBool saw_contents;
    PLArenaPool *pool;
    int digcnt;
    digestPair *digPairs;
};

/*
 * NSS_CMSDigestContext_StartMultiple - start digest calculation using all the
 *  digest algorithms in "digestalgs" in parallel.
 */
NSSCMSDigestContext *
NSS_CMSDigestContext_StartMultiple(SECAlgorithmID **digestalgs)
{
    PLArenaPool *pool;
    NSSCMSDigestContext *cmsdigcx;
    int digcnt;
    int i;

#ifdef CMS_FIND_LEAK_MULTIPLE
    PORT_Assert(global_num_digests == 0 || !stop_on_err);
#endif

    digcnt = (digestalgs == NULL) ? 0 : NSS_CMSArray_Count((void **)digestalgs);
    /* It's OK if digcnt is zero.  We have to allow this for "certs only"
    ** messages.
    */
    pool = PORT_NewArena(2048);
    if (!pool)
        return NULL;

    cmsdigcx = PORT_ArenaNew(pool, NSSCMSDigestContext);
    if (cmsdigcx == NULL)
        goto loser;

    cmsdigcx->saw_contents = PR_FALSE;
    cmsdigcx->pool = pool;
    cmsdigcx->digcnt = digcnt;

    cmsdigcx->digPairs = PORT_ArenaZNewArray(pool, digestPair, digcnt);
    if (cmsdigcx->digPairs == NULL) {
        goto loser;
    }

    /*
     * Create a digest object context for each algorithm.
     */
    for (i = 0; i < digcnt; i++) {
        const SECHashObject *digobj;
        void *digcx;

        digobj = NSS_CMSUtil_GetHashObjByAlgID(digestalgs[i]);
        /*
         * Skip any algorithm we do not even recognize; obviously,
         * this could be a problem, but if it is critical then the
         * result will just be that the signature does not verify.
         * We do not necessarily want to error out here, because
         * the particular algorithm may not actually be important,
         * but we cannot know that until later.
         */
        if (digobj == NULL)
            continue;

        digcx = (*digobj->create)();
        if (digcx != NULL) {
            (*digobj->begin)(digcx);
            cmsdigcx->digPairs[i].digobj = digobj;
            cmsdigcx->digPairs[i].digcx = digcx;
#ifdef CMS_FIND_LEAK_MULTIPLE
            global_num_digests++;
#endif
        }
    }
    return cmsdigcx;

loser:
    /* no digest objects have been created, or need to be destroyed. */
    if (pool) {
        PORT_FreeArena(pool, PR_FALSE);
    }
    return NULL;
}

/*
 * NSS_CMSDigestContext_StartSingle - same as
 * NSS_CMSDigestContext_StartMultiple, but only one algorithm.
 */
NSSCMSDigestContext *
NSS_CMSDigestContext_StartSingle(SECAlgorithmID *digestalg)
{
    SECAlgorithmID *digestalgs[] = { NULL, NULL }; /* fake array */

    digestalgs[0] = digestalg;
    return NSS_CMSDigestContext_StartMultiple(digestalgs);
}

/*
 * NSS_CMSDigestContext_Update - feed more data into the digest machine
 */
void
NSS_CMSDigestContext_Update(NSSCMSDigestContext *cmsdigcx,
                            const unsigned char *data, int len)
{
    int i;
    digestPair *pair = cmsdigcx->digPairs;

    cmsdigcx->saw_contents = PR_TRUE;

    for (i = 0; i < cmsdigcx->digcnt; i++, pair++) {
        if (pair->digcx) {
            (*pair->digobj->update)(pair->digcx, data, len);
        }
    }
}

/*
 * NSS_CMSDigestContext_Cancel - cancel digesting operation
 */
void
NSS_CMSDigestContext_Cancel(NSSCMSDigestContext *cmsdigcx)
{
    int i;
    digestPair *pair = cmsdigcx->digPairs;

    for (i = 0; i < cmsdigcx->digcnt; i++, pair++) {
        if (pair->digcx) {
            (*pair->digobj->destroy)(pair->digcx, PR_TRUE);
#ifdef CMS_FIND_LEAK_MULTIPLE
            --global_num_digests;
#endif
        }
    }
#ifdef CMS_FIND_LEAK_MULTIPLE
    PORT_Assert(global_num_digests == 0 || !stop_on_err);
#endif
    PORT_FreeArena(cmsdigcx->pool, PR_FALSE);
}

/*
 * NSS_CMSDigestContext_FinishMultiple - finish the digests and put them
 *  into an array of SECItems (allocated on poolp)
 */
SECStatus
NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx,
                                    PLArenaPool *poolp,
                                    SECItem ***digestsp)
{
    SECItem **digests = NULL;
    digestPair *pair;
    void *mark;
    int i;
    SECStatus rv;

    /* no contents? do not finish digests */
    if (digestsp == NULL || !cmsdigcx->saw_contents) {
        rv = SECSuccess;
        goto cleanup;
    }

    mark = PORT_ArenaMark(poolp);

    /* allocate digest array & SECItems on arena */
    digests = PORT_ArenaNewArray(poolp, SECItem *, cmsdigcx->digcnt + 1);

    rv = ((digests == NULL) ? SECFailure : SECSuccess);
    pair = cmsdigcx->digPairs;
    for (i = 0; rv == SECSuccess && i < cmsdigcx->digcnt; i++, pair++) {
        SECItem digest;
        unsigned char hash[HASH_LENGTH_MAX];

        if (!pair->digcx) {
            digests[i] = NULL;
            continue;
        }

        digest.type = siBuffer;
        digest.data = hash;
        digest.len = pair->digobj->length;
        (*pair->digobj->end)(pair->digcx, hash, &digest.len, digest.len);
        digests[i] = SECITEM_ArenaDupItem(poolp, &digest);
        if (!digests[i]) {
            rv = SECFailure;
        }
    }
    digests[i] = NULL;
    if (rv == SECSuccess) {
        PORT_ArenaUnmark(poolp, mark);
    } else
        PORT_ArenaRelease(poolp, mark);

cleanup:
    NSS_CMSDigestContext_Cancel(cmsdigcx);
    /* Don't change the caller's digests pointer if we have no digests.
    **  NSS_CMSSignedData_Encode_AfterData depends on this behavior.
    */
    if (rv == SECSuccess && digestsp && digests) {
        *digestsp = digests;
    }
    return rv;
}

/*
 * NSS_CMSDigestContext_FinishSingle - same as
 * NSS_CMSDigestContext_FinishMultiple, but for one digest.
 */
SECStatus
NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx,
                                  PLArenaPool *poolp,
                                  SECItem *digest)
{
    SECStatus rv = SECFailure;
    SECItem **dp;
    PLArenaPool *arena = NULL;

    if ((arena = PORT_NewArena(1024)) == NULL)
        goto loser;

    /* get the digests into arena, then copy the first digest into poolp */
    rv = NSS_CMSDigestContext_FinishMultiple(cmsdigcx, arena, &dp);
    if (rv == SECSuccess) {
        /* now copy it into poolp */
        rv = SECITEM_CopyItem(poolp, digest, dp[0]);
    }
loser:
    if (arena)
        PORT_FreeArena(arena, PR_FALSE);

    return rv;
}
