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

#include "nssrenam.h"
#include "nss.h"
#include "p12t.h"
#include "p12.h"
#include "plarena.h"
#include "secitem.h"
#include "secoid.h"
#include "seccomon.h"
#include "secport.h"
#include "cert.h"
#include "secpkcs7.h"
#include "secasn1.h"
#include "secerr.h"
#include "pk11func.h"
#include "p12plcy.h"
#include "p12local.h"
#include "secder.h"
#include "secport.h"

#include "certdb.h"

#include "prcpucfg.h"

/* This belongs in secport.h */
#define PORT_ArenaGrowArray(poolp, oldptr, type, oldnum, newnum) \
    (type *)PORT_ArenaGrow((poolp), (oldptr),                    \
                           (oldnum) * sizeof(type), (newnum) * sizeof(type))

typedef struct sec_PKCS12SafeContentsContextStr sec_PKCS12SafeContentsContext;

/* Opaque structure for decoding SafeContents.  These are used
 * for each authenticated safe as well as any nested safe contents.
 */
struct sec_PKCS12SafeContentsContextStr {
    /* the parent decoder context */
    SEC_PKCS12DecoderContext *p12dcx;

    /* memory arena to allocate space from */
    PLArenaPool *arena;

    /* decoder context and destination for decoding safe contents */
    SEC_ASN1DecoderContext *safeContentsA1Dcx;
    sec_PKCS12SafeContents safeContents;

    /* information for decoding safe bags within the safe contents.
     * these variables are updated for each safe bag decoded.
     */
    SEC_ASN1DecoderContext *currentSafeBagA1Dcx;
    sec_PKCS12SafeBag *currentSafeBag;
    PRBool skipCurrentSafeBag;

    /* if the safe contents is nested, the parent is pointed to here. */
    sec_PKCS12SafeContentsContext *nestedSafeContentsCtx;
};

/* opaque decoder context structure.  information for decoding a pkcs 12
 * PDU are stored here as well as decoding pointers for intermediary
 * structures which are part of the PKCS 12 PDU.  Upon a successful
 * decode, the safe bags containing certificates and keys encountered.
 */
struct SEC_PKCS12DecoderContextStr {
    PLArenaPool *arena;
    PK11SlotInfo *slot;
    void *wincx;
    PRBool error;
    int errorValue;

    /* password */
    SECItem *pwitem;

    /* used for decoding the PFX structure */
    SEC_ASN1DecoderContext *pfxA1Dcx;
    sec_PKCS12PFXItem pfx;

    /* safe bags found during decoding */
    sec_PKCS12SafeBag **safeBags;
    unsigned int safeBagCount;

    /* state variables for decoding authenticated safes. */
    SEC_PKCS7DecoderContext *currentASafeP7Dcx;
    SEC_ASN1DecoderContext *aSafeA1Dcx;
    SEC_PKCS7DecoderContext *aSafeP7Dcx;
    SEC_PKCS7ContentInfo *aSafeCinfo;
    sec_PKCS12AuthenticatedSafe authSafe;
    sec_PKCS12SafeContents safeContents;

    /* safe contents info */
    unsigned int safeContentsCnt;
    sec_PKCS12SafeContentsContext **safeContentsList;

    /* HMAC info */
    sec_PKCS12MacData macData;

    /* routines for reading back the data to be hmac'd */
    /* They are called as follows.
     *
     * Stage 1: decode the aSafes cinfo into a buffer in dArg,
     * which p12d.c sometimes refers to as the "temp file".
     * This occurs during SEC_PKCS12DecoderUpdate calls.
     *
     * dOpen(dArg, PR_FALSE)
     * dWrite(dArg, buf, len)
     * ...
     * dWrite(dArg, buf, len)
     * dClose(dArg, PR_FALSE)
     *
     * Stage 2: verify MAC
     * This occurs SEC_PKCS12DecoderVerify.
     *
     * dOpen(dArg, PR_TRUE)
     * dRead(dArg, buf, IN_BUF_LEN)
     * ...
     * dRead(dArg, buf, IN_BUF_LEN)
     * dClose(dArg, PR_TRUE)
     */
    digestOpenFn dOpen;
    digestCloseFn dClose;
    digestIOFn dRead, dWrite;
    void *dArg;
    PRBool dIsOpen; /* is the temp file created? */

    /* helper functions */
    SECKEYGetPasswordKey pwfn;
    void *pwfnarg;
    PRBool swapUnicodeBytes;
    PRBool forceUnicode;

    /* import information */
    PRBool bagsVerified;

    /* buffer management for the default callbacks implementation */
    void *buffer;       /* storage area */
    PRInt32 filesize;   /* actual data size */
    PRInt32 allocated;  /* total buffer size allocated */
    PRInt32 currentpos; /* position counter */
    SECPKCS12TargetTokenCAs tokenCAs;
    sec_PKCS12SafeBag **keyList; /* used by ...IterateNext() */
    unsigned int iteration;
    SEC_PKCS12DecoderItem decitem;
};

/* forward declarations of functions that are used when decoding
 * safeContents bags which are nested and when decoding the
 * authenticatedSafes.
 */
static SECStatus
sec_pkcs12_decoder_begin_nested_safe_contents(sec_PKCS12SafeContentsContext
                                                  *safeContentsCtx);
static SECStatus
sec_pkcs12_decoder_finish_nested_safe_contents(sec_PKCS12SafeContentsContext
                                                   *safeContentsCtx);

/* make sure that the PFX version being decoded is a version
 * which we support.
 */
static PRBool
sec_pkcs12_proper_version(sec_PKCS12PFXItem *pfx)
{
    /* if no version, assume it is not supported */
    if (pfx->version.len == 0) {
        return PR_FALSE;
    }

    if (DER_GetInteger(&pfx->version) > SEC_PKCS12_VERSION) {
        return PR_FALSE;
    }

    return PR_TRUE;
}

/* retrieve the key for decrypting the safe contents */
static PK11SymKey *
sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid)
{
    SEC_PKCS12DecoderContext *p12dcx = (SEC_PKCS12DecoderContext *)arg;
    PK11SlotInfo *slot;
    PK11SymKey *bulkKey;
    SECItem pwitem = { 0 };
    SECOidTag algorithm;

    if (!p12dcx) {
        return NULL;
    }

    /* if no slot specified, use the internal key slot */
    if (p12dcx->slot) {
        slot = PK11_ReferenceSlot(p12dcx->slot);
    } else {
        slot = PK11_GetInternalKeySlot();
    }

    algorithm = SECOID_GetAlgorithmTag(algid);

    if (p12dcx->forceUnicode) {
        if (SECITEM_CopyItem(NULL, &pwitem, p12dcx->pwitem) != SECSuccess) {
            PK11_FreeSlot(slot);
            return NULL;
        }
    } else {
        if (!sec_pkcs12_decode_password(NULL, &pwitem, algorithm, p12dcx->pwitem)) {
            PK11_FreeSlot(slot);
            return NULL;
        }
    }

    bulkKey = PK11_PBEKeyGen(slot, algid, &pwitem, PR_FALSE, p12dcx->wincx);
    /* some tokens can't generate PBE keys on their own, generate the
     * key in the internal slot, and let the Import code deal with it,
     * (if the slot can't generate PBEs, then we need to use the internal
     * slot anyway to unwrap). */
    if (!bulkKey && !PK11_IsInternal(slot)) {
        PK11_FreeSlot(slot);
        slot = PK11_GetInternalKeySlot();
        bulkKey = PK11_PBEKeyGen(slot, algid, &pwitem, PR_FALSE, p12dcx->wincx);
    }
    PK11_FreeSlot(slot);

    /* set the password data on the key */
    if (bulkKey) {
        PK11_SetSymKeyUserData(bulkKey, p12dcx->pwitem, NULL);
    }

    if (pwitem.data) {
        SECITEM_ZfreeItem(&pwitem, PR_FALSE);
    }

    return bulkKey;
}

/* XXX this needs to be modified to handle enveloped data.  most
 * likely, it should mirror the routines for SMIME in that regard.
 */
static PRBool
sec_pkcs12_decoder_decryption_allowed(SECAlgorithmID *algid,
                                      PK11SymKey *bulkkey)
{
    PRBool decryptionAllowed = SEC_PKCS12DecryptionAllowed(algid);

    if (!decryptionAllowed) {
        return PR_FALSE;
    }

    return PR_TRUE;
}

/* when we encounter a new safe bag during the decoding, we need
 * to allocate space for the bag to be decoded to and set the
 * state variables appropriately.  all of the safe bags are allocated
 * in a buffer in the outer SEC_PKCS12DecoderContext, however,
 * a pointer to the safeBag is also used in the sec_PKCS12SafeContentsContext
 * for the current bag.
 */
static SECStatus
sec_pkcs12_decoder_init_new_safe_bag(sec_PKCS12SafeContentsContext
                                         *safeContentsCtx)
{
    void *mark = NULL;
    SEC_PKCS12DecoderContext *p12dcx;

    /* make sure that the structures are defined, and there has
     * not been an error in the decoding
     */
    if (!safeContentsCtx || !safeContentsCtx->p12dcx || safeContentsCtx->p12dcx->error) {
        return SECFailure;
    }

    p12dcx = safeContentsCtx->p12dcx;
    mark = PORT_ArenaMark(p12dcx->arena);

    /* allocate a new safe bag, if bags already exist, grow the
     * list of bags, otherwise allocate a new list.  the list is
     * NULL terminated.
     */
    p12dcx->safeBags = (!p12dcx->safeBagCount)
                           ? PORT_ArenaZNewArray(p12dcx->arena, sec_PKCS12SafeBag *, 2)
                           : PORT_ArenaGrowArray(p12dcx->arena, p12dcx->safeBags,
                                                 sec_PKCS12SafeBag *, p12dcx->safeBagCount + 1,
                                                 p12dcx->safeBagCount + 2);

    if (!p12dcx->safeBags) {
        p12dcx->errorValue = PORT_GetError();
        goto loser;
    }

    /* append the bag to the end of the list and update the reference
     * in the safeContentsCtx.
     */
    p12dcx->safeBags[p12dcx->safeBagCount] =
        safeContentsCtx->currentSafeBag =
            PORT_ArenaZNew(p12dcx->arena, sec_PKCS12SafeBag);
    if (!safeContentsCtx->currentSafeBag) {
        p12dcx->errorValue = PORT_GetError();
        goto loser;
    }
    p12dcx->safeBags[++p12dcx->safeBagCount] = NULL;

    safeContentsCtx->currentSafeBag->slot = safeContentsCtx->p12dcx->slot;
    safeContentsCtx->currentSafeBag->pwitem = safeContentsCtx->p12dcx->pwitem;
    safeContentsCtx->currentSafeBag->swapUnicodeBytes =
        safeContentsCtx->p12dcx->swapUnicodeBytes;
    safeContentsCtx->currentSafeBag->arena = safeContentsCtx->p12dcx->arena;
    safeContentsCtx->currentSafeBag->tokenCAs =
        safeContentsCtx->p12dcx->tokenCAs;

    PORT_ArenaUnmark(p12dcx->arena, mark);
    return SECSuccess;

loser:

    /* if an error occurred, release the memory and set the error flag
     * the only possible errors triggered by this function are memory
     * related.
     */
    if (mark) {
        PORT_ArenaRelease(p12dcx->arena, mark);
    }

    p12dcx->error = PR_TRUE;
    return SECFailure;
}

/* A wrapper for updating the ASN1 context in which a safeBag is
 * being decoded.  This function is called as a callback from
 * secasn1d when decoding SafeContents structures.
 */
static void
sec_pkcs12_decoder_safe_bag_update(void *arg, const char *data,
                                   unsigned long len, int depth,
                                   SEC_ASN1EncodingPart data_kind)
{
    sec_PKCS12SafeContentsContext *safeContentsCtx =
        (sec_PKCS12SafeContentsContext *)arg;
    SEC_PKCS12DecoderContext *p12dcx;
    SECStatus rv;

    /* make sure that we are not skipping the current safeBag,
     * and that there are no errors.  If so, just return rather
     * than continuing to process.
     */
    if (!safeContentsCtx || !safeContentsCtx->p12dcx ||
        safeContentsCtx->p12dcx->error || safeContentsCtx->skipCurrentSafeBag) {
        return;
    }
    p12dcx = safeContentsCtx->p12dcx;

    rv = SEC_ASN1DecoderUpdate(safeContentsCtx->currentSafeBagA1Dcx, data, len);
    if (rv != SECSuccess) {
        p12dcx->errorValue = PORT_GetError();
        goto loser;
    }

    return;

loser:
    /* set the error, and finish the decoder context.  because there
     * is not a way of returning an error message, it may be worth
     * while to do a check higher up and finish any decoding contexts
     * that are still open.
     */
    p12dcx->error = PR_TRUE;
    SEC_ASN1DecoderFinish(safeContentsCtx->currentSafeBagA1Dcx);
    safeContentsCtx->currentSafeBagA1Dcx = NULL;
    return;
}

/* notify function for decoding safeBags.  This function is
 * used to filter safeBag types which are not supported,
 * initiate the decoding of nested safe contents, and decode
 * safeBags in general.  this function is set when the decoder
 * context for the safeBag is first created.
 */
static void
sec_pkcs12_decoder_safe_bag_notify(void *arg, PRBool before,
                                   void *dest, int real_depth)
{
    sec_PKCS12SafeContentsContext *safeContentsCtx =
        (sec_PKCS12SafeContentsContext *)arg;
    SEC_PKCS12DecoderContext *p12dcx;
    sec_PKCS12SafeBag *bag;
    PRBool after;

    /* if an error is encountered, return */
    if (!safeContentsCtx || !safeContentsCtx->p12dcx ||
        safeContentsCtx->p12dcx->error) {
        return;
    }
    p12dcx = safeContentsCtx->p12dcx;

    /* to make things more readable */
    if (before)
        after = PR_FALSE;
    else
        after = PR_TRUE;

    /* have we determined the safeBagType yet? */
    bag = safeContentsCtx->currentSafeBag;
    if (bag->bagTypeTag == NULL) {
        if (after && (dest == &(bag->safeBagType))) {
            bag->bagTypeTag = SECOID_FindOID(&(bag->safeBagType));
            if (bag->bagTypeTag == NULL) {
                p12dcx->error = PR_TRUE;
                p12dcx->errorValue = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
            }
        }
        return;
    }

    /* process the safeBag depending on it's type.  those
     * which we do not support, are ignored.  we start a decoding
     * context for a nested safeContents.
     */
    switch (bag->bagTypeTag->offset) {
        case SEC_OID_PKCS12_V1_KEY_BAG_ID:
        case SEC_OID_PKCS12_V1_CERT_BAG_ID:
        case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
            break;
        case SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID:
            /* if we are just starting to decode the safeContents, initialize
             * a new safeContentsCtx to process it.
             */
            if (before && (dest == &(bag->safeBagContent))) {
                sec_pkcs12_decoder_begin_nested_safe_contents(safeContentsCtx);
            } else if (after && (dest == &(bag->safeBagContent))) {
                /* clean up the nested decoding */
                sec_pkcs12_decoder_finish_nested_safe_contents(safeContentsCtx);
            }
            break;
        case SEC_OID_PKCS12_V1_CRL_BAG_ID:
        case SEC_OID_PKCS12_V1_SECRET_BAG_ID:
        default:
            /* skip any safe bag types we don't understand or handle */
            safeContentsCtx->skipCurrentSafeBag = PR_TRUE;
            break;
    }

    return;
}

/* notify function for decoding safe contents.  each entry in the
 * safe contents is a safeBag which needs to be allocated and
 * the decoding context initialized at the beginning and then
 * the context needs to be closed and finished at the end.
 *
 * this function is set when the safeContents decode context is
 * initialized.
 */
static void
sec_pkcs12_decoder_safe_contents_notify(void *arg, PRBool before,
                                        void *dest, int real_depth)
{
    sec_PKCS12SafeContentsContext *safeContentsCtx =
        (sec_PKCS12SafeContentsContext *)arg;
    SEC_PKCS12DecoderContext *p12dcx;
    SECStatus rv;

    /* if there is an error we don't want to continue processing,
     * just return and keep going.
     */
    if (!safeContentsCtx || !safeContentsCtx->p12dcx ||
        safeContentsCtx->p12dcx->error) {
        return;
    }
    p12dcx = safeContentsCtx->p12dcx;

    /* if we are done with the current safeBag, then we need to
     * finish the context and set the state variables appropriately.
     */
    if (!before) {
        SEC_ASN1DecoderClearFilterProc(safeContentsCtx->safeContentsA1Dcx);
        SEC_ASN1DecoderFinish(safeContentsCtx->currentSafeBagA1Dcx);
        safeContentsCtx->currentSafeBagA1Dcx = NULL;
        safeContentsCtx->skipCurrentSafeBag = PR_FALSE;
    } else {
        /* we are starting a new safe bag.  we need to allocate space
         * for the bag and initialize the decoding context.
         */
        rv = sec_pkcs12_decoder_init_new_safe_bag(safeContentsCtx);
        if (rv != SECSuccess) {
            goto loser;
        }

        /* set up the decoder context */
        safeContentsCtx->currentSafeBagA1Dcx =
            SEC_ASN1DecoderStart(p12dcx->arena,
                                 safeContentsCtx->currentSafeBag,
                                 sec_PKCS12SafeBagTemplate);
        if (!safeContentsCtx->currentSafeBagA1Dcx) {
            p12dcx->errorValue = PORT_GetError();
            goto loser;
        }

        /* set the notify and filter procs so that the safe bag
         * data gets sent to the proper location when decoding.
         */
        SEC_ASN1DecoderSetNotifyProc(safeContentsCtx->currentSafeBagA1Dcx,
                                     sec_pkcs12_decoder_safe_bag_notify,
                                     safeContentsCtx);
        SEC_ASN1DecoderSetFilterProc(safeContentsCtx->safeContentsA1Dcx,
                                     sec_pkcs12_decoder_safe_bag_update,
                                     safeContentsCtx, PR_TRUE);
    }

    return;

loser:
    /* in the event of an error, we want to close the decoding
     * context and clear the filter and notify procedures.
     */
    p12dcx->error = PR_TRUE;

    if (safeContentsCtx->currentSafeBagA1Dcx) {
        SEC_ASN1DecoderFinish(safeContentsCtx->currentSafeBagA1Dcx);
        safeContentsCtx->currentSafeBagA1Dcx = NULL;
    }

    SEC_ASN1DecoderClearNotifyProc(safeContentsCtx->safeContentsA1Dcx);
    SEC_ASN1DecoderClearFilterProc(safeContentsCtx->safeContentsA1Dcx);

    return;
}

/* initialize the safeContents for decoding.  this routine
 * is used for authenticatedSafes as well as nested safeContents.
 */
static sec_PKCS12SafeContentsContext *
sec_pkcs12_decoder_safe_contents_init_decode(SEC_PKCS12DecoderContext *p12dcx,
                                             PRBool nestedSafe)
{
    sec_PKCS12SafeContentsContext *safeContentsCtx = NULL;
    const SEC_ASN1Template *theTemplate;

    if (!p12dcx || p12dcx->error) {
        return NULL;
    }

    /* allocate a new safeContents list or grow the existing list and
     * append the new safeContents onto the end.
     */
    p12dcx->safeContentsList = (!p12dcx->safeContentsCnt)
                                   ? PORT_ArenaZNewArray(p12dcx->arena, sec_PKCS12SafeContentsContext *, 2)
                                   : PORT_ArenaGrowArray(p12dcx->arena, p12dcx->safeContentsList,
                                                         sec_PKCS12SafeContentsContext *,
                                                         1 + p12dcx->safeContentsCnt,
                                                         2 + p12dcx->safeContentsCnt);

    if (!p12dcx->safeContentsList) {
        p12dcx->errorValue = PORT_GetError();
        goto loser;
    }

    p12dcx->safeContentsList[p12dcx->safeContentsCnt] = safeContentsCtx =
        PORT_ArenaZNew(p12dcx->arena, sec_PKCS12SafeContentsContext);
    if (!p12dcx->safeContentsList[p12dcx->safeContentsCnt]) {
        p12dcx->errorValue = PORT_GetError();
        goto loser;
    }
    p12dcx->safeContentsList[++p12dcx->safeContentsCnt] = NULL;

    /* set up the state variables */
    safeContentsCtx->p12dcx = p12dcx;
    safeContentsCtx->arena = p12dcx->arena;

    /* begin the decoding -- the template is based on whether we are
     * decoding a nested safeContents or not.
     */
    if (nestedSafe == PR_TRUE) {
        theTemplate = sec_PKCS12NestedSafeContentsDecodeTemplate;
    } else {
        theTemplate = sec_PKCS12SafeContentsDecodeTemplate;
    }

    /* start the decoder context */
    safeContentsCtx->safeContentsA1Dcx = SEC_ASN1DecoderStart(p12dcx->arena,
                                                              &safeContentsCtx->safeContents,
                                                              theTemplate);

    if (!safeContentsCtx->safeContentsA1Dcx) {
        p12dcx->errorValue = PORT_GetError();
        goto loser;
    }

    /* set the safeContents notify procedure to look for
     * and start the decode of safeBags.
     */
    SEC_ASN1DecoderSetNotifyProc(safeContentsCtx->safeContentsA1Dcx,
                                 sec_pkcs12_decoder_safe_contents_notify,
                                 safeContentsCtx);

    return safeContentsCtx;

loser:
    /* in the case of an error, we want to finish the decoder
     * context and set the error flag.
     */
    if (safeContentsCtx && safeContentsCtx->safeContentsA1Dcx) {
        SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
        safeContentsCtx->safeContentsA1Dcx = NULL;
    }

    p12dcx->error = PR_TRUE;

    return NULL;
}

/* wrapper for updating safeContents.  this is set as the filter of
 * safeBag when there is a nested safeContents.
 */
static void
sec_pkcs12_decoder_nested_safe_contents_update(void *arg, const char *buf,
                                               unsigned long len, int depth,
                                               SEC_ASN1EncodingPart data_kind)
{
    sec_PKCS12SafeContentsContext *safeContentsCtx =
        (sec_PKCS12SafeContentsContext *)arg;
    SEC_PKCS12DecoderContext *p12dcx;
    SECStatus rv;

    /* check for an error */
    if (!safeContentsCtx || !safeContentsCtx->p12dcx ||
        safeContentsCtx->p12dcx->error || !safeContentsCtx->safeContentsA1Dcx) {
        return;
    }

    /* no need to update if no data sent in */
    if (!len || !buf) {
        return;
    }

    /* update the decoding context */
    p12dcx = safeContentsCtx->p12dcx;
    rv = SEC_ASN1DecoderUpdate(safeContentsCtx->safeContentsA1Dcx, buf, len);
    if (rv != SECSuccess) {
        p12dcx->errorValue = PORT_GetError();
        goto loser;
    }

    return;

loser:
    /* handle any errors.  If a decoding context is open, close it. */
    p12dcx->error = PR_TRUE;
    if (safeContentsCtx->safeContentsA1Dcx) {
        SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
        safeContentsCtx->safeContentsA1Dcx = NULL;
    }
}

/* whenever a new safeContentsSafeBag is encountered, we need
 * to init a safeContentsContext.
 */
static SECStatus
sec_pkcs12_decoder_begin_nested_safe_contents(sec_PKCS12SafeContentsContext
                                                  *safeContentsCtx)
{
    /* check for an error */
    if (!safeContentsCtx || !safeContentsCtx->p12dcx ||
        safeContentsCtx->p12dcx->error) {
        return SECFailure;
    }

    safeContentsCtx->nestedSafeContentsCtx =
        sec_pkcs12_decoder_safe_contents_init_decode(safeContentsCtx->p12dcx,
                                                     PR_TRUE);
    if (!safeContentsCtx->nestedSafeContentsCtx) {
        return SECFailure;
    }

    /* set up new filter proc */
    SEC_ASN1DecoderSetNotifyProc(
        safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx,
        sec_pkcs12_decoder_safe_contents_notify,
        safeContentsCtx->nestedSafeContentsCtx);

    SEC_ASN1DecoderSetFilterProc(safeContentsCtx->currentSafeBagA1Dcx,
                                 sec_pkcs12_decoder_nested_safe_contents_update,
                                 safeContentsCtx->nestedSafeContentsCtx,
                                 PR_TRUE);

    return SECSuccess;
}

/* when the safeContents is done decoding, we need to reset the
 * proper filter and notify procs and close the decoding context
 */
static SECStatus
sec_pkcs12_decoder_finish_nested_safe_contents(sec_PKCS12SafeContentsContext
                                                   *safeContentsCtx)
{
    /* check for error */
    if (!safeContentsCtx || !safeContentsCtx->p12dcx ||
        safeContentsCtx->p12dcx->error) {
        return SECFailure;
    }

    /* clean up */
    SEC_ASN1DecoderClearFilterProc(safeContentsCtx->currentSafeBagA1Dcx);
    SEC_ASN1DecoderClearNotifyProc(
        safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx);
    SEC_ASN1DecoderFinish(
        safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx);
    safeContentsCtx->nestedSafeContentsCtx->safeContentsA1Dcx = NULL;
    safeContentsCtx->nestedSafeContentsCtx = NULL;

    return SECSuccess;
}

/* wrapper for updating safeContents.  This is used when decoding
 * the nested safeContents and any authenticatedSafes.
 */
static void
sec_pkcs12_decoder_safe_contents_callback(void *arg, const char *buf,
                                          unsigned long len)
{
    SECStatus rv;
    sec_PKCS12SafeContentsContext *safeContentsCtx =
        (sec_PKCS12SafeContentsContext *)arg;
    SEC_PKCS12DecoderContext *p12dcx;

    /* check for error */
    if (!safeContentsCtx || !safeContentsCtx->p12dcx ||
        safeContentsCtx->p12dcx->error || !safeContentsCtx->safeContentsA1Dcx) {
        return;
    }
    p12dcx = safeContentsCtx->p12dcx;

    /* update the decoder */
    rv = SEC_ASN1DecoderUpdate(safeContentsCtx->safeContentsA1Dcx, buf, len);
    if (rv != SECSuccess) {
        /* if we fail while trying to decode a 'safe', it's probably because
         * we didn't have the correct password. */
        PORT_SetError(SEC_ERROR_BAD_PASSWORD);
        p12dcx->errorValue = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
        SEC_PKCS7DecoderAbort(p12dcx->currentASafeP7Dcx, SEC_ERROR_BAD_PASSWORD);
        goto loser;
    }

    return;

loser:
    /* set the error and finish the context */
    p12dcx->error = PR_TRUE;
    if (safeContentsCtx->safeContentsA1Dcx) {
        SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
        safeContentsCtx->safeContentsA1Dcx = NULL;
    }

    return;
}

/* this is a wrapper for the ASN1 decoder to call SEC_PKCS7DecoderUpdate
 */
static void
sec_pkcs12_decoder_wrap_p7_update(void *arg, const char *data,
                                  unsigned long len, int depth,
                                  SEC_ASN1EncodingPart data_kind)
{
    SEC_PKCS7DecoderContext *p7dcx = (SEC_PKCS7DecoderContext *)arg;

    SEC_PKCS7DecoderUpdate(p7dcx, data, len);
}

/* notify function for decoding aSafes.  at the beginning,
 * of an authenticatedSafe, we start a decode of a safeContents.
 * at the end, we clean up the safeContents decoder context and
 * reset state variables
 */
static void
sec_pkcs12_decoder_asafes_notify(void *arg, PRBool before, void *dest,
                                 int real_depth)
{
    SEC_PKCS12DecoderContext *p12dcx;
    sec_PKCS12SafeContentsContext *safeContentsCtx;

    /* make sure no error occurred. */
    p12dcx = (SEC_PKCS12DecoderContext *)arg;
    if (!p12dcx || p12dcx->error) {
        return;
    }

    if (before) {

        /* init a new safeContentsContext */
        safeContentsCtx = sec_pkcs12_decoder_safe_contents_init_decode(p12dcx,
                                                                       PR_FALSE);
        if (!safeContentsCtx) {
            goto loser;
        }

        /* initiate the PKCS7ContentInfo decode */
        p12dcx->currentASafeP7Dcx = SEC_PKCS7DecoderStart(
            sec_pkcs12_decoder_safe_contents_callback,
            safeContentsCtx,
            p12dcx->pwfn, p12dcx->pwfnarg,
            sec_pkcs12_decoder_get_decrypt_key, p12dcx,
            sec_pkcs12_decoder_decryption_allowed);
        if (!p12dcx->currentASafeP7Dcx) {
            p12dcx->errorValue = PORT_GetError();
            goto loser;
        }
        SEC_ASN1DecoderSetFilterProc(p12dcx->aSafeA1Dcx,
                                     sec_pkcs12_decoder_wrap_p7_update,
                                     p12dcx->currentASafeP7Dcx, PR_TRUE);
    }

    if (!before) {
        /* if one is being decoded, finish the decode */
        if (p12dcx->currentASafeP7Dcx != NULL) {
            SEC_PKCS7ContentInfo *cinfo;
            unsigned int cnt = p12dcx->safeContentsCnt - 1;
            safeContentsCtx = p12dcx->safeContentsList[cnt];
            if (safeContentsCtx->safeContentsA1Dcx) {
                SEC_ASN1DecoderClearFilterProc(p12dcx->aSafeA1Dcx);
                SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
                safeContentsCtx->safeContentsA1Dcx = NULL;
            }
            cinfo = SEC_PKCS7DecoderFinish(p12dcx->currentASafeP7Dcx);
            p12dcx->currentASafeP7Dcx = NULL;
            if (!cinfo) {
                p12dcx->errorValue = PORT_GetError();
                goto loser;
            }
            SEC_PKCS7DestroyContentInfo(cinfo); /* don't leak it */
        }
    }

    return;

loser:
    /* set the error flag */
    p12dcx->error = PR_TRUE;
    return;
}

/* wrapper for updating asafes decoding context.  this function
 * writes data being decoded to disk, so that a mac can be computed
 * later.
 */
static void
sec_pkcs12_decoder_asafes_callback(void *arg, const char *buf,
                                   unsigned long len)
{
    SEC_PKCS12DecoderContext *p12dcx = (SEC_PKCS12DecoderContext *)arg;
    SECStatus rv;

    if (!p12dcx || p12dcx->error) {
        return;
    }

    /* update the context */
    rv = SEC_ASN1DecoderUpdate(p12dcx->aSafeA1Dcx, buf, len);
    if (rv != SECSuccess) {
        p12dcx->errorValue = PORT_GetError();
        p12dcx->error = PR_TRUE;
        goto loser;
    }

    /* if we are writing to a file, write out the new information */
    if (p12dcx->dWrite) {
        unsigned long writeLen = (*p12dcx->dWrite)(p12dcx->dArg,
                                                   (unsigned char *)buf, len);
        if (writeLen != len) {
            p12dcx->errorValue = PORT_GetError();
            goto loser;
        }
    }

    return;

loser:
    /* set the error flag */
    p12dcx->error = PR_TRUE;
    SEC_ASN1DecoderFinish(p12dcx->aSafeA1Dcx);
    p12dcx->aSafeA1Dcx = NULL;

    return;
}

/* start the decode of an authenticatedSafe contentInfo.
 */
static SECStatus
sec_pkcs12_decode_start_asafes_cinfo(SEC_PKCS12DecoderContext *p12dcx)
{
    if (!p12dcx || p12dcx->error) {
        return SECFailure;
    }

    /* start the decode context */
    p12dcx->aSafeA1Dcx = SEC_ASN1DecoderStart(p12dcx->arena,
                                              &p12dcx->authSafe,
                                              sec_PKCS12AuthenticatedSafeTemplate);
    if (!p12dcx->aSafeA1Dcx) {
        p12dcx->errorValue = PORT_GetError();
        goto loser;
    }

    /* set the notify function */
    SEC_ASN1DecoderSetNotifyProc(p12dcx->aSafeA1Dcx,
                                 sec_pkcs12_decoder_asafes_notify, p12dcx);

    /* begin the authSafe decoder context */
    p12dcx->aSafeP7Dcx = SEC_PKCS7DecoderStart(
        sec_pkcs12_decoder_asafes_callback, p12dcx,
        p12dcx->pwfn, p12dcx->pwfnarg, NULL, NULL, NULL);
    if (!p12dcx->aSafeP7Dcx) {
        p12dcx->errorValue = PORT_GetError();
        goto loser;
    }

    /* open the temp file for writing, if the digest functions were set */
    if (p12dcx->dOpen && (*p12dcx->dOpen)(p12dcx->dArg, PR_FALSE) != SECSuccess) {
        p12dcx->errorValue = PORT_GetError();
        goto loser;
    }
    /* dOpen(dArg, PR_FALSE) creates the temp file */
    p12dcx->dIsOpen = PR_TRUE;

    return SECSuccess;

loser:
    p12dcx->error = PR_TRUE;

    if (p12dcx->aSafeA1Dcx) {
        SEC_ASN1DecoderFinish(p12dcx->aSafeA1Dcx);
        p12dcx->aSafeA1Dcx = NULL;
    }

    if (p12dcx->aSafeP7Dcx) {
        SEC_PKCS7DecoderFinish(p12dcx->aSafeP7Dcx);
        p12dcx->aSafeP7Dcx = NULL;
    }

    return SECFailure;
}

/* wrapper for updating the safeContents.  this function is used as
 * a filter for the pfx when decoding the authenticated safes
 */
static void
sec_pkcs12_decode_asafes_cinfo_update(void *arg, const char *buf,
                                      unsigned long len, int depth,
                                      SEC_ASN1EncodingPart data_kind)
{
    SEC_PKCS12DecoderContext *p12dcx;
    SECStatus rv;

    p12dcx = (SEC_PKCS12DecoderContext *)arg;
    if (!p12dcx || p12dcx->error) {
        return;
    }

    /* update the safeContents decoder */
    rv = SEC_PKCS7DecoderUpdate(p12dcx->aSafeP7Dcx, buf, len);
    if (rv != SECSuccess) {
        p12dcx->errorValue = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
        goto loser;
    }

    return;

loser:

    /* did we find an error?  if so, close the context and set the
     * error flag.
     */
    SEC_PKCS7DecoderFinish(p12dcx->aSafeP7Dcx);
    p12dcx->aSafeP7Dcx = NULL;
    p12dcx->error = PR_TRUE;
}

/* notify procedure used while decoding the pfx.  When we encounter
 * the authSafes, we want to trigger the decoding of authSafes as well
 * as when we encounter the macData, trigger the decoding of it.  we do
 * this because we we are streaming the decoder and not decoding in place.
 * the pfx which is the destination, only has the version decoded into it.
 */
static void
sec_pkcs12_decoder_pfx_notify_proc(void *arg, PRBool before, void *dest,
                                   int real_depth)
{
    SECStatus rv;
    SEC_PKCS12DecoderContext *p12dcx = (SEC_PKCS12DecoderContext *)arg;

    /* if an error occurs, clear the notifyProc and the filterProc
     * and continue.
     */
    if (p12dcx->error) {
        SEC_ASN1DecoderClearNotifyProc(p12dcx->pfxA1Dcx);
        SEC_ASN1DecoderClearFilterProc(p12dcx->pfxA1Dcx);
        return;
    }

    if (before && (dest == &p12dcx->pfx.encodedAuthSafe)) {

        /* we want to make sure this is a version we support */
        if (!sec_pkcs12_proper_version(&p12dcx->pfx)) {
            p12dcx->errorValue = SEC_ERROR_PKCS12_UNSUPPORTED_VERSION;
            goto loser;
        }

        /* start the decode of the aSafes cinfo... */
        rv = sec_pkcs12_decode_start_asafes_cinfo(p12dcx);
        if (rv != SECSuccess) {
            goto loser;
        }

        /* set the filter proc to update the authenticated safes. */
        SEC_ASN1DecoderSetFilterProc(p12dcx->pfxA1Dcx,
                                     sec_pkcs12_decode_asafes_cinfo_update,
                                     p12dcx, PR_TRUE);
    }

    if (!before && (dest == &p12dcx->pfx.encodedAuthSafe)) {

        /* we are done decoding the authenticatedSafes, so we need to
         * finish the decoderContext and clear the filter proc
         * and close the hmac callback, if present
         */
        p12dcx->aSafeCinfo = SEC_PKCS7DecoderFinish(p12dcx->aSafeP7Dcx);
        p12dcx->aSafeP7Dcx = NULL;
        if (!p12dcx->aSafeCinfo) {
            p12dcx->errorValue = PORT_GetError();
            goto loser;
        }
        SEC_ASN1DecoderClearFilterProc(p12dcx->pfxA1Dcx);
        if (p12dcx->dClose && ((*p12dcx->dClose)(p12dcx->dArg, PR_FALSE) != SECSuccess)) {
            p12dcx->errorValue = PORT_GetError();
            goto loser;
        }
    }

    return;

loser:
    p12dcx->error = PR_TRUE;
}

/*  default implementations of the open/close/read/write functions for
    SEC_PKCS12DecoderStart
*/

#define DEFAULT_TEMP_SIZE 4096

static SECStatus
p12u_DigestOpen(void *arg, PRBool readData)
{
    SEC_PKCS12DecoderContext *p12cxt = arg;

    p12cxt->currentpos = 0;

    if (PR_FALSE == readData) {
        /* allocate an initial buffer */
        p12cxt->filesize = 0;
        p12cxt->allocated = DEFAULT_TEMP_SIZE;
        p12cxt->buffer = PORT_Alloc(DEFAULT_TEMP_SIZE);
        PR_ASSERT(p12cxt->buffer);
    } else {
        PR_ASSERT(p12cxt->buffer);
        if (!p12cxt->buffer) {
            return SECFailure; /* no data to read */
        }
    }

    return SECSuccess;
}

static SECStatus
p12u_DigestClose(void *arg, PRBool removeFile)
{
    SEC_PKCS12DecoderContext *p12cxt = arg;

    PR_ASSERT(p12cxt);
    if (!p12cxt) {
        return SECFailure;
    }
    p12cxt->currentpos = 0;

    if (PR_TRUE == removeFile) {
        PR_ASSERT(p12cxt->buffer);
        if (!p12cxt->buffer) {
            return SECFailure;
        }
        if (p12cxt->buffer) {
            PORT_Free(p12cxt->buffer);
            p12cxt->buffer = NULL;
            p12cxt->allocated = 0;
            p12cxt->filesize = 0;
        }
    }

    return SECSuccess;
}

static int
p12u_DigestRead(void *arg, unsigned char *buf, unsigned long len)
{
    int toread = len;
    SEC_PKCS12DecoderContext *p12cxt = arg;

    if (!buf || len == 0 || !p12cxt->buffer) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return -1;
    }

    if ((p12cxt->filesize - p12cxt->currentpos) < (long)len) {
        /* trying to read past the end of the buffer */
        toread = p12cxt->filesize - p12cxt->currentpos;
    }
    memcpy(buf, (char *)p12cxt->buffer + p12cxt->currentpos, toread);
    p12cxt->currentpos += toread;
    return toread;
}

static int
p12u_DigestWrite(void *arg, unsigned char *buf, unsigned long len)
{
    SEC_PKCS12DecoderContext *p12cxt = arg;

    if (!buf || len == 0) {
        return -1;
    }

    if (p12cxt->currentpos + (long)len > p12cxt->filesize) {
        p12cxt->filesize = p12cxt->currentpos + len;
    } else {
        p12cxt->filesize += len;
    }
    if (p12cxt->filesize > p12cxt->allocated) {
        void *newbuffer;
        size_t newsize = p12cxt->filesize + DEFAULT_TEMP_SIZE;
        newbuffer = PORT_Realloc(p12cxt->buffer, newsize);
        if (NULL == newbuffer) {
            return -1; /* can't extend the buffer */
        }
        p12cxt->buffer = newbuffer;
        p12cxt->allocated = newsize;
    }
    PR_ASSERT(p12cxt->buffer);
    memcpy((char *)p12cxt->buffer + p12cxt->currentpos, buf, len);
    p12cxt->currentpos += len;
    return len;
}

/* SEC_PKCS12DecoderStart
 *      Creates a decoder context for decoding a PKCS 12 PDU objct.
 *      This function sets up the initial decoding context for the
 *      PFX and sets the needed state variables.
 *
 *      pwitem - the password for the hMac and any encoded safes.
 *               this should be changed to take a callback which retrieves
 *               the password.  it may be possible for different safes to
 *               have different passwords.  also, the password is already
 *               in unicode.  it should probably be converted down below via
 *               a unicode conversion callback.
 *      slot - the slot to import the dataa into should multiple slots
 *               be supported based on key type and cert type?
 *      dOpen, dClose, dRead, dWrite - digest routines for writing data
 *               to a file so it could be read back and the hmac recomputed
 *               and verified.  doesn't seem to be a way for both encoding
 *               and decoding to be single pass, thus the need for these
 *               routines.
 *      dArg - the argument for dOpen, etc.
 *
 *      if NULL == dOpen == dClose == dRead == dWrite == dArg, then default
 *      implementations using a memory buffer are used
 *
 *      This function returns the decoder context, if it was successful.
 *      Otherwise, null is returned.
 */
SEC_PKCS12DecoderContext *
SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
                       digestOpenFn dOpen, digestCloseFn dClose,
                       digestIOFn dRead, digestIOFn dWrite, void *dArg)
{
    SEC_PKCS12DecoderContext *p12dcx;
    PLArenaPool *arena;
    PRInt32 forceUnicode = PR_FALSE;
    SECStatus rv;

    arena = PORT_NewArena(2048); /* different size? */
    if (!arena) {
        return NULL; /* error is already set */
    }

    /* allocate the decoder context and set the state variables */
    p12dcx = PORT_ArenaZNew(arena, SEC_PKCS12DecoderContext);
    if (!p12dcx) {
        goto loser; /* error is already set */
    }

    if (!dOpen && !dClose && !dRead && !dWrite && !dArg) {
        /* use default implementations */
        dOpen = p12u_DigestOpen;
        dClose = p12u_DigestClose;
        dRead = p12u_DigestRead;
        dWrite = p12u_DigestWrite;
        dArg = (void *)p12dcx;
    }

    p12dcx->arena = arena;
    p12dcx->pwitem = pwitem;
    p12dcx->slot = (slot ? PK11_ReferenceSlot(slot)
                         : PK11_GetInternalKeySlot());
    p12dcx->wincx = wincx;
    p12dcx->tokenCAs = SECPKCS12TargetTokenNoCAs;
#ifdef IS_LITTLE_ENDIAN
    p12dcx->swapUnicodeBytes = PR_TRUE;
#else
    p12dcx->swapUnicodeBytes = PR_FALSE;
#endif
    rv = NSS_OptionGet(__NSS_PKCS12_DECODE_FORCE_UNICODE, &forceUnicode);
    if (rv != SECSuccess) {
        goto loser;
    }
    p12dcx->forceUnicode = forceUnicode;
    p12dcx->errorValue = 0;
    p12dcx->error = PR_FALSE;

    /* start the decoding of the PFX and set the notify proc
     * for the PFX item.
     */
    p12dcx->pfxA1Dcx = SEC_ASN1DecoderStart(p12dcx->arena, &p12dcx->pfx,
                                            sec_PKCS12PFXItemTemplate);
    if (!p12dcx->pfxA1Dcx) {
        PK11_FreeSlot(p12dcx->slot);
        goto loser;
    }

    SEC_ASN1DecoderSetNotifyProc(p12dcx->pfxA1Dcx,
                                 sec_pkcs12_decoder_pfx_notify_proc,
                                 p12dcx);

    /* set up digest functions */
    p12dcx->dOpen = dOpen;
    p12dcx->dWrite = dWrite;
    p12dcx->dClose = dClose;
    p12dcx->dRead = dRead;
    p12dcx->dArg = dArg;
    p12dcx->dIsOpen = PR_FALSE;

    p12dcx->keyList = NULL;
    p12dcx->decitem.type = 0;
    p12dcx->decitem.der = NULL;
    p12dcx->decitem.hasKey = PR_FALSE;
    p12dcx->decitem.friendlyName = NULL;
    p12dcx->iteration = 0;

    return p12dcx;

loser:
    PORT_FreeArena(arena, PR_TRUE);
    return NULL;
}

SECStatus
SEC_PKCS12DecoderSetTargetTokenCAs(SEC_PKCS12DecoderContext *p12dcx,
                                   SECPKCS12TargetTokenCAs tokenCAs)
{
    if (!p12dcx || p12dcx->error) {
        return SECFailure;
    }
    p12dcx->tokenCAs = tokenCAs;
    return SECSuccess;
}

/* SEC_PKCS12DecoderUpdate
 *      Streaming update sending more data to the decoder.  If
 *      an error occurs, SECFailure is returned.
 *
 *      p12dcx - the decoder context
 *      data, len - the data buffer and length of data to send to
 *              the update functions.
 */
SECStatus
SEC_PKCS12DecoderUpdate(SEC_PKCS12DecoderContext *p12dcx,
                        unsigned char *data, unsigned long len)
{
    SECStatus rv;

    if (!p12dcx || p12dcx->error) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* update the PFX decoder context */
    rv = SEC_ASN1DecoderUpdate(p12dcx->pfxA1Dcx, (const char *)data, len);
    if (rv != SECSuccess) {
        p12dcx->errorValue = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
        goto loser;
    }

    return SECSuccess;

loser:

    p12dcx->error = PR_TRUE;
    return SECFailure;
}

/* This should be a nice sized buffer for reading in data (potentially large
** amounts) to be MACed.  It should be MUCH larger than HASH_LENGTH_MAX.
*/
#define IN_BUF_LEN 1024
#ifdef DEBUG
static const char bufferEnd[] = { "BufferEnd" };
#endif
#define FUDGE 128 /* must be as large as bufferEnd or more. */

/* verify the hmac by reading the data from the temporary file
 * using the routines specified when the decodingContext was
 * created and return SECSuccess if the hmac matches.
 */
static SECStatus
sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
{
    PK11Context *pk11cx = NULL;
    PK11SymKey *symKey = NULL;
    SECItem *params = NULL;
    unsigned char *buf;
    SECStatus rv = SECFailure;
    SECStatus lrv;
    unsigned int bufLen;
    int iteration;
    int bytesRead;
    SECOidTag algtag;
    SECItem hmacRes;
    SECItem ignore = { 0 };
    CK_MECHANISM_TYPE integrityMech;

    if (!p12dcx || p12dcx->error) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    buf = (unsigned char *)PORT_Alloc(IN_BUF_LEN + FUDGE);
    if (!buf)
        return SECFailure; /* error code has been set. */

#ifdef DEBUG
    memcpy(buf + IN_BUF_LEN, bufferEnd, sizeof bufferEnd);
#endif

    /* generate hmac key */
    if (p12dcx->macData.iter.data) {
        iteration = (int)DER_GetInteger(&p12dcx->macData.iter);
    } else {
        iteration = 1;
    }

    params = PK11_CreatePBEParams(&p12dcx->macData.macSalt, p12dcx->pwitem,
                                  iteration);

    algtag = SECOID_GetAlgorithmTag(&p12dcx->macData.safeMac.digestAlgorithm);
    switch (algtag) {
        case SEC_OID_SHA1:
            integrityMech = CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN;
            break;
        case SEC_OID_MD5:
            integrityMech = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN;
            break;
        case SEC_OID_MD2:
            integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN;
            break;
        case SEC_OID_SHA224:
            integrityMech = CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN;
            break;
        case SEC_OID_SHA256:
            integrityMech = CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN;
            break;
        case SEC_OID_SHA384:
            integrityMech = CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN;
            break;
        case SEC_OID_SHA512:
            integrityMech = CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN;
            break;
        default:
            goto loser;
    }

    symKey = PK11_KeyGen(NULL, integrityMech, params, 0, NULL);
    PK11_DestroyPBEParams(params);
    params = NULL;
    if (!symKey)
        goto loser;
    /* init hmac */
    pk11cx = PK11_CreateContextBySymKey(sec_pkcs12_algtag_to_mech(algtag),
                                        CKA_SIGN, symKey, &ignore);
    if (!pk11cx) {
        goto loser;
    }
    lrv = PK11_DigestBegin(pk11cx);
    if (lrv == SECFailure) {
        goto loser;
    }

    /* try to open the data for readback */
    if (p12dcx->dOpen && ((*p12dcx->dOpen)(p12dcx->dArg, PR_TRUE) != SECSuccess)) {
        goto loser;
    }

    /* read the data back IN_BUF_LEN bytes at a time and recompute
     * the hmac.  if fewer bytes are read than are requested, it is
     * assumed that the end of file has been reached. if bytesRead
     * is returned as -1, then an error occurred reading from the
     * file.
     */
    do {
        bytesRead = (*p12dcx->dRead)(p12dcx->dArg, buf, IN_BUF_LEN);
        if (bytesRead < 0) {
            PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_READ);
            goto loser;
        }
        PORT_Assert(bytesRead <= IN_BUF_LEN);
        PORT_Assert(!memcmp(buf + IN_BUF_LEN, bufferEnd, sizeof bufferEnd));

        if (bytesRead > IN_BUF_LEN) {
            /* dRead callback overflowed buffer. */
            PORT_SetError(SEC_ERROR_INPUT_LEN);
            goto loser;
        }

        if (bytesRead) {
            lrv = PK11_DigestOp(pk11cx, buf, bytesRead);
            if (lrv == SECFailure) {
                goto loser;
            }
        }
    } while (bytesRead == IN_BUF_LEN);

    /* finish the hmac context */
    lrv = PK11_DigestFinal(pk11cx, buf, &bufLen, IN_BUF_LEN);
    if (lrv == SECFailure) {
        goto loser;
    }

    hmacRes.data = buf;
    hmacRes.len = bufLen;

    /* is the hmac computed the same as the hmac which was decoded? */
    rv = SECSuccess;
    if (SECITEM_CompareItem(&hmacRes, &p12dcx->macData.safeMac.digest) != SECEqual) {
        PORT_SetError(SEC_ERROR_PKCS12_INVALID_MAC);
        rv = SECFailure;
    }

loser:
    /* close the file and remove it */
    if (p12dcx->dClose) {
        (*p12dcx->dClose)(p12dcx->dArg, PR_TRUE);
        p12dcx->dIsOpen = PR_FALSE;
    }

    if (pk11cx) {
        PK11_DestroyContext(pk11cx, PR_TRUE);
    }
    if (params) {
        PK11_DestroyPBEParams(params);
    }
    if (symKey) {
        PK11_FreeSymKey(symKey);
    }
    PORT_ZFree(buf, IN_BUF_LEN + FUDGE);

    return rv;
}

/* SEC_PKCS12DecoderVerify
 *      Verify the macData or the signature of the decoded PKCS 12 PDU.
 *      If the signature or the macData do not match, SECFailure is
 *      returned.
 *
 *      p12dcx - the decoder context
 */
SECStatus
SEC_PKCS12DecoderVerify(SEC_PKCS12DecoderContext *p12dcx)
{
    SECStatus rv = SECSuccess;

    /* make sure that no errors have occurred... */
    if (!p12dcx) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (p12dcx->error) {
        /* error code is already set! PORT_SetError(p12dcx->errorValue); */
        return SECFailure;
    }

    rv = SEC_ASN1DecoderFinish(p12dcx->pfxA1Dcx);
    p12dcx->pfxA1Dcx = NULL;
    if (rv != SECSuccess) {
        return rv;
    }

    /* check the signature or the mac depending on the type of
     * integrity used.
     */
    if (p12dcx->pfx.encodedMacData.len) {
        rv = SEC_ASN1DecodeItem(p12dcx->arena, &p12dcx->macData,
                                sec_PKCS12MacDataTemplate,
                                &p12dcx->pfx.encodedMacData);
        if (rv == SECSuccess) {
            return sec_pkcs12_decoder_verify_mac(p12dcx);
        }
        return rv;
    }
    if (SEC_PKCS7VerifySignature(p12dcx->aSafeCinfo, certUsageEmailSigner,
                                 PR_FALSE)) {
        return SECSuccess;
    }
    PORT_SetError(SEC_ERROR_PKCS12_INVALID_MAC);
    return SECFailure;
}

/* SEC_PKCS12DecoderFinish
 *      Free any open ASN1 or PKCS7 decoder contexts and then
 *      free the arena pool which everything should be allocated
 *      from.  This function should be called upon completion of
 *      decoding and installing of a pfx pdu.  This should be
 *      called even if an error occurs.
 *
 *      p12dcx - the decoder context
 */
void
SEC_PKCS12DecoderFinish(SEC_PKCS12DecoderContext *p12dcx)
{
    unsigned int i;

    if (!p12dcx) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return;
    }

    if (p12dcx->pfxA1Dcx) {
        SEC_ASN1DecoderFinish(p12dcx->pfxA1Dcx);
        p12dcx->pfxA1Dcx = NULL;
    }

    if (p12dcx->aSafeA1Dcx) {
        SEC_ASN1DecoderFinish(p12dcx->aSafeA1Dcx);
        p12dcx->aSafeA1Dcx = NULL;
    }

    /* cleanup any old ASN1 decoder contexts */
    for (i = 0; i < p12dcx->safeContentsCnt; ++i) {
        sec_PKCS12SafeContentsContext *safeContentsCtx, *nested;
        safeContentsCtx = p12dcx->safeContentsList[i];
        if (safeContentsCtx) {
            nested = safeContentsCtx->nestedSafeContentsCtx;
            while (nested) {
                if (nested->safeContentsA1Dcx) {
                    SEC_ASN1DecoderFinish(nested->safeContentsA1Dcx);
                    nested->safeContentsA1Dcx = NULL;
                }
                nested = nested->nestedSafeContentsCtx;
            }
            if (safeContentsCtx->safeContentsA1Dcx) {
                SEC_ASN1DecoderFinish(safeContentsCtx->safeContentsA1Dcx);
                safeContentsCtx->safeContentsA1Dcx = NULL;
            }
        }
    }

    if (p12dcx->currentASafeP7Dcx &&
        p12dcx->currentASafeP7Dcx != p12dcx->aSafeP7Dcx) {
        SEC_PKCS7ContentInfo *cinfo;
        cinfo = SEC_PKCS7DecoderFinish(p12dcx->currentASafeP7Dcx);
        if (cinfo) {
            SEC_PKCS7DestroyContentInfo(cinfo); /* don't leak it */
        }
    }
    p12dcx->currentASafeP7Dcx = NULL;

    if (p12dcx->aSafeP7Dcx) {
        SEC_PKCS7ContentInfo *cinfo;
        cinfo = SEC_PKCS7DecoderFinish(p12dcx->aSafeP7Dcx);
        if (cinfo) {
            SEC_PKCS7DestroyContentInfo(cinfo);
        }
        p12dcx->aSafeP7Dcx = NULL;
    }

    if (p12dcx->aSafeCinfo) {
        SEC_PKCS7DestroyContentInfo(p12dcx->aSafeCinfo);
        p12dcx->aSafeCinfo = NULL;
    }

    if (p12dcx->decitem.type != 0 && p12dcx->decitem.der != NULL) {
        SECITEM_FreeItem(p12dcx->decitem.der, PR_TRUE);
    }
    if (p12dcx->decitem.friendlyName != NULL) {
        SECITEM_FreeItem(p12dcx->decitem.friendlyName, PR_TRUE);
    }

    if (p12dcx->slot) {
        PK11_FreeSlot(p12dcx->slot);
        p12dcx->slot = NULL;
    }

    if (p12dcx->dIsOpen && p12dcx->dClose) {
        (*p12dcx->dClose)(p12dcx->dArg, PR_TRUE);
        p12dcx->dIsOpen = PR_FALSE;
    }

    if (p12dcx->arena) {
        PORT_FreeArena(p12dcx->arena, PR_TRUE);
    }
}

static SECStatus
sec_pkcs12_decoder_set_attribute_value(sec_PKCS12SafeBag *bag,
                                       SECOidTag attributeType,
                                       SECItem *attrValue)
{
    int i = 0;
    SECOidData *oid;

    if (!bag || !attrValue) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    oid = SECOID_FindOIDByTag(attributeType);
    if (!oid) {
        return SECFailure;
    }

    if (!bag->attribs) {
        bag->attribs =
            PORT_ArenaZNewArray(bag->arena, sec_PKCS12Attribute *, 2);
    } else {
        while (bag->attribs[i])
            i++;
        bag->attribs = PORT_ArenaGrowArray(bag->arena, bag->attribs,
                                           sec_PKCS12Attribute *, i + 1, i + 2);
    }

    if (!bag->attribs) {
        return SECFailure;
    }

    bag->attribs[i] = PORT_ArenaZNew(bag->arena, sec_PKCS12Attribute);
    if (!bag->attribs[i]) {
        return SECFailure;
    }

    bag->attribs[i]->attrValue = PORT_ArenaZNewArray(bag->arena, SECItem *, 2);
    if (!bag->attribs[i]->attrValue) {
        return SECFailure;
    }

    bag->attribs[i + 1] = NULL;
    bag->attribs[i]->attrValue[0] = attrValue;
    bag->attribs[i]->attrValue[1] = NULL;

    return SECITEM_CopyItem(bag->arena, &bag->attribs[i]->attrType, &oid->oid);
}

static SECItem *
sec_pkcs12_get_attribute_value(sec_PKCS12SafeBag *bag,
                               SECOidTag attributeType)
{
    int i;

    if (!bag->attribs) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    for (i = 0; bag->attribs[i] != NULL; i++) {
        if (SECOID_FindOIDTag(&bag->attribs[i]->attrType) == attributeType) {
            return bag->attribs[i]->attrValue[0];
        }
    }
    return NULL;
}

/* For now, this function will merely remove any ":"
 * in the nickname which the PK11 functions may have
 * placed there.  This will keep dual certs from appearing
 * twice under "Your" certificates when imported onto smart
 * cards.  Once with the name "Slot:Cert" and another with
 * the nickname "Slot:Slot:Cert"
 */
static void
sec_pkcs12_sanitize_nickname(PK11SlotInfo *slot, SECItem *nick)
{
    char *nickname;
    char *delimit;
    int delimitlen;

    nickname = (char *)nick->data;
    if ((delimit = PORT_Strchr(nickname, ':')) != NULL) {
        char *slotName;
        int slotNameLen;

        slotNameLen = delimit - nickname;
        slotName = PORT_NewArray(char, (slotNameLen + 1));
        PORT_Assert(slotName);
        if (slotName == NULL) {
            /* What else can we do?*/
            return;
        }
        PORT_Memcpy(slotName, nickname, slotNameLen);
        slotName[slotNameLen] = '\0';
        if (PORT_Strcmp(PK11_GetTokenName(slot), slotName) == 0) {
            delimitlen = PORT_Strlen(delimit + 1);
            PORT_Memmove(nickname, delimit + 1, delimitlen + 1);
            nick->len = delimitlen;
        }
        PORT_Free(slotName);
    }
}

static SECItem *
sec_pkcs12_get_nickname(sec_PKCS12SafeBag *bag)
{
    SECItem *src, *dest;

    if (!bag) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    src = sec_pkcs12_get_attribute_value(bag, SEC_OID_PKCS9_FRIENDLY_NAME);

    /* The return value src is 16-bit Unicode characters, in big-endian format.
     * Check if it is NULL or empty name.
     */
    if (!src || !src->data || src->len < 2 || (!src->data[0] && !src->data[1])) {
        return NULL;
    }

    dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
    if (!dest) {
        goto loser;
    }
    if (!sec_pkcs12_convert_item_to_unicode(NULL, dest, src, PR_FALSE,
                                            PR_FALSE, PR_FALSE)) {
        goto loser;
    }

    sec_pkcs12_sanitize_nickname(bag->slot, dest);

    return dest;

loser:
    if (dest) {
        SECITEM_ZfreeItem(dest, PR_TRUE);
    }

    bag->problem = PR_TRUE;
    bag->error = PORT_GetError();
    return NULL;
}

static SECStatus
sec_pkcs12_set_nickname(sec_PKCS12SafeBag *bag, SECItem *name)
{
    sec_PKCS12Attribute *attr = NULL;
    SECOidData *oid = SECOID_FindOIDByTag(SEC_OID_PKCS9_FRIENDLY_NAME);

    if (!bag || !bag->arena || !name) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!bag->attribs) {
        if (!oid) {
            goto loser;
        }

        bag->attribs =
            PORT_ArenaZNewArray(bag->arena, sec_PKCS12Attribute *, 2);
        if (!bag->attribs) {
            goto loser;
        }
        bag->attribs[0] = PORT_ArenaZNew(bag->arena, sec_PKCS12Attribute);
        if (!bag->attribs[0]) {
            goto loser;
        }
        bag->attribs[1] = NULL;

        attr = bag->attribs[0];
        if (SECITEM_CopyItem(bag->arena, &attr->attrType, &oid->oid) != SECSuccess) {
            goto loser;
        }
    } else {
        int i;
        for (i = 0; bag->attribs[i]; i++) {
            if (SECOID_FindOIDTag(&bag->attribs[i]->attrType) == SEC_OID_PKCS9_FRIENDLY_NAME) {
                attr = bag->attribs[i];
                break;
            }
        }
        if (!attr) {
            if (!oid) {
                goto loser;
            }
            bag->attribs = PORT_ArenaGrowArray(bag->arena, bag->attribs,
                                               sec_PKCS12Attribute *, i + 1, i + 2);
            if (!bag->attribs) {
                goto loser;
            }
            bag->attribs[i] = PORT_ArenaZNew(bag->arena, sec_PKCS12Attribute);
            if (!bag->attribs[i]) {
                goto loser;
            }
            bag->attribs[i + 1] = NULL;
            attr = bag->attribs[i];
            if (SECITEM_CopyItem(bag->arena, &attr->attrType, &oid->oid) != SECSuccess) {
                goto loser;
            }
        }
    }

    PORT_Assert(attr);
    if (!attr->attrValue) {
        attr->attrValue = PORT_ArenaZNewArray(bag->arena, SECItem *, 2);
        if (!attr->attrValue) {
            goto loser;
        }
        attr->attrValue[0] = PORT_ArenaZNew(bag->arena, SECItem);
        if (!attr->attrValue[0]) {
            goto loser;
        }
        attr->attrValue[1] = NULL;
    }

    name->len = PORT_Strlen((char *)name->data);
    if (!sec_pkcs12_convert_item_to_unicode(bag->arena, attr->attrValue[0],
                                            name, PR_FALSE, PR_FALSE, PR_TRUE)) {
        goto loser;
    }

    return SECSuccess;

loser:
    bag->problem = PR_TRUE;
    bag->error = PORT_GetError();
    return SECFailure;
}

static SECStatus
sec_pkcs12_get_key_info(sec_PKCS12SafeBag *key)
{
    int i = 0;
    SECKEYPrivateKeyInfo *pki = NULL;

    if (!key) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* if the bag does *not* contain an unencrypted PrivateKeyInfo
     * then we cannot convert the attributes.  We are propagating
     * attributes within the PrivateKeyInfo to the SafeBag level.
     */
    if (SECOID_FindOIDTag(&(key->safeBagType)) !=
        SEC_OID_PKCS12_V1_KEY_BAG_ID) {
        return SECSuccess;
    }

    pki = key->safeBagContent.pkcs8KeyBag;

    if (!pki || !pki->attributes) {
        return SECSuccess;
    }

    while (pki->attributes[i]) {
        SECOidTag tag = SECOID_FindOIDTag(&pki->attributes[i]->attrType);

        if (tag == SEC_OID_PKCS9_LOCAL_KEY_ID ||
            tag == SEC_OID_PKCS9_FRIENDLY_NAME) {
            SECItem *attrValue = sec_pkcs12_get_attribute_value(key, tag);
            if (!attrValue) {
                if (sec_pkcs12_decoder_set_attribute_value(key, tag,
                                                           pki->attributes[i]->attrValue[0]) != SECSuccess) {
                    key->problem = PR_TRUE;
                    key->error = PORT_GetError();
                    return SECFailure;
                }
            }
        }
        i++;
    }

    return SECSuccess;
}

/* retrieve the nickname for the certificate bag.  first look
 * in the cert bag, otherwise get it from the key.
 */
static SECItem *
sec_pkcs12_get_nickname_for_cert(sec_PKCS12SafeBag *cert,
                                 sec_PKCS12SafeBag *key)
{
    SECItem *nickname;

    if (!cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    nickname = sec_pkcs12_get_nickname(cert);
    if (nickname) {
        return nickname;
    }

    if (key) {
        nickname = sec_pkcs12_get_nickname(key);

        if (nickname && sec_pkcs12_set_nickname(cert, nickname) != SECSuccess) {
            SECITEM_ZfreeItem(nickname, PR_TRUE);
            return NULL;
        }
    }

    return nickname;
}

/* set the nickname for the certificate */
static SECStatus
sec_pkcs12_set_nickname_for_cert(sec_PKCS12SafeBag *cert,
                                 sec_PKCS12SafeBag *key,
                                 SECItem *nickname)
{
    if (!nickname || !cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (sec_pkcs12_set_nickname(cert, nickname) != SECSuccess) {
        return SECFailure;
    }

    if (key) {
        if (sec_pkcs12_set_nickname(key, nickname) != SECSuccess) {
            cert->problem = PR_TRUE;
            cert->error = key->error;
            return SECFailure;
        }
    }

    return SECSuccess;
}

/* retrieve the DER cert from the cert bag */
static SECItem *
sec_pkcs12_get_der_cert(sec_PKCS12SafeBag *cert)
{
    if (!cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    if (SECOID_FindOIDTag(&cert->safeBagType) != SEC_OID_PKCS12_V1_CERT_BAG_ID) {
        return NULL;
    }

    /* only support X509 certs not SDSI */
    if (SECOID_FindOIDTag(&cert->safeBagContent.certBag->bagID) != SEC_OID_PKCS9_X509_CERT) {
        return NULL;
    }

    return SECITEM_DupItem(&(cert->safeBagContent.certBag->value.x509Cert));
}

struct certNickInfo {
    PLArenaPool *arena;
    unsigned int nNicks;
    SECItem **nickList;
    unsigned int error;
};

/* callback for traversing certificates to gather the nicknames
 * used in a particular traversal.  for instance, when using
 * CERT_TraversePermCertsForSubject, gather the nicknames and
 * store them in the certNickInfo for a particular DN.
 *
 * this handles the case where multiple nicknames are allowed
 * for the same dn, which is not currently allowed, but may be
 * in the future.
 */
static SECStatus
gatherNicknames(CERTCertificate *cert, void *arg)
{
    struct certNickInfo *nickArg = (struct certNickInfo *)arg;
    SECItem tempNick;
    unsigned int i;

    if (!cert || !nickArg || nickArg->error) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!cert->nickname) {
        return SECSuccess;
    }

    tempNick.data = (unsigned char *)cert->nickname;
    tempNick.len = PORT_Strlen(cert->nickname) + 1;
    tempNick.type = siAsciiString;

    /* do we already have the nickname in the list? */
    if (nickArg->nNicks > 0) {

        /* nicknames have been encountered, but there is no list -- bad */
        if (!nickArg->nickList) {
            nickArg->error = SEC_ERROR_INVALID_ARGS;
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return SECFailure;
        }

        for (i = 0; i < nickArg->nNicks; i++) {
            if (SECITEM_CompareItem(nickArg->nickList[i], &tempNick) == SECEqual) {
                return SECSuccess;
            }
        }
    }

    /* add the nickname to the list */
    nickArg->nickList = (nickArg->nNicks == 0)
                            ? PORT_ArenaZNewArray(nickArg->arena, SECItem *, 2)
                            : PORT_ArenaGrowArray(nickArg->arena, nickArg->nickList, SECItem *,
                                                  nickArg->nNicks + 1, nickArg->nNicks + 2);

    if (!nickArg->nickList) {
        nickArg->error = SEC_ERROR_NO_MEMORY;
        return SECFailure;
    }

    nickArg->nickList[nickArg->nNicks] =
        PORT_ArenaZNew(nickArg->arena, SECItem);
    if (!nickArg->nickList[nickArg->nNicks]) {
        nickArg->error = PORT_GetError();
        return SECFailure;
    }

    if (SECITEM_CopyItem(nickArg->arena, nickArg->nickList[nickArg->nNicks],
                         &tempNick) != SECSuccess) {
        nickArg->error = PORT_GetError();
        return SECFailure;
    }

    nickArg->nNicks++;

    return SECSuccess;
}

/* traverses the certs in the data base or in the token for the
 * DN to see if any certs currently have a nickname set.
 * If so, return it.
 */
static SECItem *
sec_pkcs12_get_existing_nick_for_dn(sec_PKCS12SafeBag *cert)
{
    struct certNickInfo *nickArg = NULL;
    SECItem *derCert, *returnDn = NULL;
    PLArenaPool *arena = NULL;
    CERTCertificate *tempCert;

    if (!cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    derCert = sec_pkcs12_get_der_cert(cert);
    if (!derCert) {
        return NULL;
    }

    tempCert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
    if (!tempCert) {
        returnDn = NULL;
        goto loser;
    }

    arena = PORT_NewArena(1024);
    if (!arena) {
        returnDn = NULL;
        goto loser;
    }
    nickArg = PORT_ArenaZNew(arena, struct certNickInfo);
    if (!nickArg) {
        returnDn = NULL;
        goto loser;
    }
    nickArg->error = 0;
    nickArg->nNicks = 0;
    nickArg->nickList = NULL;
    nickArg->arena = arena;

    /* if the token is local, first traverse the cert database
     * then traverse the token.
     */
    if (PK11_TraverseCertsForSubjectInSlot(tempCert, cert->slot, gatherNicknames,
                                           (void *)nickArg) != SECSuccess) {
        returnDn = NULL;
        goto loser;
    }

    if (nickArg->error) {
        /* XXX do we want to set the error? */
        returnDn = NULL;
        goto loser;
    }

    if (nickArg->nNicks == 0) {
        returnDn = NULL;
        goto loser;
    }

    /* set it to the first name, for now.  handle multiple names? */
    returnDn = SECITEM_DupItem(nickArg->nickList[0]);

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_TRUE);
    }

    if (tempCert) {
        CERT_DestroyCertificate(tempCert);
    }

    if (derCert) {
        SECITEM_FreeItem(derCert, PR_TRUE);
    }

    return (returnDn);
}

/* counts certificates found for a given traversal function */
static SECStatus
countCertificate(CERTCertificate *cert, void *arg)
{
    unsigned int *nCerts = (unsigned int *)arg;

    if (!cert || !arg) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    (*nCerts)++;
    return SECSuccess;
}

static PRBool
sec_pkcs12_certs_for_nickname_exist(SECItem *nickname, PK11SlotInfo *slot)
{
    unsigned int nCerts = 0;

    if (!nickname || !slot) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return PR_TRUE;
    }

    /* we want to check the local database first if we are importing to it */
    PK11_TraverseCertsForNicknameInSlot(nickname, slot, countCertificate,
                                        (void *)&nCerts);
    return (PRBool)(nCerts != 0);
}

/* validate cert nickname such that there is a one-to-one relation
 * between nicknames and dn's.  we want to enforce the case that the
 * nickname is non-NULL and that there is only one nickname per DN.
 *
 * if there is a problem with a nickname or the nickname is not present,
 * the user will be prompted for it.
 */
static void
sec_pkcs12_validate_cert_nickname(sec_PKCS12SafeBag *cert,
                                  sec_PKCS12SafeBag *key,
                                  SEC_PKCS12NicknameCollisionCallback nicknameCb,
                                  CERTCertificate *leafCert)
{
    SECItem *certNickname, *existingDNNick;
    PRBool setNickname = PR_FALSE, cancel = PR_FALSE;
    SECItem *newNickname = NULL;

    if (!cert || !cert->hasKey) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return;
    }

    if (!nicknameCb) {
        cert->problem = PR_TRUE;
        cert->error = SEC_ERROR_INVALID_ARGS;
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return;
    }

    if (cert->hasKey && !key) {
        cert->problem = PR_TRUE;
        cert->error = SEC_ERROR_INVALID_ARGS;
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return;
    }

    certNickname = sec_pkcs12_get_nickname_for_cert(cert, key);
    existingDNNick = sec_pkcs12_get_existing_nick_for_dn(cert);

    /* nickname is already used w/ this dn, so it is safe to return */
    if (certNickname && existingDNNick &&
        SECITEM_CompareItem(certNickname, existingDNNick) == SECEqual) {
        goto loser;
    }

    /* nickname not set in pkcs 12 bags, but a nick is already used for
     * this dn.  set the nicks in the p12 bags and finish.
     */
    if (existingDNNick) {
        sec_pkcs12_set_nickname_for_cert(cert, key, existingDNNick);
        goto loser;
    }

    /* at this point, we have a certificate for which the DN is not located
     * on the token.  the nickname specified may or may not be NULL.  if it
     * is not null, we need to make sure that there are no other certificates
     * with this nickname in the token for it to be valid.  this imposes a
     * one to one relationship between DN and nickname.
     *
     * if the nickname is null, we need the user to enter a nickname for
     * the certificate.
     *
     * once we have a nickname, we make sure that the nickname is unique
     * for the DN.  if it is not, the user is reprompted to enter a new
     * nickname.
     *
     * in order to exit this loop, the nickname entered is either unique
     * or the user hits cancel and the certificate is not imported.
     */
    setNickname = PR_FALSE;
    while (1) {
        /* we will use the nickname so long as no other certs have the
         * same nickname.  and the nickname is not NULL.
         */
        if (certNickname && certNickname->data &&
            !sec_pkcs12_certs_for_nickname_exist(certNickname, cert->slot)) {
            if (setNickname) {
                sec_pkcs12_set_nickname_for_cert(cert, key, certNickname);
            }
            break;
        }

        setNickname = PR_FALSE;
        newNickname = (*nicknameCb)(certNickname, &cancel, leafCert);
        if (cancel) {
            cert->problem = PR_TRUE;
            cert->error = SEC_ERROR_USER_CANCELLED;
            break;
        }

        if (!newNickname) {
            cert->problem = PR_TRUE;
            cert->error = PORT_GetError();
            break;
        }

        /* at this point we have a new nickname, if we have an existing
         * certNickname, we need to free it and assign the new nickname
         * to it to avoid a memory leak.  happy?
         */
        if (certNickname) {
            SECITEM_ZfreeItem(certNickname, PR_TRUE);
            certNickname = NULL;
        }

        certNickname = newNickname;
        setNickname = PR_TRUE;
        /* go back and recheck the new nickname */
    }

loser:
    if (certNickname) {
        SECITEM_ZfreeItem(certNickname, PR_TRUE);
    }

    if (existingDNNick) {
        SECITEM_ZfreeItem(existingDNNick, PR_TRUE);
    }
}

static void
sec_pkcs12_validate_cert(sec_PKCS12SafeBag *cert,
                         sec_PKCS12SafeBag *key,
                         SEC_PKCS12NicknameCollisionCallback nicknameCb)
{
    CERTCertificate *leafCert;

    if (!cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return;
    }

    cert->validated = PR_TRUE;

    if (!nicknameCb) {
        cert->noInstall = PR_TRUE;
        cert->problem = PR_TRUE;
        cert->error = SEC_ERROR_INVALID_ARGS;
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return;
    }

    if (!cert->safeBagContent.certBag) {
        cert->noInstall = PR_TRUE;
        cert->problem = PR_TRUE;
        cert->error = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
        return;
    }

    cert->noInstall = PR_FALSE;
    cert->unused = PR_FALSE;
    cert->problem = PR_FALSE;
    cert->error = 0;

    leafCert = CERT_DecodeDERCertificate(
        &cert->safeBagContent.certBag->value.x509Cert, PR_FALSE, NULL);
    if (!leafCert) {
        cert->noInstall = PR_TRUE;
        cert->problem = PR_TRUE;
        cert->error = PORT_GetError();
        return;
    }

    sec_pkcs12_validate_cert_nickname(cert, key, nicknameCb, leafCert);

    CERT_DestroyCertificate(leafCert);
}

static void
sec_pkcs12_validate_key_by_cert(sec_PKCS12SafeBag *cert, sec_PKCS12SafeBag *key,
                                void *wincx)
{
    CERTCertificate *leafCert;
    SECKEYPrivateKey *privk;

    if (!key) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return;
    }

    key->validated = PR_TRUE;

    if (!cert) {
        key->problem = PR_TRUE;
        key->noInstall = PR_TRUE;
        key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
        return;
    }

    leafCert = CERT_DecodeDERCertificate(
        &(cert->safeBagContent.certBag->value.x509Cert), PR_FALSE, NULL);
    if (!leafCert) {
        key->problem = PR_TRUE;
        key->noInstall = PR_TRUE;
        key->error = PORT_GetError();
        return;
    }

    privk = PK11_FindPrivateKeyFromCert(key->slot, leafCert, wincx);
    if (!privk) {
        privk = PK11_FindKeyByDERCert(key->slot, leafCert, wincx);
    }

    if (privk) {
        SECKEY_DestroyPrivateKey(privk);
        key->noInstall = PR_TRUE;
    }

    CERT_DestroyCertificate(leafCert);
}

static SECStatus
sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx)
{
    SECItem *derCert, *nickName;
    char *nickData = NULL;
    PRBool isIntermediateCA;
    SECStatus rv;

    if (!cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (cert->problem || cert->noInstall || cert->installed) {
        return SECSuccess;
    }

    derCert = &cert->safeBagContent.certBag->value.x509Cert;

    PORT_Assert(!cert->problem && !cert->noInstall);

    nickName = sec_pkcs12_get_nickname(cert);
    if (nickName) {
        nickData = (char *)nickName->data;
    }

    isIntermediateCA = CERT_IsCADERCert(derCert, NULL) &&
                       !CERT_IsRootDERCert(derCert);

    if (keyExists) {
        CERTCertificate *newCert;

        newCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                          derCert, NULL, PR_FALSE, PR_FALSE);
        if (!newCert) {
            if (nickName)
                SECITEM_ZfreeItem(nickName, PR_TRUE);
            cert->error = PORT_GetError();
            cert->problem = PR_TRUE;
            return SECFailure;
        }

        rv = PK11_ImportCertForKeyToSlot(cert->slot, newCert, nickData,
                                         PR_TRUE, wincx);
        CERT_DestroyCertificate(newCert);
    } else if ((cert->tokenCAs == SECPKCS12TargetTokenNoCAs) ||
               ((cert->tokenCAs == SECPKCS12TargetTokenIntermediateCAs) &&
                !isIntermediateCA)) {
        SECItem *certList[2];
        certList[0] = derCert;
        certList[1] = NULL;

        rv = CERT_ImportCerts(CERT_GetDefaultCertDB(), certUsageUserCertImport,
                              1, certList, NULL, PR_TRUE, PR_FALSE, nickData);
    } else {
        rv = PK11_ImportDERCert(cert->slot, derCert, CK_INVALID_HANDLE,
                                nickData, PR_FALSE);
    }
    if (rv) {
        cert->problem = 1;
        cert->error = PORT_GetError();
    }
    cert->installed = PR_TRUE;
    if (nickName)
        SECITEM_ZfreeItem(nickName, PR_TRUE);
    return rv;
}

static SECItem *
sec_pkcs12_get_public_value_and_type(SECKEYPublicKey *pubKey, KeyType *type);

static SECStatus
sec_pkcs12_add_key(sec_PKCS12SafeBag *key, SECKEYPublicKey *pubKey,
                   unsigned int keyUsage,
                   SECItem *nickName, PRBool forceUnicode, void *wincx)
{
    SECStatus rv;
    SECItem *publicValue = NULL;
    KeyType keyType;

    /* We should always have values for "key" and "pubKey"
       so they can be dereferenced later. */
    if (!key || !pubKey) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (key->problem || key->noInstall) {
        return SECSuccess;
    }

    /* get the value and type from the public key */
    publicValue = sec_pkcs12_get_public_value_and_type(pubKey, &keyType);
    if (!publicValue) {
        key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
        key->problem = PR_TRUE;
        return SECFailure;
    }

    switch (SECOID_FindOIDTag(&key->safeBagType)) {
        case SEC_OID_PKCS12_V1_KEY_BAG_ID:
            rv = PK11_ImportPrivateKeyInfo(key->slot,
                                           key->safeBagContent.pkcs8KeyBag,
                                           nickName, publicValue, PR_TRUE, PR_TRUE,
                                           keyUsage, wincx);
            break;
        case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID: {
            SECItem pwitem = { 0 };
            SECAlgorithmID *algid =
                &key->safeBagContent.pkcs8ShroudedKeyBag->algorithm;
            SECOidTag algorithm = SECOID_GetAlgorithmTag(algid);

            if (forceUnicode) {
                if (SECITEM_CopyItem(NULL, &pwitem, key->pwitem) != SECSuccess) {
                    key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
                    key->problem = PR_TRUE;
                    return SECFailure;
                }
            } else {
                if (!sec_pkcs12_decode_password(NULL, &pwitem, algorithm,
                                                key->pwitem)) {
                    key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
                    key->problem = PR_TRUE;
                    return SECFailure;
                }
            }

            rv = PK11_ImportEncryptedPrivateKeyInfo(key->slot,
                                                    key->safeBagContent.pkcs8ShroudedKeyBag,
                                                    &pwitem, nickName, publicValue,
                                                    PR_TRUE, PR_TRUE, keyType, keyUsage,
                                                    wincx);
            if (pwitem.data) {
                SECITEM_ZfreeItem(&pwitem, PR_FALSE);
            }
            break;
        }
        default:
            key->error = SEC_ERROR_PKCS12_UNSUPPORTED_VERSION;
            key->problem = PR_TRUE;
            if (nickName) {
                SECITEM_ZfreeItem(nickName, PR_TRUE);
            }
            return SECFailure;
    }

    if (rv != SECSuccess) {
        key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
        key->problem = PR_TRUE;
    } else {
        /* try to import the public key. Failure to do so is not fatal,
         * not all tokens can store the public key */
        if (pubKey) {
            PK11_ImportPublicKey(key->slot, pubKey, PR_TRUE);
        }
        key->installed = PR_TRUE;
    }

    return rv;
}

/*
 * The correctness of the code in this file ABSOLUTELY REQUIRES
 * that ALL BAGs share a single common arena.
 *
 * This function allocates the bag list from the arena of whatever bag
 * happens to be passed to it.  Each time a new bag is handed to it,
 * it grows (resizes) the arena of the bag that was handed to it.
 * If the bags have different arenas, it will grow the wrong arena.
 *
 * Worse, if the bags had separate arenas, then while destroying the bags
 * in a bag list, when the bag whose arena contained the bag list was
 * destroyed, the baglist itself would be destroyed, making it difficult
 * or impossible to continue to destroy the bags in the destroyed list.
 */
static SECStatus
sec_pkcs12_add_item_to_bag_list(sec_PKCS12SafeBag ***bagList,
                                sec_PKCS12SafeBag *bag)
{
    sec_PKCS12SafeBag **newBagList = NULL;
    int i = 0;

    if (!bagList || !bag) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!(*bagList)) {
        newBagList = PORT_ArenaZNewArray(bag->arena, sec_PKCS12SafeBag *, 2);
    } else {
        while ((*bagList)[i])
            i++;
        newBagList = PORT_ArenaGrowArray(bag->arena, *bagList,
                                         sec_PKCS12SafeBag *, i + 1, i + 2);
    }

    if (!newBagList) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    newBagList[i] = bag;
    newBagList[i + 1] = NULL;
    *bagList = newBagList;

    return SECSuccess;
}

static sec_PKCS12SafeBag **
sec_pkcs12_find_certs_for_key(sec_PKCS12SafeBag **safeBags,
                              sec_PKCS12SafeBag *key)
{
    sec_PKCS12SafeBag **certList = NULL;
    SECItem *keyId;
    int i;

    if (!safeBags || !safeBags[0]) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    keyId = sec_pkcs12_get_attribute_value(key, SEC_OID_PKCS9_LOCAL_KEY_ID);
    if (!keyId) {
        return NULL;
    }

    for (i = 0; safeBags[i]; i++) {
        if (SECOID_FindOIDTag(&(safeBags[i]->safeBagType)) == SEC_OID_PKCS12_V1_CERT_BAG_ID) {
            SECItem *certKeyId = sec_pkcs12_get_attribute_value(safeBags[i],
                                                                SEC_OID_PKCS9_LOCAL_KEY_ID);

            if (certKeyId && (SECITEM_CompareItem(certKeyId, keyId) == SECEqual)) {
                if (sec_pkcs12_add_item_to_bag_list(&certList, safeBags[i]) != SECSuccess) {
                    /* This would leak the partial list of safeBags,
                     * but that list is allocated from the arena of
                     * one of the safebags, and will be destroyed when
                     * that arena is destroyed.  So this is not a real leak.
                     */
                    return NULL;
                }
            }
        }
    }

    return certList;
}

CERTCertList *
SEC_PKCS12DecoderGetCerts(SEC_PKCS12DecoderContext *p12dcx)
{
    CERTCertList *certList = NULL;
    sec_PKCS12SafeBag **safeBags;
    int i;

    if (!p12dcx || !p12dcx->safeBags || !p12dcx->safeBags[0]) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    safeBags = p12dcx->safeBags;
    certList = CERT_NewCertList();

    if (certList == NULL) {
        return NULL;
    }

    for (i = 0; safeBags[i]; i++) {
        if (SECOID_FindOIDTag(&(safeBags[i]->safeBagType)) == SEC_OID_PKCS12_V1_CERT_BAG_ID) {
            SECItem *derCert = sec_pkcs12_get_der_cert(safeBags[i]);
            CERTCertificate *tempCert = NULL;

            if (derCert == NULL)
                continue;
            tempCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                               derCert, NULL,
                                               PR_FALSE, PR_TRUE);

            if (tempCert) {
                CERT_AddCertToListTail(certList, tempCert);
            }
            SECITEM_FreeItem(derCert, PR_TRUE);
        }
        /* fixed an infinite loop here, by ensuring that i gets incremented
         * if derCert is NULL above.
         */
    }

    return certList;
}
static sec_PKCS12SafeBag **
sec_pkcs12_get_key_bags(sec_PKCS12SafeBag **safeBags)
{
    int i;
    sec_PKCS12SafeBag **keyList = NULL;
    SECOidTag bagType;

    if (!safeBags || !safeBags[0]) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    for (i = 0; safeBags[i]; i++) {
        bagType = SECOID_FindOIDTag(&(safeBags[i]->safeBagType));
        switch (bagType) {
            case SEC_OID_PKCS12_V1_KEY_BAG_ID:
            case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
                if (sec_pkcs12_add_item_to_bag_list(&keyList, safeBags[i]) != SECSuccess) {
                    /* This would leak, except that keyList is allocated
                     * from the arena shared by all the safeBags.
                     */
                    return NULL;
                }
                break;
            default:
                break;
        }
    }

    return keyList;
}

/* This function takes two passes over the bags, validating them
 * The two passes are intended to mirror exactly the two passes in
 * sec_pkcs12_install_bags.  But they don't. :(
 */
static SECStatus
sec_pkcs12_validate_bags(sec_PKCS12SafeBag **safeBags,
                         SEC_PKCS12NicknameCollisionCallback nicknameCb,
                         void *wincx)
{
    sec_PKCS12SafeBag **keyList;
    int i;

    if (!safeBags || !nicknameCb) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!safeBags[0]) {
        return SECSuccess;
    }

    /* First pass.  Find all the key bags.
     * Find the matching cert(s) for each key.
     */
    keyList = sec_pkcs12_get_key_bags(safeBags);
    if (keyList) {
        for (i = 0; keyList[i]; ++i) {
            sec_PKCS12SafeBag *key = keyList[i];
            sec_PKCS12SafeBag **certList =
                sec_pkcs12_find_certs_for_key(safeBags, key);

            if (certList) {
                int j;

                if (SECOID_FindOIDTag(&(key->safeBagType)) ==
                    SEC_OID_PKCS12_V1_KEY_BAG_ID) {
                    /* if it is an unencrypted private key then make sure
                     * the attributes are propageted to the appropriate
                     * level
                     */
                    if (sec_pkcs12_get_key_info(key) != SECSuccess) {
                        return SECFailure;
                    }
                }

                sec_pkcs12_validate_key_by_cert(certList[0], key, wincx);
                for (j = 0; certList[j]; ++j) {
                    sec_PKCS12SafeBag *cert = certList[j];
                    cert->hasKey = PR_TRUE;
                    if (key->problem) {
                        cert->problem = PR_TRUE;
                        cert->error = key->error;
                        continue;
                    }
                    sec_pkcs12_validate_cert(cert, key, nicknameCb);
                    if (cert->problem) {
                        key->problem = cert->problem;
                        key->error = cert->error;
                    }
                }
            }
        }
    }

    /* Now take a second pass over the safebags and mark for installation any
     * certs that were neither installed nor disqualified by the first pass.
     */
    for (i = 0; safeBags[i]; ++i) {
        sec_PKCS12SafeBag *bag = safeBags[i];

        if (!bag->validated) {
            SECOidTag bagType = SECOID_FindOIDTag(&bag->safeBagType);

            switch (bagType) {
                case SEC_OID_PKCS12_V1_CERT_BAG_ID:
                    sec_pkcs12_validate_cert(bag, NULL, nicknameCb);
                    break;
                case SEC_OID_PKCS12_V1_KEY_BAG_ID:
                case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
                    bag->noInstall = PR_TRUE;
                    bag->problem = PR_TRUE;
                    bag->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
                    break;
                default:
                    bag->noInstall = PR_TRUE;
            }
        }
    }

    return SECSuccess;
}

SECStatus
SEC_PKCS12DecoderValidateBags(SEC_PKCS12DecoderContext *p12dcx,
                              SEC_PKCS12NicknameCollisionCallback nicknameCb)
{
    SECStatus rv;
    int i, noInstallCnt, probCnt, bagCnt, errorVal = 0;
    if (!p12dcx || p12dcx->error || !p12dcx->safeBags) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    rv = sec_pkcs12_validate_bags(p12dcx->safeBags, nicknameCb, p12dcx->wincx);
    if (rv == SECSuccess) {
        p12dcx->bagsVerified = PR_TRUE;
    }

    noInstallCnt = probCnt = bagCnt = 0;
    i = 0;
    while (p12dcx->safeBags[i]) {
        bagCnt++;
        if (p12dcx->safeBags[i]->noInstall)
            noInstallCnt++;
        if (p12dcx->safeBags[i]->problem) {
            probCnt++;
            errorVal = p12dcx->safeBags[i]->error;
        }
        i++;
    }

    /* formerly was erroneous code here that assumed that if all bags
     * failed to import, then the problem was duplicated data;
     * that is, it assume that the problem must be that the file had
     * previously been successfully imported.  But importing a
     * previously imported file causes NO ERRORS at all, and this
     * false assumption caused real errors to be hidden behind false
     * errors about duplicated data.
     */

    if (probCnt) {
        PORT_SetError(errorVal);
        return SECFailure;
    }

    return rv;
}

SECStatus
SEC_PKCS12DecoderRenameCertNicknames(SEC_PKCS12DecoderContext *p12dcx,
                                     SEC_PKCS12NicknameRenameCallback nicknameCb,
                                     void *arg)
{
    int i;
    sec_PKCS12SafeBag *safeBag;
    CERTCertificate *cert;
    SECStatus srv;

    if (!p12dcx || p12dcx->error || !p12dcx->safeBags || !nicknameCb) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    for (i = 0; (safeBag = p12dcx->safeBags[i]); i++) {
        SECItem *newNickname = NULL;
        SECItem *defaultNickname = NULL;
        SECStatus rename_rv;

        if (SECOID_FindOIDTag(&(safeBag->safeBagType)) !=
            SEC_OID_PKCS12_V1_CERT_BAG_ID) {
            continue;
        }

        cert = CERT_DecodeDERCertificate(
            &safeBag->safeBagContent.certBag->value.x509Cert,
            PR_FALSE, NULL);
        if (!cert) {
            return SECFailure;
        }

        defaultNickname = sec_pkcs12_get_nickname(safeBag);
        rename_rv = (*nicknameCb)(cert, defaultNickname, &newNickname, arg);

        CERT_DestroyCertificate(cert);

        if (defaultNickname) {
            SECITEM_ZfreeItem(defaultNickname, PR_TRUE);
            defaultNickname = NULL;
        }

        if (rename_rv != SECSuccess) {
            return rename_rv;
        }

        if (newNickname) {
            srv = sec_pkcs12_set_nickname(safeBag, newNickname);
            SECITEM_ZfreeItem(newNickname, PR_TRUE);
            newNickname = NULL;
            if (srv != SECSuccess) {
                return SECFailure;
            }
        }
    }

    return SECSuccess;
}

static SECKEYPublicKey *
sec_pkcs12_get_public_key_and_usage(sec_PKCS12SafeBag *certBag,
                                    unsigned int *usage)
{
    SECKEYPublicKey *pubKey = NULL;
    CERTCertificate *cert = NULL;

    if (!certBag || !usage) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    *usage = 0;

    cert = CERT_DecodeDERCertificate(
        &certBag->safeBagContent.certBag->value.x509Cert, PR_FALSE, NULL);
    if (!cert) {
        return NULL;
    }

    *usage = cert->keyUsage;
    pubKey = CERT_ExtractPublicKey(cert);
    CERT_DestroyCertificate(cert);
    return pubKey;
}

static SECItem *
sec_pkcs12_get_public_value_and_type(SECKEYPublicKey *pubKey,
                                     KeyType *type)
{
    SECItem *pubValue = NULL;

    if (!type || !pubKey) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    *type = pubKey->keyType;
    switch (pubKey->keyType) {
        case dsaKey:
            pubValue = &pubKey->u.dsa.publicValue;
            break;
        case dhKey:
            pubValue = &pubKey->u.dh.publicValue;
            break;
        case rsaKey:
            pubValue = &pubKey->u.rsa.modulus;
            break;
        case ecKey:
            pubValue = &pubKey->u.ec.publicValue;
            break;
        default:
            pubValue = NULL;
    }

    return pubValue;
}

/* This function takes two passes over the bags, installing them in the
 * desired slot.  The two passes are intended to mirror exactly the
 * two passes in sec_pkcs12_validate_bags.
 */
static SECStatus
sec_pkcs12_install_bags(sec_PKCS12SafeBag **safeBags, PRBool forceUnicode,
                        void *wincx)
{
    sec_PKCS12SafeBag **keyList;
    int i;
    int failedKeys = 0;

    if (!safeBags) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!safeBags[0]) {
        return SECSuccess;
    }

    /* First pass.  Find all the key bags.
     * Try to install them, and any certs associated with them.
     */
    keyList = sec_pkcs12_get_key_bags(safeBags);
    if (keyList) {
        for (i = 0; keyList[i]; i++) {
            SECStatus rv;
            SECKEYPublicKey *pubKey = NULL;
            SECItem *nickName = NULL;
            sec_PKCS12SafeBag *key = keyList[i];
            sec_PKCS12SafeBag **certList;
            unsigned int keyUsage;

            if (key->problem) {
                ++failedKeys;
                continue;
            }

            certList = sec_pkcs12_find_certs_for_key(safeBags, key);
            if (certList && certList[0]) {
                pubKey = sec_pkcs12_get_public_key_and_usage(certList[0],
                                                             &keyUsage);
                /* use the cert's nickname, if it has one, else use the
                 * key's nickname, else fail.
                 */
                nickName = sec_pkcs12_get_nickname_for_cert(certList[0], key);
            } else {
                nickName = sec_pkcs12_get_nickname(key);
            }
            if (!nickName) {
                key->error = SEC_ERROR_BAD_NICKNAME;
                key->problem = PR_TRUE;
                rv = SECFailure;
            } else if (!pubKey) {
                key->error = SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY;
                key->problem = PR_TRUE;
                rv = SECFailure;
            } else {
                rv = sec_pkcs12_add_key(key, pubKey, keyUsage, nickName,
                                        forceUnicode, wincx);
            }
            if (pubKey) {
                SECKEY_DestroyPublicKey(pubKey);
                pubKey = NULL;
            }
            if (nickName) {
                SECITEM_FreeItem(nickName, PR_TRUE);
                nickName = NULL;
            }
            if (rv != SECSuccess) {
                PORT_SetError(key->error);
                ++failedKeys;
            }

            if (certList) {
                int j;

                for (j = 0; certList[j]; j++) {
                    sec_PKCS12SafeBag *cert = certList[j];
                    SECStatus certRv;

                    if (!cert)
                        continue;
                    if (rv != SECSuccess) {
                        cert->problem = key->problem;
                        cert->error = key->error;
                        cert->noInstall = PR_TRUE;
                        continue;
                    }

                    certRv = sec_pkcs12_add_cert(cert, cert->hasKey, wincx);
                    if (certRv != SECSuccess) {
                        key->problem = cert->problem;
                        key->error = cert->error;
                        PORT_SetError(cert->error);
                        return SECFailure;
                    }
                }
            }
        }
    }
    if (failedKeys)
        return SECFailure;

    /* Now take a second pass over the safebags and install any certs
     * that were neither installed nor disqualified by the first pass.
     */
    for (i = 0; safeBags[i]; i++) {
        sec_PKCS12SafeBag *bag = safeBags[i];

        if (!bag->installed && !bag->problem && !bag->noInstall) {
            SECStatus rv;
            SECOidTag bagType = SECOID_FindOIDTag(&(bag->safeBagType));

            switch (bagType) {
                case SEC_OID_PKCS12_V1_CERT_BAG_ID:
                    rv = sec_pkcs12_add_cert(bag, bag->hasKey, wincx);
                    if (rv != SECSuccess) {
                        PORT_SetError(bag->error);
                        return SECFailure;
                    }
                    break;
                case SEC_OID_PKCS12_V1_KEY_BAG_ID:
                case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
                default:
                    break;
            }
        }
    }

    return SECSuccess;
}

SECStatus
SEC_PKCS12DecoderImportBags(SEC_PKCS12DecoderContext *p12dcx)
{
    PRBool forceUnicode = PR_FALSE;
    SECStatus rv;

    if (!p12dcx || p12dcx->error) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!p12dcx->bagsVerified) {
        return SECFailure;
    }

    /* We need to check the option here as well as in
     * SEC_PKCS12DecoderStart, because different PBE's could be used
     * for PKCS #7 and PKCS #8 */
    rv = NSS_OptionGet(__NSS_PKCS12_DECODE_FORCE_UNICODE, &forceUnicode);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    return sec_pkcs12_install_bags(p12dcx->safeBags, forceUnicode,
                                   p12dcx->wincx);
}

PRBool
sec_pkcs12_bagHasKey(SEC_PKCS12DecoderContext *p12dcx, sec_PKCS12SafeBag *bag)
{
    int i;
    SECItem *keyId;
    SECItem *certKeyId;

    certKeyId = sec_pkcs12_get_attribute_value(bag, SEC_OID_PKCS9_LOCAL_KEY_ID);
    if (certKeyId == NULL) {
        return PR_FALSE;
    }

    for (i = 0; p12dcx->keyList && p12dcx->keyList[i]; i++) {
        keyId = sec_pkcs12_get_attribute_value(p12dcx->keyList[i],
                                               SEC_OID_PKCS9_LOCAL_KEY_ID);
        if (!keyId) {
            continue;
        }
        if (SECITEM_CompareItem(certKeyId, keyId) == SECEqual) {
            return PR_TRUE;
        }
    }
    return PR_FALSE;
}

SECItem *
sec_pkcs12_get_friendlyName(sec_PKCS12SafeBag *bag)
{
    SECItem *friendlyName;
    SECItem *tempnm;

    tempnm = sec_pkcs12_get_attribute_value(bag, SEC_OID_PKCS9_FRIENDLY_NAME);
    friendlyName = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
    if (friendlyName) {
        if (!sec_pkcs12_convert_item_to_unicode(NULL, friendlyName,
                                                tempnm, PR_TRUE, PR_FALSE, PR_FALSE)) {
            SECITEM_FreeItem(friendlyName, PR_TRUE);
            friendlyName = NULL;
        }
    }
    return friendlyName;
}

/* Following two functions provide access to selected portions of the safe bags.
 * Iteration is implemented per decoder context and may be accessed after
 * SEC_PKCS12DecoderVerify() returns success.
 * When ...DecoderIterateNext() returns SUCCESS a decoder item has been returned
 * where item.type is always set; item.friendlyName is set if it is non-null;
 * item.der, item.hasKey are set only for SEC_OID_PKCS12_V1_CERT_BAG_ID items.
 * ...DecoderIterateNext() returns FAILURE when the list is exhausted or when
 * arguments are invalid; PORT_GetError() is 0 at end-of-list.
 * Caller has read-only access to decoder items. Any SECItems generated are
 * owned by the decoder context and are freed by ...DecoderFinish().
 */
SECStatus
SEC_PKCS12DecoderIterateInit(SEC_PKCS12DecoderContext *p12dcx)
{
    if (!p12dcx || p12dcx->error) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    p12dcx->iteration = 0;
    return SECSuccess;
}

SECStatus
SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx,
                             const SEC_PKCS12DecoderItem **ipp)
{
    sec_PKCS12SafeBag *bag;

    if (!p12dcx || p12dcx->error) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (p12dcx->decitem.type != 0 && p12dcx->decitem.der != NULL) {
        SECITEM_FreeItem(p12dcx->decitem.der, PR_TRUE);
    }
    if (p12dcx->decitem.shroudAlg != NULL) {
        SECOID_DestroyAlgorithmID(p12dcx->decitem.shroudAlg, PR_TRUE);
    }
    if (p12dcx->decitem.friendlyName != NULL) {
        SECITEM_FreeItem(p12dcx->decitem.friendlyName, PR_TRUE);
    }
    p12dcx->decitem.type = 0;
    p12dcx->decitem.der = NULL;
    p12dcx->decitem.shroudAlg = NULL;
    p12dcx->decitem.friendlyName = NULL;
    p12dcx->decitem.hasKey = PR_FALSE;
    *ipp = NULL;
    if (p12dcx->keyList == NULL) {
        p12dcx->keyList = sec_pkcs12_get_key_bags(p12dcx->safeBags);
    }

    for (; p12dcx->iteration < p12dcx->safeBagCount; p12dcx->iteration++) {
        bag = p12dcx->safeBags[p12dcx->iteration];
        if (bag == NULL || bag->problem) {
            continue;
        }
        p12dcx->decitem.type = SECOID_FindOIDTag(&(bag->safeBagType));
        switch (p12dcx->decitem.type) {
            case SEC_OID_PKCS12_V1_CERT_BAG_ID:
                p12dcx->decitem.der = sec_pkcs12_get_der_cert(bag);
                p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag);
                p12dcx->decitem.hasKey = sec_pkcs12_bagHasKey(p12dcx, bag);
                break;
            case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
                p12dcx->decitem.shroudAlg = PORT_ZNew(SECAlgorithmID);
                if (p12dcx->decitem.shroudAlg) {
                    SECOID_CopyAlgorithmID(NULL, p12dcx->decitem.shroudAlg,
                                           &bag->safeBagContent.pkcs8ShroudedKeyBag->algorithm);
                }
            /* fall through */
            case SEC_OID_PKCS12_V1_KEY_BAG_ID:
                p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag);
                break;
            default:
                /* return these even though we don't expect them */
                break;
            case SEC_OID_UNKNOWN:
                /* ignore these */
                continue;
        }
        *ipp = &p12dcx->decitem;
        p12dcx->iteration++;
        break; /* end for() */
    }

    PORT_SetError(0); /* end-of-list is SECFailure with no PORT error */
    return ((p12dcx->decitem.type == 0) ? SECFailure : SECSuccess);
}

static SECStatus
sec_pkcs12_decoder_append_bag_to_context(SEC_PKCS12DecoderContext *p12dcx,
                                         sec_PKCS12SafeBag *bag)
{
    if (!p12dcx || p12dcx->error) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    p12dcx->safeBags = !p12dcx->safeBagCount
                           ? PORT_ArenaZNewArray(p12dcx->arena, sec_PKCS12SafeBag *, 2)
                           : PORT_ArenaGrowArray(p12dcx->arena, p12dcx->safeBags,
                                                 sec_PKCS12SafeBag *, p12dcx->safeBagCount + 1,
                                                 p12dcx->safeBagCount + 2);

    if (!p12dcx->safeBags) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    p12dcx->safeBags[p12dcx->safeBagCount] = bag;
    p12dcx->safeBags[p12dcx->safeBagCount + 1] = NULL;
    p12dcx->safeBagCount++;

    return SECSuccess;
}

static sec_PKCS12SafeBag *
sec_pkcs12_decoder_convert_old_key(SEC_PKCS12DecoderContext *p12dcx,
                                   void *key, PRBool isEspvk)
{
    sec_PKCS12SafeBag *keyBag;
    SECOidData *oid;
    SECOidTag keyTag;
    SECItem *keyID, *nickName, *newNickName;

    if (!p12dcx || p12dcx->error || !key) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    newNickName = PORT_ArenaZNew(p12dcx->arena, SECItem);
    keyBag = PORT_ArenaZNew(p12dcx->arena, sec_PKCS12SafeBag);
    if (!keyBag || !newNickName) {
        return NULL;
    }

    keyBag->swapUnicodeBytes = p12dcx->swapUnicodeBytes;
    keyBag->slot = p12dcx->slot;
    keyBag->arena = p12dcx->arena;
    keyBag->pwitem = p12dcx->pwitem;
    keyBag->tokenCAs = p12dcx->tokenCAs;
    keyBag->oldBagType = PR_TRUE;

    keyTag = (isEspvk) ? SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID : SEC_OID_PKCS12_V1_KEY_BAG_ID;
    oid = SECOID_FindOIDByTag(keyTag);
    if (!oid) {
        return NULL;
    }

    if (SECITEM_CopyItem(p12dcx->arena, &keyBag->safeBagType, &oid->oid) != SECSuccess) {
        return NULL;
    }

    if (isEspvk) {
        SEC_PKCS12ESPVKItem *espvk = (SEC_PKCS12ESPVKItem *)key;
        keyBag->safeBagContent.pkcs8ShroudedKeyBag =
            espvk->espvkCipherText.pkcs8KeyShroud;
        nickName = &(espvk->espvkData.uniNickName);
        if (!espvk->espvkData.assocCerts || !espvk->espvkData.assocCerts[0]) {
            PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
            return NULL;
        }
        keyID = &espvk->espvkData.assocCerts[0]->digest;
    } else {
        SEC_PKCS12PrivateKey *pk = (SEC_PKCS12PrivateKey *)key;
        keyBag->safeBagContent.pkcs8KeyBag = &pk->pkcs8data;
        nickName = &(pk->pvkData.uniNickName);
        if (!pk->pvkData.assocCerts || !pk->pvkData.assocCerts[0]) {
            PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
            return NULL;
        }
        keyID = &pk->pvkData.assocCerts[0]->digest;
    }

    if (nickName->len) {
        if (nickName->len >= 2) {
            if (nickName->data[0] && nickName->data[1]) {
                if (!sec_pkcs12_convert_item_to_unicode(p12dcx->arena, newNickName,
                                                        nickName, PR_FALSE, PR_FALSE, PR_TRUE)) {
                    return NULL;
                }
                nickName = newNickName;
            } else if (nickName->data[0] && !nickName->data[1]) {
                unsigned int j = 0;
                unsigned char t;
                for (j = 0; j < nickName->len; j += 2) {
                    t = nickName->data[j + 1];
                    nickName->data[j + 1] = nickName->data[j];
                    nickName->data[j] = t;
                }
            }
        } else {
            if (!sec_pkcs12_convert_item_to_unicode(p12dcx->arena, newNickName,
                                                    nickName, PR_FALSE, PR_FALSE, PR_TRUE)) {
                return NULL;
            }
            nickName = newNickName;
        }
    }

    if (sec_pkcs12_decoder_set_attribute_value(keyBag,
                                               SEC_OID_PKCS9_FRIENDLY_NAME,
                                               nickName) != SECSuccess) {
        return NULL;
    }

    if (sec_pkcs12_decoder_set_attribute_value(keyBag, SEC_OID_PKCS9_LOCAL_KEY_ID,
                                               keyID) != SECSuccess) {
        return NULL;
    }

    return keyBag;
}

static sec_PKCS12SafeBag *
sec_pkcs12_decoder_create_cert(SEC_PKCS12DecoderContext *p12dcx,
                               SECItem *derCert)
{
    sec_PKCS12SafeBag *certBag;
    SECOidData *oid;
    SGNDigestInfo *digest;
    SECItem *keyId;
    SECStatus rv;

    if (!p12dcx || p12dcx->error || !derCert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    keyId = PORT_ArenaZNew(p12dcx->arena, SECItem);
    if (!keyId) {
        return NULL;
    }

    digest = sec_pkcs12_compute_thumbprint(derCert);
    if (!digest) {
        return NULL;
    }

    rv = SECITEM_CopyItem(p12dcx->arena, keyId, &digest->digest);
    SGN_DestroyDigestInfo(digest);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    oid = SECOID_FindOIDByTag(SEC_OID_PKCS12_V1_CERT_BAG_ID);
    certBag = PORT_ArenaZNew(p12dcx->arena, sec_PKCS12SafeBag);
    if (!certBag || !oid || (SECITEM_CopyItem(p12dcx->arena,
                                              &certBag->safeBagType, &oid->oid) != SECSuccess)) {
        return NULL;
    }

    certBag->slot = p12dcx->slot;
    certBag->pwitem = p12dcx->pwitem;
    certBag->swapUnicodeBytes = p12dcx->swapUnicodeBytes;
    certBag->arena = p12dcx->arena;
    certBag->tokenCAs = p12dcx->tokenCAs;

    oid = SECOID_FindOIDByTag(SEC_OID_PKCS9_X509_CERT);
    certBag->safeBagContent.certBag =
        PORT_ArenaZNew(p12dcx->arena, sec_PKCS12CertBag);
    if (!certBag->safeBagContent.certBag || !oid ||
        (SECITEM_CopyItem(p12dcx->arena,
                          &certBag->safeBagContent.certBag->bagID,
                          &oid->oid) != SECSuccess)) {
        return NULL;
    }

    if (SECITEM_CopyItem(p12dcx->arena,
                         &(certBag->safeBagContent.certBag->value.x509Cert),
                         derCert) != SECSuccess) {
        return NULL;
    }

    if (sec_pkcs12_decoder_set_attribute_value(certBag, SEC_OID_PKCS9_LOCAL_KEY_ID,
                                               keyId) != SECSuccess) {
        return NULL;
    }

    return certBag;
}

static sec_PKCS12SafeBag **
sec_pkcs12_decoder_convert_old_cert(SEC_PKCS12DecoderContext *p12dcx,
                                    SEC_PKCS12CertAndCRL *oldCert)
{
    sec_PKCS12SafeBag **certList;
    SECItem **derCertList;
    int i, j;

    if (!p12dcx || p12dcx->error || !oldCert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    derCertList = SEC_PKCS7GetCertificateList(&oldCert->value.x509->certOrCRL);
    if (!derCertList) {
        return NULL;
    }

    i = 0;
    while (derCertList[i])
        i++;

    certList = PORT_ArenaZNewArray(p12dcx->arena, sec_PKCS12SafeBag *, (i + 1));
    if (!certList) {
        return NULL;
    }

    for (j = 0; j < i; j++) {
        certList[j] = sec_pkcs12_decoder_create_cert(p12dcx, derCertList[j]);
        if (!certList[j]) {
            return NULL;
        }
    }

    return certList;
}

static SECStatus
sec_pkcs12_decoder_convert_old_key_and_certs(SEC_PKCS12DecoderContext *p12dcx,
                                             void *oldKey, PRBool isEspvk,
                                             SEC_PKCS12SafeContents *safe,
                                             SEC_PKCS12Baggage *baggage)
{
    sec_PKCS12SafeBag *key, **certList;
    SEC_PKCS12CertAndCRL *oldCert;
    SEC_PKCS12PVKSupportingData *pvkData;
    int i;
    SECItem *keyName;

    if (!p12dcx || !oldKey) {
        return SECFailure;
    }

    if (isEspvk) {
        pvkData = &((SEC_PKCS12ESPVKItem *)(oldKey))->espvkData;
    } else {
        pvkData = &((SEC_PKCS12PrivateKey *)(oldKey))->pvkData;
    }

    if (!pvkData->assocCerts || !pvkData->assocCerts[0]) {
        PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
        return SECFailure;
    }

    oldCert = (SEC_PKCS12CertAndCRL *)sec_pkcs12_find_object(safe, baggage,
                                                             SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID, NULL,
                                                             pvkData->assocCerts[0]);
    if (!oldCert) {
        PORT_SetError(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE);
        return SECFailure;
    }

    key = sec_pkcs12_decoder_convert_old_key(p12dcx, oldKey, isEspvk);
    certList = sec_pkcs12_decoder_convert_old_cert(p12dcx, oldCert);
    if (!key || !certList) {
        return SECFailure;
    }

    if (sec_pkcs12_decoder_append_bag_to_context(p12dcx, key) != SECSuccess) {
        return SECFailure;
    }

    keyName = sec_pkcs12_get_nickname(key);
    if (!keyName) {
        return SECFailure;
    }

    i = 0;
    while (certList[i]) {
        if (sec_pkcs12_decoder_append_bag_to_context(p12dcx, certList[i]) != SECSuccess) {
            return SECFailure;
        }
        i++;
    }

    certList = sec_pkcs12_find_certs_for_key(p12dcx->safeBags, key);
    if (!certList) {
        return SECFailure;
    }

    i = 0;
    while (certList[i] != 0) {
        if (sec_pkcs12_set_nickname(certList[i], keyName) != SECSuccess) {
            return SECFailure;
        }
        i++;
    }

    return SECSuccess;
}

static SECStatus
sec_pkcs12_decoder_convert_old_safe_to_bags(SEC_PKCS12DecoderContext *p12dcx,
                                            SEC_PKCS12SafeContents *safe,
                                            SEC_PKCS12Baggage *baggage)
{
    SECStatus rv;

    if (!p12dcx || p12dcx->error) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (safe && safe->contents) {
        int i = 0;
        while (safe->contents[i] != NULL) {
            if (SECOID_FindOIDTag(&safe->contents[i]->safeBagType) == SEC_OID_PKCS12_KEY_BAG_ID) {
                int j = 0;
                SEC_PKCS12PrivateKeyBag *privBag =
                    safe->contents[i]->safeContent.keyBag;

                while (privBag->privateKeys[j] != NULL) {
                    SEC_PKCS12PrivateKey *pk = privBag->privateKeys[j];
                    rv = sec_pkcs12_decoder_convert_old_key_and_certs(p12dcx, pk,
                                                                      PR_FALSE, safe, baggage);
                    if (rv != SECSuccess) {
                        goto loser;
                    }
                    j++;
                }
            }
            i++;
        }
    }

    if (baggage && baggage->bags) {
        int i = 0;
        while (baggage->bags[i] != NULL) {
            SEC_PKCS12BaggageItem *bag = baggage->bags[i];
            int j = 0;

            if (!bag->espvks) {
                i++;
                continue;
            }

            while (bag->espvks[j] != NULL) {
                SEC_PKCS12ESPVKItem *espvk = bag->espvks[j];
                rv = sec_pkcs12_decoder_convert_old_key_and_certs(p12dcx, espvk,
                                                                  PR_TRUE, safe, baggage);
                if (rv != SECSuccess) {
                    goto loser;
                }
                j++;
            }
            i++;
        }
    }

    return SECSuccess;

loser:
    return SECFailure;
}

SEC_PKCS12DecoderContext *
sec_PKCS12ConvertOldSafeToNew(PLArenaPool *arena, PK11SlotInfo *slot,
                              PRBool swapUnicode, SECItem *pwitem,
                              void *wincx, SEC_PKCS12SafeContents *safe,
                              SEC_PKCS12Baggage *baggage)
{
    SEC_PKCS12DecoderContext *p12dcx;

    if (!arena || !slot || !pwitem) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    if (!safe && !baggage) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    p12dcx = PORT_ArenaZNew(arena, SEC_PKCS12DecoderContext);
    if (!p12dcx) {
        return NULL;
    }

    p12dcx->arena = arena;
    p12dcx->slot = PK11_ReferenceSlot(slot);
    p12dcx->wincx = wincx;
    p12dcx->error = PR_FALSE;
    p12dcx->swapUnicodeBytes = swapUnicode;
    p12dcx->pwitem = pwitem;
    p12dcx->tokenCAs = SECPKCS12TargetTokenNoCAs;

    if (sec_pkcs12_decoder_convert_old_safe_to_bags(p12dcx, safe, baggage) != SECSuccess) {
        p12dcx->error = PR_TRUE;
        return NULL;
    }

    return p12dcx;
}
