/* 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 "p12t.h"
#include "p12.h"
#include "plarena.h"
#include "secitem.h"
#include "secoid.h"
#include "seccomon.h"
#include "secport.h"
#include "cert.h"
#include "secpkcs5.h"
#include "secpkcs7.h"
#include "secasn1.h"
#include "secerr.h"
#include "pk11func.h"
#include "p12plcy.h"
#include "p12local.h"
#include "prcpucfg.h"

extern const int NSS_PBE_DEFAULT_ITERATION_COUNT; /* defined in p7create.c */

/*
** This PKCS12 file encoder uses numerous nested ASN.1 and PKCS7 encoder
** contexts.  It can be difficult to keep straight.  Here's a picture:
**
**  "outer"  ASN.1 encoder.  The output goes to the library caller's CB.
**  "middle" PKCS7 encoder.  Feeds    the "outer" ASN.1 encoder.
**  "middle" ASN1  encoder.  Encodes  the encrypted aSafes.
**                           Feeds    the "middle" P7 encoder above.
**  "inner"  PKCS7 encoder.  Encrypts the "authenticated Safes" (aSafes)
**                           Feeds    the "middle" ASN.1 encoder above.
**  "inner"  ASN.1 encoder.  Encodes  the unencrypted aSafes.
**                           Feeds    the "inner" P7 enocder above.
**
** Buffering has been added at each point where the output of an ASN.1
** encoder feeds the input of a PKCS7 encoder.
*/

/*********************************
 * Output buffer object, used to buffer output from ASN.1 encoder
 * before passing data on down to the next PKCS7 encoder.
 *********************************/

#define PK12_OUTPUT_BUFFER_SIZE 8192

struct sec_pkcs12OutputBufferStr {
    SEC_PKCS7EncoderContext *p7eCx;
    PK11Context *hmacCx;
    unsigned int numBytes;
    unsigned int bufBytes;
    char buf[PK12_OUTPUT_BUFFER_SIZE];
};
typedef struct sec_pkcs12OutputBufferStr sec_pkcs12OutputBuffer;

/*********************************
 * Structures used in exporting the PKCS 12 blob
 *********************************/

/* A SafeInfo is used for each ContentInfo which makes up the
 * sequence of safes in the AuthenticatedSafe portion of the
 * PFX structure.
 */
struct SEC_PKCS12SafeInfoStr {
    PLArenaPool *arena;

    /* information for setting up password encryption */
    SECItem pwitem;
    SECOidTag algorithm;
    PK11SymKey *encryptionKey;

    /* how many items have been stored in this safe,
     * we will skip any safe which does not contain any
     * items
     */
    unsigned int itemCount;

    /* the content info for the safe */
    SEC_PKCS7ContentInfo *cinfo;

    sec_PKCS12SafeContents *safe;
};

/* An opaque structure which contains information needed for exporting
 * certificates and keys through PKCS 12.
 */
struct SEC_PKCS12ExportContextStr {
    PLArenaPool *arena;
    PK11SlotInfo *slot;
    void *wincx;

    /* integrity information */
    PRBool integrityEnabled;
    PRBool pwdIntegrity;
    union {
        struct sec_PKCS12PasswordModeInfo pwdInfo;
        struct sec_PKCS12PublicKeyModeInfo pubkeyInfo;
    } integrityInfo;

    /* helper functions */
    /* retrieve the password call back */
    SECKEYGetPasswordKey pwfn;
    void *pwfnarg;

    /* safe contents bags */
    SEC_PKCS12SafeInfo **safeInfos;
    unsigned int safeInfoCount;

    /* the sequence of safes */
    sec_PKCS12AuthenticatedSafe authSafe;

    /* information needing deletion */
    CERTCertificate **certList;
};

/* structures for passing information to encoder callbacks when processing
 * data through the ASN1 engine.
 */
struct sec_pkcs12_encoder_output {
    SEC_PKCS12EncoderOutputCallback outputfn;
    void *outputarg;
};

struct sec_pkcs12_hmac_and_output_info {
    void *arg;
    struct sec_pkcs12_encoder_output output;
};

/* An encoder context which is used for the actual encoding
 * portion of PKCS 12.
 */
typedef struct sec_PKCS12EncoderContextStr {
    PLArenaPool *arena;
    SEC_PKCS12ExportContext *p12exp;

    /* encoder information - this is set up based on whether
     * password based or public key pased privacy is being used
     */
    SEC_ASN1EncoderContext *outerA1ecx;
    union {
        struct sec_pkcs12_hmac_and_output_info hmacAndOutputInfo;
        struct sec_pkcs12_encoder_output encOutput;
    } output;

    /* structures for encoding of PFX and MAC */
    sec_PKCS12PFXItem pfx;
    sec_PKCS12MacData mac;

    /* authenticated safe encoding tracking information */
    SEC_PKCS7ContentInfo *aSafeCinfo;
    SEC_PKCS7EncoderContext *middleP7ecx;
    SEC_ASN1EncoderContext *middleA1ecx;
    unsigned int currentSafe;

    /* hmac context */
    PK11Context *hmacCx;

    /* output buffers */
    sec_pkcs12OutputBuffer middleBuf;
    sec_pkcs12OutputBuffer innerBuf;

} sec_PKCS12EncoderContext;

/*********************************
 * Export setup routines
 *********************************/

/* SEC_PKCS12CreateExportContext
 *   Creates an export context and sets the unicode and password retrieval
 *   callbacks.  This is the first call which must be made when exporting
 *   a PKCS 12 blob.
 *
 * pwfn, pwfnarg - password retrieval callback and argument.  these are
 *                 required for password-authentication mode.
 */
SEC_PKCS12ExportContext *
SEC_PKCS12CreateExportContext(SECKEYGetPasswordKey pwfn, void *pwfnarg,
                              PK11SlotInfo *slot, void *wincx)
{
    PLArenaPool *arena = NULL;
    SEC_PKCS12ExportContext *p12ctxt = NULL;

    /* allocate the arena and create the context */
    arena = PORT_NewArena(4096);
    if (!arena) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    p12ctxt = (SEC_PKCS12ExportContext *)PORT_ArenaZAlloc(arena,
                                                          sizeof(SEC_PKCS12ExportContext));
    if (!p12ctxt) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* password callback for key retrieval */
    p12ctxt->pwfn = pwfn;
    p12ctxt->pwfnarg = pwfnarg;

    p12ctxt->integrityEnabled = PR_FALSE;
    p12ctxt->arena = arena;
    p12ctxt->wincx = wincx;
    p12ctxt->slot = (slot) ? PK11_ReferenceSlot(slot) : PK11_GetInternalSlot();

    return p12ctxt;

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

    return NULL;
}

/*
 * Adding integrity mode
 */

/* SEC_PKCS12AddPasswordIntegrity
 *      Add password integrity to the exported data.  If an integrity method
 *      has already been set, then return an error.
 *
 *      p12ctxt - the export context
 *      pwitem - the password for integrity mode
 *      integAlg - the integrity algorithm to use for authentication.
 */
SECStatus
SEC_PKCS12AddPasswordIntegrity(SEC_PKCS12ExportContext *p12ctxt,
                               SECItem *pwitem, SECOidTag integAlg)
{
    if (!p12ctxt || p12ctxt->integrityEnabled) {
        return SECFailure;
    }

    /* set up integrity information */
    p12ctxt->pwdIntegrity = PR_TRUE;
    p12ctxt->integrityInfo.pwdInfo.password =
        (SECItem *)PORT_ArenaZAlloc(p12ctxt->arena, sizeof(SECItem));
    if (!p12ctxt->integrityInfo.pwdInfo.password) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }
    if (SECITEM_CopyItem(p12ctxt->arena,
                         p12ctxt->integrityInfo.pwdInfo.password, pwitem) != SECSuccess) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }
    p12ctxt->integrityInfo.pwdInfo.algorithm = integAlg;
    p12ctxt->integrityEnabled = PR_TRUE;

    return SECSuccess;
}

/* SEC_PKCS12AddPublicKeyIntegrity
 *      Add public key integrity to the exported data.  If an integrity method
 *      has already been set, then return an error.  The certificate must be
 *      allowed to be used as a signing cert.
 *
 *      p12ctxt - the export context
 *      cert - signer certificate
 *      certDb - the certificate database
 *      algorithm - signing algorithm
 *      keySize - size of the signing key (?)
 */
SECStatus
SEC_PKCS12AddPublicKeyIntegrity(SEC_PKCS12ExportContext *p12ctxt,
                                CERTCertificate *cert, CERTCertDBHandle *certDb,
                                SECOidTag algorithm, int keySize)
{
    if (!p12ctxt) {
        return SECFailure;
    }

    p12ctxt->integrityInfo.pubkeyInfo.cert = cert;
    p12ctxt->integrityInfo.pubkeyInfo.certDb = certDb;
    p12ctxt->integrityInfo.pubkeyInfo.algorithm = algorithm;
    p12ctxt->integrityInfo.pubkeyInfo.keySize = keySize;
    p12ctxt->integrityEnabled = PR_TRUE;

    return SECSuccess;
}

/*
 * Adding safes - encrypted (password/public key) or unencrypted
 *      Each of the safe creation routines return an opaque pointer which
 *      are later passed into the routines for exporting certificates and
 *      keys.
 */

/* append the newly created safeInfo to list of safeInfos in the export
 * context.
 */
static SECStatus
sec_pkcs12_append_safe_info(SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *info)
{
    void *mark = NULL, *dummy1 = NULL, *dummy2 = NULL;

    if (!p12ctxt || !info) {
        return SECFailure;
    }

    mark = PORT_ArenaMark(p12ctxt->arena);

    /* if no safeInfos have been set, create the list, otherwise expand it. */
    if (!p12ctxt->safeInfoCount) {
        p12ctxt->safeInfos = (SEC_PKCS12SafeInfo **)PORT_ArenaZAlloc(p12ctxt->arena,
                                                                     2 * sizeof(SEC_PKCS12SafeInfo *));
        dummy1 = p12ctxt->safeInfos;
        p12ctxt->authSafe.encodedSafes = (SECItem **)PORT_ArenaZAlloc(p12ctxt->arena,
                                                                      2 * sizeof(SECItem *));
        dummy2 = p12ctxt->authSafe.encodedSafes;
    } else {
        dummy1 = PORT_ArenaGrow(p12ctxt->arena, p12ctxt->safeInfos,
                                (p12ctxt->safeInfoCount + 1) * sizeof(SEC_PKCS12SafeInfo *),
                                (p12ctxt->safeInfoCount + 2) * sizeof(SEC_PKCS12SafeInfo *));
        p12ctxt->safeInfos = (SEC_PKCS12SafeInfo **)dummy1;
        dummy2 = PORT_ArenaGrow(p12ctxt->arena, p12ctxt->authSafe.encodedSafes,
                                (p12ctxt->authSafe.safeCount + 1) * sizeof(SECItem *),
                                (p12ctxt->authSafe.safeCount + 2) * sizeof(SECItem *));
        p12ctxt->authSafe.encodedSafes = (SECItem **)dummy2;
    }
    if (!dummy1 || !dummy2) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* append the new safeInfo and null terminate the list */
    p12ctxt->safeInfos[p12ctxt->safeInfoCount] = info;
    p12ctxt->safeInfos[++p12ctxt->safeInfoCount] = NULL;
    p12ctxt->authSafe.encodedSafes[p12ctxt->authSafe.safeCount] =
        (SECItem *)PORT_ArenaZAlloc(p12ctxt->arena, sizeof(SECItem));
    if (!p12ctxt->authSafe.encodedSafes[p12ctxt->authSafe.safeCount]) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    p12ctxt->authSafe.encodedSafes[++p12ctxt->authSafe.safeCount] = NULL;

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

loser:
    PORT_ArenaRelease(p12ctxt->arena, mark);
    return SECFailure;
}

/* SEC_PKCS12CreatePasswordPrivSafe
 *      Create a password privacy safe to store exported information in.
 *
 *      p12ctxt - export context
 *      pwitem - password for encryption
 *      privAlg - pbe algorithm through which encryption is done.
 */
SEC_PKCS12SafeInfo *
SEC_PKCS12CreatePasswordPrivSafe(SEC_PKCS12ExportContext *p12ctxt,
                                 SECItem *pwitem, SECOidTag privAlg)
{
    SEC_PKCS12SafeInfo *safeInfo = NULL;
    void *mark = NULL;
    PK11SlotInfo *slot = NULL;
    SECAlgorithmID *algId;
    SECItem uniPwitem = { siBuffer, NULL, 0 };

    if (!p12ctxt) {
        return NULL;
    }

    /* allocate the safe info */
    mark = PORT_ArenaMark(p12ctxt->arena);
    safeInfo = (SEC_PKCS12SafeInfo *)PORT_ArenaZAlloc(p12ctxt->arena,
                                                      sizeof(SEC_PKCS12SafeInfo));
    if (!safeInfo) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        PORT_ArenaRelease(p12ctxt->arena, mark);
        return NULL;
    }

    safeInfo->itemCount = 0;

    /* create the encrypted safe */
    if (!SEC_PKCS5IsAlgorithmPBEAlgTag(privAlg) &&
        PK11_AlgtagToMechanism(privAlg) == CKM_AES_CBC) {
        safeInfo->cinfo = SEC_PKCS7CreateEncryptedDataWithPBEV2(SEC_OID_PKCS5_PBES2,
                                                                privAlg,
                                                                SEC_OID_UNKNOWN,
                                                                0,
                                                                p12ctxt->pwfn,
                                                                p12ctxt->pwfnarg);
    } else {
        safeInfo->cinfo = SEC_PKCS7CreateEncryptedData(privAlg, 0, p12ctxt->pwfn,
                                                       p12ctxt->pwfnarg);
    }
    if (!safeInfo->cinfo) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    safeInfo->arena = p12ctxt->arena;

    if (!sec_pkcs12_encode_password(NULL, &uniPwitem, privAlg, pwitem)) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    if (SECITEM_CopyItem(p12ctxt->arena, &safeInfo->pwitem, &uniPwitem) != SECSuccess) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* generate the encryption key */
    slot = PK11_ReferenceSlot(p12ctxt->slot);
    if (!slot) {
        slot = PK11_GetInternalKeySlot();
        if (!slot) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
    }

    algId = SEC_PKCS7GetEncryptionAlgorithm(safeInfo->cinfo);
    safeInfo->encryptionKey = PK11_PBEKeyGen(slot, algId, &uniPwitem,
                                             PR_FALSE, p12ctxt->wincx);
    if (!safeInfo->encryptionKey) {
        goto loser;
    }

    safeInfo->arena = p12ctxt->arena;
    safeInfo->safe = NULL;
    if (sec_pkcs12_append_safe_info(p12ctxt, safeInfo) != SECSuccess) {
        goto loser;
    }

    if (uniPwitem.data) {
        SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
    }
    PORT_ArenaUnmark(p12ctxt->arena, mark);

    if (slot) {
        PK11_FreeSlot(slot);
    }
    return safeInfo;

loser:
    if (slot) {
        PK11_FreeSlot(slot);
    }
    if (safeInfo->cinfo) {
        SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
    }

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

    PORT_ArenaRelease(p12ctxt->arena, mark);
    return NULL;
}

/* SEC_PKCS12CreateUnencryptedSafe
 *      Creates an unencrypted safe within the export context.
 *
 *      p12ctxt - the export context
 */
SEC_PKCS12SafeInfo *
SEC_PKCS12CreateUnencryptedSafe(SEC_PKCS12ExportContext *p12ctxt)
{
    SEC_PKCS12SafeInfo *safeInfo = NULL;
    void *mark = NULL;

    if (!p12ctxt) {
        return NULL;
    }

    /* create the safe info */
    mark = PORT_ArenaMark(p12ctxt->arena);
    safeInfo = (SEC_PKCS12SafeInfo *)PORT_ArenaZAlloc(p12ctxt->arena,
                                                      sizeof(SEC_PKCS12SafeInfo));
    if (!safeInfo) {
        PORT_ArenaRelease(p12ctxt->arena, mark);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    safeInfo->itemCount = 0;

    /* create the safe content */
    safeInfo->cinfo = SEC_PKCS7CreateData();
    if (!safeInfo->cinfo) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    if (sec_pkcs12_append_safe_info(p12ctxt, safeInfo) != SECSuccess) {
        goto loser;
    }

    PORT_ArenaUnmark(p12ctxt->arena, mark);
    return safeInfo;

loser:
    if (safeInfo->cinfo) {
        SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
    }

    PORT_ArenaRelease(p12ctxt->arena, mark);
    return NULL;
}

/* SEC_PKCS12CreatePubKeyEncryptedSafe
 *      Creates a safe which is protected by public key encryption.
 *
 *      p12ctxt - the export context
 *      certDb - the certificate database
 *      signer - the signer's certificate
 *      recipients - the list of recipient certificates.
 *      algorithm - the encryption algorithm to use
 *      keysize - the algorithms key size (?)
 */
SEC_PKCS12SafeInfo *
SEC_PKCS12CreatePubKeyEncryptedSafe(SEC_PKCS12ExportContext *p12ctxt,
                                    CERTCertDBHandle *certDb,
                                    CERTCertificate *signer,
                                    CERTCertificate **recipients,
                                    SECOidTag algorithm, int keysize)
{
    SEC_PKCS12SafeInfo *safeInfo = NULL;
    void *mark = NULL;

    if (!p12ctxt || !signer || !recipients || !(*recipients)) {
        return NULL;
    }

    /* allocate the safeInfo */
    mark = PORT_ArenaMark(p12ctxt->arena);
    safeInfo = (SEC_PKCS12SafeInfo *)PORT_ArenaZAlloc(p12ctxt->arena,
                                                      sizeof(SEC_PKCS12SafeInfo));
    if (!safeInfo) {
        PORT_ArenaRelease(p12ctxt->arena, mark);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    safeInfo->itemCount = 0;
    safeInfo->arena = p12ctxt->arena;

    /* create the enveloped content info using certUsageEmailSigner currently.
     * XXX We need to eventually use something other than certUsageEmailSigner
     */
    safeInfo->cinfo = SEC_PKCS7CreateEnvelopedData(signer, certUsageEmailSigner,
                                                   certDb, algorithm, keysize,
                                                   p12ctxt->pwfn, p12ctxt->pwfnarg);
    if (!safeInfo->cinfo) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* add recipients */
    if (recipients) {
        unsigned int i = 0;
        while (recipients[i] != NULL) {
            SECStatus rv = SEC_PKCS7AddRecipient(safeInfo->cinfo, recipients[i],
                                                 certUsageEmailRecipient, certDb);
            if (rv != SECSuccess) {
                goto loser;
            }
            i++;
        }
    }

    if (sec_pkcs12_append_safe_info(p12ctxt, safeInfo) != SECSuccess) {
        goto loser;
    }

    PORT_ArenaUnmark(p12ctxt->arena, mark);
    return safeInfo;

loser:
    if (safeInfo->cinfo) {
        SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
        safeInfo->cinfo = NULL;
    }

    PORT_ArenaRelease(p12ctxt->arena, mark);
    return NULL;
}

/*********************************
 * Routines to handle the exporting of the keys and certificates
 *********************************/

/* creates a safe contents which safeBags will be appended to */
sec_PKCS12SafeContents *
sec_PKCS12CreateSafeContents(PLArenaPool *arena)
{
    sec_PKCS12SafeContents *safeContents;

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

    /* create the safe contents */
    safeContents = (sec_PKCS12SafeContents *)PORT_ArenaZAlloc(arena,
                                                              sizeof(sec_PKCS12SafeContents));
    if (!safeContents) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* set up the internal contents info */
    safeContents->safeBags = NULL;
    safeContents->arena = arena;
    safeContents->bagCount = 0;

    return safeContents;

loser:
    return NULL;
}

/* appends a safe bag to a safeContents using the specified arena.
 */
SECStatus
sec_pkcs12_append_bag_to_safe_contents(PLArenaPool *arena,
                                       sec_PKCS12SafeContents *safeContents,
                                       sec_PKCS12SafeBag *safeBag)
{
    void *mark = NULL, *dummy = NULL;

    if (!arena || !safeBag || !safeContents) {
        return SECFailure;
    }

    mark = PORT_ArenaMark(arena);
    if (!mark) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    /* allocate space for the list, or reallocate to increase space */
    if (!safeContents->safeBags) {
        safeContents->safeBags = (sec_PKCS12SafeBag **)PORT_ArenaZAlloc(arena,
                                                                        (2 * sizeof(sec_PKCS12SafeBag *)));
        dummy = safeContents->safeBags;
        safeContents->bagCount = 0;
    } else {
        dummy = PORT_ArenaGrow(arena, safeContents->safeBags,
                               (safeContents->bagCount + 1) * sizeof(sec_PKCS12SafeBag *),
                               (safeContents->bagCount + 2) * sizeof(sec_PKCS12SafeBag *));
        safeContents->safeBags = (sec_PKCS12SafeBag **)dummy;
    }

    if (!dummy) {
        PORT_ArenaRelease(arena, mark);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    /* append the bag at the end and null terminate the list */
    safeContents->safeBags[safeContents->bagCount++] = safeBag;
    safeContents->safeBags[safeContents->bagCount] = NULL;

    PORT_ArenaUnmark(arena, mark);

    return SECSuccess;
}

/* appends a safeBag to a specific safeInfo.
 */
SECStatus
sec_pkcs12_append_bag(SEC_PKCS12ExportContext *p12ctxt,
                      SEC_PKCS12SafeInfo *safeInfo, sec_PKCS12SafeBag *safeBag)
{
    sec_PKCS12SafeContents *dest;
    SECStatus rv = SECFailure;

    if (!p12ctxt || !safeBag || !safeInfo) {
        return SECFailure;
    }

    if (!safeInfo->safe) {
        safeInfo->safe = sec_PKCS12CreateSafeContents(p12ctxt->arena);
        if (!safeInfo->safe) {
            return SECFailure;
        }
    }

    dest = safeInfo->safe;
    rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena, dest, safeBag);
    if (rv == SECSuccess) {
        safeInfo->itemCount++;
    }

    return rv;
}

/* Creates a safeBag of the specified type, and if bagData is specified,
 * the contents are set.  The contents could be set later by the calling
 * routine.
 */
sec_PKCS12SafeBag *
sec_PKCS12CreateSafeBag(SEC_PKCS12ExportContext *p12ctxt, SECOidTag bagType,
                        void *bagData)
{
    sec_PKCS12SafeBag *safeBag;
    void *mark = NULL;
    SECStatus rv = SECSuccess;
    SECOidData *oidData = NULL;

    if (!p12ctxt) {
        return NULL;
    }

    mark = PORT_ArenaMark(p12ctxt->arena);
    if (!mark) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    safeBag = (sec_PKCS12SafeBag *)PORT_ArenaZAlloc(p12ctxt->arena,
                                                    sizeof(sec_PKCS12SafeBag));
    if (!safeBag) {
        PORT_ArenaRelease(p12ctxt->arena, mark);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    /* set the bags content based upon bag type */
    switch (bagType) {
        case SEC_OID_PKCS12_V1_KEY_BAG_ID:
            safeBag->safeBagContent.pkcs8KeyBag =
                (SECKEYPrivateKeyInfo *)bagData;
            break;
        case SEC_OID_PKCS12_V1_CERT_BAG_ID:
            safeBag->safeBagContent.certBag = (sec_PKCS12CertBag *)bagData;
            break;
        case SEC_OID_PKCS12_V1_CRL_BAG_ID:
            safeBag->safeBagContent.crlBag = (sec_PKCS12CRLBag *)bagData;
            break;
        case SEC_OID_PKCS12_V1_SECRET_BAG_ID:
            safeBag->safeBagContent.secretBag = (sec_PKCS12SecretBag *)bagData;
            break;
        case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
            safeBag->safeBagContent.pkcs8ShroudedKeyBag =
                (SECKEYEncryptedPrivateKeyInfo *)bagData;
            break;
        case SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID:
            safeBag->safeBagContent.safeContents =
                (sec_PKCS12SafeContents *)bagData;
            break;
        default:
            goto loser;
    }

    oidData = SECOID_FindOIDByTag(bagType);
    if (oidData) {
        rv = SECITEM_CopyItem(p12ctxt->arena, &safeBag->safeBagType, &oidData->oid);
        if (rv != SECSuccess) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
    } else {
        goto loser;
    }

    safeBag->arena = p12ctxt->arena;
    PORT_ArenaUnmark(p12ctxt->arena, mark);

    return safeBag;

loser:
    if (mark) {
        PORT_ArenaRelease(p12ctxt->arena, mark);
    }

    return NULL;
}

/* Creates a new certificate bag and returns a pointer to it.  If an error
 * occurs NULL is returned.
 */
sec_PKCS12CertBag *
sec_PKCS12NewCertBag(PLArenaPool *arena, SECOidTag certType)
{
    sec_PKCS12CertBag *certBag = NULL;
    SECOidData *bagType = NULL;
    SECStatus rv;
    void *mark = NULL;

    if (!arena) {
        return NULL;
    }

    mark = PORT_ArenaMark(arena);
    certBag = (sec_PKCS12CertBag *)PORT_ArenaZAlloc(arena,
                                                    sizeof(sec_PKCS12CertBag));
    if (!certBag) {
        PORT_ArenaRelease(arena, mark);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    bagType = SECOID_FindOIDByTag(certType);
    if (!bagType) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    rv = SECITEM_CopyItem(arena, &certBag->bagID, &bagType->oid);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    PORT_ArenaUnmark(arena, mark);
    return certBag;

loser:
    PORT_ArenaRelease(arena, mark);
    return NULL;
}

/* Creates a new CRL bag and returns a pointer to it.  If an error
 * occurs NULL is returned.
 */
sec_PKCS12CRLBag *
sec_PKCS12NewCRLBag(PLArenaPool *arena, SECOidTag crlType)
{
    sec_PKCS12CRLBag *crlBag = NULL;
    SECOidData *bagType = NULL;
    SECStatus rv;
    void *mark = NULL;

    if (!arena) {
        return NULL;
    }

    mark = PORT_ArenaMark(arena);
    crlBag = (sec_PKCS12CRLBag *)PORT_ArenaZAlloc(arena,
                                                  sizeof(sec_PKCS12CRLBag));
    if (!crlBag) {
        PORT_ArenaRelease(arena, mark);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    bagType = SECOID_FindOIDByTag(crlType);
    if (!bagType) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    rv = SECITEM_CopyItem(arena, &crlBag->bagID, &bagType->oid);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    PORT_ArenaUnmark(arena, mark);
    return crlBag;

loser:
    PORT_ArenaRelease(arena, mark);
    return NULL;
}

/* sec_PKCS12AddAttributeToBag
 * adds an attribute to a safeBag.  currently, the only attributes supported
 * are those which are specified within PKCS 12.
 *
 *      p12ctxt - the export context
 *      safeBag - the safeBag to which attributes are appended
 *      attrType - the attribute type
 *      attrData - the attribute data
 */
SECStatus
sec_PKCS12AddAttributeToBag(SEC_PKCS12ExportContext *p12ctxt,
                            sec_PKCS12SafeBag *safeBag, SECOidTag attrType,
                            SECItem *attrData)
{
    sec_PKCS12Attribute *attribute;
    void *mark = NULL, *dummy = NULL;
    SECOidData *oiddata = NULL;
    SECItem unicodeName = { siBuffer, NULL, 0 };
    void *src = NULL;
    unsigned int nItems = 0;
    SECStatus rv;

    PORT_Assert(p12ctxt->arena == safeBag->arena);
    if (!safeBag || !p12ctxt || p12ctxt->arena != safeBag->arena) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    mark = PORT_ArenaMark(safeBag->arena);

    /* allocate the attribute */
    attribute = (sec_PKCS12Attribute *)PORT_ArenaZAlloc(safeBag->arena,
                                                        sizeof(sec_PKCS12Attribute));
    if (!attribute) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* set up the attribute */
    oiddata = SECOID_FindOIDByTag(attrType);
    if (!oiddata) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    if (SECITEM_CopyItem(p12ctxt->arena, &attribute->attrType, &oiddata->oid) !=
        SECSuccess) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    nItems = 1;
    switch (attrType) {
        case SEC_OID_PKCS9_LOCAL_KEY_ID: {
            src = attrData;
            break;
        }
        case SEC_OID_PKCS9_FRIENDLY_NAME: {
            if (!sec_pkcs12_convert_item_to_unicode(p12ctxt->arena,
                                                    &unicodeName, attrData, PR_FALSE,
                                                    PR_FALSE, PR_TRUE)) {
                goto loser;
            }
            src = &unicodeName;
            break;
        }
        default:
            goto loser;
    }

    /* append the attribute to the attribute value list  */
    attribute->attrValue = (SECItem **)PORT_ArenaZAlloc(p12ctxt->arena,
                                                        ((nItems + 1) * sizeof(SECItem *)));
    if (!attribute->attrValue) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* XXX this will need to be changed if attributes requiring more than
     * one element are ever used.
     */
    attribute->attrValue[0] = (SECItem *)PORT_ArenaZAlloc(p12ctxt->arena,
                                                          sizeof(SECItem));
    if (!attribute->attrValue[0]) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }
    attribute->attrValue[1] = NULL;

    rv = SECITEM_CopyItem(p12ctxt->arena, attribute->attrValue[0],
                          (SECItem *)src);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* append the attribute to the safeBag attributes */
    if (safeBag->nAttribs) {
        dummy = PORT_ArenaGrow(p12ctxt->arena, safeBag->attribs,
                               ((safeBag->nAttribs + 1) * sizeof(sec_PKCS12Attribute *)),
                               ((safeBag->nAttribs + 2) * sizeof(sec_PKCS12Attribute *)));
        safeBag->attribs = (sec_PKCS12Attribute **)dummy;
    } else {
        safeBag->attribs = (sec_PKCS12Attribute **)PORT_ArenaZAlloc(p12ctxt->arena,
                                                                    2 * sizeof(sec_PKCS12Attribute *));
        dummy = safeBag->attribs;
    }
    if (!dummy) {
        goto loser;
    }

    safeBag->attribs[safeBag->nAttribs] = attribute;
    safeBag->attribs[++safeBag->nAttribs] = NULL;

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

loser:
    if (mark) {
        PORT_ArenaRelease(p12ctxt->arena, mark);
    }

    return SECFailure;
}

/* SEC_PKCS12AddCert
 *      Adds a certificate to the data being exported.
 *
 *      p12ctxt - the export context
 *      safe - the safeInfo to which the certificate is placed
 *      nestedDest - if the cert is to be placed within a nested safeContents then,
 *                   this value is to be specified with the destination
 *      cert - the cert to export
 *      certDb - the certificate database handle
 *      keyId - a unique identifier to associate a certificate/key pair
 *      includeCertChain - PR_TRUE if the certificate chain is to be included.
 */
SECStatus
SEC_PKCS12AddCert(SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *safe,
                  void *nestedDest, CERTCertificate *cert,
                  CERTCertDBHandle *certDb, SECItem *keyId,
                  PRBool includeCertChain)
{
    sec_PKCS12CertBag *certBag;
    sec_PKCS12SafeBag *safeBag;
    void *mark;
    SECStatus rv;
    SECItem nick = { siBuffer, NULL, 0 };

    if (!p12ctxt || !cert) {
        return SECFailure;
    }
    mark = PORT_ArenaMark(p12ctxt->arena);

    /* allocate the cert bag */
    certBag = sec_PKCS12NewCertBag(p12ctxt->arena,
                                   SEC_OID_PKCS9_X509_CERT);
    if (!certBag) {
        goto loser;
    }

    if (SECITEM_CopyItem(p12ctxt->arena, &certBag->value.x509Cert,
                         &cert->derCert) != SECSuccess) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* if the cert chain is to be included, we should only be exporting
     * the cert from our internal database.
     */
    if (includeCertChain) {
        CERTCertificateList *certList = CERT_CertChainFromCert(cert,
                                                               certUsageSSLClient,
                                                               PR_TRUE);
        unsigned int count = 0;
        if (!certList) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }

        /* add cert chain */
        for (count = 0; count < (unsigned int)certList->len; count++) {
            if (SECITEM_CompareItem(&certList->certs[count], &cert->derCert) != SECEqual) {
                CERTCertificate *tempCert;

                /* decode the certificate */
                /* XXX
                 * This was rather silly.  The chain is constructed above
                 * by finding all of the CERTCertificate's in the database.
                 * Then the chain is put into a CERTCertificateList, which only
                 * contains the DER.  Finally, the DER was decoded, and the
                 * decoded cert was sent recursively back to this function.
                 * Beyond being inefficent, this causes data loss (specifically,
                 * the nickname).  Instead, for 3.4, we'll do a lookup by the
                 * DER, which should return the cached entry.
                 */
                tempCert = CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),
                                                  &certList->certs[count]);
                if (!tempCert) {
                    CERT_DestroyCertificateList(certList);
                    goto loser;
                }

                /* add the certificate */
                if (SEC_PKCS12AddCert(p12ctxt, safe, nestedDest, tempCert,
                                      certDb, NULL, PR_FALSE) != SECSuccess) {
                    CERT_DestroyCertificate(tempCert);
                    CERT_DestroyCertificateList(certList);
                    goto loser;
                }
                CERT_DestroyCertificate(tempCert);
            }
        }
        CERT_DestroyCertificateList(certList);
    }

    /* if the certificate has a nickname, we will set the friendly name
     * to that.
     */
    if (cert->nickname) {
        if (cert->slot && !PK11_IsInternal(cert->slot)) {
            /*
             * The cert is coming off of an external token,
             * let's strip the token name from the nickname
             * and only add what comes after the colon as the
             * nickname. -javi
             */
            char *delimit;

            delimit = PORT_Strchr(cert->nickname, ':');
            if (delimit == NULL) {
                nick.data = (unsigned char *)cert->nickname;
                nick.len = PORT_Strlen(cert->nickname);
            } else {
                delimit++;
                nick.data = (unsigned char *)PORT_ArenaStrdup(p12ctxt->arena,
                                                              delimit);
                nick.len = PORT_Strlen(delimit);
            }
        } else {
            nick.data = (unsigned char *)cert->nickname;
            nick.len = PORT_Strlen(cert->nickname);
        }
    }

    safeBag = sec_PKCS12CreateSafeBag(p12ctxt, SEC_OID_PKCS12_V1_CERT_BAG_ID,
                                      certBag);
    if (!safeBag) {
        goto loser;
    }

    /* add the friendly name and keyId attributes, if necessary */
    if (nick.data) {
        if (sec_PKCS12AddAttributeToBag(p12ctxt, safeBag,
                                        SEC_OID_PKCS9_FRIENDLY_NAME, &nick) != SECSuccess) {
            goto loser;
        }
    }

    if (keyId) {
        if (sec_PKCS12AddAttributeToBag(p12ctxt, safeBag, SEC_OID_PKCS9_LOCAL_KEY_ID,
                                        keyId) != SECSuccess) {
            goto loser;
        }
    }

    /* append the cert safeBag */
    if (nestedDest) {
        rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena,
                                                    (sec_PKCS12SafeContents *)nestedDest,
                                                    safeBag);
    } else {
        rv = sec_pkcs12_append_bag(p12ctxt, safe, safeBag);
    }

    if (rv != SECSuccess) {
        goto loser;
    }

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

loser:
    if (mark) {
        PORT_ArenaRelease(p12ctxt->arena, mark);
    }

    return SECFailure;
}

/* SEC_PKCS12AddKeyForCert
 *      Extracts the key associated with a particular certificate and exports
 *      it.
 *
 *      p12ctxt - the export context
 *      safe - the safeInfo to place the key in
 *      nestedDest - the nested safeContents to place a key
 *      cert - the certificate which the key belongs to
 *      shroudKey - encrypt the private key for export.  This value should
 *              always be true.  lower level code will not allow the export
 *              of unencrypted private keys.
 *      algorithm - the algorithm with which to encrypt the private key
 *      pwitem - the password to encrypt the private key with
 *      keyId - the keyID attribute
 *      nickName - the nickname attribute
 */
SECStatus
SEC_PKCS12AddKeyForCert(SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *safe,
                        void *nestedDest, CERTCertificate *cert,
                        PRBool shroudKey, SECOidTag algorithm, SECItem *pwitem,
                        SECItem *keyId, SECItem *nickName)
{
    void *mark;
    void *keyItem;
    SECOidTag keyType;
    SECStatus rv = SECFailure;
    SECItem nickname = { siBuffer, NULL, 0 }, uniPwitem = { siBuffer, NULL, 0 };
    sec_PKCS12SafeBag *returnBag;

    if (!p12ctxt || !cert || !safe) {
        return SECFailure;
    }

    mark = PORT_ArenaMark(p12ctxt->arena);

    /* retrieve the key based upon the type that it is and
     * specify the type of safeBag to store the key in
     */
    if (!shroudKey) {

        /* extract the key unencrypted.  this will most likely go away */
        SECKEYPrivateKeyInfo *pki = PK11_ExportPrivateKeyInfo(cert,
                                                              p12ctxt->wincx);
        if (!pki) {
            PORT_ArenaRelease(p12ctxt->arena, mark);
            PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY);
            return SECFailure;
        }
        keyItem = PORT_ArenaZAlloc(p12ctxt->arena, sizeof(SECKEYPrivateKeyInfo));
        if (!keyItem) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
        rv = SECKEY_CopyPrivateKeyInfo(p12ctxt->arena,
                                       (SECKEYPrivateKeyInfo *)keyItem, pki);
        keyType = SEC_OID_PKCS12_V1_KEY_BAG_ID;
        SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE);
    } else {

        /* extract the key encrypted */
        SECKEYEncryptedPrivateKeyInfo *epki = NULL;
        PK11SlotInfo *slot = NULL;

        if (!sec_pkcs12_encode_password(p12ctxt->arena, &uniPwitem, algorithm,
                                        pwitem)) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }

        /* we want to make sure to take the key out of the key slot */
        if (PK11_IsInternal(p12ctxt->slot)) {
            slot = PK11_GetInternalKeySlot();
        } else {
            slot = PK11_ReferenceSlot(p12ctxt->slot);
        }

        epki = PK11_ExportEncryptedPrivateKeyInfo(slot, algorithm,
                                                  &uniPwitem, cert,
                                                  NSS_PBE_DEFAULT_ITERATION_COUNT,
                                                  p12ctxt->wincx);
        PK11_FreeSlot(slot);
        if (!epki) {
            PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY);
            goto loser;
        }

        keyItem = PORT_ArenaZAlloc(p12ctxt->arena,
                                   sizeof(SECKEYEncryptedPrivateKeyInfo));
        if (!keyItem) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }
        rv = SECKEY_CopyEncryptedPrivateKeyInfo(p12ctxt->arena,
                                                (SECKEYEncryptedPrivateKeyInfo *)keyItem,
                                                epki);
        keyType = SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID;
        SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE);
    }

    if (rv != SECSuccess) {
        goto loser;
    }

    /* if no nickname specified, let's see if the certificate has a
     * nickname.
     */
    if (!nickName) {
        if (cert->nickname) {
            nickname.data = (unsigned char *)cert->nickname;
            nickname.len = PORT_Strlen(cert->nickname);
            nickName = &nickname;
        }
    }

    /* create the safe bag and set any attributes */
    returnBag = sec_PKCS12CreateSafeBag(p12ctxt, keyType, keyItem);
    if (!returnBag) {
        rv = SECFailure;
        goto loser;
    }

    if (nickName) {
        if (sec_PKCS12AddAttributeToBag(p12ctxt, returnBag,
                                        SEC_OID_PKCS9_FRIENDLY_NAME, nickName) != SECSuccess) {
            goto loser;
        }
    }

    if (keyId) {
        if (sec_PKCS12AddAttributeToBag(p12ctxt, returnBag, SEC_OID_PKCS9_LOCAL_KEY_ID,
                                        keyId) != SECSuccess) {
            goto loser;
        }
    }

    if (nestedDest) {
        rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena,
                                                    (sec_PKCS12SafeContents *)nestedDest,
                                                    returnBag);
    } else {
        rv = sec_pkcs12_append_bag(p12ctxt, safe, returnBag);
    }

loser:

    if (rv != SECSuccess) {
        PORT_ArenaRelease(p12ctxt->arena, mark);
    } else {
        PORT_ArenaUnmark(p12ctxt->arena, mark);
    }

    return rv;
}

/* SEC_PKCS12AddCertOrChainAndKey
 *      Add a certificate and key pair to be exported.
 *
 *      p12ctxt          - the export context
 *      certSafe         - the safeInfo where the cert is stored
 *      certNestedDest   - the nested safeContents to store the cert
 *      keySafe          - the safeInfo where the key is stored
 *      keyNestedDest    - the nested safeContents to store the key
 *      shroudKey        - extract the private key encrypted?
 *      pwitem           - the password with which the key is encrypted
 *      algorithm        - the algorithm with which the key is encrypted
 *      includeCertChain - also add certs from chain to bag.
 */
SECStatus
SEC_PKCS12AddCertOrChainAndKey(SEC_PKCS12ExportContext *p12ctxt,
                               void *certSafe, void *certNestedDest,
                               CERTCertificate *cert, CERTCertDBHandle *certDb,
                               void *keySafe, void *keyNestedDest,
                               PRBool shroudKey, SECItem *pwitem,
                               SECOidTag algorithm, PRBool includeCertChain)
{
    SECStatus rv = SECFailure;
    SGNDigestInfo *digest = NULL;
    void *mark = NULL;

    if (!p12ctxt || !certSafe || !keySafe || !cert) {
        return SECFailure;
    }

    mark = PORT_ArenaMark(p12ctxt->arena);

    /* generate the thumbprint of the cert to use as a keyId */
    digest = sec_pkcs12_compute_thumbprint(&cert->derCert);
    if (!digest) {
        PORT_ArenaRelease(p12ctxt->arena, mark);
        return SECFailure;
    }

    /* add the certificate */
    rv = SEC_PKCS12AddCert(p12ctxt, (SEC_PKCS12SafeInfo *)certSafe,
                           (SEC_PKCS12SafeInfo *)certNestedDest, cert, certDb,
                           &digest->digest, includeCertChain);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* add the key */
    rv = SEC_PKCS12AddKeyForCert(p12ctxt, (SEC_PKCS12SafeInfo *)keySafe,
                                 keyNestedDest, cert,
                                 shroudKey, algorithm, pwitem,
                                 &digest->digest, NULL);
    if (rv != SECSuccess) {
        goto loser;
    }

    SGN_DestroyDigestInfo(digest);

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

loser:
    SGN_DestroyDigestInfo(digest);
    PORT_ArenaRelease(p12ctxt->arena, mark);

    return SECFailure;
}

/* like SEC_PKCS12AddCertOrChainAndKey, but always adds cert chain */
SECStatus
SEC_PKCS12AddCertAndKey(SEC_PKCS12ExportContext *p12ctxt,
                        void *certSafe, void *certNestedDest,
                        CERTCertificate *cert, CERTCertDBHandle *certDb,
                        void *keySafe, void *keyNestedDest,
                        PRBool shroudKey, SECItem *pwItem, SECOidTag algorithm)
{
    return SEC_PKCS12AddCertOrChainAndKey(p12ctxt, certSafe, certNestedDest,
                                          cert, certDb, keySafe, keyNestedDest, shroudKey, pwItem,
                                          algorithm, PR_TRUE);
}

/* SEC_PKCS12CreateNestedSafeContents
 *      Allows nesting of safe contents to be implemented.  No limit imposed on
 *      depth.
 *
 *      p12ctxt - the export context
 *      baseSafe - the base safeInfo
 *      nestedDest - a parent safeContents (?)
 */
void *
SEC_PKCS12CreateNestedSafeContents(SEC_PKCS12ExportContext *p12ctxt,
                                   void *baseSafe, void *nestedDest)
{
    sec_PKCS12SafeContents *newSafe;
    sec_PKCS12SafeBag *safeContentsBag;
    void *mark;
    SECStatus rv;

    if (!p12ctxt || !baseSafe) {
        return NULL;
    }

    mark = PORT_ArenaMark(p12ctxt->arena);

    newSafe = sec_PKCS12CreateSafeContents(p12ctxt->arena);
    if (!newSafe) {
        PORT_ArenaRelease(p12ctxt->arena, mark);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    /* create the safeContents safeBag */
    safeContentsBag = sec_PKCS12CreateSafeBag(p12ctxt,
                                              SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID,
                                              newSafe);
    if (!safeContentsBag) {
        goto loser;
    }

    /* append the safeContents to the appropriate area */
    if (nestedDest) {
        rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena,
                                                    (sec_PKCS12SafeContents *)nestedDest,
                                                    safeContentsBag);
    } else {
        rv = sec_pkcs12_append_bag(p12ctxt, (SEC_PKCS12SafeInfo *)baseSafe,
                                   safeContentsBag);
    }
    if (rv != SECSuccess) {
        goto loser;
    }

    PORT_ArenaUnmark(p12ctxt->arena, mark);
    return newSafe;

loser:
    PORT_ArenaRelease(p12ctxt->arena, mark);
    return NULL;
}

/*********************************
 * Encoding routines
 *********************************/

/* Clean up the resources allocated by a sec_PKCS12EncoderContext. */
static void
sec_pkcs12_encoder_destroy_context(sec_PKCS12EncoderContext *p12enc)
{
    if (p12enc) {
        if (p12enc->outerA1ecx) {
            SEC_ASN1EncoderFinish(p12enc->outerA1ecx);
            p12enc->outerA1ecx = NULL;
        }
        if (p12enc->aSafeCinfo) {
            SEC_PKCS7DestroyContentInfo(p12enc->aSafeCinfo);
            p12enc->aSafeCinfo = NULL;
        }
        if (p12enc->middleP7ecx) {
            SEC_PKCS7EncoderFinish(p12enc->middleP7ecx, p12enc->p12exp->pwfn,
                                   p12enc->p12exp->pwfnarg);
            p12enc->middleP7ecx = NULL;
        }
        if (p12enc->middleA1ecx) {
            SEC_ASN1EncoderFinish(p12enc->middleA1ecx);
            p12enc->middleA1ecx = NULL;
        }
        if (p12enc->hmacCx) {
            PK11_DestroyContext(p12enc->hmacCx, PR_TRUE);
            p12enc->hmacCx = NULL;
        }
    }
}

/* set up the encoder context based on information in the export context
 * and return the newly allocated enocoder context.  A return of NULL
 * indicates an error occurred.
 */
static sec_PKCS12EncoderContext *
sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
{
    sec_PKCS12EncoderContext *p12enc = NULL;
    unsigned int i, nonEmptyCnt;
    SECStatus rv;
    SECItem ignore = { 0 };
    void *mark;
    SECItem *salt = NULL;
    SECItem *params = NULL;

    if (!p12exp || !p12exp->safeInfos) {
        return NULL;
    }

    /* check for any empty safes and skip them */
    i = nonEmptyCnt = 0;
    while (p12exp->safeInfos[i]) {
        if (p12exp->safeInfos[i]->itemCount) {
            nonEmptyCnt++;
        }
        i++;
    }
    if (nonEmptyCnt == 0) {
        return NULL;
    }
    p12exp->authSafe.encodedSafes[nonEmptyCnt] = NULL;

    /* allocate the encoder context */
    mark = PORT_ArenaMark(p12exp->arena);
    p12enc = PORT_ArenaZNew(p12exp->arena, sec_PKCS12EncoderContext);
    if (!p12enc) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    p12enc->arena = p12exp->arena;
    p12enc->p12exp = p12exp;

    /* set up the PFX version and information */
    PORT_Memset(&p12enc->pfx, 0, sizeof(sec_PKCS12PFXItem));
    if (!SEC_ASN1EncodeInteger(p12exp->arena, &(p12enc->pfx.version),
                               SEC_PKCS12_VERSION)) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* set up the authenticated safe content info based on the
     * type of integrity being used.  this should be changed to
     * enforce integrity mode, but will not be implemented until
     * it is confirmed that integrity must be in place
     */
    if (p12exp->integrityEnabled && !p12exp->pwdIntegrity) {
        /* create public key integrity mode */
        p12enc->aSafeCinfo = SEC_PKCS7CreateSignedData(
            p12exp->integrityInfo.pubkeyInfo.cert,
            certUsageEmailSigner,
            p12exp->integrityInfo.pubkeyInfo.certDb,
            p12exp->integrityInfo.pubkeyInfo.algorithm,
            NULL,
            p12exp->pwfn,
            p12exp->pwfnarg);
        if (!p12enc->aSafeCinfo) {
            goto loser;
        }
        if (SEC_PKCS7IncludeCertChain(p12enc->aSafeCinfo, NULL) != SECSuccess) {
            goto loser;
        }
        PORT_CheckSuccess(SEC_PKCS7AddSigningTime(p12enc->aSafeCinfo));
    } else {
        p12enc->aSafeCinfo = SEC_PKCS7CreateData();

        /* init password pased integrity mode */
        if (p12exp->integrityEnabled) {
            SECItem pwd = { siBuffer, NULL, 0 };
            PK11SymKey *symKey;
            CK_MECHANISM_TYPE integrityMechType;
            CK_MECHANISM_TYPE hmacMechType;
            salt = sec_pkcs12_generate_salt();

            /* zero out macData and set values */
            PORT_Memset(&p12enc->mac, 0, sizeof(sec_PKCS12MacData));

            if (!salt) {
                PORT_SetError(SEC_ERROR_NO_MEMORY);
                goto loser;
            }
            if (SECITEM_CopyItem(p12exp->arena, &(p12enc->mac.macSalt), salt) != SECSuccess) {
                PORT_SetError(SEC_ERROR_NO_MEMORY);
                goto loser;
            }
            if (!SEC_ASN1EncodeInteger(p12exp->arena, &(p12enc->mac.iter),
                                       NSS_PBE_DEFAULT_ITERATION_COUNT)) {
                goto loser;
            }

            /* generate HMAC key */
            if (!sec_pkcs12_convert_item_to_unicode(NULL, &pwd,
                                                    p12exp->integrityInfo.pwdInfo.password, PR_TRUE,
                                                    PR_TRUE, PR_TRUE)) {
                goto loser;
            }
            /*
             * This code only works with PKCS #12 Mac using PKCS #5 v1
             * PBA keygens. PKCS #5 v2 support will require a change to
             * the PKCS #12 spec.
             */
            params = PK11_CreatePBEParams(salt, &pwd,
                                          NSS_PBE_DEFAULT_ITERATION_COUNT);
            SECITEM_ZfreeItem(salt, PR_TRUE);
            salt = NULL;
            SECITEM_ZfreeItem(&pwd, PR_FALSE);

            /* get the PBA Mechanism to generate the key */
            switch (p12exp->integrityInfo.pwdInfo.algorithm) {
                case SEC_OID_SHA1:
                    integrityMechType = CKM_PBA_SHA1_WITH_SHA1_HMAC;
                    break;
                case SEC_OID_MD5:
                    integrityMechType = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN;
                    break;
                case SEC_OID_MD2:
                    integrityMechType = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN;
                    break;
                default:
                    goto loser;
            }

            /* generate the key */
            symKey = PK11_KeyGen(NULL, integrityMechType, params, 20, NULL);
            PK11_DestroyPBEParams(params);
            if (!symKey) {
                goto loser;
            }

            /* initialize HMAC */
            /* Get the HMAC mechanism from the hash OID */
            hmacMechType = sec_pkcs12_algtag_to_mech(
                p12exp->integrityInfo.pwdInfo.algorithm);

            p12enc->hmacCx = PK11_CreateContextBySymKey(hmacMechType,
                                                        CKA_SIGN, symKey, &ignore);

            PK11_FreeSymKey(symKey);
            if (!p12enc->hmacCx) {
                PORT_SetError(SEC_ERROR_NO_MEMORY);
                goto loser;
            }
            rv = PK11_DigestBegin(p12enc->hmacCx);
            if (rv != SECSuccess)
                goto loser;
        }
    }

    if (!p12enc->aSafeCinfo) {
        goto loser;
    }

    PORT_ArenaUnmark(p12exp->arena, mark);

    return p12enc;

loser:
    sec_pkcs12_encoder_destroy_context(p12enc);
    if (p12exp->arena != NULL)
        PORT_ArenaRelease(p12exp->arena, mark);
    if (salt) {
        SECITEM_ZfreeItem(salt, PR_TRUE);
    }
    if (params) {
        PK11_DestroyPBEParams(params);
    }

    return NULL;
}

/* The outermost ASN.1 encoder calls this function for output.
** This function calls back to the library caller's output routine,
** which typically writes to a PKCS12 file.
 */
static void
sec_P12A1OutputCB_Outer(void *arg, const char *buf, unsigned long len,
                        int depth, SEC_ASN1EncodingPart data_kind)
{
    struct sec_pkcs12_encoder_output *output;

    output = (struct sec_pkcs12_encoder_output *)arg;
    (*output->outputfn)(output->outputarg, buf, len);
}

/* The "middle" and "inner" ASN.1 encoders call this function to output.
** This function does HMACing, if appropriate, and then buffers the data.
** The buffered data is eventually passed down to the underlying PKCS7 encoder.
 */
static void
sec_P12A1OutputCB_HmacP7Update(void *arg, const char *buf,
                               unsigned long len,
                               int depth,
                               SEC_ASN1EncodingPart data_kind)
{
    sec_pkcs12OutputBuffer *bufcx = (sec_pkcs12OutputBuffer *)arg;

    if (!buf || !len)
        return;

    if (bufcx->hmacCx) {
        PK11_DigestOp(bufcx->hmacCx, (unsigned char *)buf, len);
    }

    /* buffer */
    if (bufcx->numBytes > 0) {
        int toCopy;
        if (len + bufcx->numBytes <= bufcx->bufBytes) {
            memcpy(bufcx->buf + bufcx->numBytes, buf, len);
            bufcx->numBytes += len;
            if (bufcx->numBytes < bufcx->bufBytes)
                return;
            SEC_PKCS7EncoderUpdate(bufcx->p7eCx, bufcx->buf, bufcx->bufBytes);
            bufcx->numBytes = 0;
            return;
        }
        toCopy = bufcx->bufBytes - bufcx->numBytes;
        memcpy(bufcx->buf + bufcx->numBytes, buf, toCopy);
        SEC_PKCS7EncoderUpdate(bufcx->p7eCx, bufcx->buf, bufcx->bufBytes);
        bufcx->numBytes = 0;
        len -= toCopy;
        buf += toCopy;
    }
    /* buffer is presently empty */
    if (len >= bufcx->bufBytes) {
        /* Just pass it through */
        SEC_PKCS7EncoderUpdate(bufcx->p7eCx, buf, len);
    } else {
        /* copy it all into the buffer, and return */
        memcpy(bufcx->buf, buf, len);
        bufcx->numBytes = len;
    }
}

void
sec_FlushPkcs12OutputBuffer(sec_pkcs12OutputBuffer *bufcx)
{
    if (bufcx->numBytes > 0) {
        SEC_PKCS7EncoderUpdate(bufcx->p7eCx, bufcx->buf, bufcx->numBytes);
        bufcx->numBytes = 0;
    }
}

/* Feeds the output of a PKCS7 encoder into the next outward ASN.1 encoder.
** This function is used by both the inner and middle PCS7 encoders.
*/
static void
sec_P12P7OutputCB_CallA1Update(void *arg, const char *buf, unsigned long len)
{
    SEC_ASN1EncoderContext *cx = (SEC_ASN1EncoderContext *)arg;

    if (!buf || !len)
        return;

    SEC_ASN1EncoderUpdate(cx, buf, len);
}

/* this function encodes content infos which are part of the
 * sequence of content infos labeled AuthenticatedSafes
 */
static SECStatus
sec_pkcs12_encoder_asafe_process(sec_PKCS12EncoderContext *p12ecx)
{
    SEC_PKCS7EncoderContext *innerP7ecx;
    SEC_PKCS7ContentInfo *cinfo;
    PK11SymKey *bulkKey = NULL;
    SEC_ASN1EncoderContext *innerA1ecx = NULL;
    SECStatus rv = SECSuccess;

    if (p12ecx->currentSafe < p12ecx->p12exp->authSafe.safeCount) {
        SEC_PKCS12SafeInfo *safeInfo;
        SECOidTag cinfoType;

        safeInfo = p12ecx->p12exp->safeInfos[p12ecx->currentSafe];

        /* skip empty safes */
        if (safeInfo->itemCount == 0) {
            return SECSuccess;
        }

        cinfo = safeInfo->cinfo;
        cinfoType = SEC_PKCS7ContentType(cinfo);

        /* determine the safe type and set the appropriate argument */
        switch (cinfoType) {
            case SEC_OID_PKCS7_DATA:
            case SEC_OID_PKCS7_ENVELOPED_DATA:
                break;
            case SEC_OID_PKCS7_ENCRYPTED_DATA:
                bulkKey = safeInfo->encryptionKey;
                PK11_SetSymKeyUserData(bulkKey, &safeInfo->pwitem, NULL);
                break;
            default:
                return SECFailure;
        }

        /* start the PKCS7 encoder */
        innerP7ecx = SEC_PKCS7EncoderStart(cinfo,
                                           sec_P12P7OutputCB_CallA1Update,
                                           p12ecx->middleA1ecx, bulkKey);
        if (!innerP7ecx) {
            goto loser;
        }

        /* encode safe contents */
        p12ecx->innerBuf.p7eCx = innerP7ecx;
        p12ecx->innerBuf.hmacCx = NULL;
        p12ecx->innerBuf.numBytes = 0;
        p12ecx->innerBuf.bufBytes = sizeof p12ecx->innerBuf.buf;

        innerA1ecx = SEC_ASN1EncoderStart(safeInfo->safe,
                                          sec_PKCS12SafeContentsTemplate,
                                          sec_P12A1OutputCB_HmacP7Update,
                                          &p12ecx->innerBuf);
        if (!innerA1ecx) {
            goto loser;
        }
        rv = SEC_ASN1EncoderUpdate(innerA1ecx, NULL, 0);
        SEC_ASN1EncoderFinish(innerA1ecx);
        sec_FlushPkcs12OutputBuffer(&p12ecx->innerBuf);
        innerA1ecx = NULL;
        if (rv != SECSuccess) {
            goto loser;
        }

        /* finish up safe content info */
        rv = SEC_PKCS7EncoderFinish(innerP7ecx, p12ecx->p12exp->pwfn,
                                    p12ecx->p12exp->pwfnarg);
    }
    memset(&p12ecx->innerBuf, 0, sizeof p12ecx->innerBuf);
    return SECSuccess;

loser:
    if (innerP7ecx) {
        SEC_PKCS7EncoderFinish(innerP7ecx, p12ecx->p12exp->pwfn,
                               p12ecx->p12exp->pwfnarg);
    }

    if (innerA1ecx) {
        SEC_ASN1EncoderFinish(innerA1ecx);
    }
    memset(&p12ecx->innerBuf, 0, sizeof p12ecx->innerBuf);
    return SECFailure;
}

/* finish the HMAC and encode the macData so that it can be
 * encoded.
 */
static SECStatus
sec_Pkcs12FinishMac(sec_PKCS12EncoderContext *p12ecx)
{
    SECItem hmac = { siBuffer, NULL, 0 };
    SECStatus rv;
    SGNDigestInfo *di = NULL;
    void *dummy;

    if (!p12ecx) {
        return SECFailure;
    }

    /* make sure we are using password integrity mode */
    if (!p12ecx->p12exp->integrityEnabled) {
        return SECSuccess;
    }

    if (!p12ecx->p12exp->pwdIntegrity) {
        return SECSuccess;
    }

    /* finish the hmac */
    hmac.data = (unsigned char *)PORT_ZAlloc(SHA1_LENGTH);
    if (!hmac.data) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    rv = PK11_DigestFinal(p12ecx->hmacCx, hmac.data, &hmac.len, SHA1_LENGTH);

    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* create the digest info */
    di = SGN_CreateDigestInfo(p12ecx->p12exp->integrityInfo.pwdInfo.algorithm,
                              hmac.data, hmac.len);
    if (!di) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        rv = SECFailure;
        goto loser;
    }

    rv = SGN_CopyDigestInfo(p12ecx->arena, &p12ecx->mac.safeMac, di);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    /* encode the mac data */
    dummy = SEC_ASN1EncodeItem(p12ecx->arena, &p12ecx->pfx.encodedMacData,
                               &p12ecx->mac, sec_PKCS12MacDataTemplate);
    if (!dummy) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        rv = SECFailure;
    }

loser:
    if (di) {
        SGN_DestroyDigestInfo(di);
    }
    if (hmac.data) {
        SECITEM_ZfreeItem(&hmac, PR_FALSE);
    }
    PK11_DestroyContext(p12ecx->hmacCx, PR_TRUE);
    p12ecx->hmacCx = NULL;

    return rv;
}

/* pfx notify function for ASN1 encoder.
 * We want to stop encoding once we reach the authenticated safe.
 * At that point, the encoder will be updated via streaming
 * as the authenticated safe is  encoded.
 */
static void
sec_pkcs12_encoder_pfx_notify(void *arg, PRBool before, void *dest, int real_depth)
{
    sec_PKCS12EncoderContext *p12ecx;

    if (!before) {
        return;
    }

    /* look for authenticated safe */
    p12ecx = (sec_PKCS12EncoderContext *)arg;
    if (dest != &p12ecx->pfx.encodedAuthSafe) {
        return;
    }

    SEC_ASN1EncoderSetTakeFromBuf(p12ecx->outerA1ecx);
    SEC_ASN1EncoderSetStreaming(p12ecx->outerA1ecx);
    SEC_ASN1EncoderClearNotifyProc(p12ecx->outerA1ecx);
}

/* SEC_PKCS12Encode
 *      Encodes the PFX item and returns it to the output function, via
 *      callback.  the output function must be capable of multiple updates.
 *
 *      p12exp - the export context
 *      output - the output function callback, will be called more than once,
 *               must be able to accept streaming data.
 *      outputarg - argument for the output callback.
 */
SECStatus
SEC_PKCS12Encode(SEC_PKCS12ExportContext *p12exp,
                 SEC_PKCS12EncoderOutputCallback output, void *outputarg)
{
    sec_PKCS12EncoderContext *p12enc;
    struct sec_pkcs12_encoder_output outInfo;
    SECStatus rv;

    if (!p12exp || !output) {
        return SECFailure;
    }

    /* get the encoder context */
    p12enc = sec_pkcs12_encoder_start_context(p12exp);
    if (!p12enc) {
        return SECFailure;
    }

    outInfo.outputfn = output;
    outInfo.outputarg = outputarg;

    /* set up PFX encoder, the "outer" encoder.  Set it for streaming */
    p12enc->outerA1ecx = SEC_ASN1EncoderStart(&p12enc->pfx,
                                              sec_PKCS12PFXItemTemplate,
                                              sec_P12A1OutputCB_Outer,
                                              &outInfo);
    if (!p12enc->outerA1ecx) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        rv = SECFailure;
        goto loser;
    }
    SEC_ASN1EncoderSetStreaming(p12enc->outerA1ecx);
    SEC_ASN1EncoderSetNotifyProc(p12enc->outerA1ecx,
                                 sec_pkcs12_encoder_pfx_notify, p12enc);
    rv = SEC_ASN1EncoderUpdate(p12enc->outerA1ecx, NULL, 0);
    if (rv != SECSuccess) {
        rv = SECFailure;
        goto loser;
    }

    /* set up asafe cinfo - the output of the encoder feeds the PFX encoder */
    p12enc->middleP7ecx = SEC_PKCS7EncoderStart(p12enc->aSafeCinfo,
                                                sec_P12P7OutputCB_CallA1Update,
                                                p12enc->outerA1ecx, NULL);
    if (!p12enc->middleP7ecx) {
        rv = SECFailure;
        goto loser;
    }

    /* encode asafe */
    p12enc->middleBuf.p7eCx = p12enc->middleP7ecx;
    p12enc->middleBuf.hmacCx = NULL;
    p12enc->middleBuf.numBytes = 0;
    p12enc->middleBuf.bufBytes = sizeof p12enc->middleBuf.buf;

    /* Setup the "inner ASN.1 encoder for Authenticated Safes.  */
    if (p12enc->p12exp->integrityEnabled &&
        p12enc->p12exp->pwdIntegrity) {
        p12enc->middleBuf.hmacCx = p12enc->hmacCx;
    }
    p12enc->middleA1ecx = SEC_ASN1EncoderStart(&p12enc->p12exp->authSafe,
                                               sec_PKCS12AuthenticatedSafeTemplate,
                                               sec_P12A1OutputCB_HmacP7Update,
                                               &p12enc->middleBuf);
    if (!p12enc->middleA1ecx) {
        rv = SECFailure;
        goto loser;
    }
    SEC_ASN1EncoderSetStreaming(p12enc->middleA1ecx);
    SEC_ASN1EncoderSetTakeFromBuf(p12enc->middleA1ecx);

    /* encode each of the safes */
    while (p12enc->currentSafe != p12enc->p12exp->safeInfoCount) {
        sec_pkcs12_encoder_asafe_process(p12enc);
        p12enc->currentSafe++;
    }
    SEC_ASN1EncoderClearTakeFromBuf(p12enc->middleA1ecx);
    SEC_ASN1EncoderClearStreaming(p12enc->middleA1ecx);
    SEC_ASN1EncoderUpdate(p12enc->middleA1ecx, NULL, 0);
    SEC_ASN1EncoderFinish(p12enc->middleA1ecx);
    p12enc->middleA1ecx = NULL;

    sec_FlushPkcs12OutputBuffer(&p12enc->middleBuf);

    /* finish the encoding of the authenticated safes */
    rv = SEC_PKCS7EncoderFinish(p12enc->middleP7ecx, p12exp->pwfn,
                                p12exp->pwfnarg);
    p12enc->middleP7ecx = NULL;
    if (rv != SECSuccess) {
        goto loser;
    }

    SEC_ASN1EncoderClearTakeFromBuf(p12enc->outerA1ecx);
    SEC_ASN1EncoderClearStreaming(p12enc->outerA1ecx);

    /* update the mac, if necessary */
    rv = sec_Pkcs12FinishMac(p12enc);
    if (rv != SECSuccess) {
        goto loser;
    }

    /* finish encoding the pfx */
    rv = SEC_ASN1EncoderUpdate(p12enc->outerA1ecx, NULL, 0);

    SEC_ASN1EncoderFinish(p12enc->outerA1ecx);
    p12enc->outerA1ecx = NULL;

loser:
    sec_pkcs12_encoder_destroy_context(p12enc);
    return rv;
}

void
SEC_PKCS12DestroyExportContext(SEC_PKCS12ExportContext *p12ecx)
{
    int i = 0;

    if (!p12ecx) {
        return;
    }

    if (p12ecx->safeInfos) {
        i = 0;
        while (p12ecx->safeInfos[i] != NULL) {
            if (p12ecx->safeInfos[i]->encryptionKey) {
                PK11_FreeSymKey(p12ecx->safeInfos[i]->encryptionKey);
            }
            if (p12ecx->safeInfos[i]->cinfo) {
                SEC_PKCS7DestroyContentInfo(p12ecx->safeInfos[i]->cinfo);
            }
            i++;
        }
    }

    PK11_FreeSlot(p12ecx->slot);

    PORT_FreeArena(p12ecx->arena, PR_TRUE);
}
